]> granicus.if.org Git - icu/commitdiff
ICU-13634 Fixing DecimalQuantity call sites, first written in r41063, r41064, and...
authorShane Carr <shane@unicode.org>
Fri, 6 Apr 2018 09:35:16 +0000 (09:35 +0000)
committerShane Carr <shane@unicode.org>
Fri, 6 Apr 2018 09:35:16 +0000 (09:35 +0000)
X-SVN-Rev: 41204

icu4c/source/i18n/fmtable.cpp
icu4c/source/i18n/msgfmt.cpp
icu4c/source/i18n/nfsubs.cpp
icu4c/source/i18n/number_decimalquantity.cpp
icu4c/source/i18n/numparse_impl.cpp
icu4c/source/i18n/plurfmt.cpp
icu4c/source/i18n/rbnf.cpp
icu4c/source/test/intltest/numfmtst.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java
icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java

index ac2411a20b44d977fb26a3632ca3838fa9936611..68e06767a1c07bcf94ba63e314d3add461e849d9 100644 (file)
@@ -725,6 +725,7 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
         switch (fType) {
         case kDouble:
           fDecimalQuantity->setToDouble(this->getDouble());
+          fDecimalQuantity->roundToInfinity();
           break;
         case kLong:
           fDecimalQuantity->setToInt(this->getLong());
@@ -745,12 +746,7 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
         return NULL;
       }
       UnicodeString result = fDecimalQuantity->toNumberString();
-      for (int32_t i=0; i<result.length(); i++) {
-        fDecimalStr->append(static_cast<char>(result[i]), status);
-        if (U_FAILURE(status)) {
-          return NULL;
-        }
-      }
+      fDecimalStr->appendInvariantChars(result, status);
     }
     return fDecimalStr;
 }
index a758f0d055fd20f2e6208609a28d186cc9c586e1..faf6c21c6eb4b5802558ecb41fe9467ac2227ceb 100644 (file)
@@ -1962,7 +1962,7 @@ UnicodeString MessageFormat::PluralSelectorProvider::select(void *ctx, double nu
     auto* decFmt = dynamic_cast<const DecimalFormat *>(context.formatter);
     if(decFmt != NULL) {
         number::impl::DecimalQuantity dq;
-        decFmt->formatToDecimalQuantity(number, dq, ec);
+        decFmt->formatToDecimalQuantity(context.number, dq, ec);
         if (U_FAILURE(ec)) {
             return UnicodeString(FALSE, OTHER_STRING, 5);
         }
index 0911ac0887f07c6e5962b90019450deb3599bc9a..208543d1acd4de7d3c278b3f253f1c2d4a412d54 100644 (file)
@@ -1086,7 +1086,7 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser
       } else {
         pad = TRUE;
       }
-      int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0;
+      int64_t digit = dl.getDigit(didx);
       getRuleSet()->format(digit, toInsertInto, _pos + getPos(), recursionCount, status);
     }
 
@@ -1145,6 +1145,7 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
 //          double p10 = 0.1;
 
         DecimalQuantity dl;
+        int32_t totalDigits = 0;
         NumberFormat* fmt = NULL;
         while (workText.length() > 0 && workPos.getIndex() != 0) {
             workPos.setIndex(0);
@@ -1172,8 +1173,8 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
             }
 
             if (workPos.getIndex() != 0) {
-                // TODO(sffc): Make sure this is doing what it is supposed to do.
                 dl.appendDigit(static_cast<int8_t>(digit), 0, true);
+                totalDigits++;
 //                  result += digit * p10;
 //                  p10 /= 10;
                 parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
@@ -1186,6 +1187,7 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
         }
         delete fmt;
 
+        dl.adjustMagnitude(-totalDigits);
         result = dl.toDouble();
         result = composeRuleValue(result, baseValue);
         resVal.setDouble(result);
