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 #define DECIMAL_LO64_GET(dec) ((dec).v.Lo64)
59 #define DECIMAL_LO64_SET(dec,value) {(dec).v.Lo64 = value; }
61 #define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
62 #define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
63 DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
65 #define DEC_SCALE_MAX 28
68 #define OVFL_MAX_9_HI 4
69 #define OVFL_MAX_9_MID 1266874889
70 #define OVFL_MAX_9_LO 3047500985u
72 #define OVFL_MAX_5_HI 42949
73 #define OVFL_MAX_5_MID 2890341191
75 #define OVFL_MAX_1_HI 429496729
80 #if BYTE_ORDER == G_BIG_ENDIAN
90 static const SPLIT64 ten_to_eighteen = { 1000000000000000000ULL };
94 // Structure to access an encoded double floating point
97 #if BYTE_ORDER == G_BIG_ENDIAN
100 unsigned int mantHi:20;
104 unsigned int mantHi:20;
112 #if BYTE_ORDER == G_BIG_ENDIAN
113 #define DEFDS(Lo, Hi, exp, sign) { {sign, exp, Hi, Lo } }
115 #define DEFDS(Lo, Hi, exp, sign) { {Lo, Hi, exp, sign} }
118 const DoubleStructure ds2to64 = DEFDS(0, 0, DBLBIAS + 65, 0);
120 // Single floating point Bias
123 // Structure to access an encoded single floating point
125 #if BYTE_ORDER == G_BIG_ENDIAN
128 unsigned int mant:23;
130 unsigned int mant:23;
140 static const uint32_t power10 [POWER10_MAX+1] = {
141 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
145 static const double double_power10[] = {
146 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
147 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
148 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
149 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
150 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
151 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
152 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
153 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
156 const SPLIT64 sdl_power10[] = { {10000000000ULL}, // 1E10
157 {100000000000ULL}, // 1E11
158 {1000000000000ULL}, // 1E12
159 {10000000000000ULL}, // 1E13
160 {100000000000000ULL} }; // 1E14
162 static const uint64_t long_power10[] = {
179 10000000000000000ULL,
180 100000000000000000ULL,
181 1000000000000000000ULL,
182 10000000000000000000ULL};
185 uint32_t Hi, Mid, Lo;
188 const DECOVFL power_overflow[] = {
189 // This is a table of the largest values that can be in the upper two
190 // ULONGs of a 96-bit number that will not overflow when multiplied
191 // by a given power. For the upper word, this is a table of
192 // 2^32 / 10^n for 1 <= n <= 9. For the lower word, this is the
193 // remaining fraction part * 2^32. 2^32 = 4294967296.
195 { 429496729u, 2576980377u, 2576980377u }, // 10^1 remainder 0.6
196 { 42949672u, 4123168604u, 687194767u }, // 10^2 remainder 0.16
197 { 4294967u, 1271310319u, 2645699854u }, // 10^3 remainder 0.616
198 { 429496u, 3133608139u, 694066715u }, // 10^4 remainder 0.1616
199 { 42949u, 2890341191u, 2216890319u }, // 10^5 remainder 0.51616
200 { 4294u, 4154504685u, 2369172679u }, // 10^6 remainder 0.551616
201 { 429u, 2133437386u, 4102387834u }, // 10^7 remainder 0.9551616
202 { 42u, 4078814305u, 410238783u }, // 10^8 remainder 0.09991616
203 { 4u, 1266874889u, 3047500985u }, // 10^9 remainder 0.709551616
207 #define UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b)))
208 #define Div64by32(num, den) ((uint32_t)((uint64_t)(num) / (uint32_t)(den)))
209 #define Mod64by32(num, den) ((uint32_t)((uint64_t)(num) % (uint32_t)(den)))
214 const int maxIx = (sizeof(double_power10)/sizeof(double_power10[0]));
217 return double_power10[ix];
218 return pow(10.0, ix);
219 } // double fnDblPower10()
222 static inline int64_t
223 DivMod32by32(int32_t num, int32_t den)
227 sdl.u.Lo = num / den;
228 sdl.u.Hi = num % den;
232 static inline int64_t
233 DivMod64by32(int64_t num, int32_t den)
237 sdl.u.Lo = Div64by32(num, den);
238 sdl.u.Hi = Mod64by32(num, den);
243 UInt64x64To128(SPLIT64 op1, SPLIT64 op2, uint64_t *hi)
249 tmp1.int64 = UInt32x32To64(op1.u.Lo, op2.u.Lo); // lo partial prod
250 tmp2.int64 = UInt32x32To64(op1.u.Lo, op2.u.Hi); // mid 1 partial prod
251 tmp1.u.Hi += tmp2.u.Lo;
252 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
254 tmp3.int64 = UInt32x32To64(op1.u.Hi, op2.u.Hi) + (uint64_t)tmp2.u.Hi;
255 tmp2.int64 = UInt32x32To64(op1.u.Hi, op2.u.Lo);
256 tmp1.u.Hi += tmp2.u.Lo;
257 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
259 tmp3.int64 += (uint64_t)tmp2.u.Hi;
269 * pdlNum - Pointer to 64-bit dividend
270 * ulDen - 32-bit divisor
273 * Do full divide, yielding 64-bit result and 32-bit remainder.
276 * Quotient overwrites dividend.
282 // Was: FullDiv64By32
284 FullDiv64By32 (uint64_t *num, uint32_t den)
292 if (tmp.u.Hi >= den) {
293 // DivMod64by32 returns quotient in Lo, remainder in Hi.
296 res.int64 = DivMod64by32(res.int64, den);
301 tmp.int64 = DivMod64by32(tmp.int64, den);
311 * res_hi - Top uint32_t of quotient
312 * res_mid - Middle uint32_t of quotient
313 * res_lo - Bottom uint32_t of quotient
314 * scale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
317 * Determine the max power of 10, <= 9, that the quotient can be scaled
318 * up by and still fit in 96 bits.
321 * Returns power of 10 to scale by, -1 if overflow error.
323 ***********************************************************************/
326 SearchScale(uint32_t res_hi, uint32_t res_mid, uint32_t res_lo, int scale)
330 // Quick check to stop us from trying to scale any more.
332 if (res_hi > OVFL_MAX_1_HI || scale >= DEC_SCALE_MAX) {
337 if (scale > DEC_SCALE_MAX - 9) {
338 // We can't scale by 10^9 without exceeding the max scale factor.
339 // See if we can scale to the max. If not, we'll fall into
340 // standard search for scale factor.
342 cur_scale = DEC_SCALE_MAX - scale;
343 if (res_hi < power_overflow[cur_scale - 1].Hi)
346 if (res_hi == power_overflow[cur_scale - 1].Hi) {
348 if (res_mid > power_overflow[cur_scale - 1].Mid ||
349 (res_mid == power_overflow[cur_scale - 1].Mid && res_lo > power_overflow[cur_scale - 1].Lo)) {
354 } 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))
357 // Search for a power to scale by < 9. Do a binary search
358 // on power_overflow[].
361 if (res_hi < OVFL_MAX_5_HI)
363 else if (res_hi > OVFL_MAX_5_HI)
368 // cur_scale is 3 or 7.
370 if (res_hi < power_overflow[cur_scale - 1].Hi)
372 else if (res_hi > power_overflow[cur_scale - 1].Hi)
377 // cur_scale is 2, 4, 6, or 8.
379 // In all cases, we already found we could not use the power one larger.
380 // So if we can use this power, it is the biggest, and we're done. If
381 // we can't use this power, the one below it is correct for all cases
382 // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
384 if (res_hi > power_overflow[cur_scale - 1].Hi)
387 if (res_hi == power_overflow[cur_scale - 1].Hi)
391 // cur_scale = largest power of 10 we can scale by without overflow,
392 // cur_scale < 9. See if this is enough to make scale factor
393 // positive if it isn't already.
395 if (cur_scale + scale < 0)
406 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
407 * ulDen - 32-bit divisor.
410 * Do full divide, yielding 96-bit result and 32-bit remainder.
413 * Quotient overwrites dividend.
421 Div96By32(uint32_t *num, uint32_t den)
439 tmp.int64 = DivMod64by32(tmp.int64, den);
443 tmp.int64 = DivMod64by32(tmp.int64, den);
447 tmp.int64 = DivMod64by32(tmp.int64, den);
456 * pdecRes - Pointer to Decimal result location
457 * operand - Pointer to Decimal operand
460 * Chop the value to integer. Return remainder so Int() function
461 * can round down if non-zero.
469 ***********************************************************************/
472 DecFixInt(MonoDecimal * result, MonoDecimal * operand)
479 if (operand->u.u.scale > 0) {
480 num[0] = operand->v.v.Lo32;
481 num[1] = operand->v.v.Mid32;
482 num[2] = operand->Hi32;
483 scale = operand->u.u.scale;
484 result->u.u.sign = operand->u.u.sign;
488 if (scale > POWER10_MAX)
491 pwr = power10[scale];
493 rem |= Div96By32(num, pwr);
497 result->v.v.Lo32 = num[0];
498 result->v.v.Mid32 = num[1];
499 result->Hi32 = num[2];
500 result->u.u.scale = 0;
505 COPYDEC(*result, *operand);
506 // Odd, the Microsoft code does not set result->reserved to zero on this case
514 * res - Array of uint32_ts with value, least-significant first.
515 * hi_res - Index of last non-zero value in res.
516 * scale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
519 * See if we need to scale the result to fit it in 96 bits.
520 * Perform needed scaling. Adjust scale factor accordingly.
523 * res updated in place, always 3 uint32_ts.
524 * New scale factor returned, -1 if overflow error.
528 ScaleResult(uint32_t *res, int hi_res, int scale)
537 // See if we need to scale the result. The combined scale must
538 // be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
540 // Start by figuring a lower bound on the scaling needed to make
541 // the upper 96 bits zero. hi_res is the index into res[]
542 // of the highest non-zero uint32_t.
544 new_scale = hi_res * 32 - 64 - 1;
550 if (!(tmp & 0xFFFF0000)) {
554 if (!(tmp & 0xFF000000)) {
558 if (!(tmp & 0xF0000000)) {
562 if (!(tmp & 0xC0000000)) {
566 if (!(tmp & 0x80000000)) {
571 // Multiply bit position by log10(2) to figure it's power of 10.
572 // We scale the log by 256. log(2) = .30103, * 256 = 77. Doing this
573 // with a multiply saves a 96-byte lookup table. The power returned
574 // is <= the power of the number, so we must add one power of 10
575 // to make it's integer part zero after dividing by 256.
577 // Note: the result of this multiplication by an approximation of
578 // log10(2) have been exhaustively checked to verify it gives the
579 // correct result. (There were only 95 to check...)
581 new_scale = ((new_scale * 77) >> 8) + 1;
583 // new_scale = min scale factor to make high 96 bits zero, 0 - 29.
584 // This reduces the scale factor of the result. If it exceeds the
585 // current scale of the result, we'll overflow.
587 if (new_scale > scale)
593 // Make sure we scale by enough to bring the current scale factor
596 if (new_scale < scale - DEC_SCALE_MAX)
597 new_scale = scale - DEC_SCALE_MAX;
599 if (new_scale != 0) {
600 // Scale by the power of 10 given by new_scale. Note that this is
601 // NOT guaranteed to bring the number within 96 bits -- it could
602 // be 1 power of 10 short.
606 sdlTmp.u.Hi = 0; // initialize remainder
610 sticky |= sdlTmp.u.Hi; // record remainder as sticky bit
612 if (new_scale > POWER10_MAX)
615 pwr = power10[new_scale];
617 // Compute first quotient.
618 // DivMod64by32 returns quotient in Lo, remainder in Hi.
620 sdlTmp.int64 = DivMod64by32(res[hi_res], pwr);
621 res[hi_res] = sdlTmp.u.Lo;
625 // If first quotient was 0, update hi_res.
627 if (sdlTmp.u.Lo == 0)
630 // Compute subsequent quotients.
633 sdlTmp.u.Lo = res[cur];
634 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, pwr);
635 res[cur] = sdlTmp.u.Lo;
641 new_scale -= POWER10_MAX;
643 continue; // scale some more
645 // If we scaled enough, hi_res would be 2 or less. If not,
646 // divide by 10 more.
651 continue; // scale by 10
654 // Round final result. See if remainder >= 1/2 of divisor.
655 // If remainder == 1/2 divisor, round up if odd or sticky bit set.
657 pwr >>= 1; // power of 10 always even
658 if ( pwr <= sdlTmp.u.Hi && (pwr < sdlTmp.u.Hi ||
659 ((res[0] & 1) | sticky)) ) {
661 while (++res[++cur] == 0);
664 // The rounding caused us to carry beyond 96 bits.
668 sticky = 0; // no sticky bit
669 sdlTmp.u.Hi = 0; // or remainder
672 continue; // scale by 10
676 // We may have scaled it more than we planned. Make sure the scale
677 // factor hasn't gone negative, indicating overflow.
689 // Returns: MONO_DECIMAL_OVERFLOW or MONO_DECIMAL_OK
690 static MonoDecimalStatus
691 MONO_VarDecMul(MonoDecimal * left, MonoDecimal * right, MonoDecimal * result)
703 scale = left->u.u.scale + right->u.u.scale;
705 if ((left->Hi32 | left->v.v.Mid32 | right->Hi32 | right->v.v.Mid32) == 0) {
706 // Upper 64 bits are zero.
708 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
709 if (scale > DEC_SCALE_MAX)
711 // Result scale is too big. Divide result by power of 10 to reduce it.
712 // If the amount to divide by is > 19 the result is guaranteed
713 // less than 1/2. [max value in 64 bits = 1.84E19]
715 scale -= DEC_SCALE_MAX;
718 DECIMAL_SETZERO(*result);
719 return MONO_DECIMAL_OK;
722 if (scale > POWER10_MAX) {
723 // Divide by 1E10 first, to get the power down to a 32-bit quantity.
724 // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
725 // then multiply the next divisor by 4 (which will be a max of 4E9).
727 rem_lo = FullDiv64By32(&tmp.int64, ten_to_ten_div_4);
728 pwr = power10[scale - 10] << 2;
730 pwr = power10[scale];
734 // Power to divide by fits in 32 bits.
736 rem_hi = FullDiv64By32(&tmp.int64, pwr);
738 // Round result. See if remainder >= 1/2 of divisor.
739 // Divisor is a power of 10, so it is always even.
742 if (rem_hi >= pwr && (rem_hi > pwr || (rem_lo | (tmp.u.Lo & 1))))
745 scale = DEC_SCALE_MAX;
747 DECIMAL_LO32(*result) = tmp.u.Lo;
748 DECIMAL_MID32(*result) = tmp.u.Hi;
749 DECIMAL_HI32(*result) = 0;
751 // At least one operand has bits set in the upper 64 bits.
753 // Compute and accumulate the 9 partial products into a
754 // 192-bit (24-byte) result.
756 // [l-h][l-m][l-l] left high, middle, low
757 // x [r-h][r-m][r-l] right high, middle, low
758 // ------------------------------
760 // [0-h][0-l] l-l * r-l
761 // [1ah][1al] l-l * r-m
762 // [1bh][1bl] l-m * r-l
763 // [2ah][2al] l-m * r-m
764 // [2bh][2bl] l-l * r-h
765 // [2ch][2cl] l-h * r-l
766 // [3ah][3al] l-m * r-h
767 // [3bh][3bl] l-h * r-m
768 // [4-h][4-l] l-h * r-h
769 // ------------------------------
770 // [p-5][p-4][p-3][p-2][p-1][p-0] prod[] array
772 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
775 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Mid32) + tmp.u.Hi;
777 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Lo32);
778 tmp.int64 += tmp2.int64; // this could generate carry
780 if (tmp.int64 < tmp2.int64) // detect carry
784 tmp2.u.Lo = tmp.u.Hi;
786 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Mid32) + tmp2.int64;
788 if (left->Hi32 | right->Hi32) {
789 // Highest 32 bits is non-zero. Calculate 5 more partial products.
791 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->Hi32);
792 tmp.int64 += tmp2.int64; // this could generate carry
793 if (tmp.int64 < tmp2.int64) // detect carry
798 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Lo32);
799 tmp.int64 += tmp2.int64; // this could generate carry
801 if (tmp.int64 < tmp2.int64) // detect carry
803 tmp3.u.Lo = tmp.u.Hi;
805 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->Hi32);
806 tmp.int64 += tmp3.int64; // this could generate carry
807 if (tmp.int64 < tmp3.int64) // detect carry
812 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Mid32);
813 tmp.int64 += tmp2.int64; // this could generate carry
815 if (tmp.int64 < tmp2.int64) // detect carry
817 tmp3.u.Lo = tmp.u.Hi;
819 tmp.int64 = UInt32x32To64(left->Hi32, right->Hi32) + tmp3.int64;
831 // Check for leading zero uint32_ts on the product
833 while (prod[hi_prod] == 0) {
839 scale = ScaleResult(prod, hi_prod, scale);
841 return MONO_DECIMAL_OVERFLOW;
843 result->v.v.Lo32 = prod[0];
844 result->v.v.Mid32 = prod[1];
845 result->Hi32 = prod[2];
848 result->u.u.sign = right->u.u.sign ^ left->u.u.sign;
849 result->u.u.scale = (char)scale;
850 return MONO_DECIMAL_OK;
853 // Addition and subtraction
854 static MonoDecimalStatus
855 DecAddSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result, int8_t sign)
865 MonoDecimal *pdecTmp;
867 sign ^= (right->u.u.sign ^ left->u.u.sign) & DECIMAL_NEG;
869 if (right->u.u.scale == left->u.u.scale) {
870 // Scale factors are equal, no alignment necessary.
872 decRes.u.signscale = left->u.signscale;
876 // Signs differ - subtract
878 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right));
879 DECIMAL_HI32(decRes) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
883 if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*left)) {
885 if (decRes.Hi32 >= left->Hi32)
887 } else if (decRes.Hi32 > left->Hi32) {
888 // Got negative result. Flip its sign.
891 DECIMAL_LO64_SET(decRes, -(uint64_t)DECIMAL_LO64_GET(decRes));
892 decRes.Hi32 = ~decRes.Hi32;
893 if (DECIMAL_LO64_GET(decRes) == 0)
895 decRes.u.u.sign ^= DECIMAL_NEG;
899 // Signs are the same - add
901 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right));
902 decRes.Hi32 = left->Hi32 + right->Hi32;
906 if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*left)) {
908 if (decRes.Hi32 <= left->Hi32)
910 } else if (decRes.Hi32 < left->Hi32) {
912 // The addition carried above 96 bits. Divide the result by 10,
913 // dropping the scale factor.
915 if (decRes.u.u.scale == 0)
916 return MONO_DECIMAL_OVERFLOW;
919 tmp.u.Lo = decRes.Hi32;
921 tmp.int64 = DivMod64by32(tmp.int64, 10);
922 decRes.Hi32 = tmp.u.Lo;
924 tmp.u.Lo = decRes.v.v.Mid32;
925 tmp.int64 = DivMod64by32(tmp.int64, 10);
926 decRes.v.v.Mid32 = tmp.u.Lo;
928 tmp.u.Lo = decRes.v.v.Lo32;
929 tmp.int64 = DivMod64by32(tmp.int64, 10);
930 decRes.v.v.Lo32 = tmp.u.Lo;
932 // See if we need to round up.
934 if (tmp.u.Hi >= 5 && (tmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
935 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
936 if (DECIMAL_LO64_GET(decRes) == 0)
943 // Scale factors are not equal. Assume that a larger scale
944 // factor (more decimal places) is likely to mean that number
945 // is smaller. Start by guessing that the right operand has
946 // the larger scale factor. The result will have the larger
949 decRes.u.u.scale = right->u.u.scale; // scale factor of "smaller"
950 decRes.u.u.sign = left->u.u.sign; // but sign of "larger"
951 scale = decRes.u.u.scale - left->u.u.scale;
954 // Guessed scale factor wrong. Swap operands.
957 decRes.u.u.scale = left->u.u.scale;
958 decRes.u.u.sign ^= sign;
964 // *left will need to be multiplied by 10^scale so
965 // it will have the same scale as *right. We could be
966 // extending it to up to 192 bits of precision.
968 if (scale <= POWER10_MAX) {
969 // Scaling won't make it larger than 4 uint32_ts
971 pwr = power10[scale];
972 DECIMAL_LO64_SET(decTmp, UInt32x32To64(left->v.v.Lo32, pwr));
973 tmp.int64 = UInt32x32To64(left->v.v.Mid32, pwr);
974 tmp.int64 += decTmp.v.v.Mid32;
975 decTmp.v.v.Mid32 = tmp.u.Lo;
976 decTmp.Hi32 = tmp.u.Hi;
977 tmp.int64 = UInt32x32To64(left->Hi32, pwr);
978 tmp.int64 += decTmp.Hi32;
980 // Result fits in 96 bits. Use standard aligned add.
982 decTmp.Hi32 = tmp.u.Lo;
986 num[0] = decTmp.v.v.Lo32;
987 num[1] = decTmp.v.v.Mid32;
993 // Have to scale by a bunch. Move the number to a buffer
994 // where it has room to grow as it's scaled.
996 num[0] = left->v.v.Lo32;
997 num[1] = left->v.v.Mid32;
1001 // Scan for zeros in the upper words.
1008 // Left arg is zero, return right.
1010 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*right));
1011 decRes.Hi32 = right->Hi32;
1012 decRes.u.u.sign ^= sign;
1018 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
1019 // with index of highest non-zero uint32_t.
1021 for (; scale > 0; scale -= POWER10_MAX) {
1022 if (scale > POWER10_MAX)
1025 pwr = power10[scale];
1028 for (cur = 0; cur <= hi_prod; cur++) {
1029 tmp.int64 = UInt32x32To64(num[cur], pwr) + tmp.u.Hi;
1030 num[cur] = tmp.u.Lo;
1034 // We're extending the result by another uint32_t.
1035 num[++hi_prod] = tmp.u.Hi;
1039 // Scaling complete, do the add. Could be subtract if signs differ.
1045 // Signs differ, subtract.
1047 DECIMAL_LO64_SET(decRes, tmp.int64 - DECIMAL_LO64_GET(*right));
1048 decRes.Hi32 = num[2] - right->Hi32;
1052 if (DECIMAL_LO64_GET(decRes) > tmp.int64) {
1054 if (decRes.Hi32 >= num[2])
1057 else if (decRes.Hi32 > num[2]) {
1059 // If num has more than 96 bits of precision, then we need to
1060 // carry the subtraction into the higher bits. If it doesn't,
1061 // then we subtracted in the wrong order and have to flip the
1062 // sign of the result.
1068 while(num[cur++]-- == 0);
1069 if (num[hi_prod] == 0)
1074 // Signs the same, add.
1076 DECIMAL_LO64_SET(decRes, tmp.int64 + DECIMAL_LO64_GET(*right));
1077 decRes.Hi32 = num[2] + right->Hi32;
1081 if (DECIMAL_LO64_GET(decRes) < tmp.int64) {
1083 if (decRes.Hi32 <= num[2])
1086 else if (decRes.Hi32 < num[2]) {
1088 // Had a carry above 96 bits.
1092 if (hi_prod < cur) {
1097 }while (++num[cur++] == 0);
1102 num[0] = decRes.v.v.Lo32;
1103 num[1] = decRes.v.v.Mid32;
1104 num[2] = decRes.Hi32;
1105 decRes.u.u.scale = ScaleResult(num, hi_prod, decRes.u.u.scale);
1106 if (decRes.u.u.scale == (uint8_t) -1)
1107 return MONO_DECIMAL_OVERFLOW;
1109 decRes.v.v.Lo32 = num[0];
1110 decRes.v.v.Mid32 = num[1];
1111 decRes.Hi32 = num[2];
1116 COPYDEC(*result, decRes);
1117 // Odd, the Microsoft code does not set result->reserved to zero on this case
1118 return MONO_DECIMAL_OK;
1122 static MonoDecimalStatus
1123 MONO_VarDecAdd(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1125 return DecAddSub (left, right, result, 0);
1128 // Decimal subtraction
1129 static MonoDecimalStatus
1130 MONO_VarDecSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1132 return DecAddSub (left, right, result, DECIMAL_NEG);
1139 * num - Pointer to 96-bit number as array of uint32_ts, least-sig first
1140 * pwr - Scale factor to multiply by
1143 * Multiply the two numbers. The low 96 bits of the result overwrite
1144 * the input. The last 32 bits of the product are the return value.
1147 * Returns highest 32 bits of product.
1154 IncreaseScale(uint32_t *num, uint32_t pwr)
1158 sdlTmp.int64 = UInt32x32To64(num[0], pwr);
1159 num[0] = sdlTmp.u.Lo;
1160 sdlTmp.int64 = UInt32x32To64(num[1], pwr) + sdlTmp.u.Hi;
1161 num[1] = sdlTmp.u.Lo;
1162 sdlTmp.int64 = UInt32x32To64(num[2], pwr) + sdlTmp.u.Hi;
1163 num[2] = sdlTmp.u.Lo;
1171 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
1172 * sdlDen - 64-bit divisor.
1175 * Do partial divide, yielding 32-bit result and 64-bit remainder.
1176 * Divisor must be larger than upper 64 bits of dividend.
1179 * Remainder overwrites lower 64-bits of dividend.
1187 Div96By64(uint32_t *num, SPLIT64 den)
1193 sdlNum.u.Lo = num[0];
1195 if (num[2] >= den.u.Hi) {
1196 // Divide would overflow. Assume a quotient of 2^32, and set
1197 // up remainder accordingly. Then jump to loop which reduces
1200 sdlNum.u.Hi = num[1] - den.u.Lo;
1205 // Hardware divide won't overflow
1207 if (num[2] == 0 && num[1] < den.u.Hi)
1208 // Result is zero. Entire dividend is remainder.
1212 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1216 quo.int64 = DivMod64by32(quo.int64, den.u.Hi);
1217 sdlNum.u.Hi = quo.u.Hi; // remainder
1219 // Compute full remainder, rem = dividend - (quo * divisor).
1221 prod.int64 = UInt32x32To64(quo.u.Lo, den.u.Lo); // quo * lo divisor
1222 sdlNum.int64 -= prod.int64;
1224 if (sdlNum.int64 > ~prod.int64) {
1226 // Remainder went negative. Add divisor back in until it's positive,
1227 // a max of 2 times.
1231 sdlNum.int64 += den.int64;
1232 }while (sdlNum.int64 >= den.int64);
1235 num[0] = sdlNum.u.Lo;
1236 num[1] = sdlNum.u.Hi;
1244 * rgulNum - Pointer to 128-bit dividend as array of uint32_ts, least-sig first
1245 * den - Pointer to 96-bit divisor.
1248 * Do partial divide, yielding 32-bit result and 96-bit remainder.
1249 * Top divisor uint32_t must be larger than top dividend uint32_t. This is
1250 * assured in the initial call because the divisor is normalized
1251 * and the dividend can't be. In subsequent calls, the remainder
1252 * is multiplied by 10^9 (max), so it can be no more than 1/4 of
1253 * the divisor which is effectively multiplied by 2^32 (4 * 10^9).
1256 * Remainder overwrites lower 96-bits of dividend.
1262 ***********************************************************************/
1265 Div128By96(uint32_t *num, uint32_t *den)
1272 sdlNum.u.Lo = num[0];
1273 sdlNum.u.Hi = num[1];
1275 if (num[3] == 0 && num[2] < den[2]){
1276 // Result is zero. Entire dividend is remainder.
1281 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1283 sdlQuo.u.Lo = num[2];
1284 sdlQuo.u.Hi = num[3];
1285 sdlQuo.int64 = DivMod64by32(sdlQuo.int64, den[2]);
1287 // Compute full remainder, rem = dividend - (quo * divisor).
1289 sdlProd1.int64 = UInt32x32To64(sdlQuo.u.Lo, den[0]); // quo * lo divisor
1290 sdlProd2.int64 = UInt32x32To64(sdlQuo.u.Lo, den[1]); // quo * mid divisor
1291 sdlProd2.int64 += sdlProd1.u.Hi;
1292 sdlProd1.u.Hi = sdlProd2.u.Lo;
1294 sdlNum.int64 -= sdlProd1.int64;
1295 num[2] = sdlQuo.u.Hi - sdlProd2.u.Hi; // sdlQuo.Hi is remainder
1297 // Propagate carries
1299 if (sdlNum.int64 > ~sdlProd1.int64) {
1301 if (num[2] >= ~sdlProd2.u.Hi)
1303 } else if (num[2] > ~sdlProd2.u.Hi) {
1305 // Remainder went negative. Add divisor back in until it's positive,
1306 // a max of 2 times.
1308 sdlProd1.u.Lo = den[0];
1309 sdlProd1.u.Hi = den[1];
1313 sdlNum.int64 += sdlProd1.int64;
1316 if (sdlNum.int64 < sdlProd1.int64) {
1317 // Detected carry. Check for carry out of top
1318 // before adding it in.
1320 if (num[2]++ < den[2])
1323 if (num[2] < den[2])
1324 break; // detected carry
1328 num[0] = sdlNum.u.Lo;
1329 num[1] = sdlNum.u.Hi;
1333 // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer
1334 // Returns FALSE if there is an overflow
1336 Add32To96(uint32_t *num, uint32_t value)
1339 if (num[0] < value) {
1340 if (++num[1] == 0) {
1341 if (++num[2] == 0) {
1350 OverflowUnscale (uint32_t *quo, gboolean remainder)
1354 // We have overflown, so load the high bit with a one.
1356 sdlTmp.u.Lo = quo[2];
1357 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1358 quo[2] = sdlTmp.u.Lo;
1359 sdlTmp.u.Lo = quo[1];
1360 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1361 quo[1] = sdlTmp.u.Lo;
1362 sdlTmp.u.Lo = quo[0];
1363 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1364 quo[0] = sdlTmp.u.Lo;
1365 // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up
1366 if ((sdlTmp.u.Hi > 5) || ((sdlTmp.u.Hi == 5) && ( remainder || (quo[0] & 1)))) {
1371 // MONO_VarDecDiv - Decimal divide
1372 static MonoDecimalStatus
1373 MONO_VarDecDiv(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1376 uint32_t quoSave[3];
1378 uint32_t divisor[3];
1387 scale = left->u.u.scale - right->u.u.scale;
1388 divisor[0] = right->v.v.Lo32;
1389 divisor[1] = right->v.v.Mid32;
1390 divisor[2] = right->Hi32;
1392 if (divisor[1] == 0 && divisor[2] == 0) {
1393 // Divisor is only 32 bits. Easy divide.
1395 if (divisor[0] == 0)
1396 return MONO_DECIMAL_DIVBYZERO;
1398 quo[0] = left->v.v.Lo32;
1399 quo[1] = left->v.v.Mid32;
1400 quo[2] = left->Hi32;
1401 rem[0] = Div96By32(quo, divisor[0]);
1406 cur_scale = min(9, -scale);
1412 // We have computed a quotient based on the natural scale
1413 // ( <dividend scale> - <divisor scale> ). We have a non-zero
1414 // remainder, so now we should increase the scale if possible to
1415 // include more quotient bits.
1417 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
1418 // computing more quotient bits as long as the remainder stays
1419 // non-zero. If scaling by that much would cause overflow, we'll
1420 // drop out of the loop and scale by as much as we can.
1422 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
1423 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
1424 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
1425 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
1426 // is the largest value in quo[1] (when quo[2] == 4) that is
1427 // assured not to overflow.
1429 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1430 if (cur_scale == 0) {
1431 // No more scaling to be done, but remainder is non-zero.
1435 if (utmp < rem[0] || (utmp >= divisor[0] &&
1436 (utmp > divisor[0] || (quo[0] & 1)))) {
1445 if (cur_scale == -1)
1446 return MONO_DECIMAL_OVERFLOW;
1449 pwr = power10[cur_scale];
1452 if (IncreaseScale(quo, pwr) != 0)
1453 return MONO_DECIMAL_OVERFLOW;
1455 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
1456 rem[0] = sdlTmp.u.Hi;
1458 quo[0] += sdlTmp.u.Lo;
1459 if (quo[0] < sdlTmp.u.Lo) {
1466 // Divisor has bits set in the upper 64 bits.
1468 // Divisor must be fully normalized (shifted so bit 31 of the most
1469 // significant uint32_t is 1). Locate the MSB so we know how much to
1470 // normalize by. The dividend will be shifted by the same amount so
1471 // the quotient is not changed.
1473 if (divisor[2] == 0)
1479 if (!(utmp & 0xFFFF0000)) {
1483 if (!(utmp & 0xFF000000)) {
1487 if (!(utmp & 0xF0000000)) {
1491 if (!(utmp & 0xC0000000)) {
1495 if (!(utmp & 0x80000000)) {
1500 // Shift both dividend and divisor left by cur_scale.
1502 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
1503 rem[0] = sdlTmp.u.Lo;
1504 rem[1] = sdlTmp.u.Hi;
1505 sdlTmp.u.Lo = left->v.v.Mid32;
1506 sdlTmp.u.Hi = left->Hi32;
1507 sdlTmp.int64 <<= cur_scale;
1508 rem[2] = sdlTmp.u.Hi;
1509 rem[3] = (left->Hi32 >> (31 - cur_scale)) >> 1;
1511 sdlDivisor.u.Lo = divisor[0];
1512 sdlDivisor.u.Hi = divisor[1];
1513 sdlDivisor.int64 <<= cur_scale;
1515 if (divisor[2] == 0) {
1516 // Have a 64-bit divisor in sdlDivisor. The remainder
1517 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
1519 sdlTmp.u.Lo = rem[2];
1520 sdlTmp.u.Hi = rem[3];
1523 quo[1] = Div96By64(&rem[1], sdlDivisor);
1524 quo[0] = Div96By64(rem, sdlDivisor);
1527 if ((rem[0] | rem[1]) == 0) {
1529 cur_scale = min(9, -scale);
1535 // Remainder is non-zero. Scale up quotient and remainder by
1536 // powers of 10 so we can compute more significant bits.
1538 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1539 if (cur_scale == 0) {
1540 // No more scaling to be done, but remainder is non-zero.
1543 sdlTmp.u.Lo = rem[0];
1544 sdlTmp.u.Hi = rem[1];
1545 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
1546 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
1551 if (cur_scale == -1)
1552 return MONO_DECIMAL_OVERFLOW;
1555 pwr = power10[cur_scale];
1558 if (IncreaseScale(quo, pwr) != 0)
1559 return MONO_DECIMAL_OVERFLOW;
1561 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
1562 IncreaseScale(rem, pwr);
1563 utmp = Div96By64(rem, sdlDivisor);
1572 // Have a 96-bit divisor in divisor[].
1574 // Start by finishing the shift left by cur_scale.
1576 sdlTmp.u.Lo = divisor[1];
1577 sdlTmp.u.Hi = divisor[2];
1578 sdlTmp.int64 <<= cur_scale;
1579 divisor[0] = sdlDivisor.u.Lo;
1580 divisor[1] = sdlDivisor.u.Hi;
1581 divisor[2] = sdlTmp.u.Hi;
1583 // The remainder (currently 96 bits spread over 4 uint32_ts)
1584 // will be < divisor.
1588 quo[0] = Div128By96(rem, divisor);
1591 if ((rem[0] | rem[1] | rem[2]) == 0) {
1593 cur_scale = min(9, -scale);
1599 // Remainder is non-zero. Scale up quotient and remainder by
1600 // powers of 10 so we can compute more significant bits.
1602 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1603 if (cur_scale == 0) {
1604 // No more scaling to be done, but remainder is non-zero.
1607 if (rem[2] >= 0x80000000)
1610 utmp = rem[0] > 0x80000000;
1611 utmp1 = rem[1] > 0x80000000;
1613 rem[1] = (rem[1] << 1) + utmp;
1614 rem[2] = (rem[2] << 1) + utmp1;
1616 if ((rem[2] > divisor[2] || rem[2] == divisor[2]) &&
1617 ((rem[1] > divisor[1] || rem[1] == divisor[1]) &&
1618 ((rem[0] > divisor[0] || rem[0] == divisor[0]) &&
1624 if (cur_scale == -1)
1625 return MONO_DECIMAL_OVERFLOW;
1628 pwr = power10[cur_scale];
1631 if (IncreaseScale(quo, pwr) != 0)
1632 return MONO_DECIMAL_OVERFLOW;
1634 rem[3] = IncreaseScale(rem, pwr);
1635 utmp = Div128By96(rem, divisor);
1645 // No more remainder. Try extracting any extra powers of 10 we may have
1646 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
1647 // If a division by one of these powers returns a zero remainder, then
1648 // we keep the quotient. If the remainder is not zero, then we restore
1649 // the previous value.
1651 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
1652 // we can extract. We use this as a quick test on whether to try a
1655 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
1656 quoSave[0] = quo[0];
1657 quoSave[1] = quo[1];
1658 quoSave[2] = quo[2];
1660 if (Div96By32(quoSave, 100000000) == 0) {
1661 quo[0] = quoSave[0];
1662 quo[1] = quoSave[1];
1663 quo[2] = quoSave[2];
1670 if ((quo[0] & 0xF) == 0 && scale >= 4) {
1671 quoSave[0] = quo[0];
1672 quoSave[1] = quo[1];
1673 quoSave[2] = quo[2];
1675 if (Div96By32(quoSave, 10000) == 0) {
1676 quo[0] = quoSave[0];
1677 quo[1] = quoSave[1];
1678 quo[2] = quoSave[2];
1683 if ((quo[0] & 3) == 0 && scale >= 2) {
1684 quoSave[0] = quo[0];
1685 quoSave[1] = quo[1];
1686 quoSave[2] = quo[2];
1688 if (Div96By32(quoSave, 100) == 0) {
1689 quo[0] = quoSave[0];
1690 quo[1] = quoSave[1];
1691 quo[2] = quoSave[2];
1696 if ((quo[0] & 1) == 0 && scale >= 1) {
1697 quoSave[0] = quo[0];
1698 quoSave[1] = quo[1];
1699 quoSave[2] = quo[2];
1701 if (Div96By32(quoSave, 10) == 0) {
1702 quo[0] = quoSave[0];
1703 quo[1] = quoSave[1];
1704 quo[2] = quoSave[2];
1709 result->Hi32 = quo[2];
1710 result->v.v.Mid32 = quo[1];
1711 result->v.v.Lo32 = quo[0];
1712 result->u.u.scale = scale;
1713 result->u.u.sign = left->u.u.sign ^ right->u.u.sign;
1714 return MONO_DECIMAL_OK;
1717 // MONO_VarDecAbs - Decimal Absolute Value
1719 MONO_VarDecAbs (MonoDecimal *pdecOprd, MonoDecimal *result)
1721 COPYDEC(*result, *pdecOprd);
1722 result->u.u.sign &= ~DECIMAL_NEG;
1723 // Microsoft does not set reserved here
1726 // MONO_VarDecFix - Decimal Fix (chop to integer)
1728 MONO_VarDecFix (MonoDecimal *pdecOprd, MonoDecimal *result)
1730 DecFixInt(result, pdecOprd);
1734 // MONO_VarDecInt - Decimal Int (round down to integer)
1736 MONO_VarDecInt (MonoDecimal *pdecOprd, MonoDecimal *result)
1738 if (DecFixInt(result, pdecOprd) != 0 && (result->u.u.sign & DECIMAL_NEG)) {
1739 // We have chopped off a non-zero amount from a negative value. Since
1740 // we round toward -infinity, we must increase the integer result by
1741 // 1 to make it more negative. This will never overflow because
1742 // in order to have a remainder, we must have had a non-zero scale factor.
1743 // Our scale factor is back to zero now.
1745 DECIMAL_LO64_SET(*result, DECIMAL_LO64_GET(*result) + 1);
1746 if (DECIMAL_LO64_GET(*result) == 0)
1752 // MONO_VarDecNeg - Decimal Negate
1754 MONO_VarDecNeg (MonoDecimal *pdecOprd, MonoDecimal *result)
1756 COPYDEC(*result, *pdecOprd);
1757 // Microsoft does not set result->reserved to zero on this case.
1758 result->u.u.sign ^= DECIMAL_NEG;
1762 // Returns: MONO_DECIMAL_INVALID_ARGUMENT, MONO_DECIMAL_OK
1764 static MonoDecimalStatus
1765 MONO_VarDecRound(MonoDecimal *input, int cDecimals, MonoDecimal *result)
1774 return MONO_DECIMAL_INVALID_ARGUMENT;
1776 scale = input->u.u.scale - cDecimals;
1778 num[0] = input->v.v.Lo32;
1779 num[1] = input->v.v.Mid32;
1780 num[2] = input->Hi32;
1781 result->u.u.sign = input->u.u.sign;
1786 if (scale > POWER10_MAX)
1789 pwr = power10[scale];
1791 rem = Div96By32(num, pwr);
1795 // Now round. rem has last remainder, sticky has sticky bits.
1796 // To do IEEE rounding, we add LSB of result to sticky bits so
1797 // either causes round up if remainder * 2 == last divisor.
1799 sticky |= num[0] & 1;
1800 rem = (rem << 1) + (sticky != 0);
1807 result->v.v.Lo32 = num[0];
1808 result->v.v.Mid32 = num[1];
1809 result->Hi32 = num[2];
1810 result->u.u.scale = cDecimals;
1811 return MONO_DECIMAL_OK;
1814 COPYDEC(*result, *input);
1815 // Odd, the Microsoft source does not set the result->reserved to zero here.
1816 return MONO_DECIMAL_OK;
1820 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1821 static MonoDecimalStatus
1822 MONO_VarDecFromR4 (float input, MonoDecimal* result)
1824 int exp; // number of bits to left of binary point
1830 int lmax, cur; // temps used during scale reduction
1832 // The most we can scale by is 10^28, which is just slightly more
1833 // than 2^93. So a float with an exponent of -94 could just
1834 // barely reach 0.5, but smaller exponents will always round to zero.
1836 if ((exp = ((SingleStructure *)&input)->exp - SNGBIAS) < -94 ) {
1837 DECIMAL_SETZERO(*result);
1838 return MONO_DECIMAL_OK;
1842 return MONO_DECIMAL_OVERFLOW;
1844 // Round the input to a 7-digit integer. The R4 format has
1845 // only 7 digits of precision, and we want to keep garbage digits
1846 // out of the Decimal were making.
1848 // Calculate max power of 10 input value could have by multiplying
1849 // the exponent by log10(2). Using scaled integer multiplcation,
1850 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1853 power = 6 - ((exp * 19728) >> 16);
1856 // We have less than 7 digits, scale input up.
1861 dbl = dbl * double_power10[power];
1863 if (power != -1 || dbl >= 1E7)
1864 dbl = dbl / fnDblPower10(-power);
1866 power = 0; // didn't scale it
1869 g_assert (dbl < 1E7);
1870 if (dbl < 1E6 && power < DECMAX) {
1873 g_assert(dbl >= 1E6);
1878 mant = (int32_t)dbl;
1879 dbl -= (double)mant; // difference between input & integer
1880 if ( dbl > 0.5 || (dbl == 0.5 && (mant & 1)))
1884 DECIMAL_SETZERO(*result);
1885 return MONO_DECIMAL_OK;
1889 // Add -power factors of 10, -power <= (29 - 7) = 22.
1893 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power]);
1895 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1896 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1897 DECIMAL_HI32(*result) = 0;
1899 // Have a big power of 10.
1902 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 18]);
1903 sdlLo.int64 = UInt64x64To128(sdlLo, ten_to_eighteen, &sdlHi.int64);
1905 if (sdlHi.u.Hi != 0)
1906 return MONO_DECIMAL_OVERFLOW;
1909 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 9]);
1910 sdlHi.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Hi);
1911 sdlLo.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Lo);
1912 sdlHi.int64 += sdlLo.u.Hi;
1913 sdlLo.u.Hi = sdlHi.u.Lo;
1914 sdlHi.u.Lo = sdlHi.u.Hi;
1916 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1917 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1918 DECIMAL_HI32(*result) = sdlHi.u.Lo;
1920 DECIMAL_SCALE(*result) = 0;
1922 // Factor out powers of 10 to reduce the scale, if possible.
1923 // The maximum number we could factor out would be 6. This
1924 // comes from the fact we have a 7-digit number, and the
1925 // MSD must be non-zero -- but the lower 6 digits could be
1926 // zero. Note also the scale factor is never negative, so
1927 // we can't scale by any more than the power we used to
1930 // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
1932 lmax = min(power, 6);
1934 // lmax is the largest power of 10 to try, lmax <= 6.
1935 // We'll try powers 4, 2, and 1 unless they're too big.
1937 for (cur = 4; cur > 0; cur >>= 1)
1942 sdlLo.int64 = DivMod32by32(mant, (uint32_t)long_power10[cur]);
1944 if (sdlLo.u.Hi == 0) {
1950 DECIMAL_LO32(*result) = mant;
1951 DECIMAL_MID32(*result) = 0;
1952 DECIMAL_HI32(*result) = 0;
1953 DECIMAL_SCALE(*result) = power;
1956 DECIMAL_SIGN(*result) = (char)((SingleStructure *)&input)->sign << 7;
1957 return MONO_DECIMAL_OK;
1961 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1962 static MonoDecimalStatus
1963 MONO_VarDecFromR8 (double input, MonoDecimal *result)
1965 int exp; // number of bits to left of binary point
1966 int power; // power-of-10 scale factor
1970 int lmax, cur; // temps used during scale reduction
1975 // The most we can scale by is 10^28, which is just slightly more
1976 // than 2^93. So a float with an exponent of -94 could just
1977 // barely reach 0.5, but smaller exponents will always round to zero.
1979 if ((exp = ((DoubleStructure *)&input)->u.exp - DBLBIAS) < -94) {
1980 DECIMAL_SETZERO(*result);
1981 return MONO_DECIMAL_OK;
1985 return MONO_DECIMAL_OVERFLOW;
1987 // Round the input to a 15-digit integer. The R8 format has
1988 // only 15 digits of precision, and we want to keep garbage digits
1989 // out of the Decimal were making.
1991 // Calculate max power of 10 input value could have by multiplying
1992 // the exponent by log10(2). Using scaled integer multiplcation,
1993 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1996 power = 14 - ((exp * 19728) >> 16);
1999 // We have less than 15 digits, scale input up.
2004 dbl = dbl * double_power10[power];
2006 if (power != -1 || dbl >= 1E15)
2007 dbl = dbl / fnDblPower10(-power);
2009 power = 0; // didn't scale it
2012 g_assert (dbl < 1E15);
2013 if (dbl < 1E14 && power < DECMAX) {
2016 g_assert(dbl >= 1E14);
2021 sdlMant.int64 = (int64_t)dbl;
2022 dbl -= (double)(int64_t)sdlMant.int64; // dif between input & integer
2023 if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)))
2026 if (sdlMant.int64 == 0) {
2027 DECIMAL_SETZERO(*result);
2028 return MONO_DECIMAL_OK;
2032 // Add -power factors of 10, -power <= (29 - 15) = 14.
2036 sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (uint32_t)long_power10[power]);
2037 sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (uint32_t)long_power10[power]);
2038 sdlMant.int64 += sdlLo.u.Hi;
2039 sdlLo.u.Hi = sdlMant.u.Lo;
2040 sdlMant.u.Lo = sdlMant.u.Hi;
2043 // Have a big power of 10.
2045 g_assert(power <= 14);
2046 sdlLo.int64 = UInt64x64To128(sdlMant, sdl_power10[power-10], &sdlMant.int64);
2048 if (sdlMant.u.Hi != 0)
2049 return MONO_DECIMAL_OVERFLOW;
2051 DECIMAL_LO32(*result) = sdlLo.u.Lo;
2052 DECIMAL_MID32(*result) = sdlLo.u.Hi;
2053 DECIMAL_HI32(*result) = sdlMant.u.Lo;
2054 DECIMAL_SCALE(*result) = 0;
2057 // Factor out powers of 10 to reduce the scale, if possible.
2058 // The maximum number we could factor out would be 14. This
2059 // comes from the fact we have a 15-digit number, and the
2060 // MSD must be non-zero -- but the lower 14 digits could be
2061 // zero. Note also the scale factor is never negative, so
2062 // we can't scale by any more than the power we used to
2065 // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
2067 lmax = min(power, 14);
2069 // lmax is the largest power of 10 to try, lmax <= 14.
2070 // We'll try powers 8, 4, 2, and 1 unless they're too big.
2072 for (cur = 8; cur > 0; cur >>= 1)
2077 pwr_cur = (uint32_t)long_power10[cur];
2079 if (sdlMant.u.Hi >= pwr_cur) {
2080 // Overflow if we try to divide in one step.
2082 sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, pwr_cur);
2084 sdlLo.u.Lo = sdlMant.u.Lo;
2085 sdlLo.int64 = DivMod64by32(sdlLo.int64, pwr_cur);
2089 sdlLo.int64 = DivMod64by32(sdlMant.int64, pwr_cur);
2092 if (sdlLo.u.Hi == 0) {
2094 sdlMant.u.Lo = sdlLo.u.Lo;
2100 DECIMAL_HI32(*result) = 0;
2101 DECIMAL_SCALE(*result) = power;
2102 DECIMAL_LO32(*result) = sdlMant.u.Lo;
2103 DECIMAL_MID32(*result) = sdlMant.u.Hi;
2106 DECIMAL_SIGN(*result) = (char)((DoubleStructure *)&input)->u.sign << 7;
2107 return MONO_DECIMAL_OK;
2110 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2111 static MonoDecimalStatus
2112 MONO_VarR8FromDec(MonoDecimal *input, double *result)
2117 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2118 return MONO_DECIMAL_INVALID_ARGUMENT;
2120 tmp.u.Lo = DECIMAL_LO32(*input);
2121 tmp.u.Hi = DECIMAL_MID32(*input);
2123 if ((int32_t)DECIMAL_MID32(*input) < 0)
2124 dbl = (ds2to64.dbl + (double)(int64_t)tmp.int64 +
2125 (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input)) ;
2127 dbl = ((double)(int64_t)tmp.int64 +
2128 (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input));
2130 if (DECIMAL_SIGN(*input))
2134 return MONO_DECIMAL_OK;
2137 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2138 static MonoDecimalStatus
2139 MONO_VarR4FromDec(MonoDecimal *input, float *result)
2143 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2144 return MONO_DECIMAL_INVALID_ARGUMENT;
2146 // Can't overflow; no errors possible.
2148 MONO_VarR8FromDec(input, &dbl);
2149 *result = (float)dbl;
2150 return MONO_DECIMAL_OK;
2154 DecShiftLeft(MonoDecimal* value)
2156 unsigned int c0 = DECIMAL_LO32(*value) & 0x80000000? 1: 0;
2157 unsigned int c1 = DECIMAL_MID32(*value) & 0x80000000? 1: 0;
2158 g_assert(value != NULL);
2160 DECIMAL_LO32(*value) <<= 1;
2161 DECIMAL_MID32(*value) = DECIMAL_MID32(*value) << 1 | c0;
2162 DECIMAL_HI32(*value) = DECIMAL_HI32(*value) << 1 | c1;
2166 D32AddCarry(uint32_t* value, uint32_t i)
2168 uint32_t v = *value;
2169 uint32_t sum = v + i;
2171 return sum < v || sum < i? 1: 0;
2175 DecAdd(MonoDecimal *value, MonoDecimal* d)
2177 g_assert(value != NULL && d != NULL);
2179 if (D32AddCarry(&DECIMAL_LO32(*value), DECIMAL_LO32(*d))) {
2180 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2181 D32AddCarry(&DECIMAL_HI32(*value), 1);
2184 if (D32AddCarry(&DECIMAL_MID32(*value), DECIMAL_MID32(*d))) {
2185 D32AddCarry(&DECIMAL_HI32(*value), 1);
2187 D32AddCarry(&DECIMAL_HI32(*value), DECIMAL_HI32(*d));
2191 DecMul10(MonoDecimal* value)
2193 MonoDecimal d = *value;
2194 g_assert (value != NULL);
2196 DecShiftLeft(value);
2197 DecShiftLeft(value);
2199 DecShiftLeft(value);
2203 DecAddInt32(MonoDecimal* value, unsigned int i)
2205 g_assert(value != NULL);
2207 if (D32AddCarry(&DECIMAL_LO32(*value), i)) {
2208 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2209 D32AddCarry(&DECIMAL_HI32(*value), 1);
2214 MonoDecimalCompareResult
2215 mono_decimal_compare (MonoDecimal *left, MonoDecimal *right)
2218 uint32_t right_sign;
2221 // First check signs and whether either are zero. If both are
2222 // non-zero and of the same sign, just use subtraction to compare.
2224 left_sign = left->v.v.Lo32 | left->v.v.Mid32 | left->Hi32;
2225 right_sign = right->v.v.Lo32 | right->v.v.Mid32 | right->Hi32;
2227 left_sign = (left->u.u.sign & DECIMAL_NEG) | 1;
2229 if (right_sign != 0)
2230 right_sign = (right->u.u.sign & DECIMAL_NEG) | 1;
2232 // left_sign & right_sign have values 1, 0, or 0x81 depending on if the left/right
2233 // operand is +, 0, or -.
2235 if (left_sign == right_sign) {
2236 if (left_sign == 0) // both are zero
2237 return MONO_DECIMAL_CMP_EQ; // return equal
2239 DecAddSub(left, right, &result, DECIMAL_NEG);
2240 if (DECIMAL_LO64_GET(result) == 0 && result.Hi32 == 0)
2241 return MONO_DECIMAL_CMP_EQ;
2242 if (result.u.u.sign & DECIMAL_NEG)
2243 return MONO_DECIMAL_CMP_LT;
2244 return MONO_DECIMAL_CMP_GT;
2248 // Signs are different. Used signed byte compares
2250 if ((char)left_sign > (char)right_sign)
2251 return MONO_DECIMAL_CMP_GT;
2252 return MONO_DECIMAL_CMP_LT;
2256 mono_decimal_init_single (MonoDecimal *_this, float value)
2258 if (MONO_VarDecFromR4 (value, _this) == MONO_DECIMAL_OVERFLOW) {
2259 mono_set_pending_exception (mono_get_exception_overflow ());
2262 _this->reserved = 0;
2266 mono_decimal_init_double (MonoDecimal *_this, double value)
2268 if (MONO_VarDecFromR8 (value, _this) == MONO_DECIMAL_OVERFLOW) {
2269 mono_set_pending_exception (mono_get_exception_overflow ());
2272 _this->reserved = 0;
2276 mono_decimal_floor (MonoDecimal *d)
2280 MONO_VarDecInt(d, &decRes);
2282 // copy decRes into d
2283 COPYDEC(*d, decRes);
2289 mono_decimal_get_hash_code (MonoDecimal *d)
2293 if (MONO_VarR8FromDec(d, &dbl) != MONO_DECIMAL_OK)
2297 // Ensure 0 and -0 have the same hash code
2300 // conversion to double is lossy and produces rounding errors so we mask off the lowest 4 bits
2302 // For example these two numerically equal decimals with different internal representations produce
2303 // slightly different results when converted to double:
2305 // decimal a = new decimal(new int[] { 0x76969696, 0x2fdd49fa, 0x409783ff, 0x00160000 });
2306 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.176470588
2307 // decimal b = new decimal(new int[] { 0x3f0f0f0f, 0x1e62edcc, 0x06758d33, 0x00150000 });
2308 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.1764705882
2310 return ((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
2315 mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2)
2319 MonoDecimalStatus status = MONO_VarDecMul(d1, d2, &decRes);
2320 if (status != MONO_DECIMAL_OK) {
2321 mono_set_pending_exception (mono_get_exception_overflow ());
2325 COPYDEC(*d1, decRes);
2332 mono_decimal_round (MonoDecimal *d, int32_t decimals)
2336 // GC is only triggered for throwing, no need to protect result
2337 if (decimals < 0 || decimals > 28) {
2338 mono_set_pending_exception (mono_get_exception_argument_out_of_range ("d"));
2342 MONO_VarDecRound(d, decimals, &decRes);
2344 // copy decRes into d
2345 COPYDEC(*d, decRes);
2352 mono_decimal_tocurrency (MonoDecimal *decimal)
2358 mono_decimal_to_double (MonoDecimal d)
2360 double result = 0.0;
2361 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2362 MONO_VarR8FromDec(&d, &result);
2367 mono_decimal_to_int32 (MonoDecimal d)
2371 // The following can not return an error, it only returns INVALID_ARG if the decimals is < 0
2372 MONO_VarDecRound(&d, 0, &result);
2374 if (DECIMAL_SCALE(result) != 0) {
2376 MONO_VarDecFix (&d, &result);
2379 if (DECIMAL_HI32(result) == 0 && DECIMAL_MID32(result) == 0) {
2380 int32_t i = DECIMAL_LO32(result);
2381 if ((int16_t)DECIMAL_SIGNSCALE(result) >= 0) {
2391 mono_set_pending_exception (mono_get_exception_overflow ());
2396 mono_decimal_to_float (MonoDecimal d)
2398 float result = 0.0f;
2399 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2400 MONO_VarR4FromDec(&d, &result);
2405 mono_decimal_truncate (MonoDecimal *d)
2409 MONO_VarDecFix(d, &decRes);
2411 // copy decRes into d
2412 COPYDEC(*d, decRes);
2418 mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign)
2420 MonoDecimal result, decTmp;
2421 MonoDecimal *pdecTmp, *leftOriginal;
2422 uint32_t num[6], pwr;
2423 int scale, hi_prod, cur;
2426 g_assert(sign == 0 || sign == DECIMAL_NEG);
2428 leftOriginal = left;
2430 sign ^= (DECIMAL_SIGN(*right) ^ DECIMAL_SIGN(*left)) & DECIMAL_NEG;
2432 if (DECIMAL_SCALE(*right) == DECIMAL_SCALE(*left)) {
2433 // Scale factors are equal, no alignment necessary.
2435 DECIMAL_SIGNSCALE(result) = DECIMAL_SIGNSCALE(*left);
2439 // Signs differ - subtract
2441 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right)));
2442 DECIMAL_HI32(result) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
2446 if (DECIMAL_LO64_GET(result) > DECIMAL_LO64_GET(*left)) {
2447 DECIMAL_HI32(result)--;
2448 if (DECIMAL_HI32(result) >= DECIMAL_HI32(*left))
2450 } else if (DECIMAL_HI32(result) > DECIMAL_HI32(*left)) {
2451 // Got negative result. Flip its sign.
2454 DECIMAL_LO64_SET(result, -(int64_t)DECIMAL_LO64_GET(result));
2455 DECIMAL_HI32(result) = ~DECIMAL_HI32(result);
2456 if (DECIMAL_LO64_GET(result) == 0)
2457 DECIMAL_HI32(result)++;
2458 DECIMAL_SIGN(result) ^= DECIMAL_NEG;
2462 // Signs are the same - add
2464 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right)));
2465 DECIMAL_HI32(result) = DECIMAL_HI32(*left) + DECIMAL_HI32(*right);
2469 if (DECIMAL_LO64_GET(result) < DECIMAL_LO64_GET(*left)) {
2470 DECIMAL_HI32(result)++;
2471 if (DECIMAL_HI32(result) <= DECIMAL_HI32(*left))
2473 } else if (DECIMAL_HI32(result) < DECIMAL_HI32(*left)) {
2475 // The addition carried above 96 bits. Divide the result by 10,
2476 // dropping the scale factor.
2478 if (DECIMAL_SCALE(result) == 0) {
2479 mono_set_pending_exception (mono_get_exception_overflow ());
2482 DECIMAL_SCALE(result)--;
2484 sdlTmp.u.Lo = DECIMAL_HI32(result);
2486 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2487 DECIMAL_HI32(result) = sdlTmp.u.Lo;
2489 sdlTmp.u.Lo = DECIMAL_MID32(result);
2490 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2491 DECIMAL_MID32(result) = sdlTmp.u.Lo;
2493 sdlTmp.u.Lo = DECIMAL_LO32(result);
2494 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2495 DECIMAL_LO32(result) = sdlTmp.u.Lo;
2497 // See if we need to round up.
2499 if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (DECIMAL_LO32(result) & 1))) {
2500 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(result)+1);
2501 if (DECIMAL_LO64_GET(result) == 0)
2502 DECIMAL_HI32(result)++;
2507 // Scale factors are not equal. Assume that a larger scale
2508 // factor (more decimal places) is likely to mean that number
2509 // is smaller. Start by guessing that the right operand has
2510 // the larger scale factor. The result will have the larger
2513 DECIMAL_SCALE(result) = DECIMAL_SCALE(*right); // scale factor of "smaller"
2514 DECIMAL_SIGN(result) = DECIMAL_SIGN(*left); // but sign of "larger"
2515 scale = DECIMAL_SCALE(result)- DECIMAL_SCALE(*left);
2518 // Guessed scale factor wrong. Swap operands.
2521 DECIMAL_SCALE(result) = DECIMAL_SCALE(*left);
2522 DECIMAL_SIGN(result) ^= sign;
2528 // *left will need to be multiplied by 10^scale so
2529 // it will have the same scale as *right. We could be
2530 // extending it to up to 192 bits of precision.
2532 if (scale <= POWER10_MAX) {
2533 // Scaling won't make it larger than 4 uint32_ts
2535 pwr = power10[scale];
2536 DECIMAL_LO64_SET(decTmp, UInt32x32To64(DECIMAL_LO32(*left), pwr));
2537 sdlTmp.int64 = UInt32x32To64(DECIMAL_MID32(*left), pwr);
2538 sdlTmp.int64 += DECIMAL_MID32(decTmp);
2539 DECIMAL_MID32(decTmp) = sdlTmp.u.Lo;
2540 DECIMAL_HI32(decTmp) = sdlTmp.u.Hi;
2541 sdlTmp.int64 = UInt32x32To64(DECIMAL_HI32(*left), pwr);
2542 sdlTmp.int64 += DECIMAL_HI32(decTmp);
2543 if (sdlTmp.u.Hi == 0) {
2544 // Result fits in 96 bits. Use standard aligned add.
2546 DECIMAL_HI32(decTmp) = sdlTmp.u.Lo;
2550 num[0] = DECIMAL_LO32(decTmp);
2551 num[1] = DECIMAL_MID32(decTmp);
2552 num[2] = sdlTmp.u.Lo;
2553 num[3] = sdlTmp.u.Hi;
2556 // Have to scale by a bunch. Move the number to a buffer
2557 // where it has room to grow as it's scaled.
2559 num[0] = DECIMAL_LO32(*left);
2560 num[1] = DECIMAL_MID32(*left);
2561 num[2] = DECIMAL_HI32(*left);
2564 // Scan for zeros in the upper words.
2571 // Left arg is zero, return right.
2573 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(*right));
2574 DECIMAL_HI32(result) = DECIMAL_HI32(*right);
2575 DECIMAL_SIGN(result) ^= sign;
2581 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
2582 // with index of highest non-zero uint32_t.
2584 for (; scale > 0; scale -= POWER10_MAX) {
2585 if (scale > POWER10_MAX)
2588 pwr = power10[scale];
2591 for (cur = 0; cur <= hi_prod; cur++) {
2592 sdlTmp.int64 = UInt32x32To64(num[cur], pwr) + sdlTmp.u.Hi;
2593 num[cur] = sdlTmp.u.Lo;
2596 if (sdlTmp.u.Hi != 0)
2597 // We're extending the result by another uint32_t.
2598 num[++hi_prod] = sdlTmp.u.Hi;
2602 // Scaling complete, do the add. Could be subtract if signs differ.
2604 sdlTmp.u.Lo = num[0];
2605 sdlTmp.u.Hi = num[1];
2608 // Signs differ, subtract.
2610 DECIMAL_LO64_SET(result, (sdlTmp.int64 - DECIMAL_LO64_GET(*right)));
2611 DECIMAL_HI32(result) = num[2] - DECIMAL_HI32(*right);
2615 if (DECIMAL_LO64_GET(result) > sdlTmp.int64) {
2616 DECIMAL_HI32(result)--;
2617 if (DECIMAL_HI32(result) >= num[2])
2619 } else if (DECIMAL_HI32(result) > num[2]) {
2621 // If num has more than 96 bits of precision, then we need to
2622 // carry the subtraction into the higher bits. If it doesn't,
2623 // then we subtracted in the wrong order and have to flip the
2624 // sign of the result.
2630 while(num[cur++]-- == 0);
2631 if (num[hi_prod] == 0)
2635 // Signs the same, add.
2637 DECIMAL_LO64_SET(result, (sdlTmp.int64 + DECIMAL_LO64_GET(*right)));
2638 DECIMAL_HI32(result) = num[2] + DECIMAL_HI32(*right);
2642 if (DECIMAL_LO64_GET(result) < sdlTmp.int64) {
2643 DECIMAL_HI32(result)++;
2644 if (DECIMAL_HI32(result) <= num[2])
2646 } else if (DECIMAL_HI32(result) < num[2]) {
2648 // Had a carry above 96 bits.
2652 if (hi_prod < cur) {
2657 }while (++num[cur++] == 0);
2662 num[0] = DECIMAL_LO32(result);
2663 num[1] = DECIMAL_MID32(result);
2664 num[2] = DECIMAL_HI32(result);
2665 DECIMAL_SCALE(result) = (uint8_t)ScaleResult(num, hi_prod, DECIMAL_SCALE(result));
2666 if (DECIMAL_SCALE(result) == (uint8_t)-1) {
2667 mono_set_pending_exception (mono_get_exception_overflow ());
2671 DECIMAL_LO32(result) = num[0];
2672 DECIMAL_MID32(result) = num[1];
2673 DECIMAL_HI32(result) = num[2];
2678 left = leftOriginal;
2679 COPYDEC(*left, result);
2684 mono_decimal_divide (MonoDecimal *left, MonoDecimal *right)
2686 uint32_t quo[3], quo_save[3],rem[4], divisor[3];
2687 uint32_t pwr, tmp, tmp1;
2688 SPLIT64 sdlTmp, sdlDivisor;
2689 int scale, cur_scale;
2692 scale = DECIMAL_SCALE(*left) - DECIMAL_SCALE(*right);
2694 divisor[0] = DECIMAL_LO32(*right);
2695 divisor[1] = DECIMAL_MID32(*right);
2696 divisor[2] = DECIMAL_HI32(*right);
2698 if (divisor[1] == 0 && divisor[2] == 0) {
2699 // Divisor is only 32 bits. Easy divide.
2701 if (divisor[0] == 0) {
2702 mono_set_pending_exception (mono_get_exception_divide_by_zero ());
2706 quo[0] = DECIMAL_LO32(*left);
2707 quo[1] = DECIMAL_MID32(*left);
2708 quo[2] = DECIMAL_HI32(*left);
2709 rem[0] = Div96By32(quo, divisor[0]);
2714 cur_scale = min(9, -scale);
2719 // We need to unscale if and only if we have a non-zero remainder
2722 // We have computed a quotient based on the natural scale
2723 // ( <dividend scale> - <divisor scale> ). We have a non-zero
2724 // remainder, so now we should increase the scale if possible to
2725 // include more quotient bits.
2727 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
2728 // computing more quotient bits as long as the remainder stays
2729 // non-zero. If scaling by that much would cause overflow, we'll
2730 // drop out of the loop and scale by as much as we can.
2732 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
2733 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
2734 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
2735 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
2736 // is the largest value in quo[1] (when quo[2] == 4) that is
2737 // assured not to overflow.
2739 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2740 if (cur_scale == 0) {
2741 // No more scaling to be done, but remainder is non-zero.
2745 if (tmp < rem[0] || (tmp >= divisor[0] &&
2746 (tmp > divisor[0] || (quo[0] & 1)))) {
2748 if (!Add32To96(quo, 1)) {
2750 mono_set_pending_exception (mono_get_exception_overflow ());
2754 OverflowUnscale(quo, TRUE);
2761 if (cur_scale < 0) {
2762 mono_set_pending_exception (mono_get_exception_overflow ());
2767 pwr = power10[cur_scale];
2770 if (IncreaseScale(quo, pwr) != 0) {
2771 mono_set_pending_exception (mono_get_exception_overflow ());
2775 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
2776 rem[0] = sdlTmp.u.Hi;
2778 if (!Add32To96(quo, sdlTmp.u.Lo)) {
2780 mono_set_pending_exception (mono_get_exception_overflow ());
2784 OverflowUnscale(quo, (rem[0] != 0));
2789 // Divisor has bits set in the upper 64 bits.
2791 // Divisor must be fully normalized (shifted so bit 31 of the most
2792 // significant uint32_t is 1). Locate the MSB so we know how much to
2793 // normalize by. The dividend will be shifted by the same amount so
2794 // the quotient is not changed.
2796 if (divisor[2] == 0)
2802 if (!(tmp & 0xFFFF0000)) {
2806 if (!(tmp & 0xFF000000)) {
2810 if (!(tmp & 0xF0000000)) {
2814 if (!(tmp & 0xC0000000)) {
2818 if (!(tmp & 0x80000000)) {
2823 // Shift both dividend and divisor left by cur_scale.
2825 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
2826 rem[0] = sdlTmp.u.Lo;
2827 rem[1] = sdlTmp.u.Hi;
2828 sdlTmp.u.Lo = DECIMAL_MID32(*left);
2829 sdlTmp.u.Hi = DECIMAL_HI32(*left);
2830 sdlTmp.int64 <<= cur_scale;
2831 rem[2] = sdlTmp.u.Hi;
2832 rem[3] = (DECIMAL_HI32(*left) >> (31 - cur_scale)) >> 1;
2834 sdlDivisor.u.Lo = divisor[0];
2835 sdlDivisor.u.Hi = divisor[1];
2836 sdlDivisor.int64 <<= cur_scale;
2838 if (divisor[2] == 0) {
2839 // Have a 64-bit divisor in sdlDivisor. The remainder
2840 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
2842 sdlTmp.u.Lo = rem[2];
2843 sdlTmp.u.Hi = rem[3];
2846 quo[1] = Div96By64(&rem[1], sdlDivisor);
2847 quo[0] = Div96By64(rem, sdlDivisor);
2850 if ((rem[0] | rem[1]) == 0) {
2852 cur_scale = min(9, -scale);
2858 // We need to unscale if and only if we have a non-zero remainder
2861 // Remainder is non-zero. Scale up quotient and remainder by
2862 // powers of 10 so we can compute more significant bits.
2864 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2865 if (cur_scale == 0) {
2866 // No more scaling to be done, but remainder is non-zero.
2869 sdlTmp.u.Lo = rem[0];
2870 sdlTmp.u.Hi = rem[1];
2871 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
2872 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
2877 if (cur_scale < 0) {
2878 mono_set_pending_exception (mono_get_exception_overflow ());
2883 pwr = power10[cur_scale];
2886 if (IncreaseScale(quo, pwr) != 0) {
2887 mono_set_pending_exception (mono_get_exception_overflow ());
2891 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
2892 IncreaseScale(rem, pwr);
2893 tmp = Div96By64(rem, sdlDivisor);
2894 if (!Add32To96(quo, tmp)) {
2896 mono_set_pending_exception (mono_get_exception_overflow ());
2900 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0));
2906 // Have a 96-bit divisor in divisor[].
2908 // Start by finishing the shift left by cur_scale.
2910 sdlTmp.u.Lo = divisor[1];
2911 sdlTmp.u.Hi = divisor[2];
2912 sdlTmp.int64 <<= cur_scale;
2913 divisor[0] = sdlDivisor.u.Lo;
2914 divisor[1] = sdlDivisor.u.Hi;
2915 divisor[2] = sdlTmp.u.Hi;
2917 // The remainder (currently 96 bits spread over 4 uint32_ts)
2918 // will be < divisor.
2922 quo[0] = Div128By96(rem, divisor);
2925 if ((rem[0] | rem[1] | rem[2]) == 0) {
2927 cur_scale = min(9, -scale);
2933 // We need to unscale if and only if we have a non-zero remainder
2936 // Remainder is non-zero. Scale up quotient and remainder by
2937 // powers of 10 so we can compute more significant bits.
2939 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2940 if (cur_scale == 0) {
2941 // No more scaling to be done, but remainder is non-zero.
2944 if (rem[2] >= 0x80000000)
2947 tmp = rem[0] > 0x80000000;
2948 tmp1 = rem[1] > 0x80000000;
2950 rem[1] = (rem[1] << 1) + tmp;
2951 rem[2] = (rem[2] << 1) + tmp1;
2953 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)))))))
2958 if (cur_scale < 0) {
2959 mono_set_pending_exception (mono_get_exception_overflow ());
2964 pwr = power10[cur_scale];
2967 if (IncreaseScale(quo, pwr) != 0) {
2968 mono_set_pending_exception (mono_get_exception_overflow ());
2972 rem[3] = IncreaseScale(rem, pwr);
2973 tmp = Div128By96(rem, divisor);
2974 if (!Add32To96(quo, tmp)) {
2976 mono_set_pending_exception (mono_get_exception_overflow ());
2981 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0 || rem[2] != 0 || rem[3] != 0));
2989 // We need to unscale if and only if we have a non-zero remainder
2991 // Try extracting any extra powers of 10 we may have
2992 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
2993 // If a division by one of these powers returns a zero remainder, then
2994 // we keep the quotient. If the remainder is not zero, then we restore
2995 // the previous value.
2997 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
2998 // we can extract. We use this as a quick test on whether to try a
3001 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
3002 quo_save[0] = quo[0];
3003 quo_save[1] = quo[1];
3004 quo_save[2] = quo[2];
3006 if (Div96By32(quo_save, 100000000) == 0) {
3007 quo[0] = quo_save[0];
3008 quo[1] = quo_save[1];
3009 quo[2] = quo_save[2];
3015 if ((quo[0] & 0xF) == 0 && scale >= 4) {
3016 quo_save[0] = quo[0];
3017 quo_save[1] = quo[1];
3018 quo_save[2] = quo[2];
3020 if (Div96By32(quo_save, 10000) == 0) {
3021 quo[0] = quo_save[0];
3022 quo[1] = quo_save[1];
3023 quo[2] = quo_save[2];
3028 if ((quo[0] & 3) == 0 && scale >= 2) {
3029 quo_save[0] = quo[0];
3030 quo_save[1] = quo[1];
3031 quo_save[2] = quo[2];
3033 if (Div96By32(quo_save, 100) == 0) {
3034 quo[0] = quo_save[0];
3035 quo[1] = quo_save[1];
3036 quo[2] = quo_save[2];
3041 if ((quo[0] & 1) == 0 && scale >= 1) {
3042 quo_save[0] = quo[0];
3043 quo_save[1] = quo[1];
3044 quo_save[2] = quo[2];
3046 if (Div96By32(quo_save, 10) == 0) {
3047 quo[0] = quo_save[0];
3048 quo[1] = quo_save[1];
3049 quo[2] = quo_save[2];
3055 DECIMAL_SIGN(*left) = DECIMAL_SIGN(*left) ^ DECIMAL_SIGN(*right);
3056 DECIMAL_HI32(*left) = quo[2];
3057 DECIMAL_MID32(*left) = quo[1];
3058 DECIMAL_LO32(*left) = quo[0];
3059 DECIMAL_SCALE(*left) = (uint8_t)scale;
3064 #define DECIMAL_PRECISION 29
3065 #define NUMBER_MAXDIGITS 50
3070 uint16_t digits[NUMBER_MAXDIGITS + 1];
3071 uint16_t* allDigits;
3075 mono_decimal_from_number (void *from, MonoDecimal *target)
3077 CLRNumber *number = (CLRNumber *) from;
3078 uint16_t* p = number->digits;
3080 int e = number->scale;
3081 g_assert(number != NULL);
3082 g_assert(target != NULL);
3085 DECIMAL_SIGNSCALE(d) = 0;
3086 DECIMAL_HI32(d) = 0;
3087 DECIMAL_LO32(d) = 0;
3088 DECIMAL_MID32(d) = 0;
3089 g_assert(p != NULL);
3091 // 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
3092 // the scale to 0 if the scale was previously positive
3097 if (e > DECIMAL_PRECISION) return 0;
3098 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'))))))) {
3101 DecAddInt32(&d, *p++ - '0');
3105 gboolean round = TRUE;
3106 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
3107 // For digits > 5 we will be roundinp up anyway.
3108 int count = 20; // Look at the next 20 digits to check to round
3109 while (*p == '0' && count != 0) {
3113 if (*p == '\0' || count == 0)
3114 round = FALSE;// Do nothing
3119 if ((DECIMAL_HI32(d) | DECIMAL_MID32(d) | DECIMAL_LO32(d)) == 0) {
3120 DECIMAL_HI32(d) = 0x19999999;
3121 DECIMAL_MID32(d) = 0x99999999;
3122 DECIMAL_LO32(d) = 0x9999999A;
3130 if (e <= -DECIMAL_PRECISION) {
3131 // Parsing a large scale zero can give you more precision than fits in the decimal.
3132 // This should only happen for actual zeros or very small numbers that round to zero.
3133 DECIMAL_SIGNSCALE(d) = 0;
3134 DECIMAL_HI32(d) = 0;
3135 DECIMAL_LO32(d) = 0;
3136 DECIMAL_MID32(d) = 0;
3137 DECIMAL_SCALE(d) = (DECIMAL_PRECISION - 1);
3139 DECIMAL_SCALE(d) = (uint8_t)(-e);
3142 DECIMAL_SIGN(d) = number->sign? DECIMAL_NEG: 0;