Skip to content

Commit 38ac605

Browse files
committed
Reworked conversion to BIGINT datatype
1 parent 84f435c commit 38ac605

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

src/common/DecFloat.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class DecimalContext : public decContext
105105
};
106106

107107
CDecimal128 dmax(DBL_MAX, DecimalStatus(0)), dmin(-DBL_MAX, DecimalStatus(0));
108+
CDecimal128 i64max(MAX_SINT64, DecimalStatus(0)), i64min(MIN_SINT64, DecimalStatus(0));
108109

109110
unsigned digits(const unsigned pMax, unsigned char* const coeff, int& exp)
110111
{
@@ -548,18 +549,31 @@ double Decimal128::toDouble(DecimalStatus decSt) const
548549

549550
SINT64 Decimal128::toInt64(DecimalStatus decSt, int scale) const
550551
{
552+
static CDecimal128 quant(1);
553+
551554
Decimal128 wrk(*this);
552555
wrk.setScale(decSt, -scale);
556+
wrk = wrk.quantize(decSt, quant);
553557

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;
563577
}
564578

565579
UCHAR* Decimal128::getBytes()

0 commit comments

Comments
 (0)