2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5 // Copyright 2015 Xamarin Inc
9 // Ported from C++ to C and adjusted to Mono runtime
12 // DoToCurrency (they look like new methods we do not have)
14 #ifndef DISABLE_DECIMAL
18 #include <mono/utils/mono-compiler.h>
19 #include <mono/metadata/exception.h>
20 #include <mono/metadata/object-internals.h>
31 #include "decimal-ms.h"
33 #define min(a, b) (((a) < (b)) ? (a) : (b))
37 MONO_DECIMAL_OVERFLOW,
38 MONO_DECIMAL_INVALID_ARGUMENT,
39 MONO_DECIMAL_DIVBYZERO,
40 MONO_DECIMAL_ARGUMENT_OUT_OF_RANGE
47 static const uint32_t ten_to_nine = 1000000000U;
48 static const uint32_t ten_to_ten_div_4 = 2500000000U;
50 #define DECIMAL_NEG ((uint8_t)0x80)
52 #define DECIMAL_SCALE(dec) ((dec).u.u.scale)
53 #define DECIMAL_SIGN(dec) ((dec).u.u.sign)
54 #define DECIMAL_SIGNSCALE(dec) ((dec).u.signscale)
55 #define DECIMAL_LO32(dec) ((dec).v.v.Lo32)
56 #define DECIMAL_MID32(dec) ((dec).v.v.Mid32)
57 #define DECIMAL_HI32(dec) ((dec).Hi32)
58 #define DECIMAL_LO64_GET(dec) ((dec).v.Lo64)
59 #define DECIMAL_LO64_SET(dec,value) {(dec).v.Lo64 = value; }
61 #define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
62 #define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
63 DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
65 #define DEC_SCALE_MAX 28
68 #define OVFL_MAX_9_HI 4
69 #define OVFL_MAX_9_MID 1266874889
70 #define OVFL_MAX_9_LO 3047500985u
72 #define OVFL_MAX_5_HI 42949
73 #define OVFL_MAX_5_MID 2890341191
75 #define OVFL_MAX_1_HI 429496729
80 #if BYTE_ORDER == G_BIG_ENDIAN
90 static const SPLIT64 ten_to_eighteen = { 1000000000000000000ULL };
94 // Structure to access an encoded double floating point
97 #if BYTE_ORDER == G_BIG_ENDIAN
100 unsigned int mantHi:20;
104 unsigned int mantHi:20;
112 #if BYTE_ORDER == G_BIG_ENDIAN
113 #define DEFDS(Lo, Hi, exp, sign) { {sign, exp, Hi, Lo } }
115 #define DEFDS(Lo, Hi, exp, sign) { {Lo, Hi, exp, sign} }
118 const DoubleStructure ds2to64 = DEFDS(0, 0, DBLBIAS + 65, 0);
120 // Single floating point Bias
123 // Structure to access an encoded single floating point
125 #if BYTE_ORDER == G_BIG_ENDIAN
128 unsigned int mant:23;
130 unsigned int mant:23;
140 static const uint32_t power10 [POWER10_MAX+1] = {
141 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
145 static const double double_power10[] = {
146 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
147 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
148 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
149 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
150 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
151 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
152 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
153 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
156 const SPLIT64 sdl_power10[] = { {10000000000ULL}, // 1E10
157 {100000000000ULL}, // 1E11
158 {1000000000000ULL}, // 1E12
159 {10000000000000ULL}, // 1E13
160 {100000000000000ULL} }; // 1E14
162 static const uint64_t long_power10[] = {
179 10000000000000000ULL,
180 100000000000000000ULL,
181 1000000000000000000ULL,
182 10000000000000000000ULL};
185 uint32_t Hi, Mid, Lo;
188 const DECOVFL power_overflow[] = {
189 // This is a table of the largest values that can be in the upper two
190 // ULONGs of a 96-bit number that will not overflow when multiplied
191 // by a given power. For the upper word, this is a table of
192 // 2^32 / 10^n for 1 <= n <= 9. For the lower word, this is the
193 // remaining fraction part * 2^32. 2^32 = 4294967296.
195 { 429496729u, 2576980377u, 2576980377u }, // 10^1 remainder 0.6
196 { 42949672u, 4123168604u, 687194767u }, // 10^2 remainder 0.16
197 { 4294967u, 1271310319u, 2645699854u }, // 10^3 remainder 0.616
198 { 429496u, 3133608139u, 694066715u }, // 10^4 remainder 0.1616
199 { 42949u, 2890341191u, 2216890319u }, // 10^5 remainder 0.51616
200 { 4294u, 4154504685u, 2369172679u }, // 10^6 remainder 0.551616
201 { 429u, 2133437386u, 4102387834u }, // 10^7 remainder 0.9551616
202 { 42u, 4078814305u, 410238783u }, // 10^8 remainder 0.09991616
203 { 4u, 1266874889u, 3047500985u }, // 10^9 remainder 0.709551616
207 #define UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b)))
208 #define Div64by32(num, den) ((uint32_t)((uint64_t)(num) / (uint32_t)(den)))
209 #define Mod64by32(num, den) ((uint32_t)((uint64_t)(num) % (uint32_t)(den)))
214 const int maxIx = (sizeof(double_power10)/sizeof(double_power10[0]));
217 return double_power10[ix];
218 return pow(10.0, ix);
219 } // double fnDblPower10()
222 static inline int64_t
223 DivMod32by32(int32_t num, int32_t den)
227 sdl.u.Lo = num / den;
228 sdl.u.Hi = num % den;
232 static inline int64_t
233 DivMod64by32(int64_t num, int32_t den)
237 sdl.u.Lo = Div64by32(num, den);
238 sdl.u.Hi = Mod64by32(num, den);
243 UInt64x64To128(SPLIT64 op1, SPLIT64 op2, uint64_t *hi)
249 tmp1.int64 = UInt32x32To64(op1.u.Lo, op2.u.Lo); // lo partial prod
250 tmp2.int64 = UInt32x32To64(op1.u.Lo, op2.u.Hi); // mid 1 partial prod
251 tmp1.u.Hi += tmp2.u.Lo;
252 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
254 tmp3.int64 = UInt32x32To64(op1.u.Hi, op2.u.Hi) + (uint64_t)tmp2.u.Hi;
255 tmp2.int64 = UInt32x32To64(op1.u.Hi, op2.u.Lo);
256 tmp1.u.Hi += tmp2.u.Lo;
257 if (tmp1.u.Hi < tmp2.u.Lo) // test for carry
259 tmp3.int64 += (uint64_t)tmp2.u.Hi;
269 * pdlNum - Pointer to 64-bit dividend
270 * ulDen - 32-bit divisor
273 * Do full divide, yielding 64-bit result and 32-bit remainder.
276 * Quotient overwrites dividend.
282 // Was: FullDiv64By32
284 FullDiv64By32 (uint64_t *num, uint32_t den)
292 if (tmp.u.Hi >= den) {
293 // DivMod64by32 returns quotient in Lo, remainder in Hi.
296 res.int64 = DivMod64by32(res.int64, den);
301 tmp.int64 = DivMod64by32(tmp.int64, den);
311 * res_hi - Top uint32_t of quotient
312 * res_mid - Middle uint32_t of quotient
313 * res_lo - Bottom uint32_t of quotient
314 * scale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
317 * Determine the max power of 10, <= 9, that the quotient can be scaled
318 * up by and still fit in 96 bits.
321 * Returns power of 10 to scale by, -1 if overflow error.
323 ***********************************************************************/
326 SearchScale(uint32_t res_hi, uint32_t res_mid, uint32_t res_lo, int scale)
330 // Quick check to stop us from trying to scale any more.
332 if (res_hi > OVFL_MAX_1_HI || scale >= DEC_SCALE_MAX) {
337 if (scale > DEC_SCALE_MAX - 9) {
338 // We can't scale by 10^9 without exceeding the max scale factor.
339 // See if we can scale to the max. If not, we'll fall into
340 // standard search for scale factor.
342 cur_scale = DEC_SCALE_MAX - scale;
343 if (res_hi < power_overflow[cur_scale - 1].Hi)
346 if (res_hi == power_overflow[cur_scale - 1].Hi) {
348 if (res_mid > power_overflow[cur_scale - 1].Mid ||
349 (res_mid == power_overflow[cur_scale - 1].Mid && res_lo > power_overflow[cur_scale - 1].Lo)) {
354 } else if (res_hi < OVFL_MAX_9_HI || (res_hi == OVFL_MAX_9_HI && res_mid < OVFL_MAX_9_MID) || (res_hi == OVFL_MAX_9_HI && res_mid == OVFL_MAX_9_MID && res_lo <= OVFL_MAX_9_LO))
357 // Search for a power to scale by < 9. Do a binary search
358 // on power_overflow[].
361 if (res_hi < OVFL_MAX_5_HI)
363 else if (res_hi > OVFL_MAX_5_HI)
368 // cur_scale is 3 or 7.
370 if (res_hi < power_overflow[cur_scale - 1].Hi)
372 else if (res_hi > power_overflow[cur_scale - 1].Hi)
377 // cur_scale is 2, 4, 6, or 8.
379 // In all cases, we already found we could not use the power one larger.
380 // So if we can use this power, it is the biggest, and we're done. If
381 // we can't use this power, the one below it is correct for all cases
382 // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
384 if (res_hi > power_overflow[cur_scale - 1].Hi)
387 if (res_hi == power_overflow[cur_scale - 1].Hi)
391 // cur_scale = largest power of 10 we can scale by without overflow,
392 // cur_scale < 9. See if this is enough to make scale factor
393 // positive if it isn't already.
395 if (cur_scale + scale < 0)
406 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
407 * ulDen - 32-bit divisor.
410 * Do full divide, yielding 96-bit result and 32-bit remainder.
413 * Quotient overwrites dividend.
421 Div96By32(uint32_t *num, uint32_t den)
439 tmp.int64 = DivMod64by32(tmp.int64, den);
443 tmp.int64 = DivMod64by32(tmp.int64, den);
447 tmp.int64 = DivMod64by32(tmp.int64, den);
456 * pdecRes - Pointer to Decimal result location
457 * operand - Pointer to Decimal operand
460 * Chop the value to integer. Return remainder so Int() function
461 * can round down if non-zero.
469 ***********************************************************************/
472 DecFixInt(MonoDecimal * result, MonoDecimal * operand)
479 if (operand->u.u.scale > 0) {
480 num[0] = operand->v.v.Lo32;
481 num[1] = operand->v.v.Mid32;
482 num[2] = operand->Hi32;
483 scale = operand->u.u.scale;
484 result->u.u.sign = operand->u.u.sign;
488 if (scale > POWER10_MAX)
491 pwr = power10[scale];
493 rem |= Div96By32(num, pwr);
497 result->v.v.Lo32 = num[0];
498 result->v.v.Mid32 = num[1];
499 result->Hi32 = num[2];
500 result->u.u.scale = 0;
505 COPYDEC(*result, *operand);
506 // Odd, the Microsoft code does not set result->reserved to zero on this case
514 * res - Array of uint32_ts with value, least-significant first.
515 * hi_res - Index of last non-zero value in res.
516 * scale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
519 * See if we need to scale the result to fit it in 96 bits.
520 * Perform needed scaling. Adjust scale factor accordingly.
523 * res updated in place, always 3 uint32_ts.
524 * New scale factor returned, -1 if overflow error.
528 ScaleResult(uint32_t *res, int hi_res, int scale)
537 // See if we need to scale the result. The combined scale must
538 // be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
540 // Start by figuring a lower bound on the scaling needed to make
541 // the upper 96 bits zero. hi_res is the index into res[]
542 // of the highest non-zero uint32_t.
544 new_scale = hi_res * 32 - 64 - 1;
550 if (!(tmp & 0xFFFF0000)) {
554 if (!(tmp & 0xFF000000)) {
558 if (!(tmp & 0xF0000000)) {
562 if (!(tmp & 0xC0000000)) {
566 if (!(tmp & 0x80000000)) {
571 // Multiply bit position by log10(2) to figure it's power of 10.
572 // We scale the log by 256. log(2) = .30103, * 256 = 77. Doing this
573 // with a multiply saves a 96-byte lookup table. The power returned
574 // is <= the power of the number, so we must add one power of 10
575 // to make it's integer part zero after dividing by 256.
577 // Note: the result of this multiplication by an approximation of
578 // log10(2) have been exhaustively checked to verify it gives the
579 // correct result. (There were only 95 to check...)
581 new_scale = ((new_scale * 77) >> 8) + 1;
583 // new_scale = min scale factor to make high 96 bits zero, 0 - 29.
584 // This reduces the scale factor of the result. If it exceeds the
585 // current scale of the result, we'll overflow.
587 if (new_scale > scale)
593 // Make sure we scale by enough to bring the current scale factor
596 if (new_scale < scale - DEC_SCALE_MAX)
597 new_scale = scale - DEC_SCALE_MAX;
599 if (new_scale != 0) {
600 // Scale by the power of 10 given by new_scale. Note that this is
601 // NOT guaranteed to bring the number within 96 bits -- it could
602 // be 1 power of 10 short.
606 sdlTmp.u.Hi = 0; // initialize remainder
610 sticky |= sdlTmp.u.Hi; // record remainder as sticky bit
612 if (new_scale > POWER10_MAX)
615 pwr = power10[new_scale];
617 // Compute first quotient.
618 // DivMod64by32 returns quotient in Lo, remainder in Hi.
620 sdlTmp.int64 = DivMod64by32(res[hi_res], pwr);
621 res[hi_res] = sdlTmp.u.Lo;
625 // If first quotient was 0, update hi_res.
627 if (sdlTmp.u.Lo == 0)
630 // Compute subsequent quotients.
633 sdlTmp.u.Lo = res[cur];
634 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, pwr);
635 res[cur] = sdlTmp.u.Lo;
641 new_scale -= POWER10_MAX;
643 continue; // scale some more
645 // If we scaled enough, hi_res would be 2 or less. If not,
646 // divide by 10 more.
651 continue; // scale by 10
654 // Round final result. See if remainder >= 1/2 of divisor.
655 // If remainder == 1/2 divisor, round up if odd or sticky bit set.
657 pwr >>= 1; // power of 10 always even
658 if ( pwr <= sdlTmp.u.Hi && (pwr < sdlTmp.u.Hi ||
659 ((res[0] & 1) | sticky)) ) {
661 while (++res[++cur] == 0);
664 // The rounding caused us to carry beyond 96 bits.
668 sticky = 0; // no sticky bit
669 sdlTmp.u.Hi = 0; // or remainder
672 continue; // scale by 10
676 // We may have scaled it more than we planned. Make sure the scale
677 // factor hasn't gone negative, indicating overflow.
689 // Returns: MONO_DECIMAL_OVERFLOW or MONO_DECIMAL_OK
690 static MonoDecimalStatus
691 mono_decimal_multiply_result(MonoDecimal * left, MonoDecimal * right, MonoDecimal * result)
703 scale = left->u.u.scale + right->u.u.scale;
705 if ((left->Hi32 | left->v.v.Mid32 | right->Hi32 | right->v.v.Mid32) == 0) {
706 // Upper 64 bits are zero.
708 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
709 if (scale > DEC_SCALE_MAX)
711 // Result scale is too big. Divide result by power of 10 to reduce it.
712 // If the amount to divide by is > 19 the result is guaranteed
713 // less than 1/2. [max value in 64 bits = 1.84E19]
715 scale -= DEC_SCALE_MAX;
718 DECIMAL_SETZERO(*result);
719 return MONO_DECIMAL_OK;
722 if (scale > POWER10_MAX) {
723 // Divide by 1E10 first, to get the power down to a 32-bit quantity.
724 // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
725 // then multiply the next divisor by 4 (which will be a max of 4E9).
727 rem_lo = FullDiv64By32(&tmp.int64, ten_to_ten_div_4);
728 pwr = power10[scale - 10] << 2;
730 pwr = power10[scale];
734 // Power to divide by fits in 32 bits.
736 rem_hi = FullDiv64By32(&tmp.int64, pwr);
738 // Round result. See if remainder >= 1/2 of divisor.
739 // Divisor is a power of 10, so it is always even.
742 if (rem_hi >= pwr && (rem_hi > pwr || (rem_lo | (tmp.u.Lo & 1))))
745 scale = DEC_SCALE_MAX;
747 DECIMAL_LO32(*result) = tmp.u.Lo;
748 DECIMAL_MID32(*result) = tmp.u.Hi;
749 DECIMAL_HI32(*result) = 0;
751 // At least one operand has bits set in the upper 64 bits.
753 // Compute and accumulate the 9 partial products into a
754 // 192-bit (24-byte) result.
756 // [l-h][l-m][l-l] left high, middle, low
757 // x [r-h][r-m][r-l] right high, middle, low
758 // ------------------------------
760 // [0-h][0-l] l-l * r-l
761 // [1ah][1al] l-l * r-m
762 // [1bh][1bl] l-m * r-l
763 // [2ah][2al] l-m * r-m
764 // [2bh][2bl] l-l * r-h
765 // [2ch][2cl] l-h * r-l
766 // [3ah][3al] l-m * r-h
767 // [3bh][3bl] l-h * r-m
768 // [4-h][4-l] l-h * r-h
769 // ------------------------------
770 // [p-5][p-4][p-3][p-2][p-1][p-0] prod[] array
772 tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
775 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Mid32) + tmp.u.Hi;
777 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Lo32);
778 tmp.int64 += tmp2.int64; // this could generate carry
780 if (tmp.int64 < tmp2.int64) // detect carry
784 tmp2.u.Lo = tmp.u.Hi;
786 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Mid32) + tmp2.int64;
788 if (left->Hi32 | right->Hi32) {
789 // Highest 32 bits is non-zero. Calculate 5 more partial products.
791 tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->Hi32);
792 tmp.int64 += tmp2.int64; // this could generate carry
793 if (tmp.int64 < tmp2.int64) // detect carry
798 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Lo32);
799 tmp.int64 += tmp2.int64; // this could generate carry
801 if (tmp.int64 < tmp2.int64) // detect carry
803 tmp3.u.Lo = tmp.u.Hi;
805 tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->Hi32);
806 tmp.int64 += tmp3.int64; // this could generate carry
807 if (tmp.int64 < tmp3.int64) // detect carry
812 tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Mid32);
813 tmp.int64 += tmp2.int64; // this could generate carry
815 if (tmp.int64 < tmp2.int64) // detect carry
817 tmp3.u.Lo = tmp.u.Hi;
819 tmp.int64 = UInt32x32To64(left->Hi32, right->Hi32) + tmp3.int64;
831 // Check for leading zero uint32_ts on the product
833 while (prod[hi_prod] == 0) {
839 scale = ScaleResult(prod, hi_prod, scale);
841 return MONO_DECIMAL_OVERFLOW;
843 result->v.v.Lo32 = prod[0];
844 result->v.v.Mid32 = prod[1];
845 result->Hi32 = prod[2];
848 result->u.u.sign = right->u.u.sign ^ left->u.u.sign;
849 result->u.u.scale = (char)scale;
850 return MONO_DECIMAL_OK;
853 // Addition and subtraction
854 static MonoDecimalStatus
855 DecAddSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result, int8_t sign)
865 MonoDecimal *pdecTmp;
867 sign ^= (right->u.u.sign ^ left->u.u.sign) & DECIMAL_NEG;
869 if (right->u.u.scale == left->u.u.scale) {
870 // Scale factors are equal, no alignment necessary.
872 decRes.u.signscale = left->u.signscale;
876 // Signs differ - subtract
878 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right));
879 DECIMAL_HI32(decRes) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
883 if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*left)) {
885 if (decRes.Hi32 >= left->Hi32)
887 } else if (decRes.Hi32 > left->Hi32) {
888 // Got negative result. Flip its sign.
891 DECIMAL_LO64_SET(decRes, -(uint64_t)DECIMAL_LO64_GET(decRes));
892 decRes.Hi32 = ~decRes.Hi32;
893 if (DECIMAL_LO64_GET(decRes) == 0)
895 decRes.u.u.sign ^= DECIMAL_NEG;
899 // Signs are the same - add
901 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right));
902 decRes.Hi32 = left->Hi32 + right->Hi32;
906 if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*left)) {
908 if (decRes.Hi32 <= left->Hi32)
910 } else if (decRes.Hi32 < left->Hi32) {
912 // The addition carried above 96 bits. Divide the result by 10,
913 // dropping the scale factor.
915 if (decRes.u.u.scale == 0)
916 return MONO_DECIMAL_OVERFLOW;
919 tmp.u.Lo = decRes.Hi32;
921 tmp.int64 = DivMod64by32(tmp.int64, 10);
922 decRes.Hi32 = tmp.u.Lo;
924 tmp.u.Lo = decRes.v.v.Mid32;
925 tmp.int64 = DivMod64by32(tmp.int64, 10);
926 decRes.v.v.Mid32 = tmp.u.Lo;
928 tmp.u.Lo = decRes.v.v.Lo32;
929 tmp.int64 = DivMod64by32(tmp.int64, 10);
930 decRes.v.v.Lo32 = tmp.u.Lo;
932 // See if we need to round up.
934 if (tmp.u.Hi >= 5 && (tmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
935 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
936 if (DECIMAL_LO64_GET(decRes) == 0)
943 // Scale factors are not equal. Assume that a larger scale
944 // factor (more decimal places) is likely to mean that number
945 // is smaller. Start by guessing that the right operand has
946 // the larger scale factor. The result will have the larger
949 decRes.u.u.scale = right->u.u.scale; // scale factor of "smaller"
950 decRes.u.u.sign = left->u.u.sign; // but sign of "larger"
951 scale = decRes.u.u.scale - left->u.u.scale;
954 // Guessed scale factor wrong. Swap operands.
957 decRes.u.u.scale = left->u.u.scale;
958 decRes.u.u.sign ^= sign;
964 // *left will need to be multiplied by 10^scale so
965 // it will have the same scale as *right. We could be
966 // extending it to up to 192 bits of precision.
968 if (scale <= POWER10_MAX) {
969 // Scaling won't make it larger than 4 uint32_ts
971 pwr = power10[scale];
972 DECIMAL_LO64_SET(decTmp, UInt32x32To64(left->v.v.Lo32, pwr));
973 tmp.int64 = UInt32x32To64(left->v.v.Mid32, pwr);
974 tmp.int64 += decTmp.v.v.Mid32;
975 decTmp.v.v.Mid32 = tmp.u.Lo;
976 decTmp.Hi32 = tmp.u.Hi;
977 tmp.int64 = UInt32x32To64(left->Hi32, pwr);
978 tmp.int64 += decTmp.Hi32;
980 // Result fits in 96 bits. Use standard aligned add.
982 decTmp.Hi32 = tmp.u.Lo;
986 num[0] = decTmp.v.v.Lo32;
987 num[1] = decTmp.v.v.Mid32;
993 // Have to scale by a bunch. Move the number to a buffer
994 // where it has room to grow as it's scaled.
996 num[0] = left->v.v.Lo32;
997 num[1] = left->v.v.Mid32;
1001 // Scan for zeros in the upper words.
1008 // Left arg is zero, return right.
1010 DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*right));
1011 decRes.Hi32 = right->Hi32;
1012 decRes.u.u.sign ^= sign;
1018 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
1019 // with index of highest non-zero uint32_t.
1021 for (; scale > 0; scale -= POWER10_MAX) {
1022 if (scale > POWER10_MAX)
1025 pwr = power10[scale];
1028 for (cur = 0; cur <= hi_prod; cur++) {
1029 tmp.int64 = UInt32x32To64(num[cur], pwr) + tmp.u.Hi;
1030 num[cur] = tmp.u.Lo;
1034 // We're extending the result by another uint32_t.
1035 num[++hi_prod] = tmp.u.Hi;
1039 // Scaling complete, do the add. Could be subtract if signs differ.
1045 // Signs differ, subtract.
1047 DECIMAL_LO64_SET(decRes, tmp.int64 - DECIMAL_LO64_GET(*right));
1048 decRes.Hi32 = num[2] - right->Hi32;
1052 if (DECIMAL_LO64_GET(decRes) > tmp.int64) {
1054 if (decRes.Hi32 >= num[2])
1057 else if (decRes.Hi32 > num[2]) {
1059 // If num has more than 96 bits of precision, then we need to
1060 // carry the subtraction into the higher bits. If it doesn't,
1061 // then we subtracted in the wrong order and have to flip the
1062 // sign of the result.
1068 while(num[cur++]-- == 0);
1069 if (num[hi_prod] == 0)
1074 // Signs the same, add.
1076 DECIMAL_LO64_SET(decRes, tmp.int64 + DECIMAL_LO64_GET(*right));
1077 decRes.Hi32 = num[2] + right->Hi32;
1081 if (DECIMAL_LO64_GET(decRes) < tmp.int64) {
1083 if (decRes.Hi32 <= num[2])
1086 else if (decRes.Hi32 < num[2]) {
1088 // Had a carry above 96 bits.
1092 if (hi_prod < cur) {
1097 }while (++num[cur++] == 0);
1102 num[0] = decRes.v.v.Lo32;
1103 num[1] = decRes.v.v.Mid32;
1104 num[2] = decRes.Hi32;
1105 decRes.u.u.scale = ScaleResult(num, hi_prod, decRes.u.u.scale);
1106 if (decRes.u.u.scale == (uint8_t) -1)
1107 return MONO_DECIMAL_OVERFLOW;
1109 decRes.v.v.Lo32 = num[0];
1110 decRes.v.v.Mid32 = num[1];
1111 decRes.Hi32 = num[2];
1116 COPYDEC(*result, decRes);
1117 // Odd, the Microsoft code does not set result->reserved to zero on this case
1118 return MONO_DECIMAL_OK;
1122 static MonoDecimalStatus G_GNUC_UNUSED
1123 mono_decimal_add(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1125 return DecAddSub (left, right, result, 0);
1128 // Decimal subtraction
1129 static MonoDecimalStatus G_GNUC_UNUSED
1130 mono_decimal_sub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1132 return DecAddSub (left, right, result, DECIMAL_NEG);
1139 * num - Pointer to 96-bit number as array of uint32_ts, least-sig first
1140 * pwr - Scale factor to multiply by
1143 * Multiply the two numbers. The low 96 bits of the result overwrite
1144 * the input. The last 32 bits of the product are the return value.
1147 * Returns highest 32 bits of product.
1154 IncreaseScale(uint32_t *num, uint32_t pwr)
1158 sdlTmp.int64 = UInt32x32To64(num[0], pwr);
1159 num[0] = sdlTmp.u.Lo;
1160 sdlTmp.int64 = UInt32x32To64(num[1], pwr) + sdlTmp.u.Hi;
1161 num[1] = sdlTmp.u.Lo;
1162 sdlTmp.int64 = UInt32x32To64(num[2], pwr) + sdlTmp.u.Hi;
1163 num[2] = sdlTmp.u.Lo;
1171 * rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
1172 * sdlDen - 64-bit divisor.
1175 * Do partial divide, yielding 32-bit result and 64-bit remainder.
1176 * Divisor must be larger than upper 64 bits of dividend.
1179 * Remainder overwrites lower 64-bits of dividend.
1187 Div96By64(uint32_t *num, SPLIT64 den)
1193 sdlNum.u.Lo = num[0];
1195 if (num[2] >= den.u.Hi) {
1196 // Divide would overflow. Assume a quotient of 2^32, and set
1197 // up remainder accordingly. Then jump to loop which reduces
1200 sdlNum.u.Hi = num[1] - den.u.Lo;
1205 // Hardware divide won't overflow
1207 if (num[2] == 0 && num[1] < den.u.Hi)
1208 // Result is zero. Entire dividend is remainder.
1212 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1216 quo.int64 = DivMod64by32(quo.int64, den.u.Hi);
1217 sdlNum.u.Hi = quo.u.Hi; // remainder
1219 // Compute full remainder, rem = dividend - (quo * divisor).
1221 prod.int64 = UInt32x32To64(quo.u.Lo, den.u.Lo); // quo * lo divisor
1222 sdlNum.int64 -= prod.int64;
1224 if (sdlNum.int64 > ~prod.int64) {
1226 // Remainder went negative. Add divisor back in until it's positive,
1227 // a max of 2 times.
1231 sdlNum.int64 += den.int64;
1232 }while (sdlNum.int64 >= den.int64);
1235 num[0] = sdlNum.u.Lo;
1236 num[1] = sdlNum.u.Hi;
1244 * rgulNum - Pointer to 128-bit dividend as array of uint32_ts, least-sig first
1245 * den - Pointer to 96-bit divisor.
1248 * Do partial divide, yielding 32-bit result and 96-bit remainder.
1249 * Top divisor uint32_t must be larger than top dividend uint32_t. This is
1250 * assured in the initial call because the divisor is normalized
1251 * and the dividend can't be. In subsequent calls, the remainder
1252 * is multiplied by 10^9 (max), so it can be no more than 1/4 of
1253 * the divisor which is effectively multiplied by 2^32 (4 * 10^9).
1256 * Remainder overwrites lower 96-bits of dividend.
1262 ***********************************************************************/
1265 Div128By96(uint32_t *num, uint32_t *den)
1272 sdlNum.u.Lo = num[0];
1273 sdlNum.u.Hi = num[1];
1275 if (num[3] == 0 && num[2] < den[2]){
1276 // Result is zero. Entire dividend is remainder.
1281 // DivMod64by32 returns quotient in Lo, remainder in Hi.
1283 sdlQuo.u.Lo = num[2];
1284 sdlQuo.u.Hi = num[3];
1285 sdlQuo.int64 = DivMod64by32(sdlQuo.int64, den[2]);
1287 // Compute full remainder, rem = dividend - (quo * divisor).
1289 sdlProd1.int64 = UInt32x32To64(sdlQuo.u.Lo, den[0]); // quo * lo divisor
1290 sdlProd2.int64 = UInt32x32To64(sdlQuo.u.Lo, den[1]); // quo * mid divisor
1291 sdlProd2.int64 += sdlProd1.u.Hi;
1292 sdlProd1.u.Hi = sdlProd2.u.Lo;
1294 sdlNum.int64 -= sdlProd1.int64;
1295 num[2] = sdlQuo.u.Hi - sdlProd2.u.Hi; // sdlQuo.Hi is remainder
1297 // Propagate carries
1299 if (sdlNum.int64 > ~sdlProd1.int64) {
1301 if (num[2] >= ~sdlProd2.u.Hi)
1303 } else if (num[2] > ~sdlProd2.u.Hi) {
1305 // Remainder went negative. Add divisor back in until it's positive,
1306 // a max of 2 times.
1308 sdlProd1.u.Lo = den[0];
1309 sdlProd1.u.Hi = den[1];
1313 sdlNum.int64 += sdlProd1.int64;
1316 if (sdlNum.int64 < sdlProd1.int64) {
1317 // Detected carry. Check for carry out of top
1318 // before adding it in.
1320 if (num[2]++ < den[2])
1323 if (num[2] < den[2])
1324 break; // detected carry
1328 num[0] = sdlNum.u.Lo;
1329 num[1] = sdlNum.u.Hi;
1333 // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer
1334 // Returns FALSE if there is an overflow
1336 Add32To96(uint32_t *num, uint32_t value)
1339 if (num[0] < value) {
1340 if (++num[1] == 0) {
1341 if (++num[2] == 0) {
1350 OverflowUnscale (uint32_t *quo, gboolean remainder)
1354 // We have overflown, so load the high bit with a one.
1356 sdlTmp.u.Lo = quo[2];
1357 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1358 quo[2] = sdlTmp.u.Lo;
1359 sdlTmp.u.Lo = quo[1];
1360 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1361 quo[1] = sdlTmp.u.Lo;
1362 sdlTmp.u.Lo = quo[0];
1363 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
1364 quo[0] = sdlTmp.u.Lo;
1365 // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up
1366 if ((sdlTmp.u.Hi > 5) || ((sdlTmp.u.Hi == 5) && ( remainder || (quo[0] & 1)))) {
1371 // mono_decimal_divide - Decimal divide
1372 static MonoDecimalStatus G_GNUC_UNUSED
1373 mono_decimal_divide_result(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
1376 uint32_t quoSave[3];
1378 uint32_t divisor[3];
1387 scale = left->u.u.scale - right->u.u.scale;
1388 divisor[0] = right->v.v.Lo32;
1389 divisor[1] = right->v.v.Mid32;
1390 divisor[2] = right->Hi32;
1392 if (divisor[1] == 0 && divisor[2] == 0) {
1393 // Divisor is only 32 bits. Easy divide.
1395 if (divisor[0] == 0)
1396 return MONO_DECIMAL_DIVBYZERO;
1398 quo[0] = left->v.v.Lo32;
1399 quo[1] = left->v.v.Mid32;
1400 quo[2] = left->Hi32;
1401 rem[0] = Div96By32(quo, divisor[0]);
1406 cur_scale = min(9, -scale);
1412 // We have computed a quotient based on the natural scale
1413 // ( <dividend scale> - <divisor scale> ). We have a non-zero
1414 // remainder, so now we should increase the scale if possible to
1415 // include more quotient bits.
1417 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
1418 // computing more quotient bits as long as the remainder stays
1419 // non-zero. If scaling by that much would cause overflow, we'll
1420 // drop out of the loop and scale by as much as we can.
1422 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
1423 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
1424 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
1425 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
1426 // is the largest value in quo[1] (when quo[2] == 4) that is
1427 // assured not to overflow.
1429 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1430 if (cur_scale == 0) {
1431 // No more scaling to be done, but remainder is non-zero.
1435 if (utmp < rem[0] || (utmp >= divisor[0] &&
1436 (utmp > divisor[0] || (quo[0] & 1)))) {
1445 if (cur_scale == -1)
1446 return MONO_DECIMAL_OVERFLOW;
1449 pwr = power10[cur_scale];
1452 if (IncreaseScale(quo, pwr) != 0)
1453 return MONO_DECIMAL_OVERFLOW;
1455 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
1456 rem[0] = sdlTmp.u.Hi;
1458 quo[0] += sdlTmp.u.Lo;
1459 if (quo[0] < sdlTmp.u.Lo) {
1466 // Divisor has bits set in the upper 64 bits.
1468 // Divisor must be fully normalized (shifted so bit 31 of the most
1469 // significant uint32_t is 1). Locate the MSB so we know how much to
1470 // normalize by. The dividend will be shifted by the same amount so
1471 // the quotient is not changed.
1473 if (divisor[2] == 0)
1479 if (!(utmp & 0xFFFF0000)) {
1483 if (!(utmp & 0xFF000000)) {
1487 if (!(utmp & 0xF0000000)) {
1491 if (!(utmp & 0xC0000000)) {
1495 if (!(utmp & 0x80000000)) {
1500 // Shift both dividend and divisor left by cur_scale.
1502 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
1503 rem[0] = sdlTmp.u.Lo;
1504 rem[1] = sdlTmp.u.Hi;
1505 sdlTmp.u.Lo = left->v.v.Mid32;
1506 sdlTmp.u.Hi = left->Hi32;
1507 sdlTmp.int64 <<= cur_scale;
1508 rem[2] = sdlTmp.u.Hi;
1509 rem[3] = (left->Hi32 >> (31 - cur_scale)) >> 1;
1511 sdlDivisor.u.Lo = divisor[0];
1512 sdlDivisor.u.Hi = divisor[1];
1513 sdlDivisor.int64 <<= cur_scale;
1515 if (divisor[2] == 0) {
1516 // Have a 64-bit divisor in sdlDivisor. The remainder
1517 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
1519 sdlTmp.u.Lo = rem[2];
1520 sdlTmp.u.Hi = rem[3];
1523 quo[1] = Div96By64(&rem[1], sdlDivisor);
1524 quo[0] = Div96By64(rem, sdlDivisor);
1527 if ((rem[0] | rem[1]) == 0) {
1529 cur_scale = min(9, -scale);
1535 // Remainder is non-zero. Scale up quotient and remainder by
1536 // powers of 10 so we can compute more significant bits.
1538 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1539 if (cur_scale == 0) {
1540 // No more scaling to be done, but remainder is non-zero.
1543 sdlTmp.u.Lo = rem[0];
1544 sdlTmp.u.Hi = rem[1];
1545 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
1546 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
1551 if (cur_scale == -1)
1552 return MONO_DECIMAL_OVERFLOW;
1555 pwr = power10[cur_scale];
1558 if (IncreaseScale(quo, pwr) != 0)
1559 return MONO_DECIMAL_OVERFLOW;
1561 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
1562 IncreaseScale(rem, pwr);
1563 utmp = Div96By64(rem, sdlDivisor);
1572 // Have a 96-bit divisor in divisor[].
1574 // Start by finishing the shift left by cur_scale.
1576 sdlTmp.u.Lo = divisor[1];
1577 sdlTmp.u.Hi = divisor[2];
1578 sdlTmp.int64 <<= cur_scale;
1579 divisor[0] = sdlDivisor.u.Lo;
1580 divisor[1] = sdlDivisor.u.Hi;
1581 divisor[2] = sdlTmp.u.Hi;
1583 // The remainder (currently 96 bits spread over 4 uint32_ts)
1584 // will be < divisor.
1588 quo[0] = Div128By96(rem, divisor);
1591 if ((rem[0] | rem[1] | rem[2]) == 0) {
1593 cur_scale = min(9, -scale);
1599 // Remainder is non-zero. Scale up quotient and remainder by
1600 // powers of 10 so we can compute more significant bits.
1602 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
1603 if (cur_scale == 0) {
1604 // No more scaling to be done, but remainder is non-zero.
1607 if (rem[2] >= 0x80000000)
1610 utmp = rem[0] > 0x80000000;
1611 utmp1 = rem[1] > 0x80000000;
1613 rem[1] = (rem[1] << 1) + utmp;
1614 rem[2] = (rem[2] << 1) + utmp1;
1616 if ((rem[2] > divisor[2] || rem[2] == divisor[2]) &&
1617 ((rem[1] > divisor[1] || rem[1] == divisor[1]) &&
1618 ((rem[0] > divisor[0] || rem[0] == divisor[0]) &&
1624 if (cur_scale == -1)
1625 return MONO_DECIMAL_OVERFLOW;
1628 pwr = power10[cur_scale];
1631 if (IncreaseScale(quo, pwr) != 0)
1632 return MONO_DECIMAL_OVERFLOW;
1634 rem[3] = IncreaseScale(rem, pwr);
1635 utmp = Div128By96(rem, divisor);
1645 // No more remainder. Try extracting any extra powers of 10 we may have
1646 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
1647 // If a division by one of these powers returns a zero remainder, then
1648 // we keep the quotient. If the remainder is not zero, then we restore
1649 // the previous value.
1651 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
1652 // we can extract. We use this as a quick test on whether to try a
1655 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
1656 quoSave[0] = quo[0];
1657 quoSave[1] = quo[1];
1658 quoSave[2] = quo[2];
1660 if (Div96By32(quoSave, 100000000) == 0) {
1661 quo[0] = quoSave[0];
1662 quo[1] = quoSave[1];
1663 quo[2] = quoSave[2];
1670 if ((quo[0] & 0xF) == 0 && scale >= 4) {
1671 quoSave[0] = quo[0];
1672 quoSave[1] = quo[1];
1673 quoSave[2] = quo[2];
1675 if (Div96By32(quoSave, 10000) == 0) {
1676 quo[0] = quoSave[0];
1677 quo[1] = quoSave[1];
1678 quo[2] = quoSave[2];
1683 if ((quo[0] & 3) == 0 && scale >= 2) {
1684 quoSave[0] = quo[0];
1685 quoSave[1] = quo[1];
1686 quoSave[2] = quo[2];
1688 if (Div96By32(quoSave, 100) == 0) {
1689 quo[0] = quoSave[0];
1690 quo[1] = quoSave[1];
1691 quo[2] = quoSave[2];
1696 if ((quo[0] & 1) == 0 && scale >= 1) {
1697 quoSave[0] = quo[0];
1698 quoSave[1] = quo[1];
1699 quoSave[2] = quo[2];
1701 if (Div96By32(quoSave, 10) == 0) {
1702 quo[0] = quoSave[0];
1703 quo[1] = quoSave[1];
1704 quo[2] = quoSave[2];
1709 result->Hi32 = quo[2];
1710 result->v.v.Mid32 = quo[1];
1711 result->v.v.Lo32 = quo[0];
1712 result->u.u.scale = scale;
1713 result->u.u.sign = left->u.u.sign ^ right->u.u.sign;
1714 return MONO_DECIMAL_OK;
1717 // mono_decimal_absolute - Decimal Absolute Value
1718 static void G_GNUC_UNUSED
1719 mono_decimal_absolute (MonoDecimal *pdecOprd, MonoDecimal *result)
1721 COPYDEC(*result, *pdecOprd);
1722 result->u.u.sign &= ~DECIMAL_NEG;
1723 // Microsoft does not set reserved here
1726 // mono_decimal_fix - Decimal Fix (chop to integer)
1728 mono_decimal_fix (MonoDecimal *pdecOprd, MonoDecimal *result)
1730 DecFixInt(result, pdecOprd);
1733 // mono_decimal_round_to_int - Decimal Int (round down to integer)
1735 mono_decimal_round_to_int (MonoDecimal *pdecOprd, MonoDecimal *result)
1737 if (DecFixInt(result, pdecOprd) != 0 && (result->u.u.sign & DECIMAL_NEG)) {
1738 // We have chopped off a non-zero amount from a negative value. Since
1739 // we round toward -infinity, we must increase the integer result by
1740 // 1 to make it more negative. This will never overflow because
1741 // in order to have a remainder, we must have had a non-zero scale factor.
1742 // Our scale factor is back to zero now.
1744 DECIMAL_LO64_SET(*result, DECIMAL_LO64_GET(*result) + 1);
1745 if (DECIMAL_LO64_GET(*result) == 0)
1750 // mono_decimal_negate - Decimal Negate
1751 static void G_GNUC_UNUSED
1752 mono_decimal_negate (MonoDecimal *pdecOprd, MonoDecimal *result)
1754 COPYDEC(*result, *pdecOprd);
1755 // Microsoft does not set result->reserved to zero on this case.
1756 result->u.u.sign ^= DECIMAL_NEG;
1760 // Returns: MONO_DECIMAL_INVALID_ARGUMENT, MONO_DECIMAL_OK
1762 static MonoDecimalStatus
1763 mono_decimal_round_result(MonoDecimal *input, int cDecimals, MonoDecimal *result)
1772 return MONO_DECIMAL_INVALID_ARGUMENT;
1774 scale = input->u.u.scale - cDecimals;
1776 num[0] = input->v.v.Lo32;
1777 num[1] = input->v.v.Mid32;
1778 num[2] = input->Hi32;
1779 result->u.u.sign = input->u.u.sign;
1784 if (scale > POWER10_MAX)
1787 pwr = power10[scale];
1789 rem = Div96By32(num, pwr);
1793 // Now round. rem has last remainder, sticky has sticky bits.
1794 // To do IEEE rounding, we add LSB of result to sticky bits so
1795 // either causes round up if remainder * 2 == last divisor.
1797 sticky |= num[0] & 1;
1798 rem = (rem << 1) + (sticky != 0);
1805 result->v.v.Lo32 = num[0];
1806 result->v.v.Mid32 = num[1];
1807 result->Hi32 = num[2];
1808 result->u.u.scale = cDecimals;
1809 return MONO_DECIMAL_OK;
1812 COPYDEC(*result, *input);
1813 // Odd, the Microsoft source does not set the result->reserved to zero here.
1814 return MONO_DECIMAL_OK;
1818 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1819 static MonoDecimalStatus
1820 mono_decimal_from_float (float input, MonoDecimal* result)
1822 int exp; // number of bits to left of binary point
1828 int lmax, cur; // temps used during scale reduction
1830 // The most we can scale by is 10^28, which is just slightly more
1831 // than 2^93. So a float with an exponent of -94 could just
1832 // barely reach 0.5, but smaller exponents will always round to zero.
1834 if ((exp = ((SingleStructure *)&input)->exp - SNGBIAS) < -94 ) {
1835 DECIMAL_SETZERO(*result);
1836 return MONO_DECIMAL_OK;
1840 return MONO_DECIMAL_OVERFLOW;
1842 // Round the input to a 7-digit integer. The R4 format has
1843 // only 7 digits of precision, and we want to keep garbage digits
1844 // out of the Decimal were making.
1846 // Calculate max power of 10 input value could have by multiplying
1847 // the exponent by log10(2). Using scaled integer multiplcation,
1848 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1851 power = 6 - ((exp * 19728) >> 16);
1854 // We have less than 7 digits, scale input up.
1859 dbl = dbl * double_power10[power];
1861 if (power != -1 || dbl >= 1E7)
1862 dbl = dbl / fnDblPower10(-power);
1864 power = 0; // didn't scale it
1867 g_assert (dbl < 1E7);
1868 if (dbl < 1E6 && power < DECMAX) {
1871 g_assert(dbl >= 1E6);
1876 mant = (int32_t)dbl;
1877 dbl -= (double)mant; // difference between input & integer
1878 if ( dbl > 0.5 || (dbl == 0.5 && (mant & 1)))
1882 DECIMAL_SETZERO(*result);
1883 return MONO_DECIMAL_OK;
1887 // Add -power factors of 10, -power <= (29 - 7) = 22.
1891 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power]);
1893 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1894 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1895 DECIMAL_HI32(*result) = 0;
1897 // Have a big power of 10.
1900 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 18]);
1901 sdlLo.int64 = UInt64x64To128(sdlLo, ten_to_eighteen, &sdlHi.int64);
1903 if (sdlHi.u.Hi != 0)
1904 return MONO_DECIMAL_OVERFLOW;
1907 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 9]);
1908 sdlHi.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Hi);
1909 sdlLo.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Lo);
1910 sdlHi.int64 += sdlLo.u.Hi;
1911 sdlLo.u.Hi = sdlHi.u.Lo;
1912 sdlHi.u.Lo = sdlHi.u.Hi;
1914 DECIMAL_LO32(*result) = sdlLo.u.Lo;
1915 DECIMAL_MID32(*result) = sdlLo.u.Hi;
1916 DECIMAL_HI32(*result) = sdlHi.u.Lo;
1918 DECIMAL_SCALE(*result) = 0;
1920 // Factor out powers of 10 to reduce the scale, if possible.
1921 // The maximum number we could factor out would be 6. This
1922 // comes from the fact we have a 7-digit number, and the
1923 // MSD must be non-zero -- but the lower 6 digits could be
1924 // zero. Note also the scale factor is never negative, so
1925 // we can't scale by any more than the power we used to
1928 // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
1930 lmax = min(power, 6);
1932 // lmax is the largest power of 10 to try, lmax <= 6.
1933 // We'll try powers 4, 2, and 1 unless they're too big.
1935 for (cur = 4; cur > 0; cur >>= 1)
1940 sdlLo.int64 = DivMod32by32(mant, (uint32_t)long_power10[cur]);
1942 if (sdlLo.u.Hi == 0) {
1948 DECIMAL_LO32(*result) = mant;
1949 DECIMAL_MID32(*result) = 0;
1950 DECIMAL_HI32(*result) = 0;
1951 DECIMAL_SCALE(*result) = power;
1954 DECIMAL_SIGN(*result) = (char)((SingleStructure *)&input)->sign << 7;
1955 return MONO_DECIMAL_OK;
1958 // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
1959 static MonoDecimalStatus
1960 mono_decimal_from_double (double input, MonoDecimal *result)
1962 int exp; // number of bits to left of binary point
1963 int power; // power-of-10 scale factor
1967 int lmax, cur; // temps used during scale reduction
1972 // The most we can scale by is 10^28, which is just slightly more
1973 // than 2^93. So a float with an exponent of -94 could just
1974 // barely reach 0.5, but smaller exponents will always round to zero.
1976 if ((exp = ((DoubleStructure *)&input)->u.exp - DBLBIAS) < -94) {
1977 DECIMAL_SETZERO(*result);
1978 return MONO_DECIMAL_OK;
1982 return MONO_DECIMAL_OVERFLOW;
1984 // Round the input to a 15-digit integer. The R8 format has
1985 // only 15 digits of precision, and we want to keep garbage digits
1986 // out of the Decimal were making.
1988 // Calculate max power of 10 input value could have by multiplying
1989 // the exponent by log10(2). Using scaled integer multiplcation,
1990 // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
1993 power = 14 - ((exp * 19728) >> 16);
1996 // We have less than 15 digits, scale input up.
2001 dbl = dbl * double_power10[power];
2003 if (power != -1 || dbl >= 1E15)
2004 dbl = dbl / fnDblPower10(-power);
2006 power = 0; // didn't scale it
2009 g_assert (dbl < 1E15);
2010 if (dbl < 1E14 && power < DECMAX) {
2013 g_assert(dbl >= 1E14);
2018 sdlMant.int64 = (int64_t)dbl;
2019 dbl -= (double)(int64_t)sdlMant.int64; // dif between input & integer
2020 if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)))
2023 if (sdlMant.int64 == 0) {
2024 DECIMAL_SETZERO(*result);
2025 return MONO_DECIMAL_OK;
2029 // Add -power factors of 10, -power <= (29 - 15) = 14.
2033 sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (uint32_t)long_power10[power]);
2034 sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (uint32_t)long_power10[power]);
2035 sdlMant.int64 += sdlLo.u.Hi;
2036 sdlLo.u.Hi = sdlMant.u.Lo;
2037 sdlMant.u.Lo = sdlMant.u.Hi;
2040 // Have a big power of 10.
2042 g_assert(power <= 14);
2043 sdlLo.int64 = UInt64x64To128(sdlMant, sdl_power10[power-10], &sdlMant.int64);
2045 if (sdlMant.u.Hi != 0)
2046 return MONO_DECIMAL_OVERFLOW;
2048 DECIMAL_LO32(*result) = sdlLo.u.Lo;
2049 DECIMAL_MID32(*result) = sdlLo.u.Hi;
2050 DECIMAL_HI32(*result) = sdlMant.u.Lo;
2051 DECIMAL_SCALE(*result) = 0;
2054 // Factor out powers of 10 to reduce the scale, if possible.
2055 // The maximum number we could factor out would be 14. This
2056 // comes from the fact we have a 15-digit number, and the
2057 // MSD must be non-zero -- but the lower 14 digits could be
2058 // zero. Note also the scale factor is never negative, so
2059 // we can't scale by any more than the power we used to
2062 // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
2064 lmax = min(power, 14);
2066 // lmax is the largest power of 10 to try, lmax <= 14.
2067 // We'll try powers 8, 4, 2, and 1 unless they're too big.
2069 for (cur = 8; cur > 0; cur >>= 1)
2074 pwr_cur = (uint32_t)long_power10[cur];
2076 if (sdlMant.u.Hi >= pwr_cur) {
2077 // Overflow if we try to divide in one step.
2079 sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, pwr_cur);
2081 sdlLo.u.Lo = sdlMant.u.Lo;
2082 sdlLo.int64 = DivMod64by32(sdlLo.int64, pwr_cur);
2086 sdlLo.int64 = DivMod64by32(sdlMant.int64, pwr_cur);
2089 if (sdlLo.u.Hi == 0) {
2091 sdlMant.u.Lo = sdlLo.u.Lo;
2097 DECIMAL_HI32(*result) = 0;
2098 DECIMAL_SCALE(*result) = power;
2099 DECIMAL_LO32(*result) = sdlMant.u.Lo;
2100 DECIMAL_MID32(*result) = sdlMant.u.Hi;
2103 DECIMAL_SIGN(*result) = (char)((DoubleStructure *)&input)->u.sign << 7;
2104 return MONO_DECIMAL_OK;
2107 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2108 static MonoDecimalStatus
2109 mono_decimal_to_double_result(MonoDecimal *input, double *result)
2114 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2115 return MONO_DECIMAL_INVALID_ARGUMENT;
2117 tmp.u.Lo = DECIMAL_LO32(*input);
2118 tmp.u.Hi = DECIMAL_MID32(*input);
2120 if ((int32_t)DECIMAL_MID32(*input) < 0)
2121 dbl = (ds2to64.dbl + (double)(int64_t)tmp.int64 +
2122 (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input)) ;
2124 dbl = ((double)(int64_t)tmp.int64 +
2125 (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input));
2127 if (DECIMAL_SIGN(*input))
2131 return MONO_DECIMAL_OK;
2134 // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
2135 static MonoDecimalStatus
2136 mono_decimal_to_float_result(MonoDecimal *input, float *result)
2140 if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
2141 return MONO_DECIMAL_INVALID_ARGUMENT;
2143 // Can't overflow; no errors possible.
2145 mono_decimal_to_double_result(input, &dbl);
2146 *result = (float)dbl;
2147 return MONO_DECIMAL_OK;
2151 DecShiftLeft(MonoDecimal* value)
2153 unsigned int c0 = DECIMAL_LO32(*value) & 0x80000000? 1: 0;
2154 unsigned int c1 = DECIMAL_MID32(*value) & 0x80000000? 1: 0;
2155 g_assert(value != NULL);
2157 DECIMAL_LO32(*value) <<= 1;
2158 DECIMAL_MID32(*value) = DECIMAL_MID32(*value) << 1 | c0;
2159 DECIMAL_HI32(*value) = DECIMAL_HI32(*value) << 1 | c1;
2163 D32AddCarry(uint32_t* value, uint32_t i)
2165 uint32_t v = *value;
2166 uint32_t sum = v + i;
2168 return sum < v || sum < i? 1: 0;
2172 DecAdd(MonoDecimal *value, MonoDecimal* d)
2174 g_assert(value != NULL && d != NULL);
2176 if (D32AddCarry(&DECIMAL_LO32(*value), DECIMAL_LO32(*d))) {
2177 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2178 D32AddCarry(&DECIMAL_HI32(*value), 1);
2181 if (D32AddCarry(&DECIMAL_MID32(*value), DECIMAL_MID32(*d))) {
2182 D32AddCarry(&DECIMAL_HI32(*value), 1);
2184 D32AddCarry(&DECIMAL_HI32(*value), DECIMAL_HI32(*d));
2188 DecMul10(MonoDecimal* value)
2190 MonoDecimal d = *value;
2191 g_assert (value != NULL);
2193 DecShiftLeft(value);
2194 DecShiftLeft(value);
2196 DecShiftLeft(value);
2200 DecAddInt32(MonoDecimal* value, unsigned int i)
2202 g_assert(value != NULL);
2204 if (D32AddCarry(&DECIMAL_LO32(*value), i)) {
2205 if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
2206 D32AddCarry(&DECIMAL_HI32(*value), 1);
2211 MonoDecimalCompareResult
2212 mono_decimal_compare (MonoDecimal *left, MonoDecimal *right)
2215 uint32_t right_sign;
2218 // First check signs and whether either are zero. If both are
2219 // non-zero and of the same sign, just use subtraction to compare.
2221 left_sign = left->v.v.Lo32 | left->v.v.Mid32 | left->Hi32;
2222 right_sign = right->v.v.Lo32 | right->v.v.Mid32 | right->Hi32;
2224 left_sign = (left->u.u.sign & DECIMAL_NEG) | 1;
2226 if (right_sign != 0)
2227 right_sign = (right->u.u.sign & DECIMAL_NEG) | 1;
2229 // left_sign & right_sign have values 1, 0, or 0x81 depending on if the left/right
2230 // operand is +, 0, or -.
2232 if (left_sign == right_sign) {
2233 if (left_sign == 0) // both are zero
2234 return MONO_DECIMAL_CMP_EQ; // return equal
2236 DecAddSub(left, right, &result, DECIMAL_NEG);
2237 if (DECIMAL_LO64_GET(result) == 0 && result.Hi32 == 0)
2238 return MONO_DECIMAL_CMP_EQ;
2239 if (result.u.u.sign & DECIMAL_NEG)
2240 return MONO_DECIMAL_CMP_LT;
2241 return MONO_DECIMAL_CMP_GT;
2245 // Signs are different. Use signed byte comparison
2247 if ((signed char)left_sign > (signed char)right_sign)
2248 return MONO_DECIMAL_CMP_GT;
2249 return MONO_DECIMAL_CMP_LT;
2253 mono_decimal_init_single (MonoDecimal *_this, float value)
2255 if (mono_decimal_from_float (value, _this) == MONO_DECIMAL_OVERFLOW) {
2256 mono_set_pending_exception (mono_get_exception_overflow ());
2259 _this->reserved = 0;
2263 mono_decimal_init_double (MonoDecimal *_this, double value)
2265 if (mono_decimal_from_double (value, _this) == MONO_DECIMAL_OVERFLOW) {
2266 mono_set_pending_exception (mono_get_exception_overflow ());
2269 _this->reserved = 0;
2273 mono_decimal_floor (MonoDecimal *d)
2277 mono_decimal_round_to_int(d, &decRes);
2279 // copy decRes into d
2280 COPYDEC(*d, decRes);
2286 mono_decimal_get_hash_code (MonoDecimal *d)
2290 if (mono_decimal_to_double_result(d, &dbl) != MONO_DECIMAL_OK)
2294 // Ensure 0 and -0 have the same hash code
2297 // conversion to double is lossy and produces rounding errors so we mask off the lowest 4 bits
2299 // For example these two numerically equal decimals with different internal representations produce
2300 // slightly different results when converted to double:
2302 // decimal a = new decimal(new int[] { 0x76969696, 0x2fdd49fa, 0x409783ff, 0x00160000 });
2303 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.176470588
2304 // decimal b = new decimal(new int[] { 0x3f0f0f0f, 0x1e62edcc, 0x06758d33, 0x00150000 });
2305 // => (decimal)1999021.176470588235294117647000000000 => (double)1999021.1764705882
2307 return ((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
2312 mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2)
2316 MonoDecimalStatus status = mono_decimal_multiply_result(d1, d2, &decRes);
2317 if (status != MONO_DECIMAL_OK) {
2318 mono_set_pending_exception (mono_get_exception_overflow ());
2322 COPYDEC(*d1, decRes);
2329 mono_decimal_round (MonoDecimal *d, int32_t decimals)
2333 // GC is only triggered for throwing, no need to protect result
2334 if (decimals < 0 || decimals > 28) {
2335 mono_set_pending_exception (mono_get_exception_argument_out_of_range ("d"));
2339 mono_decimal_round_result(d, decimals, &decRes);
2341 // copy decRes into d
2342 COPYDEC(*d, decRes);
2349 mono_decimal_tocurrency (MonoDecimal *decimal)
2355 mono_decimal_to_double (MonoDecimal d)
2357 double result = 0.0;
2358 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2359 mono_decimal_to_double_result(&d, &result);
2364 mono_decimal_to_int32 (MonoDecimal d)
2368 // The following can not return an error, it only returns INVALID_ARG if the decimals is < 0
2369 mono_decimal_round_result(&d, 0, &result);
2371 if (DECIMAL_SCALE(result) != 0) {
2373 mono_decimal_fix (&d, &result);
2376 if (DECIMAL_HI32(result) == 0 && DECIMAL_MID32(result) == 0) {
2377 int32_t i = DECIMAL_LO32(result);
2378 if ((int16_t)DECIMAL_SIGNSCALE(result) >= 0) {
2388 mono_set_pending_exception (mono_get_exception_overflow ());
2393 mono_decimal_to_float (MonoDecimal d)
2395 float result = 0.0f;
2396 // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
2397 mono_decimal_to_float_result(&d, &result);
2402 mono_decimal_truncate (MonoDecimal *d)
2406 mono_decimal_fix(d, &decRes);
2408 // copy decRes into d
2409 COPYDEC(*d, decRes);
2415 mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign)
2417 MonoDecimal result, decTmp;
2418 MonoDecimal *pdecTmp, *leftOriginal;
2419 uint32_t num[6], pwr;
2420 int scale, hi_prod, cur;
2423 g_assert(sign == 0 || sign == DECIMAL_NEG);
2425 leftOriginal = left;
2427 sign ^= (DECIMAL_SIGN(*right) ^ DECIMAL_SIGN(*left)) & DECIMAL_NEG;
2429 if (DECIMAL_SCALE(*right) == DECIMAL_SCALE(*left)) {
2430 // Scale factors are equal, no alignment necessary.
2432 DECIMAL_SIGNSCALE(result) = DECIMAL_SIGNSCALE(*left);
2436 // Signs differ - subtract
2438 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right)));
2439 DECIMAL_HI32(result) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
2443 if (DECIMAL_LO64_GET(result) > DECIMAL_LO64_GET(*left)) {
2444 DECIMAL_HI32(result)--;
2445 if (DECIMAL_HI32(result) >= DECIMAL_HI32(*left))
2447 } else if (DECIMAL_HI32(result) > DECIMAL_HI32(*left)) {
2448 // Got negative result. Flip its sign.
2451 DECIMAL_LO64_SET(result, -(int64_t)DECIMAL_LO64_GET(result));
2452 DECIMAL_HI32(result) = ~DECIMAL_HI32(result);
2453 if (DECIMAL_LO64_GET(result) == 0)
2454 DECIMAL_HI32(result)++;
2455 DECIMAL_SIGN(result) ^= DECIMAL_NEG;
2459 // Signs are the same - add
2461 DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right)));
2462 DECIMAL_HI32(result) = DECIMAL_HI32(*left) + DECIMAL_HI32(*right);
2466 if (DECIMAL_LO64_GET(result) < DECIMAL_LO64_GET(*left)) {
2467 DECIMAL_HI32(result)++;
2468 if (DECIMAL_HI32(result) <= DECIMAL_HI32(*left))
2470 } else if (DECIMAL_HI32(result) < DECIMAL_HI32(*left)) {
2472 // The addition carried above 96 bits. Divide the result by 10,
2473 // dropping the scale factor.
2475 if (DECIMAL_SCALE(result) == 0) {
2476 mono_set_pending_exception (mono_get_exception_overflow ());
2479 DECIMAL_SCALE(result)--;
2481 sdlTmp.u.Lo = DECIMAL_HI32(result);
2483 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2484 DECIMAL_HI32(result) = sdlTmp.u.Lo;
2486 sdlTmp.u.Lo = DECIMAL_MID32(result);
2487 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2488 DECIMAL_MID32(result) = sdlTmp.u.Lo;
2490 sdlTmp.u.Lo = DECIMAL_LO32(result);
2491 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
2492 DECIMAL_LO32(result) = sdlTmp.u.Lo;
2494 // See if we need to round up.
2496 if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (DECIMAL_LO32(result) & 1))) {
2497 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(result)+1);
2498 if (DECIMAL_LO64_GET(result) == 0)
2499 DECIMAL_HI32(result)++;
2504 // Scale factors are not equal. Assume that a larger scale
2505 // factor (more decimal places) is likely to mean that number
2506 // is smaller. Start by guessing that the right operand has
2507 // the larger scale factor. The result will have the larger
2510 DECIMAL_SCALE(result) = DECIMAL_SCALE(*right); // scale factor of "smaller"
2511 DECIMAL_SIGN(result) = DECIMAL_SIGN(*left); // but sign of "larger"
2512 scale = DECIMAL_SCALE(result)- DECIMAL_SCALE(*left);
2515 // Guessed scale factor wrong. Swap operands.
2518 DECIMAL_SCALE(result) = DECIMAL_SCALE(*left);
2519 DECIMAL_SIGN(result) ^= sign;
2525 // *left will need to be multiplied by 10^scale so
2526 // it will have the same scale as *right. We could be
2527 // extending it to up to 192 bits of precision.
2529 if (scale <= POWER10_MAX) {
2530 // Scaling won't make it larger than 4 uint32_ts
2532 pwr = power10[scale];
2533 DECIMAL_LO64_SET(decTmp, UInt32x32To64(DECIMAL_LO32(*left), pwr));
2534 sdlTmp.int64 = UInt32x32To64(DECIMAL_MID32(*left), pwr);
2535 sdlTmp.int64 += DECIMAL_MID32(decTmp);
2536 DECIMAL_MID32(decTmp) = sdlTmp.u.Lo;
2537 DECIMAL_HI32(decTmp) = sdlTmp.u.Hi;
2538 sdlTmp.int64 = UInt32x32To64(DECIMAL_HI32(*left), pwr);
2539 sdlTmp.int64 += DECIMAL_HI32(decTmp);
2540 if (sdlTmp.u.Hi == 0) {
2541 // Result fits in 96 bits. Use standard aligned add.
2543 DECIMAL_HI32(decTmp) = sdlTmp.u.Lo;
2547 num[0] = DECIMAL_LO32(decTmp);
2548 num[1] = DECIMAL_MID32(decTmp);
2549 num[2] = sdlTmp.u.Lo;
2550 num[3] = sdlTmp.u.Hi;
2553 // Have to scale by a bunch. Move the number to a buffer
2554 // where it has room to grow as it's scaled.
2556 num[0] = DECIMAL_LO32(*left);
2557 num[1] = DECIMAL_MID32(*left);
2558 num[2] = DECIMAL_HI32(*left);
2561 // Scan for zeros in the upper words.
2568 // Left arg is zero, return right.
2570 DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(*right));
2571 DECIMAL_HI32(result) = DECIMAL_HI32(*right);
2572 DECIMAL_SIGN(result) ^= sign;
2578 // Scaling loop, up to 10^9 at a time. hi_prod stays updated
2579 // with index of highest non-zero uint32_t.
2581 for (; scale > 0; scale -= POWER10_MAX) {
2582 if (scale > POWER10_MAX)
2585 pwr = power10[scale];
2588 for (cur = 0; cur <= hi_prod; cur++) {
2589 sdlTmp.int64 = UInt32x32To64(num[cur], pwr) + sdlTmp.u.Hi;
2590 num[cur] = sdlTmp.u.Lo;
2593 if (sdlTmp.u.Hi != 0)
2594 // We're extending the result by another uint32_t.
2595 num[++hi_prod] = sdlTmp.u.Hi;
2599 // Scaling complete, do the add. Could be subtract if signs differ.
2601 sdlTmp.u.Lo = num[0];
2602 sdlTmp.u.Hi = num[1];
2605 // Signs differ, subtract.
2607 DECIMAL_LO64_SET(result, (sdlTmp.int64 - DECIMAL_LO64_GET(*right)));
2608 DECIMAL_HI32(result) = num[2] - DECIMAL_HI32(*right);
2612 if (DECIMAL_LO64_GET(result) > sdlTmp.int64) {
2613 DECIMAL_HI32(result)--;
2614 if (DECIMAL_HI32(result) >= num[2])
2616 } else if (DECIMAL_HI32(result) > num[2]) {
2618 // If num has more than 96 bits of precision, then we need to
2619 // carry the subtraction into the higher bits. If it doesn't,
2620 // then we subtracted in the wrong order and have to flip the
2621 // sign of the result.
2627 while(num[cur++]-- == 0);
2628 if (num[hi_prod] == 0)
2632 // Signs the same, add.
2634 DECIMAL_LO64_SET(result, (sdlTmp.int64 + DECIMAL_LO64_GET(*right)));
2635 DECIMAL_HI32(result) = num[2] + DECIMAL_HI32(*right);
2639 if (DECIMAL_LO64_GET(result) < sdlTmp.int64) {
2640 DECIMAL_HI32(result)++;
2641 if (DECIMAL_HI32(result) <= num[2])
2643 } else if (DECIMAL_HI32(result) < num[2]) {
2645 // Had a carry above 96 bits.
2649 if (hi_prod < cur) {
2654 }while (++num[cur++] == 0);
2659 num[0] = DECIMAL_LO32(result);
2660 num[1] = DECIMAL_MID32(result);
2661 num[2] = DECIMAL_HI32(result);
2662 DECIMAL_SCALE(result) = (uint8_t)ScaleResult(num, hi_prod, DECIMAL_SCALE(result));
2663 if (DECIMAL_SCALE(result) == (uint8_t)-1) {
2664 mono_set_pending_exception (mono_get_exception_overflow ());
2668 DECIMAL_LO32(result) = num[0];
2669 DECIMAL_MID32(result) = num[1];
2670 DECIMAL_HI32(result) = num[2];
2675 left = leftOriginal;
2676 COPYDEC(*left, result);
2681 mono_decimal_divide (MonoDecimal *left, MonoDecimal *right)
2683 uint32_t quo[3], quo_save[3],rem[4], divisor[3];
2684 uint32_t pwr, tmp, tmp1;
2685 SPLIT64 sdlTmp, sdlDivisor;
2686 int scale, cur_scale;
2689 scale = DECIMAL_SCALE(*left) - DECIMAL_SCALE(*right);
2691 divisor[0] = DECIMAL_LO32(*right);
2692 divisor[1] = DECIMAL_MID32(*right);
2693 divisor[2] = DECIMAL_HI32(*right);
2695 if (divisor[1] == 0 && divisor[2] == 0) {
2696 // Divisor is only 32 bits. Easy divide.
2698 if (divisor[0] == 0) {
2699 mono_set_pending_exception (mono_get_exception_divide_by_zero ());
2703 quo[0] = DECIMAL_LO32(*left);
2704 quo[1] = DECIMAL_MID32(*left);
2705 quo[2] = DECIMAL_HI32(*left);
2706 rem[0] = Div96By32(quo, divisor[0]);
2711 cur_scale = min(9, -scale);
2716 // We need to unscale if and only if we have a non-zero remainder
2719 // We have computed a quotient based on the natural scale
2720 // ( <dividend scale> - <divisor scale> ). We have a non-zero
2721 // remainder, so now we should increase the scale if possible to
2722 // include more quotient bits.
2724 // If it doesn't cause overflow, we'll loop scaling by 10^9 and
2725 // computing more quotient bits as long as the remainder stays
2726 // non-zero. If scaling by that much would cause overflow, we'll
2727 // drop out of the loop and scale by as much as we can.
2729 // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
2730 // = 4.294 967 296. So the upper limit is quo[2] == 4 and
2731 // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+. Since
2732 // quotient bits in quo[0] could be all 1's, then 1,266,874,888
2733 // is the largest value in quo[1] (when quo[2] == 4) that is
2734 // assured not to overflow.
2736 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2737 if (cur_scale == 0) {
2738 // No more scaling to be done, but remainder is non-zero.
2742 if (tmp < rem[0] || (tmp >= divisor[0] &&
2743 (tmp > divisor[0] || (quo[0] & 1)))) {
2745 if (!Add32To96(quo, 1)) {
2747 mono_set_pending_exception (mono_get_exception_overflow ());
2751 OverflowUnscale(quo, TRUE);
2758 if (cur_scale < 0) {
2759 mono_set_pending_exception (mono_get_exception_overflow ());
2764 pwr = power10[cur_scale];
2767 if (IncreaseScale(quo, pwr) != 0) {
2768 mono_set_pending_exception (mono_get_exception_overflow ());
2772 sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
2773 rem[0] = sdlTmp.u.Hi;
2775 if (!Add32To96(quo, sdlTmp.u.Lo)) {
2777 mono_set_pending_exception (mono_get_exception_overflow ());
2781 OverflowUnscale(quo, (rem[0] != 0));
2786 // Divisor has bits set in the upper 64 bits.
2788 // Divisor must be fully normalized (shifted so bit 31 of the most
2789 // significant uint32_t is 1). Locate the MSB so we know how much to
2790 // normalize by. The dividend will be shifted by the same amount so
2791 // the quotient is not changed.
2793 if (divisor[2] == 0)
2799 if (!(tmp & 0xFFFF0000)) {
2803 if (!(tmp & 0xFF000000)) {
2807 if (!(tmp & 0xF0000000)) {
2811 if (!(tmp & 0xC0000000)) {
2815 if (!(tmp & 0x80000000)) {
2820 // Shift both dividend and divisor left by cur_scale.
2822 sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
2823 rem[0] = sdlTmp.u.Lo;
2824 rem[1] = sdlTmp.u.Hi;
2825 sdlTmp.u.Lo = DECIMAL_MID32(*left);
2826 sdlTmp.u.Hi = DECIMAL_HI32(*left);
2827 sdlTmp.int64 <<= cur_scale;
2828 rem[2] = sdlTmp.u.Hi;
2829 rem[3] = (DECIMAL_HI32(*left) >> (31 - cur_scale)) >> 1;
2831 sdlDivisor.u.Lo = divisor[0];
2832 sdlDivisor.u.Hi = divisor[1];
2833 sdlDivisor.int64 <<= cur_scale;
2835 if (divisor[2] == 0) {
2836 // Have a 64-bit divisor in sdlDivisor. The remainder
2837 // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
2839 sdlTmp.u.Lo = rem[2];
2840 sdlTmp.u.Hi = rem[3];
2843 quo[1] = Div96By64(&rem[1], sdlDivisor);
2844 quo[0] = Div96By64(rem, sdlDivisor);
2847 if ((rem[0] | rem[1]) == 0) {
2849 cur_scale = min(9, -scale);
2855 // We need to unscale if and only if we have a non-zero remainder
2858 // Remainder is non-zero. Scale up quotient and remainder by
2859 // powers of 10 so we can compute more significant bits.
2861 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2862 if (cur_scale == 0) {
2863 // No more scaling to be done, but remainder is non-zero.
2866 sdlTmp.u.Lo = rem[0];
2867 sdlTmp.u.Hi = rem[1];
2868 if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
2869 (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
2874 if (cur_scale < 0) {
2875 mono_set_pending_exception (mono_get_exception_overflow ());
2880 pwr = power10[cur_scale];
2883 if (IncreaseScale(quo, pwr) != 0) {
2884 mono_set_pending_exception (mono_get_exception_overflow ());
2888 rem[2] = 0; // rem is 64 bits, IncreaseScale uses 96
2889 IncreaseScale(rem, pwr);
2890 tmp = Div96By64(rem, sdlDivisor);
2891 if (!Add32To96(quo, tmp)) {
2893 mono_set_pending_exception (mono_get_exception_overflow ());
2897 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0));
2903 // Have a 96-bit divisor in divisor[].
2905 // Start by finishing the shift left by cur_scale.
2907 sdlTmp.u.Lo = divisor[1];
2908 sdlTmp.u.Hi = divisor[2];
2909 sdlTmp.int64 <<= cur_scale;
2910 divisor[0] = sdlDivisor.u.Lo;
2911 divisor[1] = sdlDivisor.u.Hi;
2912 divisor[2] = sdlTmp.u.Hi;
2914 // The remainder (currently 96 bits spread over 4 uint32_ts)
2915 // will be < divisor.
2919 quo[0] = Div128By96(rem, divisor);
2922 if ((rem[0] | rem[1] | rem[2]) == 0) {
2924 cur_scale = min(9, -scale);
2930 // We need to unscale if and only if we have a non-zero remainder
2933 // Remainder is non-zero. Scale up quotient and remainder by
2934 // powers of 10 so we can compute more significant bits.
2936 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
2937 if (cur_scale == 0) {
2938 // No more scaling to be done, but remainder is non-zero.
2941 if (rem[2] >= 0x80000000)
2944 tmp = rem[0] > 0x80000000;
2945 tmp1 = rem[1] > 0x80000000;
2947 rem[1] = (rem[1] << 1) + tmp;
2948 rem[2] = (rem[2] << 1) + tmp1;
2950 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)))))))
2955 if (cur_scale < 0) {
2956 mono_set_pending_exception (mono_get_exception_overflow ());
2961 pwr = power10[cur_scale];
2964 if (IncreaseScale(quo, pwr) != 0) {
2965 mono_set_pending_exception (mono_get_exception_overflow ());
2969 rem[3] = IncreaseScale(rem, pwr);
2970 tmp = Div128By96(rem, divisor);
2971 if (!Add32To96(quo, tmp)) {
2973 mono_set_pending_exception (mono_get_exception_overflow ());
2978 OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0 || rem[2] != 0 || rem[3] != 0));
2986 // We need to unscale if and only if we have a non-zero remainder
2988 // Try extracting any extra powers of 10 we may have
2989 // added. We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
2990 // If a division by one of these powers returns a zero remainder, then
2991 // we keep the quotient. If the remainder is not zero, then we restore
2992 // the previous value.
2994 // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
2995 // we can extract. We use this as a quick test on whether to try a
2998 while ((quo[0] & 0xFF) == 0 && scale >= 8) {
2999 quo_save[0] = quo[0];
3000 quo_save[1] = quo[1];
3001 quo_save[2] = quo[2];
3003 if (Div96By32(quo_save, 100000000) == 0) {
3004 quo[0] = quo_save[0];
3005 quo[1] = quo_save[1];
3006 quo[2] = quo_save[2];
3012 if ((quo[0] & 0xF) == 0 && scale >= 4) {
3013 quo_save[0] = quo[0];
3014 quo_save[1] = quo[1];
3015 quo_save[2] = quo[2];
3017 if (Div96By32(quo_save, 10000) == 0) {
3018 quo[0] = quo_save[0];
3019 quo[1] = quo_save[1];
3020 quo[2] = quo_save[2];
3025 if ((quo[0] & 3) == 0 && scale >= 2) {
3026 quo_save[0] = quo[0];
3027 quo_save[1] = quo[1];
3028 quo_save[2] = quo[2];
3030 if (Div96By32(quo_save, 100) == 0) {
3031 quo[0] = quo_save[0];
3032 quo[1] = quo_save[1];
3033 quo[2] = quo_save[2];
3038 if ((quo[0] & 1) == 0 && scale >= 1) {
3039 quo_save[0] = quo[0];
3040 quo_save[1] = quo[1];
3041 quo_save[2] = quo[2];
3043 if (Div96By32(quo_save, 10) == 0) {
3044 quo[0] = quo_save[0];
3045 quo[1] = quo_save[1];
3046 quo[2] = quo_save[2];
3052 DECIMAL_SIGN(*left) = DECIMAL_SIGN(*left) ^ DECIMAL_SIGN(*right);
3053 DECIMAL_HI32(*left) = quo[2];
3054 DECIMAL_MID32(*left) = quo[1];
3055 DECIMAL_LO32(*left) = quo[0];
3056 DECIMAL_SCALE(*left) = (uint8_t)scale;
3061 #define DECIMAL_PRECISION 29
3062 #define NUMBER_MAXDIGITS 50
3067 uint16_t digits[NUMBER_MAXDIGITS + 1];
3068 uint16_t* allDigits;
3072 mono_decimal_from_number (void *from, MonoDecimal *target)
3074 CLRNumber *number = (CLRNumber *) from;
3075 uint16_t* p = number->digits;
3077 int e = number->scale;
3078 g_assert(number != NULL);
3079 g_assert(target != NULL);
3082 DECIMAL_SIGNSCALE(d) = 0;
3083 DECIMAL_HI32(d) = 0;
3084 DECIMAL_LO32(d) = 0;
3085 DECIMAL_MID32(d) = 0;
3086 g_assert(p != NULL);
3088 // 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
3089 // the scale to 0 if the scale was previously positive
3094 if (e > DECIMAL_PRECISION) return 0;
3095 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'))))))) {
3098 DecAddInt32(&d, *p++ - '0');
3102 gboolean round = TRUE;
3103 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
3104 // For digits > 5 we will be roundinp up anyway.
3105 int count = 20; // Look at the next 20 digits to check to round
3106 while (*p == '0' && count != 0) {
3110 if (*p == '\0' || count == 0)
3111 round = FALSE;// Do nothing
3116 if ((DECIMAL_HI32(d) | DECIMAL_MID32(d) | DECIMAL_LO32(d)) == 0) {
3117 DECIMAL_HI32(d) = 0x19999999;
3118 DECIMAL_MID32(d) = 0x99999999;
3119 DECIMAL_LO32(d) = 0x9999999A;
3127 if (e <= -DECIMAL_PRECISION) {
3128 // Parsing a large scale zero can give you more precision than fits in the decimal.
3129 // This should only happen for actual zeros or very small numbers that round to zero.
3130 DECIMAL_SIGNSCALE(d) = 0;
3131 DECIMAL_HI32(d) = 0;
3132 DECIMAL_LO32(d) = 0;
3133 DECIMAL_MID32(d) = 0;
3134 DECIMAL_SCALE(d) = (DECIMAL_PRECISION - 1);
3136 DECIMAL_SCALE(d) = (uint8_t)(-e);
3139 DECIMAL_SIGN(d) = number->sign? DECIMAL_NEG: 0;