From ce846b6b34aace00931b6aea3382ddff0657292f Mon Sep 17 00:00:00 2001
From: Shane Carr <shane@unicode.org>
Date: Sat, 14 Apr 2018 09:45:39 +0000
Subject: [PATCH] ICU-13678 Renaming Multiplier to Scale.

X-SVN-Rev: 41231
---
 icu4c/source/i18n/number_fluent.cpp           |  8 +-
 icu4c/source/i18n/number_formatimpl.cpp       |  6 +-
 icu4c/source/i18n/number_mapper.cpp           |  2 +-
 icu4c/source/i18n/number_multiplier.cpp       | 45 +++++++----
 icu4c/source/i18n/number_multiplier.h         | 22 +++---
 icu4c/source/i18n/number_skeletons.cpp        | 34 ++++-----
 icu4c/source/i18n/number_skeletons.h          | 12 +--
 icu4c/source/i18n/numparse_impl.cpp           |  2 +-
 icu4c/source/i18n/numparse_validators.h       |  4 +-
 icu4c/source/i18n/unicode/numberformatter.h   | 76 ++++++++++---------
 icu4c/source/test/intltest/numbertest.h       |  2 +-
 icu4c/source/test/intltest/numbertest_api.cpp | 59 +++++++++-----
 .../test/intltest/numbertest_skeletons.cpp    | 20 ++---
 .../com/ibm/icu/impl/number/MacroProps.java   | 12 +--
 .../impl/number/MultiplierFormatHandler.java  |  8 +-
 .../ibm/icu/impl/number/RoundingUtils.java    |  8 +-
 .../number/parse/MultiplierParseHandler.java  |  8 +-
 .../impl/number/parse/NumberParserImpl.java   |  4 +-
 .../ibm/icu/number/NumberFormatterImpl.java   |  6 +-
 .../icu/number/NumberFormatterSettings.java   | 24 +++---
 .../ibm/icu/number/NumberPropertyMapper.java  |  2 +-
 .../ibm/icu/number/NumberSkeletonImpl.java    | 42 +++++-----
 .../number/{Multiplier.java => Scale.java}    | 44 +++++++----
 .../test/number/NumberFormatterApiTest.java   | 59 +++++++++-----
 .../dev/test/number/NumberSkeletonTest.java   | 20 ++---
 25 files changed, 306 insertions(+), 223 deletions(-)
 rename icu4j/main/classes/core/src/com/ibm/icu/number/{Multiplier.java => Scale.java} (79%)

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<Derived>::decimal(const UNumberDecimalSeparatorD
 }
 
 template<typename Derived>
