From: Shane Carr Date: Fri, 6 Apr 2018 09:35:16 +0000 (+0000) Subject: ICU-13634 Fixing DecimalQuantity call sites, first written in r41063, r41064, and... X-Git-Tag: release-62-rc~200^2~49 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73f93a457aa640d1f8e1874977adbcbf0365a81f;p=icu ICU-13634 Fixing DecimalQuantity call sites, first written in r41063, r41064, and r41098. RNBF test is passing again. X-SVN-Rev: 41204 --- diff --git a/icu4c/source/i18n/fmtable.cpp b/icu4c/source/i18n/fmtable.cpp index ac2411a20b4..68e06767a1c 100644 --- a/icu4c/source/i18n/fmtable.cpp +++ b/icu4c/source/i18n/fmtable.cpp @@ -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; iappend(static_cast(result[i]), status); - if (U_FAILURE(status)) { - return NULL; - } - } + fDecimalStr->appendInvariantChars(result, status); } return fDecimalStr; } diff --git a/icu4c/source/i18n/msgfmt.cpp b/icu4c/source/i18n/msgfmt.cpp index a758f0d055f..faf6c21c6eb 100644 --- a/icu4c/source/i18n/msgfmt.cpp +++ b/icu4c/source/i18n/msgfmt.cpp @@ -1962,7 +1962,7 @@ UnicodeString MessageFormat::PluralSelectorProvider::select(void *ctx, double nu auto* decFmt = dynamic_cast(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); } diff --git a/icu4c/source/i18n/nfsubs.cpp b/icu4c/source/i18n/nfsubs.cpp index 0911ac0887f..208543d1acd 100644 --- a/icu4c/source/i18n/nfsubs.cpp +++ b/icu4c/source/i18n/nfsubs.cpp @@ -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(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); diff --git a/icu4c/source/i18n/number_decimalquantity.cpp b/icu4c/source/i18n/number_decimalquantity.cpp index 1a3e258384e..8b369547aef 100644 --- a/icu4c/source/i18n/number_decimalquantity.cpp +++ b/icu4c/source/i18n/number_decimalquantity.cpp @@ -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'); diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index c917aad1764..b8240e7f401 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -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)) { diff --git a/icu4c/source/i18n/plurfmt.cpp b/icu4c/source/i18n/plurfmt.cpp index a8fd24d1766..eb8b5d88a8f 100644 --- a/icu4c/source/i18n/plurfmt.cpp +++ b/icu4c/source/i18n/plurfmt.cpp @@ -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(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(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); diff --git a/icu4c/source/i18n/rbnf.cpp b/icu4c/source/i18n/rbnf.cpp index 3cc208585f6..68bbf1ab17e 100644 --- a/icu4c/source/i18n/rbnf.cpp +++ b/icu4c/source/i18n/rbnf.cpp @@ -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. diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index c1c194cfb1d..8e75246e2e0 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -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() + ")"); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java index b5fac765261..72ab98e4e31 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java @@ -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)) { diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java b/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java index 15ca301ed8c..e2a992bc45d 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java @@ -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);