@@ -105,6 +105,7 @@ class DecimalContext : public decContext
105
105
};
106
106
107
107
CDecimal128 dmax (DBL_MAX, DecimalStatus(0 )), dmin(-DBL_MAX, DecimalStatus(0 ));
108
+ CDecimal128 i64max (MAX_SINT64, DecimalStatus(0 )), i64min(MIN_SINT64, DecimalStatus(0 ));
108
109
109
110
unsigned digits (const unsigned pMax, unsigned char * const coeff, int & exp)
110
111
{
@@ -548,18 +549,31 @@ double Decimal128::toDouble(DecimalStatus decSt) const
548
549
549
550
SINT64 Decimal128::toInt64 (DecimalStatus decSt, int scale) const
550
551
{
552
+ static CDecimal128 quant (1 );
553
+
551
554
Decimal128 wrk (*this );
552
555
wrk.setScale (decSt, -scale);
556
+ wrk = wrk.quantize (decSt, quant);
553
557
554
- DecimalContext context (this , decSt);
555
- decQuad pow2_32, div, rem;
556
- decQuadFromString (&pow2_32, " 4294967296" , &context);
557
- decQuadDivideInteger (&div, &wrk.dec , &pow2_32, &context);
558
- decQuadRemainder (&rem, &wrk.dec , &pow2_32, &context);
559
-
560
- SINT64 high = decQuadToInt32 (&div, &context, DEC_ROUND_DOWN);
561
- high <<= 32 ;
562
- return high + decQuadToInt32 (&rem, &context, DEC_ROUND_DOWN);
558
+ if (wrk.compare (decSt, i64min) < 0 || wrk.compare (decSt, i64max) > 0 )
559
+ {
560
+ DecimalContext context (this , decSt);
561
+ decContextSetStatus (&context, DEC_Invalid_operation);
562
+ return 0 ; // in case of no trap on invalid operation
563
+ }
564
+
565
+ unsigned char coeff[DECQUAD_Pmax];
566
+ int sign = decQuadGetCoefficient (&wrk.dec , coeff);
567
+ SINT64 rc = 0 ;
568
+ for (int i = 0 ; i < DECQUAD_Pmax; ++i)
569
+ {
570
+ rc *= 10 ;
571
+ if (sign)
572
+ rc -= coeff[i];
573
+ else
574
+ rc += coeff[i];
575
+ }
576
+ return rc;
563
577
}
564
578
565
579
UCHAR* Decimal128::getBytes ()
0 commit comments