diff --git a/icu4c/source/i18n/plurrule.cpp b/icu4c/source/i18n/plurrule.cpp
index 7d1037f..edc3d88 100644
--- a/icu4c/source/i18n/plurrule.cpp
+++ b/icu4c/source/i18n/plurrule.cpp
@@ -26,6 +26,7 @@
 #include "hash.h"
 #include "locutil.h"
 #include "mutex.h"
+#include "number_decnum.h"
 #include "patternprops.h"
 #include "plurrule_impl.h"
 #include "putilimp.h"
@@ -45,7 +46,9 @@
 U_NAMESPACE_BEGIN
 
 using namespace icu::pluralimpl;
+using icu::number::impl::DecNum;
 using icu::number::impl::DecimalQuantity;
+using icu::number::impl::RoundingMode;
 
 static const UChar PLURAL_KEYWORD_OTHER[]={LOW_O,LOW_T,LOW_H,LOW_E,LOW_R,0};
 static const UChar PLURAL_DEFAULT_RULE[]={LOW_O,LOW_T,LOW_H,LOW_E,LOW_R,COLON,SPACE,LOW_N,0};
@@ -369,36 +372,18 @@
     return 0;
 }
 
-
-static double scaleForInt(double d) {
-    double scale = 1.0;
-    while (d != floor(d)) {
-        d = d * 10.0;
-        scale = scale * 10.0;
-    }
-    return scale;
-}
-
-static const double powers10[7] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0}; // powers of 10 for 0..6
-static double applyExponent(double source, int32_t exponent) {
-    if (exponent >= 0 && exponent <= 6) {
-        return source * powers10[exponent];
-    }
-    return source * pow(10.0, exponent);
-}
-
 /**
- * Helper method for the overrides of getSamples() for double and FixedDecimal
- * return value types.  Provide only one of an allocated array of doubles or
- * FixedDecimals, and a nullptr for the other.
+ * Helper method for the overrides of getSamples() for double and DecimalQuantity
+ * return value types.  Provide only one of an allocated array of double or
+ * DecimalQuantity, and a nullptr for the other.
  */
 static int32_t
 getSamplesFromString(const UnicodeString &samples, double *destDbl,
-                        FixedDecimal* destFd, int32_t destCapacity,
+                        DecimalQuantity* destDq, int32_t destCapacity,
                         UErrorCode& status) {
 
-    if ((destDbl == nullptr && destFd == nullptr)
-            || (destDbl != nullptr && destFd != nullptr)) {
+    if ((destDbl == nullptr && destDq == nullptr)
+            || (destDbl != nullptr && destDq != nullptr)) {
         status = U_INTERNAL_PROGRAM_ERROR;
         return 0;
     }
@@ -420,58 +405,75 @@
         // std::cout << "PluralRules::getSamples(), samplesRange = \"" << sampleRange.toUTF8String(ss) << "\"\n";
         int32_t tildeIndex = sampleRange.indexOf(TILDE);
         if (tildeIndex < 0) {
-            FixedDecimal fixed(sampleRange, status);
+            DecimalQuantity dq = DecimalQuantity::fromExponentString(sampleRange, status);
             if (isDouble) {
-                double sampleValue = fixed.source;
-                if (fixed.visibleDecimalDigitCount == 0 || sampleValue != floor(sampleValue)) {
-                    destDbl[sampleCount++] = applyExponent(sampleValue, fixed.exponent);
+                // See warning note below about lack of precision for floating point samples for numbers with
+                // trailing zeroes in the decimal fraction representation.
+                double dblValue = dq.toDouble();
+                if (!(dblValue == floor(dblValue) && dq.fractionCount() > 0)) {
+                    destDbl[sampleCount++] = dblValue;
                 }
             } else {
-                destFd[sampleCount++] = fixed;
+                destDq[sampleCount++] = dq;
             }
         } else {
-            FixedDecimal fixedLo(sampleRange.tempSubStringBetween(0, tildeIndex), status);
-            FixedDecimal fixedHi(sampleRange.tempSubStringBetween(tildeIndex+1), status);
-            double rangeLo = fixedLo.source;
-            double rangeHi = fixedHi.source;
+            DecimalQuantity rangeLo =
+                DecimalQuantity::fromExponentString(sampleRange.tempSubStringBetween(0, tildeIndex), status);
+            DecimalQuantity rangeHi = DecimalQuantity::fromExponentString(sampleRange.tempSubStringBetween(tildeIndex+1), status);
             if (U_FAILURE(status)) {
                 break;
             }
-            if (rangeHi < rangeLo) {
+            if (rangeHi.toDouble() < rangeLo.toDouble()) {
                 status = U_INVALID_FORMAT_ERROR;
                 break;
             }
 
-            // For ranges of samples with fraction decimal digits, scale the number up so that we
-            //   are adding one in the units place. Avoids roundoffs from repetitive adds of tenths.
+            DecimalQuantity incrementDq;
+            incrementDq.setToInt(1);
+            int32_t lowerDispMag = rangeLo.getLowerDisplayMagnitude();
+            int32_t exponent = rangeLo.getExponent();
+            int32_t incrementScale = lowerDispMag + exponent;
+            incrementDq.adjustMagnitude(incrementScale);
+            double incrementVal = incrementDq.toDouble();  // 10 ^ incrementScale
+            
 
-            double scale = scaleForInt(rangeLo);
-            double t = scaleForInt(rangeHi);
-            if (t > scale) {
-                scale = t;
-            }
-            rangeLo *= scale;
-            rangeHi *= scale;
-            for (double n=rangeLo; n<=rangeHi; n+=1) {
-                double sampleValue = n/scale;
+            DecimalQuantity dq(rangeLo);
+            double dblValue = dq.toDouble();
+            double end = rangeHi.toDouble();
+
+            while (dblValue <= end) {
                 if (isDouble) {
                     // Hack Alert: don't return any decimal samples with integer values that
                     //    originated from a format with trailing decimals.
                     //    This API is returning doubles, which can't distinguish having displayed
                     //    zeros to the right of the decimal.
                     //    This results in test failures with values mapping back to a different keyword.
-                    if (!(sampleValue == floor(sampleValue) && fixedLo.visibleDecimalDigitCount > 0)) {
-                        destDbl[sampleCount++] = sampleValue;
+                    if (!(dblValue == floor(dblValue) && dq.fractionCount() > 0)) {
+                        destDbl[sampleCount++] = dblValue;
                     }
                 } else {
-                    int32_t v = (int32_t) fixedLo.getPluralOperand(PluralOperand::PLURAL_OPERAND_V);
-                    int32_t e = (int32_t) fixedLo.getPluralOperand(PluralOperand::PLURAL_OPERAND_E);
-                    FixedDecimal newSample = FixedDecimal::createWithExponent(sampleValue, v, e);
-                    destFd[sampleCount++] = newSample;
+                    destDq[sampleCount++] = dq;
                 }
                 if (sampleCount >= destCapacity) {
                     break;
                 }
+
+                // Increment dq for next iteration
+
+                // Because DecNum and DecimalQuantity do not support
+                // add operations, we need to convert to/from double,
+                // despite precision lossiness for decimal fractions like 0.1.
+                dblValue += incrementVal;
+                DecNum newDqDecNum;
+                newDqDecNum.setTo(dblValue, status);
+                DecimalQuantity newDq;             
+                newDq.setToDecNum(newDqDecNum, status);
+                newDq.setMinFraction(-lowerDispMag);
+                newDq.roundToMagnitude(lowerDispMag, RoundingMode::UNUM_ROUND_HALFEVEN, status);
+                newDq.adjustMagnitude(-exponent);
+                newDq.adjustExponent(exponent);
+                dblValue = newDq.toDouble();
+                dq = newDq;
             }
         }
         sampleStartIdx = sampleEndIdx + 1;
@@ -505,7 +507,7 @@
 }
 
 int32_t
-PluralRules::getSamples(const UnicodeString &keyword, FixedDecimal *dest,
+PluralRules::getSamples(const UnicodeString &keyword, DecimalQuantity *dest,
                         int32_t destCapacity, UErrorCode& status) {
     if (U_FAILURE(status)) {
         return 0;
diff --git a/icu4c/source/i18n/plurrule_impl.h b/icu4c/source/i18n/plurrule_impl.h
index 7274da5..c27b655 100644
--- a/icu4c/source/i18n/plurrule_impl.h
+++ b/icu4c/source/i18n/plurrule_impl.h
@@ -34,7 +34,7 @@
  * A FixedDecimal version of UPLRULES_NO_UNIQUE_VALUE used in PluralRulesTest
  * for parsing of samples.
  */
-#define UPLRULES_NO_UNIQUE_VALUE_DECIMAL (FixedDecimal((double)-0.00123456777))
+#define UPLRULES_NO_UNIQUE_VALUE_DECIMAL(ERROR_CODE) (DecimalQuantity::fromExponentString(u"-0.00123456777", ERROR_CODE))
 
 class PluralRulesTest;
 
diff --git a/icu4c/source/i18n/unicode/plurrule.h b/icu4c/source/i18n/unicode/plurrule.h
index e3822dd..b4298de 100644
--- a/icu4c/source/i18n/unicode/plurrule.h
+++ b/icu4c/source/i18n/unicode/plurrule.h
@@ -59,9 +59,15 @@
 class FormattedNumberRange;
 namespace impl {
 class UFormattedNumberRangeData;
+class DecimalQuantity;
+class DecNum;
 }
 }
 
+#ifndef U_HIDE_INTERNAL_API
+using icu::number::impl::DecimalQuantity;
+#endif  /* U_HIDE_INTERNAL_API */
+
 /**
  * Defines rules for mapping non-negative numeric values onto a small set of
  * keywords. Rules are constructed from a text description, consisting
@@ -468,7 +474,7 @@
 
 #ifndef U_HIDE_INTERNAL_API
     /**
-     * Internal-only function that returns FixedDecimals instead of doubles.
+     * Internal-only function that returns DecimalQuantitys instead of doubles.
      *
      * Returns sample values for which select() would return the keyword.  If
      * the keyword is unknown, returns no values, but this is not an error.
@@ -488,7 +494,7 @@
      * @internal
      */
     int32_t getSamples(const UnicodeString &keyword,
-                       FixedDecimal *dest, int32_t destCapacity,
+                       DecimalQuantity *dest, int32_t destCapacity,
                        UErrorCode& status);
 #endif  /* U_HIDE_INTERNAL_API */
 
diff --git a/icu4c/source/test/intltest/plurults.cpp b/icu4c/source/test/intltest/plurults.cpp
index 54cc77a..8de9745 100644
--- a/icu4c/source/test/intltest/plurults.cpp
+++ b/icu4c/source/test/intltest/plurults.cpp
@@ -50,7 +50,9 @@
     TESTCASE_AUTO(testAPI);
     // TESTCASE_AUTO(testGetUniqueKeywordValue);
     TESTCASE_AUTO(testGetSamples);
-    TESTCASE_AUTO(testGetFixedDecimalSamples);
+    TESTCASE_AUTO(testGetDecimalQuantitySamples);
+    TESTCASE_AUTO(testGetOrAddSamplesFromString);
+    TESTCASE_AUTO(testGetOrAddSamplesFromStringCompactNotation);
     TESTCASE_AUTO(testSamplesWithExponent);
     TESTCASE_AUTO(testSamplesWithCompactNotation);
     TESTCASE_AUTO(testWithin);
@@ -396,9 +398,16 @@
     assertRuleKeyValue("a: n is 1", "other", UPLRULES_NO_UNIQUE_VALUE); // key matches default rule
 }
 
+/**
+ * Using the double API for getting plural samples, assert all samples match the keyword
+ * they are listed under, for all locales.
+ * 
+ * Specifically, iterate over all locales, get plural rules for the locale, iterate over every rule,
+ * then iterate over every sample in the rule, parse sample to a number (double), use that number
+ * as an input to .select() for the rules object, and assert the actual return plural keyword matches
+ * what we expect based on the plural rule string.
+ */
 void PluralRulesTest::testGetSamples() {
-    // TODO: fix samples, re-enable this test.
-
     // no get functional equivalent API in ICU4C, so just
     // test every locale...
     UErrorCode status = U_ZERO_ERROR;
@@ -457,21 +466,24 @@
     }
 }
 
-void PluralRulesTest::testGetFixedDecimalSamples() {
-    // TODO: fix samples, re-enable this test.
-
+/**
+ * Using the DecimalQuantity API for getting plural samples, assert all samples match the keyword
+ * they are listed under, for all locales.
+ * 
+ * Specifically, iterate over all locales, get plural rules for the locale, iterate over every rule,
+ * then iterate over every sample in the rule, parse sample to a number (DecimalQuantity), use that number
+ * as an input to .select() for the rules object, and assert the actual return plural keyword matches
+ * what we expect based on the plural rule string.
+ */
+void PluralRulesTest::testGetDecimalQuantitySamples() {
     // no get functional equivalent API in ICU4C, so just
     // test every locale...
     UErrorCode status = U_ZERO_ERROR;
     int32_t numLocales;
     const Locale* locales = Locale::getAvailableLocales(numLocales);
 
-    FixedDecimal values[1000];
+    DecimalQuantity values[1000];
     for (int32_t i = 0; U_SUCCESS(status) && i < numLocales; ++i) {
-        //if (uprv_strcmp(locales[i].getLanguage(), "fr") == 0 &&
-        //        logKnownIssue("21322", "PluralRules::getSamples cannot distinguish 1e5 from 100000")) {
-        //    continue;
-        //}
         LocalPointer<PluralRules> rules(PluralRules::forLocale(locales[i], status));
         if (U_FAILURE(status)) {
             break;
@@ -501,21 +513,24 @@
                 count = UPRV_LENGTHOF(values);
             }
             for (int32_t j = 0; j < count; ++j) {
-                if (values[j] == UPLRULES_NO_UNIQUE_VALUE_DECIMAL) {
+                if (values[j] == UPLRULES_NO_UNIQUE_VALUE_DECIMAL(status)) {
                     errln("got 'no unique value' among values");
                 } else {
+                    if (U_FAILURE(status)){
+                        errln(UnicodeString(u"getSamples() failed for sample ") +
+                            values[j].toExponentString() +
+                            UnicodeString(u", keyword ") + *keyword);
+                        continue;
+                    }
                     UnicodeString resultKeyword = rules->select(values[j]);
                     // if (strcmp(locales[i].getName(), "uk") == 0) {    // Debug only.
                     //     std::cout << "  uk " << US(resultKeyword).cstr() << " " << values[j] << std::endl;
                     // }
                     if (*keyword != resultKeyword) {
-                        if (values[j].exponent == 0 || !logKnownIssue("21714", "PluralRules::select treats 1c6 as 1")) {
-                            UnicodeString valueString(values[j].toString());
-                            char valueBuf[16];
-                            valueString.extract(0, valueString.length(), valueBuf, sizeof(valueBuf));
-                            errln("file %s, line %d, Locale %s, sample for keyword \"%s\":  %s, select(%s) returns keyword \"%s\"",
-                                      __FILE__, __LINE__, locales[i].getName(), US(*keyword).cstr(), valueBuf, valueBuf, US(resultKeyword).cstr());
-                        }
+                        errln("file %s, line %d, Locale %s, sample for keyword \"%s\":  %s, select(%s) returns keyword \"%s\"",
+                            __FILE__, __LINE__, locales[i].getName(), US(*keyword).cstr(),
+                            US(values[j].toExponentString()).cstr(), US(values[j].toExponentString()).cstr(),
+                            US(resultKeyword).cstr());
                     }
                 }
             }
@@ -523,6 +538,102 @@
     }
 }
 
+/**
+ * Test addSamples (Java) / getSamplesFromString (C++) to ensure the expansion of plural rule sample range
+ * expands to a sequence of sample numbers that is incremented as the right scale.
+ *
+ *  Do this for numbers with fractional digits but no exponent.
+ */
+void PluralRulesTest::testGetOrAddSamplesFromString() {
+    UErrorCode status = U_ZERO_ERROR;
+    UnicodeString description(u"testkeyword: e != 0 @decimal 2.0c6~4.0c6, …");
+    LocalPointer<PluralRules> rules(PluralRules::createRules(description, status));
+    if (U_FAILURE(status)) {
+        errln("Couldn't create plural rules from a string, with error = %s", u_errorName(status));
+        return;
+    }
+
+    LocalPointer<StringEnumeration> keywords(rules->getKeywords(status));
+    if (U_FAILURE(status)) {
+        errln("Couldn't get keywords from a parsed rules object, with error = %s", u_errorName(status));
+        return;
+    }
+
+    DecimalQuantity values[1000];
+    const UnicodeString keyword(u"testkeyword");
+    int32_t count = rules->getSamples(keyword, values, UPRV_LENGTHOF(values), status);
+    if (U_FAILURE(status)) {
+        errln(UnicodeString(u"getSamples() failed for plural rule keyword ") + keyword);
+        return;
+    }
+
+    UnicodeString expDqStrs[] = {
+        u"2.0c6", u"2.1c6", u"2.2c6", u"2.3c6", u"2.4c6", u"2.5c6", u"2.6c6", u"2.7c6", u"2.8c6", u"2.9c6",
+        u"3.0c6", u"3.1c6", u"3.2c6", u"3.3c6", u"3.4c6", u"3.5c6", u"3.6c6", u"3.7c6", u"3.8c6", u"3.9c6",
+        u"4.0c6"
+    };
+    assertEquals(u"Number of parsed samples from test string incorrect", 21, count);
+    for (int i = 0; i < count; i++) {
+        UnicodeString expDqStr = expDqStrs[i];
+        DecimalQuantity sample = values[i];
+        UnicodeString sampleStr = sample.toExponentString();
+
+        assertEquals(u"Expansion of sample range to sequence of sample values should increment at the right scale",
+            expDqStr, sampleStr);
+    }
+}
+
+/**
+ * Test addSamples (Java) / getSamplesFromString (C++) to ensure the expansion of plural rule sample range
+ * expands to a sequence of sample numbers that is incremented as the right scale.
+ *
+ *  Do this for numbers written in a notation that has an exponent, for which the number is an
+ *  integer (also as defined in the UTS 35 spec for the plural operands) but whose representation
+ *  has fractional digits in the significand written before the exponent.
+ */
+void PluralRulesTest::testGetOrAddSamplesFromStringCompactNotation() {
+    UErrorCode status = U_ZERO_ERROR;
+    UnicodeString description(u"testkeyword: e != 0 @decimal 2.0~4.0, …");
+    LocalPointer<PluralRules> rules(PluralRules::createRules(description, status));
+    if (U_FAILURE(status)) {
+        errln("Couldn't create plural rules from a string, with error = %s", u_errorName(status));
+        return;
+    }
+
+    LocalPointer<StringEnumeration> keywords(rules->getKeywords(status));
+    if (U_FAILURE(status)) {
+        errln("Couldn't get keywords from a parsed rules object, with error = %s", u_errorName(status));
+        return;
+    }
+
+    DecimalQuantity values[1000];
+    const UnicodeString keyword(u"testkeyword");
+    int32_t count = rules->getSamples(keyword, values, UPRV_LENGTHOF(values), status);
+    if (U_FAILURE(status)) {
+        errln(UnicodeString(u"getSamples() failed for plural rule keyword ") + keyword);
+        return;
+    }
+
+    UnicodeString expDqStrs[] = {
+        u"2.0", u"2.1", u"2.2", u"2.3", u"2.4", u"2.5", u"2.6", u"2.7", u"2.8", u"2.9",
+        u"3.0", u"3.1", u"3.2", u"3.3", u"3.4", u"3.5", u"3.6", u"3.7", u"3.8", u"3.9",
+        u"4.0"
+    };
+    assertEquals(u"Number of parsed samples from test string incorrect", 21, count);
+    for (int i = 0; i < count; i++) {
+        UnicodeString expDqStr = expDqStrs[i];
+        DecimalQuantity sample = values[i];
+        UnicodeString sampleStr = sample.toExponentString();
+
+        assertEquals(u"Expansion of sample range to sequence of sample values should increment at the right scale",
+            expDqStr, sampleStr);
+    }
+}
+
+/**
+ * This test is for the support of X.YeZ scientific notation of numbers in
+ * the plural sample string.
+ */
 void PluralRulesTest::testSamplesWithExponent() {
     // integer samples
     UErrorCode status = U_ZERO_ERROR;
@@ -538,9 +649,9 @@
         errln("Couldn't create plural rules from a string using exponent notation, with error = %s", u_errorName(status));
         return;
     }
-    checkNewSamples(description, test, u"one", u"@integer 0, 1, 1e5", FixedDecimal(0));
-    checkNewSamples(description, test, u"many", u"@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", FixedDecimal(1000000));
-    checkNewSamples(description, test, u"other", u"@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", FixedDecimal(2));
+    checkNewSamples(description, test, u"one", u"@integer 0, 1, 1e5", DecimalQuantity::fromExponentString(u"0", status));
+    checkNewSamples(description, test, u"many", u"@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", DecimalQuantity::fromExponentString(u"1000000", status));
+    checkNewSamples(description, test, u"other", u"@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", DecimalQuantity::fromExponentString(u"2", status));
 
     // decimal samples
     status = U_ZERO_ERROR;
@@ -555,12 +666,15 @@
         errln("Couldn't create plural rules from a string using exponent notation, with error = %s", u_errorName(status));
         return;
     }
-    checkNewSamples(description2, test2, u"one", u"@decimal 0.0~1.5, 1.1e5", FixedDecimal(0, 1));
-    checkNewSamples(description2, test2, u"many", u"@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", FixedDecimal::createWithExponent(2.1, 1, 6));
-    checkNewSamples(description2, test2, u"other", u"@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", FixedDecimal(2.0, 1));
+    checkNewSamples(description2, test2, u"one", u"@decimal 0.0~1.5, 1.1e5", DecimalQuantity::fromExponentString(u"0.0", status));
+    checkNewSamples(description2, test2, u"many", u"@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", DecimalQuantity::fromExponentString(u"2.1c6", status));
+    checkNewSamples(description2, test2, u"other", u"@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", DecimalQuantity::fromExponentString(u"2.0", status));
 }
 
-
+/**
+ * This test is for the support of X.YcZ compact notation of numbers in
+ * the plural sample string.
+ */
 void PluralRulesTest::testSamplesWithCompactNotation() {
     // integer samples
     UErrorCode status = U_ZERO_ERROR;
@@ -576,9 +690,9 @@
         errln("Couldn't create plural rules from a string using exponent notation, with error = %s", u_errorName(status));
         return;
     }
-    checkNewSamples(description, test, u"one", u"@integer 0, 1, 1c5", FixedDecimal(0));
-    checkNewSamples(description, test, u"many", u"@integer 1000000, 2c6, 3c6, 4c6, 5c6, 6c6, 7c6, …", FixedDecimal(1000000));
-    checkNewSamples(description, test, u"other", u"@integer 2~17, 100, 1000, 10000, 100000, 2c5, 3c5, 4c5, 5c5, 6c5, 7c5, …", FixedDecimal(2));
+    checkNewSamples(description, test, u"one", u"@integer 0, 1, 1c5", DecimalQuantity::fromExponentString(u"0", status));
+    checkNewSamples(description, test, u"many", u"@integer 1000000, 2c6, 3c6, 4c6, 5c6, 6c6, 7c6, …", DecimalQuantity::fromExponentString(u"1000000", status));
+    checkNewSamples(description, test, u"other", u"@integer 2~17, 100, 1000, 10000, 100000, 2c5, 3c5, 4c5, 5c5, 6c5, 7c5, …", DecimalQuantity::fromExponentString(u"2", status));
 
     // decimal samples
     status = U_ZERO_ERROR;
@@ -593,9 +707,9 @@
         errln("Couldn't create plural rules from a string using exponent notation, with error = %s", u_errorName(status));
         return;
     }
-    checkNewSamples(description2, test2, u"one", u"@decimal 0.0~1.5, 1.1c5", FixedDecimal(0, 1));
-    checkNewSamples(description2, test2, u"many", u"@decimal 2.1c6, 3.1c6, 4.1c6, 5.1c6, 6.1c6, 7.1c6, …", FixedDecimal::createWithExponent(2.1, 1, 6));
-    checkNewSamples(description2, test2, u"other", u"@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1c5, 3.1c5, 4.1c5, 5.1c5, 6.1c5, 7.1c5, …", FixedDecimal(2.0, 1));
+    checkNewSamples(description2, test2, u"one", u"@decimal 0.0~1.5, 1.1c5", DecimalQuantity::fromExponentString(u"0.0", status));
+    checkNewSamples(description2, test2, u"many", u"@decimal 2.1c6, 3.1c6, 4.1c6, 5.1c6, 6.1c6, 7.1c6, …", DecimalQuantity::fromExponentString(u"2.1c6", status));
+    checkNewSamples(description2, test2, u"other", u"@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1c5, 3.1c5, 4.1c5, 5.1c5, 6.1c5, 7.1c5, …", DecimalQuantity::fromExponentString(u"2.0", status));
 }
 
 void PluralRulesTest::checkNewSamples(
@@ -603,17 +717,17 @@
         const LocalPointer<PluralRules> &test,
         UnicodeString keyword,
         UnicodeString samplesString,
-        FixedDecimal firstInRange) {
+        DecimalQuantity firstInRange) {
 
     UErrorCode status = U_ZERO_ERROR;
-    FixedDecimal samples[1000];
+    DecimalQuantity samples[1000];
     
     test->getSamples(keyword, samples, UPRV_LENGTHOF(samples), status);
     if (U_FAILURE(status)) {
         errln("Couldn't retrieve plural samples, with error = %s", u_errorName(status));
         return;
     }
-    FixedDecimal actualFirstSample = samples[0];
+    DecimalQuantity actualFirstSample = samples[0];
 
     if (!(firstInRange == actualFirstSample)) {
         CStr descCstr(description);
@@ -776,6 +890,11 @@
 
 // For the time being, the  compact notation exponent operand `c` is an alias
 // for the scientific exponent operand `e` and compact notation.
+/**
+ * Test the proper plural rule keyword selection given an input number that is
+ * already formatted into scientific notation. This exercises the `e` plural operand
+ * for the formatted number.
+ */
 void
 PluralRulesTest::testScientificPluralKeyword() {
     IcuTestErrorCode errorCode(*this, "testScientificPluralKeyword");
@@ -838,6 +957,11 @@
     }
 }
 
+/**
+ * Test the proper plural rule keyword selection given an input number that is
+ * already formatted into compact notation. This exercises the `c` plural operand
+ * for the formatted number.
+ */
 void
 PluralRulesTest::testCompactDecimalPluralKeyword() {
     IcuTestErrorCode errorCode(*this, "testCompactDecimalPluralKeyword");
diff --git a/icu4c/source/test/intltest/plurults.h b/icu4c/source/test/intltest/plurults.h
index 76ecb6b..f02a484 100644
--- a/icu4c/source/test/intltest/plurults.h
+++ b/icu4c/source/test/intltest/plurults.h
@@ -14,6 +14,7 @@
 #if !UCONFIG_NO_FORMATTING
 
 #include "intltest.h"
+#include "number_decimalquantity.h"
 #include "unicode/localpointer.h"
 #include "unicode/plurrule.h"
 
@@ -30,7 +31,9 @@
     void testAPI();
     void testGetUniqueKeywordValue();
     void testGetSamples();
-    void testGetFixedDecimalSamples();
+    void testGetDecimalQuantitySamples();
+    void testGetOrAddSamplesFromString();
+    void testGetOrAddSamplesFromStringCompactNotation();
     void testSamplesWithExponent();
     void testSamplesWithCompactNotation();
     void testWithin();
@@ -55,7 +58,7 @@
                          const LocalPointer<PluralRules> &test,
                          UnicodeString keyword,
                          UnicodeString samplesString,
-                         FixedDecimal firstInRange);
+                         ::icu::number::impl::DecimalQuantity firstInRange);
     UnicodeString getPluralKeyword(const LocalPointer<PluralRules> &rules,
                                    Locale locale, double number, const char16_t* skeleton);
     void checkSelect(const LocalPointer<PluralRules> &rules, UErrorCode &status, 
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java b/icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java
index bf0e411..9cc7923 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java
@@ -15,21 +15,22 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
-import java.util.TreeSet;
 import java.util.regex.Pattern;
 
 import com.ibm.icu.impl.PluralRulesLoader;
 import com.ibm.icu.impl.StandardPlural;
+import com.ibm.icu.impl.number.DecimalQuantity;
+import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
 import com.ibm.icu.impl.number.range.StandardPluralRanges;
 import com.ibm.icu.number.FormattedNumber;
 import com.ibm.icu.number.FormattedNumberRange;
@@ -330,6 +331,16 @@
     public static final double NO_UNIQUE_VALUE = -0.00123456777;
 
     /**
+     * Value returned by {@link #getUniqueKeywordDecimalQuantityValue} when there is no
+     * unique value to return.
+     * @internal CLDR
+     * @deprecated This API is ICU internal only.
+     */
+    @Deprecated
+    public static final DecimalQuantity NO_UNIQUE_VALUE_DECIMAL_QUANTITY =
+        new DecimalQuantity_DualStorageBCD(-0.00123456777);
+
+    /**
      * Type of plurals and PluralRules.
      * @stable ICU 50
      */
@@ -868,50 +879,6 @@
         }
 
         /**
-         * @internal CLDR
-         * @deprecated This API is ICU internal only.
-         */
-        @Deprecated
-        public FixedDecimal (String n) {
-            // Ugly, but for samples we don't care.
-            this(parseDecimalSampleRangeNumString(n));
-        }
-
-        /**
-         * @internal CLDR
-         * @deprecated This API is ICU internal only
-         */
-        @Deprecated
-        private static FixedDecimal parseDecimalSampleRangeNumString(String num) {
-            if (num.contains("e") || num.contains("c")) {
-                int ePos = num.lastIndexOf('e');
-                if (ePos < 0) {
-                    ePos = num.lastIndexOf('c');
-                }
-                int expNumPos = ePos + 1;
-                String exponentStr = num.substring(expNumPos);
-                int exponent = Integer.parseInt(exponentStr);
-                String fractionStr = num.substring(0, ePos);
-                return FixedDecimal.createWithExponent(
-                        Double.parseDouble(fractionStr),
-                        getVisibleFractionCount(fractionStr),
-                        exponent);
-            } else {
-                return new FixedDecimal(Double.parseDouble(num), getVisibleFractionCount(num));
-            }
-        }
-
-        private static int getVisibleFractionCount(String value) {
-            value = value.trim();
-            int decimalPos = value.indexOf('.') + 1;
-            if (decimalPos == 0) {
-                return 0;
-            } else {
-                return value.length() - decimalPos;
-            }
-        }
-
-        /**
          * {@inheritDoc}
          *
          * @internal CLDR
@@ -1070,19 +1037,6 @@
             return (isNegative ? -source : source) * Math.pow(10, exponent);
         }
 
-        /**
-         * @internal CLDR
-         * @deprecated This API is ICU internal only.
-         */
-        @Deprecated
-        public long getShiftedValue() {
-            if (exponent != 0 && visibleDecimalDigitCount == 0 && decimalDigits == 0) {
-                // Need to take exponent into account if we have it
-                return (long)(source * Math.pow(10, exponent));
-            }
-            return integerValue * baseFactor + decimalDigits;
-        }
-
         private void writeObject(
                 ObjectOutputStream out)
                         throws IOException {
@@ -1141,31 +1095,32 @@
     }
 
     /**
-     * A range of NumberInfo that includes all values with the same visibleFractionDigitCount.
+     * A range of DecimalQuantity representing PluralRules samples that includes
+     * all values with the same visibleFractionDigitCount.
      * @internal CLDR
      * @deprecated This API is ICU internal only.
      */
     @Deprecated
-    public static class FixedDecimalRange {
+    public static class DecimalQuantitySamplesRange {
         /**
          * @internal CLDR
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public final FixedDecimal start;
+        public final DecimalQuantity start;
         /**
          * @internal CLDR
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public final FixedDecimal end;
+        public final DecimalQuantity end;
         /**
          * @internal CLDR
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public FixedDecimalRange(FixedDecimal start, FixedDecimal end) {
-            if (start.visibleDecimalDigitCount != end.visibleDecimalDigitCount) {
+        public DecimalQuantitySamplesRange(DecimalQuantity start, DecimalQuantity end) {
+            if (start.getPluralOperand(Operand.v)!= end.getPluralOperand(Operand.v)) {
                 throw new IllegalArgumentException("Ranges must have the same number of visible decimals: " + start + "~" + end);
             }
             this.start = start;
@@ -1178,17 +1133,18 @@
         @Deprecated
         @Override
         public String toString() {
-            return start + (end == start ? "" : "~" + end);
+            return start.toExponentString() + (end == start ? "" : "~" + end.toExponentString());
         }
     }
 
     /**
-     * A list of NumberInfo that includes all values with the same visibleFractionDigitCount.
+     * A list of DecimalQuantity representing PluralRules that includes all
+     * values with the same visibleFractionDigitCount.
      * @internal CLDR
      * @deprecated This API is ICU internal only.
      */
     @Deprecated
-    public static class FixedDecimalSamples {
+    public static class DecimalQuantitySamples {
         /**
          * @internal CLDR
          * @deprecated This API is ICU internal only.
@@ -1200,7 +1156,7 @@
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public final Set<FixedDecimalRange> samples;
+        public final Set<DecimalQuantitySamplesRange> samples;
         /**
          * @internal CLDR
          * @deprecated This API is ICU internal only.
@@ -1212,7 +1168,7 @@
          * @param sampleType
          * @param samples
          */
-        private FixedDecimalSamples(SampleType sampleType, Set<FixedDecimalRange> samples, boolean bounded) {
+        private DecimalQuantitySamples(SampleType sampleType, Set<DecimalQuantitySamplesRange> samples, boolean bounded) {
             super();
             this.sampleType = sampleType;
             this.samples = samples;
@@ -1221,11 +1177,11 @@
         /*
          * Parse a list of the form described in CLDR. The source must be trimmed.
          */
-        static FixedDecimalSamples parse(String source) {
+        static DecimalQuantitySamples parse(String source) {
             SampleType sampleType2;
             boolean bounded2 = true;
             boolean haveBound = false;
-            Set<FixedDecimalRange> samples2 = new LinkedHashSet<>();
+            Set<DecimalQuantitySamplesRange> samples2 = new LinkedHashSet<>();
 
             if (source.startsWith("integer")) {
                 sampleType2 = SampleType.INTEGER;
@@ -1248,25 +1204,33 @@
                 String[] rangeParts = TILDE_SEPARATED.split(range, 0);
                 switch (rangeParts.length) {
                 case 1:
-                    FixedDecimal sample = new FixedDecimal(rangeParts[0]);
+                    DecimalQuantity sample =
+                        DecimalQuantity_DualStorageBCD.fromExponentString(rangeParts[0]);
                     checkDecimal(sampleType2, sample);
-                    samples2.add(new FixedDecimalRange(sample, sample));
+                    samples2.add(new DecimalQuantitySamplesRange(sample, sample));
                     break;
                 case 2:
-                    FixedDecimal start = new FixedDecimal(rangeParts[0]);
-                    FixedDecimal end = new FixedDecimal(rangeParts[1]);
+                    DecimalQuantity start =
+                            DecimalQuantity_DualStorageBCD.fromExponentString(rangeParts[0]);
+                    DecimalQuantity end =
+                            DecimalQuantity_DualStorageBCD.fromExponentString(rangeParts[1]);
                     checkDecimal(sampleType2, start);
                     checkDecimal(sampleType2, end);
-                    samples2.add(new FixedDecimalRange(start, end));
+                    samples2.add(new DecimalQuantitySamplesRange(start, end));
                     break;
                 default: throw new IllegalArgumentException("Ill-formed number range: " + range);
                 }
             }
-            return new FixedDecimalSamples(sampleType2, Collections.unmodifiableSet(samples2), bounded2);
+            return new DecimalQuantitySamples(sampleType2, Collections.unmodifiableSet(samples2), bounded2);
         }
 
-        private static void checkDecimal(SampleType sampleType2, FixedDecimal sample) {
-            if ((sampleType2 == SampleType.INTEGER) != (sample.getVisibleDecimalDigitCount() == 0)) {
+        private static void checkDecimal(SampleType sampleType2, DecimalQuantity sample) {
+            // TODO(CLDR-15452): Remove the need for the fallback check for exponent notation integers classified
+            // as "@decimal" type samples, if/when changes are made to
+            // resolve https://unicode-org.atlassian.net/browse/CLDR-15452
+            if ((sampleType2 == SampleType.INTEGER && sample.getPluralOperand(Operand.v) != 0)
+                    || (sampleType2 == SampleType.DECIMAL && sample.getPluralOperand(Operand.v) == 0
+                        && sample.getPluralOperand(Operand.e) == 0)) {
                 throw new IllegalArgumentException("Ill-formed number range: " + sample);
             }
         }
@@ -1276,17 +1240,64 @@
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public Set<Double> addSamples(Set<Double> result) {
-            for (FixedDecimalRange item : samples) {
-                // we have to convert to longs so we don't get strange double issues
-                long startDouble = item.start.getShiftedValue();
-                long endDouble = item.end.getShiftedValue();
+        public Collection<Double> addSamples(Collection<Double> result) {
+            addSamples(result, null);
+            return result;
+        }
 
-                for (long d = startDouble; d <= endDouble; d += 1) {
-                    result.add(d/(double)item.start.baseFactor);
+        /**
+         * @internal CLDR
+         * @deprecated This API is ICU internal only.
+         */
+        @Deprecated
+        public Collection<DecimalQuantity> addDecimalQuantitySamples(Collection<DecimalQuantity> result) {
+            addSamples(null, result);
+            return result;
+        }
+
+        /**
+         * @internal CLDR
+         * @deprecated This API is ICU internal only.
+         */
+        @Deprecated
+        public void addSamples(Collection<Double> doubleResult, Collection<DecimalQuantity> dqResult) {
+            if ((doubleResult == null && dqResult == null)
+                    || (doubleResult != null && dqResult != null)) {
+                return;
+            }
+            boolean isDouble = doubleResult != null;
+            for (DecimalQuantitySamplesRange range : samples) {
+                DecimalQuantity start = range.start;
+                DecimalQuantity end = range.end;
+                int lowerDispMag = start.getLowerDisplayMagnitude();
+                int exponent = start.getExponent();
+                int incrementScale = lowerDispMag + exponent;
+                BigDecimal incrementBd = BigDecimal.ONE.movePointRight(incrementScale);
+
+                for (DecimalQuantity dq = start.createCopy(); dq.toDouble() <= end.toDouble(); ) {
+                    if (isDouble) {
+                        double dblValue = dq.toDouble();
+                        // Hack Alert: don't return any decimal samples with integer values that
+                        //    originated from a format with trailing decimals.
+                        //    This API is returning doubles, which can't distinguish having displayed
+                        //    zeros to the right of the decimal.
+                        //    This results in test failures with values mapping back to a different keyword.
+                        if (!(dblValue == Math.floor(dblValue)) && dq.getPluralOperand(Operand.v) > 0) {
+                            doubleResult.add(dblValue);
+                        }
+                    } else {
+                        dqResult.add(dq);
+                    }
+
+                    // Increment dq for next iteration
+                    java.math.BigDecimal dqBd = dq.toBigDecimal();
+                    java.math.BigDecimal newDqBd = dqBd.add(incrementBd);
+                    dq = new DecimalQuantity_DualStorageBCD(newDqBd);
+                    dq.setMinFraction(-lowerDispMag);
+                    dq.adjustMagnitude(-exponent);
+                    dq.adjustExponent(exponent);
                 }
             }
-            return result;
         }
 
         /**
@@ -1298,7 +1309,7 @@
         public String toString() {
             StringBuilder b = new StringBuilder("@").append(sampleType.toString().toLowerCase(Locale.ENGLISH));
             boolean first = true;
-            for (FixedDecimalRange item : samples) {
+            for (DecimalQuantitySamplesRange item : samples) {
                 if (first) {
                     first = false;
                 } else {
@@ -1317,7 +1328,7 @@
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public Set<FixedDecimalRange> getSamples() {
+        public Set<DecimalQuantitySamplesRange> getSamples() {
             return samples;
         }
 
@@ -1326,10 +1337,10 @@
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
-        public void getStartEndSamples(Set<FixedDecimal> target) {
-            for (FixedDecimalRange item : samples) {
-                target.add(item.start);
-                target.add(item.end);
+        public void getStartEndSamples(Set<DecimalQuantity> target) {
+            for (DecimalQuantitySamplesRange range : samples) {
+                target.add(range.start);
+                target.add(range.end);
             }
         }
     }
@@ -1610,19 +1621,19 @@
         description = description.substring(x+1).trim();
         String[] constraintOrSamples = AT_SEPARATED.split(description, 0);
         boolean sampleFailure = false;
-        FixedDecimalSamples integerSamples = null, decimalSamples = null;
+        DecimalQuantitySamples integerSamples = null, decimalSamples = null;
         switch (constraintOrSamples.length) {
         case 1: break;
         case 2:
-            integerSamples = FixedDecimalSamples.parse(constraintOrSamples[1]);
+            integerSamples = DecimalQuantitySamples.parse(constraintOrSamples[1]);
             if (integerSamples.sampleType == SampleType.DECIMAL) {
                 decimalSamples = integerSamples;
                 integerSamples = null;
             }
             break;
         case 3:
-            integerSamples = FixedDecimalSamples.parse(constraintOrSamples[1]);
-            decimalSamples = FixedDecimalSamples.parse(constraintOrSamples[2]);
+            integerSamples = DecimalQuantitySamples.parse(constraintOrSamples[1]);
+            decimalSamples = DecimalQuantitySamples.parse(constraintOrSamples[2]);
             if (integerSamples.sampleType != SampleType.INTEGER || decimalSamples.sampleType != SampleType.DECIMAL) {
                 throw new IllegalArgumentException("Must have @integer then @decimal in " + description);
             }
@@ -1857,10 +1868,10 @@
         private static final long serialVersionUID = 1;
         private final String keyword;
         private final Constraint constraint;
-        private final FixedDecimalSamples integerSamples;
-        private final FixedDecimalSamples decimalSamples;
+        private final DecimalQuantitySamples integerSamples;
+        private final DecimalQuantitySamples decimalSamples;
 
-        public Rule(String keyword, Constraint constraint, FixedDecimalSamples integerSamples, FixedDecimalSamples decimalSamples) {
+        public Rule(String keyword, Constraint constraint, DecimalQuantitySamples integerSamples, DecimalQuantitySamples decimalSamples) {
             this.keyword = keyword;
             this.constraint = constraint;
             this.integerSamples = integerSamples;
@@ -1972,7 +1983,7 @@
 
         public boolean isLimited(String keyword, SampleType sampleType) {
             if (hasExplicitBoundingInfo) {
-                FixedDecimalSamples mySamples = getDecimalSamples(keyword, sampleType);
+                DecimalQuantitySamples mySamples = getDecimalSamples(keyword, sampleType);
                 return mySamples == null ? true : mySamples.bounded;
             }
 
@@ -2024,7 +2035,7 @@
             return false;
         }
 
-        public FixedDecimalSamples getDecimalSamples(String keyword, SampleType sampleType) {
+        public DecimalQuantitySamples getDecimalSamples(String keyword, SampleType sampleType) {
             for (Rule rule : rules) {
                 if (rule.getKeyword().equals(keyword)) {
                     return sampleType == SampleType.INTEGER ? rule.integerSamples : rule.decimalSamples;
@@ -2285,11 +2296,29 @@
      * @stable ICU 4.8
      */
     public double getUniqueKeywordValue(String keyword) {
-        Collection<Double> values = getAllKeywordValues(keyword);
+        DecimalQuantity uniqValDq = getUniqueKeywordDecimalQuantityValue(keyword);
+        if (uniqValDq.equals(NO_UNIQUE_VALUE_DECIMAL_QUANTITY)) {
+            return NO_UNIQUE_VALUE;
+        } else {
+            return uniqValDq.toDouble();
+        }
+    }
+
+    /**
+     * Returns the unique value that this keyword matches, or {@link #NO_UNIQUE_VALUE}
+     * if the keyword matches multiple values or is not defined for this PluralRules.
+     *
+     * @param keyword the keyword to check for a unique value
+     * @internal Visible For Testing
+     * @deprecated This API is ICU internal only.
+     */
+    @Deprecated
+    public DecimalQuantity getUniqueKeywordDecimalQuantityValue(String keyword) {
+        Collection<DecimalQuantity> values = getAllKeywordDecimalQuantityValues(keyword);
         if (values != null && values.size() == 1) {
             return values.iterator().next();
         }
-        return NO_UNIQUE_VALUE;
+        return NO_UNIQUE_VALUE_DECIMAL_QUANTITY;
     }
 
     /**
@@ -2302,6 +2331,31 @@
      * @stable ICU 4.8
      */
     public Collection<Double> getAllKeywordValues(String keyword) {
+        Collection<DecimalQuantity> samples = getAllKeywordDecimalQuantityValues(keyword);
+        if (samples == null) {
+            return null;
+        } else {
+            Collection<Double> result = new LinkedHashSet<>();
+            for (DecimalQuantity dq : samples) {
+                result.add(dq.toDouble());
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Returns all the values that trigger this keyword, or null if the number of such
+     * values is unlimited.
+     *
+     * @param keyword the keyword
+     * @return the values that trigger this keyword, or null.  The returned collection
+     * is immutable. It will be empty if the keyword is not defined.
+     *
+     * @internal Visible For Testing
+     * @deprecated This API is ICU internal only.
+     */
+    @Deprecated
+    public Collection<DecimalQuantity> getAllKeywordDecimalQuantityValues(String keyword) {
         return getAllKeywordValues(keyword, SampleType.INTEGER);
     }
 
@@ -2318,12 +2372,11 @@
      * @deprecated This API is ICU internal only.
      */
     @Deprecated
-    public Collection<Double> getAllKeywordValues(String keyword, SampleType type) {
+    public Collection<DecimalQuantity> getAllKeywordValues(String keyword, SampleType type) {
         if (!isLimited(keyword, type)) {
             return null;
         }
-        Collection<Double> samples = getSamples(keyword, type);
-        return samples == null ? null : Collections.unmodifiableCollection(samples);
+        return getDecimalQuantitySamples(keyword, type);
     }
 
     /**
@@ -2341,6 +2394,22 @@
     }
 
     /**
+     * Returns a list of integer values for which select() would return that keyword,
+     * or null if the keyword is not defined. The returned collection is unmodifiable.
+     * The returned list is not complete, and there might be additional values that
+     * would return the keyword.
+     *
+     * @param keyword the keyword to test
+     * @return a list of values matching the keyword.
+     * @internal CLDR
+     * @deprecated ICU internal only
+     */
+    @Deprecated
+  public Collection<DecimalQuantity> getDecimalQuantitySamples(String keyword) {
+        return getDecimalQuantitySamples(keyword, SampleType.INTEGER);
+    }
+
+    /**
      * Returns a list of values for which select() would return that keyword,
      * or null if the keyword is not defined.
      * The returned collection is unmodifiable.
@@ -2356,15 +2425,43 @@
      */
     @Deprecated
     public Collection<Double> getSamples(String keyword, SampleType sampleType) {
+        Collection<DecimalQuantity> samples = getDecimalQuantitySamples(keyword, sampleType);
+        if (samples == null) {
+            return null;
+        } else {
+            Collection<Double> result = new LinkedHashSet<>();
+            for (DecimalQuantity dq: samples) {
+                result.add(dq.toDouble());
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Returns a list of values for which select() would return that keyword,
+     * or null if the keyword is not defined.
+     * The returned collection is unmodifiable.
+     * The returned list is not complete, and there might be additional values that
+     * would return the keyword. The keyword might be defined, and yet have an empty set of samples,
+     * IF there are samples for the other sampleType.
+     *
+     * @param keyword the keyword to test
+     * @param sampleType the type of samples requested, INTEGER or DECIMAL
+     * @return a list of values matching the keyword.
+     * @internal CLDR
+     * @deprecated ICU internal only
+     */
+    @Deprecated
+    public Collection<DecimalQuantity> getDecimalQuantitySamples(String keyword, SampleType sampleType) {
         if (!keywords.contains(keyword)) {
             return null;
         }
-        Set<Double> result = new TreeSet<>();
+        Set<DecimalQuantity> result = new LinkedHashSet<>();
 
         if (rules.hasExplicitBoundingInfo) {
-            FixedDecimalSamples samples = rules.getDecimalSamples(keyword, sampleType);
+            DecimalQuantitySamples samples = rules.getDecimalSamples(keyword, sampleType);
             return samples == null ? Collections.unmodifiableSet(result)
-                    : Collections.unmodifiableSet(samples.addSamples(result));
+                    : Collections.unmodifiableCollection(samples.addDecimalQuantitySamples(result));
         }
 
         // hack in case the rule is created without explicit samples
@@ -2373,28 +2470,31 @@
         switch (sampleType) {
         case INTEGER:
             for (int i = 0; i < 200; ++i) {
-                if (!addSample(keyword, i, maxCount, result)) {
+                if (!addSample(keyword, new DecimalQuantity_DualStorageBCD(i), maxCount, result)) {
                     break;
                 }
             }
-            addSample(keyword, 1000000, maxCount, result); // hack for Welsh
+            addSample(keyword, new DecimalQuantity_DualStorageBCD(1000000), maxCount, result); // hack for Welsh
             break;
         case DECIMAL:
             for (int i = 0; i < 2000; ++i) {
-                if (!addSample(keyword, new FixedDecimal(i/10d, 1), maxCount, result)) {
+                DecimalQuantity_DualStorageBCD nextSample = new DecimalQuantity_DualStorageBCD(i);
+                nextSample.adjustMagnitude(-1);
+                if (!addSample(keyword, nextSample, maxCount, result)) {
                     break;
                 }
             }
-            addSample(keyword, new FixedDecimal(1000000d, 1), maxCount, result); // hack for Welsh
+            addSample(keyword, DecimalQuantity_DualStorageBCD.fromExponentString("1000000.0"), maxCount, result); // hack for Welsh
             break;
         }
+
         return result.size() == 0 ? null : Collections.unmodifiableSet(result);
     }
 
-    private boolean addSample(String keyword, Number sample, int maxCount, Set<Double> result) {
-        String selectedKeyword = sample instanceof FixedDecimal ? select((FixedDecimal)sample) : select(sample.doubleValue());
+    private boolean addSample(String keyword, DecimalQuantity sample, int maxCount, Set<DecimalQuantity> result) {
+        String selectedKeyword = select(sample);
         if (selectedKeyword.equals(keyword)) {
-            result.add(sample.doubleValue());
+            result.add(sample);
             if (--maxCount < 0) {
                 return false;
             }
@@ -2416,7 +2516,7 @@
      * @deprecated This API is ICU internal only.
      */
     @Deprecated
-    public FixedDecimalSamples getDecimalSamples(String keyword, SampleType sampleType) {
+    public DecimalQuantitySamples getDecimalSamples(String keyword, SampleType sampleType) {
         return rules.getDecimalSamples(keyword, sampleType);
     }
 
@@ -2525,14 +2625,14 @@
      *            the offset used, or 0.0d if not. Internally, the offset is subtracted from each explicit value before
      *            checking against the keyword values.
      * @param explicits
-     *            a set of Doubles that are used explicitly (eg [=0], "[=1]"). May be empty or null.
+     *            a set of {@code DecimalQuantity}s that are used explicitly (eg [=0], "[=1]"). May be empty or null.
      * @param uniqueValue
      *            If non null, set to the unique value.
      * @return the KeywordStatus
      * @draft ICU 50
      */
-    public KeywordStatus getKeywordStatus(String keyword, int offset, Set<Double> explicits,
-            Output<Double> uniqueValue) {
+    public KeywordStatus getKeywordStatus(String keyword, int offset, Set<DecimalQuantity> explicits,
+            Output<DecimalQuantity> uniqueValue) {
         return getKeywordStatus(keyword, offset, explicits, uniqueValue, SampleType.INTEGER);
     }
     /**
@@ -2544,7 +2644,7 @@
      *            the offset used, or 0.0d if not. Internally, the offset is subtracted from each explicit value before
      *            checking against the keyword values.
      * @param explicits
-     *            a set of Doubles that are used explicitly (eg [=0], "[=1]"). May be empty or null.
+     *            a set of {@code DecimalQuantity}s that are used explicitly (eg [=0], "[=1]"). May be empty or null.
      * @param sampleType
      *            request KeywordStatus relative to INTEGER or DECIMAL values
      * @param uniqueValue
@@ -2554,8 +2654,8 @@
      * @deprecated This API is ICU internal only.
      */
     @Deprecated
-    public KeywordStatus getKeywordStatus(String keyword, int offset, Set<Double> explicits,
-            Output<Double> uniqueValue, SampleType sampleType) {
+    public KeywordStatus getKeywordStatus(String keyword, int offset,
+            Set<DecimalQuantity> explicits, Output<DecimalQuantity> uniqueValue, SampleType sampleType) {
         if (uniqueValue != null) {
             uniqueValue.value = null;
         }
@@ -2568,7 +2668,7 @@
             return KeywordStatus.UNBOUNDED;
         }
 
-        Collection<Double> values = getSamples(keyword, sampleType);
+        Collection<DecimalQuantity> values = getDecimalQuantitySamples(keyword, sampleType);
 
         int originalSize = values.size();
 
@@ -2590,9 +2690,12 @@
 
         // Compute if the quick test is insufficient.
 
-        HashSet<Double> subtractedSet = new HashSet<>(values);
-        for (Double explicit : explicits) {
-            subtractedSet.remove(explicit - offset);
+        ArrayList<DecimalQuantity> subtractedSet = new ArrayList<>(values);
+        for (DecimalQuantity explicit : explicits) {
+            BigDecimal explicitBd = explicit.toBigDecimal();
+            BigDecimal valToRemoveBd = explicitBd.subtract(new BigDecimal(offset));
+            DecimalQuantity_DualStorageBCD valToRemove = new DecimalQuantity_DualStorageBCD(valToRemoveBd);
+            subtractedSet.remove(valToRemove);
         }
         if (subtractedSet.size() == 0) {
             return KeywordStatus.SUPPRESSED;
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/PluralSamples.java b/icu4j/main/classes/core/src/com/ibm/icu/text/PluralSamples.java
deleted file mode 100644
index 6b260c6..0000000
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/PluralSamples.java
+++ /dev/null
@@ -1,332 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2013-2015, International Business Machines Corporation and
- * others. All Rights Reserved.
- *******************************************************************************
- */
-package com.ibm.icu.text;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeSet;
-
-import com.ibm.icu.text.PluralRules.FixedDecimal;
-import com.ibm.icu.text.PluralRules.KeywordStatus;
-import com.ibm.icu.util.Output;
-
-/**
- * @author markdavis
- * Refactor samples as first step to moving into CLDR
- * 
- * @internal
- * @deprecated This API is ICU internal only.
- */
-@Deprecated
-public class PluralSamples {
-
-    private PluralRules pluralRules;
-    private final Map<String, List<Double>> _keySamplesMap;
-
-    /**
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    public final Map<String, Boolean> _keyLimitedMap;
-    private final Map<String, Set<FixedDecimal>> _keyFractionSamplesMap;
-    private final Set<FixedDecimal> _fractionSamples;
-
-    /**
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    public PluralSamples(PluralRules pluralRules) {
-        this.pluralRules = pluralRules;
-        Set<String> keywords = pluralRules.getKeywords();
-        // ensure both _keySamplesMap and _keyLimitedMap are initialized.
-        // If this were allowed to vary on a per-call basis, we'd have to recheck and
-        // possibly rebuild the samples cache.  Doesn't seem worth it.
-        // This 'max samples' value only applies to keywords that are unlimited, for
-        // other keywords all the matching values are returned.  This might be a lot.
-        final int MAX_SAMPLES = 3;
-
-        Map<String, Boolean> temp = new HashMap<String, Boolean>();
-        for (String k : keywords) {
-            temp.put(k, pluralRules.isLimited(k));
-        }
-        _keyLimitedMap = temp;
-
-        Map<String, List<Double>> sampleMap = new HashMap<String, List<Double>>();
-        int keywordsRemaining = keywords.size();
-
-        int limit = 128; // Math.max(5, getRepeatLimit() * MAX_SAMPLES) * 2;
-
-        for (int i = 0; keywordsRemaining > 0 && i < limit; ++i) {
-            keywordsRemaining = addSimpleSamples(pluralRules, MAX_SAMPLES, sampleMap, keywordsRemaining, i / 2.0);
-        }
-        // Hack for Celtic
-        keywordsRemaining = addSimpleSamples(pluralRules, MAX_SAMPLES, sampleMap, keywordsRemaining, 1000000);
-
-
-        // collect explicit samples
-        Map<String, Set<FixedDecimal>> sampleFractionMap = new HashMap<String, Set<FixedDecimal>>();
-        Set<FixedDecimal> mentioned = new TreeSet<FixedDecimal>();
-        // make sure that there is at least one 'other' value
-        Map<String, Set<FixedDecimal>> foundKeywords = new HashMap<String, Set<FixedDecimal>>();
-        for (FixedDecimal s : mentioned) {
-            String keyword = pluralRules.select(s);
-            addRelation(foundKeywords, keyword, s);
-        }
-        main:
-            if (foundKeywords.size() != keywords.size()) {
-                for (int i = 1; i < 1000; ++i) {
-                    boolean done = addIfNotPresent(i, mentioned, foundKeywords);
-                    if (done) break main;
-                }
-                // if we are not done, try tenths
-                for (int i = 10; i < 1000; ++i) {
-                    boolean done = addIfNotPresent(i/10d, mentioned, foundKeywords);
-                    if (done) break main;
-                }
-                System.out.println("Failed to find sample for each keyword: " + foundKeywords + "\n\t" + pluralRules + "\n\t" + mentioned);
-            }
-        mentioned.add(new FixedDecimal(0)); // always there
-        mentioned.add(new FixedDecimal(1)); // always there
-        mentioned.add(new FixedDecimal(2)); // always there
-        mentioned.add(new FixedDecimal(0.1,1)); // always there
-        mentioned.add(new FixedDecimal(1.99,2)); // always there
-        mentioned.addAll(fractions(mentioned));
-        for (FixedDecimal s : mentioned) {
-            String keyword = pluralRules.select(s);
-            Set<FixedDecimal> list = sampleFractionMap.get(keyword);
-            if (list == null) {
-                list = new LinkedHashSet<FixedDecimal>(); // will be sorted because the iteration is
-                sampleFractionMap.put(keyword, list);
-            }
-            list.add(s);
-        }
-
-        if (keywordsRemaining > 0) {
-            for (String k : keywords) {
-                if (!sampleMap.containsKey(k)) {
-                    sampleMap.put(k, Collections.<Double>emptyList());
-                }
-                if (!sampleFractionMap.containsKey(k)) {
-                    sampleFractionMap.put(k, Collections.<FixedDecimal>emptySet());
-                }
-            }
-        }
-
-        // Make lists immutable so we can return them directly
-        for (Entry<String, List<Double>> entry : sampleMap.entrySet()) {
-            sampleMap.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
-        }
-        for (Entry<String, Set<FixedDecimal>> entry : sampleFractionMap.entrySet()) {
-            sampleFractionMap.put(entry.getKey(), Collections.unmodifiableSet(entry.getValue()));
-        }
-        _keySamplesMap = sampleMap;
-        _keyFractionSamplesMap = sampleFractionMap;
-        _fractionSamples = Collections.unmodifiableSet(mentioned);
-    }
-
-    private int addSimpleSamples(PluralRules pluralRules, final int MAX_SAMPLES, Map<String, List<Double>> sampleMap,
-            int keywordsRemaining, double val) {
-        String keyword = pluralRules.select(val);
-        boolean keyIsLimited = _keyLimitedMap.get(keyword);
-
-        List<Double> list = sampleMap.get(keyword);
-        if (list == null) {
-            list = new ArrayList<Double>(MAX_SAMPLES);
-            sampleMap.put(keyword, list);
-        } else if (!keyIsLimited && list.size() == MAX_SAMPLES) {
-            return keywordsRemaining;
-        }
-        list.add(Double.valueOf(val));
-
-        if (!keyIsLimited && list.size() == MAX_SAMPLES) {
-            --keywordsRemaining;
-        }
-        return keywordsRemaining;
-    }
-
-    private void addRelation(Map<String, Set<FixedDecimal>> foundKeywords, String keyword, FixedDecimal s) {
-        Set<FixedDecimal> set = foundKeywords.get(keyword);
-        if (set == null) {
-            foundKeywords.put(keyword, set = new HashSet<FixedDecimal>());
-        }
-        set.add(s);
-    }
-
-    private boolean addIfNotPresent(double d, Set<FixedDecimal> mentioned, Map<String, Set<FixedDecimal>> foundKeywords) {
-        FixedDecimal numberInfo = new FixedDecimal(d);
-        String keyword = pluralRules.select(numberInfo);
-        if (!foundKeywords.containsKey(keyword) || keyword.equals("other")) {
-            addRelation(foundKeywords, keyword, numberInfo);
-            mentioned.add(numberInfo);
-            if (keyword.equals("other")) {
-                if (foundKeywords.get("other").size() > 1) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private static final int[] TENS = {1, 10, 100, 1000, 10000, 100000, 1000000};
-
-    private static final int LIMIT_FRACTION_SAMPLES = 3;
-
-
-    private Set<FixedDecimal> fractions(Set<FixedDecimal> original) {
-        Set<FixedDecimal> toAddTo = new HashSet<FixedDecimal>();
-
-        Set<Integer> result = new HashSet<Integer>();
-        for (FixedDecimal base1 : original) {
-            result.add((int)base1.integerValue);
-        }
-        List<Integer> ints = new ArrayList<Integer>(result);
-        Set<String> keywords = new HashSet<String>();
-
-        for (int j = 0; j < ints.size(); ++j) {
-            Integer base = ints.get(j);
-            String keyword = pluralRules.select(base);
-            if (keywords.contains(keyword)) {
-                continue;
-            }
-            keywords.add(keyword);
-            toAddTo.add(new FixedDecimal(base,1)); // add .0
-            toAddTo.add(new FixedDecimal(base,2)); // add .00
-            Integer fract = getDifferentCategory(ints, keyword);
-            if (fract >= TENS[LIMIT_FRACTION_SAMPLES-1]) { // make sure that we always get the value
-                toAddTo.add(new FixedDecimal(base + "." + fract));
-            } else {
-                for (int visibleFractions = 1; visibleFractions < LIMIT_FRACTION_SAMPLES; ++visibleFractions) {
-                    for (int i = 1; i <= visibleFractions; ++i) {
-                        // with visible fractions = 3, and fract = 1, then we should get x.10, 0.01
-                        // with visible fractions = 3, and fract = 15, then we should get x.15, x.15
-                        if (fract >= TENS[i]) {
-                            continue;
-                        }
-                        toAddTo.add(new FixedDecimal(base + fract/(double)TENS[i], visibleFractions));
-                    }
-                }
-            }
-        }
-        return toAddTo;
-    }
-
-    private Integer getDifferentCategory(List<Integer> ints, String keyword) {
-        for (int i = ints.size() - 1; i >= 0; --i) {
-            Integer other = ints.get(i);
-            String keywordOther = pluralRules.select(other);
-            if (!keywordOther.equals(keyword)) {
-                return other;
-            }
-        }
-        return 37;
-    }
-
-    /**
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    public KeywordStatus getStatus(String keyword, int offset, Set<Double> explicits, Output<Double> uniqueValue) {
-        if (uniqueValue != null) {
-            uniqueValue.value = null;
-        }
-
-        if (!pluralRules.getKeywords().contains(keyword)) {
-            return KeywordStatus.INVALID;
-        }
-        Collection<Double> values = pluralRules.getAllKeywordValues(keyword);
-        if (values == null) {
-            return KeywordStatus.UNBOUNDED;
-        }
-        int originalSize = values.size();
-
-        if (explicits == null) {
-            explicits = Collections.emptySet();
-        }
-
-        // Quick check on whether there are multiple elements
-
-        if (originalSize > explicits.size()) {
-            if (originalSize == 1) {
-                if (uniqueValue != null) {
-                    uniqueValue.value = values.iterator().next();
-                }
-                return KeywordStatus.UNIQUE;
-            }
-            return KeywordStatus.BOUNDED;
-        }
-
-        // Compute if the quick test is insufficient.
-
-        HashSet<Double> subtractedSet = new HashSet<Double>(values);
-        for (Double explicit : explicits) {
-            subtractedSet.remove(explicit - offset);
-        }
-        if (subtractedSet.size() == 0) {
-            return KeywordStatus.SUPPRESSED;
-        }
-
-        if (uniqueValue != null && subtractedSet.size() == 1) {
-            uniqueValue.value = subtractedSet.iterator().next();
-        }
-
-        return originalSize == 1 ? KeywordStatus.UNIQUE : KeywordStatus.BOUNDED;
-    }
-
-    Map<String, List<Double>> getKeySamplesMap() {
-        return _keySamplesMap;
-    }
-
-    Map<String, Set<FixedDecimal>> getKeyFractionSamplesMap() {
-        return _keyFractionSamplesMap;
-    }
-
-    Set<FixedDecimal> getFractionSamples() {
-        return _fractionSamples;
-    }
-
-    /**
-     * Returns all the values that trigger this keyword, or null if the number of such
-     * values is unlimited.
-     *
-     * @param keyword the keyword
-     * @return the values that trigger this keyword, or null.  The returned collection
-     * is immutable. It will be empty if the keyword is not defined.
-     * @stable ICU 4.8
-     */
-
-    Collection<Double> getAllKeywordValues(String keyword) {
-        // HACK for now
-        if (!pluralRules.getKeywords().contains(keyword)) {
-            return Collections.<Double>emptyList();
-        }
-        Collection<Double> result = getKeySamplesMap().get(keyword);
-
-        // We depend on MAX_SAMPLES here.  It's possible for a conjunction
-        // of unlimited rules that 'looks' unlimited to return a limited
-        // number of values.  There's no bounds to this limited number, in
-        // general, because you can construct arbitrarily complex rules.  Since
-        // we always generate 3 samples if a rule is really unlimited, that's
-        // where we put the cutoff.
-        if (result.size() > 2 && !_keyLimitedMap.get(keyword)) {
-            return null;
-        }
-        return result;
-    }
-}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatUnitTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatUnitTest.java
index 0b22c8e..1e2c0d9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatUnitTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatUnitTest.java
@@ -23,6 +23,7 @@
 import org.junit.runners.JUnit4;
 
 import com.ibm.icu.dev.test.TestFmwk;
+import com.ibm.icu.impl.number.DecimalQuantity;
 import com.ibm.icu.text.DecimalFormat;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.MessageFormat;
@@ -228,10 +229,10 @@
             logln(localeName + "\ttoString\t" + rules.toString());
             Set<String> keywords = rules.getKeywords();
             for (String keyword : keywords) {
-                Collection<Double> list = rules.getSamples(keyword);
+                Collection<DecimalQuantity> list = rules.getDecimalQuantitySamples(keyword);
                 if (list.size() == 0) {
                     // if there aren't any integer samples, get the decimal ones.
-                    list = rules.getSamples(keyword, SampleType.DECIMAL);
+                    list = rules.getDecimalQuantitySamples(keyword, SampleType.DECIMAL);
                 }
 
                 if (list == null || list.size() == 0) {
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
index d07f41e..f0bed53 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
@@ -23,6 +23,7 @@
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
@@ -31,6 +32,8 @@
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -41,6 +44,8 @@
 import com.ibm.icu.dev.util.CollectionUtilities;
 import com.ibm.icu.impl.Relation;
 import com.ibm.icu.impl.Utility;
+import com.ibm.icu.impl.number.DecimalQuantity;
+import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
 import com.ibm.icu.number.FormattedNumber;
 import com.ibm.icu.number.FormattedNumberRange;
 import com.ibm.icu.number.LocalizedNumberFormatter;
@@ -50,9 +55,9 @@
 import com.ibm.icu.number.UnlocalizedNumberFormatter;
 import com.ibm.icu.text.NumberFormat;
 import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.text.PluralRules.DecimalQuantitySamples;
+import com.ibm.icu.text.PluralRules.DecimalQuantitySamplesRange;
 import com.ibm.icu.text.PluralRules.FixedDecimal;
-import com.ibm.icu.text.PluralRules.FixedDecimalRange;
-import com.ibm.icu.text.PluralRules.FixedDecimalSamples;
 import com.ibm.icu.text.PluralRules.KeywordStatus;
 import com.ibm.icu.text.PluralRules.PluralType;
 import com.ibm.icu.text.PluralRules.SampleType;
@@ -177,17 +182,27 @@
         PluralRules test = PluralRules.createRules(description);
 
         checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 3, 19", true,
-                new FixedDecimal(3));
+                DecimalQuantity_DualStorageBCD.fromExponentString("3"));
         checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 3.50~3.53, …", false,
-                new FixedDecimal(3.5, 2));
-        checkOldSamples(description, test, "one", SampleType.INTEGER, 3d, 19d);
-        checkOldSamples(description, test, "one", SampleType.DECIMAL, 3.5d, 3.51d, 3.52d, 3.53d);
+                DecimalQuantity_DualStorageBCD.fromExponentString("3.50"));
+        checkOldSamples(description, test, "one", SampleType.INTEGER,
+                DecimalQuantity_DualStorageBCD.fromExponentString("3"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("19"));
+        checkOldSamples(description, test, "one", SampleType.DECIMAL,
+                DecimalQuantity_DualStorageBCD.fromExponentString("3.50"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("3.51"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("3.52"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("3.53"));
 
         checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "", true, null);
         checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 99.0~99.2, 999.0, …",
-                false, new FixedDecimal(99d, 1));
+                false, DecimalQuantity_DualStorageBCD.fromExponentString("99.0"));
         checkOldSamples(description, test, "other", SampleType.INTEGER);
-        checkOldSamples(description, test, "other", SampleType.DECIMAL, 99d, 99.1, 99.2d, 999d);
+        checkOldSamples(description, test, "other", SampleType.DECIMAL,
+                DecimalQuantity_DualStorageBCD.fromExponentString("99.0"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("99.1"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("99.2"),
+                DecimalQuantity_DualStorageBCD.fromExponentString("999.0"));
     }
 
     /**
@@ -205,22 +220,26 @@
         // Creating the PluralRules object means being able to parse numbers
         // like 1e5 and 1.1e5
         PluralRules test = PluralRules.createRules(description);
+
+        // Currently, 'c' is the canonical representation of numbers with suppressed exponent, and 'e'
+        // is an alias. The test helpers here skip 'e' for round-trip sample string parsing and formatting.
+
         checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 0, 1, 1e5", true,
-                new FixedDecimal(0));
+                DecimalQuantity_DualStorageBCD.fromExponentString("0"));
         checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 0.0~1.5, 1.1e5", true,
-                new FixedDecimal(0, 1));
+                DecimalQuantity_DualStorageBCD.fromExponentString("0.0"));
         checkNewSamples(description, test, "many", PluralRules.SampleType.INTEGER, "@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", false,
-                new FixedDecimal(1000000));
+                DecimalQuantity_DualStorageBCD.fromExponentString("1000000"));
         checkNewSamples(description, test, "many", PluralRules.SampleType.DECIMAL, "@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", false,
-                FixedDecimal.createWithExponent(2.1, 1, 6));
+                DecimalQuantity_DualStorageBCD.fromExponentString("2.1c6"));
         checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", false,
-                new FixedDecimal(2));
+                DecimalQuantity_DualStorageBCD.fromExponentString("2"));
         checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", false,
-                new FixedDecimal(2.0, 1));
+                DecimalQuantity_DualStorageBCD.fromExponentString("2.0"));
     }
 
     /**
-     * This test is for the support of X.YcZ compactnotation of numbers in
+     * This test is for the support of X.YcZ compact notation of numbers in
      * the plural sample string.
      */
     @Test
@@ -236,34 +255,53 @@
         // Note: Since `c` is currently an alias to `e`, the toString() of
         // FixedDecimal will return "1e5" even when input is "1c5".
         PluralRules test = PluralRules.createRules(description);
-        checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 0, 1, 1e5", true,
-                new FixedDecimal(0));
-        checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 0.0~1.5, 1.1e5", true,
-                new FixedDecimal(0, 1));
-        checkNewSamples(description, test, "many", PluralRules.SampleType.INTEGER, "@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", false,
-                new FixedDecimal(1000000));
-        checkNewSamples(description, test, "many", PluralRules.SampleType.DECIMAL, "@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", false,
-                FixedDecimal.createWithExponent(2.1, 1, 6));
-        checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", false,
-                new FixedDecimal(2));
-        checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", false,
-                new FixedDecimal(2.0, 1));
+
+        checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 0, 1, 1c5", true,
+                DecimalQuantity_DualStorageBCD.fromExponentString("0"));
+        checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 0.0~1.5, 1.1c5", true,
+                DecimalQuantity_DualStorageBCD.fromExponentString("0.0"));
+        checkNewSamples(description, test, "many", PluralRules.SampleType.INTEGER, "@integer 1000000, 2c6, 3c6, 4c6, 5c6, 6c6, 7c6, …", false,
+                DecimalQuantity_DualStorageBCD.fromExponentString("1000000"));
+        checkNewSamples(description, test, "many", PluralRules.SampleType.DECIMAL, "@decimal 2.1c6, 3.1c6, 4.1c6, 5.1c6, 6.1c6, 7.1c6, …", false,
+                DecimalQuantity_DualStorageBCD.fromExponentString("2.1c6"));
+        checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "@integer 2~17, 100, 1000, 10000, 100000, 2c5, 3c5, 4c5, 5c5, 6c5, 7c5, …", false,
+                DecimalQuantity_DualStorageBCD.fromExponentString("2"));
+        checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1c5, 3.1c5, 4.1c5, 5.1c5, 6.1c5, 7.1c5, …", false,
+                DecimalQuantity_DualStorageBCD.fromExponentString("2.0"));
     }
 
     public void checkOldSamples(String description, PluralRules rules, String keyword, SampleType sampleType,
-            Double... expected) {
-        Collection<Double> oldSamples = rules.getSamples(keyword, sampleType);
-        if (!assertEquals("getOldSamples; " + keyword + "; " + description, new HashSet(Arrays.asList(expected)),
-                oldSamples)) {
+            DecimalQuantity... expected) {
+        Collection<DecimalQuantity> oldSamples = rules.getDecimalQuantitySamples(keyword, sampleType);
+
+        // Collect actual (oldSamples) and expected (expectedSamplesList) into the
+        // same concrete collection for comparison purposes.
+        ArrayList<DecimalQuantity> oldSamplesList = new ArrayList(oldSamples);
+        ArrayList<DecimalQuantity> expectedSamplesList = new ArrayList(Arrays.asList(expected));
+
+        if (!assertEquals("getOldSamples; " + keyword + "; " + description, expectedSamplesList,
+                oldSamplesList)) {
             rules.getSamples(keyword, sampleType);
         }
     }
 
     public void checkNewSamples(String description, PluralRules test, String keyword, SampleType sampleType,
-            String samplesString, boolean isBounded, FixedDecimal firstInRange) {
+            String samplesString, boolean isBounded, DecimalQuantity firstInRange) {
         String title = description + ", " + sampleType;
-        FixedDecimalSamples samples = test.getDecimalSamples(keyword, sampleType);
+        DecimalQuantitySamples samples = test.getDecimalSamples(keyword, sampleType);
         if (samples != null) {
+
+            // For now, skip round-trip formatting test when samples string uses
+            // 'e' instead of 'c' for compact notation.
+
+            // We are skipping tests for 'e' by replacing 'e' with 'c' in exponent
+            // notation.
+            Pattern p = Pattern.compile("(\\d+)(e)([-]?\\d+)");
+            Matcher m = p.matcher(samplesString);
+            if (m.find()) {
+                samplesString = m.replaceAll("$1c$3");
+            }
+
             assertEquals("samples; " + title, samplesString, samples.toString());
             assertEquals("bounded; " + title, isBounded, samples.bounded);
             assertEquals("first; " + title, firstInRange, samples.samples.iterator().next().start);
@@ -391,11 +429,11 @@
         main: for (ULocale locale : factory.getAvailableULocales()) {
             PluralRules rules = factory.forLocale(locale);
             Map<String, PluralRules> keywordToRule = new HashMap<>();
-            Collection<FixedDecimalSamples> samples = new LinkedHashSet<>();
+            Collection<DecimalQuantitySamples> samples = new LinkedHashSet<>();
 
             for (String keyword : rules.getKeywords()) {
                 for (SampleType sampleType : SampleType.values()) {
-                    FixedDecimalSamples samples2 = rules.getDecimalSamples(keyword, sampleType);
+                    DecimalQuantitySamples samples2 = rules.getDecimalSamples(keyword, sampleType);
                     if (samples2 != null) {
                         samples.add(samples2);
                     }
@@ -412,15 +450,16 @@
                 }
                 keywordToRule.put(keyword, singleRule);
             }
-            Map<FixedDecimal, String> collisionTest = new TreeMap();
-            for (FixedDecimalSamples sample3 : samples) {
-                Set<FixedDecimalRange> samples2 = sample3.getSamples();
+
+            Map<DecimalQuantity, String> collisionTest = new LinkedHashMap();
+            for (DecimalQuantitySamples sample3 : samples) {
+                Set<DecimalQuantitySamplesRange> samples2 = sample3.getSamples();
                 if (samples2 == null) {
                     continue;
                 }
-                for (FixedDecimalRange sample : samples2) {
+                for (DecimalQuantitySamplesRange sample : samples2) {
                     for (int i = 0; i < 1; ++i) {
-                        FixedDecimal item = i == 0 ? sample.start : sample.end;
+                        DecimalQuantity item = i == 0 ? sample.start : sample.end;
                         collisionTest.clear();
                         for (Entry<String, PluralRules> entry : keywordToRule.entrySet()) {
                             PluralRules rule = entry.getValue();
@@ -460,9 +499,9 @@
     }
 
     public void checkValue(String title1, PluralRules rules, String expected, String value) {
-        FixedDecimal fdNum = new FixedDecimal(value);
+        DecimalQuantity dqNum = DecimalQuantity_DualStorageBCD.fromExponentString(value);
 
-        String result = rules.select(fdNum);
+        String result = rules.select(dqNum);
         ULocale locale = null;
         assertEquals(getAssertMessage(title1, locale, rules, expected) + "; value: " + value, expected, result);
     }
@@ -733,13 +772,20 @@
         }
     }
 
-    private void assertRuleValue(String rule, double value) {
+    private void assertRuleValue(String rule, DecimalQuantity value) {
         assertRuleKeyValue("a:" + rule, "a", value);
     }
 
-    private void assertRuleKeyValue(String rule, String key, double value) {
+    private void assertRuleKeyValue(String rule, String key, DecimalQuantity value) {
         PluralRules pr = PluralRules.createRules(rule);
-        assertEquals(rule, value, pr.getUniqueKeywordValue(key));
+
+        // as a DecimalQuantity
+        assertEquals(rule, value, pr.getUniqueKeywordDecimalQuantityValue(key));
+
+        // as a double
+        double expDouble = value.equals(PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY) ?
+                PluralRules.NO_UNIQUE_VALUE : value.toDouble();
+        assertEquals(rule, expDouble, pr.getUniqueKeywordValue(key));
     }
 
     /*
@@ -747,26 +793,36 @@
      */
     @Test
     public void TestGetUniqueKeywordValue() {
-        assertRuleKeyValue("a: n is 1", "not_defined", PluralRules.NO_UNIQUE_VALUE); // key not defined
-        assertRuleValue("n within 2..2", 2);
-        assertRuleValue("n is 1", 1);
-        assertRuleValue("n in 2..2", 2);
-        assertRuleValue("n in 3..4", PluralRules.NO_UNIQUE_VALUE);
-        assertRuleValue("n within 3..4", PluralRules.NO_UNIQUE_VALUE);
-        assertRuleValue("n is 2 or n is 2", 2);
-        assertRuleValue("n is 2 and n is 2", 2);
-        assertRuleValue("n is 2 or n is 3", PluralRules.NO_UNIQUE_VALUE);
-        assertRuleValue("n is 2 and n is 3", PluralRules.NO_UNIQUE_VALUE);
-        assertRuleValue("n is 2 or n in 2..3", PluralRules.NO_UNIQUE_VALUE);
-        assertRuleValue("n is 2 and n in 2..3", 2);
-        assertRuleKeyValue("a: n is 1", "other", PluralRules.NO_UNIQUE_VALUE); // key matches default rule
-        assertRuleValue("n in 2,3", PluralRules.NO_UNIQUE_VALUE);
-        assertRuleValue("n in 2,3..6 and n not in 2..3,5..6", 4);
+        LocalizedNumberFormatter fmtr = NumberFormatter.withLocale(ULocale.ROOT);
+
+        assertRuleKeyValue("a: n is 1", "not_defined", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY); // key not defined
+        assertRuleValue("n within 2..2", new DecimalQuantity_DualStorageBCD(2));
+        assertRuleValue("n is 1", new DecimalQuantity_DualStorageBCD(1));
+        assertRuleValue("n in 2..2", new DecimalQuantity_DualStorageBCD(2));
+        assertRuleValue("n in 3..4", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
+        assertRuleValue("n within 3..4", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
+        assertRuleValue("n is 2 or n is 2", new DecimalQuantity_DualStorageBCD(2));
+        assertRuleValue("n is 2 and n is 2", new DecimalQuantity_DualStorageBCD(2));
+        assertRuleValue("n is 2 or n is 3", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
+        assertRuleValue("n is 2 and n is 3", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
+        assertRuleValue("n is 2 or n in 2..3", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
+        assertRuleValue("n is 2 and n in 2..3", new DecimalQuantity_DualStorageBCD(2));
+        assertRuleKeyValue("a: n is 1", "other", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY); // key matches default rule
+        assertRuleValue("n in 2,3", PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
+        assertRuleValue("n in 2,3..6 and n not in 2..3,5..6", new DecimalQuantity_DualStorageBCD(4));
     }
 
     /**
      * The version in PluralFormatUnitTest is not really a test, and it's in the wrong place anyway, so I'm putting a
      * variant of it here.
+     *
+     * Using the double API for getting plural samples, assert all samples match the keyword
+     * they are listed under, for all locales.
+     *
+     * Specifically, iterate over all locales, get plural rules for the locale, iterate over every rule,
+     * then iterate over every sample in the rule, parse sample to a number (double), use that number
+     * as an input to .select() for the rules object, and assert the actual return plural keyword matches
+     * what we expect based on the plural rule string.
      */
     @Test
     public void TestGetSamples() {
@@ -775,10 +831,6 @@
             uniqueRuleSet.add(PluralRules.getFunctionalEquivalent(locale, null));
         }
         for (ULocale locale : uniqueRuleSet) {
-            //if (locale.getLanguage().equals("fr") &&
-            //        logKnownIssue("21322", "PluralRules::getSamples cannot distinguish 1e5 from 100000")) {
-            //    continue;
-            //}
             PluralRules rules = factory.forLocale(locale);
             logln("\nlocale: " + (locale == ULocale.ROOT ? "root" : locale.toString()) + ", rules: " + rules);
             Set<String> keywords = rules.getKeywords();
@@ -791,8 +843,8 @@
                 if (list.size() == 0) {
                     // when the samples (meaning integer samples) are null, then then integerSamples must be, and the
                     // decimalSamples must not be
-                    FixedDecimalSamples integerSamples = rules.getDecimalSamples(keyword, SampleType.INTEGER);
-                    FixedDecimalSamples decimalSamples = rules.getDecimalSamples(keyword, SampleType.DECIMAL);
+                    DecimalQuantitySamples integerSamples = rules.getDecimalSamples(keyword, SampleType.INTEGER);
+                    DecimalQuantitySamples decimalSamples = rules.getDecimalSamples(keyword, SampleType.DECIMAL);
                     assertTrue(getAssertMessage("List is not null", locale, rules, keyword), integerSamples == null
                             && decimalSamples != null && decimalSamples.samples.size() != 0);
                 } else {
@@ -816,6 +868,131 @@
         }
     }
 
+    /**
+     * This replicates the setup of TestGetSamples(), but parses samples as DecimalQuantity instead of double.
+     *
+     * Using the DecimalQuantity API for getting plural samples, assert all samples match the keyword
+     * they are listed under, for all locales.
+     *
+     * Specifically, iterate over all locales, get plural rules for the locale, iterate over every rule,
+     * then iterate over every sample in the rule, parse sample to a number (DecimalQuantity), use that number
+     * as an input to .select() for the rules object, and assert the actual return plural keyword matches
+     * what we expect based on the plural rule string.
+     */
+    @Test
+    public void TestGetDecimalQuantitySamples() {
+        Set<ULocale> uniqueRuleSet = new HashSet<>();
+        for (ULocale locale : factory.getAvailableULocales()) {
+            uniqueRuleSet.add(PluralRules.getFunctionalEquivalent(locale, null));
+        }
+        for (ULocale locale : uniqueRuleSet) {
+            PluralRules rules = factory.forLocale(locale);
+            logln("\nlocale: " + (locale == ULocale.ROOT ? "root" : locale.toString()) + ", rules: " + rules);
+            Set<String> keywords = rules.getKeywords();
+            for (String keyword : keywords) {
+                Collection<DecimalQuantity> list = rules.getDecimalQuantitySamples(keyword);
+                logln("keyword: " + keyword + ", samples: " + list);
+                // with fractions, the samples can be empty and thus the list null. In that case, however, there will be
+                // FixedDecimal values.
+                // So patch the test for that.
+                if (list.size() == 0) {
+                    // when the samples (meaning integer samples) are null, then then integerSamples must be, and the
+                    // decimalSamples must not be
+                    DecimalQuantitySamples integerSamples = rules.getDecimalSamples(keyword, SampleType.INTEGER);
+                    DecimalQuantitySamples decimalSamples = rules.getDecimalSamples(keyword, SampleType.DECIMAL);
+                    assertTrue(getAssertMessage("List is not null", locale, rules, keyword), integerSamples == null
+                            && decimalSamples != null && decimalSamples.samples.size() != 0);
+                } else {
+                    if (!assertTrue(getAssertMessage("Test getSamples.isEmpty", locale, rules, keyword),
+                            !list.isEmpty())) {
+                        rules.getDecimalQuantitySamples(keyword);
+                    }
+                    if (rules.toString().contains(": j")) {
+                        // hack until we remove j
+                    } else {
+                        for (DecimalQuantity value : list) {
+                            assertEquals(getAssertMessage("Match keyword", locale, rules, keyword) + "; value '"
+                                    + value + "'", keyword, rules.select(value));
+                        }
+                    }
+                }
+            }
+
+            assertNull(locale + ", list is null", rules.getDecimalQuantitySamples("@#$%^&*"));
+            assertNull(locale + ", list is null", rules.getDecimalQuantitySamples("@#$%^&*", SampleType.DECIMAL));
+        }
+    }
+
+    /**
+     * Test addSamples (Java) / getSamplesFromString (C++) to ensure the expansion of plural rule sample range
+     * expands to a sequence of sample numbers that is incremented as the right scale.
+     *
+     *  Do this for numbers with fractional digits but no exponent.
+     */
+    @Test
+    public void testGetOrAddSamplesFromString() {
+        PluralRules rules = PluralRules.createRules("testkeyword: e != 0 @decimal 2.0~4.0, …");
+
+        Set<String> keywords = rules.getKeywords();
+        assertTrue("At least parse the test keyword in the test rule string", 0 < keywords.size());
+
+        String expKeyword = "testkeyword";
+        Collection<DecimalQuantity> list = rules.getDecimalQuantitySamples(expKeyword, SampleType.DECIMAL);
+
+        String[] expDqStrs = {
+                "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9",
+                "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9",
+                "4.0"
+        };
+        assertEquals("Number of parsed samples from test string incorrect", expDqStrs.length, list.size());
+        ArrayList<DecimalQuantity> actSamples = new ArrayList<>(list);
+        for (int i = 0; i < list.size(); i++) {
+            String expDqStr = expDqStrs[i];
+            DecimalQuantity sample = actSamples.get(i);
+            String sampleStr = sample.toExponentString();
+
+            assertEquals("Expansion of sample range to sequence of sample values should increment at the right scale",
+                    expDqStr, sampleStr);
+
+        }
+    }
+
+    /**
+     * Test addSamples (Java) / getSamplesFromString (C++) to ensure the expansion of plural rule sample range
+     * expands to a sequence of sample numbers that is incremented as the right scale.
+     *
+     *  Do this for numbers written in a notation that has an exponent, for which the number is an
+     *  integer (also as defined in the UTS 35 spec for the plural operands) but whose representation
+     *  has fractional digits in the significand written before the exponent.
+     */
+    @Test
+    public void testGetOrAddSamplesFromStringCompactNotation() {
+        PluralRules rules = PluralRules.createRules("testkeyword: e != 0 @decimal 2.0c6~4.0c6, …");
+
+        Set<String> keywords = rules.getKeywords();
+        assertTrue("At least parse the test keyword in the test rule string", 0 < keywords.size());
+
+        String expKeyword = "testkeyword";
+        Collection<DecimalQuantity> list = rules.getDecimalQuantitySamples(expKeyword, SampleType.DECIMAL);
+
+        String[] expDqStrs = {
+                "2.0c6", "2.1c6", "2.2c6", "2.3c6", "2.4c6", "2.5c6", "2.6c6", "2.7c6", "2.8c6", "2.9c6",
+                "3.0c6", "3.1c6", "3.2c6", "3.3c6", "3.4c6", "3.5c6", "3.6c6", "3.7c6", "3.8c6", "3.9c6",
+                "4.0c6"
+        };
+        assertEquals("Number of parsed samples from test string incorrect", expDqStrs.length, list.size());
+        ArrayList<DecimalQuantity> actSamples = new ArrayList<>(list);
+        for (int i = 0; i < list.size(); i++) {
+            String expDqStr = expDqStrs[i];
+            DecimalQuantity sample = actSamples.get(i);
+            String sampleStr = sample.toExponentString();
+
+            assertEquals("Expansion of sample range to sequence of sample values should increment at the right scale",
+                    expDqStr, sampleStr);
+
+        }
+    }
+
     public String getAssertMessage(String message, ULocale locale, PluralRules rules, String keyword) {
         String ruleString = "";
         if (keyword != null) {
@@ -882,24 +1059,42 @@
                 if (valueList != null) {
                     valueList = valueList.trim();
                 }
-                Collection<Double> values;
+                Collection<DecimalQuantity> values;
                 if (valueList == null || valueList.length() == 0) {
                     values = Collections.EMPTY_SET;
                 } else if ("null".equals(valueList)) {
                     values = null;
                 } else {
-                    values = new TreeSet<>();
+                    values = new LinkedHashSet<>();
                     for (String value : valueList.split(",")) {
-                        values.add(Double.parseDouble(value));
+                        values.add(DecimalQuantity_DualStorageBCD.fromExponentString(value));
                     }
                 }
 
-                Collection<Double> results = p.getAllKeywordValues(keyword);
-                assertEquals(keyword + " in " + ruleDescription, values, results == null ? null : new HashSet(results));
+                Collection<DecimalQuantity> results = p.getAllKeywordDecimalQuantityValues(keyword);
+
+                // Convert DecimalQuantity using a 1:1 conversion to String for comparison purposes
+                Set<String> valuesForComparison = new HashSet<>();
+                if (values != null) {
+                    for (DecimalQuantity dq : values) {
+                        valuesForComparison.add(dq.toExponentString());
+                    }
+                }
+                Set<String> resultsForComparison = new HashSet<>();
+                if (results != null) {
+                    for (DecimalQuantity dq : results) {
+                        resultsForComparison.add(dq.toExponentString());
+                    }
+                }
+
+                assertEquals(keyword + " in " + ruleDescription,
+                        values == null ? null : valuesForComparison,
+                        results == null ? null : resultsForComparison
+                );
 
                 if (results != null) {
                     try {
-                        results.add(PluralRules.NO_UNIQUE_VALUE);
+                        results.add(PluralRules.NO_UNIQUE_VALUE_DECIMAL_QUANTITY);
                         fail("returned set is modifiable");
                     } catch (UnsupportedOperationException e) {
                         // pass
@@ -967,13 +1162,9 @@
                     for (String keyword : rules.getKeywords()) {
                         boolean isLimited = rules.isLimited(keyword, sampleType);
                         boolean computeLimited = rules.computeLimited(keyword, sampleType);
-                        if (!keyword.equals("other") && !(locale.getLanguage().equals("fr") && logKnownIssue("ICU-21322", "fr plurals many case computeLimited == isLimited"))) {
-                            assertEquals(getAssertMessage("computeLimited == isLimited", locale, rules, keyword),
-                                    computeLimited, isLimited);
-                        }
-                        Collection<Double> samples = rules.getSamples(keyword, sampleType);
+                        Collection<DecimalQuantity> samples = rules.getDecimalQuantitySamples(keyword, sampleType);
                         assertNotNull(getAssertMessage("Samples must not be null", locale, rules, keyword), samples);
-                        /* FixedDecimalSamples decimalSamples = */rules.getDecimalSamples(keyword, sampleType);
+                        rules.getDecimalSamples(keyword, sampleType);
                         // assertNotNull(getAssertMessage("Decimal samples must be null if unlimited", locale, rules,
                         // keyword), decimalSamples);
                     }
@@ -985,29 +1176,30 @@
     @Test
     public void TestKeywords() {
         Set<String> possibleKeywords = new LinkedHashSet(Arrays.asList("zero", "one", "two", "few", "many", "other"));
+        DecimalQuantity ONE_INTEGER = DecimalQuantity_DualStorageBCD.fromExponentString("1");
         Object[][][] tests = {
                 // format is locale, explicits, then triples of keyword, status, unique value.
-                { { "en", null }, { "one", KeywordStatus.UNIQUE, 1.0d }, { "other", KeywordStatus.UNBOUNDED, null } },
-                { { "pl", null }, { "one", KeywordStatus.UNIQUE, 1.0d }, { "few", KeywordStatus.UNBOUNDED, null },
+                { { "en", null }, { "one", KeywordStatus.UNIQUE, ONE_INTEGER }, { "other", KeywordStatus.UNBOUNDED, null } },
+                { { "pl", null }, { "one", KeywordStatus.UNIQUE, ONE_INTEGER }, { "few", KeywordStatus.UNBOUNDED, null },
                         { "many", KeywordStatus.UNBOUNDED, null },
                         { "other", KeywordStatus.SUPPRESSED, null, KeywordStatus.UNBOUNDED, null } // note that it is
                                                                                                    // suppressed in
                                                                                                    // INTEGER but not
                                                                                                    // DECIMAL
-                }, { { "en", new HashSet<>(Arrays.asList(1.0d)) }, // check that 1 is suppressed
+                }, { { "en", new HashSet<>(Arrays.asList(ONE_INTEGER)) }, // check that 1 is suppressed
                         { "one", KeywordStatus.SUPPRESSED, null }, { "other", KeywordStatus.UNBOUNDED, null } }, };
-        Output<Double> uniqueValue = new Output<>();
+        Output<DecimalQuantity> uniqueValue = new Output<>();
         for (Object[][] test : tests) {
             ULocale locale = new ULocale((String) test[0][0]);
             // NumberType numberType = (NumberType) test[1];
-            Set<Double> explicits = (Set<Double>) test[0][1];
+            Set<DecimalQuantity> explicits = (Set<DecimalQuantity>) test[0][1];
             PluralRules pluralRules = factory.forLocale(locale);
             LinkedHashSet<String> remaining = new LinkedHashSet(possibleKeywords);
             for (int i = 1; i < test.length; ++i) {
                 Object[] row = test[i];
                 String keyword = (String) row[0];
                 KeywordStatus statusExpected = (KeywordStatus) row[1];
-                Double uniqueExpected = (Double) row[2];
+                DecimalQuantity uniqueExpected = (DecimalQuantity) row[2];
                 remaining.remove(keyword);
                 KeywordStatus status = pluralRules.getKeywordStatus(keyword, 0, explicits, uniqueValue);
                 assertEquals(getAssertMessage("Unique Value", locale, pluralRules, keyword), uniqueExpected,
@@ -1015,7 +1207,7 @@
                 assertEquals(getAssertMessage("Keyword Status", locale, pluralRules, keyword), statusExpected, status);
                 if (row.length > 3) {
                     statusExpected = (KeywordStatus) row[3];
-                    uniqueExpected = (Double) row[4];
+                    uniqueExpected = (DecimalQuantity) row[4];
                     status = pluralRules.getKeywordStatus(keyword, 0, explicits, uniqueValue, SampleType.DECIMAL);
                     assertEquals(getAssertMessage("Unique Value - decimal", locale, pluralRules, keyword),
                             uniqueExpected, uniqueValue.value);
@@ -1033,6 +1225,11 @@
 
     // For the time being, the compact notation exponent operand `c` is an alias
     // for the scientific exponent operand `e` and compact notation.
+    /**
+     * Test the proper plural rule keyword selection given an input number that is
+     * already formatted into scientific notation. This exercises the `e` plural operand
+     * for the formatted number.
+     */
     @Test
     public void testScientificPluralKeyword() {
         PluralRules rules = PluralRules.createRules("one: i = 0,1 @integer 0, 1 @decimal 0.0~1.5;  many: e = 0 and i % 1000000 = 0 and v = 0 or " +
@@ -1082,6 +1279,11 @@
         }
     }
 
+    /**
+     * Test the proper plural rule keyword selection given an input number that is
+     * already formatted into compact notation. This exercises the `c` plural operand
+     * for the formatted number.
+     */
     @Test
     public void testCompactDecimalPluralKeyword() {
         PluralRules rules = PluralRules.createRules("one: i = 0,1 @integer 0, 1 @decimal 0.0~1.5;  many: c = 0 and i % 1000000 = 0 and v = 0 or " +
@@ -1261,8 +1463,13 @@
 
     @Test
     public void TestLocales() {
+        // This test will fail when the locale snapshot gets out of sync with the real CLDR data.
+        // In that case, temporarily use "if (true)",
+        // copy & paste the output into the initializer above,
+        // and revert to "if (false)" for normal testing.
         if (false) {
             generateLOCALE_SNAPSHOT();
+            return;
         }
         for (String test : LOCALE_SNAPSHOT) {
             test = test.trim();
@@ -1308,7 +1515,7 @@
                 System.out.print("        \"" + CollectionUtilities.join(locales, ","));
                 for (StandardPluralCategories spc : set) {
                     String keyword = spc.toString();
-                    FixedDecimalSamples samples = rule.getDecimalSamples(keyword, SampleType.INTEGER);
+                    DecimalQuantitySamples samples = rule.getDecimalSamples(keyword, SampleType.INTEGER);
                     System.out.print("; " + spc + ": " + samples);
                 }
                 System.out.println("\",");
