diff --git a/icu4c/source/i18n/number_fluent.cpp b/icu4c/source/i18n/number_fluent.cpp index 0a559b445e5..a22ab4de8ce 100644 --- a/icu4c/source/i18n/number_fluent.cpp +++ b/icu4c/source/i18n/number_fluent.cpp @@ -234,16 +234,16 @@ Derived NumberFormatterSettings::decimal(const UNumberDecimalSeparatorD } template -Derived NumberFormatterSettings::multiplier(const Multiplier& multiplier) const& { +Derived NumberFormatterSettings::scale(const Scale& scale) const& { Derived copy(*this); - copy.fMacros.multiplier = multiplier; + copy.fMacros.scale = scale; return copy; } template -Derived NumberFormatterSettings::multiplier(const Multiplier& multiplier)&& { +Derived NumberFormatterSettings::scale(const Scale& scale)&& { Derived move(std::move(*this)); - move.fMacros.multiplier = multiplier; + move.fMacros.scale = scale; return move; } diff --git a/icu4c/source/i18n/number_formatimpl.cpp b/icu4c/source/i18n/number_formatimpl.cpp index f198187921c..885fd3fd3b1 100644 --- a/icu4c/source/i18n/number_formatimpl.cpp +++ b/icu4c/source/i18n/number_formatimpl.cpp @@ -223,9 +223,9 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, /// START POPULATING THE DEFAULT MICROPROPS AND BUILDING THE MICROPROPS GENERATOR /// ///////////////////////////////////////////////////////////////////////////////////// - // Multiplier (compatibility mode value). - if (macros.multiplier.isValid()) { - fMicros.helpers.multiplier.setAndChain(macros.multiplier, chain); + // Multiplier + if (macros.scale.isValid()) { + fMicros.helpers.multiplier.setAndChain(macros.scale, chain); chain = &fMicros.helpers.multiplier; } diff --git a/icu4c/source/i18n/number_mapper.cpp b/icu4c/source/i18n/number_mapper.cpp index 51ebb3c0870..22fe87fc67c 100644 --- a/icu4c/source/i18n/number_mapper.cpp +++ b/icu4c/source/i18n/number_mapper.cpp @@ -257,7 +257,7 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert // MULTIPLIERS // ///////////////// - macros.multiplier = multiplierFromProperties(properties); + macros.scale = scaleFromProperties(properties); ////////////////////// // PROPERTY EXPORTS // diff --git a/icu4c/source/i18n/number_multiplier.cpp b/icu4c/source/i18n/number_multiplier.cpp index 10e5508b556..ccce71a33b4 100644 --- a/icu4c/source/i18n/number_multiplier.cpp +++ b/icu4c/source/i18n/number_multiplier.cpp @@ -21,7 +21,7 @@ using namespace icu::number::impl; using namespace icu::numparse::impl; -Multiplier::Multiplier(int32_t magnitude, DecNum* arbitraryToAdopt) +Scale::Scale(int32_t magnitude, DecNum* arbitraryToAdopt) : fMagnitude(magnitude), fArbitrary(arbitraryToAdopt), fError(U_ZERO_ERROR) { if (fArbitrary != nullptr) { // Attempt to convert the DecNum to a magnitude multiplier. @@ -29,14 +29,14 @@ Multiplier::Multiplier(int32_t magnitude, DecNum* arbitraryToAdopt) if (fArbitrary->getRawDecNumber()->digits == 1 && fArbitrary->getRawDecNumber()->lsu[0] == 1 && !fArbitrary->isNegative()) { // Success! - fMagnitude = fArbitrary->getRawDecNumber()->exponent; + fMagnitude += fArbitrary->getRawDecNumber()->exponent; delete fArbitrary; fArbitrary = nullptr; } } } -Multiplier::Multiplier(const Multiplier& other) +Scale::Scale(const Scale& other) : fMagnitude(other.fMagnitude), fArbitrary(nullptr), fError(other.fError) { if (other.fArbitrary != nullptr) { UErrorCode localStatus = U_ZERO_ERROR; @@ -44,7 +44,7 @@ Multiplier::Multiplier(const Multiplier& other) } } -Multiplier& Multiplier::operator=(const Multiplier& other) { +Scale& Scale::operator=(const Scale& other) { fMagnitude = other.fMagnitude; if (other.fArbitrary != nullptr) { UErrorCode localStatus = U_ZERO_ERROR; @@ -56,13 +56,13 @@ Multiplier& Multiplier::operator=(const Multiplier& other) { return *this; } -Multiplier::Multiplier(Multiplier&& src) U_NOEXCEPT +Scale::Scale(Scale&& src) U_NOEXCEPT : fMagnitude(src.fMagnitude), fArbitrary(src.fArbitrary), fError(src.fError) { // Take ownership away from src if necessary src.fArbitrary = nullptr; } -Multiplier& Multiplier::operator=(Multiplier&& src) U_NOEXCEPT { +Scale& Scale::operator=(Scale&& src) U_NOEXCEPT { fMagnitude = src.fMagnitude; fArbitrary = src.fArbitrary; fError = src.fError; @@ -71,20 +71,20 @@ Multiplier& Multiplier::operator=(Multiplier&& src) U_NOEXCEPT { return *this; } -Multiplier::~Multiplier() { +Scale::~Scale() { delete fArbitrary; } -Multiplier Multiplier::none() { +Scale Scale::none() { return {0, nullptr}; } -Multiplier Multiplier::powerOfTen(int32_t power) { +Scale Scale::powerOfTen(int32_t power) { return {power, nullptr}; } -Multiplier Multiplier::arbitraryDecimal(StringPiece multiplicand) { +Scale Scale::byDecimal(StringPiece multiplicand) { UErrorCode localError = U_ZERO_ERROR; LocalPointer decnum(new DecNum(), localError); if (U_FAILURE(localError)) { @@ -97,7 +97,7 @@ Multiplier Multiplier::arbitraryDecimal(StringPiece multiplicand) { return {0, decnum.orphan()}; } -Multiplier Multiplier::arbitraryDouble(double multiplicand) { +Scale Scale::byDouble(double multiplicand) { UErrorCode localError = U_ZERO_ERROR; LocalPointer decnum(new DecNum(), localError); if (U_FAILURE(localError)) { @@ -110,7 +110,20 @@ Multiplier Multiplier::arbitraryDouble(double multiplicand) { return {0, decnum.orphan()}; } -void Multiplier::applyTo(impl::DecimalQuantity& quantity) const { +Scale Scale::byDoubleAndPowerOfTen(double multiplicand, int32_t power) { + UErrorCode localError = U_ZERO_ERROR; + LocalPointer decnum(new DecNum(), localError); + if (U_FAILURE(localError)) { + return {localError}; + } + decnum->setTo(multiplicand, localError); + if (U_FAILURE(localError)) { + return {localError}; + } + return {power, decnum.orphan()}; +} + +void Scale::applyTo(impl::DecimalQuantity& quantity) const { quantity.adjustMagnitude(fMagnitude); if (fArbitrary != nullptr) { UErrorCode localStatus = U_ZERO_ERROR; @@ -118,7 +131,7 @@ void Multiplier::applyTo(impl::DecimalQuantity& quantity) const { } } -void Multiplier::applyReciprocalTo(impl::DecimalQuantity& quantity) const { +void Scale::applyReciprocalTo(impl::DecimalQuantity& quantity) const { quantity.adjustMagnitude(-fMagnitude); if (fArbitrary != nullptr) { UErrorCode localStatus = U_ZERO_ERROR; @@ -128,7 +141,7 @@ void Multiplier::applyReciprocalTo(impl::DecimalQuantity& quantity) const { void -MultiplierFormatHandler::setAndChain(const Multiplier& multiplier, const MicroPropsGenerator* parent) { +MultiplierFormatHandler::setAndChain(const Scale& multiplier, const MicroPropsGenerator* parent) { this->multiplier = multiplier; this->parent = parent; } @@ -141,7 +154,7 @@ void MultiplierFormatHandler::processQuantity(DecimalQuantity& quantity, MicroPr // NOTE: MultiplierParseHandler is declared in the header numparse_validators.h -MultiplierParseHandler::MultiplierParseHandler(::icu::number::Multiplier multiplier) +MultiplierParseHandler::MultiplierParseHandler(::icu::number::Scale multiplier) : fMultiplier(std::move(multiplier)) {} void MultiplierParseHandler::postProcess(ParsedNumber& result) const { @@ -152,7 +165,7 @@ void MultiplierParseHandler::postProcess(ParsedNumber& result) const { } UnicodeString MultiplierParseHandler::toString() const { - return u""; + return u""; } diff --git a/icu4c/source/i18n/number_multiplier.h b/icu4c/source/i18n/number_multiplier.h index 6baa6865916..b31be8ed617 100644 --- a/icu4c/source/i18n/number_multiplier.h +++ b/icu4c/source/i18n/number_multiplier.h @@ -19,25 +19,29 @@ namespace impl { */ class MultiplierFormatHandler : public MicroPropsGenerator, public UMemory { public: - void setAndChain(const Multiplier& multiplier, const MicroPropsGenerator* parent); + void setAndChain(const Scale& multiplier, const MicroPropsGenerator* parent); void processQuantity(DecimalQuantity& quantity, MicroProps& micros, UErrorCode& status) const U_OVERRIDE; private: - Multiplier multiplier; + Scale multiplier; const MicroPropsGenerator *parent; }; -/** Gets a Multiplier from a DecimalFormatProperties. In Java, defined in RoundingUtils.java */ -static inline Multiplier multiplierFromProperties(const DecimalFormatProperties& properties) { - if (properties.magnitudeMultiplier != 0) { - return Multiplier::powerOfTen(properties.magnitudeMultiplier); - } else if (properties.multiplier != 1) { - return Multiplier::arbitraryDouble(properties.multiplier); +/** Gets a Scale from a DecimalFormatProperties. In Java, defined in RoundingUtils.java */ +static inline Scale scaleFromProperties(const DecimalFormatProperties& properties) { + int32_t magnitudeMultiplier = properties.magnitudeMultiplier + properties.scaleMultiplier; + int32_t arbitraryMultiplier = properties.multiplier; + if (magnitudeMultiplier != 0 && arbitraryMultiplier != 1) { + return Scale::byDoubleAndPowerOfTen(arbitraryMultiplier, magnitudeMultiplier); + } else if (magnitudeMultiplier != 0) { + return Scale::powerOfTen(magnitudeMultiplier); + } else if (arbitraryMultiplier != 1) { + return Scale::byDouble(arbitraryMultiplier); } else { - return Multiplier::none(); + return Scale::none(); } } diff --git a/icu4c/source/i18n/number_skeletons.cpp b/icu4c/source/i18n/number_skeletons.cpp index 35de1358cd0..ed97025b3a3 100644 --- a/icu4c/source/i18n/number_skeletons.cpp +++ b/icu4c/source/i18n/number_skeletons.cpp @@ -85,7 +85,7 @@ void U_CALLCONV initNumberSkeletons(UErrorCode& status) { b.add(u"currency", STEM_CURRENCY, status); b.add(u"integer-width", STEM_INTEGER_WIDTH, status); b.add(u"numbering-system", STEM_NUMBERING_SYSTEM, status); - b.add(u"multiply", STEM_MULTIPLY, status); + b.add(u"scale", STEM_SCALE, status); if (U_FAILURE(status)) { return; } // Build the CharsTrie @@ -444,7 +444,7 @@ MacroProps skeleton::parseSkeleton(const UnicodeString& skeletonString, UErrorCo case STATE_CURRENCY_UNIT: case STATE_INTEGER_WIDTH: case STATE_NUMBERING_SYSTEM: - case STATE_MULTIPLY: + case STATE_SCALE: // segment.setLength(U16_LENGTH(cp)); // for error message // throw new SkeletonSyntaxException("Stem requires an option", segment); status = U_NUMBER_SKELETON_SYNTAX_ERROR; @@ -594,9 +594,9 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se CHECK_NULL(seen, symbols, status); return STATE_NUMBERING_SYSTEM; - case STEM_MULTIPLY: - CHECK_NULL(seen, multiplier, status); - return STATE_MULTIPLY; + case STEM_SCALE: + CHECK_NULL(seen, scale, status); + return STATE_SCALE; default: U_ASSERT(false); @@ -627,8 +627,8 @@ ParseState skeleton::parseOption(ParseState stem, const StringSegment& segment, case STATE_NUMBERING_SYSTEM: blueprint_helpers::parseNumberingSystemOption(segment, macros, status); return STATE_NULL; - case STATE_MULTIPLY: - blueprint_helpers::parseMultiplierOption(segment, macros, status); + case STATE_SCALE: + blueprint_helpers::parseScaleOption(segment, macros, status); return STATE_NULL; default: break; @@ -721,7 +721,7 @@ void GeneratorHelpers::generateSkeleton(const MacroProps& macros, UnicodeString& sb.append(u' '); } if (U_FAILURE(status)) { return; } - if (GeneratorHelpers::multiplier(macros, sb, status)) { + if (GeneratorHelpers::scale(macros, sb, status)) { sb.append(u' '); } if (U_FAILURE(status)) { return; } @@ -1184,7 +1184,7 @@ void blueprint_helpers::generateNumberingSystemOption(const NumberingSystem& ns, sb.append(UnicodeString(ns.getName(), -1, US_INV)); } -void blueprint_helpers::parseMultiplierOption(const StringSegment& segment, MacroProps& macros, +void blueprint_helpers::parseScaleOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status) { // Need to do char <-> UChar conversion... CharString buffer; @@ -1199,11 +1199,11 @@ void blueprint_helpers::parseMultiplierOption(const StringSegment& segment, Macr } // NOTE: The constructor will optimize the decnum for us if possible. - macros.multiplier = {0, decnum.orphan()}; + macros.scale = {0, decnum.orphan()}; } void -blueprint_helpers::generateMultiplierOption(int32_t magnitude, const DecNum* arbitrary, UnicodeString& sb, +blueprint_helpers::generateScaleOption(int32_t magnitude, const DecNum* arbitrary, UnicodeString& sb, UErrorCode& status) { // Utilize DecimalQuantity/double_conversion to format this for us. DecimalQuantity dq; @@ -1418,14 +1418,14 @@ bool GeneratorHelpers::decimal(const MacroProps& macros, UnicodeString& sb, UErr return true; } -bool GeneratorHelpers::multiplier(const MacroProps& macros, UnicodeString& sb, UErrorCode& status) { - if (!macros.multiplier.isValid()) { +bool GeneratorHelpers::scale(const MacroProps& macros, UnicodeString& sb, UErrorCode& status) { + if (!macros.scale.isValid()) { return false; // Default or Bogus } - sb.append(u"multiply/", -1); - blueprint_helpers::generateMultiplierOption( - macros.multiplier.fMagnitude, - macros.multiplier.fArbitrary, + sb.append(u"scale/", -1); + blueprint_helpers::generateScaleOption( + macros.scale.fMagnitude, + macros.scale.fArbitrary, sb, status); return true; diff --git a/icu4c/source/i18n/number_skeletons.h b/icu4c/source/i18n/number_skeletons.h index b3e7287f543..3510aa2b801 100644 --- a/icu4c/source/i18n/number_skeletons.h +++ b/icu4c/source/i18n/number_skeletons.h @@ -50,7 +50,7 @@ enum ParseState { STATE_CURRENCY_UNIT, STATE_INTEGER_WIDTH, STATE_NUMBERING_SYSTEM, - STATE_MULTIPLY, + STATE_SCALE, }; /** @@ -105,7 +105,7 @@ enum StemEnum { STEM_CURRENCY, STEM_INTEGER_WIDTH, STEM_NUMBERING_SYSTEM, - STEM_MULTIPLY, + STEM_SCALE, }; /** @@ -243,9 +243,9 @@ void parseNumberingSystemOption(const StringSegment& segment, MacroProps& macros void generateNumberingSystemOption(const NumberingSystem& ns, UnicodeString& sb, UErrorCode& status); -void parseMultiplierOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); +void parseScaleOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); -void generateMultiplierOption(int32_t magnitude, const DecNum* arbitrary, UnicodeString& sb, +void generateScaleOption(int32_t magnitude, const DecNum* arbitrary, UnicodeString& sb, UErrorCode& status); } // namespace blueprint_helpers @@ -287,7 +287,7 @@ class GeneratorHelpers { static bool decimal(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); - static bool multiplier(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); + static bool scale(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); }; @@ -307,7 +307,7 @@ struct SeenMacroProps { bool unitWidth = false; bool sign = false; bool decimal = false; - bool multiplier = false; + bool scale = false; }; } // namespace impl diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index 25be60726d4..547ba6b55dd 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -203,7 +203,7 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr parser->addMatcher(parser->fLocalValidators.decimalSeparator = {patternHasDecimalSeparator}); } // The multiplier takes care of scaling percentages. - Multiplier multiplier = multiplierFromProperties(properties); + Scale multiplier = scaleFromProperties(properties); if (multiplier.isValid()) { parser->addMatcher(parser->fLocalValidators.multiplier = {multiplier}); } diff --git a/icu4c/source/i18n/numparse_validators.h b/icu4c/source/i18n/numparse_validators.h index d3bc63aceb3..21acb625a57 100644 --- a/icu4c/source/i18n/numparse_validators.h +++ b/icu4c/source/i18n/numparse_validators.h @@ -86,14 +86,14 @@ class MultiplierParseHandler : public ValidationMatcher, public UMemory { public: MultiplierParseHandler() = default; // leaves instance in valid but undefined state - MultiplierParseHandler(::icu::number::Multiplier multiplier); + MultiplierParseHandler(::icu::number::Scale multiplier); void postProcess(ParsedNumber& result) const U_OVERRIDE; UnicodeString toString() const U_OVERRIDE; private: - ::icu::number::Multiplier fMultiplier; + ::icu::number::Scale fMultiplier; }; diff --git a/icu4c/source/i18n/unicode/numberformatter.h b/icu4c/source/i18n/unicode/numberformatter.h index bf4b1a7a152..897e4c45eb9 100644 --- a/icu4c/source/i18n/unicode/numberformatter.h +++ b/icu4c/source/i18n/unicode/numberformatter.h @@ -970,31 +970,31 @@ class U_I18N_API IntegerWidth : public UMemory { * A class that defines a quantity by which a number should be multiplied when formatting. * *

- * To create a Multiplier, use one of the factory methods. + * To create a Scale, use one of the factory methods. * * @draft ICU 62 */ -class U_I18N_API Multiplier : public UMemory { +class U_I18N_API Scale : public UMemory { public: /** * Do not change the value of numbers when formatting or parsing. * - * @return A Multiplier to prevent any multiplication. + * @return A Scale to prevent any multiplication. * @draft ICU 62 */ - static Multiplier none(); + static Scale none(); /** - * Multiply numbers by 100 before formatting. Useful for combining with a percent unit: + * Multiply numbers by a power of ten before formatting. Useful for combining with a percent unit: * *

-     * NumberFormatter::with().unit(NoUnit::percent()).multiplier(Multiplier::powerOfTen(2))
+     * NumberFormatter::with().unit(NoUnit::percent()).multiplier(Scale::powerOfTen(2))
      * 
* - * @return A Multiplier for passing to the setter in NumberFormatter. + * @return A Scale for passing to the setter in NumberFormatter. * @draft ICU 62 */ - static Multiplier powerOfTen(int32_t power); + static Scale powerOfTen(int32_t power); /** * Multiply numbers by an arbitrary value before formatting. Useful for unit conversions. @@ -1005,50 +1005,58 @@ class U_I18N_API Multiplier : public UMemory { * * Also see the version of this method that takes a double. * - * @return A Multiplier for passing to the setter in NumberFormatter. + * @return A Scale for passing to the setter in NumberFormatter. * @draft ICU 62 */ - static Multiplier arbitraryDecimal(StringPiece multiplicand); + static Scale byDecimal(StringPiece multiplicand); /** * Multiply numbers by an arbitrary value before formatting. Useful for unit conversions. * * This method takes a double; also see the version of this method that takes an exact decimal. * - * @return A Multiplier for passing to the setter in NumberFormatter. + * @return A Scale for passing to the setter in NumberFormatter. * @draft ICU 62 */ - static Multiplier arbitraryDouble(double multiplicand); + static Scale byDouble(double multiplicand); + + /** + * Multiply a number by both a power of ten and by an arbitrary double value. + * + * @return A Scale for passing to the setter in NumberFormatter. + * @draft ICU 62 + */ + static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power); // We need a custom destructor for the DecNum, which means we need to declare // the copy/move constructor/assignment quartet. /** @draft ICU 62 */ - Multiplier(const Multiplier& other); + Scale(const Scale& other); /** @draft ICU 62 */ - Multiplier& operator=(const Multiplier& other); + Scale& operator=(const Scale& other); /** @draft ICU 62 */ - Multiplier(Multiplier&& src) U_NOEXCEPT; + Scale(Scale&& src) U_NOEXCEPT; /** @draft ICU 62 */ - Multiplier& operator=(Multiplier&& src) U_NOEXCEPT; + Scale& operator=(Scale&& src) U_NOEXCEPT; /** @draft ICU 62 */ - ~Multiplier(); + ~Scale(); /** @internal */ - Multiplier(int32_t magnitude, impl::DecNum* arbitraryToAdopt); + Scale(int32_t magnitude, impl::DecNum* arbitraryToAdopt); private: int32_t fMagnitude; impl::DecNum* fArbitrary; UErrorCode fError; - Multiplier(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {} + Scale(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {} - Multiplier() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {} + Scale() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {} bool isValid() const { return fMagnitude != 0 || fArbitrary != nullptr; @@ -1364,7 +1372,7 @@ struct U_I18N_API MacroProps : public UMemory { UNumberDecimalSeparatorDisplay decimal = UNUM_DECIMAL_SEPARATOR_COUNT; /** @internal */ - Multiplier multiplier; // = Multiplier(); (benign value) + Scale scale; // = Scale(); (benign value) /** @internal */ AffixPatternProvider* affixProvider = nullptr; // no ownership @@ -1390,7 +1398,7 @@ struct U_I18N_API MacroProps : public UMemory { bool copyErrorTo(UErrorCode &status) const { return notation.copyErrorTo(status) || rounder.copyErrorTo(status) || padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) || - symbols.copyErrorTo(status) || multiplier.copyErrorTo(status); + symbols.copyErrorTo(status) || scale.copyErrorTo(status); } }; @@ -1926,8 +1934,8 @@ class U_I18N_API NumberFormatterSettings { Derived decimal(const UNumberDecimalSeparatorDisplay &style) &&; /** - * Sets a multiplier to be used to scale the number by an arbitrary amount before formatting. Most - * common values: + * Sets a scale (multiplier) to be used to scale the number by an arbitrary amount before formatting. + * Most common values: * *
    *
  • Multiply by 100: useful for percentages. @@ -1935,32 +1943,32 @@ class U_I18N_API NumberFormatterSettings { *
* *

- * Pass an element from a {@link Multiplier} factory method to this setter. For example: + * Pass an element from a {@link Scale} factory method to this setter. For example: * *

-     * NumberFormatter::with().multiplier(Multiplier::powerOfTen(2))
+     * NumberFormatter::with().scale(Scale::powerOfTen(2))
      * 
* *

* The default is to not apply any multiplier. * - * @param style - * The decimal separator display strategy to use when rendering numbers. + * @param scale + * The scale to apply when rendering numbers. * @return The fluent chain * @draft ICU 60 */ - Derived multiplier(const Multiplier &style) const &; + Derived scale(const Scale &scale) const &; /** - * Overload of multiplier() for use on an rvalue reference. + * Overload of scale() for use on an rvalue reference. * - * @param style - * The multiplier separator display strategy to use when rendering numbers. + * @param scale + * The scale to apply when rendering numbers. * @return The fluent chain. - * @see #multiplier + * @see #scale * @draft ICU 62 */ - Derived multiplier(const Multiplier &style) &&; + Derived scale(const Scale &scale) &&; #ifndef U_HIDE_INTERNAL_API diff --git a/icu4c/source/test/intltest/numbertest.h b/icu4c/source/test/intltest/numbertest.h index a3678d5913a..fdb892a0fc9 100644 --- a/icu4c/source/test/intltest/numbertest.h +++ b/icu4c/source/test/intltest/numbertest.h @@ -64,7 +64,7 @@ class NumberFormatterApiTest : public IntlTest { //void symbolsOverride(); void sign(); void decimal(); - void multiplier(); + void scale(); void locale(); void formatTypes(); void errors(); diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp index ca759183115..d81a1cf1333 100644 --- a/icu4c/source/test/intltest/numbertest_api.cpp +++ b/icu4c/source/test/intltest/numbertest_api.cpp @@ -78,7 +78,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha //TESTCASE_AUTO(symbolsOverride); TESTCASE_AUTO(sign); TESTCASE_AUTO(decimal); - TESTCASE_AUTO(multiplier); + TESTCASE_AUTO(scale); TESTCASE_AUTO(locale); TESTCASE_AUTO(formatTypes); TESTCASE_AUTO(errors); @@ -1911,11 +1911,11 @@ void NumberFormatterApiTest::decimal() { u"0."); } -void NumberFormatterApiTest::multiplier() { +void NumberFormatterApiTest::scale() { assertFormatDescending( u"Multiplier None", - u"multiply/1", - NumberFormatter::with().multiplier(Multiplier::none()), + u"scale/1", + NumberFormatter::with().scale(Scale::none()), Locale::getEnglish(), u"87,650", u"8,765", @@ -1929,8 +1929,8 @@ void NumberFormatterApiTest::multiplier() { assertFormatDescending( u"Multiplier Power of Ten", - u"multiply/1000000", - NumberFormatter::with().multiplier(Multiplier::powerOfTen(6)), + u"scale/1000000", + NumberFormatter::with().scale(Scale::powerOfTen(6)), Locale::getEnglish(), u"87,650,000,000", u"8,765,000,000", @@ -1944,8 +1944,8 @@ void NumberFormatterApiTest::multiplier() { assertFormatDescending( u"Multiplier Arbitrary Double", - u"multiply/5.2", - NumberFormatter::with().multiplier(Multiplier::arbitraryDouble(5.2)), + u"scale/5.2", + NumberFormatter::with().scale(Scale::byDouble(5.2)), Locale::getEnglish(), u"455,780", u"45,578", @@ -1959,8 +1959,8 @@ void NumberFormatterApiTest::multiplier() { assertFormatDescending( u"Multiplier Arbitrary BigDecimal", - u"multiply/5.2", - NumberFormatter::with().multiplier(Multiplier::arbitraryDecimal({"5.2", -1})), + u"scale/5.2", + NumberFormatter::with().scale(Scale::byDecimal({"5.2", -1})), Locale::getEnglish(), u"455,780", u"45,578", @@ -1972,10 +1972,25 @@ void NumberFormatterApiTest::multiplier() { u"0.045578", u"0"); + assertFormatDescending( + u"Multiplier Arbitrary Double And Power Of Ten", + u"scale/5200", + NumberFormatter::with().scale(Scale::byDoubleAndPowerOfTen(5.2, 3)), + Locale::getEnglish(), + u"455,780,000", + u"45,578,000", + u"4,557,800", + u"455,780", + u"45,578", + u"4,557.8", + u"455.78", + u"45.578", + u"0"); + assertFormatDescending( u"Multiplier Zero", - u"multiply/0", - NumberFormatter::with().multiplier(Multiplier::arbitraryDouble(0)), + u"scale/0", + NumberFormatter::with().scale(Scale::byDouble(0)), Locale::getEnglish(), u"0", u"0", @@ -1989,27 +2004,35 @@ void NumberFormatterApiTest::multiplier() { assertFormatSingle( u"Multiplier Skeleton Scientific Notation and Percent", - u"percent multiply/1E2", - NumberFormatter::with().unit(NoUnit::percent()).multiplier(Multiplier::powerOfTen(2)), + u"percent scale/1E2", + NumberFormatter::with().unit(NoUnit::percent()).scale(Scale::powerOfTen(2)), Locale::getEnglish(), 0.5, u"50%"); assertFormatSingle( u"Negative Multiplier", - u"multiply/-5.2", - NumberFormatter::with().multiplier(Multiplier::arbitraryDouble(-5.2)), + u"scale/-5.2", + NumberFormatter::with().scale(Scale::byDouble(-5.2)), Locale::getEnglish(), 2, u"-10.4"); assertFormatSingle( u"Negative One Multiplier", - u"multiply/-1", - NumberFormatter::with().multiplier(Multiplier::arbitraryDouble(-1)), + u"scale/-1", + NumberFormatter::with().scale(Scale::byDouble(-1)), Locale::getEnglish(), 444444, u"-444,444"); + + assertFormatSingle( + u"Two-Type Multiplier with Overlap", + u"scale/10000", + NumberFormatter::with().scale(Scale::byDoubleAndPowerOfTen(100, 2)), + Locale::getEnglish(), + 2, + u"20,000"); } void NumberFormatterApiTest::locale() { diff --git a/icu4c/source/test/intltest/numbertest_skeletons.cpp b/icu4c/source/test/intltest/numbertest_skeletons.cpp index 28700b3bf9d..33de5c311b2 100644 --- a/icu4c/source/test/intltest/numbertest_skeletons.cpp +++ b/icu4c/source/test/intltest/numbertest_skeletons.cpp @@ -90,11 +90,11 @@ void NumberSkeletonTest::validTokens() { u"unit-width-hidden", u"decimal-auto", u"decimal-always", - u"multiply/5.2", - u"multiply/-5.2", - u"multiply/100", - u"multiply/1E2", - u"multiply/1", + u"scale/5.2", + u"scale/-5.2", + u"scale/100", + u"scale/1E2", + u"scale/1", u"latin", u"numbering-system/arab", u"numbering-system/latn", @@ -132,10 +132,10 @@ void NumberSkeletonTest::invalidTokens() { u"round-increment/xxx", u"round-increment/NaN", u"round-increment/0.1.2", - u"multiply/xxx", - u"multiply/NaN", - u"multiply/0.1.2", - u"multiply/français", // non-invariant characters for C++ + u"scale/xxx", + u"scale/NaN", + u"scale/0.1.2", + u"scale/français", // non-invariant characters for C++ u"currency/dummy", u"measure-unit/foo", u"integer-width/xxx", @@ -191,7 +191,7 @@ void NumberSkeletonTest::stemsRequiringOption() { u"currency", u"integer-width", u"numbering-system", - u"multiply"}; + u"scale"}; static const char16_t* suffixes[] = {u"", u"/ceiling", u" scientific", u"/ceiling scientific"}; for (auto& stem : stems) { diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MacroProps.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MacroProps.java index 47448c2bbde..9cb89879e97 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MacroProps.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MacroProps.java @@ -4,7 +4,7 @@ package com.ibm.icu.impl.number; import com.ibm.icu.impl.Utility; import com.ibm.icu.number.IntegerWidth; -import com.ibm.icu.number.Multiplier; +import com.ibm.icu.number.Scale; import com.ibm.icu.number.Notation; import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay; import com.ibm.icu.number.NumberFormatter.SignDisplay; @@ -26,7 +26,7 @@ public class MacroProps implements Cloneable { public UnitWidth unitWidth; public SignDisplay sign; public DecimalSeparatorDisplay decimal; - public Multiplier multiplier; + public Scale scale; public AffixPatternProvider affixProvider; // not in API; for JDK compatibility mode only public PluralRules rules; // not in API; could be made public in the future public Long threshold; // not in API; controls internal self-regulation threshold @@ -63,8 +63,8 @@ public class MacroProps implements Cloneable { decimal = fallback.decimal; if (affixProvider == null) affixProvider = fallback.affixProvider; - if (multiplier == null) - multiplier = fallback.multiplier; + if (scale == null) + scale = fallback.scale; if (rules == null) rules = fallback.rules; if (loc == null) @@ -85,7 +85,7 @@ public class MacroProps implements Cloneable { sign, decimal, affixProvider, - multiplier, + scale, rules, loc); } @@ -111,7 +111,7 @@ public class MacroProps implements Cloneable { && Utility.equals(sign, other.sign) && Utility.equals(decimal, other.decimal) && Utility.equals(affixProvider, other.affixProvider) - && Utility.equals(multiplier, other.multiplier) + && Utility.equals(scale, other.scale) && Utility.equals(rules, other.rules) && Utility.equals(loc, other.loc); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MultiplierFormatHandler.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MultiplierFormatHandler.java index fb7389a6311..d75cbab45f3 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MultiplierFormatHandler.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MultiplierFormatHandler.java @@ -2,16 +2,16 @@ // License & terms of use: http://www.unicode.org/copyright.html#License package com.ibm.icu.impl.number; -import com.ibm.icu.number.Multiplier; +import com.ibm.icu.number.Scale; /** - * Wraps a {@link Multiplier} for use in the number formatting pipeline. + * Wraps a {@link Scale} for use in the number formatting pipeline. */ public class MultiplierFormatHandler implements MicroPropsGenerator { - final Multiplier multiplier; + final Scale multiplier; final MicroPropsGenerator parent; - public MultiplierFormatHandler(Multiplier multiplier, MicroPropsGenerator parent) { + public MultiplierFormatHandler(Scale multiplier, MicroPropsGenerator parent) { this.multiplier = multiplier; this.parent = parent; } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/RoundingUtils.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/RoundingUtils.java index 7d9ca686c31..5921f60ff2d 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/RoundingUtils.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/RoundingUtils.java @@ -6,7 +6,7 @@ import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; -import com.ibm.icu.number.Multiplier; +import com.ibm.icu.number.Scale; /** @author sffc */ public class RoundingUtils { @@ -209,12 +209,12 @@ public class RoundingUtils { return MATH_CONTEXT_BY_ROUNDING_MODE_UNLIMITED[roundingMode.ordinal()]; } - public static Multiplier multiplierFromProperties(DecimalFormatProperties properties) { + public static Scale scaleFromProperties(DecimalFormatProperties properties) { MathContext mc = getMathContextOr34Digits(properties); if (properties.getMagnitudeMultiplier() != 0) { - return Multiplier.powerOfTen(properties.getMagnitudeMultiplier()).withMathContext(mc); + return Scale.powerOfTen(properties.getMagnitudeMultiplier()).withMathContext(mc); } else if (properties.getMultiplier() != null) { - return Multiplier.arbitrary(properties.getMultiplier()).withMathContext(mc); + return Scale.byBigDecimal(properties.getMultiplier()).withMathContext(mc); } else { return null; } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MultiplierParseHandler.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MultiplierParseHandler.java index 054cdf41c47..f0a98aea51f 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MultiplierParseHandler.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MultiplierParseHandler.java @@ -2,16 +2,16 @@ // License & terms of use: http://www.unicode.org/copyright.html#License package com.ibm.icu.impl.number.parse; -import com.ibm.icu.number.Multiplier; +import com.ibm.icu.number.Scale; /** - * Wraps a {@link Multiplier} for use in the number parsing pipeline. + * Wraps a {@link Scale} for use in the number parsing pipeline. */ public class MultiplierParseHandler extends ValidationMatcher { - private final Multiplier multiplier; + private final Scale multiplier; - public MultiplierParseHandler(Multiplier multiplier) { + public MultiplierParseHandler(Scale multiplier) { this.multiplier = multiplier; } 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 0e964ef5762..19dd535fa29 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 @@ -19,7 +19,7 @@ import com.ibm.icu.impl.number.PatternStringParser; import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo; import com.ibm.icu.impl.number.PropertiesAffixPatternProvider; import com.ibm.icu.impl.number.RoundingUtils; -import com.ibm.icu.number.Multiplier; +import com.ibm.icu.number.Scale; import com.ibm.icu.number.NumberFormatter.GroupingStrategy; import com.ibm.icu.text.DecimalFormatSymbols; import com.ibm.icu.util.Currency; @@ -250,7 +250,7 @@ public class NumberParserImpl { parser.addMatcher(RequireDecimalSeparatorValidator.getInstance(patternHasDecimalSeparator)); } // The multiplier takes care of scaling percentages. - Multiplier multiplier = RoundingUtils.multiplierFromProperties(properties); + Scale multiplier = RoundingUtils.scaleFromProperties(properties); if (multiplier != null) { parser.addMatcher(new MultiplierParseHandler(multiplier)); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterImpl.java index 91536e9beb0..7fbce25a771 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterImpl.java @@ -197,9 +197,9 @@ class NumberFormatterImpl { /// START POPULATING THE DEFAULT MICROPROPS AND BUILDING THE MICROPROPS GENERATOR /// ///////////////////////////////////////////////////////////////////////////////////// - // Multiplier (compatibility mode value). - if (macros.multiplier != null) { - chain = new MultiplierFormatHandler(macros.multiplier, chain); + // Multiplier + if (macros.scale != null) { + chain = new MultiplierFormatHandler(macros.scale, chain); } // Rounding strategy diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterSettings.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterSettings.java index 5fb86d5a10c..70cf69389c7 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterSettings.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterSettings.java @@ -39,7 +39,7 @@ public abstract class NumberFormatterSettings *

  • Multiply by 100: useful for percentages. @@ -452,24 +452,24 @@ public abstract class NumberFormatterSettings * *

    - * Pass an element from a {@link Multiplier} factory method to this setter. For example: + * Pass an element from a {@link Scale} factory method to this setter. For example: * *

    -     * NumberFormatter.with().multiplier(Multiplier.powerOfTen(2))
    +     * NumberFormatter.with().scale(Scale.powerOfTen(2))
          * 
    * *

    * The default is to not apply any multiplier. * - * @param multiplier + * @param scale * An amount to be multiplied against numbers before formatting. * @return The fluent chain - * @see Multiplier + * @see Scale * @draft ICU 62 * @provisional This API might change or be removed in a future release. */ - public T multiplier(Multiplier multiplier) { - return create(KEY_MULTIPLIER, multiplier); + public T scale(Scale scale) { + return create(KEY_SCALE, scale); } /** @@ -599,9 +599,9 @@ public abstract class NumberFormatterSettings