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"
32 #include "number-ms.h"
34 #define min(a, b) (((a) < (b)) ? (a) : (b))
38 MONO_DECIMAL_OVERFLOW,
39 MONO_DECIMAL_INVALID_ARGUMENT,
40 MONO_DECIMAL_DIVBYZERO,
41 MONO_DECIMAL_ARGUMENT_OUT_OF_RANGE
48 static const uint32_t ten_to_nine = 1000000000U;
49 static const uint32_t ten_to_ten_div_4 = 2500000000U;
51 #define DECIMAL_NEG ((uint8_t)0x80)
53 #define DECIMAL_SCALE(dec) ((dec).u.u.scale)
54 #define DECIMAL_SIGN(dec) ((dec).u.u.sign)
55 #define DECIMAL_SIGNSCALE(dec) ((dec).u.signscale)
56 #define DECIMAL_LO32(dec) ((dec).v.v.Lo32)
57 #define DECIMAL_MID32(dec) ((dec).v.v.Mid32)
58 #define DECIMAL_HI32(dec) ((dec).Hi32)
59 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
60 # define DECIMAL_LO64_GET(dec) (((uint64_t)((dec).v.v.Mid32) << 32) | (dec).v.v.Lo32)
61 # define DECIMAL_LO64_SET(dec,value) {(dec).v.v.Lo32 = (value); (dec).v.v.Mid32 = ((value) >> 32); }
63 # define DECIMAL_LO64_GET(dec) ((dec).v.Lo64)
64 # define DECIMAL_LO64_SET(dec,value) {(dec).v.Lo64 = value; }
67 #define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
68 #define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
69 DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
71 #define DEC_SCALE_MAX 28
74 #define OVFL_MAX_9_HI 4
75 #define OVFL_MAX_9_MID 1266874889
76 #define OVFL_MAX_9_LO 3047500985u
78 #define OVFL_MAX_5_HI 42949
79 #define OVFL_MAX_5_MID 2890341191
81 #define OVFL_MAX_1_HI 429496729
86 #if BYTE_ORDER == G_BIG_ENDIAN
96 static const SPLIT64 ten_to_eighteen = { 1000000000000000000ULL };
98 const MonoDouble_double ds2to64 = { .s = { .sign = 0, .exp = MONO_DOUBLE_BIAS + 65, .mantHi = 0, .mantLo = 0 } };
104 static const uint32_t power10 [POWER10_MAX+1] = {
105 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
109 static const double double_power10[] = {
110 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
111 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
112 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
113 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
114 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
115 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
116 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
117 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
120 const SPLIT64 sdl_power10[] = { {10000000000ULL}, // 1E10
121 {100000000000ULL}, // 1E11
122 {1000000000000ULL}, // 1E12
123 {10000000000000ULL}, // 1E13
124 {100000000000000ULL} }; // 1E14
126 static const uint64_t long_power10[] = {
143 10000000000000000ULL,
144 100000000000000000ULL,
145 1000000000000000000ULL,
146 10000000000000000000ULL};
149 uint32_t Hi, Mid, Lo;
152 const DECOVFL power_overflow[] = {
153 // This is a table of the largest values that can be in the upper two
154 // ULONGs of a 96-bit number that will not overflow when multiplied
155 // by a given power. For the upper word, this is a table of
156 // 2^32 / 10^n for 1 <= n <= 9. For the lower word, this is the
157 // remaining fraction part * 2^32. 2^32 = 4294967296.
159 { 429496729u, 2576980377u, 2576980377u }, // 10^1 remainder 0.6
160 { 42949672u, 4123168604u, 687194767u }, // 10^2 remainder 0.16
161 { 4294967u, 1271310319u, 2645699854u }, // 10^3 remainder 0.616
162 { 429496u, 3133608139u, 694066715u }, // 10^4 remainder 0.1616
163 { 42949u, 2890341191u, 2216890319u }, // 10^5 remainder 0.51616
164 { 4294u, 4154504685u, 2369172679u }, // 10^6 remainder 0.551616
165 { 429u, 2133437386u, 4102387834u }, // 10^7 remainder 0.9551616
166 { 42u, 4078814305u, 410238783u }, // 10^8 remainder 0.09991616
167 { 4u, 1266874889u, 3047500985u }, // 10^9 remainder 0.709551616
171 #define UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b)))
172 #define Div64by32(num, den) ((uint32_t)((uint64_t)(num) / (uint32_t)(den)))
173 #define Mod64by32(num, den) ((uint32_t)((uint64_t)(num) % (uint32_t)(den)))
178 const int maxIx = (sizeof(double_power10)/sizeof(double_power10[0]));
181 return double_power10[ix];
182 return pow(10.0, ix);
183 } // double fnDblPower10()
186 static inline int64_t
187 DivMod32by32(int32_t num, int32_t den)
191 sdl.u.Lo = num / den;
192 sdl.u.Hi = num % den;
196 static inline int64_t
197 DivMod64by32(int64_t num, int32_t den)
201 sdl.u.Lo = Div64by32(num, den);
202 sdl.u.Hi = Mod64by32(num, den);
207 UInt64x64To128(SPLIT64 op1, SPLIT64 op2, uint64_t *hi)
213 tmp1.int64 = UInt32x32To64(op1.u.Lo, op2.u.Lo); // lo partial prod
214 tmp2.int64 = UInt32x32To64(op1.u.Lo, op2.u.Hi); // mid 1 partial prod
215 tmp1.u.Hi += tmp2.u.Lo;
216 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
218 tmp3.int64 = UInt32x32To64(op1.u.Hi, op2.u.Hi) + (uint64_t)tmp2.u.Hi;
219 tmp2.int64 = UInt32x32To64(op1.u.Hi, op2.u.Lo);
220 tmp1.u.Hi += tmp2.u.Lo;
221 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
223 tmp3.int64 += (uint64_t)tmp2.u.Hi;
233 * pdlNum - Pointer to 64-bit dividend
234 * ulDen - 32-bit divisor
237 * Do full divide, yielding 64-bit result and 32-bit remainder.
240 * Quotient overwrites dividend.
246 // Was: FullDiv64By32
248 FullDiv64By32 (uint64_t *num, uint32_t den)
256 if (tmp.u.Hi >= den) {
257 // DivMod64by32 returns quotient in Lo, remainder in Hi.
260 res.int64 = DivMod64by32(res.int64, den);
265 tmp.int64 = DivMod64by32(tmp.int64, den);
275 * res_hi - Top uint32_t of quotient
276 * res_mid - Middle uint32_t of quotient
277 * res_lo - Bottom uint32_t of quotient
278 * scale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
281 * Determine the max power of 10, <= 9, that the quotient can be scaled
282 * up by and still fit in 96 bits.
285 * Returns power of 10 to scale by, -1 if overflow error.
287 ***********************************************************************/
290 SearchScale(uint32_t res_hi, uint32_t res_mid, uint32_t res_lo, int scale)
294 // Quick check to stop us from trying to scale any more.
296 if (res_hi > OVFL_MAX_1_HI || scale >= DEC_SCALE_MAX) {
301 if (scale > DEC_SCALE_MAX - 9) {
302 // We can't scale by 10^9 without exceeding the max scale factor.
303 // See if we can scale to the max. If not, we'll fall into
304 // standard search for scale factor.
306 cur_scale = DEC_SCALE_MAX - scale;
307 if (res_hi < power_overflow[cur_scale - 1].Hi)
310 if (res_hi == power_overflow[cur_scale - 1].Hi) {
312 if (res_mid > power_overflow[cur_scale - 1].Mid ||
313 (res_mid == power_overflow[cur_scale - 1].Mid && res_lo > power_overflow[cur_scale - 1].Lo)) {
318 } 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))
321 // Search for a power to scale by < 9. Do a binary search
322 // on power_overflow[].
325 if (res_hi < OVFL_MAX_5_HI)
327 else if (res_hi > OVFL_MAX_5_HI)
332 // cur_scale is 3 or 7.
334 if (res_hi < power_overflow[cur_scale - 1].Hi)
336 else if (res_hi > power_overflow[cur_scale - 1].Hi)
341 // cur_scale is 2, 4, 6, or 8.
343 // In all cases, we already found we could not use the power one larger.
344 // So if we can use this power, it is the biggest, and we're done. If
345 // we can't use this power, the one below it is correct for all cases
346 // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
348 if (res_hi > power_overflow[cur_scale - 1].Hi)
351 if (res_hi == power_overflow[cur_scale - 1].Hi)
355 // cur_scale = largest power of 10 we can scale by without overflow,
356 // cur_scale < 9. See if this is enough to make scale factor
357 // positive if it isn't already.
359 if (cur_scale + scale < 0)
370 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
371 * ulDen - 32-bit divisor.
374 * Do full divide, yielding 96-bit result and 32-bit remainder.
377 * Quotient overwrites dividend.
385 Div96By32(uint32_t *num, uint32_t den)
403 tmp.int64 = DivMod64by32(tmp.int64, den);
407 tmp.int64 = DivMod64by32(tmp.int64, den);
411 tmp.int64 = DivMod64by32(tmp.int64, den);
420 * pdecRes - Pointer to Decimal result location
421 * operand - Pointer to Decimal operand
424 * Chop the value to integer. Return remainder so Int() function
425 * can round down if non-zero.
433 ***********************************************************************/
436 DecFixInt(MonoDecimal * result, MonoDecimal * operand)
443 if (operand->u.u.scale > 0) {
444 num[0] = operand->v.v.Lo32;
445 num[1] = operand->v.v.Mid32;
446 num[2] = operand->Hi32;
447 scale = operand->u.u.scale;
448 result->u.u.sign = operand->u.u.sign;
452 if (scale > POWER10_MAX)
455 pwr = power10[scale];
457 rem |= Div96By32(num, pwr);
461 result->v.v.Lo32 = num[0];
462 result->v.v.Mid32 = num[1];
463 result->Hi32 = num[2];
464 result->u.u.scale = 0;
469 COPYDEC(*result, *operand);
470 // Odd, the Microsoft code does not set result->reserved to zero on this case
478 * res - Array of uint32_ts with value, least-significant first.
479 * hi_res - Index of last non-zero value in res.
480 * scale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
483 * See if we need to scale the result to fit it in 96 bits.
484 * Perform needed scaling. Adjust scale factor accordingly.
487 * res updated in place, always 3 uint32_ts.
488 * New scale factor returned, -1 if overflow error.
492 ScaleResult(uint32_t *res, int hi_res, int scale)
501 // See if we need to scale the result. The combined scale must
502 // be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
504 // Start by figuring a lower bound on the scaling needed to make
505 // the upper 96 bits zero. hi_res is the index into res[]
506 // of the highest non-zero uint32_t.
508 new_scale = hi_res * 32 - 64 - 1;
514 if (!(tmp & 0xFFFF0000)) {
518 if (!(tmp & 0xFF000000)) {
522 if (!(tmp & 0xF0000000)) {
526 if (!(tmp & 0xC0000000)) {
530 if (!(tmp & 0x80000000)) {
535 // Multiply bit position by log10(2) to figure it's power of 10.
536 // We scale the log by 256. log(2) = .30103, * 256 = 77. Doing this
537 // with a multiply saves a 96-byte lookup table. The power returned
538 // is <= the power of the number, so we must add one power of 10
539 // to make it's integer part zero after dividing by 256.
541 // Note: the result of this multiplication by an approximation of
542 // log10(2) have been exhaustively checked to verify it gives the
543 // correct result. (There were only 95 to check...)
545 new_scale = ((new_scale * 77) >> 8) + 1;
547 // new_scale = min scale factor to make high 96 bits zero, 0 - 29.
548 // This reduces the scale factor of the result. If it exceeds the
549 // current scale of the result, we'll overflow.
551 if (new_scale > scale)
557 // Make sure we scale by enough to bring the current scale factor
560 if (new_scale < scale - DEC_SCALE_MAX)
561 new_scale = scale - DEC_SCALE_MAX;
563 if (new_scale != 0) {
564 // Scale by the power of 10 given by new_scale. Note that this is
565 // NOT guaranteed to bring the number within 96 bits -- it could
566 // be 1 power of 10 short.
570 sdlTmp.u.Hi = 0; // initialize remainder
574 sticky |= sdlTmp.u.Hi; // record remainder as sticky bit
576 if (new_scale > POWER10_MAX)
579 pwr = power10[new_scale];
581 // Compute first quotient.
582 // DivMod64by32 returns quotient in Lo, remainder in Hi.
584 sdlTmp.int64 = DivMod64by32(res[hi_res], pwr);
585 res[hi_res] = sdlTmp.u.Lo;
589 // If first quotient was 0, update hi_res.
591 if (sdlTmp.u.Lo == 0)
594 // Compute subsequent quotients.
597 sdlTmp.u.Lo = res[cur];
598 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, pwr);
599 res[cur] = sdlTmp.u.Lo;
605 new_scale -= POWER10_MAX;
607 continue; // scale some more
609 // If we scaled enough, hi_res would be 2 or less. If not,
610 // divide by 10 more.
615 continue; // scale by 10
618 // Round final result. See if remainder >= 1/2 of divisor.
619 // If remainder == 1/2 divisor, round up if odd or sticky bit set.
621 pwr >>= 1; // power of 10 always even
622 if ( pwr <= sdlTmp.u.Hi && (pwr < sdlTmp.u.Hi ||
623 ((res[0] & 1) | sticky)) ) {
625 while (++res[++cur] == 0);
628 // The rounding caused us to carry beyond 96 bits.
632 sticky = 0; // no sticky bit
633 sdlTmp.u.Hi = 0; // or remainder
636 continue; // scale by 10
640 // We may have scaled it more than we planned. Make sure the scale
641 // factor hasn't gone negative, indicating overflow.
653 // Returns: MONO_DECIMAL_OVERFLOW or MONO_DECIMAL_OK
654 static MonoDecimalStatus
655 mono_decimal_multiply_result(MonoDecimal * left, MonoDecimal * right, MonoDecimal * result)
667 scale = left->u.u.scale + right->u.u.scale;
669 if ((left->Hi32 | left->v.v.Mid32 | right->Hi32 | right->v.v.Mid32) == 0) {
670 // Upper 64 bits are zero.
672 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
673 if (scale > DEC_SCALE_MAX)
675 // Result scale is too big. Divide result by power of 10 to reduce it.
676 // If the amount to divide by is > 19 the result is guaranteed
677 // less than 1/2. [max value in 64 bits = 1.84E19]
679 scale -= DEC_SCALE_MAX;
682 DECIMAL_SETZERO(*result);
683 return MONO_DECIMAL_OK;
686 if (scale > POWER10_MAX) {
687 // Divide by 1E10 first, to get the power down to a 32-bit quantity.
688 // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
689 // then multiply the next divisor by 4 (which will be a max of 4E9).
691 rem_lo = FullDiv64By32(&tmp.int64, ten_to_ten_div_4);
692 pwr = power10[scale - 10] << 2;
694 pwr = power10[scale];
698 // Power to divide by fits in 32 bits.
700 rem_hi = FullDiv64By32(&tmp.int64, pwr);
702 // Round result. See if remainder >= 1/2 of divisor.
703 // Divisor is a power of 10, so it is always even.
706 if (rem_hi >= pwr && (rem_hi > pwr || (rem_lo | (tmp.u.Lo & 1))))
709 scale = DEC_SCALE_MAX;
711 DECIMAL_LO32(*result) = tmp.u.Lo;
712 DECIMAL_MID32(*result) = tmp.u.Hi;
713 DECIMAL_HI32(*result) = 0;
715 // At least one operand has bits set in the upper 64 bits.
717 // Compute and accumulate the 9 partial products into a
718 // 192-bit (24-byte) result.
720 // [l-h][l-m][l-l] left high, middle, low
721 // x [r-h][r-m][r-l] right high, middle, low
722 // ------------------------------
724 // [0-h][0-l] l-l * r-l
725 // [1ah][1al] l-l * r-m
726 // [1bh][1bl] l-m * r-l
727 // [2ah][2al] l-m * r-m
728 // [2bh][2bl] l-l * r-h
729 // [2ch][2cl] l-h * r-l
730 // [3ah][3al] l-m * r-h
731 // [3bh][3bl] l-h * r-m
732 // [4-h][4-l] l-h * r-h
733 // ------------------------------
734 // [p-5][p-4][p-3][p-2][p-1][p-0] prod[] array
736 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
739 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Mid32) + tmp.u.Hi;
741 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Lo32);
742 tmp.int64 += tmp2.int64; // this could generate carry
744 if (tmp.int64 < tmp2.int64) // detect carry
748 tmp2.u.Lo = tmp.u.Hi;
750 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Mid32) + tmp2.int64;
752 if (left->Hi32 | right->Hi32) {
753 // Highest 32 bits is non-zero. Calculate 5 more partial products.
755 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->Hi32);
756 tmp.int64 += tmp2.int64; // this could generate carry
757 if (tmp.int64 < tmp2.int64) // detect carry
762 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Lo32);
763 tmp.int64 += tmp2.int64; // this could generate carry
765 if (tmp.int64 < tmp2.int64) // detect carry
767 tmp3.u.Lo = tmp.u.Hi;
769 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->Hi32);
770 tmp.int64 += tmp3.int64; // this could generate carry
771 if (tmp.int64 < tmp3.int64) // detect carry
776 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Mid32);
777 tmp.int64 += tmp2.int64; // this could generate carry
779 if (tmp.int64 < tmp2.int64) // detect carry
781 tmp3.u.Lo = tmp.u.Hi;
783 tmp.int64 = UInt32x32To64(left->Hi32, right->Hi32) + tmp3.int64;
795 // Check for leading zero uint32_ts on the product
797 while (prod[hi_prod] == 0) {
803 scale = ScaleResult(prod, hi_prod, scale);
805 return MONO_DECIMAL_OVERFLOW;
807 result->v.v.Lo32 = prod[0];
808 result->v.v.Mid32 = prod[1];
809 result->Hi32 = prod[2];
812 result->u.u.sign = right->u.u.sign ^ left->u.u.sign;
813 result->u.u.scale = (char)scale;
814 return MONO_DECIMAL_OK;
817 // Addition and subtraction
818 static MonoDecimalStatus
819 DecAddSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result, int8_t sign)
829 MonoDecimal *pdecTmp;
831 sign ^= (right->u.u.sign ^ left->u.u.sign) & DECIMAL_NEG;
833 if (right->u.u.scale == left->u.u.scale) {
834 // Scale factors are equal, no alignment necessary.
836 decRes.u.signscale = left->u.signscale;
840 // Signs differ - subtract
842 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right));
843 DECIMAL_HI32(decRes) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
847 if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*left)) {
849 if (decRes.Hi32 >= left->Hi32)
851 } else if (decRes.Hi32 > left->Hi32) {
852 // Got negative result. Flip its sign.
855 DECIMAL_LO64_SET(decRes, -(uint64_t)DECIMAL_LO64_GET(decRes));
856 decRes.Hi32 = ~decRes.Hi32;
857 if (DECIMAL_LO64_GET(decRes) == 0)
859 decRes.u.u.sign ^= DECIMAL_NEG;
863 // Signs are the same - add
865 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right));
866 decRes.Hi32 = left->Hi32 + right->Hi32;
870 if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*left)) {
872 if (decRes.Hi32 <= left->Hi32)
874 } else if (decRes.Hi32 < left->Hi32) {
876 // The addition carried above 96 bits. Divide the result by 10,
877 // dropping the scale factor.
879 if (decRes.u.u.scale == 0)
880 return MONO_DECIMAL_OVERFLOW;
883 tmp.u.Lo = decRes.Hi32;
885 tmp.int64 = DivMod64by32(tmp.int64, 10);
886 decRes.Hi32 = tmp.u.Lo;
888 tmp.u.Lo = decRes.v.v.Mid32;
889 tmp.int64 = DivMod64by32(tmp.int64, 10);
890 decRes.v.v.Mid32 = tmp.u.Lo;
892 tmp.u.Lo = decRes.v.v.Lo32;
893 tmp.int64 = DivMod64by32(tmp.int64, 10);
894 decRes.v.v.Lo32 = tmp.u.Lo;
896 // See if we need to round up.
898 if (tmp.u.Hi >= 5 && (tmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
899 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
900 if (DECIMAL_LO64_GET(decRes) == 0)
907 // Scale factors are not equal. Assume that a larger scale
908 // factor (more decimal places) is likely to mean that number
909 // is smaller. Start by guessing that the right operand has
910 // the larger scale factor. The result will have the larger
913 decRes.u.u.scale = right->u.u.scale; // scale factor of "smaller"
914 decRes.u.u.sign = left->u.u.sign; // but sign of "larger"
915 scale = decRes.u.u.scale - left->u.u.scale;
918 // Guessed scale factor wrong. Swap operands.
921 decRes.u.u.scale = left->u.u.scale;
922 decRes.u.u.sign ^= sign;
928 // *left will need to be multiplied by 10^scale so
929 // it will have the same scale as *right. We could be
930 // extending it to up to 192 bits of precision.
932 if (scale <= POWER10_MAX) {
933 // Scaling won't make it larger than 4 uint32_ts
935 pwr = power10[scale];
936 DECIMAL_LO64_SET(decTmp, UInt32x32To64(left->v.v.Lo32, pwr));
937 tmp.int64 = UInt32x32To64(left->v.v.Mid32, pwr);
938 tmp.int64 += decTmp.v.v.Mid32;
939 decTmp.v.v.Mid32 = tmp.u.Lo;
940 decTmp.Hi32 = tmp.u.Hi;
941 tmp.int64 = UInt32x32To64(left->Hi32, pwr);
942 tmp.int64 += decTmp.Hi32;
944 // Result fits in 96 bits. Use standard aligned add.
946 decTmp.Hi32 = tmp.u.Lo;
950 num[0] = decTmp.v.v.Lo32;
951 num[1] = decTmp.v.v.Mid32;
957 // Have to scale by a bunch. Move the number to a buffer
958 // where it has room to grow as it's scaled.
960 num[0] = left->v.v.Lo32;
961 num[1] = left->v.v.Mid32;
965 // Scan for zeros in the upper words.
972 // Left arg is zero, return right.
974 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*right));
975 decRes.Hi32 = right->Hi32;
976 decRes.u.u.sign ^= sign;
982 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
983 // with index of highest non-zero uint32_t.
985 for (; scale > 0; scale -= POWER10_MAX) {
986 if (scale > POWER10_MAX)
989 pwr = power10[scale];
992 for (cur = 0; cur <= hi_prod; cur++) {
993 tmp.int64 = UInt32x32To64(num[cur], pwr) + tmp.u.Hi;
998 // We're extending the result by another uint32_t.
999 num[++hi_prod] = tmp.u.Hi;
1003 // Scaling complete, do the add. Could be subtract if signs differ.
1009 // Signs differ, subtract.
1011 DECIMAL_LO64_SET(decRes, tmp.int64 - DECIMAL_LO64_GET(*right));
1012 decRes.Hi32 = num[2] - right->Hi32;
1016 if (DECIMAL_LO64_GET(decRes) > tmp.int64) {
1018 if (decRes.Hi32 >= num[2])
1021 else if (decRes.Hi32 > num[2]) {
1023 // If num has more than 96 bits of precision, then we need to
1024 // carry the subtraction into the higher bits. If it doesn't,
1025 // then we subtracted in the wrong order and have to flip the
1026 // sign of the result.
1032 while(num[cur++]-- == 0);
1033 if (num[hi_prod] == 0)
1038 // Signs the same, add.
1040 DECIMAL_LO64_SET(decRes, tmp.int64 + DECIMAL_LO64_GET(*right));
1041 decRes.Hi32 = num[2] + right->Hi32;
1045 if (DECIMAL_LO64_GET(decRes) < tmp.int64) {
1047 if (decRes.Hi32 <= num[2])
1050 else if (decRes.Hi32 < num[2]) {
1052 // Had a carry above 96 bits.
1056 if (hi_prod < cur) {
1061 }while (++num[cur++] == 0);
1066 num[0] = decRes.v.v.Lo32;
1067 num[1] = decRes.v.v.Mid32;
1068 num[2] = decRes.Hi32;
1069 decRes.u.u.scale = ScaleResult(num, hi_prod, decRes.u.u.scale);
1070 if (decRes.u.u.scale == (uint8_t) -1)
1071 return MONO_DECIMAL_OVERFLOW;
1073 decRes.v.v.Lo32 = num[0];
1074 decRes.v.v.Mid32 = num[1];
1075 decRes.Hi32 = num[2];
1080 COPYDEC(*result, decRes);
1081 // Odd, the Microsoft code does not set result->reserved to zero on this case
1082 return MONO_DECIMAL_OK;
1086 static MonoDecimalStatus G_GNUC_UNUSED
1087 mono_decimal_add(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1089 return DecAddSub (left, right, result, 0);
1092 // Decimal subtraction
1093 static MonoDecimalStatus G_GNUC_UNUSED
1094 mono_decimal_sub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1096 return DecAddSub (left, right, result, DECIMAL_NEG);
1103 * num - Pointer to 96-bit number as array of uint32_ts, least-sig first
1104 * pwr - Scale factor to multiply by
1107 * Multiply the two numbers. The low 96 bits of the result overwrite
1108 * the input. The last 32 bits of the product are the return value.
1111 * Returns highest 32 bits of product.
1118 IncreaseScale(uint32_t *num, uint32_t pwr)
1122 sdlTmp.int64 = UInt32x32To64(num[0], pwr);
1123 num[0] = sdlTmp.u.Lo;
1124 sdlTmp.int64 = UInt32x32To64(num[1], pwr) + sdlTmp.u.Hi;
1125 num[1] = sdlTmp.u.Lo;
1126 sdlTmp.int64 = UInt32x32To64(num[2], pwr) + sdlTmp.u.Hi;
1127 num[2] = sdlTmp.u.Lo;
1135 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
1136 * sdlDen - 64-bit divisor.
1139 * Do partial divide, yielding 32-bit result and 64-bit remainder.
1140 * Divisor must be larger than upper 64 bits of dividend.
1143 * Remainder overwrites lower 64-bits of dividend.
1151 Div96By64(uint32_t *num, SPLIT64 den)
1157 sdlNum.u.Lo = num[0];
1159 if (num[2] >= den.u.Hi) {
1160 // Divide would overflow. Assume a quotient of 2^32, and set
1161 // up remainder accordingly. Then jump to loop which reduces
1164 sdlNum.u.Hi = num[1] - den.u.Lo;
1169 // Hardware divide won't overflow
1171 if (num[2] == 0 && num[1] < den.u.Hi)
1172 // Result is zero. Entire dividend is remainder.
1176 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1180 quo.int64 = DivMod64by32(quo.int64, den.u.Hi);
1181 sdlNum.u.Hi = quo.u.Hi; // remainder
1183 // Compute full remainder, rem = dividend - (quo * divisor).
1185 prod.int64 = UInt32x32To64(quo.u.Lo, den.u.Lo); // quo * lo divisor
1186 sdlNum.int64 -= prod.int64;
1188 if (sdlNum.int64 > ~prod.int64) {
1190 // Remainder went negative. Add divisor back in until it's positive,
1191 // a max of 2 times.
1195 sdlNum.int64 += den.int64;
1196 }while (sdlNum.int64 >= den.int64);
1199 num[0] = sdlNum.u.Lo;
1200 num[1] = sdlNum.u.Hi;
1208 * rgulNum - Pointer to 128-bit dividend as array of uint32_ts, least-sig first
1209 * den - Pointer to 96-bit divisor.
1212 * Do partial divide, yielding 32-bit result and 96-bit remainder.
1213 * Top divisor uint32_t must be larger than top dividend uint32_t. This is
1214 * assured in the initial call because the divisor is normalized
1215 * and the dividend can't be. In subsequent calls, the remainder
1216 * is multiplied by 10^9 (max), so it can be no more than 1/4 of
1217 * the divisor which is effectively multiplied by 2^32 (4 * 10^9).
1220 * Remainder overwrites lower 96-bits of dividend.
1226 ***********************************************************************/
1229 Div128By96(uint32_t *num, uint32_t *den)
1236 sdlNum.u.Lo = num[0];
1237 sdlNum.u.Hi = num[1];
1239 if (num[3] == 0 && num[2] < den[2]){
1240 // Result is zero. Entire dividend is remainder.
1245 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1247 sdlQuo.u.Lo = num[2];
1248 sdlQuo.u.Hi = num[3];
1249 sdlQuo.int64 = DivMod64by32(sdlQuo.int64, den[2]);
1251 // Compute full remainder, rem = dividend - (quo * divisor).
1253 sdlProd1.int64 = UInt32x32To64(sdlQuo.u.Lo, den[0]); // quo * lo divisor
1254 sdlProd2.int64 = UInt32x32To64(sdlQuo.u.Lo, den[1]); // quo * mid divisor
1255 sdlProd2.int64 += sdlProd1.u.Hi;
1256 sdlProd1.u.Hi = sdlProd2.u.Lo;
1258 sdlNum.int64 -= sdlProd1.int64;
1259 num[2] = sdlQuo.u.Hi - sdlProd2.u.Hi; // sdlQuo.Hi is remainder
1261 // Propagate carries
1263 if (sdlNum.int64 > ~sdlProd1.int64) {
1265 if (num[2] >= ~sdlProd2.u.Hi)
1267 } else if (num[2] > ~sdlProd2.u.Hi) {
1269 // Remainder went negative. Add divisor back in until it's positive,
1270 // a max of 2 times.
1272 sdlProd1.u.Lo = den[0];
1273 sdlProd1.u.Hi = den[1];
1277 sdlNum.int64 += sdlProd1.int64;
1280 if (sdlNum.int64 < sdlProd1.int64) {
1281 // Detected carry. Check for carry out of top
1282 // before adding it in.
1284 if (num[2]++ < den[2])
1287 if (num[2] < den[2])
1288 break; // detected carry
1292 num[0] = sdlNum.u.Lo;
1293 num[1] = sdlNum.u.Hi;
1297 // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer
1298 // Returns FALSE if there is an overflow
1300 Add32To96(uint32_t *num, uint32_t value)
1303 if (num[0] < value) {
1304 if (++num[1] == 0) {
1305 if (++num[2] == 0) {
1314 OverflowUnscale (uint32_t *quo, gboolean remainder)
1318 // We have overflown, so load the high bit with a one.
1320 sdlTmp.u.Lo = quo[2];
1321 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1322 quo[2] = sdlTmp.u.Lo;
1323 sdlTmp.u.Lo = quo[1];
1324 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1325 quo[1] = sdlTmp.u.Lo;
1326 sdlTmp.u.Lo = quo[0];
1327 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1328 quo[0] = sdlTmp.u.Lo;
1329 // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up
1330 if ((sdlTmp.u.Hi > 5) || ((sdlTmp.u.Hi == 5) && ( remainder || (quo[0] & 1)))) {
1335 // mono_decimal_divide - Decimal divide
1336 static MonoDecimalStatus G_GNUC_UNUSED
1337 mono_decimal_divide_result(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1340 uint32_t quoSave[3];
1342 uint32_t divisor[3];
1351 scale = left->u.u.scale - right->u.u.scale;
1352 divisor[0] = right->v.v.Lo32;
1353 divisor[1] = right->v.v.Mid32;
1354 divisor[2] = right->Hi32;
1356 if (divisor[1] == 0 && divisor[2] == 0) {
1357 // Divisor is only 32 bits. Easy divide.
1359 if (divisor[0] == 0)
1360 return MONO_DECIMAL_DIVBYZERO;
1362 quo[0] = left->v.v.Lo32;
1363 quo[1] = left->v.v.Mid32;
1364 quo[2] = left->Hi32;
1365 rem[0] = Div96By32(quo, divisor[0]);
1370 cur_scale = min(9, -scale);
1376 // We have computed a quotient based on the natural scale
1377 // ( <dividend scale> - <divisor scale> ). We have a non-zero
1378 // remainder, so now we should increase the scale if possible to
1379 // include more quotient bits.
1381 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
1382 // computing more quotient bits as long as the remainder stays
1383 // non-zero. If scaling by that much would cause overflow, we'll
1384 // drop out of the loop and scale by as much as we can.
1386 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
1387 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
1388 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
1389 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
1390 // is the largest value in quo[1] (when quo[2] == 4) that is
1391 // assured not to overflow.
1393 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1394 if (cur_scale == 0) {
1395 // No more scaling to be done, but remainder is non-zero.
1399 if (utmp < rem[0] || (utmp >= divisor[0] &&
1400 (utmp > divisor[0] || (quo[0] & 1)))) {
1409 if (cur_scale == -1)
1410 return MONO_DECIMAL_OVERFLOW;
1413 pwr = power10[cur_scale];
1416 if (IncreaseScale(quo, pwr) != 0)
1417 return MONO_DECIMAL_OVERFLOW;
1419 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
1420 rem[0] = sdlTmp.u.Hi;
1422 quo[0] += sdlTmp.u.Lo;
1423 if (quo[0] < sdlTmp.u.Lo) {
1430 // Divisor has bits set in the upper 64 bits.
1432 // Divisor must be fully normalized (shifted so bit 31 of the most
1433 // significant uint32_t is 1). Locate the MSB so we know how much to
1434 // normalize by. The dividend will be shifted by the same amount so
1435 // the quotient is not changed.
1437 if (divisor[2] == 0)
1443 if (!(utmp & 0xFFFF0000)) {
1447 if (!(utmp & 0xFF000000)) {
1451 if (!(utmp & 0xF0000000)) {
1455 if (!(utmp & 0xC0000000)) {
1459 if (!(utmp & 0x80000000)) {
1464 // Shift both dividend and divisor left by cur_scale.
1466 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
1467 rem[0] = sdlTmp.u.Lo;
1468 rem[1] = sdlTmp.u.Hi;
1469 sdlTmp.u.Lo = left->v.v.Mid32;
1470 sdlTmp.u.Hi = left->Hi32;
1471 sdlTmp.int64 <<= cur_scale;
1472 rem[2] = sdlTmp.u.Hi;
1473 rem[3] = (left->Hi32 >> (31 - cur_scale)) >> 1;
1475 sdlDivisor.u.Lo = divisor[0];
1476 sdlDivisor.u.Hi = divisor[1];
1477 sdlDivisor.int64 <<= cur_scale;
1479 if (divisor[2] == 0) {
1480 // Have a 64-bit divisor in sdlDivisor. The remainder
1481 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
1483 sdlTmp.u.Lo = rem[2];
1484 sdlTmp.u.Hi = rem[3];
1487 quo[1] = Div96By64(&rem[1], sdlDivisor);
1488 quo[0] = Div96By64(rem, sdlDivisor);
1491 if ((rem[0] | rem[1]) == 0) {
1493 cur_scale = min(9, -scale);
1499 // Remainder is non-zero. Scale up quotient and remainder by
1500 // powers of 10 so we can compute more significant bits.
1502 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1503 if (cur_scale == 0) {
1504 // No more scaling to be done, but remainder is non-zero.
1507 sdlTmp.u.Lo = rem[0];
1508 sdlTmp.u.Hi = rem[1];
1509 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
1510 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
1515 if (cur_scale == -1)
1516 return MONO_DECIMAL_OVERFLOW;
1519 pwr = power10[cur_scale];
1522 if (IncreaseScale(quo, pwr) != 0)
1523 return MONO_DECIMAL_OVERFLOW;
1525 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
1526 IncreaseScale(rem, pwr);
1527 utmp = Div96By64(rem, sdlDivisor);
1536 // Have a 96-bit divisor in divisor[].
1538 // Start by finishing the shift left by cur_scale.
1540 sdlTmp.u.Lo = divisor[1];
1541 sdlTmp.u.Hi = divisor[2];
1542 sdlTmp.int64 <<= cur_scale;
1543 divisor[0] = sdlDivisor.u.Lo;
1544 divisor[1] = sdlDivisor.u.Hi;
1545 divisor[2] = sdlTmp.u.Hi;
1547 // The remainder (currently 96 bits spread over 4 uint32_ts)
1548 // will be < divisor.
1552 quo[0] = Div128By96(rem, divisor);
1555 if ((rem[0] | rem[1] | rem[2]) == 0) {
1557 cur_scale = min(9, -scale);
1563 // Remainder is non-zero. Scale up quotient and remainder by
1564 // powers of 10 so we can compute more significant bits.
1566 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1567 if (cur_scale == 0) {
1568 // No more scaling to be done, but remainder is non-zero.
1571 if (rem[2] >= 0x80000000)
1574 utmp = rem[0] > 0x80000000;
1575 utmp1 = rem[1] > 0x80000000;
1577 rem[1] = (rem[1] << 1) + utmp;
1578 rem[2] = (rem[2] << 1) + utmp1;
1580 if ((rem[2] > divisor[2] || rem[2] == divisor[2]) &&
1581 ((rem[1] > divisor[1] || rem[1] == divisor[1]) &&
1582 ((rem[0] > divisor[0] || rem[0] == divisor[0]) &&
1588 if (cur_scale == -1)
1589 return MONO_DECIMAL_OVERFLOW;
1592 pwr = power10[cur_scale];
1595 if (IncreaseScale(quo, pwr) != 0)
1596 return MONO_DECIMAL_OVERFLOW;
1598 rem[3] = IncreaseScale(rem, pwr);
1599 utmp = Div128By96(rem, divisor);
1609 // No more remainder. Try extracting any extra powers of 10 we may have
1610 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
1611 // If a division by one of these powers returns a zero remainder, then
1612 // we keep the quotient. If the remainder is not zero, then we restore
1613 // the previous value.
1615 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
1616 // we can extract. We use this as a quick test on whether to try a
1619 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
1620 quoSave[0] = quo[0];
1621 quoSave[1] = quo[1];
1622 quoSave[2] = quo[2];
1624 if (Div96By32(quoSave, 100000000) == 0) {
1625 quo[0] = quoSave[0];
1626 quo[1] = quoSave[1];
1627 quo[2] = quoSave[2];
1634 if ((quo[0] & 0xF) == 0 && scale >= 4) {
1635 quoSave[0] = quo[0];
1636 quoSave[1] = quo[1];
1637 quoSave[2] = quo[2];
1639 if (Div96By32(quoSave, 10000) == 0) {
1640 quo[0] = quoSave[0];
1641 quo[1] = quoSave[1];
1642 quo[2] = quoSave[2];
1647 if ((quo[0] & 3) == 0 && scale >= 2) {
1648 quoSave[0] = quo[0];
1649 quoSave[1] = quo[1];
1650 quoSave[2] = quo[2];
1652 if (Div96By32(quoSave, 100) == 0) {
1653 quo[0] = quoSave[0];
1654 quo[1] = quoSave[1];
1655 quo[2] = quoSave[2];
1660 if ((quo[0] & 1) == 0 && scale >= 1) {
1661 quoSave[0] = quo[0];
1662 quoSave[1] = quo[1];
1663 quoSave[2] = quo[2];
1665 if (Div96By32(quoSave, 10) == 0) {
1666 quo[0] = quoSave[0];
1667 quo[1] = quoSave[1];
1668 quo[2] = quoSave[2];
1673 result->Hi32 = quo[2];
1674 result->v.v.Mid32 = quo[1];
1675 result->v.v.Lo32 = quo[0];
1676 result->u.u.scale = scale;
1677 result->u.u.sign = left->u.u.sign ^ right->u.u.sign;
1678 return MONO_DECIMAL_OK;
1681 // mono_decimal_absolute - Decimal Absolute Value
1682 static void G_GNUC_UNUSED
1683 mono_decimal_absolute (MonoDecimal *pdecOprd, MonoDecimal *result)
1685 COPYDEC(*result, *pdecOprd);
1686 result->u.u.sign &= ~DECIMAL_NEG;
1687 // Microsoft does not set reserved here
1690 // mono_decimal_fix - Decimal Fix (chop to integer)
1692 mono_decimal_fix (MonoDecimal *pdecOprd, MonoDecimal *result)
1694 DecFixInt(result, pdecOprd);
1697 // mono_decimal_round_to_int - Decimal Int (round down to integer)
1699 mono_decimal_round_to_int (MonoDecimal *pdecOprd, MonoDecimal *result)
1701 if (DecFixInt(result, pdecOprd) != 0 && (result->u.u.sign & DECIMAL_NEG)) {
1702 // We have chopped off a non-zero amount from a negative value. Since
1703 // we round toward -infinity, we must increase the integer result by
1704 // 1 to make it more negative. This will never overflow because
1705 // in order to have a remainder, we must have had a non-zero scale factor.
1706 // Our scale factor is back to zero now.
1708 DECIMAL_LO64_SET(*result, DECIMAL_LO64_GET(*result) + 1);
1709 if (DECIMAL_LO64_GET(*result) == 0)
1714 // mono_decimal_negate - Decimal Negate
1715 static void G_GNUC_UNUSED
1716 mono_decimal_negate (MonoDecimal *pdecOprd, MonoDecimal *result)
1718 COPYDEC(*result, *pdecOprd);
1719 // Microsoft does not set result->reserved to zero on this case.
1720 result->u.u.sign ^= DECIMAL_NEG;
1724 // Returns: MONO_DECIMAL_INVALID_ARGUMENT, MONO_DECIMAL_OK
1726 static MonoDecimalStatus
1727 mono_decimal_round_result(MonoDecimal *input, int cDecimals, MonoDecimal *result)
1736 return MONO_DECIMAL_INVALID_ARGUMENT;
1738 scale = input->u.u.scale - cDecimals;
1740 num[0] = input->v.v.Lo32;
1741 num[1] = input->v.v.Mid32;
1742 num[2] = input->Hi32;
1743 result->u.u.sign = input->u.u.sign;
1748 if (scale > POWER10_MAX)
1751 pwr = power10[scale];
1753 rem = Div96By32(num, pwr);
1757 // Now round. rem has last remainder, sticky has sticky bits.
1758 // To do IEEE rounding, we add LSB of result to sticky bits so
1759 // either causes round up if remainder * 2 == last divisor.
1761 sticky |= num[0] & 1;
1762 rem = (rem << 1) + (sticky != 0);
1769 result->v.v.Lo32 = num[0];
1770 result->v.v.Mid32 = num[1];
1771 result->Hi32 = num[2];
1772 result->u.u.scale = cDecimals;
1773 return MONO_DECIMAL_OK;
1776 COPYDEC(*result, *input);
1777 // Odd, the Microsoft source does not set the result->reserved to zero here.
1778 return MONO_DECIMAL_OK;
1782 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1783 static MonoDecimalStatus
1784 mono_decimal_from_float (float input_f, MonoDecimal* result)
1786 int exp; // number of bits to left of binary point
1792 int lmax, cur; // temps used during scale reduction
1793 MonoSingle_float input = { .f = input_f };
1795 // The most we can scale by is 10^28, which is just slightly more
1796 // than 2^93. So a float with an exponent of -94 could just
1797 // barely reach 0.5, but smaller exponents will always round to zero.
1799 if ((exp = input.s.exp - MONO_SINGLE_BIAS) < -94 ) {
1800 DECIMAL_SETZERO(*result);
1801 return MONO_DECIMAL_OK;
1805 return MONO_DECIMAL_OVERFLOW;
1807 // Round the input to a 7-digit integer. The R4 format has
1808 // only 7 digits of precision, and we want to keep garbage digits
1809 // out of the Decimal were making.
1811 // Calculate max power of 10 input value could have by multiplying
1812 // the exponent by log10(2). Using scaled integer multiplcation,
1813 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1815 dbl = fabs(input.f);
1816 power = 6 - ((exp * 19728) >> 16);
1819 // We have less than 7 digits, scale input up.
1824 dbl = dbl * double_power10[power];
1826 if (power != -1 || dbl >= 1E7)
1827 dbl = dbl / fnDblPower10(-power);
1829 power = 0; // didn't scale it
1832 g_assert (dbl < 1E7);
1833 if (dbl < 1E6 && power < DECMAX) {
1836 g_assert(dbl >= 1E6);
1841 mant = (int32_t)dbl;
1842 dbl -= (double)mant; // difference between input & integer
1843 if ( dbl > 0.5 || (dbl == 0.5 && (mant & 1)))
1847 DECIMAL_SETZERO(*result);
1848 return MONO_DECIMAL_OK;
1852 // Add -power factors of 10, -power <= (29 - 7) = 22.
1856 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power]);
1858 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1859 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1860 DECIMAL_HI32(*result) = 0;
1862 // Have a big power of 10.
1865 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 18]);
1866 sdlLo.int64 = UInt64x64To128(sdlLo, ten_to_eighteen, &sdlHi.int64);
1868 if (sdlHi.u.Hi != 0)
1869 return MONO_DECIMAL_OVERFLOW;
1872 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 9]);
1873 sdlHi.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Hi);
1874 sdlLo.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Lo);
1875 sdlHi.int64 += sdlLo.u.Hi;
1876 sdlLo.u.Hi = sdlHi.u.Lo;
1877 sdlHi.u.Lo = sdlHi.u.Hi;
1879 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1880 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1881 DECIMAL_HI32(*result) = sdlHi.u.Lo;
1883 DECIMAL_SCALE(*result) = 0;
1885 // Factor out powers of 10 to reduce the scale, if possible.
1886 // The maximum number we could factor out would be 6. This
1887 // comes from the fact we have a 7-digit number, and the
1888 // MSD must be non-zero -- but the lower 6 digits could be
1889 // zero. Note also the scale factor is never negative, so
1890 // we can't scale by any more than the power we used to
1893 // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
1895 lmax = min(power, 6);
1897 // lmax is the largest power of 10 to try, lmax <= 6.
1898 // We'll try powers 4, 2, and 1 unless they're too big.
1900 for (cur = 4; cur > 0; cur >>= 1)
1905 sdlLo.int64 = DivMod32by32(mant, (uint32_t)long_power10[cur]);
1907 if (sdlLo.u.Hi == 0) {
1913 DECIMAL_LO32(*result) = mant;
1914 DECIMAL_MID32(*result) = 0;
1915 DECIMAL_HI32(*result) = 0;
1916 DECIMAL_SCALE(*result) = power;
1919 DECIMAL_SIGN(*result) = (char)input.s.sign << 7;
1920 return MONO_DECIMAL_OK;
1923 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1924 static MonoDecimalStatus
1925 mono_decimal_from_double (double input_d, MonoDecimal *result)
1927 int exp; // number of bits to left of binary point
1928 int power; // power-of-10 scale factor
1932 int lmax, cur; // temps used during scale reduction
1935 MonoDouble_double input = { .d = input_d };
1937 // The most we can scale by is 10^28, which is just slightly more
1938 // than 2^93. So a float with an exponent of -94 could just
1939 // barely reach 0.5, but smaller exponents will always round to zero.
1941 if ((exp = input.s.exp - MONO_DOUBLE_BIAS) < -94) {
1942 DECIMAL_SETZERO(*result);
1943 return MONO_DECIMAL_OK;
1947 return MONO_DECIMAL_OVERFLOW;
1949 // Round the input to a 15-digit integer. The R8 format has
1950 // only 15 digits of precision, and we want to keep garbage digits
1951 // out of the Decimal were making.
1953 // Calculate max power of 10 input value could have by multiplying
1954 // the exponent by log10(2). Using scaled integer multiplcation,
1955 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1957 dbl = fabs(input.d);
1958 power = 14 - ((exp * 19728) >> 16);
1961 // We have less than 15 digits, scale input up.
1966 dbl = dbl * double_power10[power];
1968 if (power != -1 || dbl >= 1E15)
1969 dbl = dbl / fnDblPower10(-power);
1971 power = 0; // didn't scale it
1974 g_assert (dbl < 1E15);
1975 if (dbl < 1E14 && power < DECMAX) {
1978 g_assert(dbl >= 1E14);
1983 sdlMant.int64 = (int64_t)dbl;
1984 dbl -= (double)(int64_t)sdlMant.int64; // dif between input & integer
1985 if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)))
1988 if (sdlMant.int64 == 0) {
1989 DECIMAL_SETZERO(*result);
1990 return MONO_DECIMAL_OK;
1994 // Add -power factors of 10, -power <= (29 - 15) = 14.
1998 sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (uint32_t)long_power10[power]);
1999 sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (uint32_t)long_power10[power]);
2000 sdlMant.int64 += sdlLo.u.Hi;
2001 sdlLo.u.Hi = sdlMant.u.Lo;
2002 sdlMant.u.Lo = sdlMant.u.Hi;
2005 // Have a big power of 10.
2007 g_assert(power <= 14);
2008 sdlLo.int64 = UInt64x64To128(sdlMant, sdl_power10[power-10], &sdlMant.int64);
2010 if (sdlMant.u.Hi != 0)
2011 return MONO_DECIMAL_OVERFLOW;
2013 DECIMAL_LO32(*result) = sdlLo.u.Lo;
2014 DECIMAL_MID32(*result) = sdlLo.u.Hi;
2015 DECIMAL_HI32(*result) = sdlMant.u.Lo;
2016 DECIMAL_SCALE(*result) = 0;
2019 // Factor out powers of 10 to reduce the scale, if possible.
2020 // The maximum number we could factor out would be 14. This
2021 // comes from the fact we have a 15-digit number, and the
2022 // MSD must be non-zero -- but the lower 14 digits could be
2023 // zero. Note also the scale factor is never negative, so
2024 // we can't scale by any more than the power we used to
2027 // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
2029 lmax = min(power, 14);
2031 // lmax is the largest power of 10 to try, lmax <= 14.
2032 // We'll try powers 8, 4, 2, and 1 unless they're too big.
2034 for (cur = 8; cur > 0; cur >>= 1)
2039 pwr_cur = (uint32_t)long_power10[cur];
2041 if (sdlMant.u.Hi >= pwr_cur) {
2042 // Overflow if we try to divide in one step.
2044 sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, pwr_cur);
2046 sdlLo.u.Lo = sdlMant.u.Lo;
2047 sdlLo.int64 = DivMod64by32(sdlLo.int64, pwr_cur);
2051 sdlLo.int64 = DivMod64by32(sdlMant.int64, pwr_cur);
2054 if (sdlLo.u.Hi == 0) {
2056 sdlMant.u.Lo = sdlLo.u.Lo;
2062 DECIMAL_HI32(*result) = 0;
2063 DECIMAL_SCALE(*result) = power;
2064 DECIMAL_LO32(*result) = sdlMant.u.Lo;
2065 DECIMAL_MID32(*result) = sdlMant.u.Hi;
2068 DECIMAL_SIGN(*result) = (char)input.s.sign << 7;
2069 return MONO_DECIMAL_OK;
2072 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2073 static MonoDecimalStatus
2074 mono_decimal_to_double_result(MonoDecimal *input, double *result)
2079 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2080 return MONO_DECIMAL_INVALID_ARGUMENT;
2082 tmp.u.Lo = DECIMAL_LO32(*input);
2083 tmp.u.Hi = DECIMAL_MID32(*input);
2085 if ((int32_t)DECIMAL_MID32(*input) < 0)
2086 dbl = (ds2to64.d + (double)(int64_t)tmp.int64 +
2087 (double)DECIMAL_HI32(*input) * ds2to64.d) / fnDblPower10(DECIMAL_SCALE(*input)) ;
2089 dbl = ((double)(int64_t)tmp.int64 +
2090 (double)DECIMAL_HI32(*input) * ds2to64.d) / fnDblPower10(DECIMAL_SCALE(*input));
2092 if (DECIMAL_SIGN(*input))
2096 return MONO_DECIMAL_OK;
2099 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2100 static MonoDecimalStatus
2101 mono_decimal_to_float_result(MonoDecimal *input, float *result)
2105 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2106 return MONO_DECIMAL_INVALID_ARGUMENT;
2108 // Can't overflow; no errors possible.
2110 mono_decimal_to_double_result(input, &dbl);
2111 *result = (float)dbl;
2112 return MONO_DECIMAL_OK;
2116 DecShiftLeft(MonoDecimal* value)
2118 unsigned int c0 = DECIMAL_LO32(*value) & 0x80000000? 1: 0;
2119 unsigned int c1 = DECIMAL_MID32(*value) & 0x80000000? 1: 0;
2120 g_assert(value != NULL);
2122 DECIMAL_LO32(*value) <<= 1;
2123 DECIMAL_MID32(*value) = DECIMAL_MID32(*value) << 1 | c0;
2124 DECIMAL_HI32(*value) = DECIMAL_HI32(*value) << 1 | c1;
2128 D32AddCarry(uint32_t* value, uint32_t i)
2130 uint32_t v = *value;
2131 uint32_t sum = v + i;
2133 return sum < v || sum < i? 1: 0;
2137 DecAdd(MonoDecimal *value, MonoDecimal* d)
2139 g_assert(value != NULL && d != NULL);
2141 if (D32AddCarry(&DECIMAL_LO32(*value), DECIMAL_LO32(*d))) {
2142 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2143 D32AddCarry(&DECIMAL_HI32(*value), 1);
2146 if (D32AddCarry(&DECIMAL_MID32(*value), DECIMAL_MID32(*d))) {
2147 D32AddCarry(&DECIMAL_HI32(*value), 1);
2149 D32AddCarry(&DECIMAL_HI32(*value), DECIMAL_HI32(*d));
2153 DecMul10(MonoDecimal* value)
2155 MonoDecimal d = *value;
2156 g_assert (value != NULL);
2158 DecShiftLeft(value);
2159 DecShiftLeft(value);
2161 DecShiftLeft(value);
2165 DecAddInt32(MonoDecimal* value, unsigned int i)
2167 g_assert(value != NULL);
2169 if (D32AddCarry(&DECIMAL_LO32(*value), i)) {
2170 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2171 D32AddCarry(&DECIMAL_HI32(*value), 1);
2176 MonoDecimalCompareResult
2177 mono_decimal_compare (MonoDecimal *left, MonoDecimal *right)
2180 uint32_t right_sign;
2183 result.Hi32 = 0; // Just to shut up the compiler
2185 // First check signs and whether either are zero. If both are
2186 // non-zero and of the same sign, just use subtraction to compare.
2188 left_sign = left->v.v.Lo32 | left->v.v.Mid32 | left->Hi32;
2189 right_sign = right->v.v.Lo32 | right->v.v.Mid32 | right->Hi32;
2191 left_sign = (left->u.u.sign & DECIMAL_NEG) | 1;
2193 if (right_sign != 0)
2194 right_sign = (right->u.u.sign & DECIMAL_NEG) | 1;
2196 // left_sign & right_sign have values 1, 0, or 0x81 depending on if the left/right
2197 // operand is +, 0, or -.
2199 if (left_sign == right_sign) {
2200 if (left_sign == 0) // both are zero
2201 return MONO_DECIMAL_CMP_EQ; // return equal
2203 DecAddSub(left, right, &result, DECIMAL_NEG);
2204 if (DECIMAL_LO64_GET(result) == 0 && result.Hi32 == 0)
2205 return MONO_DECIMAL_CMP_EQ;
2206 if (result.u.u.sign & DECIMAL_NEG)
2207 return MONO_DECIMAL_CMP_LT;
2208 return MONO_DECIMAL_CMP_GT;
2212 // Signs are different. Use signed byte comparison
2214 if ((signed char)left_sign > (signed char)right_sign)
2215 return MONO_DECIMAL_CMP_GT;
2216 return MONO_DECIMAL_CMP_LT;
2220 mono_decimal_init_single (MonoDecimal *_this, float value)
2222 if (mono_decimal_from_float (value, _this) == MONO_DECIMAL_OVERFLOW) {
2223 mono_set_pending_exception (mono_get_exception_overflow ());
2226 _this->reserved = 0;
2230 mono_decimal_init_double (MonoDecimal *_this, double value)
2232 if (mono_decimal_from_double (value, _this) == MONO_DECIMAL_OVERFLOW) {
2233 mono_set_pending_exception (mono_get_exception_overflow ());
2236 _this->reserved = 0;
2240 mono_decimal_floor (MonoDecimal *d)
2244 mono_decimal_round_to_int(d, &decRes);
2246 // copy decRes into d
2247 COPYDEC(*d, decRes);
2253 mono_decimal_get_hash_code (MonoDecimal *d)
2257 if (mono_decimal_to_double_result(d, &dbl) != MONO_DECIMAL_OK)
2261 // Ensure 0 and -0 have the same hash code
2264 // conversion to double is lossy and produces rounding errors so we mask off the lowest 4 bits
2266 // For example these two numerically equal decimals with different internal representations produce
2267 // slightly different results when converted to double:
2269 // decimal a = new decimal(new int[] { 0x76969696, 0x2fdd49fa, 0x409783ff, 0x00160000 });
2270 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.176470588
2271 // decimal b = new decimal(new int[] { 0x3f0f0f0f, 0x1e62edcc, 0x06758d33, 0x00150000 });
2272 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.1764705882
2274 return ((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
2279 mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2)
2283 MonoDecimalStatus status = mono_decimal_multiply_result(d1, d2, &decRes);
2284 if (status != MONO_DECIMAL_OK) {
2285 mono_set_pending_exception (mono_get_exception_overflow ());
2289 COPYDEC(*d1, decRes);
2296 mono_decimal_round (MonoDecimal *d, int32_t decimals)
2300 // GC is only triggered for throwing, no need to protect result
2301 if (decimals < 0 || decimals > 28) {
2302 mono_set_pending_exception (mono_get_exception_argument_out_of_range ("d"));
2306 mono_decimal_round_result(d, decimals, &decRes);
2308 // copy decRes into d
2309 COPYDEC(*d, decRes);
2316 mono_decimal_tocurrency (MonoDecimal *decimal)
2322 mono_decimal_to_double (MonoDecimal d)
2324 double result = 0.0;
2325 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2326 mono_decimal_to_double_result(&d, &result);
2331 mono_decimal_to_int32 (MonoDecimal d)
2335 // The following can not return an error, it only returns INVALID_ARG if the decimals is < 0
2336 mono_decimal_round_result(&d, 0, &result);
2338 if (DECIMAL_SCALE(result) != 0) {
2340 mono_decimal_fix (&d, &result);
2343 if (DECIMAL_HI32(result) == 0 && DECIMAL_MID32(result) == 0) {
2344 int32_t i = DECIMAL_LO32(result);
2345 if ((int16_t)DECIMAL_SIGNSCALE(result) >= 0) {
2355 mono_set_pending_exception (mono_get_exception_overflow ());
2360 mono_decimal_to_float (MonoDecimal d)
2362 float result = 0.0f;
2363 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2364 mono_decimal_to_float_result(&d, &result);
2369 mono_decimal_truncate (MonoDecimal *d)
2373 mono_decimal_fix(d, &decRes);
2375 // copy decRes into d
2376 COPYDEC(*d, decRes);
2382 mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign)
2384 MonoDecimal result, decTmp;
2385 MonoDecimal *pdecTmp, *leftOriginal;
2386 uint32_t num[6], pwr;
2387 int scale, hi_prod, cur;
2390 g_assert(sign == 0 || sign == DECIMAL_NEG);
2392 leftOriginal = left;
2394 sign ^= (DECIMAL_SIGN(*right) ^ DECIMAL_SIGN(*left)) & DECIMAL_NEG;
2396 if (DECIMAL_SCALE(*right) == DECIMAL_SCALE(*left)) {
2397 // Scale factors are equal, no alignment necessary.
2399 DECIMAL_SIGNSCALE(result) = DECIMAL_SIGNSCALE(*left);
2403 // Signs differ - subtract
2405 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right)));
2406 DECIMAL_HI32(result) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
2410 if (DECIMAL_LO64_GET(result) > DECIMAL_LO64_GET(*left)) {
2411 DECIMAL_HI32(result)--;
2412 if (DECIMAL_HI32(result) >= DECIMAL_HI32(*left))
2414 } else if (DECIMAL_HI32(result) > DECIMAL_HI32(*left)) {
2415 // Got negative result. Flip its sign.
2418 DECIMAL_LO64_SET(result, -(int64_t)DECIMAL_LO64_GET(result));
2419 DECIMAL_HI32(result) = ~DECIMAL_HI32(result);
2420 if (DECIMAL_LO64_GET(result) == 0)
2421 DECIMAL_HI32(result)++;
2422 DECIMAL_SIGN(result) ^= DECIMAL_NEG;
2426 // Signs are the same - add
2428 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right)));
2429 DECIMAL_HI32(result) = DECIMAL_HI32(*left) + DECIMAL_HI32(*right);
2433 if (DECIMAL_LO64_GET(result) < DECIMAL_LO64_GET(*left)) {
2434 DECIMAL_HI32(result)++;
2435 if (DECIMAL_HI32(result) <= DECIMAL_HI32(*left))
2437 } else if (DECIMAL_HI32(result) < DECIMAL_HI32(*left)) {
2439 // The addition carried above 96 bits. Divide the result by 10,
2440 // dropping the scale factor.
2442 if (DECIMAL_SCALE(result) == 0) {
2443 mono_set_pending_exception (mono_get_exception_overflow ());
2446 DECIMAL_SCALE(result)--;
2448 sdlTmp.u.Lo = DECIMAL_HI32(result);
2450 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2451 DECIMAL_HI32(result) = sdlTmp.u.Lo;
2453 sdlTmp.u.Lo = DECIMAL_MID32(result);
2454 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2455 DECIMAL_MID32(result) = sdlTmp.u.Lo;
2457 sdlTmp.u.Lo = DECIMAL_LO32(result);
2458 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2459 DECIMAL_LO32(result) = sdlTmp.u.Lo;
2461 // See if we need to round up.
2463 if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (DECIMAL_LO32(result) & 1))) {
2464 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(result)+1);
2465 if (DECIMAL_LO64_GET(result) == 0)
2466 DECIMAL_HI32(result)++;
2471 // Scale factors are not equal. Assume that a larger scale
2472 // factor (more decimal places) is likely to mean that number
2473 // is smaller. Start by guessing that the right operand has
2474 // the larger scale factor. The result will have the larger
2477 DECIMAL_SCALE(result) = DECIMAL_SCALE(*right); // scale factor of "smaller"
2478 DECIMAL_SIGN(result) = DECIMAL_SIGN(*left); // but sign of "larger"
2479 scale = DECIMAL_SCALE(result)- DECIMAL_SCALE(*left);
2482 // Guessed scale factor wrong. Swap operands.
2485 DECIMAL_SCALE(result) = DECIMAL_SCALE(*left);
2486 DECIMAL_SIGN(result) ^= sign;
2492 // *left will need to be multiplied by 10^scale so
2493 // it will have the same scale as *right. We could be
2494 // extending it to up to 192 bits of precision.
2496 if (scale <= POWER10_MAX) {
2497 // Scaling won't make it larger than 4 uint32_ts
2499 pwr = power10[scale];
2500 DECIMAL_LO64_SET(decTmp, UInt32x32To64(DECIMAL_LO32(*left), pwr));
2501 sdlTmp.int64 = UInt32x32To64(DECIMAL_MID32(*left), pwr);
2502 sdlTmp.int64 += DECIMAL_MID32(decTmp);
2503 DECIMAL_MID32(decTmp) = sdlTmp.u.Lo;
2504 DECIMAL_HI32(decTmp) = sdlTmp.u.Hi;
2505 sdlTmp.int64 = UInt32x32To64(DECIMAL_HI32(*left), pwr);
2506 sdlTmp.int64 += DECIMAL_HI32(decTmp);
2507 if (sdlTmp.u.Hi == 0) {
2508 // Result fits in 96 bits. Use standard aligned add.
2510 DECIMAL_HI32(decTmp) = sdlTmp.u.Lo;
2514 num[0] = DECIMAL_LO32(decTmp);
2515 num[1] = DECIMAL_MID32(decTmp);
2516 num[2] = sdlTmp.u.Lo;
2517 num[3] = sdlTmp.u.Hi;
2520 // Have to scale by a bunch. Move the number to a buffer
2521 // where it has room to grow as it's scaled.
2523 num[0] = DECIMAL_LO32(*left);
2524 num[1] = DECIMAL_MID32(*left);
2525 num[2] = DECIMAL_HI32(*left);
2528 // Scan for zeros in the upper words.
2535 // Left arg is zero, return right.
2537 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(*right));
2538 DECIMAL_HI32(result) = DECIMAL_HI32(*right);
2539 DECIMAL_SIGN(result) ^= sign;
2545 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
2546 // with index of highest non-zero uint32_t.
2548 for (; scale > 0; scale -= POWER10_MAX) {
2549 if (scale > POWER10_MAX)
2552 pwr = power10[scale];
2555 for (cur = 0; cur <= hi_prod; cur++) {
2556 sdlTmp.int64 = UInt32x32To64(num[cur], pwr) + sdlTmp.u.Hi;
2557 num[cur] = sdlTmp.u.Lo;
2560 if (sdlTmp.u.Hi != 0)
2561 // We're extending the result by another uint32_t.
2562 num[++hi_prod] = sdlTmp.u.Hi;
2566 // Scaling complete, do the add. Could be subtract if signs differ.
2568 sdlTmp.u.Lo = num[0];
2569 sdlTmp.u.Hi = num[1];
2572 // Signs differ, subtract.
2574 DECIMAL_LO64_SET(result, (sdlTmp.int64 - DECIMAL_LO64_GET(*right)));
2575 DECIMAL_HI32(result) = num[2] - DECIMAL_HI32(*right);
2579 if (DECIMAL_LO64_GET(result) > sdlTmp.int64) {
2580 DECIMAL_HI32(result)--;
2581 if (DECIMAL_HI32(result) >= num[2])
2583 } else if (DECIMAL_HI32(result) > num[2]) {
2585 // If num has more than 96 bits of precision, then we need to
2586 // carry the subtraction into the higher bits. If it doesn't,
2587 // then we subtracted in the wrong order and have to flip the
2588 // sign of the result.
2594 while(num[cur++]-- == 0);
2595 if (num[hi_prod] == 0)
2599 // Signs the same, add.
2601 DECIMAL_LO64_SET(result, (sdlTmp.int64 + DECIMAL_LO64_GET(*right)));
2602 DECIMAL_HI32(result) = num[2] + DECIMAL_HI32(*right);
2606 if (DECIMAL_LO64_GET(result) < sdlTmp.int64) {
2607 DECIMAL_HI32(result)++;
2608 if (DECIMAL_HI32(result) <= num[2])
2610 } else if (DECIMAL_HI32(result) < num[2]) {
2612 // Had a carry above 96 bits.
2616 if (hi_prod < cur) {
2621 }while (++num[cur++] == 0);
2626 num[0] = DECIMAL_LO32(result);
2627 num[1] = DECIMAL_MID32(result);
2628 num[2] = DECIMAL_HI32(result);
2629 DECIMAL_SCALE(result) = (uint8_t)ScaleResult(num, hi_prod, DECIMAL_SCALE(result));
2630 if (DECIMAL_SCALE(result) == (uint8_t)-1) {
2631 mono_set_pending_exception (mono_get_exception_overflow ());
2635 DECIMAL_LO32(result) = num[0];
2636 DECIMAL_MID32(result) = num[1];
2637 DECIMAL_HI32(result) = num[2];
2642 left = leftOriginal;
2643 COPYDEC(*left, result);
2648 mono_decimal_divide (MonoDecimal *left, MonoDecimal *right)
2650 uint32_t quo[3], quo_save[3],rem[4], divisor[3];
2651 uint32_t pwr, tmp, tmp1;
2652 SPLIT64 sdlTmp, sdlDivisor;
2653 int scale, cur_scale;
2656 scale = DECIMAL_SCALE(*left) - DECIMAL_SCALE(*right);
2658 divisor[0] = DECIMAL_LO32(*right);
2659 divisor[1] = DECIMAL_MID32(*right);
2660 divisor[2] = DECIMAL_HI32(*right);
2662 if (divisor[1] == 0 && divisor[2] == 0) {
2663 // Divisor is only 32 bits. Easy divide.
2665 if (divisor[0] == 0) {
2666 mono_set_pending_exception (mono_get_exception_divide_by_zero ());
2670 quo[0] = DECIMAL_LO32(*left);
2671 quo[1] = DECIMAL_MID32(*left);
2672 quo[2] = DECIMAL_HI32(*left);
2673 rem[0] = Div96By32(quo, divisor[0]);
2678 cur_scale = min(9, -scale);
2683 // We need to unscale if and only if we have a non-zero remainder
2686 // We have computed a quotient based on the natural scale
2687 // ( <dividend scale> - <divisor scale> ). We have a non-zero
2688 // remainder, so now we should increase the scale if possible to
2689 // include more quotient bits.
2691 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
2692 // computing more quotient bits as long as the remainder stays
2693 // non-zero. If scaling by that much would cause overflow, we'll
2694 // drop out of the loop and scale by as much as we can.
2696 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
2697 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
2698 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
2699 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
2700 // is the largest value in quo[1] (when quo[2] == 4) that is
2701 // assured not to overflow.
2703 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2704 if (cur_scale == 0) {
2705 // No more scaling to be done, but remainder is non-zero.
2709 if (tmp < rem[0] || (tmp >= divisor[0] &&
2710 (tmp > divisor[0] || (quo[0] & 1)))) {
2712 if (!Add32To96(quo, 1)) {
2714 mono_set_pending_exception (mono_get_exception_overflow ());
2718 OverflowUnscale(quo, TRUE);
2725 if (cur_scale < 0) {
2726 mono_set_pending_exception (mono_get_exception_overflow ());
2731 pwr = power10[cur_scale];
2734 if (IncreaseScale(quo, pwr) != 0) {
2735 mono_set_pending_exception (mono_get_exception_overflow ());
2739 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
2740 rem[0] = sdlTmp.u.Hi;
2742 if (!Add32To96(quo, sdlTmp.u.Lo)) {
2744 mono_set_pending_exception (mono_get_exception_overflow ());
2748 OverflowUnscale(quo, (rem[0] != 0));
2753 // Divisor has bits set in the upper 64 bits.
2755 // Divisor must be fully normalized (shifted so bit 31 of the most
2756 // significant uint32_t is 1). Locate the MSB so we know how much to
2757 // normalize by. The dividend will be shifted by the same amount so
2758 // the quotient is not changed.
2760 if (divisor[2] == 0)
2766 if (!(tmp & 0xFFFF0000)) {
2770 if (!(tmp & 0xFF000000)) {
2774 if (!(tmp & 0xF0000000)) {
2778 if (!(tmp & 0xC0000000)) {
2782 if (!(tmp & 0x80000000)) {
2787 // Shift both dividend and divisor left by cur_scale.
2789 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
2790 rem[0] = sdlTmp.u.Lo;
2791 rem[1] = sdlTmp.u.Hi;
2792 sdlTmp.u.Lo = DECIMAL_MID32(*left);
2793 sdlTmp.u.Hi = DECIMAL_HI32(*left);
2794 sdlTmp.int64 <<= cur_scale;
2795 rem[2] = sdlTmp.u.Hi;
2796 rem[3] = (DECIMAL_HI32(*left) >> (31 - cur_scale)) >> 1;
2798 sdlDivisor.u.Lo = divisor[0];
2799 sdlDivisor.u.Hi = divisor[1];
2800 sdlDivisor.int64 <<= cur_scale;
2802 if (divisor[2] == 0) {
2803 // Have a 64-bit divisor in sdlDivisor. The remainder
2804 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
2806 sdlTmp.u.Lo = rem[2];
2807 sdlTmp.u.Hi = rem[3];
2810 quo[1] = Div96By64(&rem[1], sdlDivisor);
2811 quo[0] = Div96By64(rem, sdlDivisor);
2814 if ((rem[0] | rem[1]) == 0) {
2816 cur_scale = min(9, -scale);
2822 // We need to unscale if and only if we have a non-zero remainder
2825 // Remainder is non-zero. Scale up quotient and remainder by
2826 // powers of 10 so we can compute more significant bits.
2828 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2829 if (cur_scale == 0) {
2830 // No more scaling to be done, but remainder is non-zero.
2833 sdlTmp.u.Lo = rem[0];
2834 sdlTmp.u.Hi = rem[1];
2835 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
2836 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
2841 if (cur_scale < 0) {
2842 mono_set_pending_exception (mono_get_exception_overflow ());
2847 pwr = power10[cur_scale];
2850 if (IncreaseScale(quo, pwr) != 0) {
2851 mono_set_pending_exception (mono_get_exception_overflow ());
2855 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
2856 IncreaseScale(rem, pwr);
2857 tmp = Div96By64(rem, sdlDivisor);
2858 if (!Add32To96(quo, tmp)) {
2860 mono_set_pending_exception (mono_get_exception_overflow ());
2864 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0));
2870 // Have a 96-bit divisor in divisor[].
2872 // Start by finishing the shift left by cur_scale.
2874 sdlTmp.u.Lo = divisor[1];
2875 sdlTmp.u.Hi = divisor[2];
2876 sdlTmp.int64 <<= cur_scale;
2877 divisor[0] = sdlDivisor.u.Lo;
2878 divisor[1] = sdlDivisor.u.Hi;
2879 divisor[2] = sdlTmp.u.Hi;
2881 // The remainder (currently 96 bits spread over 4 uint32_ts)
2882 // will be < divisor.
2886 quo[0] = Div128By96(rem, divisor);
2889 if ((rem[0] | rem[1] | rem[2]) == 0) {
2891 cur_scale = min(9, -scale);
2897 // We need to unscale if and only if we have a non-zero remainder
2900 // Remainder is non-zero. Scale up quotient and remainder by
2901 // powers of 10 so we can compute more significant bits.
2903 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2904 if (cur_scale == 0) {
2905 // No more scaling to be done, but remainder is non-zero.
2908 if (rem[2] >= 0x80000000)
2911 tmp = rem[0] > 0x80000000;
2912 tmp1 = rem[1] > 0x80000000;
2914 rem[1] = (rem[1] << 1) + tmp;
2915 rem[2] = (rem[2] << 1) + tmp1;
2917 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)))))))
2922 if (cur_scale < 0) {
2923 mono_set_pending_exception (mono_get_exception_overflow ());
2928 pwr = power10[cur_scale];
2931 if (IncreaseScale(quo, pwr) != 0) {
2932 mono_set_pending_exception (mono_get_exception_overflow ());
2936 rem[3] = IncreaseScale(rem, pwr);
2937 tmp = Div128By96(rem, divisor);
2938 if (!Add32To96(quo, tmp)) {
2940 mono_set_pending_exception (mono_get_exception_overflow ());
2945 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0 || rem[2] != 0 || rem[3] != 0));
2953 // We need to unscale if and only if we have a non-zero remainder
2955 // Try extracting any extra powers of 10 we may have
2956 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
2957 // If a division by one of these powers returns a zero remainder, then
2958 // we keep the quotient. If the remainder is not zero, then we restore
2959 // the previous value.
2961 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
2962 // we can extract. We use this as a quick test on whether to try a
2965 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
2966 quo_save[0] = quo[0];
2967 quo_save[1] = quo[1];
2968 quo_save[2] = quo[2];
2970 if (Div96By32(quo_save, 100000000) == 0) {
2971 quo[0] = quo_save[0];
2972 quo[1] = quo_save[1];
2973 quo[2] = quo_save[2];
2979 if ((quo[0] & 0xF) == 0 && scale >= 4) {
2980 quo_save[0] = quo[0];
2981 quo_save[1] = quo[1];
2982 quo_save[2] = quo[2];
2984 if (Div96By32(quo_save, 10000) == 0) {
2985 quo[0] = quo_save[0];
2986 quo[1] = quo_save[1];
2987 quo[2] = quo_save[2];
2992 if ((quo[0] & 3) == 0 && scale >= 2) {
2993 quo_save[0] = quo[0];
2994 quo_save[1] = quo[1];
2995 quo_save[2] = quo[2];
2997 if (Div96By32(quo_save, 100) == 0) {
2998 quo[0] = quo_save[0];
2999 quo[1] = quo_save[1];
3000 quo[2] = quo_save[2];
3005 if ((quo[0] & 1) == 0 && scale >= 1) {
3006 quo_save[0] = quo[0];
3007 quo_save[1] = quo[1];
3008 quo_save[2] = quo[2];
3010 if (Div96By32(quo_save, 10) == 0) {
3011 quo[0] = quo_save[0];
3012 quo[1] = quo_save[1];
3013 quo[2] = quo_save[2];
3019 DECIMAL_SIGN(*left) = DECIMAL_SIGN(*left) ^ DECIMAL_SIGN(*right);
3020 DECIMAL_HI32(*left) = quo[2];
3021 DECIMAL_MID32(*left) = quo[1];
3022 DECIMAL_LO32(*left) = quo[0];
3023 DECIMAL_SCALE(*left) = (uint8_t)scale;
3028 #define DECIMAL_PRECISION 29
3031 mono_decimal_from_number (void *from, MonoDecimal *target)
3033 MonoNumber *number = (MonoNumber *) from;
3034 uint16_t* p = number->digits;
3036 int e = number->scale;
3037 g_assert(number != NULL);
3038 g_assert(target != NULL);
3041 DECIMAL_SIGNSCALE(d) = 0;
3042 DECIMAL_HI32(d) = 0;
3043 DECIMAL_LO32(d) = 0;
3044 DECIMAL_MID32(d) = 0;
3045 g_assert(p != NULL);
3047 // 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
3048 // the scale to 0 if the scale was previously positive
3053 if (e > DECIMAL_PRECISION) return 0;
3054 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'))))))) {
3057 DecAddInt32(&d, *p++ - '0');
3061 gboolean round = TRUE;
3062 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
3063 // For digits > 5 we will be roundinp up anyway.
3064 int count = 20; // Look at the next 20 digits to check to round
3065 while (*p == '0' && count != 0) {
3069 if (*p == '\0' || count == 0)
3070 round = FALSE;// Do nothing
3075 if ((DECIMAL_HI32(d) | DECIMAL_MID32(d) | DECIMAL_LO32(d)) == 0) {
3076 DECIMAL_HI32(d) = 0x19999999;
3077 DECIMAL_MID32(d) = 0x99999999;
3078 DECIMAL_LO32(d) = 0x9999999A;
3086 if (e <= -DECIMAL_PRECISION) {
3087 // Parsing a large scale zero can give you more precision than fits in the decimal.
3088 // This should only happen for actual zeros or very small numbers that round to zero.
3089 DECIMAL_SIGNSCALE(d) = 0;
3090 DECIMAL_HI32(d) = 0;
3091 DECIMAL_LO32(d) = 0;
3092 DECIMAL_MID32(d) = 0;
3093 DECIMAL_SCALE(d) = (DECIMAL_PRECISION - 1);
3095 DECIMAL_SCALE(d) = (uint8_t)(-e);
3098 DECIMAL_SIGN(d) = number->sign? DECIMAL_NEG: 0;