2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5 // Copyright 2015 Xamarin Inc
9 // Ported from C++ to C and adjusted to Mono runtime
12 // DoToCurrency (they look like new methods we do not have)
14 #ifndef DISABLE_DECIMAL
18 #include <mono/utils/mono-compiler.h>
19 #include <mono/metadata/exception.h>
20 #include <mono/metadata/object-internals.h>
31 #include "decimal-ms.h"
33 #define min(a, b) (((a) < (b)) ? (a) : (b))
37 MONO_DECIMAL_OVERFLOW,
38 MONO_DECIMAL_INVALID_ARGUMENT,
39 MONO_DECIMAL_DIVBYZERO,
40 MONO_DECIMAL_ARGUMENT_OUT_OF_RANGE
47 static const uint32_t ten_to_nine = 1000000000U;
48 static const uint32_t ten_to_ten_div_4 = 2500000000U;
50 #define DECIMAL_NEG ((uint8_t)0x80)
52 #define DECIMAL_SCALE(dec) ((dec).u.u.scale)
53 #define DECIMAL_SIGN(dec) ((dec).u.u.sign)
54 #define DECIMAL_SIGNSCALE(dec) ((dec).u.signscale)
55 #define DECIMAL_LO32(dec) ((dec).v.v.Lo32)
56 #define DECIMAL_MID32(dec) ((dec).v.v.Mid32)
57 #define DECIMAL_HI32(dec) ((dec).Hi32)
58 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
59 # define DECIMAL_LO64_GET(dec) (((uint64_t)((dec).v.v.Mid32) << 32) | (dec).v.v.Lo32)
60 # define DECIMAL_LO64_SET(dec,value) {(dec).v.v.Lo32 = (value); (dec).v.v.Mid32 = ((value) >> 32); }
62 # define DECIMAL_LO64_GET(dec) ((dec).v.Lo64)
63 # define DECIMAL_LO64_SET(dec,value) {(dec).v.Lo64 = value; }
66 #define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
67 #define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
68 DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
70 #define DEC_SCALE_MAX 28
73 #define OVFL_MAX_9_HI 4
74 #define OVFL_MAX_9_MID 1266874889
75 #define OVFL_MAX_9_LO 3047500985u
77 #define OVFL_MAX_5_HI 42949
78 #define OVFL_MAX_5_MID 2890341191
80 #define OVFL_MAX_1_HI 429496729
85 #if BYTE_ORDER == G_BIG_ENDIAN
95 static const SPLIT64 ten_to_eighteen = { 1000000000000000000ULL };
99 // Structure to access an encoded double floating point
102 #if BYTE_ORDER == G_BIG_ENDIAN
105 unsigned int mantHi:20;
109 unsigned int mantHi:20;
117 #if BYTE_ORDER == G_BIG_ENDIAN
118 #define DEFDS(Lo, Hi, exp, sign) { {sign, exp, Hi, Lo } }
120 #define DEFDS(Lo, Hi, exp, sign) { {Lo, Hi, exp, sign} }
123 const DoubleStructure ds2to64 = DEFDS(0, 0, DBLBIAS + 65, 0);
125 // Single floating point Bias
128 // Structure to access an encoded single floating point
130 #if BYTE_ORDER == G_BIG_ENDIAN
133 unsigned int mant:23;
135 unsigned int mant:23;
145 static const uint32_t power10 [POWER10_MAX+1] = {
146 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
150 static const double double_power10[] = {
151 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
152 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
153 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
154 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
155 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
156 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
157 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
158 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
161 const SPLIT64 sdl_power10[] = { {10000000000ULL}, // 1E10
162 {100000000000ULL}, // 1E11
163 {1000000000000ULL}, // 1E12
164 {10000000000000ULL}, // 1E13
165 {100000000000000ULL} }; // 1E14
167 static const uint64_t long_power10[] = {
184 10000000000000000ULL,
185 100000000000000000ULL,
186 1000000000000000000ULL,
187 10000000000000000000ULL};
190 uint32_t Hi, Mid, Lo;
193 const DECOVFL power_overflow[] = {
194 // This is a table of the largest values that can be in the upper two
195 // ULONGs of a 96-bit number that will not overflow when multiplied
196 // by a given power. For the upper word, this is a table of
197 // 2^32 / 10^n for 1 <= n <= 9. For the lower word, this is the
198 // remaining fraction part * 2^32. 2^32 = 4294967296.
200 { 429496729u, 2576980377u, 2576980377u }, // 10^1 remainder 0.6
201 { 42949672u, 4123168604u, 687194767u }, // 10^2 remainder 0.16
202 { 4294967u, 1271310319u, 2645699854u }, // 10^3 remainder 0.616
203 { 429496u, 3133608139u, 694066715u }, // 10^4 remainder 0.1616
204 { 42949u, 2890341191u, 2216890319u }, // 10^5 remainder 0.51616
205 { 4294u, 4154504685u, 2369172679u }, // 10^6 remainder 0.551616
206 { 429u, 2133437386u, 4102387834u }, // 10^7 remainder 0.9551616
207 { 42u, 4078814305u, 410238783u }, // 10^8 remainder 0.09991616
208 { 4u, 1266874889u, 3047500985u }, // 10^9 remainder 0.709551616
212 #define UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b)))
213 #define Div64by32(num, den) ((uint32_t)((uint64_t)(num) / (uint32_t)(den)))
214 #define Mod64by32(num, den) ((uint32_t)((uint64_t)(num) % (uint32_t)(den)))
219 const int maxIx = (sizeof(double_power10)/sizeof(double_power10[0]));
222 return double_power10[ix];
223 return pow(10.0, ix);
224 } // double fnDblPower10()
227 static inline int64_t
228 DivMod32by32(int32_t num, int32_t den)
232 sdl.u.Lo = num / den;
233 sdl.u.Hi = num % den;
237 static inline int64_t
238 DivMod64by32(int64_t num, int32_t den)
242 sdl.u.Lo = Div64by32(num, den);
243 sdl.u.Hi = Mod64by32(num, den);
248 UInt64x64To128(SPLIT64 op1, SPLIT64 op2, uint64_t *hi)
254 tmp1.int64 = UInt32x32To64(op1.u.Lo, op2.u.Lo); // lo partial prod
255 tmp2.int64 = UInt32x32To64(op1.u.Lo, op2.u.Hi); // mid 1 partial prod
256 tmp1.u.Hi += tmp2.u.Lo;
257 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
259 tmp3.int64 = UInt32x32To64(op1.u.Hi, op2.u.Hi) + (uint64_t)tmp2.u.Hi;
260 tmp2.int64 = UInt32x32To64(op1.u.Hi, op2.u.Lo);
261 tmp1.u.Hi += tmp2.u.Lo;
262 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
264 tmp3.int64 += (uint64_t)tmp2.u.Hi;
274 * pdlNum - Pointer to 64-bit dividend
275 * ulDen - 32-bit divisor
278 * Do full divide, yielding 64-bit result and 32-bit remainder.
281 * Quotient overwrites dividend.
287 // Was: FullDiv64By32
289 FullDiv64By32 (uint64_t *num, uint32_t den)
297 if (tmp.u.Hi >= den) {
298 // DivMod64by32 returns quotient in Lo, remainder in Hi.
301 res.int64 = DivMod64by32(res.int64, den);
306 tmp.int64 = DivMod64by32(tmp.int64, den);
316 * res_hi - Top uint32_t of quotient
317 * res_mid - Middle uint32_t of quotient
318 * res_lo - Bottom uint32_t of quotient
319 * scale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
322 * Determine the max power of 10, <= 9, that the quotient can be scaled
323 * up by and still fit in 96 bits.
326 * Returns power of 10 to scale by, -1 if overflow error.
328 ***********************************************************************/
331 SearchScale(uint32_t res_hi, uint32_t res_mid, uint32_t res_lo, int scale)
335 // Quick check to stop us from trying to scale any more.
337 if (res_hi > OVFL_MAX_1_HI || scale >= DEC_SCALE_MAX) {
342 if (scale > DEC_SCALE_MAX - 9) {
343 // We can't scale by 10^9 without exceeding the max scale factor.
344 // See if we can scale to the max. If not, we'll fall into
345 // standard search for scale factor.
347 cur_scale = DEC_SCALE_MAX - scale;
348 if (res_hi < power_overflow[cur_scale - 1].Hi)
351 if (res_hi == power_overflow[cur_scale - 1].Hi) {
353 if (res_mid > power_overflow[cur_scale - 1].Mid ||
354 (res_mid == power_overflow[cur_scale - 1].Mid && res_lo > power_overflow[cur_scale - 1].Lo)) {
359 } else if (res_hi < OVFL_MAX_9_HI || (res_hi == OVFL_MAX_9_HI && res_mid < OVFL_MAX_9_MID) || (res_hi == OVFL_MAX_9_HI && res_mid == OVFL_MAX_9_MID && res_lo <= OVFL_MAX_9_LO))
362 // Search for a power to scale by < 9. Do a binary search
363 // on power_overflow[].
366 if (res_hi < OVFL_MAX_5_HI)
368 else if (res_hi > OVFL_MAX_5_HI)
373 // cur_scale is 3 or 7.
375 if (res_hi < power_overflow[cur_scale - 1].Hi)
377 else if (res_hi > power_overflow[cur_scale - 1].Hi)
382 // cur_scale is 2, 4, 6, or 8.
384 // In all cases, we already found we could not use the power one larger.
385 // So if we can use this power, it is the biggest, and we're done. If
386 // we can't use this power, the one below it is correct for all cases
387 // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
389 if (res_hi > power_overflow[cur_scale - 1].Hi)
392 if (res_hi == power_overflow[cur_scale - 1].Hi)
396 // cur_scale = largest power of 10 we can scale by without overflow,
397 // cur_scale < 9. See if this is enough to make scale factor
398 // positive if it isn't already.
400 if (cur_scale + scale < 0)
411 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
412 * ulDen - 32-bit divisor.
415 * Do full divide, yielding 96-bit result and 32-bit remainder.
418 * Quotient overwrites dividend.
426 Div96By32(uint32_t *num, uint32_t den)
444 tmp.int64 = DivMod64by32(tmp.int64, den);
448 tmp.int64 = DivMod64by32(tmp.int64, den);
452 tmp.int64 = DivMod64by32(tmp.int64, den);
461 * pdecRes - Pointer to Decimal result location
462 * operand - Pointer to Decimal operand
465 * Chop the value to integer. Return remainder so Int() function
466 * can round down if non-zero.
474 ***********************************************************************/
477 DecFixInt(MonoDecimal * result, MonoDecimal * operand)
484 if (operand->u.u.scale > 0) {
485 num[0] = operand->v.v.Lo32;
486 num[1] = operand->v.v.Mid32;
487 num[2] = operand->Hi32;
488 scale = operand->u.u.scale;
489 result->u.u.sign = operand->u.u.sign;
493 if (scale > POWER10_MAX)
496 pwr = power10[scale];
498 rem |= Div96By32(num, pwr);
502 result->v.v.Lo32 = num[0];
503 result->v.v.Mid32 = num[1];
504 result->Hi32 = num[2];
505 result->u.u.scale = 0;
510 COPYDEC(*result, *operand);
511 // Odd, the Microsoft code does not set result->reserved to zero on this case
519 * res - Array of uint32_ts with value, least-significant first.
520 * hi_res - Index of last non-zero value in res.
521 * scale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
524 * See if we need to scale the result to fit it in 96 bits.
525 * Perform needed scaling. Adjust scale factor accordingly.
528 * res updated in place, always 3 uint32_ts.
529 * New scale factor returned, -1 if overflow error.
533 ScaleResult(uint32_t *res, int hi_res, int scale)
542 // See if we need to scale the result. The combined scale must
543 // be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
545 // Start by figuring a lower bound on the scaling needed to make
546 // the upper 96 bits zero. hi_res is the index into res[]
547 // of the highest non-zero uint32_t.
549 new_scale = hi_res * 32 - 64 - 1;
555 if (!(tmp & 0xFFFF0000)) {
559 if (!(tmp & 0xFF000000)) {
563 if (!(tmp & 0xF0000000)) {
567 if (!(tmp & 0xC0000000)) {
571 if (!(tmp & 0x80000000)) {
576 // Multiply bit position by log10(2) to figure it's power of 10.
577 // We scale the log by 256. log(2) = .30103, * 256 = 77. Doing this
578 // with a multiply saves a 96-byte lookup table. The power returned
579 // is <= the power of the number, so we must add one power of 10
580 // to make it's integer part zero after dividing by 256.
582 // Note: the result of this multiplication by an approximation of
583 // log10(2) have been exhaustively checked to verify it gives the
584 // correct result. (There were only 95 to check...)
586 new_scale = ((new_scale * 77) >> 8) + 1;
588 // new_scale = min scale factor to make high 96 bits zero, 0 - 29.
589 // This reduces the scale factor of the result. If it exceeds the
590 // current scale of the result, we'll overflow.
592 if (new_scale > scale)
598 // Make sure we scale by enough to bring the current scale factor
601 if (new_scale < scale - DEC_SCALE_MAX)
602 new_scale = scale - DEC_SCALE_MAX;
604 if (new_scale != 0) {
605 // Scale by the power of 10 given by new_scale. Note that this is
606 // NOT guaranteed to bring the number within 96 bits -- it could
607 // be 1 power of 10 short.
611 sdlTmp.u.Hi = 0; // initialize remainder
615 sticky |= sdlTmp.u.Hi; // record remainder as sticky bit
617 if (new_scale > POWER10_MAX)
620 pwr = power10[new_scale];
622 // Compute first quotient.
623 // DivMod64by32 returns quotient in Lo, remainder in Hi.
625 sdlTmp.int64 = DivMod64by32(res[hi_res], pwr);
626 res[hi_res] = sdlTmp.u.Lo;
630 // If first quotient was 0, update hi_res.
632 if (sdlTmp.u.Lo == 0)
635 // Compute subsequent quotients.
638 sdlTmp.u.Lo = res[cur];
639 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, pwr);
640 res[cur] = sdlTmp.u.Lo;
646 new_scale -= POWER10_MAX;
648 continue; // scale some more
650 // If we scaled enough, hi_res would be 2 or less. If not,
651 // divide by 10 more.
656 continue; // scale by 10
659 // Round final result. See if remainder >= 1/2 of divisor.
660 // If remainder == 1/2 divisor, round up if odd or sticky bit set.
662 pwr >>= 1; // power of 10 always even
663 if ( pwr <= sdlTmp.u.Hi && (pwr < sdlTmp.u.Hi ||
664 ((res[0] & 1) | sticky)) ) {
666 while (++res[++cur] == 0);
669 // The rounding caused us to carry beyond 96 bits.
673 sticky = 0; // no sticky bit
674 sdlTmp.u.Hi = 0; // or remainder
677 continue; // scale by 10
681 // We may have scaled it more than we planned. Make sure the scale
682 // factor hasn't gone negative, indicating overflow.
694 // Returns: MONO_DECIMAL_OVERFLOW or MONO_DECIMAL_OK
695 static MonoDecimalStatus
696 mono_decimal_multiply_result(MonoDecimal * left, MonoDecimal * right, MonoDecimal * result)
708 scale = left->u.u.scale + right->u.u.scale;
710 if ((left->Hi32 | left->v.v.Mid32 | right->Hi32 | right->v.v.Mid32) == 0) {
711 // Upper 64 bits are zero.
713 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
714 if (scale > DEC_SCALE_MAX)
716 // Result scale is too big. Divide result by power of 10 to reduce it.
717 // If the amount to divide by is > 19 the result is guaranteed
718 // less than 1/2. [max value in 64 bits = 1.84E19]
720 scale -= DEC_SCALE_MAX;
723 DECIMAL_SETZERO(*result);
724 return MONO_DECIMAL_OK;
727 if (scale > POWER10_MAX) {
728 // Divide by 1E10 first, to get the power down to a 32-bit quantity.
729 // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
730 // then multiply the next divisor by 4 (which will be a max of 4E9).
732 rem_lo = FullDiv64By32(&tmp.int64, ten_to_ten_div_4);
733 pwr = power10[scale - 10] << 2;
735 pwr = power10[scale];
739 // Power to divide by fits in 32 bits.
741 rem_hi = FullDiv64By32(&tmp.int64, pwr);
743 // Round result. See if remainder >= 1/2 of divisor.
744 // Divisor is a power of 10, so it is always even.
747 if (rem_hi >= pwr && (rem_hi > pwr || (rem_lo | (tmp.u.Lo & 1))))
750 scale = DEC_SCALE_MAX;
752 DECIMAL_LO32(*result) = tmp.u.Lo;
753 DECIMAL_MID32(*result) = tmp.u.Hi;
754 DECIMAL_HI32(*result) = 0;
756 // At least one operand has bits set in the upper 64 bits.
758 // Compute and accumulate the 9 partial products into a
759 // 192-bit (24-byte) result.
761 // [l-h][l-m][l-l] left high, middle, low
762 // x [r-h][r-m][r-l] right high, middle, low
763 // ------------------------------
765 // [0-h][0-l] l-l * r-l
766 // [1ah][1al] l-l * r-m
767 // [1bh][1bl] l-m * r-l
768 // [2ah][2al] l-m * r-m
769 // [2bh][2bl] l-l * r-h
770 // [2ch][2cl] l-h * r-l
771 // [3ah][3al] l-m * r-h
772 // [3bh][3bl] l-h * r-m
773 // [4-h][4-l] l-h * r-h
774 // ------------------------------
775 // [p-5][p-4][p-3][p-2][p-1][p-0] prod[] array
777 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
780 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Mid32) + tmp.u.Hi;
782 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Lo32);
783 tmp.int64 += tmp2.int64; // this could generate carry
785 if (tmp.int64 < tmp2.int64) // detect carry
789 tmp2.u.Lo = tmp.u.Hi;
791 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Mid32) + tmp2.int64;
793 if (left->Hi32 | right->Hi32) {
794 // Highest 32 bits is non-zero. Calculate 5 more partial products.
796 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->Hi32);
797 tmp.int64 += tmp2.int64; // this could generate carry
798 if (tmp.int64 < tmp2.int64) // detect carry
803 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Lo32);
804 tmp.int64 += tmp2.int64; // this could generate carry
806 if (tmp.int64 < tmp2.int64) // detect carry
808 tmp3.u.Lo = tmp.u.Hi;
810 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->Hi32);
811 tmp.int64 += tmp3.int64; // this could generate carry
812 if (tmp.int64 < tmp3.int64) // detect carry
817 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Mid32);
818 tmp.int64 += tmp2.int64; // this could generate carry
820 if (tmp.int64 < tmp2.int64) // detect carry
822 tmp3.u.Lo = tmp.u.Hi;
824 tmp.int64 = UInt32x32To64(left->Hi32, right->Hi32) + tmp3.int64;
836 // Check for leading zero uint32_ts on the product
838 while (prod[hi_prod] == 0) {
844 scale = ScaleResult(prod, hi_prod, scale);
846 return MONO_DECIMAL_OVERFLOW;
848 result->v.v.Lo32 = prod[0];
849 result->v.v.Mid32 = prod[1];
850 result->Hi32 = prod[2];
853 result->u.u.sign = right->u.u.sign ^ left->u.u.sign;
854 result->u.u.scale = (char)scale;
855 return MONO_DECIMAL_OK;
858 // Addition and subtraction
859 static MonoDecimalStatus
860 DecAddSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result, int8_t sign)
870 MonoDecimal *pdecTmp;
872 sign ^= (right->u.u.sign ^ left->u.u.sign) & DECIMAL_NEG;
874 if (right->u.u.scale == left->u.u.scale) {
875 // Scale factors are equal, no alignment necessary.
877 decRes.u.signscale = left->u.signscale;
881 // Signs differ - subtract
883 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right));
884 DECIMAL_HI32(decRes) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
888 if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*left)) {
890 if (decRes.Hi32 >= left->Hi32)
892 } else if (decRes.Hi32 > left->Hi32) {
893 // Got negative result. Flip its sign.
896 DECIMAL_LO64_SET(decRes, -(uint64_t)DECIMAL_LO64_GET(decRes));
897 decRes.Hi32 = ~decRes.Hi32;
898 if (DECIMAL_LO64_GET(decRes) == 0)
900 decRes.u.u.sign ^= DECIMAL_NEG;
904 // Signs are the same - add
906 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right));
907 decRes.Hi32 = left->Hi32 + right->Hi32;
911 if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*left)) {
913 if (decRes.Hi32 <= left->Hi32)
915 } else if (decRes.Hi32 < left->Hi32) {
917 // The addition carried above 96 bits. Divide the result by 10,
918 // dropping the scale factor.
920 if (decRes.u.u.scale == 0)
921 return MONO_DECIMAL_OVERFLOW;
924 tmp.u.Lo = decRes.Hi32;
926 tmp.int64 = DivMod64by32(tmp.int64, 10);
927 decRes.Hi32 = tmp.u.Lo;
929 tmp.u.Lo = decRes.v.v.Mid32;
930 tmp.int64 = DivMod64by32(tmp.int64, 10);
931 decRes.v.v.Mid32 = tmp.u.Lo;
933 tmp.u.Lo = decRes.v.v.Lo32;
934 tmp.int64 = DivMod64by32(tmp.int64, 10);
935 decRes.v.v.Lo32 = tmp.u.Lo;
937 // See if we need to round up.
939 if (tmp.u.Hi >= 5 && (tmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
940 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
941 if (DECIMAL_LO64_GET(decRes) == 0)
948 // Scale factors are not equal. Assume that a larger scale
949 // factor (more decimal places) is likely to mean that number
950 // is smaller. Start by guessing that the right operand has
951 // the larger scale factor. The result will have the larger
954 decRes.u.u.scale = right->u.u.scale; // scale factor of "smaller"
955 decRes.u.u.sign = left->u.u.sign; // but sign of "larger"
956 scale = decRes.u.u.scale - left->u.u.scale;
959 // Guessed scale factor wrong. Swap operands.
962 decRes.u.u.scale = left->u.u.scale;
963 decRes.u.u.sign ^= sign;
969 // *left will need to be multiplied by 10^scale so
970 // it will have the same scale as *right. We could be
971 // extending it to up to 192 bits of precision.
973 if (scale <= POWER10_MAX) {
974 // Scaling won't make it larger than 4 uint32_ts
976 pwr = power10[scale];
977 DECIMAL_LO64_SET(decTmp, UInt32x32To64(left->v.v.Lo32, pwr));
978 tmp.int64 = UInt32x32To64(left->v.v.Mid32, pwr);
979 tmp.int64 += decTmp.v.v.Mid32;
980 decTmp.v.v.Mid32 = tmp.u.Lo;
981 decTmp.Hi32 = tmp.u.Hi;
982 tmp.int64 = UInt32x32To64(left->Hi32, pwr);
983 tmp.int64 += decTmp.Hi32;
985 // Result fits in 96 bits. Use standard aligned add.
987 decTmp.Hi32 = tmp.u.Lo;
991 num[0] = decTmp.v.v.Lo32;
992 num[1] = decTmp.v.v.Mid32;
998 // Have to scale by a bunch. Move the number to a buffer
999 // where it has room to grow as it's scaled.
1001 num[0] = left->v.v.Lo32;
1002 num[1] = left->v.v.Mid32;
1003 num[2] = left->Hi32;
1006 // Scan for zeros in the upper words.
1013 // Left arg is zero, return right.
1015 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*right));
1016 decRes.Hi32 = right->Hi32;
1017 decRes.u.u.sign ^= sign;
1023 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
1024 // with index of highest non-zero uint32_t.
1026 for (; scale > 0; scale -= POWER10_MAX) {
1027 if (scale > POWER10_MAX)
1030 pwr = power10[scale];
1033 for (cur = 0; cur <= hi_prod; cur++) {
1034 tmp.int64 = UInt32x32To64(num[cur], pwr) + tmp.u.Hi;
1035 num[cur] = tmp.u.Lo;
1039 // We're extending the result by another uint32_t.
1040 num[++hi_prod] = tmp.u.Hi;
1044 // Scaling complete, do the add. Could be subtract if signs differ.
1050 // Signs differ, subtract.
1052 DECIMAL_LO64_SET(decRes, tmp.int64 - DECIMAL_LO64_GET(*right));
1053 decRes.Hi32 = num[2] - right->Hi32;
1057 if (DECIMAL_LO64_GET(decRes) > tmp.int64) {
1059 if (decRes.Hi32 >= num[2])
1062 else if (decRes.Hi32 > num[2]) {
1064 // If num has more than 96 bits of precision, then we need to
1065 // carry the subtraction into the higher bits. If it doesn't,
1066 // then we subtracted in the wrong order and have to flip the
1067 // sign of the result.
1073 while(num[cur++]-- == 0);
1074 if (num[hi_prod] == 0)
1079 // Signs the same, add.
1081 DECIMAL_LO64_SET(decRes, tmp.int64 + DECIMAL_LO64_GET(*right));
1082 decRes.Hi32 = num[2] + right->Hi32;
1086 if (DECIMAL_LO64_GET(decRes) < tmp.int64) {
1088 if (decRes.Hi32 <= num[2])
1091 else if (decRes.Hi32 < num[2]) {
1093 // Had a carry above 96 bits.
1097 if (hi_prod < cur) {
1102 }while (++num[cur++] == 0);
1107 num[0] = decRes.v.v.Lo32;
1108 num[1] = decRes.v.v.Mid32;
1109 num[2] = decRes.Hi32;
1110 decRes.u.u.scale = ScaleResult(num, hi_prod, decRes.u.u.scale);
1111 if (decRes.u.u.scale == (uint8_t) -1)
1112 return MONO_DECIMAL_OVERFLOW;
1114 decRes.v.v.Lo32 = num[0];
1115 decRes.v.v.Mid32 = num[1];
1116 decRes.Hi32 = num[2];
1121 COPYDEC(*result, decRes);
1122 // Odd, the Microsoft code does not set result->reserved to zero on this case
1123 return MONO_DECIMAL_OK;
1127 static MonoDecimalStatus G_GNUC_UNUSED
1128 mono_decimal_add(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1130 return DecAddSub (left, right, result, 0);
1133 // Decimal subtraction
1134 static MonoDecimalStatus G_GNUC_UNUSED
1135 mono_decimal_sub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1137 return DecAddSub (left, right, result, DECIMAL_NEG);
1144 * num - Pointer to 96-bit number as array of uint32_ts, least-sig first
1145 * pwr - Scale factor to multiply by
1148 * Multiply the two numbers. The low 96 bits of the result overwrite
1149 * the input. The last 32 bits of the product are the return value.
1152 * Returns highest 32 bits of product.
1159 IncreaseScale(uint32_t *num, uint32_t pwr)
1163 sdlTmp.int64 = UInt32x32To64(num[0], pwr);
1164 num[0] = sdlTmp.u.Lo;
1165 sdlTmp.int64 = UInt32x32To64(num[1], pwr) + sdlTmp.u.Hi;
1166 num[1] = sdlTmp.u.Lo;
1167 sdlTmp.int64 = UInt32x32To64(num[2], pwr) + sdlTmp.u.Hi;
1168 num[2] = sdlTmp.u.Lo;
1176 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
1177 * sdlDen - 64-bit divisor.
1180 * Do partial divide, yielding 32-bit result and 64-bit remainder.
1181 * Divisor must be larger than upper 64 bits of dividend.
1184 * Remainder overwrites lower 64-bits of dividend.
1192 Div96By64(uint32_t *num, SPLIT64 den)
1198 sdlNum.u.Lo = num[0];
1200 if (num[2] >= den.u.Hi) {
1201 // Divide would overflow. Assume a quotient of 2^32, and set
1202 // up remainder accordingly. Then jump to loop which reduces
1205 sdlNum.u.Hi = num[1] - den.u.Lo;
1210 // Hardware divide won't overflow
1212 if (num[2] == 0 && num[1] < den.u.Hi)
1213 // Result is zero. Entire dividend is remainder.
1217 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1221 quo.int64 = DivMod64by32(quo.int64, den.u.Hi);
1222 sdlNum.u.Hi = quo.u.Hi; // remainder
1224 // Compute full remainder, rem = dividend - (quo * divisor).
1226 prod.int64 = UInt32x32To64(quo.u.Lo, den.u.Lo); // quo * lo divisor
1227 sdlNum.int64 -= prod.int64;
1229 if (sdlNum.int64 > ~prod.int64) {
1231 // Remainder went negative. Add divisor back in until it's positive,
1232 // a max of 2 times.
1236 sdlNum.int64 += den.int64;
1237 }while (sdlNum.int64 >= den.int64);
1240 num[0] = sdlNum.u.Lo;
1241 num[1] = sdlNum.u.Hi;
1249 * rgulNum - Pointer to 128-bit dividend as array of uint32_ts, least-sig first
1250 * den - Pointer to 96-bit divisor.
1253 * Do partial divide, yielding 32-bit result and 96-bit remainder.
1254 * Top divisor uint32_t must be larger than top dividend uint32_t. This is
1255 * assured in the initial call because the divisor is normalized
1256 * and the dividend can't be. In subsequent calls, the remainder
1257 * is multiplied by 10^9 (max), so it can be no more than 1/4 of
1258 * the divisor which is effectively multiplied by 2^32 (4 * 10^9).
1261 * Remainder overwrites lower 96-bits of dividend.
1267 ***********************************************************************/
1270 Div128By96(uint32_t *num, uint32_t *den)
1277 sdlNum.u.Lo = num[0];
1278 sdlNum.u.Hi = num[1];
1280 if (num[3] == 0 && num[2] < den[2]){
1281 // Result is zero. Entire dividend is remainder.
1286 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1288 sdlQuo.u.Lo = num[2];
1289 sdlQuo.u.Hi = num[3];
1290 sdlQuo.int64 = DivMod64by32(sdlQuo.int64, den[2]);
1292 // Compute full remainder, rem = dividend - (quo * divisor).
1294 sdlProd1.int64 = UInt32x32To64(sdlQuo.u.Lo, den[0]); // quo * lo divisor
1295 sdlProd2.int64 = UInt32x32To64(sdlQuo.u.Lo, den[1]); // quo * mid divisor
1296 sdlProd2.int64 += sdlProd1.u.Hi;
1297 sdlProd1.u.Hi = sdlProd2.u.Lo;
1299 sdlNum.int64 -= sdlProd1.int64;
1300 num[2] = sdlQuo.u.Hi - sdlProd2.u.Hi; // sdlQuo.Hi is remainder
1302 // Propagate carries
1304 if (sdlNum.int64 > ~sdlProd1.int64) {
1306 if (num[2] >= ~sdlProd2.u.Hi)
1308 } else if (num[2] > ~sdlProd2.u.Hi) {
1310 // Remainder went negative. Add divisor back in until it's positive,
1311 // a max of 2 times.
1313 sdlProd1.u.Lo = den[0];
1314 sdlProd1.u.Hi = den[1];
1318 sdlNum.int64 += sdlProd1.int64;
1321 if (sdlNum.int64 < sdlProd1.int64) {
1322 // Detected carry. Check for carry out of top
1323 // before adding it in.
1325 if (num[2]++ < den[2])
1328 if (num[2] < den[2])
1329 break; // detected carry
1333 num[0] = sdlNum.u.Lo;
1334 num[1] = sdlNum.u.Hi;
1338 // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer
1339 // Returns FALSE if there is an overflow
1341 Add32To96(uint32_t *num, uint32_t value)
1344 if (num[0] < value) {
1345 if (++num[1] == 0) {
1346 if (++num[2] == 0) {
1355 OverflowUnscale (uint32_t *quo, gboolean remainder)
1359 // We have overflown, so load the high bit with a one.
1361 sdlTmp.u.Lo = quo[2];
1362 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1363 quo[2] = sdlTmp.u.Lo;
1364 sdlTmp.u.Lo = quo[1];
1365 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1366 quo[1] = sdlTmp.u.Lo;
1367 sdlTmp.u.Lo = quo[0];
1368 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1369 quo[0] = sdlTmp.u.Lo;
1370 // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up
1371 if ((sdlTmp.u.Hi > 5) || ((sdlTmp.u.Hi == 5) && ( remainder || (quo[0] & 1)))) {
1376 // mono_decimal_divide - Decimal divide
1377 static MonoDecimalStatus G_GNUC_UNUSED
1378 mono_decimal_divide_result(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1381 uint32_t quoSave[3];
1383 uint32_t divisor[3];
1392 scale = left->u.u.scale - right->u.u.scale;
1393 divisor[0] = right->v.v.Lo32;
1394 divisor[1] = right->v.v.Mid32;
1395 divisor[2] = right->Hi32;
1397 if (divisor[1] == 0 && divisor[2] == 0) {
1398 // Divisor is only 32 bits. Easy divide.
1400 if (divisor[0] == 0)
1401 return MONO_DECIMAL_DIVBYZERO;
1403 quo[0] = left->v.v.Lo32;
1404 quo[1] = left->v.v.Mid32;
1405 quo[2] = left->Hi32;
1406 rem[0] = Div96By32(quo, divisor[0]);
1411 cur_scale = min(9, -scale);
1417 // We have computed a quotient based on the natural scale
1418 // ( <dividend scale> - <divisor scale> ). We have a non-zero
1419 // remainder, so now we should increase the scale if possible to
1420 // include more quotient bits.
1422 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
1423 // computing more quotient bits as long as the remainder stays
1424 // non-zero. If scaling by that much would cause overflow, we'll
1425 // drop out of the loop and scale by as much as we can.
1427 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
1428 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
1429 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
1430 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
1431 // is the largest value in quo[1] (when quo[2] == 4) that is
1432 // assured not to overflow.
1434 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1435 if (cur_scale == 0) {
1436 // No more scaling to be done, but remainder is non-zero.
1440 if (utmp < rem[0] || (utmp >= divisor[0] &&
1441 (utmp > divisor[0] || (quo[0] & 1)))) {
1450 if (cur_scale == -1)
1451 return MONO_DECIMAL_OVERFLOW;
1454 pwr = power10[cur_scale];
1457 if (IncreaseScale(quo, pwr) != 0)
1458 return MONO_DECIMAL_OVERFLOW;
1460 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
1461 rem[0] = sdlTmp.u.Hi;
1463 quo[0] += sdlTmp.u.Lo;
1464 if (quo[0] < sdlTmp.u.Lo) {
1471 // Divisor has bits set in the upper 64 bits.
1473 // Divisor must be fully normalized (shifted so bit 31 of the most
1474 // significant uint32_t is 1). Locate the MSB so we know how much to
1475 // normalize by. The dividend will be shifted by the same amount so
1476 // the quotient is not changed.
1478 if (divisor[2] == 0)
1484 if (!(utmp & 0xFFFF0000)) {
1488 if (!(utmp & 0xFF000000)) {
1492 if (!(utmp & 0xF0000000)) {
1496 if (!(utmp & 0xC0000000)) {
1500 if (!(utmp & 0x80000000)) {
1505 // Shift both dividend and divisor left by cur_scale.
1507 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
1508 rem[0] = sdlTmp.u.Lo;
1509 rem[1] = sdlTmp.u.Hi;
1510 sdlTmp.u.Lo = left->v.v.Mid32;
1511 sdlTmp.u.Hi = left->Hi32;
1512 sdlTmp.int64 <<= cur_scale;
1513 rem[2] = sdlTmp.u.Hi;
1514 rem[3] = (left->Hi32 >> (31 - cur_scale)) >> 1;
1516 sdlDivisor.u.Lo = divisor[0];
1517 sdlDivisor.u.Hi = divisor[1];
1518 sdlDivisor.int64 <<= cur_scale;
1520 if (divisor[2] == 0) {
1521 // Have a 64-bit divisor in sdlDivisor. The remainder
1522 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
1524 sdlTmp.u.Lo = rem[2];
1525 sdlTmp.u.Hi = rem[3];
1528 quo[1] = Div96By64(&rem[1], sdlDivisor);
1529 quo[0] = Div96By64(rem, sdlDivisor);
1532 if ((rem[0] | rem[1]) == 0) {
1534 cur_scale = min(9, -scale);
1540 // Remainder is non-zero. Scale up quotient and remainder by
1541 // powers of 10 so we can compute more significant bits.
1543 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1544 if (cur_scale == 0) {
1545 // No more scaling to be done, but remainder is non-zero.
1548 sdlTmp.u.Lo = rem[0];
1549 sdlTmp.u.Hi = rem[1];
1550 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
1551 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
1556 if (cur_scale == -1)
1557 return MONO_DECIMAL_OVERFLOW;
1560 pwr = power10[cur_scale];
1563 if (IncreaseScale(quo, pwr) != 0)
1564 return MONO_DECIMAL_OVERFLOW;
1566 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
1567 IncreaseScale(rem, pwr);
1568 utmp = Div96By64(rem, sdlDivisor);
1577 // Have a 96-bit divisor in divisor[].
1579 // Start by finishing the shift left by cur_scale.
1581 sdlTmp.u.Lo = divisor[1];
1582 sdlTmp.u.Hi = divisor[2];
1583 sdlTmp.int64 <<= cur_scale;
1584 divisor[0] = sdlDivisor.u.Lo;
1585 divisor[1] = sdlDivisor.u.Hi;
1586 divisor[2] = sdlTmp.u.Hi;
1588 // The remainder (currently 96 bits spread over 4 uint32_ts)
1589 // will be < divisor.
1593 quo[0] = Div128By96(rem, divisor);
1596 if ((rem[0] | rem[1] | rem[2]) == 0) {
1598 cur_scale = min(9, -scale);
1604 // Remainder is non-zero. Scale up quotient and remainder by
1605 // powers of 10 so we can compute more significant bits.
1607 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1608 if (cur_scale == 0) {
1609 // No more scaling to be done, but remainder is non-zero.
1612 if (rem[2] >= 0x80000000)
1615 utmp = rem[0] > 0x80000000;
1616 utmp1 = rem[1] > 0x80000000;
1618 rem[1] = (rem[1] << 1) + utmp;
1619 rem[2] = (rem[2] << 1) + utmp1;
1621 if ((rem[2] > divisor[2] || rem[2] == divisor[2]) &&
1622 ((rem[1] > divisor[1] || rem[1] == divisor[1]) &&
1623 ((rem[0] > divisor[0] || rem[0] == divisor[0]) &&
1629 if (cur_scale == -1)
1630 return MONO_DECIMAL_OVERFLOW;
1633 pwr = power10[cur_scale];
1636 if (IncreaseScale(quo, pwr) != 0)
1637 return MONO_DECIMAL_OVERFLOW;
1639 rem[3] = IncreaseScale(rem, pwr);
1640 utmp = Div128By96(rem, divisor);
1650 // No more remainder. Try extracting any extra powers of 10 we may have
1651 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
1652 // If a division by one of these powers returns a zero remainder, then
1653 // we keep the quotient. If the remainder is not zero, then we restore
1654 // the previous value.
1656 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
1657 // we can extract. We use this as a quick test on whether to try a
1660 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
1661 quoSave[0] = quo[0];
1662 quoSave[1] = quo[1];
1663 quoSave[2] = quo[2];
1665 if (Div96By32(quoSave, 100000000) == 0) {
1666 quo[0] = quoSave[0];
1667 quo[1] = quoSave[1];
1668 quo[2] = quoSave[2];
1675 if ((quo[0] & 0xF) == 0 && scale >= 4) {
1676 quoSave[0] = quo[0];
1677 quoSave[1] = quo[1];
1678 quoSave[2] = quo[2];
1680 if (Div96By32(quoSave, 10000) == 0) {
1681 quo[0] = quoSave[0];
1682 quo[1] = quoSave[1];
1683 quo[2] = quoSave[2];
1688 if ((quo[0] & 3) == 0 && scale >= 2) {
1689 quoSave[0] = quo[0];
1690 quoSave[1] = quo[1];
1691 quoSave[2] = quo[2];
1693 if (Div96By32(quoSave, 100) == 0) {
1694 quo[0] = quoSave[0];
1695 quo[1] = quoSave[1];
1696 quo[2] = quoSave[2];
1701 if ((quo[0] & 1) == 0 && scale >= 1) {
1702 quoSave[0] = quo[0];
1703 quoSave[1] = quo[1];
1704 quoSave[2] = quo[2];
1706 if (Div96By32(quoSave, 10) == 0) {
1707 quo[0] = quoSave[0];
1708 quo[1] = quoSave[1];
1709 quo[2] = quoSave[2];
1714 result->Hi32 = quo[2];
1715 result->v.v.Mid32 = quo[1];
1716 result->v.v.Lo32 = quo[0];
1717 result->u.u.scale = scale;
1718 result->u.u.sign = left->u.u.sign ^ right->u.u.sign;
1719 return MONO_DECIMAL_OK;
1722 // mono_decimal_absolute - Decimal Absolute Value
1723 static void G_GNUC_UNUSED
1724 mono_decimal_absolute (MonoDecimal *pdecOprd, MonoDecimal *result)
1726 COPYDEC(*result, *pdecOprd);
1727 result->u.u.sign &= ~DECIMAL_NEG;
1728 // Microsoft does not set reserved here
1731 // mono_decimal_fix - Decimal Fix (chop to integer)
1733 mono_decimal_fix (MonoDecimal *pdecOprd, MonoDecimal *result)
1735 DecFixInt(result, pdecOprd);
1738 // mono_decimal_round_to_int - Decimal Int (round down to integer)
1740 mono_decimal_round_to_int (MonoDecimal *pdecOprd, MonoDecimal *result)
1742 if (DecFixInt(result, pdecOprd) != 0 && (result->u.u.sign & DECIMAL_NEG)) {
1743 // We have chopped off a non-zero amount from a negative value. Since
1744 // we round toward -infinity, we must increase the integer result by
1745 // 1 to make it more negative. This will never overflow because
1746 // in order to have a remainder, we must have had a non-zero scale factor.
1747 // Our scale factor is back to zero now.
1749 DECIMAL_LO64_SET(*result, DECIMAL_LO64_GET(*result) + 1);
1750 if (DECIMAL_LO64_GET(*result) == 0)
1755 // mono_decimal_negate - Decimal Negate
1756 static void G_GNUC_UNUSED
1757 mono_decimal_negate (MonoDecimal *pdecOprd, MonoDecimal *result)
1759 COPYDEC(*result, *pdecOprd);
1760 // Microsoft does not set result->reserved to zero on this case.
1761 result->u.u.sign ^= DECIMAL_NEG;
1765 // Returns: MONO_DECIMAL_INVALID_ARGUMENT, MONO_DECIMAL_OK
1767 static MonoDecimalStatus
1768 mono_decimal_round_result(MonoDecimal *input, int cDecimals, MonoDecimal *result)
1777 return MONO_DECIMAL_INVALID_ARGUMENT;
1779 scale = input->u.u.scale - cDecimals;
1781 num[0] = input->v.v.Lo32;
1782 num[1] = input->v.v.Mid32;
1783 num[2] = input->Hi32;
1784 result->u.u.sign = input->u.u.sign;
1789 if (scale > POWER10_MAX)
1792 pwr = power10[scale];
1794 rem = Div96By32(num, pwr);
1798 // Now round. rem has last remainder, sticky has sticky bits.
1799 // To do IEEE rounding, we add LSB of result to sticky bits so
1800 // either causes round up if remainder * 2 == last divisor.
1802 sticky |= num[0] & 1;
1803 rem = (rem << 1) + (sticky != 0);
1810 result->v.v.Lo32 = num[0];
1811 result->v.v.Mid32 = num[1];
1812 result->Hi32 = num[2];
1813 result->u.u.scale = cDecimals;
1814 return MONO_DECIMAL_OK;
1817 COPYDEC(*result, *input);
1818 // Odd, the Microsoft source does not set the result->reserved to zero here.
1819 return MONO_DECIMAL_OK;
1823 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1824 static MonoDecimalStatus
1825 mono_decimal_from_float (float input, MonoDecimal* result)
1827 int exp; // number of bits to left of binary point
1833 int lmax, cur; // temps used during scale reduction
1835 // The most we can scale by is 10^28, which is just slightly more
1836 // than 2^93. So a float with an exponent of -94 could just
1837 // barely reach 0.5, but smaller exponents will always round to zero.
1839 if ((exp = ((SingleStructure *)&input)->exp - SNGBIAS) < -94 ) {
1840 DECIMAL_SETZERO(*result);
1841 return MONO_DECIMAL_OK;
1845 return MONO_DECIMAL_OVERFLOW;
1847 // Round the input to a 7-digit integer. The R4 format has
1848 // only 7 digits of precision, and we want to keep garbage digits
1849 // out of the Decimal were making.
1851 // Calculate max power of 10 input value could have by multiplying
1852 // the exponent by log10(2). Using scaled integer multiplcation,
1853 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1856 power = 6 - ((exp * 19728) >> 16);
1859 // We have less than 7 digits, scale input up.
1864 dbl = dbl * double_power10[power];
1866 if (power != -1 || dbl >= 1E7)
1867 dbl = dbl / fnDblPower10(-power);
1869 power = 0; // didn't scale it
1872 g_assert (dbl < 1E7);
1873 if (dbl < 1E6 && power < DECMAX) {
1876 g_assert(dbl >= 1E6);
1881 mant = (int32_t)dbl;
1882 dbl -= (double)mant; // difference between input & integer
1883 if ( dbl > 0.5 || (dbl == 0.5 && (mant & 1)))
1887 DECIMAL_SETZERO(*result);
1888 return MONO_DECIMAL_OK;
1892 // Add -power factors of 10, -power <= (29 - 7) = 22.
1896 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power]);
1898 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1899 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1900 DECIMAL_HI32(*result) = 0;
1902 // Have a big power of 10.
1905 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 18]);
1906 sdlLo.int64 = UInt64x64To128(sdlLo, ten_to_eighteen, &sdlHi.int64);
1908 if (sdlHi.u.Hi != 0)
1909 return MONO_DECIMAL_OVERFLOW;
1912 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 9]);
1913 sdlHi.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Hi);
1914 sdlLo.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Lo);
1915 sdlHi.int64 += sdlLo.u.Hi;
1916 sdlLo.u.Hi = sdlHi.u.Lo;
1917 sdlHi.u.Lo = sdlHi.u.Hi;
1919 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1920 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1921 DECIMAL_HI32(*result) = sdlHi.u.Lo;
1923 DECIMAL_SCALE(*result) = 0;
1925 // Factor out powers of 10 to reduce the scale, if possible.
1926 // The maximum number we could factor out would be 6. This
1927 // comes from the fact we have a 7-digit number, and the
1928 // MSD must be non-zero -- but the lower 6 digits could be
1929 // zero. Note also the scale factor is never negative, so
1930 // we can't scale by any more than the power we used to
1933 // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
1935 lmax = min(power, 6);
1937 // lmax is the largest power of 10 to try, lmax <= 6.
1938 // We'll try powers 4, 2, and 1 unless they're too big.
1940 for (cur = 4; cur > 0; cur >>= 1)
1945 sdlLo.int64 = DivMod32by32(mant, (uint32_t)long_power10[cur]);
1947 if (sdlLo.u.Hi == 0) {
1953 DECIMAL_LO32(*result) = mant;
1954 DECIMAL_MID32(*result) = 0;
1955 DECIMAL_HI32(*result) = 0;
1956 DECIMAL_SCALE(*result) = power;
1959 DECIMAL_SIGN(*result) = (char)((SingleStructure *)&input)->sign << 7;
1960 return MONO_DECIMAL_OK;
1963 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1964 static MonoDecimalStatus
1965 mono_decimal_from_double (double input, MonoDecimal *result)
1967 int exp; // number of bits to left of binary point
1968 int power; // power-of-10 scale factor
1972 int lmax, cur; // temps used during scale reduction
1977 // The most we can scale by is 10^28, which is just slightly more
1978 // than 2^93. So a float with an exponent of -94 could just
1979 // barely reach 0.5, but smaller exponents will always round to zero.
1981 if ((exp = ((DoubleStructure *)&input)->u.exp - DBLBIAS) < -94) {
1982 DECIMAL_SETZERO(*result);
1983 return MONO_DECIMAL_OK;
1987 return MONO_DECIMAL_OVERFLOW;
1989 // Round the input to a 15-digit integer. The R8 format has
1990 // only 15 digits of precision, and we want to keep garbage digits
1991 // out of the Decimal were making.
1993 // Calculate max power of 10 input value could have by multiplying
1994 // the exponent by log10(2). Using scaled integer multiplcation,
1995 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1998 power = 14 - ((exp * 19728) >> 16);
2001 // We have less than 15 digits, scale input up.
2006 dbl = dbl * double_power10[power];
2008 if (power != -1 || dbl >= 1E15)
2009 dbl = dbl / fnDblPower10(-power);
2011 power = 0; // didn't scale it
2014 g_assert (dbl < 1E15);
2015 if (dbl < 1E14 && power < DECMAX) {
2018 g_assert(dbl >= 1E14);
2023 sdlMant.int64 = (int64_t)dbl;
2024 dbl -= (double)(int64_t)sdlMant.int64; // dif between input & integer
2025 if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)))
2028 if (sdlMant.int64 == 0) {
2029 DECIMAL_SETZERO(*result);
2030 return MONO_DECIMAL_OK;
2034 // Add -power factors of 10, -power <= (29 - 15) = 14.
2038 sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (uint32_t)long_power10[power]);
2039 sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (uint32_t)long_power10[power]);
2040 sdlMant.int64 += sdlLo.u.Hi;
2041 sdlLo.u.Hi = sdlMant.u.Lo;
2042 sdlMant.u.Lo = sdlMant.u.Hi;
2045 // Have a big power of 10.
2047 g_assert(power <= 14);
2048 sdlLo.int64 = UInt64x64To128(sdlMant, sdl_power10[power-10], &sdlMant.int64);
2050 if (sdlMant.u.Hi != 0)
2051 return MONO_DECIMAL_OVERFLOW;
2053 DECIMAL_LO32(*result) = sdlLo.u.Lo;
2054 DECIMAL_MID32(*result) = sdlLo.u.Hi;
2055 DECIMAL_HI32(*result) = sdlMant.u.Lo;
2056 DECIMAL_SCALE(*result) = 0;
2059 // Factor out powers of 10 to reduce the scale, if possible.
2060 // The maximum number we could factor out would be 14. This
2061 // comes from the fact we have a 15-digit number, and the
2062 // MSD must be non-zero -- but the lower 14 digits could be
2063 // zero. Note also the scale factor is never negative, so
2064 // we can't scale by any more than the power we used to
2067 // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
2069 lmax = min(power, 14);
2071 // lmax is the largest power of 10 to try, lmax <= 14.
2072 // We'll try powers 8, 4, 2, and 1 unless they're too big.
2074 for (cur = 8; cur > 0; cur >>= 1)
2079 pwr_cur = (uint32_t)long_power10[cur];
2081 if (sdlMant.u.Hi >= pwr_cur) {
2082 // Overflow if we try to divide in one step.
2084 sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, pwr_cur);
2086 sdlLo.u.Lo = sdlMant.u.Lo;
2087 sdlLo.int64 = DivMod64by32(sdlLo.int64, pwr_cur);
2091 sdlLo.int64 = DivMod64by32(sdlMant.int64, pwr_cur);
2094 if (sdlLo.u.Hi == 0) {
2096 sdlMant.u.Lo = sdlLo.u.Lo;
2102 DECIMAL_HI32(*result) = 0;
2103 DECIMAL_SCALE(*result) = power;
2104 DECIMAL_LO32(*result) = sdlMant.u.Lo;
2105 DECIMAL_MID32(*result) = sdlMant.u.Hi;
2108 DECIMAL_SIGN(*result) = (char)((DoubleStructure *)&input)->u.sign << 7;
2109 return MONO_DECIMAL_OK;
2112 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2113 static MonoDecimalStatus
2114 mono_decimal_to_double_result(MonoDecimal *input, double *result)
2119 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2120 return MONO_DECIMAL_INVALID_ARGUMENT;
2122 tmp.u.Lo = DECIMAL_LO32(*input);
2123 tmp.u.Hi = DECIMAL_MID32(*input);
2125 if ((int32_t)DECIMAL_MID32(*input) < 0)
2126 dbl = (ds2to64.dbl + (double)(int64_t)tmp.int64 +
2127 (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input)) ;
2129 dbl = ((double)(int64_t)tmp.int64 +
2130 (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input));
2132 if (DECIMAL_SIGN(*input))
2136 return MONO_DECIMAL_OK;
2139 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2140 static MonoDecimalStatus
2141 mono_decimal_to_float_result(MonoDecimal *input, float *result)
2145 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2146 return MONO_DECIMAL_INVALID_ARGUMENT;
2148 // Can't overflow; no errors possible.
2150 mono_decimal_to_double_result(input, &dbl);
2151 *result = (float)dbl;
2152 return MONO_DECIMAL_OK;
2156 DecShiftLeft(MonoDecimal* value)
2158 unsigned int c0 = DECIMAL_LO32(*value) & 0x80000000? 1: 0;
2159 unsigned int c1 = DECIMAL_MID32(*value) & 0x80000000? 1: 0;
2160 g_assert(value != NULL);
2162 DECIMAL_LO32(*value) <<= 1;
2163 DECIMAL_MID32(*value) = DECIMAL_MID32(*value) << 1 | c0;
2164 DECIMAL_HI32(*value) = DECIMAL_HI32(*value) << 1 | c1;
2168 D32AddCarry(uint32_t* value, uint32_t i)
2170 uint32_t v = *value;
2171 uint32_t sum = v + i;
2173 return sum < v || sum < i? 1: 0;
2177 DecAdd(MonoDecimal *value, MonoDecimal* d)
2179 g_assert(value != NULL && d != NULL);
2181 if (D32AddCarry(&DECIMAL_LO32(*value), DECIMAL_LO32(*d))) {
2182 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2183 D32AddCarry(&DECIMAL_HI32(*value), 1);
2186 if (D32AddCarry(&DECIMAL_MID32(*value), DECIMAL_MID32(*d))) {
2187 D32AddCarry(&DECIMAL_HI32(*value), 1);
2189 D32AddCarry(&DECIMAL_HI32(*value), DECIMAL_HI32(*d));
2193 DecMul10(MonoDecimal* value)
2195 MonoDecimal d = *value;
2196 g_assert (value != NULL);
2198 DecShiftLeft(value);
2199 DecShiftLeft(value);
2201 DecShiftLeft(value);
2205 DecAddInt32(MonoDecimal* value, unsigned int i)
2207 g_assert(value != NULL);
2209 if (D32AddCarry(&DECIMAL_LO32(*value), i)) {
2210 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2211 D32AddCarry(&DECIMAL_HI32(*value), 1);
2216 MonoDecimalCompareResult
2217 mono_decimal_compare (MonoDecimal *left, MonoDecimal *right)
2220 uint32_t right_sign;
2223 result.Hi32 = 0; // Just to shut up the compiler
2225 // First check signs and whether either are zero. If both are
2226 // non-zero and of the same sign, just use subtraction to compare.
2228 left_sign = left->v.v.Lo32 | left->v.v.Mid32 | left->Hi32;
2229 right_sign = right->v.v.Lo32 | right->v.v.Mid32 | right->Hi32;
2231 left_sign = (left->u.u.sign & DECIMAL_NEG) | 1;
2233 if (right_sign != 0)
2234 right_sign = (right->u.u.sign & DECIMAL_NEG) | 1;
2236 // left_sign & right_sign have values 1, 0, or 0x81 depending on if the left/right
2237 // operand is +, 0, or -.
2239 if (left_sign == right_sign) {
2240 if (left_sign == 0) // both are zero
2241 return MONO_DECIMAL_CMP_EQ; // return equal
2243 DecAddSub(left, right, &result, DECIMAL_NEG);
2244 if (DECIMAL_LO64_GET(result) == 0 && result.Hi32 == 0)
2245 return MONO_DECIMAL_CMP_EQ;
2246 if (result.u.u.sign & DECIMAL_NEG)
2247 return MONO_DECIMAL_CMP_LT;
2248 return MONO_DECIMAL_CMP_GT;
2252 // Signs are different. Use signed byte comparison
2254 if ((signed char)left_sign > (signed char)right_sign)
2255 return MONO_DECIMAL_CMP_GT;
2256 return MONO_DECIMAL_CMP_LT;
2260 mono_decimal_init_single (MonoDecimal *_this, float value)
2262 if (mono_decimal_from_float (value, _this) == MONO_DECIMAL_OVERFLOW) {
2263 mono_set_pending_exception (mono_get_exception_overflow ());
2266 _this->reserved = 0;
2270 mono_decimal_init_double (MonoDecimal *_this, double value)
2272 if (mono_decimal_from_double (value, _this) == MONO_DECIMAL_OVERFLOW) {
2273 mono_set_pending_exception (mono_get_exception_overflow ());
2276 _this->reserved = 0;
2280 mono_decimal_floor (MonoDecimal *d)
2284 mono_decimal_round_to_int(d, &decRes);
2286 // copy decRes into d
2287 COPYDEC(*d, decRes);
2293 mono_decimal_get_hash_code (MonoDecimal *d)
2297 if (mono_decimal_to_double_result(d, &dbl) != MONO_DECIMAL_OK)
2301 // Ensure 0 and -0 have the same hash code
2304 // conversion to double is lossy and produces rounding errors so we mask off the lowest 4 bits
2306 // For example these two numerically equal decimals with different internal representations produce
2307 // slightly different results when converted to double:
2309 // decimal a = new decimal(new int[] { 0x76969696, 0x2fdd49fa, 0x409783ff, 0x00160000 });
2310 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.176470588
2311 // decimal b = new decimal(new int[] { 0x3f0f0f0f, 0x1e62edcc, 0x06758d33, 0x00150000 });
2312 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.1764705882
2314 return ((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
2319 mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2)
2323 MonoDecimalStatus status = mono_decimal_multiply_result(d1, d2, &decRes);
2324 if (status != MONO_DECIMAL_OK) {
2325 mono_set_pending_exception (mono_get_exception_overflow ());
2329 COPYDEC(*d1, decRes);
2336 mono_decimal_round (MonoDecimal *d, int32_t decimals)
2340 // GC is only triggered for throwing, no need to protect result
2341 if (decimals < 0 || decimals > 28) {
2342 mono_set_pending_exception (mono_get_exception_argument_out_of_range ("d"));
2346 mono_decimal_round_result(d, decimals, &decRes);
2348 // copy decRes into d
2349 COPYDEC(*d, decRes);
2356 mono_decimal_tocurrency (MonoDecimal *decimal)
2362 mono_decimal_to_double (MonoDecimal d)
2364 double result = 0.0;
2365 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2366 mono_decimal_to_double_result(&d, &result);
2371 mono_decimal_to_int32 (MonoDecimal d)
2375 // The following can not return an error, it only returns INVALID_ARG if the decimals is < 0
2376 mono_decimal_round_result(&d, 0, &result);
2378 if (DECIMAL_SCALE(result) != 0) {
2380 mono_decimal_fix (&d, &result);
2383 if (DECIMAL_HI32(result) == 0 && DECIMAL_MID32(result) == 0) {
2384 int32_t i = DECIMAL_LO32(result);
2385 if ((int16_t)DECIMAL_SIGNSCALE(result) >= 0) {
2395 mono_set_pending_exception (mono_get_exception_overflow ());
2400 mono_decimal_to_float (MonoDecimal d)
2402 float result = 0.0f;
2403 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2404 mono_decimal_to_float_result(&d, &result);
2409 mono_decimal_truncate (MonoDecimal *d)
2413 mono_decimal_fix(d, &decRes);
2415 // copy decRes into d
2416 COPYDEC(*d, decRes);
2422 mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign)
2424 MonoDecimal result, decTmp;
2425 MonoDecimal *pdecTmp, *leftOriginal;
2426 uint32_t num[6], pwr;
2427 int scale, hi_prod, cur;
2430 g_assert(sign == 0 || sign == DECIMAL_NEG);
2432 leftOriginal = left;
2434 sign ^= (DECIMAL_SIGN(*right) ^ DECIMAL_SIGN(*left)) & DECIMAL_NEG;
2436 if (DECIMAL_SCALE(*right) == DECIMAL_SCALE(*left)) {
2437 // Scale factors are equal, no alignment necessary.
2439 DECIMAL_SIGNSCALE(result) = DECIMAL_SIGNSCALE(*left);
2443 // Signs differ - subtract
2445 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right)));
2446 DECIMAL_HI32(result) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
2450 if (DECIMAL_LO64_GET(result) > DECIMAL_LO64_GET(*left)) {
2451 DECIMAL_HI32(result)--;
2452 if (DECIMAL_HI32(result) >= DECIMAL_HI32(*left))
2454 } else if (DECIMAL_HI32(result) > DECIMAL_HI32(*left)) {
2455 // Got negative result. Flip its sign.
2458 DECIMAL_LO64_SET(result, -(int64_t)DECIMAL_LO64_GET(result));
2459 DECIMAL_HI32(result) = ~DECIMAL_HI32(result);
2460 if (DECIMAL_LO64_GET(result) == 0)
2461 DECIMAL_HI32(result)++;
2462 DECIMAL_SIGN(result) ^= DECIMAL_NEG;
2466 // Signs are the same - add
2468 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right)));
2469 DECIMAL_HI32(result) = DECIMAL_HI32(*left) + DECIMAL_HI32(*right);
2473 if (DECIMAL_LO64_GET(result) < DECIMAL_LO64_GET(*left)) {
2474 DECIMAL_HI32(result)++;
2475 if (DECIMAL_HI32(result) <= DECIMAL_HI32(*left))
2477 } else if (DECIMAL_HI32(result) < DECIMAL_HI32(*left)) {
2479 // The addition carried above 96 bits. Divide the result by 10,
2480 // dropping the scale factor.
2482 if (DECIMAL_SCALE(result) == 0) {
2483 mono_set_pending_exception (mono_get_exception_overflow ());
2486 DECIMAL_SCALE(result)--;
2488 sdlTmp.u.Lo = DECIMAL_HI32(result);
2490 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2491 DECIMAL_HI32(result) = sdlTmp.u.Lo;
2493 sdlTmp.u.Lo = DECIMAL_MID32(result);
2494 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2495 DECIMAL_MID32(result) = sdlTmp.u.Lo;
2497 sdlTmp.u.Lo = DECIMAL_LO32(result);
2498 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2499 DECIMAL_LO32(result) = sdlTmp.u.Lo;
2501 // See if we need to round up.
2503 if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (DECIMAL_LO32(result) & 1))) {
2504 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(result)+1);
2505 if (DECIMAL_LO64_GET(result) == 0)
2506 DECIMAL_HI32(result)++;
2511 // Scale factors are not equal. Assume that a larger scale
2512 // factor (more decimal places) is likely to mean that number
2513 // is smaller. Start by guessing that the right operand has
2514 // the larger scale factor. The result will have the larger
2517 DECIMAL_SCALE(result) = DECIMAL_SCALE(*right); // scale factor of "smaller"
2518 DECIMAL_SIGN(result) = DECIMAL_SIGN(*left); // but sign of "larger"
2519 scale = DECIMAL_SCALE(result)- DECIMAL_SCALE(*left);
2522 // Guessed scale factor wrong. Swap operands.
2525 DECIMAL_SCALE(result) = DECIMAL_SCALE(*left);
2526 DECIMAL_SIGN(result) ^= sign;
2532 // *left will need to be multiplied by 10^scale so
2533 // it will have the same scale as *right. We could be
2534 // extending it to up to 192 bits of precision.
2536 if (scale <= POWER10_MAX) {
2537 // Scaling won't make it larger than 4 uint32_ts
2539 pwr = power10[scale];
2540 DECIMAL_LO64_SET(decTmp, UInt32x32To64(DECIMAL_LO32(*left), pwr));
2541 sdlTmp.int64 = UInt32x32To64(DECIMAL_MID32(*left), pwr);
2542 sdlTmp.int64 += DECIMAL_MID32(decTmp);
2543 DECIMAL_MID32(decTmp) = sdlTmp.u.Lo;
2544 DECIMAL_HI32(decTmp) = sdlTmp.u.Hi;
2545 sdlTmp.int64 = UInt32x32To64(DECIMAL_HI32(*left), pwr);
2546 sdlTmp.int64 += DECIMAL_HI32(decTmp);
2547 if (sdlTmp.u.Hi == 0) {
2548 // Result fits in 96 bits. Use standard aligned add.
2550 DECIMAL_HI32(decTmp) = sdlTmp.u.Lo;
2554 num[0] = DECIMAL_LO32(decTmp);
2555 num[1] = DECIMAL_MID32(decTmp);
2556 num[2] = sdlTmp.u.Lo;
2557 num[3] = sdlTmp.u.Hi;
2560 // Have to scale by a bunch. Move the number to a buffer
2561 // where it has room to grow as it's scaled.
2563 num[0] = DECIMAL_LO32(*left);
2564 num[1] = DECIMAL_MID32(*left);
2565 num[2] = DECIMAL_HI32(*left);
2568 // Scan for zeros in the upper words.
2575 // Left arg is zero, return right.
2577 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(*right));
2578 DECIMAL_HI32(result) = DECIMAL_HI32(*right);
2579 DECIMAL_SIGN(result) ^= sign;
2585 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
2586 // with index of highest non-zero uint32_t.
2588 for (; scale > 0; scale -= POWER10_MAX) {
2589 if (scale > POWER10_MAX)
2592 pwr = power10[scale];
2595 for (cur = 0; cur <= hi_prod; cur++) {
2596 sdlTmp.int64 = UInt32x32To64(num[cur], pwr) + sdlTmp.u.Hi;
2597 num[cur] = sdlTmp.u.Lo;
2600 if (sdlTmp.u.Hi != 0)
2601 // We're extending the result by another uint32_t.
2602 num[++hi_prod] = sdlTmp.u.Hi;
2606 // Scaling complete, do the add. Could be subtract if signs differ.
2608 sdlTmp.u.Lo = num[0];
2609 sdlTmp.u.Hi = num[1];
2612 // Signs differ, subtract.
2614 DECIMAL_LO64_SET(result, (sdlTmp.int64 - DECIMAL_LO64_GET(*right)));
2615 DECIMAL_HI32(result) = num[2] - DECIMAL_HI32(*right);
2619 if (DECIMAL_LO64_GET(result) > sdlTmp.int64) {
2620 DECIMAL_HI32(result)--;
2621 if (DECIMAL_HI32(result) >= num[2])
2623 } else if (DECIMAL_HI32(result) > num[2]) {
2625 // If num has more than 96 bits of precision, then we need to
2626 // carry the subtraction into the higher bits. If it doesn't,
2627 // then we subtracted in the wrong order and have to flip the
2628 // sign of the result.
2634 while(num[cur++]-- == 0);
2635 if (num[hi_prod] == 0)
2639 // Signs the same, add.
2641 DECIMAL_LO64_SET(result, (sdlTmp.int64 + DECIMAL_LO64_GET(*right)));
2642 DECIMAL_HI32(result) = num[2] + DECIMAL_HI32(*right);
2646 if (DECIMAL_LO64_GET(result) < sdlTmp.int64) {
2647 DECIMAL_HI32(result)++;
2648 if (DECIMAL_HI32(result) <= num[2])
2650 } else if (DECIMAL_HI32(result) < num[2]) {
2652 // Had a carry above 96 bits.
2656 if (hi_prod < cur) {
2661 }while (++num[cur++] == 0);
2666 num[0] = DECIMAL_LO32(result);
2667 num[1] = DECIMAL_MID32(result);
2668 num[2] = DECIMAL_HI32(result);
2669 DECIMAL_SCALE(result) = (uint8_t)ScaleResult(num, hi_prod, DECIMAL_SCALE(result));
2670 if (DECIMAL_SCALE(result) == (uint8_t)-1) {
2671 mono_set_pending_exception (mono_get_exception_overflow ());
2675 DECIMAL_LO32(result) = num[0];
2676 DECIMAL_MID32(result) = num[1];
2677 DECIMAL_HI32(result) = num[2];
2682 left = leftOriginal;
2683 COPYDEC(*left, result);
2688 mono_decimal_divide (MonoDecimal *left, MonoDecimal *right)
2690 uint32_t quo[3], quo_save[3],rem[4], divisor[3];
2691 uint32_t pwr, tmp, tmp1;
2692 SPLIT64 sdlTmp, sdlDivisor;
2693 int scale, cur_scale;
2696 scale = DECIMAL_SCALE(*left) - DECIMAL_SCALE(*right);
2698 divisor[0] = DECIMAL_LO32(*right);
2699 divisor[1] = DECIMAL_MID32(*right);
2700 divisor[2] = DECIMAL_HI32(*right);
2702 if (divisor[1] == 0 && divisor[2] == 0) {
2703 // Divisor is only 32 bits. Easy divide.
2705 if (divisor[0] == 0) {
2706 mono_set_pending_exception (mono_get_exception_divide_by_zero ());
2710 quo[0] = DECIMAL_LO32(*left);
2711 quo[1] = DECIMAL_MID32(*left);
2712 quo[2] = DECIMAL_HI32(*left);
2713 rem[0] = Div96By32(quo, divisor[0]);
2718 cur_scale = min(9, -scale);
2723 // We need to unscale if and only if we have a non-zero remainder
2726 // We have computed a quotient based on the natural scale
2727 // ( <dividend scale> - <divisor scale> ). We have a non-zero
2728 // remainder, so now we should increase the scale if possible to
2729 // include more quotient bits.
2731 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
2732 // computing more quotient bits as long as the remainder stays
2733 // non-zero. If scaling by that much would cause overflow, we'll
2734 // drop out of the loop and scale by as much as we can.
2736 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
2737 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
2738 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
2739 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
2740 // is the largest value in quo[1] (when quo[2] == 4) that is
2741 // assured not to overflow.
2743 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2744 if (cur_scale == 0) {
2745 // No more scaling to be done, but remainder is non-zero.
2749 if (tmp < rem[0] || (tmp >= divisor[0] &&
2750 (tmp > divisor[0] || (quo[0] & 1)))) {
2752 if (!Add32To96(quo, 1)) {
2754 mono_set_pending_exception (mono_get_exception_overflow ());
2758 OverflowUnscale(quo, TRUE);
2765 if (cur_scale < 0) {
2766 mono_set_pending_exception (mono_get_exception_overflow ());
2771 pwr = power10[cur_scale];
2774 if (IncreaseScale(quo, pwr) != 0) {
2775 mono_set_pending_exception (mono_get_exception_overflow ());
2779 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
2780 rem[0] = sdlTmp.u.Hi;
2782 if (!Add32To96(quo, sdlTmp.u.Lo)) {
2784 mono_set_pending_exception (mono_get_exception_overflow ());
2788 OverflowUnscale(quo, (rem[0] != 0));
2793 // Divisor has bits set in the upper 64 bits.
2795 // Divisor must be fully normalized (shifted so bit 31 of the most
2796 // significant uint32_t is 1). Locate the MSB so we know how much to
2797 // normalize by. The dividend will be shifted by the same amount so
2798 // the quotient is not changed.
2800 if (divisor[2] == 0)
2806 if (!(tmp & 0xFFFF0000)) {
2810 if (!(tmp & 0xFF000000)) {
2814 if (!(tmp & 0xF0000000)) {
2818 if (!(tmp & 0xC0000000)) {
2822 if (!(tmp & 0x80000000)) {
2827 // Shift both dividend and divisor left by cur_scale.
2829 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
2830 rem[0] = sdlTmp.u.Lo;
2831 rem[1] = sdlTmp.u.Hi;
2832 sdlTmp.u.Lo = DECIMAL_MID32(*left);
2833 sdlTmp.u.Hi = DECIMAL_HI32(*left);
2834 sdlTmp.int64 <<= cur_scale;
2835 rem[2] = sdlTmp.u.Hi;
2836 rem[3] = (DECIMAL_HI32(*left) >> (31 - cur_scale)) >> 1;
2838 sdlDivisor.u.Lo = divisor[0];
2839 sdlDivisor.u.Hi = divisor[1];
2840 sdlDivisor.int64 <<= cur_scale;
2842 if (divisor[2] == 0) {
2843 // Have a 64-bit divisor in sdlDivisor. The remainder
2844 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
2846 sdlTmp.u.Lo = rem[2];
2847 sdlTmp.u.Hi = rem[3];
2850 quo[1] = Div96By64(&rem[1], sdlDivisor);
2851 quo[0] = Div96By64(rem, sdlDivisor);
2854 if ((rem[0] | rem[1]) == 0) {
2856 cur_scale = min(9, -scale);
2862 // We need to unscale if and only if we have a non-zero remainder
2865 // Remainder is non-zero. Scale up quotient and remainder by
2866 // powers of 10 so we can compute more significant bits.
2868 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2869 if (cur_scale == 0) {
2870 // No more scaling to be done, but remainder is non-zero.
2873 sdlTmp.u.Lo = rem[0];
2874 sdlTmp.u.Hi = rem[1];
2875 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
2876 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
2881 if (cur_scale < 0) {
2882 mono_set_pending_exception (mono_get_exception_overflow ());
2887 pwr = power10[cur_scale];
2890 if (IncreaseScale(quo, pwr) != 0) {
2891 mono_set_pending_exception (mono_get_exception_overflow ());
2895 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
2896 IncreaseScale(rem, pwr);
2897 tmp = Div96By64(rem, sdlDivisor);
2898 if (!Add32To96(quo, tmp)) {
2900 mono_set_pending_exception (mono_get_exception_overflow ());
2904 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0));
2910 // Have a 96-bit divisor in divisor[].
2912 // Start by finishing the shift left by cur_scale.
2914 sdlTmp.u.Lo = divisor[1];
2915 sdlTmp.u.Hi = divisor[2];
2916 sdlTmp.int64 <<= cur_scale;
2917 divisor[0] = sdlDivisor.u.Lo;
2918 divisor[1] = sdlDivisor.u.Hi;
2919 divisor[2] = sdlTmp.u.Hi;
2921 // The remainder (currently 96 bits spread over 4 uint32_ts)
2922 // will be < divisor.
2926 quo[0] = Div128By96(rem, divisor);
2929 if ((rem[0] | rem[1] | rem[2]) == 0) {
2931 cur_scale = min(9, -scale);
2937 // We need to unscale if and only if we have a non-zero remainder
2940 // Remainder is non-zero. Scale up quotient and remainder by
2941 // powers of 10 so we can compute more significant bits.
2943 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2944 if (cur_scale == 0) {
2945 // No more scaling to be done, but remainder is non-zero.
2948 if (rem[2] >= 0x80000000)
2951 tmp = rem[0] > 0x80000000;
2952 tmp1 = rem[1] > 0x80000000;
2954 rem[1] = (rem[1] << 1) + tmp;
2955 rem[2] = (rem[2] << 1) + tmp1;
2957 if (rem[2] > divisor[2] || (rem[2] == divisor[2] && (rem[1] > divisor[1] || rem[1] == (divisor[1] && (rem[0] > divisor[0] || (rem[0] == divisor[0] && (quo[0] & 1)))))))
2962 if (cur_scale < 0) {
2963 mono_set_pending_exception (mono_get_exception_overflow ());
2968 pwr = power10[cur_scale];
2971 if (IncreaseScale(quo, pwr) != 0) {
2972 mono_set_pending_exception (mono_get_exception_overflow ());
2976 rem[3] = IncreaseScale(rem, pwr);
2977 tmp = Div128By96(rem, divisor);
2978 if (!Add32To96(quo, tmp)) {
2980 mono_set_pending_exception (mono_get_exception_overflow ());
2985 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0 || rem[2] != 0 || rem[3] != 0));
2993 // We need to unscale if and only if we have a non-zero remainder
2995 // Try extracting any extra powers of 10 we may have
2996 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
2997 // If a division by one of these powers returns a zero remainder, then
2998 // we keep the quotient. If the remainder is not zero, then we restore
2999 // the previous value.
3001 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
3002 // we can extract. We use this as a quick test on whether to try a
3005 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
3006 quo_save[0] = quo[0];
3007 quo_save[1] = quo[1];
3008 quo_save[2] = quo[2];
3010 if (Div96By32(quo_save, 100000000) == 0) {
3011 quo[0] = quo_save[0];
3012 quo[1] = quo_save[1];
3013 quo[2] = quo_save[2];
3019 if ((quo[0] & 0xF) == 0 && scale >= 4) {
3020 quo_save[0] = quo[0];
3021 quo_save[1] = quo[1];
3022 quo_save[2] = quo[2];
3024 if (Div96By32(quo_save, 10000) == 0) {
3025 quo[0] = quo_save[0];
3026 quo[1] = quo_save[1];
3027 quo[2] = quo_save[2];
3032 if ((quo[0] & 3) == 0 && scale >= 2) {
3033 quo_save[0] = quo[0];
3034 quo_save[1] = quo[1];
3035 quo_save[2] = quo[2];
3037 if (Div96By32(quo_save, 100) == 0) {
3038 quo[0] = quo_save[0];
3039 quo[1] = quo_save[1];
3040 quo[2] = quo_save[2];
3045 if ((quo[0] & 1) == 0 && scale >= 1) {
3046 quo_save[0] = quo[0];
3047 quo_save[1] = quo[1];
3048 quo_save[2] = quo[2];
3050 if (Div96By32(quo_save, 10) == 0) {
3051 quo[0] = quo_save[0];
3052 quo[1] = quo_save[1];
3053 quo[2] = quo_save[2];
3059 DECIMAL_SIGN(*left) = DECIMAL_SIGN(*left) ^ DECIMAL_SIGN(*right);
3060 DECIMAL_HI32(*left) = quo[2];
3061 DECIMAL_MID32(*left) = quo[1];
3062 DECIMAL_LO32(*left) = quo[0];
3063 DECIMAL_SCALE(*left) = (uint8_t)scale;
3068 #define DECIMAL_PRECISION 29
3069 #define NUMBER_MAXDIGITS 50
3074 uint16_t digits[NUMBER_MAXDIGITS + 1];
3075 uint16_t* allDigits;
3079 mono_decimal_from_number (void *from, MonoDecimal *target)
3081 CLRNumber *number = (CLRNumber *) from;
3082 uint16_t* p = number->digits;
3084 int e = number->scale;
3085 g_assert(number != NULL);
3086 g_assert(target != NULL);
3089 DECIMAL_SIGNSCALE(d) = 0;
3090 DECIMAL_HI32(d) = 0;
3091 DECIMAL_LO32(d) = 0;
3092 DECIMAL_MID32(d) = 0;
3093 g_assert(p != NULL);
3095 // To avoid risking an app-compat issue with pre 4.5 (where some app was illegally using Reflection to examine the internal scale bits), we'll only force
3096 // the scale to 0 if the scale was previously positive
3101 if (e > DECIMAL_PRECISION) return 0;
3102 while ((e > 0 || (*p && e > -28)) && (DECIMAL_HI32(d) < 0x19999999 || (DECIMAL_HI32(d) == 0x19999999 && (DECIMAL_MID32(d) < 0x99999999 || (DECIMAL_MID32(d) == 0x99999999 && (DECIMAL_LO32(d) < 0x99999999 || (DECIMAL_LO32(d) == 0x99999999 && *p <= '5'))))))) {
3105 DecAddInt32(&d, *p++ - '0');
3109 gboolean round = TRUE;
3110 if (*(p-1) == '5' && *(p-2) % 2 == 0) { // Check if previous digit is even, only if the when we are unsure whether hows to do Banker's rounding
3111 // For digits > 5 we will be roundinp up anyway.
3112 int count = 20; // Look at the next 20 digits to check to round
3113 while (*p == '0' && count != 0) {
3117 if (*p == '\0' || count == 0)
3118 round = FALSE;// Do nothing
3123 if ((DECIMAL_HI32(d) | DECIMAL_MID32(d) | DECIMAL_LO32(d)) == 0) {
3124 DECIMAL_HI32(d) = 0x19999999;
3125 DECIMAL_MID32(d) = 0x99999999;
3126 DECIMAL_LO32(d) = 0x9999999A;
3134 if (e <= -DECIMAL_PRECISION) {
3135 // Parsing a large scale zero can give you more precision than fits in the decimal.
3136 // This should only happen for actual zeros or very small numbers that round to zero.
3137 DECIMAL_SIGNSCALE(d) = 0;
3138 DECIMAL_HI32(d) = 0;
3139 DECIMAL_LO32(d) = 0;
3140 DECIMAL_MID32(d) = 0;
3141 DECIMAL_SCALE(d) = (DECIMAL_PRECISION - 1);
3143 DECIMAL_SCALE(d) = (uint8_t)(-e);
3146 DECIMAL_SIGN(d) = number->sign? DECIMAL_NEG: 0;