From 3574a63853748b1789082a7f3406825a38437f37 Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Sat, 24 Mar 2018 08:06:34 +0000 Subject: [PATCH] ICU-8610 API test is passing with the skeletons in C++. :) X-SVN-Rev: 41154 --- icu4c/source/i18n/number_rounding.cpp | 1 + icu4c/source/i18n/number_skeletons.cpp | 27 ++++++++++++++++--- icu4c/source/i18n/number_skeletons.h | 3 ++- icu4c/source/test/intltest/numbertest_api.cpp | 4 +-- .../test/number/NumberFormatterApiTest.java | 6 ++--- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/icu4c/source/i18n/number_rounding.cpp b/icu4c/source/i18n/number_rounding.cpp index 5f794228dbc..80120261e1c 100644 --- a/icu4c/source/i18n/number_rounding.cpp +++ b/icu4c/source/i18n/number_rounding.cpp @@ -251,6 +251,7 @@ IncrementRounder Rounder::constructIncrement(double increment, int32_t minFrac) settings.fIncrement = increment; settings.fMinFrac = static_cast(minFrac); // One of the few pre-computed quantities: + // Note: it is possible for minFrac to be more than maxFrac... (misleading) settings.fMaxFrac = roundingutils::doubleFractionLength(increment); RounderUnion union_; union_.increment = settings; diff --git a/icu4c/source/i18n/number_skeletons.cpp b/icu4c/source/i18n/number_skeletons.cpp index 357c443455e..0958d95c554 100644 --- a/icu4c/source/i18n/number_skeletons.cpp +++ b/icu4c/source/i18n/number_skeletons.cpp @@ -1055,15 +1055,32 @@ void blueprint_helpers::parseIncrementOption(const StringSegment& segment, Macro return; } double increment = dq.toDouble(); - macros.rounder = Rounder::increment(increment); + + // We also need to figure out how many digits. Do a brute force string operation. + int decimalOffset = 0; + while (decimalOffset < segment.length() && segment.charAt(decimalOffset) != '.') { + decimalOffset++; + } + if (decimalOffset == segment.length()) { + macros.rounder = Rounder::increment(increment); + } else { + int32_t fractionLength = segment.length() - decimalOffset - 1; + macros.rounder = Rounder::increment(increment).withMinFraction(fractionLength); + } } -void blueprint_helpers::generateIncrementOption(double increment, UnicodeString& sb, UErrorCode&) { +void blueprint_helpers::generateIncrementOption(double increment, int32_t trailingZeros, UnicodeString& sb, + UErrorCode&) { // Utilize DecimalQuantity/double_conversion to format this for us. DecimalQuantity dq; dq.setToDouble(increment); dq.roundToInfinity(); sb.append(dq.toPlainString()); + + // We might need to append extra trailing zeros for min fraction... + if (trailingZeros > 0) { + appendMultiple(sb, u'0', trailingZeros); + } } bool @@ -1257,7 +1274,11 @@ bool GeneratorHelpers::rounding(const MacroProps& macros, UnicodeString& sb, UEr } else if (macros.rounder.fType == Rounder::RND_INCREMENT) { const Rounder::IncrementSettings& impl = macros.rounder.fUnion.increment; sb.append(u"round-increment/", -1); - blueprint_helpers::generateIncrementOption(impl.fIncrement, sb, status); + blueprint_helpers::generateIncrementOption( + impl.fIncrement, + impl.fMinFrac - impl.fMaxFrac, + sb, + status); } else if (macros.rounder.fType == Rounder::RND_CURRENCY) { UCurrencyUsage usage = macros.rounder.fUnion.currencyUsage; if (usage == UCURR_USAGE_STANDARD) { diff --git a/icu4c/source/i18n/number_skeletons.h b/icu4c/source/i18n/number_skeletons.h index 6a15d9efb40..aeae63f4d9f 100644 --- a/icu4c/source/i18n/number_skeletons.h +++ b/icu4c/source/i18n/number_skeletons.h @@ -222,7 +222,8 @@ bool parseFracSigOption(const StringSegment& segment, MacroProps& macros, UError void parseIncrementOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); -void generateIncrementOption(double increment, UnicodeString& sb, UErrorCode& status); +void +generateIncrementOption(double increment, int32_t trailingZeros, UnicodeString& sb, UErrorCode& status); /** @return Whether we successfully found and parsed a rounding mode. */ bool parseRoundingModeOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp index fd9872dd990..9fe790cd4a6 100644 --- a/icu4c/source/test/intltest/numbertest_api.cpp +++ b/icu4c/source/test/intltest/numbertest_api.cpp @@ -528,7 +528,7 @@ void NumberFormatterApiTest::unitMeasure() { assertFormatSingle( u"MeasureUnit form without {0} in CLDR pattern and wide base form", - u"measure-unit/temperature-kelvin .0000000000 unit-width-full-name", + u"measure-unit/temperature-kelvin .00000000000000000000 unit-width-full-name", NumberFormatter::with().rounding(Rounder::fixedFraction(20)) .unit(KELVIN) .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), @@ -1761,8 +1761,8 @@ void NumberFormatterApiTest::sign() { u"$444,444.00"); assertFormatSingle( - u"currency/USD sign-accounting", u"Sign Accounting Negative", + u"currency/USD sign-accounting", NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING).unit(USD), Locale::getEnglish(), -444444, diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java index 968f7a13a53..fad64604d95 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java @@ -502,9 +502,9 @@ public class NumberFormatterApiTest { assertFormatSingle( "MeasureUnit form without {0} in CLDR pattern and wide base form", - "measure-unit/temperature-kelvin .0000000000 unit-width-full-name", + "measure-unit/temperature-kelvin .00000000000000000000 unit-width-full-name", NumberFormatter.with() - .rounding(Rounder.fixedFraction(10)) + .rounding(Rounder.fixedFraction(20)) .unit(MeasureUnit.KELVIN) .unitWidth(UnitWidth.FULL_NAME), ULocale.forLanguageTag("es-MX"), @@ -515,7 +515,7 @@ public class NumberFormatterApiTest { @Test public void unitCompoundMeasure() { assertFormatDescending( - "Meters Per Second Short (unit that simplifies)", + "Meters Per Second Short (unit that simplifies) and perUnit method", "measure-unit/length-meter per-measure-unit/duration-second", NumberFormatter.with().unit(MeasureUnit.METER).perUnit(MeasureUnit.SECOND), ULocale.ENGLISH, -- 2.40.0