diff options
Diffstat (limited to 'deps/icu-small/source/i18n/precision.cpp')
-rw-r--r-- | deps/icu-small/source/i18n/precision.cpp | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/deps/icu-small/source/i18n/precision.cpp b/deps/icu-small/source/i18n/precision.cpp deleted file mode 100644 index 97dc13dc38..0000000000 --- a/deps/icu-small/source/i18n/precision.cpp +++ /dev/null @@ -1,444 +0,0 @@ -// © 2016 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html -/* - * Copyright (C) 2015, International Business Machines - * Corporation and others. All Rights Reserved. - * - * file name: precisison.cpp - */ - -#include <math.h> - -#include "unicode/utypes.h" - -#if !UCONFIG_NO_FORMATTING - -#include "digitlst.h" -#include "fmtableimp.h" -#include "precision.h" -#include "putilimp.h" -#include "visibledigits.h" - -U_NAMESPACE_BEGIN - -static const int32_t gPower10[] = {1, 10, 100, 1000}; - -FixedPrecision::FixedPrecision() - : fExactOnly(FALSE), fFailIfOverMax(FALSE), fRoundingMode(DecimalFormat::kRoundHalfEven) { - fMin.setIntDigitCount(1); - fMin.setFracDigitCount(0); -} - -UBool -FixedPrecision::isRoundingRequired( - int32_t upperExponent, int32_t lowerExponent) const { - int32_t leastSigAllowed = fMax.getLeastSignificantInclusive(); - int32_t maxSignificantDigits = fSignificant.getMax(); - int32_t roundDigit; - if (maxSignificantDigits == INT32_MAX) { - roundDigit = leastSigAllowed; - } else { - int32_t limitDigit = upperExponent - maxSignificantDigits; - roundDigit = - limitDigit > leastSigAllowed ? limitDigit : leastSigAllowed; - } - return (roundDigit > lowerExponent); -} - -DigitList & -FixedPrecision::round( - DigitList &value, int32_t exponent, UErrorCode &status) const { - if (U_FAILURE(status)) { - return value; - } - value .fContext.status &= ~DEC_Inexact; - if (!fRoundingIncrement.isZero()) { - if (exponent == 0) { - value.quantize(fRoundingIncrement, status); - } else { - DigitList adjustedIncrement(fRoundingIncrement); - adjustedIncrement.shiftDecimalRight(exponent); - value.quantize(adjustedIncrement, status); - } - if (U_FAILURE(status)) { - return value; - } - } - int32_t leastSig = fMax.getLeastSignificantInclusive(); - if (leastSig == INT32_MIN) { - value.round(fSignificant.getMax()); - } else { - value.roundAtExponent( - exponent + leastSig, - fSignificant.getMax()); - } - if (fExactOnly && (value.fContext.status & DEC_Inexact)) { - status = U_FORMAT_INEXACT_ERROR; - } else if (fFailIfOverMax) { - // Smallest interval for value stored in interval - DigitInterval interval; - value.getSmallestInterval(interval); - if (fMax.getIntDigitCount() < interval.getIntDigitCount()) { - status = U_ILLEGAL_ARGUMENT_ERROR; - } - } - return value; -} - -DigitInterval & -FixedPrecision::getIntervalForZero(DigitInterval &interval) const { - interval = fMin; - if (fSignificant.getMin() > 0) { - interval.expandToContainDigit(interval.getIntDigitCount() - fSignificant.getMin()); - } - interval.shrinkToFitWithin(fMax); - return interval; -} - -DigitInterval & -FixedPrecision::getInterval( - int32_t upperExponent, DigitInterval &interval) const { - if (fSignificant.getMin() > 0) { - interval.expandToContainDigit( - upperExponent - fSignificant.getMin()); - } - interval.expandToContain(fMin); - interval.shrinkToFitWithin(fMax); - return interval; -} - -DigitInterval & -FixedPrecision::getInterval( - const DigitList &value, DigitInterval &interval) const { - if (value.isZero()) { - interval = fMin; - if (fSignificant.getMin() > 0) { - interval.expandToContainDigit(interval.getIntDigitCount() - fSignificant.getMin()); - } - } else { - value.getSmallestInterval(interval); - if (fSignificant.getMin() > 0) { - interval.expandToContainDigit( - value.getUpperExponent() - fSignificant.getMin()); - } - interval.expandToContain(fMin); - } - interval.shrinkToFitWithin(fMax); - return interval; -} - -UBool -FixedPrecision::isFastFormattable() const { - return (fMin.getFracDigitCount() == 0 && fSignificant.isNoConstraints() && fRoundingIncrement.isZero() && !fFailIfOverMax); -} - -UBool -FixedPrecision::handleNonNumeric(DigitList &value, VisibleDigits &digits) { - if (value.isNaN()) { - digits.setNaN(); - return TRUE; - } - if (value.isInfinite()) { - digits.setInfinite(); - if (!value.isPositive()) { - digits.setNegative(); - } - return TRUE; - } - return FALSE; -} - -VisibleDigits & -FixedPrecision::initVisibleDigits( - DigitList &value, - VisibleDigits &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return digits; - } - digits.clear(); - if (handleNonNumeric(value, digits)) { - return digits; - } - if (!value.isPositive()) { - digits.setNegative(); - } - value.setRoundingMode(fRoundingMode); - round(value, 0, status); - getInterval(value, digits.fInterval); - digits.fExponent = value.getLowerExponent(); - value.appendDigitsTo(digits.fDigits, status); - return digits; -} - -VisibleDigits & -FixedPrecision::initVisibleDigits( - int64_t value, - VisibleDigits &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return digits; - } - if (!fRoundingIncrement.isZero()) { - // If we have round increment, use digit list. - DigitList digitList; - digitList.set(value); - return initVisibleDigits(digitList, digits, status); - } - // Try fast path - if (initVisibleDigits(value, 0, digits, status)) { - digits.fAbsDoubleValue = fabs((double) value); - digits.fAbsDoubleValueSet = U_SUCCESS(status) && !digits.isOverMaxDigits(); - return digits; - } - // Oops have to use digit list - DigitList digitList; - digitList.set(value); - return initVisibleDigits(digitList, digits, status); -} - -VisibleDigits & -FixedPrecision::initVisibleDigits( - double value, - VisibleDigits &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return digits; - } - digits.clear(); - if (uprv_isNaN(value)) { - digits.setNaN(); - return digits; - } - if (uprv_isPositiveInfinity(value)) { - digits.setInfinite(); - return digits; - } - if (uprv_isNegativeInfinity(value)) { - digits.setInfinite(); - digits.setNegative(); - return digits; - } - if (!fRoundingIncrement.isZero()) { - // If we have round increment, use digit list. - DigitList digitList; - digitList.set(value); - return initVisibleDigits(digitList, digits, status); - } - // Try to find n such that value * 10^n is an integer - int32_t n = -1; - double scaled; - for (int32_t i = 0; i < UPRV_LENGTHOF(gPower10); ++i) { - scaled = value * gPower10[i]; - if (scaled > MAX_INT64_IN_DOUBLE || scaled < -MAX_INT64_IN_DOUBLE) { - break; - } - if (scaled == floor(scaled)) { - n = i; - break; - } - } - // Try fast path - if (n >= 0 && initVisibleDigits(static_cast<int64_t>(scaled), -n, digits, status)) { - digits.fAbsDoubleValue = fabs(value); - digits.fAbsDoubleValueSet = U_SUCCESS(status) && !digits.isOverMaxDigits(); - // Adjust for negative 0 because when we cast to an int64, - // negative 0 becomes positive 0. - if (scaled == 0.0 && uprv_isNegative(scaled)) { - digits.setNegative(); - } - return digits; - } - - // Oops have to use digit list - DigitList digitList; - digitList.set(value); - return initVisibleDigits(digitList, digits, status); -} - -UBool -FixedPrecision::initVisibleDigits( - int64_t mantissa, - int32_t exponent, - VisibleDigits &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return TRUE; - } - digits.clear(); - - // Precompute fAbsIntValue if it is small enough, but we don't know yet - // if it will be valid. - UBool absIntValueComputed = FALSE; - if (mantissa > -1000000000000000000LL /* -1e18 */ - && mantissa < 1000000000000000000LL /* 1e18 */) { - digits.fAbsIntValue = mantissa; - if (digits.fAbsIntValue < 0) { - digits.fAbsIntValue = -digits.fAbsIntValue; - } - int32_t i = 0; - int32_t maxPower10Exp = UPRV_LENGTHOF(gPower10) - 1; - for (; i > exponent + maxPower10Exp; i -= maxPower10Exp) { - digits.fAbsIntValue /= gPower10[maxPower10Exp]; - } - digits.fAbsIntValue /= gPower10[i - exponent]; - absIntValueComputed = TRUE; - } - if (mantissa == 0) { - getIntervalForZero(digits.fInterval); - digits.fAbsIntValueSet = absIntValueComputed; - return TRUE; - } - // be sure least significant digit is non zero - while (mantissa % 10 == 0) { - mantissa /= 10; - ++exponent; - } - if (mantissa < 0) { - digits.fDigits.append((char) -(mantissa % -10), status); - mantissa /= -10; - digits.setNegative(); - } - while (mantissa) { - digits.fDigits.append((char) (mantissa % 10), status); - mantissa /= 10; - } - if (U_FAILURE(status)) { - return TRUE; - } - digits.fExponent = exponent; - int32_t upperExponent = exponent + digits.fDigits.length(); - if (fFailIfOverMax && upperExponent > fMax.getIntDigitCount()) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return TRUE; - } - UBool roundingRequired = - isRoundingRequired(upperExponent, exponent); - if (roundingRequired) { - if (fExactOnly) { - status = U_FORMAT_INEXACT_ERROR; - return TRUE; - } - return FALSE; - } - digits.fInterval.setLeastSignificantInclusive(exponent); - digits.fInterval.setMostSignificantExclusive(upperExponent); - getInterval(upperExponent, digits.fInterval); - - // The intValue we computed above is only valid if our visible digits - // doesn't exceed the maximum integer digits allowed. - digits.fAbsIntValueSet = absIntValueComputed && !digits.isOverMaxDigits(); - return TRUE; -} - -VisibleDigitsWithExponent & -FixedPrecision::initVisibleDigitsWithExponent( - DigitList &value, - VisibleDigitsWithExponent &digits, - UErrorCode &status) const { - digits.clear(); - initVisibleDigits(value, digits.fMantissa, status); - return digits; -} - -VisibleDigitsWithExponent & -FixedPrecision::initVisibleDigitsWithExponent( - double value, - VisibleDigitsWithExponent &digits, - UErrorCode &status) const { - digits.clear(); - initVisibleDigits(value, digits.fMantissa, status); - return digits; -} - -VisibleDigitsWithExponent & -FixedPrecision::initVisibleDigitsWithExponent( - int64_t value, - VisibleDigitsWithExponent &digits, - UErrorCode &status) const { - digits.clear(); - initVisibleDigits(value, digits.fMantissa, status); - return digits; -} - -ScientificPrecision::ScientificPrecision() : fMinExponentDigits(1) { -} - -DigitList & -ScientificPrecision::round(DigitList &value, UErrorCode &status) const { - if (U_FAILURE(status)) { - return value; - } - int32_t exponent = value.getScientificExponent( - fMantissa.fMin.getIntDigitCount(), getMultiplier()); - return fMantissa.round(value, exponent, status); -} - -int32_t -ScientificPrecision::toScientific(DigitList &value) const { - return value.toScientific( - fMantissa.fMin.getIntDigitCount(), getMultiplier()); -} - -int32_t -ScientificPrecision::getMultiplier() const { - int32_t maxIntDigitCount = fMantissa.fMax.getIntDigitCount(); - if (maxIntDigitCount == INT32_MAX) { - return 1; - } - int32_t multiplier = - maxIntDigitCount - fMantissa.fMin.getIntDigitCount() + 1; - return (multiplier < 1 ? 1 : multiplier); -} - -VisibleDigitsWithExponent & -ScientificPrecision::initVisibleDigitsWithExponent( - DigitList &value, - VisibleDigitsWithExponent &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return digits; - } - digits.clear(); - if (FixedPrecision::handleNonNumeric(value, digits.fMantissa)) { - return digits; - } - value.setRoundingMode(fMantissa.fRoundingMode); - int64_t exponent = toScientific(round(value, status)); - fMantissa.initVisibleDigits(value, digits.fMantissa, status); - FixedPrecision exponentPrecision; - exponentPrecision.fMin.setIntDigitCount(fMinExponentDigits); - exponentPrecision.initVisibleDigits(exponent, digits.fExponent, status); - digits.fHasExponent = TRUE; - return digits; -} - -VisibleDigitsWithExponent & -ScientificPrecision::initVisibleDigitsWithExponent( - double value, - VisibleDigitsWithExponent &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return digits; - } - DigitList digitList; - digitList.set(value); - return initVisibleDigitsWithExponent(digitList, digits, status); -} - -VisibleDigitsWithExponent & -ScientificPrecision::initVisibleDigitsWithExponent( - int64_t value, - VisibleDigitsWithExponent &digits, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return digits; - } - DigitList digitList; - digitList.set(value); - return initVisibleDigitsWithExponent(digitList, digits, status); -} - - -U_NAMESPACE_END -#endif /* #if !UCONFIG_NO_FORMATTING */ |