ICU-20923 Fix compact notation with percent.
diff --git a/icu4c/source/i18n/number_formatimpl.cpp b/icu4c/source/i18n/number_formatimpl.cpp
index e6b1c5b..875f71b 100644
--- a/icu4c/source/i18n/number_formatimpl.cpp
+++ b/icu4c/source/i18n/number_formatimpl.cpp
@@ -133,6 +133,7 @@
     bool isBaseUnit = utils::unitIsBaseUnit(macros.unit);
     bool isPercent = utils::unitIsPercent(macros.unit);
     bool isPermille = utils::unitIsPermille(macros.unit);
+    bool isCompactNotation = macros.notation.fType == Notation::NTN_COMPACT;
     bool isAccounting =
             macros.sign == UNUM_SIGN_ACCOUNTING || macros.sign == UNUM_SIGN_ACCOUNTING_ALWAYS ||
             macros.sign == UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO;
@@ -144,8 +145,18 @@
     if (macros.unitWidth != UNUM_UNIT_WIDTH_COUNT) {
         unitWidth = macros.unitWidth;
     }
-    bool isCldrUnit = !isCurrency && !isBaseUnit &&
-        (unitWidth == UNUM_UNIT_WIDTH_FULL_NAME || !(isPercent || isPermille));
+    // Use CLDR unit data for all MeasureUnits (not currency and not
+    // no-unit), except use the dedicated percent pattern for percent and
+    // permille. However, use the CLDR unit data for percent/permille if a
+    // long name was requested OR if compact notation is being used, since
+    // compact notation overrides the middle modifier (micros.modMiddle)
+    // normally used for the percent pattern.
+    bool isCldrUnit = !isCurrency
+        && !isBaseUnit
+        && (unitWidth == UNUM_UNIT_WIDTH_FULL_NAME
+            || !(isPercent || isPermille)
+            || isCompactNotation
+        );
 
     // Select the numbering system.
     LocalPointer<const NumberingSystem> nsLocal;
