3 * Copyright (c) Microsoft. All rights reserved.
4 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 * Copyright 2015 Xamarin Inc
10 * Ported from C++ to C and adjusted to Mono runtime
13 * DoToCurrency (they look like new methods we do not have)
15 #ifndef DISABLE_DECIMAL
19 #include <mono/utils/mono-compiler.h>
20 #include <mono/metadata/exception.h>
21 #include <mono/metadata/object-internals.h>
32 #include "decimal-ms.h"
33 #include "number-ms.h"
35 #define min(a, b) (((a) < (b)) ? (a) : (b))
39 MONO_DECIMAL_OVERFLOW,
40 MONO_DECIMAL_INVALID_ARGUMENT,
41 MONO_DECIMAL_DIVBYZERO,
42 MONO_DECIMAL_ARGUMENT_OUT_OF_RANGE
49 static const uint32_t ten_to_nine = 1000000000U;
50 static const uint32_t ten_to_ten_div_4 = 2500000000U;
52 #define DECIMAL_NEG ((uint8_t)0x80)
54 #define DECIMAL_SCALE(dec) ((dec).u.u.scale)
55 #define DECIMAL_SIGN(dec) ((dec).u.u.sign)
56 #define DECIMAL_SIGNSCALE(dec) ((dec).u.signscale)
57 #define DECIMAL_LO32(dec) ((dec).v.v.Lo32)
58 #define DECIMAL_MID32(dec) ((dec).v.v.Mid32)
59 #define DECIMAL_HI32(dec) ((dec).Hi32)
60 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
61 # define DECIMAL_LO64_GET(dec) (((uint64_t)((dec).v.v.Mid32) << 32) | (dec).v.v.Lo32)
62 # define DECIMAL_LO64_SET(dec,value) {(dec).v.v.Lo32 = (value); (dec).v.v.Mid32 = ((value) >> 32); }
64 # define DECIMAL_LO64_GET(dec) ((dec).v.Lo64)
65 # define DECIMAL_LO64_SET(dec,value) {(dec).v.Lo64 = value; }
68 #define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
69 #define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
70 DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
72 #define DEC_SCALE_MAX 28
75 #define OVFL_MAX_9_HI 4
76 #define OVFL_MAX_9_MID 1266874889
77 #define OVFL_MAX_9_LO 3047500985u
79 #define OVFL_MAX_5_HI 42949
80 #define OVFL_MAX_5_MID 2890341191
82 #define OVFL_MAX_1_HI 429496729
87 #if BYTE_ORDER == G_BIG_ENDIAN
97 static const SPLIT64 ten_to_eighteen = { 1000000000000000000ULL };
99 const MonoDouble_double ds2to64 = { .s = { .sign = 0, .exp = MONO_DOUBLE_BIAS + 65, .mantHi = 0, .mantLo = 0 } };
105 static const uint32_t power10 [POWER10_MAX+1] = {
106 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
110 static const double double_power10[] = {
111 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
112 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
113 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
114 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
115 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
116 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
117 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
118 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
121 const SPLIT64 sdl_power10[] = { {10000000000ULL}, // 1E10
122 {100000000000ULL}, // 1E11
123 {1000000000000ULL}, // 1E12
124 {10000000000000ULL}, // 1E13
125 {100000000000000ULL} }; // 1E14
127 static const uint64_t long_power10[] = {
144 10000000000000000ULL,
145 100000000000000000ULL,
146 1000000000000000000ULL,
147 10000000000000000000ULL};
150 uint32_t Hi, Mid, Lo;
153 const DECOVFL power_overflow[] = {
154 // This is a table of the largest values that can be in the upper two
155 // ULONGs of a 96-bit number that will not overflow when multiplied
156 // by a given power. For the upper word, this is a table of
157 // 2^32 / 10^n for 1 <= n <= 9. For the lower word, this is the
158 // remaining fraction part * 2^32. 2^32 = 4294967296.
160 { 429496729u, 2576980377u, 2576980377u }, // 10^1 remainder 0.6
161 { 42949672u, 4123168604u, 687194767u }, // 10^2 remainder 0.16
162 { 4294967u, 1271310319u, 2645699854u }, // 10^3 remainder 0.616
163 { 429496u, 3133608139u, 694066715u }, // 10^4 remainder 0.1616
164 { 42949u, 2890341191u, 2216890319u }, // 10^5 remainder 0.51616
165 { 4294u, 4154504685u, 2369172679u }, // 10^6 remainder 0.551616
166 { 429u, 2133437386u, 4102387834u }, // 10^7 remainder 0.9551616
167 { 42u, 4078814305u, 410238783u }, // 10^8 remainder 0.09991616
168 { 4u, 1266874889u, 3047500985u }, // 10^9 remainder 0.709551616
172 #define UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b)))
173 #define Div64by32(num, den) ((uint32_t)((uint64_t)(num) / (uint32_t)(den)))
174 #define Mod64by32(num, den) ((uint32_t)((uint64_t)(num) % (uint32_t)(den)))
179 const int maxIx = (sizeof(double_power10)/sizeof(double_power10[0]));
182 return double_power10[ix];
183 return pow(10.0, ix);
184 } // double fnDblPower10()
187 static inline int64_t
188 DivMod32by32(int32_t num, int32_t den)
192 sdl.u.Lo = num / den;
193 sdl.u.Hi = num % den;
197 static inline int64_t
198 DivMod64by32(int64_t num, int32_t den)
202 sdl.u.Lo = Div64by32(num, den);
203 sdl.u.Hi = Mod64by32(num, den);
208 UInt64x64To128(SPLIT64 op1, SPLIT64 op2, uint64_t *hi)
214 tmp1.int64 = UInt32x32To64(op1.u.Lo, op2.u.Lo); // lo partial prod
215 tmp2.int64 = UInt32x32To64(op1.u.Lo, op2.u.Hi); // mid 1 partial prod
216 tmp1.u.Hi += tmp2.u.Lo;
217 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
219 tmp3.int64 = UInt32x32To64(op1.u.Hi, op2.u.Hi) + (uint64_t)tmp2.u.Hi;
220 tmp2.int64 = UInt32x32To64(op1.u.Hi, op2.u.Lo);
221 tmp1.u.Hi += tmp2.u.Lo;
222 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
224 tmp3.int64 += (uint64_t)tmp2.u.Hi;
234 * pdlNum - Pointer to 64-bit dividend
235 * ulDen - 32-bit divisor
238 * Do full divide, yielding 64-bit result and 32-bit remainder.
241 * Quotient overwrites dividend.
247 // Was: FullDiv64By32
249 FullDiv64By32 (uint64_t *num, uint32_t den)
257 if (tmp.u.Hi >= den) {
258 // DivMod64by32 returns quotient in Lo, remainder in Hi.
261 res.int64 = DivMod64by32(res.int64, den);
266 tmp.int64 = DivMod64by32(tmp.int64, den);
276 * res_hi - Top uint32_t of quotient
277 * res_mid - Middle uint32_t of quotient
278 * res_lo - Bottom uint32_t of quotient
279 * scale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
282 * Determine the max power of 10, <= 9, that the quotient can be scaled
283 * up by and still fit in 96 bits.
286 * Returns power of 10 to scale by, -1 if overflow error.
288 ***********************************************************************/
291 SearchScale(uint32_t res_hi, uint32_t res_mid, uint32_t res_lo, int scale)
295 // Quick check to stop us from trying to scale any more.
297 if (res_hi > OVFL_MAX_1_HI || scale >= DEC_SCALE_MAX) {
302 if (scale > DEC_SCALE_MAX - 9) {
303 // We can't scale by 10^9 without exceeding the max scale factor.
304 // See if we can scale to the max. If not, we'll fall into
305 // standard search for scale factor.
307 cur_scale = DEC_SCALE_MAX - scale;
308 if (res_hi < power_overflow[cur_scale - 1].Hi)
311 if (res_hi == power_overflow[cur_scale - 1].Hi) {
313 if (res_mid > power_overflow[cur_scale - 1].Mid ||
314 (res_mid == power_overflow[cur_scale - 1].Mid && res_lo > power_overflow[cur_scale - 1].Lo)) {
319 } 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))
322 // Search for a power to scale by < 9. Do a binary search
323 // on power_overflow[].
326 if (res_hi < OVFL_MAX_5_HI)
328 else if (res_hi > OVFL_MAX_5_HI)
333 // cur_scale is 3 or 7.
335 if (res_hi < power_overflow[cur_scale - 1].Hi)
337 else if (res_hi > power_overflow[cur_scale - 1].Hi)
342 // cur_scale is 2, 4, 6, or 8.
344 // In all cases, we already found we could not use the power one larger.
345 // So if we can use this power, it is the biggest, and we're done. If
346 // we can't use this power, the one below it is correct for all cases
347 // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
349 if (res_hi > power_overflow[cur_scale - 1].Hi)
352 if (res_hi == power_overflow[cur_scale - 1].Hi)
356 // cur_scale = largest power of 10 we can scale by without overflow,
357 // cur_scale < 9. See if this is enough to make scale factor
358 // positive if it isn't already.
360 if (cur_scale + scale < 0)
371 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
372 * ulDen - 32-bit divisor.
375 * Do full divide, yielding 96-bit result and 32-bit remainder.
378 * Quotient overwrites dividend.
386 Div96By32(uint32_t *num, uint32_t den)
404 tmp.int64 = DivMod64by32(tmp.int64, den);
408 tmp.int64 = DivMod64by32(tmp.int64, den);
412 tmp.int64 = DivMod64by32(tmp.int64, den);
421 * pdecRes - Pointer to Decimal result location
422 * operand - Pointer to Decimal operand
425 * Chop the value to integer. Return remainder so Int() function
426 * can round down if non-zero.
434 ***********************************************************************/
437 DecFixInt(MonoDecimal * result, MonoDecimal * operand)
444 if (operand->u.u.scale > 0) {
445 num[0] = operand->v.v.Lo32;
446 num[1] = operand->v.v.Mid32;
447 num[2] = operand->Hi32;
448 scale = operand->u.u.scale;
449 result->u.u.sign = operand->u.u.sign;
453 if (scale > POWER10_MAX)
456 pwr = power10[scale];
458 rem |= Div96By32(num, pwr);
462 result->v.v.Lo32 = num[0];
463 result->v.v.Mid32 = num[1];
464 result->Hi32 = num[2];
465 result->u.u.scale = 0;
470 COPYDEC(*result, *operand);
471 // Odd, the Microsoft code does not set result->reserved to zero on this case
479 * res - Array of uint32_ts with value, least-significant first.
480 * hi_res - Index of last non-zero value in res.
481 * scale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
484 * See if we need to scale the result to fit it in 96 bits.
485 * Perform needed scaling. Adjust scale factor accordingly.
488 * res updated in place, always 3 uint32_ts.
489 * New scale factor returned, -1 if overflow error.
493 ScaleResult(uint32_t *res, int hi_res, int scale)
502 // See if we need to scale the result. The combined scale must
503 // be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
505 // Start by figuring a lower bound on the scaling needed to make
506 // the upper 96 bits zero. hi_res is the index into res[]
507 // of the highest non-zero uint32_t.
509 new_scale = hi_res * 32 - 64 - 1;
515 if (!(tmp & 0xFFFF0000)) {
519 if (!(tmp & 0xFF000000)) {
523 if (!(tmp & 0xF0000000)) {
527 if (!(tmp & 0xC0000000)) {
531 if (!(tmp & 0x80000000)) {
536 // Multiply bit position by log10(2) to figure it's power of 10.
537 // We scale the log by 256. log(2) = .30103, * 256 = 77. Doing this
538 // with a multiply saves a 96-byte lookup table. The power returned
539 // is <= the power of the number, so we must add one power of 10
540 // to make it's integer part zero after dividing by 256.
542 // Note: the result of this multiplication by an approximation of
543 // log10(2) have been exhaustively checked to verify it gives the
544 // correct result. (There were only 95 to check...)
546 new_scale = ((new_scale * 77) >> 8) + 1;
548 // new_scale = min scale factor to make high 96 bits zero, 0 - 29.
549 // This reduces the scale factor of the result. If it exceeds the
550 // current scale of the result, we'll overflow.
552 if (new_scale > scale)
558 // Make sure we scale by enough to bring the current scale factor
561 if (new_scale < scale - DEC_SCALE_MAX)
562 new_scale = scale - DEC_SCALE_MAX;
564 if (new_scale != 0) {
565 // Scale by the power of 10 given by new_scale. Note that this is
566 // NOT guaranteed to bring the number within 96 bits -- it could
567 // be 1 power of 10 short.
571 sdlTmp.u.Hi = 0; // initialize remainder
575 sticky |= sdlTmp.u.Hi; // record remainder as sticky bit
577 if (new_scale > POWER10_MAX)
580 pwr = power10[new_scale];
582 // Compute first quotient.
583 // DivMod64by32 returns quotient in Lo, remainder in Hi.
585 sdlTmp.int64 = DivMod64by32(res[hi_res], pwr);
586 res[hi_res] = sdlTmp.u.Lo;
590 // If first quotient was 0, update hi_res.
592 if (sdlTmp.u.Lo == 0)
595 // Compute subsequent quotients.
598 sdlTmp.u.Lo = res[cur];
599 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, pwr);
600 res[cur] = sdlTmp.u.Lo;
606 new_scale -= POWER10_MAX;
608 continue; // scale some more
610 // If we scaled enough, hi_res would be 2 or less. If not,
611 // divide by 10 more.
616 continue; // scale by 10
619 // Round final result. See if remainder >= 1/2 of divisor.
620 // If remainder == 1/2 divisor, round up if odd or sticky bit set.
622 pwr >>= 1; // power of 10 always even
623 if ( pwr <= sdlTmp.u.Hi && (pwr < sdlTmp.u.Hi ||
624 ((res[0] & 1) | sticky)) ) {
626 while (++res[++cur] == 0);
629 // The rounding caused us to carry beyond 96 bits.
633 sticky = 0; // no sticky bit
634 sdlTmp.u.Hi = 0; // or remainder
637 continue; // scale by 10
641 // We may have scaled it more than we planned. Make sure the scale
642 // factor hasn't gone negative, indicating overflow.
654 // Returns: MONO_DECIMAL_OVERFLOW or MONO_DECIMAL_OK
655 static MonoDecimalStatus
656 mono_decimal_multiply_result(MonoDecimal * left, MonoDecimal * right, MonoDecimal * result)
668 scale = left->u.u.scale + right->u.u.scale;
670 if ((left->Hi32 | left->v.v.Mid32 | right->Hi32 | right->v.v.Mid32) == 0) {
671 // Upper 64 bits are zero.
673 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
674 if (scale > DEC_SCALE_MAX)
676 // Result scale is too big. Divide result by power of 10 to reduce it.
677 // If the amount to divide by is > 19 the result is guaranteed
678 // less than 1/2. [max value in 64 bits = 1.84E19]
680 scale -= DEC_SCALE_MAX;
683 DECIMAL_SETZERO(*result);
684 return MONO_DECIMAL_OK;
687 if (scale > POWER10_MAX) {
688 // Divide by 1E10 first, to get the power down to a 32-bit quantity.
689 // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
690 // then multiply the next divisor by 4 (which will be a max of 4E9).
692 rem_lo = FullDiv64By32(&tmp.int64, ten_to_ten_div_4);
693 pwr = power10[scale - 10] << 2;
695 pwr = power10[scale];
699 // Power to divide by fits in 32 bits.
701 rem_hi = FullDiv64By32(&tmp.int64, pwr);
703 // Round result. See if remainder >= 1/2 of divisor.
704 // Divisor is a power of 10, so it is always even.
707 if (rem_hi >= pwr && (rem_hi > pwr || (rem_lo | (tmp.u.Lo & 1))))
710 scale = DEC_SCALE_MAX;
712 DECIMAL_LO32(*result) = tmp.u.Lo;
713 DECIMAL_MID32(*result) = tmp.u.Hi;
714 DECIMAL_HI32(*result) = 0;
716 // At least one operand has bits set in the upper 64 bits.
718 // Compute and accumulate the 9 partial products into a
719 // 192-bit (24-byte) result.
721 // [l-h][l-m][l-l] left high, middle, low
722 // x [r-h][r-m][r-l] right high, middle, low
723 // ------------------------------
725 // [0-h][0-l] l-l * r-l
726 // [1ah][1al] l-l * r-m
727 // [1bh][1bl] l-m * r-l
728 // [2ah][2al] l-m * r-m
729 // [2bh][2bl] l-l * r-h
730 // [2ch][2cl] l-h * r-l
731 // [3ah][3al] l-m * r-h
732 // [3bh][3bl] l-h * r-m
733 // [4-h][4-l] l-h * r-h
734 // ------------------------------
735 // [p-5][p-4][p-3][p-2][p-1][p-0] prod[] array
737 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
740 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Mid32) + tmp.u.Hi;
742 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Lo32);
743 tmp.int64 += tmp2.int64; // this could generate carry
745 if (tmp.int64 < tmp2.int64) // detect carry
749 tmp2.u.Lo = tmp.u.Hi;
751 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Mid32) + tmp2.int64;
753 if (left->Hi32 | right->Hi32) {
754 // Highest 32 bits is non-zero. Calculate 5 more partial products.
756 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->Hi32);
757 tmp.int64 += tmp2.int64; // this could generate carry
758 if (tmp.int64 < tmp2.int64) // detect carry
763 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Lo32);
764 tmp.int64 += tmp2.int64; // this could generate carry
766 if (tmp.int64 < tmp2.int64) // detect carry
768 tmp3.u.Lo = tmp.u.Hi;
770 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->Hi32);
771 tmp.int64 += tmp3.int64; // this could generate carry
772 if (tmp.int64 < tmp3.int64) // detect carry
777 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Mid32);
778 tmp.int64 += tmp2.int64; // this could generate carry
780 if (tmp.int64 < tmp2.int64) // detect carry
782 tmp3.u.Lo = tmp.u.Hi;
784 tmp.int64 = UInt32x32To64(left->Hi32, right->Hi32) + tmp3.int64;
796 // Check for leading zero uint32_ts on the product
798 while (prod[hi_prod] == 0) {
804 scale = ScaleResult(prod, hi_prod, scale);
806 return MONO_DECIMAL_OVERFLOW;
808 result->v.v.Lo32 = prod[0];
809 result->v.v.Mid32 = prod[1];
810 result->Hi32 = prod[2];
813 result->u.u.sign = right->u.u.sign ^ left->u.u.sign;
814 result->u.u.scale = (char)scale;
815 return MONO_DECIMAL_OK;
818 // Addition and subtraction
819 static MonoDecimalStatus
820 DecAddSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result, int8_t sign)
830 MonoDecimal *pdecTmp;
832 sign ^= (right->u.u.sign ^ left->u.u.sign) & DECIMAL_NEG;
834 if (right->u.u.scale == left->u.u.scale) {
835 // Scale factors are equal, no alignment necessary.
837 decRes.u.signscale = left->u.signscale;
841 // Signs differ - subtract
843 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right));
844 DECIMAL_HI32(decRes) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
848 if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*left)) {
850 if (decRes.Hi32 >= left->Hi32)
852 } else if (decRes.Hi32 > left->Hi32) {
853 // Got negative result. Flip its sign.
856 DECIMAL_LO64_SET(decRes, -(uint64_t)DECIMAL_LO64_GET(decRes));
857 decRes.Hi32 = ~decRes.Hi32;
858 if (DECIMAL_LO64_GET(decRes) == 0)
860 decRes.u.u.sign ^= DECIMAL_NEG;
864 // Signs are the same - add
866 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right));
867 decRes.Hi32 = left->Hi32 + right->Hi32;
871 if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*left)) {
873 if (decRes.Hi32 <= left->Hi32)
875 } else if (decRes.Hi32 < left->Hi32) {
877 // The addition carried above 96 bits. Divide the result by 10,
878 // dropping the scale factor.
880 if (decRes.u.u.scale == 0)
881 return MONO_DECIMAL_OVERFLOW;
884 tmp.u.Lo = decRes.Hi32;
886 tmp.int64 = DivMod64by32(tmp.int64, 10);
887 decRes.Hi32 = tmp.u.Lo;
889 tmp.u.Lo = decRes.v.v.Mid32;
890 tmp.int64 = DivMod64by32(tmp.int64, 10);
891 decRes.v.v.Mid32 = tmp.u.Lo;
893 tmp.u.Lo = decRes.v.v.Lo32;
894 tmp.int64 = DivMod64by32(tmp.int64, 10);
895 decRes.v.v.Lo32 = tmp.u.Lo;
897 // See if we need to round up.
899 if (tmp.u.Hi >= 5 && (tmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
900 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
901 if (DECIMAL_LO64_GET(decRes) == 0)
908 // Scale factors are not equal. Assume that a larger scale
909 // factor (more decimal places) is likely to mean that number
910 // is smaller. Start by guessing that the right operand has
911 // the larger scale factor. The result will have the larger
914 decRes.u.u.scale = right->u.u.scale; // scale factor of "smaller"
915 decRes.u.u.sign = left->u.u.sign; // but sign of "larger"
916 scale = decRes.u.u.scale - left->u.u.scale;
919 // Guessed scale factor wrong. Swap operands.
922 decRes.u.u.scale = left->u.u.scale;
923 decRes.u.u.sign ^= sign;
929 // *left will need to be multiplied by 10^scale so
930 // it will have the same scale as *right. We could be
931 // extending it to up to 192 bits of precision.
933 if (scale <= POWER10_MAX) {
934 // Scaling won't make it larger than 4 uint32_ts
936 pwr = power10[scale];
937 DECIMAL_LO64_SET(decTmp, UInt32x32To64(left->v.v.Lo32, pwr));
938 tmp.int64 = UInt32x32To64(left->v.v.Mid32, pwr);
939 tmp.int64 += decTmp.v.v.Mid32;
940 decTmp.v.v.Mid32 = tmp.u.Lo;
941 decTmp.Hi32 = tmp.u.Hi;
942 tmp.int64 = UInt32x32To64(left->Hi32, pwr);
943 tmp.int64 += decTmp.Hi32;
945 // Result fits in 96 bits. Use standard aligned add.
947 decTmp.Hi32 = tmp.u.Lo;
951 num[0] = decTmp.v.v.Lo32;
952 num[1] = decTmp.v.v.Mid32;
958 // Have to scale by a bunch. Move the number to a buffer
959 // where it has room to grow as it's scaled.
961 num[0] = left->v.v.Lo32;
962 num[1] = left->v.v.Mid32;
966 // Scan for zeros in the upper words.
973 // Left arg is zero, return right.
975 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*right));
976 decRes.Hi32 = right->Hi32;
977 decRes.u.u.sign ^= sign;
983 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
984 // with index of highest non-zero uint32_t.
986 for (; scale > 0; scale -= POWER10_MAX) {
987 if (scale > POWER10_MAX)
990 pwr = power10[scale];
993 for (cur = 0; cur <= hi_prod; cur++) {
994 tmp.int64 = UInt32x32To64(num[cur], pwr) + tmp.u.Hi;
999 // We're extending the result by another uint32_t.
1000 num[++hi_prod] = tmp.u.Hi;
1004 // Scaling complete, do the add. Could be subtract if signs differ.
1010 // Signs differ, subtract.
1012 DECIMAL_LO64_SET(decRes, tmp.int64 - DECIMAL_LO64_GET(*right));
1013 decRes.Hi32 = num[2] - right->Hi32;
1017 if (DECIMAL_LO64_GET(decRes) > tmp.int64) {
1019 if (decRes.Hi32 >= num[2])
1022 else if (decRes.Hi32 > num[2]) {
1024 // If num has more than 96 bits of precision, then we need to
1025 // carry the subtraction into the higher bits. If it doesn't,
1026 // then we subtracted in the wrong order and have to flip the
1027 // sign of the result.
1033 while(num[cur++]-- == 0);
1034 if (num[hi_prod] == 0)
1039 // Signs the same, add.
1041 DECIMAL_LO64_SET(decRes, tmp.int64 + DECIMAL_LO64_GET(*right));
1042 decRes.Hi32 = num[2] + right->Hi32;
1046 if (DECIMAL_LO64_GET(decRes) < tmp.int64) {
1048 if (decRes.Hi32 <= num[2])
1051 else if (decRes.Hi32 < num[2]) {
1053 // Had a carry above 96 bits.
1057 if (hi_prod < cur) {
1062 }while (++num[cur++] == 0);
1067 num[0] = decRes.v.v.Lo32;
1068 num[1] = decRes.v.v.Mid32;
1069 num[2] = decRes.Hi32;
1070 decRes.u.u.scale = ScaleResult(num, hi_prod, decRes.u.u.scale);
1071 if (decRes.u.u.scale == (uint8_t) -1)
1072 return MONO_DECIMAL_OVERFLOW;
1074 decRes.v.v.Lo32 = num[0];
1075 decRes.v.v.Mid32 = num[1];
1076 decRes.Hi32 = num[2];
1081 COPYDEC(*result, decRes);
1082 // Odd, the Microsoft code does not set result->reserved to zero on this case
1083 return MONO_DECIMAL_OK;
1087 static MonoDecimalStatus G_GNUC_UNUSED
1088 mono_decimal_add(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1090 return DecAddSub (left, right, result, 0);
1093 // Decimal subtraction
1094 static MonoDecimalStatus G_GNUC_UNUSED
1095 mono_decimal_sub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1097 return DecAddSub (left, right, result, DECIMAL_NEG);
1104 * num - Pointer to 96-bit number as array of uint32_ts, least-sig first
1105 * pwr - Scale factor to multiply by
1108 * Multiply the two numbers. The low 96 bits of the result overwrite
1109 * the input. The last 32 bits of the product are the return value.
1112 * Returns highest 32 bits of product.
1119 IncreaseScale(uint32_t *num, uint32_t pwr)
1123 sdlTmp.int64 = UInt32x32To64(num[0], pwr);
1124 num[0] = sdlTmp.u.Lo;
1125 sdlTmp.int64 = UInt32x32To64(num[1], pwr) + sdlTmp.u.Hi;
1126 num[1] = sdlTmp.u.Lo;
1127 sdlTmp.int64 = UInt32x32To64(num[2], pwr) + sdlTmp.u.Hi;
1128 num[2] = sdlTmp.u.Lo;
1136 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
1137 * sdlDen - 64-bit divisor.
1140 * Do partial divide, yielding 32-bit result and 64-bit remainder.
1141 * Divisor must be larger than upper 64 bits of dividend.
1144 * Remainder overwrites lower 64-bits of dividend.
1152 Div96By64(uint32_t *num, SPLIT64 den)
1158 sdlNum.u.Lo = num[0];
1160 if (num[2] >= den.u.Hi) {
1161 // Divide would overflow. Assume a quotient of 2^32, and set
1162 // up remainder accordingly. Then jump to loop which reduces
1165 sdlNum.u.Hi = num[1] - den.u.Lo;
1170 // Hardware divide won't overflow
1172 if (num[2] == 0 && num[1] < den.u.Hi)
1173 // Result is zero. Entire dividend is remainder.
1177 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1181 quo.int64 = DivMod64by32(quo.int64, den.u.Hi);
1182 sdlNum.u.Hi = quo.u.Hi; // remainder
1184 // Compute full remainder, rem = dividend - (quo * divisor).
1186 prod.int64 = UInt32x32To64(quo.u.Lo, den.u.Lo); // quo * lo divisor
1187 sdlNum.int64 -= prod.int64;
1189 if (sdlNum.int64 > ~prod.int64) {
1191 // Remainder went negative. Add divisor back in until it's positive,
1192 // a max of 2 times.
1196 sdlNum.int64 += den.int64;
1197 }while (sdlNum.int64 >= den.int64);
1200 num[0] = sdlNum.u.Lo;
1201 num[1] = sdlNum.u.Hi;
1209 * rgulNum - Pointer to 128-bit dividend as array of uint32_ts, least-sig first
1210 * den - Pointer to 96-bit divisor.
1213 * Do partial divide, yielding 32-bit result and 96-bit remainder.
1214 * Top divisor uint32_t must be larger than top dividend uint32_t. This is
1215 * assured in the initial call because the divisor is normalized
1216 * and the dividend can't be. In subsequent calls, the remainder
1217 * is multiplied by 10^9 (max), so it can be no more than 1/4 of
1218 * the divisor which is effectively multiplied by 2^32 (4 * 10^9).
1221 * Remainder overwrites lower 96-bits of dividend.
1227 ***********************************************************************/
1230 Div128By96(uint32_t *num, uint32_t *den)
1237 sdlNum.u.Lo = num[0];
1238 sdlNum.u.Hi = num[1];
1240 if (num[3] == 0 && num[2] < den[2]){
1241 // Result is zero. Entire dividend is remainder.
1246 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1248 sdlQuo.u.Lo = num[2];
1249 sdlQuo.u.Hi = num[3];
1250 sdlQuo.int64 = DivMod64by32(sdlQuo.int64, den[2]);
1252 // Compute full remainder, rem = dividend - (quo * divisor).
1254 sdlProd1.int64 = UInt32x32To64(sdlQuo.u.Lo, den[0]); // quo * lo divisor
1255 sdlProd2.int64 = UInt32x32To64(sdlQuo.u.Lo, den[1]); // quo * mid divisor
1256 sdlProd2.int64 += sdlProd1.u.Hi;
1257 sdlProd1.u.Hi = sdlProd2.u.Lo;
1259 sdlNum.int64 -= sdlProd1.int64;
1260 num[2] = sdlQuo.u.Hi - sdlProd2.u.Hi; // sdlQuo.Hi is remainder
1262 // Propagate carries
1264 if (sdlNum.int64 > ~sdlProd1.int64) {
1266 if (num[2] >= ~sdlProd2.u.Hi)
1268 } else if (num[2] > ~sdlProd2.u.Hi) {
1270 // Remainder went negative. Add divisor back in until it's positive,
1271 // a max of 2 times.
1273 sdlProd1.u.Lo = den[0];
1274 sdlProd1.u.Hi = den[1];
1278 sdlNum.int64 += sdlProd1.int64;
1281 if (sdlNum.int64 < sdlProd1.int64) {
1282 // Detected carry. Check for carry out of top
1283 // before adding it in.
1285 if (num[2]++ < den[2])
1288 if (num[2] < den[2])
1289 break; // detected carry
1293 num[0] = sdlNum.u.Lo;
1294 num[1] = sdlNum.u.Hi;
1298 // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer
1299 // Returns FALSE if there is an overflow
1301 Add32To96(uint32_t *num, uint32_t value)
1304 if (num[0] < value) {
1305 if (++num[1] == 0) {
1306 if (++num[2] == 0) {
1315 OverflowUnscale (uint32_t *quo, gboolean remainder)
1319 // We have overflown, so load the high bit with a one.
1321 sdlTmp.u.Lo = quo[2];
1322 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1323 quo[2] = sdlTmp.u.Lo;
1324 sdlTmp.u.Lo = quo[1];
1325 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1326 quo[1] = sdlTmp.u.Lo;
1327 sdlTmp.u.Lo = quo[0];
1328 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1329 quo[0] = sdlTmp.u.Lo;
1330 // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up
1331 if ((sdlTmp.u.Hi > 5) || ((sdlTmp.u.Hi == 5) && ( remainder || (quo[0] & 1)))) {
1336 // mono_decimal_divide - Decimal divide
1337 static MonoDecimalStatus G_GNUC_UNUSED
1338 mono_decimal_divide_result(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1341 uint32_t quoSave[3];
1343 uint32_t divisor[3];
1352 scale = left->u.u.scale - right->u.u.scale;
1353 divisor[0] = right->v.v.Lo32;
1354 divisor[1] = right->v.v.Mid32;
1355 divisor[2] = right->Hi32;
1357 if (divisor[1] == 0 && divisor[2] == 0) {
1358 // Divisor is only 32 bits. Easy divide.
1360 if (divisor[0] == 0)
1361 return MONO_DECIMAL_DIVBYZERO;
1363 quo[0] = left->v.v.Lo32;
1364 quo[1] = left->v.v.Mid32;
1365 quo[2] = left->Hi32;
1366 rem[0] = Div96By32(quo, divisor[0]);
1371 cur_scale = min(9, -scale);
1377 // We have computed a quotient based on the natural scale
1378 // ( <dividend scale> - <divisor scale> ). We have a non-zero
1379 // remainder, so now we should increase the scale if possible to
1380 // include more quotient bits.
1382 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
1383 // computing more quotient bits as long as the remainder stays
1384 // non-zero. If scaling by that much would cause overflow, we'll
1385 // drop out of the loop and scale by as much as we can.
1387 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
1388 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
1389 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
1390 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
1391 // is the largest value in quo[1] (when quo[2] == 4) that is
1392 // assured not to overflow.
1394 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1395 if (cur_scale == 0) {
1396 // No more scaling to be done, but remainder is non-zero.
1400 if (utmp < rem[0] || (utmp >= divisor[0] &&
1401 (utmp > divisor[0] || (quo[0] & 1)))) {
1410 if (cur_scale == -1)
1411 return MONO_DECIMAL_OVERFLOW;
1414 pwr = power10[cur_scale];
1417 if (IncreaseScale(quo, pwr) != 0)
1418 return MONO_DECIMAL_OVERFLOW;
1420 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
1421 rem[0] = sdlTmp.u.Hi;
1423 quo[0] += sdlTmp.u.Lo;
1424 if (quo[0] < sdlTmp.u.Lo) {
1431 // Divisor has bits set in the upper 64 bits.
1433 // Divisor must be fully normalized (shifted so bit 31 of the most
1434 // significant uint32_t is 1). Locate the MSB so we know how much to
1435 // normalize by. The dividend will be shifted by the same amount so
1436 // the quotient is not changed.
1438 if (divisor[2] == 0)
1444 if (!(utmp & 0xFFFF0000)) {
1448 if (!(utmp & 0xFF000000)) {
1452 if (!(utmp & 0xF0000000)) {
1456 if (!(utmp & 0xC0000000)) {
1460 if (!(utmp & 0x80000000)) {
1465 // Shift both dividend and divisor left by cur_scale.
1467 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
1468 rem[0] = sdlTmp.u.Lo;
1469 rem[1] = sdlTmp.u.Hi;
1470 sdlTmp.u.Lo = left->v.v.Mid32;
1471 sdlTmp.u.Hi = left->Hi32;
1472 sdlTmp.int64 <<= cur_scale;
1473 rem[2] = sdlTmp.u.Hi;
1474 rem[3] = (left->Hi32 >> (31 - cur_scale)) >> 1;
1476 sdlDivisor.u.Lo = divisor[0];
1477 sdlDivisor.u.Hi = divisor[1];
1478 sdlDivisor.int64 <<= cur_scale;
1480 if (divisor[2] == 0) {
1481 // Have a 64-bit divisor in sdlDivisor. The remainder
1482 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
1484 sdlTmp.u.Lo = rem[2];
1485 sdlTmp.u.Hi = rem[3];
1488 quo[1] = Div96By64(&rem[1], sdlDivisor);
1489 quo[0] = Div96By64(rem, sdlDivisor);
1492 if ((rem[0] | rem[1]) == 0) {
1494 cur_scale = min(9, -scale);
1500 // Remainder is non-zero. Scale up quotient and remainder by
1501 // powers of 10 so we can compute more significant bits.
1503 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1504 if (cur_scale == 0) {
1505 // No more scaling to be done, but remainder is non-zero.
1508 sdlTmp.u.Lo = rem[0];
1509 sdlTmp.u.Hi = rem[1];
1510 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
1511 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
1516 if (cur_scale == -1)
1517 return MONO_DECIMAL_OVERFLOW;
1520 pwr = power10[cur_scale];
1523 if (IncreaseScale(quo, pwr) != 0)
1524 return MONO_DECIMAL_OVERFLOW;
1526 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
1527 IncreaseScale(rem, pwr);
1528 utmp = Div96By64(rem, sdlDivisor);
1537 // Have a 96-bit divisor in divisor[].
1539 // Start by finishing the shift left by cur_scale.
1541 sdlTmp.u.Lo = divisor[1];
1542 sdlTmp.u.Hi = divisor[2];
1543 sdlTmp.int64 <<= cur_scale;
1544 divisor[0] = sdlDivisor.u.Lo;
1545 divisor[1] = sdlDivisor.u.Hi;
1546 divisor[2] = sdlTmp.u.Hi;
1548 // The remainder (currently 96 bits spread over 4 uint32_ts)
1549 // will be < divisor.
1553 quo[0] = Div128By96(rem, divisor);
1556 if ((rem[0] | rem[1] | rem[2]) == 0) {
1558 cur_scale = min(9, -scale);
1564 // Remainder is non-zero. Scale up quotient and remainder by
1565 // powers of 10 so we can compute more significant bits.
1567 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1568 if (cur_scale == 0) {
1569 // No more scaling to be done, but remainder is non-zero.
1572 if (rem[2] >= 0x80000000)
1575 utmp = rem[0] > 0x80000000;
1576 utmp1 = rem[1] > 0x80000000;
1578 rem[1] = (rem[1] << 1) + utmp;
1579 rem[2] = (rem[2] << 1) + utmp1;
1581 if ((rem[2] > divisor[2] || rem[2] == divisor[2]) &&
1582 ((rem[1] > divisor[1] || rem[1] == divisor[1]) &&
1583 ((rem[0] > divisor[0] || rem[0] == divisor[0]) &&
1589 if (cur_scale == -1)
1590 return MONO_DECIMAL_OVERFLOW;
1593 pwr = power10[cur_scale];
1596 if (IncreaseScale(quo, pwr) != 0)
1597 return MONO_DECIMAL_OVERFLOW;
1599 rem[3] = IncreaseScale(rem, pwr);
1600 utmp = Div128By96(rem, divisor);
1610 // No more remainder. Try extracting any extra powers of 10 we may have
1611 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
1612 // If a division by one of these powers returns a zero remainder, then
1613 // we keep the quotient. If the remainder is not zero, then we restore
1614 // the previous value.
1616 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
1617 // we can extract. We use this as a quick test on whether to try a
1620 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
1621 quoSave[0] = quo[0];
1622 quoSave[1] = quo[1];
1623 quoSave[2] = quo[2];
1625 if (Div96By32(quoSave, 100000000) == 0) {
1626 quo[0] = quoSave[0];
1627 quo[1] = quoSave[1];
1628 quo[2] = quoSave[2];
1635 if ((quo[0] & 0xF) == 0 && scale >= 4) {
1636 quoSave[0] = quo[0];
1637 quoSave[1] = quo[1];
1638 quoSave[2] = quo[2];
1640 if (Div96By32(quoSave, 10000) == 0) {
1641 quo[0] = quoSave[0];
1642 quo[1] = quoSave[1];
1643 quo[2] = quoSave[2];
1648 if ((quo[0] & 3) == 0 && scale >= 2) {
1649 quoSave[0] = quo[0];
1650 quoSave[1] = quo[1];
1651 quoSave[2] = quo[2];
1653 if (Div96By32(quoSave, 100) == 0) {
1654 quo[0] = quoSave[0];
1655 quo[1] = quoSave[1];
1656 quo[2] = quoSave[2];
1661 if ((quo[0] & 1) == 0 && scale >= 1) {
1662 quoSave[0] = quo[0];
1663 quoSave[1] = quo[1];
1664 quoSave[2] = quo[2];
1666 if (Div96By32(quoSave, 10) == 0) {
1667 quo[0] = quoSave[0];
1668 quo[1] = quoSave[1];
1669 quo[2] = quoSave[2];
1674 result->Hi32 = quo[2];
1675 result->v.v.Mid32 = quo[1];
1676 result->v.v.Lo32 = quo[0];
1677 result->u.u.scale = scale;
1678 result->u.u.sign = left->u.u.sign ^ right->u.u.sign;
1679 return MONO_DECIMAL_OK;
1682 // mono_decimal_absolute - Decimal Absolute Value
1683 static void G_GNUC_UNUSED
1684 mono_decimal_absolute (MonoDecimal *pdecOprd, MonoDecimal *result)
1686 COPYDEC(*result, *pdecOprd);
1687 result->u.u.sign &= ~DECIMAL_NEG;
1688 // Microsoft does not set reserved here
1691 // mono_decimal_fix - Decimal Fix (chop to integer)
1693 mono_decimal_fix (MonoDecimal *pdecOprd, MonoDecimal *result)
1695 DecFixInt(result, pdecOprd);
1698 // mono_decimal_round_to_int - Decimal Int (round down to integer)
1700 mono_decimal_round_to_int (MonoDecimal *pdecOprd, MonoDecimal *result)
1702 if (DecFixInt(result, pdecOprd) != 0 && (result->u.u.sign & DECIMAL_NEG)) {
1703 // We have chopped off a non-zero amount from a negative value. Since
1704 // we round toward -infinity, we must increase the integer result by
1705 // 1 to make it more negative. This will never overflow because
1706 // in order to have a remainder, we must have had a non-zero scale factor.
1707 // Our scale factor is back to zero now.
1709 DECIMAL_LO64_SET(*result, DECIMAL_LO64_GET(*result) + 1);
1710 if (DECIMAL_LO64_GET(*result) == 0)
1715 // mono_decimal_negate - Decimal Negate
1716 static void G_GNUC_UNUSED
1717 mono_decimal_negate (MonoDecimal *pdecOprd, MonoDecimal *result)
1719 COPYDEC(*result, *pdecOprd);
1720 // Microsoft does not set result->reserved to zero on this case.
1721 result->u.u.sign ^= DECIMAL_NEG;
1725 // Returns: MONO_DECIMAL_INVALID_ARGUMENT, MONO_DECIMAL_OK
1727 static MonoDecimalStatus
1728 mono_decimal_round_result(MonoDecimal *input, int cDecimals, MonoDecimal *result)
1737 return MONO_DECIMAL_INVALID_ARGUMENT;
1739 scale = input->u.u.scale - cDecimals;
1741 num[0] = input->v.v.Lo32;
1742 num[1] = input->v.v.Mid32;
1743 num[2] = input->Hi32;
1744 result->u.u.sign = input->u.u.sign;
1749 if (scale > POWER10_MAX)
1752 pwr = power10[scale];
1754 rem = Div96By32(num, pwr);
1758 // Now round. rem has last remainder, sticky has sticky bits.
1759 // To do IEEE rounding, we add LSB of result to sticky bits so
1760 // either causes round up if remainder * 2 == last divisor.
1762 sticky |= num[0] & 1;
1763 rem = (rem << 1) + (sticky != 0);
1770 result->v.v.Lo32 = num[0];
1771 result->v.v.Mid32 = num[1];
1772 result->Hi32 = num[2];
1773 result->u.u.scale = cDecimals;
1774 return MONO_DECIMAL_OK;
1777 COPYDEC(*result, *input);
1778 // Odd, the Microsoft source does not set the result->reserved to zero here.
1779 return MONO_DECIMAL_OK;
1783 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1784 static MonoDecimalStatus
1785 mono_decimal_from_float (float input_f, MonoDecimal* result)
1787 int exp; // number of bits to left of binary point
1793 int lmax, cur; // temps used during scale reduction
1794 MonoSingle_float input = { .f = input_f };
1796 // The most we can scale by is 10^28, which is just slightly more
1797 // than 2^93. So a float with an exponent of -94 could just
1798 // barely reach 0.5, but smaller exponents will always round to zero.
1800 if ((exp = input.s.exp - MONO_SINGLE_BIAS) < -94 ) {
1801 DECIMAL_SETZERO(*result);
1802 return MONO_DECIMAL_OK;
1806 return MONO_DECIMAL_OVERFLOW;
1808 // Round the input to a 7-digit integer. The R4 format has
1809 // only 7 digits of precision, and we want to keep garbage digits
1810 // out of the Decimal were making.
1812 // Calculate max power of 10 input value could have by multiplying
1813 // the exponent by log10(2). Using scaled integer multiplcation,
1814 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1816 dbl = fabs(input.f);
1817 power = 6 - ((exp * 19728) >> 16);
1820 // We have less than 7 digits, scale input up.
1825 dbl = dbl * double_power10[power];
1827 if (power != -1 || dbl >= 1E7)
1828 dbl = dbl / fnDblPower10(-power);
1830 power = 0; // didn't scale it
1833 g_assert (dbl < 1E7);
1834 if (dbl < 1E6 && power < DECMAX) {
1837 g_assert(dbl >= 1E6);
1842 mant = (int32_t)dbl;
1843 dbl -= (double)mant; // difference between input & integer
1844 if ( dbl > 0.5 || (dbl == 0.5 && (mant & 1)))
1848 DECIMAL_SETZERO(*result);
1849 return MONO_DECIMAL_OK;
1853 // Add -power factors of 10, -power <= (29 - 7) = 22.
1857 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power]);
1859 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1860 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1861 DECIMAL_HI32(*result) = 0;
1863 // Have a big power of 10.
1866 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 18]);
1867 sdlLo.int64 = UInt64x64To128(sdlLo, ten_to_eighteen, &sdlHi.int64);
1869 if (sdlHi.u.Hi != 0)
1870 return MONO_DECIMAL_OVERFLOW;
1873 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 9]);
1874 sdlHi.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Hi);
1875 sdlLo.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Lo);
1876 sdlHi.int64 += sdlLo.u.Hi;
1877 sdlLo.u.Hi = sdlHi.u.Lo;
1878 sdlHi.u.Lo = sdlHi.u.Hi;
1880 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1881 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1882 DECIMAL_HI32(*result) = sdlHi.u.Lo;
1884 DECIMAL_SCALE(*result) = 0;
1886 // Factor out powers of 10 to reduce the scale, if possible.
1887 // The maximum number we could factor out would be 6. This
1888 // comes from the fact we have a 7-digit number, and the
1889 // MSD must be non-zero -- but the lower 6 digits could be
1890 // zero. Note also the scale factor is never negative, so
1891 // we can't scale by any more than the power we used to
1894 // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
1896 lmax = min(power, 6);
1898 // lmax is the largest power of 10 to try, lmax <= 6.
1899 // We'll try powers 4, 2, and 1 unless they're too big.
1901 for (cur = 4; cur > 0; cur >>= 1)
1906 sdlLo.int64 = DivMod32by32(mant, (uint32_t)long_power10[cur]);
1908 if (sdlLo.u.Hi == 0) {
1914 DECIMAL_LO32(*result) = mant;
1915 DECIMAL_MID32(*result) = 0;
1916 DECIMAL_HI32(*result) = 0;
1917 DECIMAL_SCALE(*result) = power;
1920 DECIMAL_SIGN(*result) = (char)input.s.sign << 7;
1921 return MONO_DECIMAL_OK;
1924 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1925 static MonoDecimalStatus
1926 mono_decimal_from_double (double input_d, MonoDecimal *result)
1928 int exp; // number of bits to left of binary point
1929 int power; // power-of-10 scale factor
1933 int lmax, cur; // temps used during scale reduction
1936 MonoDouble_double input = { .d = input_d };
1938 // The most we can scale by is 10^28, which is just slightly more
1939 // than 2^93. So a float with an exponent of -94 could just
1940 // barely reach 0.5, but smaller exponents will always round to zero.
1942 if ((exp = input.s.exp - MONO_DOUBLE_BIAS) < -94) {
1943 DECIMAL_SETZERO(*result);
1944 return MONO_DECIMAL_OK;
1948 return MONO_DECIMAL_OVERFLOW;
1950 // Round the input to a 15-digit integer. The R8 format has
1951 // only 15 digits of precision, and we want to keep garbage digits
1952 // out of the Decimal were making.
1954 // Calculate max power of 10 input value could have by multiplying
1955 // the exponent by log10(2). Using scaled integer multiplcation,
1956 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1958 dbl = fabs(input.d);
1959 power = 14 - ((exp * 19728) >> 16);
1962 // We have less than 15 digits, scale input up.
1967 dbl = dbl * double_power10[power];
1969 if (power != -1 || dbl >= 1E15)
1970 dbl = dbl / fnDblPower10(-power);
1972 power = 0; // didn't scale it
1975 g_assert (dbl < 1E15);
1976 if (dbl < 1E14 && power < DECMAX) {
1979 g_assert(dbl >= 1E14);
1984 sdlMant.int64 = (int64_t)dbl;
1985 dbl -= (double)(int64_t)sdlMant.int64; // dif between input & integer
1986 if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)))
1989 if (sdlMant.int64 == 0) {
1990 DECIMAL_SETZERO(*result);
1991 return MONO_DECIMAL_OK;
1995 // Add -power factors of 10, -power <= (29 - 15) = 14.
1999 sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (uint32_t)long_power10[power]);
2000 sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (uint32_t)long_power10[power]);
2001 sdlMant.int64 += sdlLo.u.Hi;
2002 sdlLo.u.Hi = sdlMant.u.Lo;
2003 sdlMant.u.Lo = sdlMant.u.Hi;
2006 // Have a big power of 10.
2008 g_assert(power <= 14);
2009 sdlLo.int64 = UInt64x64To128(sdlMant, sdl_power10[power-10], &sdlMant.int64);
2011 if (sdlMant.u.Hi != 0)
2012 return MONO_DECIMAL_OVERFLOW;
2014 DECIMAL_LO32(*result) = sdlLo.u.Lo;
2015 DECIMAL_MID32(*result) = sdlLo.u.Hi;
2016 DECIMAL_HI32(*result) = sdlMant.u.Lo;
2017 DECIMAL_SCALE(*result) = 0;
2020 // Factor out powers of 10 to reduce the scale, if possible.
2021 // The maximum number we could factor out would be 14. This
2022 // comes from the fact we have a 15-digit number, and the
2023 // MSD must be non-zero -- but the lower 14 digits could be
2024 // zero. Note also the scale factor is never negative, so
2025 // we can't scale by any more than the power we used to
2028 // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
2030 lmax = min(power, 14);
2032 // lmax is the largest power of 10 to try, lmax <= 14.
2033 // We'll try powers 8, 4, 2, and 1 unless they're too big.
2035 for (cur = 8; cur > 0; cur >>= 1)
2040 pwr_cur = (uint32_t)long_power10[cur];
2042 if (sdlMant.u.Hi >= pwr_cur) {
2043 // Overflow if we try to divide in one step.
2045 sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, pwr_cur);
2047 sdlLo.u.Lo = sdlMant.u.Lo;
2048 sdlLo.int64 = DivMod64by32(sdlLo.int64, pwr_cur);
2052 sdlLo.int64 = DivMod64by32(sdlMant.int64, pwr_cur);
2055 if (sdlLo.u.Hi == 0) {
2057 sdlMant.u.Lo = sdlLo.u.Lo;
2063 DECIMAL_HI32(*result) = 0;
2064 DECIMAL_SCALE(*result) = power;
2065 DECIMAL_LO32(*result) = sdlMant.u.Lo;
2066 DECIMAL_MID32(*result) = sdlMant.u.Hi;
2069 DECIMAL_SIGN(*result) = (char)input.s.sign << 7;
2070 return MONO_DECIMAL_OK;
2073 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2074 static MonoDecimalStatus
2075 mono_decimal_to_double_result(MonoDecimal *input, double *result)
2080 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2081 return MONO_DECIMAL_INVALID_ARGUMENT;
2083 tmp.u.Lo = DECIMAL_LO32(*input);
2084 tmp.u.Hi = DECIMAL_MID32(*input);
2086 if ((int32_t)DECIMAL_MID32(*input) < 0)
2087 dbl = (ds2to64.d + (double)(int64_t)tmp.int64 +
2088 (double)DECIMAL_HI32(*input) * ds2to64.d) / fnDblPower10(DECIMAL_SCALE(*input)) ;
2090 dbl = ((double)(int64_t)tmp.int64 +
2091 (double)DECIMAL_HI32(*input) * ds2to64.d) / fnDblPower10(DECIMAL_SCALE(*input));
2093 if (DECIMAL_SIGN(*input))
2097 return MONO_DECIMAL_OK;
2100 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2101 static MonoDecimalStatus
2102 mono_decimal_to_float_result(MonoDecimal *input, float *result)
2106 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2107 return MONO_DECIMAL_INVALID_ARGUMENT;
2109 // Can't overflow; no errors possible.
2111 mono_decimal_to_double_result(input, &dbl);
2112 *result = (float)dbl;
2113 return MONO_DECIMAL_OK;
2117 DecShiftLeft(MonoDecimal* value)
2119 unsigned int c0 = DECIMAL_LO32(*value) & 0x80000000? 1: 0;
2120 unsigned int c1 = DECIMAL_MID32(*value) & 0x80000000? 1: 0;
2121 g_assert(value != NULL);
2123 DECIMAL_LO32(*value) <<= 1;
2124 DECIMAL_MID32(*value) = DECIMAL_MID32(*value) << 1 | c0;
2125 DECIMAL_HI32(*value) = DECIMAL_HI32(*value) << 1 | c1;
2129 D32AddCarry(uint32_t* value, uint32_t i)
2131 uint32_t v = *value;
2132 uint32_t sum = v + i;
2134 return sum < v || sum < i? 1: 0;
2138 DecAdd(MonoDecimal *value, MonoDecimal* d)
2140 g_assert(value != NULL && d != NULL);
2142 if (D32AddCarry(&DECIMAL_LO32(*value), DECIMAL_LO32(*d))) {
2143 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2144 D32AddCarry(&DECIMAL_HI32(*value), 1);
2147 if (D32AddCarry(&DECIMAL_MID32(*value), DECIMAL_MID32(*d))) {
2148 D32AddCarry(&DECIMAL_HI32(*value), 1);
2150 D32AddCarry(&DECIMAL_HI32(*value), DECIMAL_HI32(*d));
2154 DecMul10(MonoDecimal* value)
2156 MonoDecimal d = *value;
2157 g_assert (value != NULL);
2159 DecShiftLeft(value);
2160 DecShiftLeft(value);
2162 DecShiftLeft(value);
2166 DecAddInt32(MonoDecimal* value, unsigned int i)
2168 g_assert(value != NULL);
2170 if (D32AddCarry(&DECIMAL_LO32(*value), i)) {
2171 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2172 D32AddCarry(&DECIMAL_HI32(*value), 1);
2177 MonoDecimalCompareResult
2178 mono_decimal_compare (MonoDecimal *left, MonoDecimal *right)
2181 uint32_t right_sign;
2184 result.Hi32 = 0; // Just to shut up the compiler
2186 // First check signs and whether either are zero. If both are
2187 // non-zero and of the same sign, just use subtraction to compare.
2189 left_sign = left->v.v.Lo32 | left->v.v.Mid32 | left->Hi32;
2190 right_sign = right->v.v.Lo32 | right->v.v.Mid32 | right->Hi32;
2192 left_sign = (left->u.u.sign & DECIMAL_NEG) | 1;
2194 if (right_sign != 0)
2195 right_sign = (right->u.u.sign & DECIMAL_NEG) | 1;
2197 // left_sign & right_sign have values 1, 0, or 0x81 depending on if the left/right
2198 // operand is +, 0, or -.
2200 if (left_sign == right_sign) {
2201 if (left_sign == 0) // both are zero
2202 return MONO_DECIMAL_CMP_EQ; // return equal
2204 DecAddSub(left, right, &result, DECIMAL_NEG);
2205 if (DECIMAL_LO64_GET(result) == 0 && result.Hi32 == 0)
2206 return MONO_DECIMAL_CMP_EQ;
2207 if (result.u.u.sign & DECIMAL_NEG)
2208 return MONO_DECIMAL_CMP_LT;
2209 return MONO_DECIMAL_CMP_GT;
2213 // Signs are different. Use signed byte comparison
2215 if ((signed char)left_sign > (signed char)right_sign)
2216 return MONO_DECIMAL_CMP_GT;
2217 return MONO_DECIMAL_CMP_LT;
2221 mono_decimal_init_single (MonoDecimal *_this, float value)
2223 if (mono_decimal_from_float (value, _this) == MONO_DECIMAL_OVERFLOW) {
2224 mono_set_pending_exception (mono_get_exception_overflow ());
2227 _this->reserved = 0;
2231 mono_decimal_init_double (MonoDecimal *_this, double value)
2233 if (mono_decimal_from_double (value, _this) == MONO_DECIMAL_OVERFLOW) {
2234 mono_set_pending_exception (mono_get_exception_overflow ());
2237 _this->reserved = 0;
2241 mono_decimal_floor (MonoDecimal *d)
2245 mono_decimal_round_to_int(d, &decRes);
2247 // copy decRes into d
2248 COPYDEC(*d, decRes);
2254 mono_decimal_get_hash_code (MonoDecimal *d)
2258 if (mono_decimal_to_double_result(d, &dbl) != MONO_DECIMAL_OK)
2262 // Ensure 0 and -0 have the same hash code
2265 // conversion to double is lossy and produces rounding errors so we mask off the lowest 4 bits
2267 // For example these two numerically equal decimals with different internal representations produce
2268 // slightly different results when converted to double:
2270 // decimal a = new decimal(new int[] { 0x76969696, 0x2fdd49fa, 0x409783ff, 0x00160000 });
2271 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.176470588
2272 // decimal b = new decimal(new int[] { 0x3f0f0f0f, 0x1e62edcc, 0x06758d33, 0x00150000 });
2273 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.1764705882
2275 return ((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
2280 mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2)
2284 MonoDecimalStatus status = mono_decimal_multiply_result(d1, d2, &decRes);
2285 if (status != MONO_DECIMAL_OK) {
2286 mono_set_pending_exception (mono_get_exception_overflow ());
2290 COPYDEC(*d1, decRes);
2297 mono_decimal_round (MonoDecimal *d, int32_t decimals)
2301 // GC is only triggered for throwing, no need to protect result
2302 if (decimals < 0 || decimals > 28) {
2303 mono_set_pending_exception (mono_get_exception_argument_out_of_range ("d"));
2307 mono_decimal_round_result(d, decimals, &decRes);
2309 // copy decRes into d
2310 COPYDEC(*d, decRes);
2317 mono_decimal_tocurrency (MonoDecimal *decimal)
2323 mono_decimal_to_double (MonoDecimal d)
2325 double result = 0.0;
2326 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2327 mono_decimal_to_double_result(&d, &result);
2332 mono_decimal_to_int32 (MonoDecimal d)
2336 // The following can not return an error, it only returns INVALID_ARG if the decimals is < 0
2337 mono_decimal_round_result(&d, 0, &result);
2339 if (DECIMAL_SCALE(result) != 0) {
2341 mono_decimal_fix (&d, &result);
2344 if (DECIMAL_HI32(result) == 0 && DECIMAL_MID32(result) == 0) {
2345 int32_t i = DECIMAL_LO32(result);
2346 if ((int16_t)DECIMAL_SIGNSCALE(result) >= 0) {
2356 mono_set_pending_exception (mono_get_exception_overflow ());
2361 mono_decimal_to_float (MonoDecimal d)
2363 float result = 0.0f;
2364 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2365 mono_decimal_to_float_result(&d, &result);
2370 mono_decimal_truncate (MonoDecimal *d)
2374 mono_decimal_fix(d, &decRes);
2376 // copy decRes into d
2377 COPYDEC(*d, decRes);
2383 mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign)
2385 MonoDecimal result, decTmp;
2386 MonoDecimal *pdecTmp, *leftOriginal;
2387 uint32_t num[6], pwr;
2388 int scale, hi_prod, cur;
2391 g_assert(sign == 0 || sign == DECIMAL_NEG);
2393 leftOriginal = left;
2395 sign ^= (DECIMAL_SIGN(*right) ^ DECIMAL_SIGN(*left)) & DECIMAL_NEG;
2397 if (DECIMAL_SCALE(*right) == DECIMAL_SCALE(*left)) {
2398 // Scale factors are equal, no alignment necessary.
2400 DECIMAL_SIGNSCALE(result) = DECIMAL_SIGNSCALE(*left);
2404 // Signs differ - subtract
2406 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right)));
2407 DECIMAL_HI32(result) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
2411 if (DECIMAL_LO64_GET(result) > DECIMAL_LO64_GET(*left)) {
2412 DECIMAL_HI32(result)--;
2413 if (DECIMAL_HI32(result) >= DECIMAL_HI32(*left))
2415 } else if (DECIMAL_HI32(result) > DECIMAL_HI32(*left)) {
2416 // Got negative result. Flip its sign.
2419 DECIMAL_LO64_SET(result, -(int64_t)DECIMAL_LO64_GET(result));
2420 DECIMAL_HI32(result) = ~DECIMAL_HI32(result);
2421 if (DECIMAL_LO64_GET(result) == 0)
2422 DECIMAL_HI32(result)++;
2423 DECIMAL_SIGN(result) ^= DECIMAL_NEG;
2427 // Signs are the same - add
2429 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right)));
2430 DECIMAL_HI32(result) = DECIMAL_HI32(*left) + DECIMAL_HI32(*right);
2434 if (DECIMAL_LO64_GET(result) < DECIMAL_LO64_GET(*left)) {
2435 DECIMAL_HI32(result)++;
2436 if (DECIMAL_HI32(result) <= DECIMAL_HI32(*left))
2438 } else if (DECIMAL_HI32(result) < DECIMAL_HI32(*left)) {
2440 // The addition carried above 96 bits. Divide the result by 10,
2441 // dropping the scale factor.
2443 if (DECIMAL_SCALE(result) == 0) {
2444 mono_set_pending_exception (mono_get_exception_overflow ());
2447 DECIMAL_SCALE(result)--;
2449 sdlTmp.u.Lo = DECIMAL_HI32(result);
2451 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2452 DECIMAL_HI32(result) = sdlTmp.u.Lo;
2454 sdlTmp.u.Lo = DECIMAL_MID32(result);
2455 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2456 DECIMAL_MID32(result) = sdlTmp.u.Lo;
2458 sdlTmp.u.Lo = DECIMAL_LO32(result);
2459 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2460 DECIMAL_LO32(result) = sdlTmp.u.Lo;
2462 // See if we need to round up.
2464 if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (DECIMAL_LO32(result) & 1))) {
2465 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(result)+1);
2466 if (DECIMAL_LO64_GET(result) == 0)
2467 DECIMAL_HI32(result)++;
2472 // Scale factors are not equal. Assume that a larger scale
2473 // factor (more decimal places) is likely to mean that number
2474 // is smaller. Start by guessing that the right operand has
2475 // the larger scale factor. The result will have the larger
2478 DECIMAL_SCALE(result) = DECIMAL_SCALE(*right); // scale factor of "smaller"
2479 DECIMAL_SIGN(result) = DECIMAL_SIGN(*left); // but sign of "larger"
2480 scale = DECIMAL_SCALE(result)- DECIMAL_SCALE(*left);
2483 // Guessed scale factor wrong. Swap operands.
2486 DECIMAL_SCALE(result) = DECIMAL_SCALE(*left);
2487 DECIMAL_SIGN(result) ^= sign;
2493 // *left will need to be multiplied by 10^scale so
2494 // it will have the same scale as *right. We could be
2495 // extending it to up to 192 bits of precision.
2497 if (scale <= POWER10_MAX) {
2498 // Scaling won't make it larger than 4 uint32_ts
2500 pwr = power10[scale];
2501 DECIMAL_LO64_SET(decTmp, UInt32x32To64(DECIMAL_LO32(*left), pwr));
2502 sdlTmp.int64 = UInt32x32To64(DECIMAL_MID32(*left), pwr);
2503 sdlTmp.int64 += DECIMAL_MID32(decTmp);
2504 DECIMAL_MID32(decTmp) = sdlTmp.u.Lo;
2505 DECIMAL_HI32(decTmp) = sdlTmp.u.Hi;
2506 sdlTmp.int64 = UInt32x32To64(DECIMAL_HI32(*left), pwr);
2507 sdlTmp.int64 += DECIMAL_HI32(decTmp);
2508 if (sdlTmp.u.Hi == 0) {
2509 // Result fits in 96 bits. Use standard aligned add.
2511 DECIMAL_HI32(decTmp) = sdlTmp.u.Lo;
2515 num[0] = DECIMAL_LO32(decTmp);
2516 num[1] = DECIMAL_MID32(decTmp);
2517 num[2] = sdlTmp.u.Lo;
2518 num[3] = sdlTmp.u.Hi;
2521 // Have to scale by a bunch. Move the number to a buffer
2522 // where it has room to grow as it's scaled.
2524 num[0] = DECIMAL_LO32(*left);
2525 num[1] = DECIMAL_MID32(*left);
2526 num[2] = DECIMAL_HI32(*left);
2529 // Scan for zeros in the upper words.
2536 // Left arg is zero, return right.
2538 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(*right));
2539 DECIMAL_HI32(result) = DECIMAL_HI32(*right);
2540 DECIMAL_SIGN(result) ^= sign;
2546 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
2547 // with index of highest non-zero uint32_t.
2549 for (; scale > 0; scale -= POWER10_MAX) {
2550 if (scale > POWER10_MAX)
2553 pwr = power10[scale];
2556 for (cur = 0; cur <= hi_prod; cur++) {
2557 sdlTmp.int64 = UInt32x32To64(num[cur], pwr) + sdlTmp.u.Hi;
2558 num[cur] = sdlTmp.u.Lo;
2561 if (sdlTmp.u.Hi != 0)
2562 // We're extending the result by another uint32_t.
2563 num[++hi_prod] = sdlTmp.u.Hi;
2567 // Scaling complete, do the add. Could be subtract if signs differ.
2569 sdlTmp.u.Lo = num[0];
2570 sdlTmp.u.Hi = num[1];
2573 // Signs differ, subtract.
2575 DECIMAL_LO64_SET(result, (sdlTmp.int64 - DECIMAL_LO64_GET(*right)));
2576 DECIMAL_HI32(result) = num[2] - DECIMAL_HI32(*right);
2580 if (DECIMAL_LO64_GET(result) > sdlTmp.int64) {
2581 DECIMAL_HI32(result)--;
2582 if (DECIMAL_HI32(result) >= num[2])
2584 } else if (DECIMAL_HI32(result) > num[2]) {
2586 // If num has more than 96 bits of precision, then we need to
2587 // carry the subtraction into the higher bits. If it doesn't,
2588 // then we subtracted in the wrong order and have to flip the
2589 // sign of the result.
2595 while(num[cur++]-- == 0);
2596 if (num[hi_prod] == 0)
2600 // Signs the same, add.
2602 DECIMAL_LO64_SET(result, (sdlTmp.int64 + DECIMAL_LO64_GET(*right)));
2603 DECIMAL_HI32(result) = num[2] + DECIMAL_HI32(*right);
2607 if (DECIMAL_LO64_GET(result) < sdlTmp.int64) {
2608 DECIMAL_HI32(result)++;
2609 if (DECIMAL_HI32(result) <= num[2])
2611 } else if (DECIMAL_HI32(result) < num[2]) {
2613 // Had a carry above 96 bits.
2617 if (hi_prod < cur) {
2622 }while (++num[cur++] == 0);
2627 num[0] = DECIMAL_LO32(result);
2628 num[1] = DECIMAL_MID32(result);
2629 num[2] = DECIMAL_HI32(result);
2630 DECIMAL_SCALE(result) = (uint8_t)ScaleResult(num, hi_prod, DECIMAL_SCALE(result));
2631 if (DECIMAL_SCALE(result) == (uint8_t)-1) {
2632 mono_set_pending_exception (mono_get_exception_overflow ());
2636 DECIMAL_LO32(result) = num[0];
2637 DECIMAL_MID32(result) = num[1];
2638 DECIMAL_HI32(result) = num[2];
2643 left = leftOriginal;
2644 COPYDEC(*left, result);
2649 mono_decimal_divide (MonoDecimal *left, MonoDecimal *right)
2651 uint32_t quo[3], quo_save[3],rem[4], divisor[3];
2652 uint32_t pwr, tmp, tmp1;
2653 SPLIT64 sdlTmp, sdlDivisor;
2654 int scale, cur_scale;
2657 scale = DECIMAL_SCALE(*left) - DECIMAL_SCALE(*right);
2659 divisor[0] = DECIMAL_LO32(*right);
2660 divisor[1] = DECIMAL_MID32(*right);
2661 divisor[2] = DECIMAL_HI32(*right);
2663 if (divisor[1] == 0 && divisor[2] == 0) {
2664 // Divisor is only 32 bits. Easy divide.
2666 if (divisor[0] == 0) {
2667 mono_set_pending_exception (mono_get_exception_divide_by_zero ());
2671 quo[0] = DECIMAL_LO32(*left);
2672 quo[1] = DECIMAL_MID32(*left);
2673 quo[2] = DECIMAL_HI32(*left);
2674 rem[0] = Div96By32(quo, divisor[0]);
2679 cur_scale = min(9, -scale);
2684 // We need to unscale if and only if we have a non-zero remainder
2687 // We have computed a quotient based on the natural scale
2688 // ( <dividend scale> - <divisor scale> ). We have a non-zero
2689 // remainder, so now we should increase the scale if possible to
2690 // include more quotient bits.
2692 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
2693 // computing more quotient bits as long as the remainder stays
2694 // non-zero. If scaling by that much would cause overflow, we'll
2695 // drop out of the loop and scale by as much as we can.
2697 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
2698 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
2699 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
2700 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
2701 // is the largest value in quo[1] (when quo[2] == 4) that is
2702 // assured not to overflow.
2704 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2705 if (cur_scale == 0) {
2706 // No more scaling to be done, but remainder is non-zero.
2710 if (tmp < rem[0] || (tmp >= divisor[0] &&
2711 (tmp > divisor[0] || (quo[0] & 1)))) {
2713 if (!Add32To96(quo, 1)) {
2715 mono_set_pending_exception (mono_get_exception_overflow ());
2719 OverflowUnscale(quo, TRUE);
2726 if (cur_scale < 0) {
2727 mono_set_pending_exception (mono_get_exception_overflow ());
2732 pwr = power10[cur_scale];
2735 if (IncreaseScale(quo, pwr) != 0) {
2736 mono_set_pending_exception (mono_get_exception_overflow ());
2740 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
2741 rem[0] = sdlTmp.u.Hi;
2743 if (!Add32To96(quo, sdlTmp.u.Lo)) {
2745 mono_set_pending_exception (mono_get_exception_overflow ());
2749 OverflowUnscale(quo, (rem[0] != 0));
2754 // Divisor has bits set in the upper 64 bits.
2756 // Divisor must be fully normalized (shifted so bit 31 of the most
2757 // significant uint32_t is 1). Locate the MSB so we know how much to
2758 // normalize by. The dividend will be shifted by the same amount so
2759 // the quotient is not changed.
2761 if (divisor[2] == 0)
2767 if (!(tmp & 0xFFFF0000)) {
2771 if (!(tmp & 0xFF000000)) {
2775 if (!(tmp & 0xF0000000)) {
2779 if (!(tmp & 0xC0000000)) {
2783 if (!(tmp & 0x80000000)) {
2788 // Shift both dividend and divisor left by cur_scale.
2790 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
2791 rem[0] = sdlTmp.u.Lo;
2792 rem[1] = sdlTmp.u.Hi;
2793 sdlTmp.u.Lo = DECIMAL_MID32(*left);
2794 sdlTmp.u.Hi = DECIMAL_HI32(*left);
2795 sdlTmp.int64 <<= cur_scale;
2796 rem[2] = sdlTmp.u.Hi;
2797 rem[3] = (DECIMAL_HI32(*left) >> (31 - cur_scale)) >> 1;
2799 sdlDivisor.u.Lo = divisor[0];
2800 sdlDivisor.u.Hi = divisor[1];
2801 sdlDivisor.int64 <<= cur_scale;
2803 if (divisor[2] == 0) {
2804 // Have a 64-bit divisor in sdlDivisor. The remainder
2805 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
2807 sdlTmp.u.Lo = rem[2];
2808 sdlTmp.u.Hi = rem[3];
2811 quo[1] = Div96By64(&rem[1], sdlDivisor);
2812 quo[0] = Div96By64(rem, sdlDivisor);
2815 if ((rem[0] | rem[1]) == 0) {
2817 cur_scale = min(9, -scale);
2823 // We need to unscale if and only if we have a non-zero remainder
2826 // Remainder is non-zero. Scale up quotient and remainder by
2827 // powers of 10 so we can compute more significant bits.
2829 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2830 if (cur_scale == 0) {
2831 // No more scaling to be done, but remainder is non-zero.
2834 sdlTmp.u.Lo = rem[0];
2835 sdlTmp.u.Hi = rem[1];
2836 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
2837 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
2842 if (cur_scale < 0) {
2843 mono_set_pending_exception (mono_get_exception_overflow ());
2848 pwr = power10[cur_scale];
2851 if (IncreaseScale(quo, pwr) != 0) {
2852 mono_set_pending_exception (mono_get_exception_overflow ());
2856 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
2857 IncreaseScale(rem, pwr);
2858 tmp = Div96By64(rem, sdlDivisor);
2859 if (!Add32To96(quo, tmp)) {
2861 mono_set_pending_exception (mono_get_exception_overflow ());
2865 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0));
2871 // Have a 96-bit divisor in divisor[].
2873 // Start by finishing the shift left by cur_scale.
2875 sdlTmp.u.Lo = divisor[1];
2876 sdlTmp.u.Hi = divisor[2];
2877 sdlTmp.int64 <<= cur_scale;
2878 divisor[0] = sdlDivisor.u.Lo;
2879 divisor[1] = sdlDivisor.u.Hi;
2880 divisor[2] = sdlTmp.u.Hi;
2882 // The remainder (currently 96 bits spread over 4 uint32_ts)
2883 // will be < divisor.
2887 quo[0] = Div128By96(rem, divisor);
2890 if ((rem[0] | rem[1] | rem[2]) == 0) {
2892 cur_scale = min(9, -scale);
2898 // We need to unscale if and only if we have a non-zero remainder
2901 // Remainder is non-zero. Scale up quotient and remainder by
2902 // powers of 10 so we can compute more significant bits.
2904 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2905 if (cur_scale == 0) {
2906 // No more scaling to be done, but remainder is non-zero.
2909 if (rem[2] >= 0x80000000)
2912 tmp = rem[0] > 0x80000000;
2913 tmp1 = rem[1] > 0x80000000;
2915 rem[1] = (rem[1] << 1) + tmp;
2916 rem[2] = (rem[2] << 1) + tmp1;
2918 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)))))))
2923 if (cur_scale < 0) {
2924 mono_set_pending_exception (mono_get_exception_overflow ());
2929 pwr = power10[cur_scale];
2932 if (IncreaseScale(quo, pwr) != 0) {
2933 mono_set_pending_exception (mono_get_exception_overflow ());
2937 rem[3] = IncreaseScale(rem, pwr);
2938 tmp = Div128By96(rem, divisor);
2939 if (!Add32To96(quo, tmp)) {
2941 mono_set_pending_exception (mono_get_exception_overflow ());
2946 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0 || rem[2] != 0 || rem[3] != 0));
2954 // We need to unscale if and only if we have a non-zero remainder
2956 // Try extracting any extra powers of 10 we may have
2957 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
2958 // If a division by one of these powers returns a zero remainder, then
2959 // we keep the quotient. If the remainder is not zero, then we restore
2960 // the previous value.
2962 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
2963 // we can extract. We use this as a quick test on whether to try a
2966 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
2967 quo_save[0] = quo[0];
2968 quo_save[1] = quo[1];
2969 quo_save[2] = quo[2];
2971 if (Div96By32(quo_save, 100000000) == 0) {
2972 quo[0] = quo_save[0];
2973 quo[1] = quo_save[1];
2974 quo[2] = quo_save[2];
2980 if ((quo[0] & 0xF) == 0 && scale >= 4) {
2981 quo_save[0] = quo[0];
2982 quo_save[1] = quo[1];
2983 quo_save[2] = quo[2];
2985 if (Div96By32(quo_save, 10000) == 0) {
2986 quo[0] = quo_save[0];
2987 quo[1] = quo_save[1];
2988 quo[2] = quo_save[2];
2993 if ((quo[0] & 3) == 0 && scale >= 2) {
2994 quo_save[0] = quo[0];
2995 quo_save[1] = quo[1];
2996 quo_save[2] = quo[2];
2998 if (Div96By32(quo_save, 100) == 0) {
2999 quo[0] = quo_save[0];
3000 quo[1] = quo_save[1];
3001 quo[2] = quo_save[2];
3006 if ((quo[0] & 1) == 0 && scale >= 1) {
3007 quo_save[0] = quo[0];
3008 quo_save[1] = quo[1];
3009 quo_save[2] = quo[2];
3011 if (Div96By32(quo_save, 10) == 0) {
3012 quo[0] = quo_save[0];
3013 quo[1] = quo_save[1];
3014 quo[2] = quo_save[2];
3020 DECIMAL_SIGN(*left) = DECIMAL_SIGN(*left) ^ DECIMAL_SIGN(*right);
3021 DECIMAL_HI32(*left) = quo[2];
3022 DECIMAL_MID32(*left) = quo[1];
3023 DECIMAL_LO32(*left) = quo[0];
3024 DECIMAL_SCALE(*left) = (uint8_t)scale;
3029 #define DECIMAL_PRECISION 29
3032 mono_decimal_from_number (void *from, MonoDecimal *target)
3034 MonoNumber *number = (MonoNumber *) from;
3035 uint16_t* p = number->digits;
3037 int e = number->scale;
3038 g_assert(number != NULL);
3039 g_assert(target != NULL);
3042 DECIMAL_SIGNSCALE(d) = 0;
3043 DECIMAL_HI32(d) = 0;
3044 DECIMAL_LO32(d) = 0;
3045 DECIMAL_MID32(d) = 0;
3046 g_assert(p != NULL);
3048 // 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
3049 // the scale to 0 if the scale was previously positive
3054 if (e > DECIMAL_PRECISION) return 0;
3055 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'))))))) {
3058 DecAddInt32(&d, *p++ - '0');
3062 gboolean round = TRUE;
3063 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
3064 // For digits > 5 we will be roundinp up anyway.
3065 int count = 20; // Look at the next 20 digits to check to round
3066 while (*p == '0' && count != 0) {
3070 if (*p == '\0' || count == 0)
3071 round = FALSE;// Do nothing
3076 if ((DECIMAL_HI32(d) | DECIMAL_MID32(d) | DECIMAL_LO32(d)) == 0) {
3077 DECIMAL_HI32(d) = 0x19999999;
3078 DECIMAL_MID32(d) = 0x99999999;
3079 DECIMAL_LO32(d) = 0x9999999A;
3087 if (e <= -DECIMAL_PRECISION) {
3088 // Parsing a large scale zero can give you more precision than fits in the decimal.
3089 // This should only happen for actual zeros or very small numbers that round to zero.
3090 DECIMAL_SIGNSCALE(d) = 0;
3091 DECIMAL_HI32(d) = 0;
3092 DECIMAL_LO32(d) = 0;
3093 DECIMAL_MID32(d) = 0;
3094 DECIMAL_SCALE(d) = (DECIMAL_PRECISION - 1);
3096 DECIMAL_SCALE(d) = (uint8_t)(-e);
3099 DECIMAL_SIGN(d) = number->sign? DECIMAL_NEG: 0;