summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp')
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp123
1 files changed, 114 insertions, 9 deletions
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
index 6a2847b1c18..b40e1276c35 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
@@ -181,20 +181,22 @@ uint64_t DecimalQuantity::getPositionFingerprint() const {
return fingerprint;
}
-void DecimalQuantity::roundToIncrement(double roundingIncrement, RoundingMode roundingMode,
- UErrorCode& status) {
+void DecimalQuantity::roundToIncrement(
+ uint64_t increment,
+ digits_t magnitude,
+ RoundingMode roundingMode,
+ UErrorCode& status) {
// Do not call this method with an increment having only a 1 or a 5 digit!
// Use a more efficient call to either roundToMagnitude() or roundToNickel().
// Check a few popular rounding increments; a more thorough check is in Java.
- U_ASSERT(roundingIncrement != 0.01);
- U_ASSERT(roundingIncrement != 0.05);
- U_ASSERT(roundingIncrement != 0.1);
- U_ASSERT(roundingIncrement != 0.5);
- U_ASSERT(roundingIncrement != 1);
- U_ASSERT(roundingIncrement != 5);
+ U_ASSERT(increment != 1);
+ U_ASSERT(increment != 5);
+ DecimalQuantity incrementDQ;
+ incrementDQ.setToLong(increment);
+ incrementDQ.adjustMagnitude(magnitude);
DecNum incrementDN;
- incrementDN.setTo(roundingIncrement, status);
+ incrementDQ.toDecNum(incrementDN, status);
if (U_FAILURE(status)) { return; }
// Divide this DecimalQuantity by the increment, round, then multiply back.
@@ -254,6 +256,12 @@ bool DecimalQuantity::adjustMagnitude(int32_t delta) {
return false;
}
+int32_t DecimalQuantity::adjustToZeroScale() {
+ int32_t retval = scale;
+ scale = 0;
+ return retval;
+}
+
double DecimalQuantity::getPluralOperand(PluralOperand operand) const {
// If this assertion fails, you need to call roundToInfinity() or some other rounding method.
// See the comment at the top of this file explaining the "isApproximate" field.
@@ -549,6 +557,65 @@ void DecimalQuantity::_setToDecNum(const DecNum& decnum, UErrorCode& status) {
}
}
+DecimalQuantity DecimalQuantity::fromExponentString(UnicodeString num, UErrorCode& status) {
+ if (num.indexOf(u'e') >= 0 || num.indexOf(u'c') >= 0
+ || num.indexOf(u'E') >= 0 || num.indexOf(u'C') >= 0) {
+ int32_t ePos = num.lastIndexOf('e');
+ if (ePos < 0) {
+ ePos = num.lastIndexOf('c');
+ }
+ if (ePos < 0) {
+ ePos = num.lastIndexOf('E');
+ }
+ if (ePos < 0) {
+ ePos = num.lastIndexOf('C');
+ }
+ int32_t expNumPos = ePos + 1;
+ UnicodeString exponentStr = num.tempSubString(expNumPos, num.length() - expNumPos);
+
+ // parse exponentStr into exponent, but note that parseAsciiInteger doesn't handle the minus sign
+ bool isExpStrNeg = num[expNumPos] == u'-';
+ int32_t exponentParsePos = isExpStrNeg ? 1 : 0;
+ int32_t exponent = ICU_Utility::parseAsciiInteger(exponentStr, exponentParsePos);
+ exponent = isExpStrNeg ? -exponent : exponent;
+
+ // Compute the decNumber representation
+ UnicodeString fractionStr = num.tempSubString(0, ePos);
+ CharString fracCharStr = CharString();
+ fracCharStr.appendInvariantChars(fractionStr, status);
+ DecNum decnum;
+ decnum.setTo(fracCharStr.toStringPiece(), status);
+
+ // Clear and set this DecimalQuantity instance
+ DecimalQuantity dq;
+ dq.setToDecNum(decnum, status);
+ int32_t numFracDigit = getVisibleFractionCount(fractionStr);
+ dq.setMinFraction(numFracDigit);
+ dq.adjustExponent(exponent);
+
+ return dq;
+ } else {
+ DecimalQuantity dq;
+ int numFracDigit = getVisibleFractionCount(num);
+
+ CharString numCharStr = CharString();
+ numCharStr.appendInvariantChars(num, status);
+ dq.setToDecNumber(numCharStr.toStringPiece(), status);
+
+ dq.setMinFraction(numFracDigit);
+ return dq;
+ }
+}
+
+int32_t DecimalQuantity::getVisibleFractionCount(UnicodeString value) {
+ int decimalPos = value.indexOf('.') + 1;
+ if (decimalPos == 0) {
+ return 0;
+ } else {
+ return value.length() - decimalPos;
+ }
+}
+
int64_t DecimalQuantity::toLong(bool truncateIfOverflow) const {
// NOTE: Call sites should be guarded by fitsInLong(), like this:
// if (dq.fitsInLong()) { /* use dq.toLong() */ } else { /* use some fallback */ }
@@ -948,6 +1015,44 @@ UnicodeString DecimalQuantity::toPlainString() const {
return sb;
}
+
+UnicodeString DecimalQuantity::toExponentString() const {
+ U_ASSERT(!isApproximate);
+ UnicodeString sb;
+ if (isNegative()) {
+ sb.append(u'-');
+ }
+
+ int32_t upper = scale + precision - 1;
+ int32_t lower = scale;
+ if (upper < lReqPos - 1) {
+ upper = lReqPos - 1;
+ }
+ if (lower > rReqPos) {
+ lower = rReqPos;
+ }
+ int32_t p = upper;
+ if (p < 0) {
+ sb.append(u'0');
+ }
+ for (; p >= 0; p--) {
+ sb.append(u'0' + getDigitPos(p - scale));
+ }
+ if (lower < 0) {
+ sb.append(u'.');
+ }
+ for(; p >= lower; p--) {
+ sb.append(u'0' + getDigitPos(p - scale));
+ }
+
+ if (exponent != 0) {
+ sb.append(u'c');
+ ICU_Utility::appendNumber(sb, exponent);
+ }
+
+ return sb;
+}
+
UnicodeString DecimalQuantity::toScientificString() const {
U_ASSERT(!isApproximate);
UnicodeString result;