-Derived NumberFormatterSettings<Derived>::multiplier(const Multiplier& multiplier) const& {
+Derived NumberFormatterSettings<Derived>::scale(const Scale& scale) const& {
     Derived copy(*this);
-    copy.fMacros.multiplier = multiplier;
+    copy.fMacros.scale = scale;
     return copy;
 }
 
 template<typename Derived>
-Derived NumberFormatterSettings<Derived>::multiplier(const Multiplier& multiplier)&& {
+Derived NumberFormatterSettings<Derived>::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> 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> 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> 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"<Multiplier>";
+    return u"<Scale>";
 }
 
 
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.
  *
  * <p>
- * 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:
      *
      * <pre>
-     * NumberFormatter::with().unit(NoUnit::percent()).multiplier(Multiplier::powerOfTen(2))
+     * NumberFormatter::with().unit(NoUnit::percent()).multiplier(Scale::powerOfTen(2))
      * </pre>
      *
-     * @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:
      *
      * <ul>
      * <li>Multiply by 100: useful for percentages.
@@ -1935,32 +1943,32 @@ class U_I18N_API NumberFormatterSettings {
      * </ul>
      *
      * <p>
-     * 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:
      *
      * <pre>
-     * NumberFormatter::with().multiplier(Multiplier::powerOfTen(2))
+     * NumberFormatter::with().scale(Scale::powerOfTen(2))
      * </pre>
      *
      * <p>
      * 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<T extends NumberFormatterSettings<
     static final int KEY_UNIT_WIDTH = 9;
     static final int KEY_SIGN = 10;
     static final int KEY_DECIMAL = 11;
-    static final int KEY_MULTIPLIER = 12;
+    static final int KEY_SCALE = 12;
     static final int KEY_THRESHOLD = 13;
     static final int KEY_PER_UNIT = 14;
     static final int KEY_MAX = 15;
@@ -443,8 +443,8 @@ public abstract class NumberFormatterSettings<T extends NumberFormatterSettings<
     }
 
     /**
-     * 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:
      *
      * <ul>
      * <li>Multiply by 100: useful for percentages.
@@ -452,24 +452,24 @@ public abstract class NumberFormatterSettings<T extends NumberFormatterSettings<
      * </ul>
      *
      * <p>
-     * 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:
      *
      * <pre>
-     * NumberFormatter.with().multiplier(Multiplier.powerOfTen(2))
+     * NumberFormatter.with().scale(Scale.powerOfTen(2))
      * </pre>
      *
      * <p>
      * 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<T extends NumberFormatterSettings<
                     macros.decimal = (DecimalSeparatorDisplay) current.value;
                 }
                 break;
-            case KEY_MULTIPLIER:
-                if (macros.multiplier == null) {
-                    macros.multiplier = (Multiplier) current.value;
+            case KEY_SCALE:
+                if (macros.scale == null) {
+                    macros.scale = (Scale) current.value;
                 }
                 break;
             case KEY_THRESHOLD:
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
index 0cbdf3c5ef7..ccc67a44109 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
@@ -298,7 +298,7 @@ final class NumberPropertyMapper {
         // MULTIPLIERS //
         /////////////////
 
-        macros.multiplier = RoundingUtils.multiplierFromProperties(properties);
+        macros.scale = RoundingUtils.scaleFromProperties(properties);
 
         //////////////////////
         // PROPERTY EXPORTS //
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberSkeletonImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberSkeletonImpl.java
index 1f855830f02..707ea0cedba 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberSkeletonImpl.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberSkeletonImpl.java
@@ -57,7 +57,7 @@ class NumberSkeletonImpl {
         STATE_CURRENCY_UNIT,
         STATE_INTEGER_WIDTH,
         STATE_NUMBERING_SYSTEM,
-        STATE_MULTIPLY,
+        STATE_SCALE,
     }
 
     /**
@@ -109,7 +109,7 @@ class NumberSkeletonImpl {
         STEM_CURRENCY,
         STEM_INTEGER_WIDTH,
         STEM_NUMBERING_SYSTEM,
-        STEM_MULTIPLY,
+        STEM_SCALE,
     };
 
     /** For mapping from ordinal back to StemEnum in Java. */
@@ -162,7 +162,7 @@ class NumberSkeletonImpl {
         b.add("currency", StemEnum.STEM_CURRENCY.ordinal());
         b.add("integer-width", StemEnum.STEM_INTEGER_WIDTH.ordinal());
         b.add("numbering-system", StemEnum.STEM_NUMBERING_SYSTEM.ordinal());
-        b.add("multiply", StemEnum.STEM_MULTIPLY.ordinal());
+        b.add("scale", StemEnum.STEM_SCALE.ordinal());
 
         // Build the CharsTrie
         // TODO: Use SLOW or FAST here?
@@ -514,7 +514,7 @@ class NumberSkeletonImpl {
                 case STATE_CURRENCY_UNIT:
                 case STATE_INTEGER_WIDTH:
                 case STATE_NUMBERING_SYSTEM:
-                case STATE_MULTIPLY:
+                case STATE_SCALE:
                     segment.setLength(Character.charCount(cp)); // for error message
                     throw new SkeletonSyntaxException("Stem requires an option", segment);
                 default:
@@ -662,9 +662,9 @@ class NumberSkeletonImpl {
             checkNull(macros.symbols, segment);
             return ParseState.STATE_NUMBERING_SYSTEM;
 
-        case STEM_MULTIPLY:
-            checkNull(macros.multiplier, segment);
-            return ParseState.STATE_MULTIPLY;
+        case STEM_SCALE:
+            checkNull(macros.scale, segment);
+            return ParseState.STATE_SCALE;
 
         default:
             throw new AssertionError();
@@ -700,8 +700,8 @@ class NumberSkeletonImpl {
         case STATE_NUMBERING_SYSTEM:
             BlueprintHelpers.parseNumberingSystemOption(segment, macros);
             return ParseState.STATE_NULL;
-        case STATE_MULTIPLY:
-            BlueprintHelpers.parseMultiplierOption(segment, macros);
+        case STATE_SCALE:
+            BlueprintHelpers.parseScaleOption(segment, macros);
             return ParseState.STATE_NULL;
         default:
             break;
@@ -788,7 +788,7 @@ class NumberSkeletonImpl {
         if (macros.decimal != null && GeneratorHelpers.decimal(macros, sb)) {
             sb.append(' ');
         }
-        if (macros.multiplier != null && GeneratorHelpers.multiplier(macros, sb)) {
+        if (macros.scale != null && GeneratorHelpers.scale(macros, sb)) {
             sb.append(' ');
         }
 
@@ -1168,25 +1168,25 @@ class NumberSkeletonImpl {
             sb.append(ns.getName());
         }
 
-        private static void parseMultiplierOption(StringSegment segment, MacroProps macros) {
+        private static void parseScaleOption(StringSegment segment, MacroProps macros) {
             // Call segment.subSequence() because segment.toString() doesn't create a clean string.
             String str = segment.subSequence(0, segment.length()).toString();
             BigDecimal bd;
             try {
                 bd = new BigDecimal(str);
             } catch (NumberFormatException e) {
-                throw new SkeletonSyntaxException("Invalid multiplier", segment, e);
+                throw new SkeletonSyntaxException("Invalid scale", segment, e);
             }
-            // NOTE: If bd is a power of ten, the Multiplier API optimizes it for us.
-            macros.multiplier = Multiplier.arbitrary(bd);
+            // NOTE: If bd is a power of ten, the Scale API optimizes it for us.
+            macros.scale = Scale.byBigDecimal(bd);
         }
 
-        private static void generateMultiplierOption(Multiplier multiplier, StringBuilder sb) {
-            BigDecimal bd = multiplier.arbitrary;
+        private static void generateScaleOption(Scale scale, StringBuilder sb) {
+            BigDecimal bd = scale.arbitrary;
             if (bd == null) {
                 bd = BigDecimal.ONE;
             }
-            bd = bd.scaleByPowerOfTen(multiplier.magnitude);
+            bd = bd.scaleByPowerOfTen(scale.magnitude);
             sb.append(bd.toPlainString());
         }
     }
@@ -1380,12 +1380,12 @@ class NumberSkeletonImpl {
             return true;
         }
 
-        private static boolean multiplier(MacroProps macros, StringBuilder sb) {
-            if (!macros.multiplier.isValid()) {
+        private static boolean scale(MacroProps macros, StringBuilder sb) {
+            if (!macros.scale.isValid()) {
                 return false; // Default value
             }
-            sb.append("multiply/");
-            BlueprintHelpers.generateMultiplierOption(macros.multiplier, sb);
+            sb.append("scale/");
+            BlueprintHelpers.generateScaleOption(macros.scale, sb);
             return true;
         }
 
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/Multiplier.java b/icu4j/main/classes/core/src/com/ibm/icu/number/Scale.java
similarity index 79%
rename from icu4j/main/classes/core/src/com/ibm/icu/number/Multiplier.java
rename to icu4j/main/classes/core/src/com/ibm/icu/number/Scale.java
index a40850ae19c..2952e885a11 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/number/Multiplier.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/number/Scale.java
@@ -19,11 +19,11 @@ import com.ibm.icu.impl.number.RoundingUtils;
  * @provisional This API might change or be removed in a future release.
  * @see NumberFormatter
  */
-public class Multiplier {
+public class Scale {
 
-    private static final Multiplier DEFAULT = new Multiplier(0, null);
-    private static final Multiplier HUNDRED = new Multiplier(2, null);
-    private static final Multiplier THOUSAND = new Multiplier(3, null);
+    private static final Scale DEFAULT = new Scale(0, null);
+    private static final Scale HUNDRED = new Scale(2, null);
+    private static final Scale THOUSAND = new Scale(3, null);
 
     private static final BigDecimal BIG_DECIMAL_100 = BigDecimal.valueOf(100);
     private static final BigDecimal BIG_DECIMAL_1000 = BigDecimal.valueOf(1000);
@@ -33,17 +33,17 @@ public class Multiplier {
     final BigDecimal reciprocal;
     final MathContext mc;
 
-    private Multiplier(int magnitude, BigDecimal arbitrary) {
+    private Scale(int magnitude, BigDecimal arbitrary) {
         this(magnitude, arbitrary, RoundingUtils.DEFAULT_MATH_CONTEXT_34_DIGITS);
     }
 
-    private Multiplier(int magnitude, BigDecimal arbitrary, MathContext mc) {
+    private Scale(int magnitude, BigDecimal arbitrary, MathContext mc) {
         if (arbitrary != null) {
             // Attempt to convert the BigDecimal to a magnitude multiplier.
             arbitrary = arbitrary.stripTrailingZeros();
             if (arbitrary.precision() == 1 && arbitrary.unscaledValue().equals(BigInteger.ONE)) {
                 // Success!
-                magnitude = -arbitrary.scale();
+                magnitude -= arbitrary.scale();
                 arbitrary = null;
             }
         }
@@ -68,7 +68,7 @@ public class Multiplier {
      * @provisional This API might change or be removed in a future release.
      * @see NumberFormatter
      */
-    public static Multiplier none() {
+    public static Scale none() {
         return DEFAULT;
     }
 
@@ -85,7 +85,7 @@ public class Multiplier {
      * @provisional This API might change or be removed in a future release.
      * @see NumberFormatter
      */
-    public static Multiplier powerOfTen(int power) {
+    public static Scale powerOfTen(int power) {
         if (power == 0) {
             return DEFAULT;
         } else if (power == 2) {
@@ -93,7 +93,7 @@ public class Multiplier {
         } else if (power == 3) {
             return THOUSAND;
         } else {
-            return new Multiplier(power, null);
+            return new Scale(power, null);
         }
     }
 
@@ -107,7 +107,7 @@ public class Multiplier {
      * @provisional This API might change or be removed in a future release.
      * @see NumberFormatter
      */
-    public static Multiplier arbitrary(BigDecimal multiplicand) {
+    public static Scale byBigDecimal(BigDecimal multiplicand) {
         if (multiplicand.compareTo(BigDecimal.ONE) == 0) {
             return DEFAULT;
         } else if (multiplicand.compareTo(BIG_DECIMAL_100) == 0) {
@@ -115,7 +115,7 @@ public class Multiplier {
         } else if (multiplicand.compareTo(BIG_DECIMAL_1000) == 0) {
             return THOUSAND;
         } else {
-            return new Multiplier(0, multiplicand);
+            return new Scale(0, multiplicand);
         }
     }
 
@@ -129,7 +129,7 @@ public class Multiplier {
      * @provisional This API might change or be removed in a future release.
      * @see NumberFormatter
      */
-    public static Multiplier arbitrary(double multiplicand) {
+    public static Scale byDouble(double multiplicand) {
         if (multiplicand == 1) {
             return DEFAULT;
         } else if (multiplicand == 100.0) {
@@ -137,10 +137,22 @@ public class Multiplier {
         } else if (multiplicand == 1000.0) {
             return THOUSAND;
         } else {
-            return new Multiplier(0, BigDecimal.valueOf(multiplicand));
+            return new Scale(0, BigDecimal.valueOf(multiplicand));
         }
     }
 
+    /**
+     * Multiply a number by both a power of ten and by an arbitrary double value before formatting.
+     *
+     * @return A Multiplier for passing to the setter in NumberFormatter.
+     * @draft ICU 62
+     * @provisional This API might change or be removed in a future release.
+     * @see NumberFormatter
+     */
+    public static Scale byDoubleAndPowerOfTen(double multiplicand, int power) {
+        return new Scale(power, BigDecimal.valueOf(multiplicand));
+    }
+
     /**
      * Returns whether the multiplier will change the number.
      */
@@ -153,12 +165,12 @@ public class Multiplier {
      * @deprecated ICU 62 This API is ICU internal only.
      */
     @Deprecated
-    public Multiplier withMathContext(MathContext mc) {
+    public Scale withMathContext(MathContext mc) {
         // TODO: Make this public?
         if (this.mc.equals(mc)) {
             return this;
         }
-        return new Multiplier(magnitude, arbitrary, mc);
+        return new Scale(magnitude, arbitrary, mc);
     }
 
     /**
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 4505b21cb12..0ad9fe3ce8e 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
@@ -29,7 +29,6 @@ import com.ibm.icu.number.CompactNotation;
 import com.ibm.icu.number.FractionRounder;
 import com.ibm.icu.number.IntegerWidth;
 import com.ibm.icu.number.LocalizedNumberFormatter;
-import com.ibm.icu.number.Multiplier;
 import com.ibm.icu.number.Notation;
 import com.ibm.icu.number.NumberFormatter;
 import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay;
@@ -37,6 +36,7 @@ import com.ibm.icu.number.NumberFormatter.GroupingStrategy;
 import com.ibm.icu.number.NumberFormatter.SignDisplay;
 import com.ibm.icu.number.NumberFormatter.UnitWidth;
 import com.ibm.icu.number.Rounder;
+import com.ibm.icu.number.Scale;
 import com.ibm.icu.number.ScientificNotation;
 import com.ibm.icu.number.UnlocalizedNumberFormatter;
 import com.ibm.icu.text.DecimalFormatSymbols;
@@ -1884,11 +1884,11 @@ public class NumberFormatterApiTest {
     }
 
     @Test
-    public void multiplier() {
+    public void scale() {
         assertFormatDescending(
                 "Multiplier None",
-                "multiply/1",
-                NumberFormatter.with().multiplier(Multiplier.none()),
+                "scale/1",
+                NumberFormatter.with().scale(Scale.none()),
                 ULocale.ENGLISH,
                 "87,650",
                 "8,765",
@@ -1902,8 +1902,8 @@ public class NumberFormatterApiTest {
 
         assertFormatDescending(
                 "Multiplier Power of Ten",
-                "multiply/1000000",
-                NumberFormatter.with().multiplier(Multiplier.powerOfTen(6)),
+                "scale/1000000",
+                NumberFormatter.with().scale(Scale.powerOfTen(6)),
                 ULocale.ENGLISH,
                 "87,650,000,000",
                 "8,765,000,000",
@@ -1917,8 +1917,8 @@ public class NumberFormatterApiTest {
 
         assertFormatDescending(
                 "Multiplier Arbitrary Double",
-                "multiply/5.2",
-                NumberFormatter.with().multiplier(Multiplier.arbitrary(5.2)),
+                "scale/5.2",
+                NumberFormatter.with().scale(Scale.byDouble(5.2)),
                 ULocale.ENGLISH,
                 "455,780",
                 "45,578",
@@ -1932,8 +1932,8 @@ public class NumberFormatterApiTest {
 
         assertFormatDescending(
                 "Multiplier Arbitrary BigDecimal",
-                "multiply/5.2",
-                NumberFormatter.with().multiplier(Multiplier.arbitrary(new BigDecimal("5.2"))),
+                "scale/5.2",
+                NumberFormatter.with().scale(Scale.byBigDecimal(new BigDecimal("5.2"))),
                 ULocale.ENGLISH,
                 "455,780",
                 "45,578",
@@ -1945,10 +1945,25 @@ public class NumberFormatterApiTest {
                 "0.045578",
                 "0");
 
+        assertFormatDescending(
+                "Multiplier Arbitrary Double And Power Of Ten",
+                "scale/5200",
+                NumberFormatter.with().scale(Scale.byDoubleAndPowerOfTen(5.2, 3)),
+                ULocale.ENGLISH,
+                "455,780,000",
+                "45,578,000",
+                "4,557,800",
+                "455,780",
+                "45,578",
+                "4,557.8",
+                "455.78",
+                "45.578",
+                "0");
+
         assertFormatDescending(
                 "Multiplier Zero",
-                "multiply/0",
-                NumberFormatter.with().multiplier(Multiplier.arbitrary(0)),
+                "scale/0",
+                NumberFormatter.with().scale(Scale.byDouble(0)),
                 ULocale.ENGLISH,
                 "0",
                 "0",
@@ -1962,27 +1977,35 @@ public class NumberFormatterApiTest {
 
         assertFormatSingle(
                 "Multiplier Skeleton Scientific Notation and Percent",
-                "percent multiply/1E2",
-                NumberFormatter.with().unit(NoUnit.PERCENT).multiplier(Multiplier.powerOfTen(2)),
+                "percent scale/1E2",
+                NumberFormatter.with().unit(NoUnit.PERCENT).scale(Scale.powerOfTen(2)),
                 ULocale.ENGLISH,
                 0.5,
                 "50%");
 
         assertFormatSingle(
                 "Negative Multiplier",
-                "multiply/-5.2",
-                NumberFormatter.with().multiplier(Multiplier.arbitrary(-5.2)),
+                "scale/-5.2",
+                NumberFormatter.with().scale(Scale.byDouble(-5.2)),
                 ULocale.ENGLISH,
                 2,
                 "-10.4");
 
         assertFormatSingle(
                 "Negative One Multiplier",
-                "multiply/-1",
-                NumberFormatter.with().multiplier(Multiplier.arbitrary(-1)),
+                "scale/-1",
+                NumberFormatter.with().scale(Scale.byDouble(-1)),
                 ULocale.ENGLISH,
                 444444,
                 "-444,444");
+
+        assertFormatSingle(
+                "Two-Type Multiplier with Overlap",
+                "scale/10000",
+                NumberFormatter.with().scale(Scale.byDoubleAndPowerOfTen(100, 2)),
+                ULocale.ENGLISH,
+                2,
+                "20,000");
     }
 
     @Test
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java
index 216127923ba..7c7349b5e99 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java
@@ -82,11 +82,11 @@ public class NumberSkeletonTest {
                 "unit-width-hidden",
                 "decimal-auto",
                 "decimal-always",
-                "multiply/5.2",
-                "multiply/-5.2",
-                "multiply/100",
-                "multiply/1E2",
-                "multiply/1",
+                "scale/5.2",
+                "scale/-5.2",
+                "scale/100",
+                "scale/1E2",
+                "scale/1",
                 "latin",
                 "numbering-system/arab",
                 "numbering-system/latn",
@@ -126,10 +126,10 @@ public class NumberSkeletonTest {
                 "round-increment/xxx",
                 "round-increment/NaN",
                 "round-increment/0.1.2",
-                "multiply/xxx",
-                "multiply/NaN",
-                "multiply/0.1.2",
-                "multiply/français", // non-invariant characters for C++
+                "scale/xxx",
+                "scale/NaN",
+                "scale/0.1.2",
+                "scale/français", // non-invariant characters for C++
                 "currency/dummy",
                 "measure-unit/foo",
                 "integer-width/xxx",
@@ -217,7 +217,7 @@ public class NumberSkeletonTest {
                 "currency",
                 "integer-width",
                 "numbering-system",
-                "multiply" };
+                "scale" };
         String[] suffixes = { "", "/ceiling", " scientific", "/ceiling scientific" };
 
         for (String stem : stems) {
-- 
2.40.0