diff --git a/icu4c/source/i18n/number_formatimpl.cpp b/icu4c/source/i18n/number_formatimpl.cpp index a7f162ecc6..08b833beb7 100644 --- a/icu4c/source/i18n/number_formatimpl.cpp +++ b/icu4c/source/i18n/number_formatimpl.cpp @@ -172,9 +172,8 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, // Pre-compute a few values for efficiency. bool isCurrency = utils::unitIsCurrency(macros.unit); bool isNoUnit = utils::unitIsNoUnit(macros.unit); - bool isPercent = isNoUnit && utils::unitIsPercent(macros.unit); - bool isPermille = isNoUnit && utils::unitIsPermille(macros.unit); - bool isCldrUnit = !isCurrency && !isNoUnit; + bool isPercent = utils::unitIsPercent(macros.unit); + bool isPermille = utils::unitIsPermille(macros.unit); bool isAccounting = macros.sign == UNUM_SIGN_ACCOUNTING || macros.sign == UNUM_SIGN_ACCOUNTING_ALWAYS || macros.sign == UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO; @@ -194,6 +193,8 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, if (macros.unitWidth != UNUM_UNIT_WIDTH_COUNT) { unitWidth = macros.unitWidth; } + bool isCldrUnit = !isCurrency && !isNoUnit && + (unitWidth == UNUM_UNIT_WIDTH_FULL_NAME || !(isPercent || isPermille)); // Select the numbering system. LocalPointer nsLocal; @@ -243,7 +244,9 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, } if (pattern == nullptr) { CldrPatternStyle patternStyle; - if (isPercent || isPermille) { + if (isCldrUnit) { + patternStyle = CLDR_PATTERN_STYLE_DECIMAL; + } else if (isPercent || isPermille) { patternStyle = CLDR_PATTERN_STYLE_PERCENT; } else if (!isCurrency || unitWidth == UNUM_UNIT_WIDTH_FULL_NAME) { patternStyle = CLDR_PATTERN_STYLE_DECIMAL; diff --git a/icu4c/source/test/intltest/numbertest.h b/icu4c/source/test/intltest/numbertest.h index 35463612e0..c07fe9e37e 100644 --- a/icu4c/source/test/intltest/numbertest.h +++ b/icu4c/source/test/intltest/numbertest.h @@ -56,6 +56,7 @@ class NumberFormatterApiTest : public IntlTestWithFieldPosition { void unitCompoundMeasure(); void unitCurrency(); void unitPercent(); + void percentParity(); void roundingFraction(); void roundingFigures(); void roundingFractionFigures(); diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp index 4e6f7f5d74..2d925eee5b 100644 --- a/icu4c/source/test/intltest/numbertest_api.cpp +++ b/icu4c/source/test/intltest/numbertest_api.cpp @@ -70,6 +70,10 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha TESTCASE_AUTO(unitCompoundMeasure); TESTCASE_AUTO(unitCurrency); TESTCASE_AUTO(unitPercent); + if (!quick) { + // Slow test: run in exhaustive mode only + TESTCASE_AUTO(percentParity); + } TESTCASE_AUTO(roundingFraction); TESTCASE_AUTO(roundingFigures); TESTCASE_AUTO(roundingFractionFigures); @@ -89,7 +93,11 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha TESTCASE_AUTO(fieldPositionCoverage); TESTCASE_AUTO(toFormat); TESTCASE_AUTO(errors); - TESTCASE_AUTO(validRanges); + if (!quick) { + // Slow test: run in exhaustive mode only + // (somewhat slow to check all permutations of settings) + TESTCASE_AUTO(validRanges); + } TESTCASE_AUTO(copyMove); TESTCASE_AUTO(localPointerCAPI); TESTCASE_AUTO(toObject); @@ -830,6 +838,33 @@ void NumberFormatterApiTest::unitPercent() { u"-98.765432%"); } +void NumberFormatterApiTest::percentParity() { + IcuTestErrorCode status(*this, "percentParity"); + UnlocalizedNumberFormatter uNoUnitPercent = NumberFormatter::with().unit(NoUnit::percent()); + UnlocalizedNumberFormatter uNoUnitPermille = NumberFormatter::with().unit(NoUnit::permille()); + UnlocalizedNumberFormatter uMeasurePercent = NumberFormatter::with().unit(MeasureUnit::getPercent()); + UnlocalizedNumberFormatter uMeasurePermille = NumberFormatter::with().unit(MeasureUnit::getPermille()); + + int32_t localeCount; + auto locales = Locale::getAvailableLocales(localeCount); + for (int32_t i=0; i