index 1a3e258384e4ba5cf216c74fc5ba3e6db28a2151..8b369547aef658a4d6c075f455f6b395d45d8ffa 100644 (file)
@@ -474,6 +474,7 @@ void DecimalQuantity::_setToDecNum(const DecNum& decnum, UErrorCode& status) {
 int64_t DecimalQuantity::toLong() const {
     // NOTE: Call sites should be guarded by fitsInLong(), like this:
     // if (dq.fitsInLong()) { /* use dq.toLong() */ } else { /* use some fallback */ }
+    U_ASSERT(fitsInLong());
     int64_t result = 0L;
     for (int32_t magnitude = scale + precision - 1; magnitude >= 0; magnitude--) {
         result = result * 10 + getDigitPos(magnitude - scale);
@@ -753,6 +754,7 @@ void DecimalQuantity::appendDigit(int8_t value, int32_t leadingZeros, bool appen
 }
 
 UnicodeString DecimalQuantity::toPlainString() const {
+    U_ASSERT(!isApproximate);
     UnicodeString sb;
     if (isNegative()) {
         sb.append(u'-');
@@ -1097,6 +1099,7 @@ UnicodeString DecimalQuantity::toString() const {
 }
 
 UnicodeString DecimalQuantity::toNumberString() const {
+    U_ASSERT(!isApproximate);
     UnicodeString result;
     if (precision == 0) {
         result.append(u'0');
index c917aad1764b383652865bf5a20ac9ac1b9090fc..b8240e7f401a76c5f9000b6c6306103ad4b087d3 100644 (file)
@@ -146,10 +146,10 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr
     if (!isStrict) {
         parser->addMatcher(parser->fLocalMatchers.plusSign = {symbols, false});
         parser->addMatcher(parser->fLocalMatchers.minusSign = {symbols, false});
-        parser->addMatcher(parser->fLocalMatchers.nan = {symbols});
         parser->addMatcher(parser->fLocalMatchers.percent = {symbols});
         parser->addMatcher(parser->fLocalMatchers.permille = {symbols});
     }
+    parser->addMatcher(parser->fLocalMatchers.nan = {symbols});
     parser->addMatcher(parser->fLocalMatchers.infinity = {symbols});
     UnicodeString padString = properties.padString;
     if (!padString.isBogus() && !ignorables.getSet()->contains(padString)) {
index a8fd24d17662d714b3d63db264a4caa1a3851447..eb8b5d88a8fa721d962198a47f16f8e2ac666b47 100644 (file)
@@ -264,35 +264,26 @@ PluralFormat::format(const Formattable& numberObject, double number,
     double numberMinusOffset = number - offset;
     UnicodeString numberString;
     DecimalQuantity quantity;
-    quantity.setToDouble(numberMinusOffset);
     FieldPosition ignorePos;
     if (offset == 0) {
         DecimalFormat *decFmt = dynamic_cast<DecimalFormat *>(numberFormat);
         if(decFmt != NULL) {
-//            decFmt->initVisibleDigitsWithExponent(
-//                    numberObject, dec, status);
-//            if (U_FAILURE(status)) {
-//                return appendTo;
-//            }
-//            decFmt->format(dec, numberString, ignorePos, status);
-            decFmt->format(quantity, numberString, ignorePos, status);
+            decFmt->formatToDecimalQuantity(numberObject, quantity, status);
         } else {
             numberFormat->format(
                     numberObject, numberString, ignorePos, status);  // could be BigDecimal etc.
+            quantity.setToDouble(numberMinusOffset);
+            quantity.roundToInfinity();
         }
     } else {
         DecimalFormat *decFmt = dynamic_cast<DecimalFormat *>(numberFormat);
         if(decFmt != NULL) {
-//            decFmt->initVisibleDigitsWithExponent(
-//                    numberMinusOffset, dec, status);
-//            if (U_FAILURE(status)) {
-//                return appendTo;
-//            }
-//            decFmt->format(dec, numberString, ignorePos, status);
-            decFmt->format(quantity, numberString, ignorePos, status);
+            decFmt->formatToDecimalQuantity(numberMinusOffset, quantity, status);
         } else {
             numberFormat->format(
                     numberMinusOffset, numberString, ignorePos, status);
+            quantity.setToDouble(numberMinusOffset);
+            quantity.roundToInfinity();
         }
     }
     int32_t partIndex = findSubMessage(msgPattern, 0, pluralRulesWrapper, &quantity, number, status);
index 3cc208585f6a79e6cd5ab01a8a8d6ec03cc2922a..68bbf1ab17e00a7a6b2f873b85f81ae57ba66819 100644 (file)
@@ -1120,12 +1120,12 @@ RuleBasedNumberFormat::format(const DecimalQuantity &number,
     }
     DecimalQuantity copy(number);
     if (copy.fitsInLong()) {
-        format(((DecimalQuantity &)number).toLong(), appendTo, posIter, status);
+        format(number.toLong(), appendTo, posIter, status);
     }
     else {
         copy.roundToMagnitude(0, number::impl::RoundingMode::UNUM_ROUND_HALFEVEN, status);
         if (copy.fitsInLong()) {
-            format(number.toLong(), appendTo, posIter, status);
+            format(number.toDouble(), appendTo, posIter, status);
         }
         else {
             // We're outside of our normal range that this framework can handle.
@@ -1153,12 +1153,12 @@ RuleBasedNumberFormat::format(const DecimalQuantity &number,
     }
     DecimalQuantity copy(number);
     if (copy.fitsInLong()) {
-        format(((DecimalQuantity &)number).toLong(), appendTo, pos, status);
+        format(number.toLong(), appendTo, pos, status);
     }
     else {
         copy.roundToMagnitude(0, number::impl::RoundingMode::UNUM_ROUND_HALFEVEN, status);
         if (copy.fitsInLong()) {
-            format(number.toLong(), appendTo, pos, status);
+            format(number.toDouble(), appendTo, pos, status);
         }
         else {
             // We're outside of our normal range that this framework can handle.
index c1c194cfb1d3bf6c3c2245864dd07ed080293952..8e75246e2e0a40e0094e83ea4778605424b96d99 100644 (file)
@@ -3691,6 +3691,7 @@ NumberFormatTest::TestSpaceParsing() {
         foo->setLenient(DATA[i].lenient);
         Formattable result;
         foo->parse(stringToBeParsed, result, parsePosition);
+        logln("Parsing: " + stringToBeParsed);
         if (parsePosition.getIndex() != parsedPosition ||
             parsePosition.getErrorIndex() != errorIndex) {
             errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
index b5fac7652617ec01bf9a6c28d3fee5c849c6e08a..72ab98e4e31f041acae214a384d2153ba10d2665 100644 (file)
@@ -196,10 +196,10 @@ public class NumberParserImpl {
         if (!isStrict) {
             parser.addMatcher(PlusSignMatcher.getInstance(symbols, false));
             parser.addMatcher(MinusSignMatcher.getInstance(symbols, false));
-            parser.addMatcher(NanMatcher.getInstance(symbols, parseFlags));
             parser.addMatcher(PercentMatcher.getInstance(symbols));
             parser.addMatcher(PermilleMatcher.getInstance(symbols));
         }
+        parser.addMatcher(NanMatcher.getInstance(symbols, parseFlags));
         parser.addMatcher(InfinityMatcher.getInstance(symbols));
         String padString = properties.getPadString();
         if (padString != null && !ignorables.getSet().contains(padString)) {
index 15ca301ed8cf724dcce4168a261036736906e1dc..e2a992bc45d4e274df1e54bcc947fc21867bae50 100644 (file)
@@ -1317,7 +1317,7 @@ class FractionalPartSubstitution extends NFSubstitution {
             int digit;
 
             DecimalQuantity_DualStorageBCD fq = new DecimalQuantity_DualStorageBCD();
-            int leadingZeros = 0;
+            int totalDigits = 0;
             while (workText.length() > 0 && workPos.getIndex() != 0) {
                 workPos.setIndex(0);
                 digit = ruleSet.parse(workText, workPos, 10, nonNumericalExecutedRuleMask).intValue();
@@ -1329,12 +1329,8 @@ class FractionalPartSubstitution extends NFSubstitution {
                 }
 
                 if (workPos.getIndex() != 0) {
-                    if (digit == 0) {
-                        leadingZeros++;
-                    } else {
-                        fq.appendDigit((byte) digit, leadingZeros, false);
-                        leadingZeros = 0;
-                    }
+                    fq.appendDigit((byte) digit, 0, true);
+                    totalDigits++;
 
                     parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
                     workText = workText.substring(workPos.getIndex());
@@ -1344,6 +1340,7 @@ class FractionalPartSubstitution extends NFSubstitution {
                     }
                 }
             }
+            fq.adjustMagnitude(-totalDigits);
             result = fq.toDouble();
 
             result = composeRuleValue(result, baseValue);