@@ -232,7 +243,7 @@
     Precision precision;
     if (!macros.precision.isBogus()) {
         precision = macros.precision;
-    } else if (macros.notation.fType == Notation::NTN_COMPACT) {
+    } else if (isCompactNotation) {
         precision = Precision::integer().withMinDigits(2);
     } else if (isCurrency) {
         precision = Precision::currency(UCURR_USAGE_STANDARD);
@@ -254,7 +265,7 @@
     // Grouping strategy
     if (!macros.grouper.isBogus()) {
         fMicros.grouping = macros.grouper;
-    } else if (macros.notation.fType == Notation::NTN_COMPACT) {
+    } else if (isCompactNotation) {
         // Compact notation uses minGrouping by default since ICU 59
         fMicros.grouping = Grouper::forStrategy(UNUM_GROUPING_MIN2);
     } else {
@@ -366,7 +377,7 @@
     }
 
     // Compact notation
-    if (macros.notation.fType == Notation::NTN_COMPACT) {
+    if (isCompactNotation) {
         CompactType compactType = (isCurrency && unitWidth != UNUM_UNIT_WIDTH_FULL_NAME)
                                   ? CompactType::TYPE_CURRENCY : CompactType::TYPE_DECIMAL;
         auto newCompactHandler = new CompactHandler(
diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp
index 75b0d00..b0e1015 100644
--- a/icu4c/source/test/intltest/numbertest_api.cpp
+++ b/icu4c/source/test/intltest/numbertest_api.cpp
@@ -1014,6 +1014,65 @@
             -98.7654321,
             u"-98.765432%");
 
+    // ICU-20923
+    assertFormatDescendingBig(
+            u"Compact Percent",
+            u"compact-short percent",
+            u"K %",
+            NumberFormatter::with()
+                    .notation(Notation::compactShort())
+                    .unit(NoUnit::percent()),
+            Locale::getEnglish(),
+            u"88M%",
+            u"8.8M%",
+            u"876K%",
+            u"88K%",
+            u"8.8K%",
+            u"876%",
+            u"88%",
+            u"8.8%",
+            u"0%");
+
+    // ICU-20923
+    assertFormatDescendingBig(
+            u"Compact Percent with Scale",
+            u"compact-short percent scale/100",
+            u"K %x100",
+            NumberFormatter::with()
+                    .notation(Notation::compactShort())
+                    .unit(NoUnit::percent())
+                    .scale(Scale::powerOfTen(2)),
+            Locale::getEnglish(),
+            u"8.8B%",
+            u"876M%",
+            u"88M%",
+            u"8.8M%",
+            u"876K%",
+            u"88K%",
+            u"8.8K%",
+            u"876%",
+            u"0%");
+
+    // ICU-20923
+    assertFormatDescendingBig(
+            u"Compact Percent Long Name",
+            u"compact-short percent unit-width-full-name",
+            u"K % unit-width-full-name",
+            NumberFormatter::with()
+                    .notation(Notation::compactShort())
+                    .unit(NoUnit::percent())
+                    .unitWidth(UNUM_UNIT_WIDTH_FULL_NAME),
+            Locale::getEnglish(),
+            u"88M percent",
+            u"8.8M percent",
+            u"876K percent",
+            u"88K percent",
+            u"8.8K percent",
+            u"876 percent",
+            u"88 percent",
+            u"8.8 percent",
+            u"0 percent");
+
     assertFormatSingle(
             u"Per Percent",
             u"measure-unit/length-meter per-measure-unit/concentr-percent unit-width-full-name",
diff --git a/icu4c/source/test/intltest/numbertest_permutation.cpp b/icu4c/source/test/intltest/numbertest_permutation.cpp
index 85f32d5..a96dd75 100644
--- a/icu4c/source/test/intltest/numbertest_permutation.cpp
+++ b/icu4c/source/test/intltest/numbertest_permutation.cpp
@@ -71,7 +71,11 @@
  * Test permutations of 3 orthogonal skeleton parts from the list above.
  * Compare the results against the golden data file:
  *     numberpermutationtest.txt
- * To regenerate that file, run intltest with the -G option.
+ * To regenerate that file, run intltest with the -e and -G options.
+ * On Linux, from icu4c/source:
+ *     make -j8 tests && (cd test/intltest && LD_LIBRARY_PATH=../../lib:../../tools/ctestfw ./intltest -e -G format/NumberTest/NumberPermutationTest)
+ * After re-generating the file, copy it into icu4j:
+ *     cp test/testdata/numberpermutationtest.txt ../../icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberpermutationtest.txt
  */
 void NumberPermutationTest::testPermutations() {
     IcuTestErrorCode status(*this, "testPermutations");
diff --git a/icu4c/source/test/testdata/numberpermutationtest.txt b/icu4c/source/test/testdata/numberpermutationtest.txt
index e5f0b78..b63df7d 100644
--- a/icu4c/source/test/testdata/numberpermutationtest.txt
+++ b/icu4c/source/test/testdata/numberpermutationtest.txt
@@ -4,15 +4,15 @@
 compact-short percent unit-width-narrow
   es-MX
     0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০%
-    ৯২ হা
+    ৯২ হা%
     -০.২২%
 
 compact-short percent unit-width-full-name
@@ -172,57 +172,57 @@
 compact-short percent precision-integer
   es-MX
     0 %
-    92 k
+    92 k %
     -0 %
   zh-TW
     0%
-    9萬
+    9萬%
     -0%
   bn-BD
     ০%
-    ৯২ হা
+    ৯২ হা%
     -০%
 
 compact-short percent .000
   es-MX
     0.000 %
-    91.827 k
+    91.827 k %
     -0.222 %
   zh-TW
     0.000%
-    9.183萬
+    9.183萬%
     -0.222%
   bn-BD
     ০.০০০%
-    ৯১.৮২৭ হা
+    ৯১.৮২৭ হা%
     -০.২২২%
 
 compact-short percent .##/@@@+
   es-MX
     0 %
-    91.83 k
+    91.83 k %
     -0.222 %
   zh-TW
     0%
-    9.18萬
+    9.18萬%
     -0.222%
   bn-BD
     ০%
-    ৯১.৮৩ হা
+    ৯১.৮৩ হা%
     -০.২২২%
 
 compact-short percent @@
   es-MX
     0.0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0.0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০.০%
-    ৯২ হা
+    ৯২ হা%
     -০.২২%
 
 compact-short currency/EUR precision-integer
@@ -508,15 +508,15 @@
 compact-short percent rounding-mode-floor
   es-MX
     0 %
-    91 k
+    91 k %
     -0.23 %
   zh-TW
     0%
-    9.1萬
+    9.1萬%
     -0.23%
   bn-BD
     ০%
-    ৯১ হা
+    ৯১ হা%
     -০.২৩%
 
 compact-short currency/EUR rounding-mode-floor
@@ -592,15 +592,15 @@
 compact-short percent integer-width/##00
   es-MX
     00 %
-    92 k
+    92 k %
     -00.22 %
   zh-TW
     00%
-    09.2萬
+    09.2萬%
     -00.22%
   bn-BD
     ০০%
-    ৯২ হা
+    ৯২ হা%
     -০০.২২%
 
 compact-short currency/EUR integer-width/##00
@@ -676,15 +676,15 @@
 compact-short percent scale/0.5
   es-MX
     0 %
-    46 k
+    46 k %
     -0.11 %
   zh-TW
     0%
-    4.6萬
+    4.6萬%
     -0.11%
   bn-BD
     ০%
-    ৪৬ হা
+    ৪৬ হা%
     -০.১১%
 
 compact-short currency/EUR scale/0.5
@@ -760,15 +760,15 @@
 compact-short percent group-on-aligned
   es-MX
     0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০%
-    ৯২ হা
+    ৯২ হা%
     -০.২২%
 
 compact-short currency/EUR group-on-aligned
@@ -844,15 +844,15 @@
 compact-short percent latin
   es-MX
     0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     0%
-    92 হা
+    92 হা%
     -0.22%
 
 compact-short currency/EUR latin
@@ -928,15 +928,15 @@
 compact-short percent sign-accounting-except-zero
   es-MX
     0 %
-    +92 k
+    +92 k %
     -0.22 %
   zh-TW
     0%
-    +9.2萬
+    +9.2萬%
     -0.22%
   bn-BD
     ০%
-    +৯২ হা
+    +৯২ হা%
     -০.২২%
 
 compact-short currency/EUR sign-accounting-except-zero
@@ -1012,15 +1012,15 @@
 compact-short percent decimal-always
   es-MX
     0. %
-    92. k
+    92. k %
     -0.22 %
   zh-TW
     0.%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০.%
-    ৯২. হা
+    ৯২. হা%
     -০.২২%
 
 compact-short currency/EUR decimal-always
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 629732e..fa483ef 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
@@ -182,6 +182,7 @@
         boolean isBaseUnit = unitIsBaseUnit(macros.unit);
         boolean isPercent = unitIsPercent(macros.unit);
         boolean isPermille = unitIsPermille(macros.unit);
+        boolean isCompactNotation = (macros.notation instanceof CompactNotation);
         boolean isAccounting = macros.sign == SignDisplay.ACCOUNTING
                 || macros.sign == SignDisplay.ACCOUNTING_ALWAYS
                 || macros.sign == SignDisplay.ACCOUNTING_EXCEPT_ZERO;
@@ -190,8 +191,18 @@
         if (macros.unitWidth != null) {
             unitWidth = macros.unitWidth;
         }
-        boolean isCldrUnit = !isCurrency && !isBaseUnit &&
-            (unitWidth == UnitWidth.FULL_NAME || !(isPercent || isPermille));
+        // Use CLDR unit data for all MeasureUnits (not currency and not
+        // no-unit), except use the dedicated percent pattern for percent and
+        // permille. However, use the CLDR unit data for percent/permille if a
+        // long name was requested OR if compact notation is being used, since
+        // compact notation overrides the middle modifier (micros.modMiddle)
+        // normally used for the percent pattern.
+        boolean isCldrUnit = !isCurrency
+            && !isBaseUnit
+            && (unitWidth == UnitWidth.FULL_NAME
+                || !(isPercent || isPermille)
+                || isCompactNotation
+            );
         PluralRules rules = macros.rules;
 
         // Select the numbering system.
@@ -252,7 +263,7 @@
         // Rounding strategy
         if (macros.precision != null) {
             micros.rounder = macros.precision;
-        } else if (macros.notation instanceof CompactNotation) {
+        } else if (isCompactNotation) {
             micros.rounder = Precision.COMPACT_STRATEGY;
         } else if (isCurrency) {
             micros.rounder = Precision.MONETARY_STANDARD;
@@ -270,7 +281,7 @@
             micros.grouping = (Grouper) macros.grouping;
         } else if (macros.grouping instanceof GroupingStrategy) {
             micros.grouping = Grouper.forStrategy((GroupingStrategy) macros.grouping);
-        } else if (macros.notation instanceof CompactNotation) {
+        } else if (isCompactNotation) {
             // Compact notation uses minGrouping by default since ICU 59
             micros.grouping = Grouper.forStrategy(GroupingStrategy.MIN2);
         } else {
@@ -356,7 +367,7 @@
         }
 
         // Compact notation
-        if (macros.notation instanceof CompactNotation) {
+        if (isCompactNotation) {
             if (rules == null) {
                 // Lazily create PluralRules
                 rules = PluralRules.forLocale(macros.loc);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberpermutationtest.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberpermutationtest.txt
index e5f0b78..b63df7d 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberpermutationtest.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberpermutationtest.txt
@@ -4,15 +4,15 @@
 compact-short percent unit-width-narrow
   es-MX
     0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০%
-    ৯২ হা
+    ৯২ হা%
     -০.২২%
 
 compact-short percent unit-width-full-name
@@ -172,57 +172,57 @@
 compact-short percent precision-integer
   es-MX
     0 %
-    92 k
+    92 k %
     -0 %
   zh-TW
     0%
-    9萬
+    9萬%
     -0%
   bn-BD
     ০%
-    ৯২ হা
+    ৯২ হা%
     -০%
 
 compact-short percent .000
   es-MX
     0.000 %
-    91.827 k
+    91.827 k %
     -0.222 %
   zh-TW
     0.000%
-    9.183萬
+    9.183萬%
     -0.222%
   bn-BD
     ০.০০০%
-    ৯১.৮২৭ হা
+    ৯১.৮২৭ হা%
     -০.২২২%
 
 compact-short percent .##/@@@+
   es-MX
     0 %
-    91.83 k
+    91.83 k %
     -0.222 %
   zh-TW
     0%
-    9.18萬
+    9.18萬%
     -0.222%
   bn-BD
     ০%
-    ৯১.৮৩ হা
+    ৯১.৮৩ হা%
     -০.২২২%
 
 compact-short percent @@
   es-MX
     0.0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0.0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০.০%
-    ৯২ হা
+    ৯২ হা%
     -০.২২%
 
 compact-short currency/EUR precision-integer
@@ -508,15 +508,15 @@
 compact-short percent rounding-mode-floor
   es-MX
     0 %
-    91 k
+    91 k %
     -0.23 %
   zh-TW
     0%
-    9.1萬
+    9.1萬%
     -0.23%
   bn-BD
     ০%
-    ৯১ হা
+    ৯১ হা%
     -০.২৩%
 
 compact-short currency/EUR rounding-mode-floor
@@ -592,15 +592,15 @@
 compact-short percent integer-width/##00
   es-MX
     00 %
-    92 k
+    92 k %
     -00.22 %
   zh-TW
     00%
-    09.2萬
+    09.2萬%
     -00.22%
   bn-BD
     ০০%
-    ৯২ হা
+    ৯২ হা%
     -০০.২২%
 
 compact-short currency/EUR integer-width/##00
@@ -676,15 +676,15 @@
 compact-short percent scale/0.5
   es-MX
     0 %
-    46 k
+    46 k %
     -0.11 %
   zh-TW
     0%
-    4.6萬
+    4.6萬%
     -0.11%
   bn-BD
     ০%
-    ৪৬ হা
+    ৪৬ হা%
     -০.১১%
 
 compact-short currency/EUR scale/0.5
@@ -760,15 +760,15 @@
 compact-short percent group-on-aligned
   es-MX
     0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০%
-    ৯২ হা
+    ৯২ হা%
     -০.২২%
 
 compact-short currency/EUR group-on-aligned
@@ -844,15 +844,15 @@
 compact-short percent latin
   es-MX
     0 %
-    92 k
+    92 k %
     -0.22 %
   zh-TW
     0%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     0%
-    92 হা
+    92 হা%
     -0.22%
 
 compact-short currency/EUR latin
@@ -928,15 +928,15 @@
 compact-short percent sign-accounting-except-zero
   es-MX
     0 %
-    +92 k
+    +92 k %
     -0.22 %
   zh-TW
     0%
-    +9.2萬
+    +9.2萬%
     -0.22%
   bn-BD
     ০%
-    +৯২ হা
+    +৯২ হা%
     -০.২২%
 
 compact-short currency/EUR sign-accounting-except-zero
@@ -1012,15 +1012,15 @@
 compact-short percent decimal-always
   es-MX
     0. %
-    92. k
+    92. k %
     -0.22 %
   zh-TW
     0.%
-    9.2萬
+    9.2萬%
     -0.22%
   bn-BD
     ০.%
-    ৯২. হা
+    ৯২. হা%
     -০.২২%
 
 compact-short currency/EUR decimal-always
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 d3bbc13..73df02c 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
@@ -967,6 +967,65 @@
                 -98.7654321,
                 "-98.765432%");
 
+        // ICU-20923
+        assertFormatDescendingBig(
+                "Compact Percent",
+                "compact-short percent",
+                "K %",
+                NumberFormatter.with()
+                        .notation(Notation.compactShort())
+                        .unit(NoUnit.PERCENT),
+                ULocale.ENGLISH,
+                "88M%",
+                "8.8M%",
+                "876K%",
+                "88K%",
+                "8.8K%",
+                "876%",
+                "88%",
+                "8.8%",
+                "0%");
+
+        // ICU-20923
+        assertFormatDescendingBig(
+                "Compact Percent with Scale",
+                "compact-short percent scale/100",
+                "K %x100",
+                NumberFormatter.with()
+                        .notation(Notation.compactShort())
+                        .unit(NoUnit.PERCENT)
+                        .scale(Scale.powerOfTen(2)),
+                ULocale.ENGLISH,
+                "8.8B%",
+                "876M%",
+                "88M%",
+                "8.8M%",
+                "876K%",
+                "88K%",
+                "8.8K%",
+                "876%",
+                "0%");
+
+        // ICU-20923
+        assertFormatDescendingBig(
+                "Compact Percent Long Name",
+                "compact-short percent unit-width-full-name",
+                "K % unit-width-full-name",
+                NumberFormatter.with()
+                        .notation(Notation.compactShort())
+                        .unit(NoUnit.PERCENT)
+                        .unitWidth(UnitWidth.FULL_NAME),
+                ULocale.ENGLISH,
+                "88M percent",
+                "8.8M percent",
+                "876K percent",
+                "88K percent",
+                "8.8K percent",
+                "876 percent",
+                "88 percent",
+                "8.8 percent",
+                "0 percent");
+
         assertFormatSingle(
                 "Per Percent",
                 "measure-unit/length-meter per-measure-unit/concentr-percent unit-width-full-name",