void DigitList::roundFixedPoint(int32_t maximumFractionDigits) { reduce(); // Remove trailing zeros. if (fDecNumber->exponent >= -maximumFractionDigits) { return; } decNumber scale; // Dummy decimal number, but with the desired number of uprv_decNumberZero(&scale); // fraction digits. scale.exponent = -maximumFractionDigits; scale.lsu[0] = 1; uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext); reduce(); internalClear(); }
/** * convert this number to an int32_t. Round if there is a fractional part. * Return zero if the number cannot be represented. */ int32_t DigitList::getLong() /*const*/ { int32_t result = 0; if (getUpperExponent() > 10) { // Overflow, absolute value too big. return result; } if (fDecNumber->exponent != 0) { // Force to an integer, with zero exponent, rounding if necessary. // (decNumberToInt32 will only work if the exponent is exactly zero.) DigitList copy(*this); DigitList zero; uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext); result = uprv_decNumberToInt32(copy.fDecNumber, &fContext); } else { result = uprv_decNumberToInt32(fDecNumber, &fContext); } return result; }
int64_t DigitList::getInt64() /*const*/ { // Round if non-integer. (Truncate or round?) // Return 0 if out of range. // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digits) // if (fDecNumber->digits + fDecNumber->exponent > 19) { // Overflow, absolute value too big. return 0; } decNumber *workingNum = fDecNumber; if (fDecNumber->exponent != 0) { // Force to an integer, with zero exponent, rounding if necessary. DigitList copy(*this); DigitList zero; uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext); workingNum = copy.fDecNumber; } uint64_t value = 0; int32_t numDigits = workingNum->digits; for (int i = numDigits-1; i>=0 ; --i) { int v = workingNum->lsu[i]; value = value * (uint64_t)10 + (uint64_t)v; } if (decNumberIsNegative(workingNum)) { value = ~value; value += 1; } int64_t svalue = (int64_t)value; // Check overflow. It's convenient that the MSD is 9 only on overflow, the amount of // overflow can't wrap too far. The test will also fail -0, but // that does no harm; the right answer is 0. if (numDigits == 19) { if (( decNumberIsNegative(fDecNumber) && svalue>0) || (!decNumberIsNegative(fDecNumber) && svalue<0)) { svalue = 0; } } return svalue; }