]> granicus.if.org Git - icu/commitdiff
ICU-21330 Use =0 and =1 plural forms in compact notation
authorShane F. Carr <shane@unicode.org>
Wed, 10 Mar 2021 02:29:59 +0000 (02:29 +0000)
committerShane F. Carr <shane@unicode.org>
Thu, 11 Mar 2021 23:34:35 +0000 (17:34 -0600)
See #1632

16 files changed:
icu4c/source/i18n/number_compact.cpp
icu4c/source/i18n/number_compact.h
icu4c/source/i18n/standardplural.cpp
icu4c/source/i18n/standardplural.h
icu4c/source/test/intltest/numbertest.h
icu4c/source/test/intltest/numbertest_api.cpp
icu4c/source/test/intltest/numbertest_decimalquantity.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/StandardPlural.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/CompactData.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity_AbstractBCD.java
icu4j/main/classes/core/src/com/ibm/icu/number/CompactNotation.java
icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java
icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java

index d781b6fada234ccd599ee1f98b7dcbf93d57e9df..8f898e704703a431a0e0ac32c634b2f2a209880b 100644 (file)
@@ -55,7 +55,7 @@ int32_t countZeros(const UChar *patternString, int32_t patternLength) {
 } // namespace
 
 // NOTE: patterns and multipliers both get zero-initialized.
-CompactData::CompactData() : patterns(), multipliers(), largestMagnitude(0), isEmpty(TRUE) {
+CompactData::CompactData() : patterns(), multipliers(), largestMagnitude(0), isEmpty(true) {
 }
 
 void CompactData::populate(const Locale &locale, const char *nsName, CompactStyle compactStyle,
@@ -104,14 +104,30 @@ int32_t CompactData::getMultiplier(int32_t magnitude) const {
     return multipliers[magnitude];
 }
 
-const UChar *CompactData::getPattern(int32_t magnitude, StandardPlural::Form plural) const {
+const UChar *CompactData::getPattern(
+        int32_t magnitude,
+        const PluralRules *rules,
+        const DecimalQuantity &dq) const {
     if (magnitude < 0) {
         return nullptr;
     }
     if (magnitude > largestMagnitude) {
         magnitude = largestMagnitude;
     }
-    const UChar *patternString = patterns[getIndex(magnitude, plural)];
+    const UChar *patternString = nullptr;
+    if (dq.hasIntegerValue()) {
+        int64_t i = dq.toLong(true);
+        if (i == 0) {
+            patternString = patterns[getIndex(magnitude, StandardPlural::Form::EQ_0)];
+        } else if (i == 1) {
+            patternString = patterns[getIndex(magnitude, StandardPlural::Form::EQ_1)];
+        }
+        if (patternString != nullptr) {
+            return patternString;
+        }
+    }
+    StandardPlural::Form plural = utils::getStandardPlural(rules, dq);
+    patternString = patterns[getIndex(magnitude, plural)];
     if (patternString == nullptr && plural != StandardPlural::OTHER) {
         // Fall back to "other" plural variant
         patternString = patterns[getIndex(magnitude, StandardPlural::OTHER)];
@@ -166,12 +182,6 @@ void CompactData::CompactDataSink::put(const char *key, ResourceValue &value, UB
         ResourceTable pluralVariantsTable = value.getTable(status);
         if (U_FAILURE(status)) { return; }
         for (int i4 = 0; pluralVariantsTable.getKeyAndValue(i4, key, value); ++i4) {
-
-            if (uprv_strcmp(key, "0") == 0 || uprv_strcmp(key, "1") == 0) {
-                // TODO(ICU-21258): Handle this case. For now, skip.
-                continue;
-            }
-
             // Skip this magnitude/plural if we already have it from a child locale.
             // Note: This also skips USE_FALLBACK entries.
             StandardPlural::Form plural = StandardPlural::fromString(key, status);
@@ -296,8 +306,7 @@ void CompactHandler::processQuantity(DecimalQuantity &quantity, MicroProps &micr
         magnitude -= multiplier;
     }
 
-    StandardPlural::Form plural = utils::getStandardPlural(rules, quantity);
-    const UChar *patternString = data.getPattern(magnitude, plural);
+    const UChar *patternString = data.getPattern(magnitude, rules, quantity);
     if (patternString == nullptr) {
         // Use the default (non-compact) modifier.
         // No need to take any action.
index 199d39f65911caa8b7b04462f61e8f2cfc993fbe..9802b9fb10ee723e1e085ba7e242f53384fa78e2 100644 (file)
@@ -28,7 +28,10 @@ class CompactData : public MultiplierProducer {
 
     int32_t getMultiplier(int32_t magnitude) const U_OVERRIDE;
 
-    const UChar *getPattern(int32_t magnitude, StandardPlural::Form plural) const;
+    const UChar *getPattern(
+        int32_t magnitude,
+        const PluralRules *rules,
+        const DecimalQuantity &dq) const;
 
     void getUniquePatterns(UVector &output, UErrorCode &status) const;
 
index 0391034b3e4a8dcec42c5c0a1db06c01e4c44646..5a6069bf7ddc47a5484433c1c8eedbe48b2c7c0d 100644 (file)
@@ -23,7 +23,7 @@
 U_NAMESPACE_BEGIN
 
 static const char *gKeywords[StandardPlural::COUNT] = {
-    "zero", "one", "two", "few", "many", "other"
+    "zero", "one", "two", "few", "many", "other", "=0", "=1"
 };
 
 const char *StandardPlural::getKeyword(Form p) {
@@ -60,21 +60,55 @@ int32_t StandardPlural::indexOrNegativeFromString(const char *keyword) {
             return ZERO;
         }
         break;
+    case '=':
+        if (uprv_strcmp(keyword, "0") == 0) {
+            return EQ_0;
+        } else if (uprv_strcmp(keyword, "1") == 0) {
+            return EQ_1;
+        }
+        break;
+    // Also allow "0" and "1"
+    case '0':
+        if (*keyword == 0) {
+            return EQ_0;
+        }
+        break;
+    case '1':
+        if (*keyword == 0) {
+            return EQ_1;
+        }
+        break;
     default:
         break;
     }
     return -1;
 }
 
-static const UChar gZero[] = { 0x7A, 0x65, 0x72, 0x6F };
-static const UChar gOne[] = { 0x6F, 0x6E, 0x65 };
-static const UChar gTwo[] = { 0x74, 0x77, 0x6F };
-static const UChar gFew[] = { 0x66, 0x65, 0x77 };
-static const UChar gMany[] = { 0x6D, 0x61, 0x6E, 0x79 };
-static const UChar gOther[] = { 0x6F, 0x74, 0x68, 0x65, 0x72 };
+static const UChar gZero[] = u"zero";
+static const UChar gOne[] = u"one";
+static const UChar gTwo[] = u"two";
+static const UChar gFew[] = u"few";
+static const UChar gMany[] = u"many";
+static const UChar gOther[] = u"other";
+static const UChar gEq0[] = u"=0";
+static const UChar gEq1[] = u"=1";
 
 int32_t StandardPlural::indexOrNegativeFromString(const UnicodeString &keyword) {
     switch (keyword.length()) {
+    case 1:
+        if (keyword.charAt(0) == '0') {
+            return EQ_0;
+        } else if (keyword.charAt(0) == '1') {
+            return EQ_1;
+        }
+        break;
+    case 2:
+        if (keyword.compare(gEq0, 2) == 0) {
+            return EQ_0;
+        } else if (keyword.compare(gEq1, 2) == 0) {
+            return EQ_1;
+        }
+        break;
     case 3:
         if (keyword.compare(gOne, 3) == 0) {
             return ONE;
index 33e1d605f6856bc0a7ff7e674ad38365c50a2efc..16593065c8aa91bda194bafebb917f18346fe166 100644 (file)
@@ -35,6 +35,8 @@ public:
         FEW,
         MANY,
         OTHER,
+        EQ_0,
+        EQ_1,
         COUNT
     };
 
index 39e888582f75b1697ed5af68f08267be5dd2ca62..49f9b12ab69ea6a616dcfa74e7bc39a3395bccb1 100644 (file)
@@ -198,6 +198,7 @@ class DecimalQuantityTest : public IntlTest {
     void testConvertToAccurateDouble();
     void testUseApproximateDoubleWhenAble();
     void testHardDoubleConversion();
+    void testFitsInLong();
     void testToDouble();
     void testMaxDigits();
     void testNickelRounding();
index 4d74a55842bd2ea15e7d828c4ed339d6abb60f94..689af5c48852c5950729f15dfd874cab0260cc3b 100644 (file)
@@ -498,16 +498,14 @@ void NumberFormatterApiTest::notationCompact() {
             1e7,
             u"1000\u842C");
 
-    if (!logKnownIssue("21258", "StandardPlural cannot handle keywords 1, 0")) {
-        assertFormatSingle(
-                u"Compact with plural form =1 (ICU-21258)",
-                u"compact-long",
-                u"K",
-                NumberFormatter::with().notation(Notation::compactLong()),
-                Locale("fr-FR"),
-                1e3,
-                u"mille");
-    }
+    assertFormatSingle(
+            u"Compact with plural form =1 (ICU-21258)",
+            u"compact-long",
+            u"KK",
+            NumberFormatter::with().notation(Notation::compactLong()),
+            Locale("fr-FR"),
+            1e3,
+            u"mille");
 
     assertFormatSingle(
             u"Compact Infinity",
index 610df9658c831b86521334dc643fb8b92b5945ca..7403dda7e75b1033cc61daf95817f6bd3ddf8562 100644 (file)
@@ -27,6 +27,7 @@ void DecimalQuantityTest::runIndexedTest(int32_t index, UBool exec, const char *
         }
         TESTCASE_AUTO(testUseApproximateDoubleWhenAble);
         TESTCASE_AUTO(testHardDoubleConversion);
+        TESTCASE_AUTO(testFitsInLong);
         TESTCASE_AUTO(testToDouble);
         TESTCASE_AUTO(testMaxDigits);
         TESTCASE_AUTO(testNickelRounding);
@@ -357,6 +358,44 @@ void DecimalQuantityTest::testHardDoubleConversion() {
     }
 }
 
+void DecimalQuantityTest::testFitsInLong() {
+    IcuTestErrorCode status(*this, "testFitsInLong");
+    DecimalQuantity quantity;
+    quantity.setToInt(0);
+    assertTrue("Zero should fit", quantity.fitsInLong());
+    quantity.setToInt(42);
+    assertTrue("Small int should fit", quantity.fitsInLong());
+    quantity.setToDouble(0.1);
+    assertFalse("Fraction should not fit", quantity.fitsInLong());
+    quantity.setToDouble(42.1);
+    assertFalse("Fraction should not fit", quantity.fitsInLong());
+    quantity.setToLong(1000000);
+    assertTrue("Large low-precision int should fit", quantity.fitsInLong());
+    quantity.setToLong(1000000000000000000L);
+    assertTrue("10^19 should fit", quantity.fitsInLong());
+    quantity.setToLong(1234567890123456789L);
+    assertTrue("A number between 10^19 and max long should fit", quantity.fitsInLong());
+    quantity.setToLong(1234567890000000000L);
+    assertTrue("A number with trailing zeros less than max long should fit", quantity.fitsInLong());
+    quantity.setToLong(9223372026854775808L);
+    assertTrue("A number less than max long but with similar digits should fit",
+            quantity.fitsInLong());
+    quantity.setToLong(9223372036854775806L);
+    assertTrue("One less than max long should fit", quantity.fitsInLong());
+    quantity.setToLong(9223372036854775807L);
+    assertTrue("Max long should fit", quantity.fitsInLong());
+    assertEquals("Max long should equal toLong", 9223372036854775807L, quantity.toLong(false));
+    quantity.setToDecNumber("9223372036854775808", status);
+    assertFalse("One greater than max long should not fit", quantity.fitsInLong());
+    assertEquals("toLong(true) should truncate", 223372036854775808L, quantity.toLong(true));
+    quantity.setToDecNumber("9223372046854775806", status);
+    assertFalse("A number between max long and 10^20 should not fit", quantity.fitsInLong());
+    quantity.setToDecNumber("9223372046800000000", status);
+    assertFalse("A large 10^19 number with trailing zeros should not fit", quantity.fitsInLong());
+    quantity.setToDecNumber("10000000000000000000", status);
+    assertFalse("10^20 should not fit", quantity.fitsInLong());
+}
+
 void DecimalQuantityTest::testToDouble() {
     IcuTestErrorCode status(*this, "testToDouble");
     static const struct TestCase {
@@ -531,12 +570,12 @@ void DecimalQuantityTest::testScientificAndCompactSuppressedExponent() {
         {u"scientific",    0.012, u"1,2E-2",  0L, 0.012, u"0.012", -2, -2},
 
         {u"",              999.9, u"999,9",     999L,  999.9,  u"999.9", 0, 0},
-        {u"compact-long",  999.9, u"1 millier", 1000L, 1000.0, u"1000",  3, 3},
+        {u"compact-long",  999.9, u"mille",     1000L, 1000.0, u"1000",  3, 3},
         {u"compact-short", 999.9, u"1 k",       1000L, 1000.0, u"1000",  3, 3},
         {u"scientific",    999.9, u"9,999E2",   999L,  999.9,  u"999.9", 2, 2},
 
         {u"",              1000.0, u"1 000",     1000L, 1000.0, u"1000", 0, 0},
-        {u"compact-long",  1000.0, u"1 millier", 1000L, 1000.0, u"1000", 3, 3},
+        {u"compact-long",  1000.0, u"mille",     1000L, 1000.0, u"1000", 3, 3},
         {u"compact-short", 1000.0, u"1 k",       1000L, 1000.0, u"1000", 3, 3},
         {u"scientific",    1000.0, u"1E3",       1000L, 1000.0, u"1000", 3, 3},
     };
index d77a7ff6e04d7c21007e05aab593e6cf2628c04b..ff9fc7ddbaeb5da5db329fced5759e90a736823c 100644 (file)
@@ -22,7 +22,9 @@ public enum StandardPlural {
     TWO("two"),
     FEW("few"),
     MANY("many"),
-    OTHER("other");
+    OTHER("other"),
+    EQ_0("=0"),
+    EQ_1("=1");
 
     /**
      * Numeric index of OTHER, same as OTHER.ordinal().
@@ -60,6 +62,20 @@ public enum StandardPlural {
      */
     public static final StandardPlural orNullFromString(CharSequence keyword) {
         switch (keyword.length()) {
+        case 1:
+            if (keyword.charAt(0) == '0') {
+                return EQ_0;
+            } else if (keyword.charAt(0) == '1') {
+                return EQ_1;
+            }
+            break;
+        case 2:
+            if ("=0".contentEquals(keyword)) {
+                return EQ_0;
+            } else if ("=1".contentEquals(keyword)) {
+                return EQ_1;
+            }
+            break;    
         case 3:
             if ("one".contentEquals(keyword)) {
                 return ONE;
index b3e536afde3d1bd39f9ac62b9ca480a18dbab16e..1cc28992cffb7f21543e42822dcb0df75df499ba 100644 (file)
@@ -10,6 +10,7 @@ import com.ibm.icu.impl.ICUData;
 import com.ibm.icu.impl.ICUResourceBundle;
 import com.ibm.icu.impl.StandardPlural;
 import com.ibm.icu.impl.UResource;
+import com.ibm.icu.text.PluralRules;
 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
 import com.ibm.icu.util.ICUException;
 import com.ibm.icu.util.ULocale;
@@ -99,10 +100,6 @@ public class CompactData implements MultiplierProducer {
             byte magnitude = (byte) (magnitudeEntry.getKey().length() - 1);
             for (Map.Entry<String, String> pluralEntry : magnitudeEntry.getValue().entrySet()) {
                 String pluralString = pluralEntry.getKey().toString();
-                if ("0".equals(pluralString) || "1".equals(pluralString)) {
-                    // TODO(ICU-21258): Handle this case. For now, skip.
-                    continue;
-                }
                 StandardPlural plural = StandardPlural.fromString(pluralString);
                 String patternString = pluralEntry.getValue().toString();
                 patterns[getIndex(magnitude, plural)] = patternString;
@@ -130,14 +127,27 @@ public class CompactData implements MultiplierProducer {
         return multipliers[magnitude];
     }
 
-    public String getPattern(int magnitude, StandardPlural plural) {
+    public String getPattern(int magnitude, PluralRules rules, DecimalQuantity dq) {
         if (magnitude < 0) {
             return null;
         }
         if (magnitude > largestMagnitude) {
             magnitude = largestMagnitude;
         }
-        String patternString = patterns[getIndex(magnitude, plural)];
+        String patternString = null;
+        if (dq.isHasIntegerValue()) {
+            long i = dq.toLong(true);
+            if (i == 0) {
+                patternString = patterns[getIndex(magnitude, StandardPlural.EQ_0)];
+            } else if (i == 1) {
+                patternString = patterns[getIndex(magnitude, StandardPlural.EQ_1)];
+            }
+            if (patternString != null) {
+                return patternString;
+            }
+        }
+        StandardPlural plural = dq.getStandardPlural(rules);
+        patternString = patterns[getIndex(magnitude, plural)];
         if (patternString == null && plural != StandardPlural.OTHER) {
             // Fall back to "other" plural variant
             patternString = patterns[getIndex(magnitude, StandardPlural.OTHER)];
@@ -181,12 +191,6 @@ public class CompactData implements MultiplierProducer {
                 // Iterate over the plural variants ("one", "other", etc)
                 UResource.Table pluralVariantsTable = value.getTable();
                 for (int i4 = 0; pluralVariantsTable.getKeyAndValue(i4, key, value); ++i4) {
-
-                    if ("0".equals(key.toString()) || "1".equals(key.toString())) {
-                        // TODO(ICU-21258): Handle this case. For now, skip.
-                        continue;
-                    }
-
                     // Skip this magnitude/plural if we already have it from a child locale.
                     // Note: This also skips USE_FALLBACK entries.
                     StandardPlural plural = StandardPlural.fromString(key.toString());
index d33f407c28e28304343830686d5d419adb2646b4..a571b65c71c707c11195df70955df2a52f01370e 100644 (file)
@@ -167,6 +167,18 @@ public interface DecimalQuantity extends PluralRules.IFixedDecimal {
 
     public BigDecimal toBigDecimal();
 
+    /**
+     * Returns a long approximating the decimal quantity. A long can only represent the
+     * integral part of the number.  Note: this method incorporates the value of
+     * {@code getExponent} (for cases such as compact notation) to return the proper long
+     * value represented by the result.
+     *
+     * @param truncateIfOverflow if false and the number does NOT fit, fails with an error.
+     *        See comment about call site guards in DecimalQuantity_AbstractBCD.java
+     * @return A 64-bit integer representation of the internal number.
+     */
+    public long toLong(boolean truncateIfOverflow);
+
     public void setToBigDecimal(BigDecimal input);
 
     public int maxRepresentableDigits();
index 2d98cc2e098f0848e33e20606f5eac6db22a585f..510177d3132416f884edfaaa18b77aa2ed96781e 100644 (file)
@@ -233,6 +233,11 @@ public abstract class DecimalQuantity_AbstractBCD implements DecimalQuantity {
         exponent = exponent + delta;
     }
 
+    @Override
+    public boolean isHasIntegerValue() {
+        return scale >= 0;
+    }
+
     @Override
     public StandardPlural getStandardPlural(PluralRules rules) {
         if (rules == null) {
@@ -603,15 +608,7 @@ public abstract class DecimalQuantity_AbstractBCD implements DecimalQuantity {
         scale -= fracLength;
     }
 
-    /**
-     * Returns a long approximating the internal BCD. A long can only represent the integral part of the
-     * number.  Note: this method incorporates the value of {@code exponent}
-     * (for cases such as compact notation) to return the proper long value
-     * represented by the result.
-     *
-     * @param truncateIfOverflow if false and the number does NOT fit, fails with an assertion error.
-     * @return A 64-bit integer representation of the internal BCD.
-     */
+    @Override
     public long toLong(boolean truncateIfOverflow) {
         // NOTE: Call sites should be guarded by fitsInLong(), like this:
         // if (dq.fitsInLong()) { /* use dq.toLong() */ } else { /* use some fallback */ }
index 380114343085c674c96823f5aa919e2a57089337..0b5693788a9c0bf42daaff3c8cb9d6d63266524f 100644 (file)
@@ -138,8 +138,7 @@ public class CompactNotation extends Notation {
                 magnitude -= multiplier;
             }
 
-            StandardPlural plural = quantity.getStandardPlural(rules);
-            String patternString = data.getPattern(magnitude, plural);
+            String patternString = data.getPattern(magnitude, rules, quantity);
             if (patternString == null) {
                 // Use the default (non-compact) modifier.
                 // No need to take any action.
index 870b9476b8f9eb006d4d64111fdef82171039ac2..8ebc31bcbf4e2d648a851284517d2373838d08cc 100644 (file)
@@ -550,6 +550,14 @@ public class PluralRules implements Serializable {
          */
         @Deprecated
         public boolean isInfinite();
+
+        /**
+         * Whether the number has no nonzero fraction digits.
+         * @internal CLDR
+         * @deprecated This API is ICU internal only.
+         */
+        @Deprecated
+        public boolean isHasIntegerValue();
     }
 
     /**
@@ -639,6 +647,7 @@ public class PluralRules implements Serializable {
          * @deprecated This API is ICU internal only.
          */
         @Deprecated
+        @Override
         public boolean isHasIntegerValue() {
             return hasIntegerValue;
         }
index afc73dcdd958ad3889101a2513d82417ff668f63..24aedabd1ed5bc718edf8cc18aff99d3e8564f22 100644 (file)
@@ -325,6 +325,16 @@ public class DecimalQuantity_SimpleStorage implements DecimalQuantity {
     primary = -1;
   }
 
+  @Override
+  public long toLong(boolean truncateIfOverflow) {
+    BigDecimal temp = toBigDecimal().setScale(0, RoundingMode.FLOOR);
+    if (truncateIfOverflow) {
+      return temp.longValue();
+    } else {
+      return temp.longValueExact();
+    }
+  }
+
   @Override
   public void setMinInteger(int minInt) {
     // Graceful failures for bogus input
@@ -940,4 +950,9 @@ public class DecimalQuantity_SimpleStorage implements DecimalQuantity {
   public void adjustExponent(int delta) {
       origPrimaryScale = origPrimaryScale + delta;
   }
+
+  @Override
+  public boolean isHasIntegerValue() {
+    return scaleBigDecimal(toBigDecimal()) >= 0;
+  }
 }
index ec2d5982197694951039f3c4a2e1ea5426bdb875..f8d961d0e98764ea816413bbfe983d20fbfad04c 100644 (file)
@@ -269,6 +269,10 @@ public class DecimalQuantityTest extends TestFmwk {
                 q0.toBigDecimal(),
                 q1.toBigDecimal());
 
+        assertEquals("Different long values (" + q0 + ", " + q1 + ")",
+                q0.toLong(true),
+                q1.toLong(true));
+
         q0.roundToInfinity();
         q1.roundToInfinity();
 
@@ -456,8 +460,16 @@ public class DecimalQuantityTest extends TestFmwk {
         assertTrue("One less than max long should fit", quantity.fitsInLong());
         quantity.setToLong(9223372036854775807L);
         assertTrue("Max long should fit", quantity.fitsInLong());
+        assertEquals("Max long should equal toLong", 9223372036854775807L, quantity.toLong(false));
         quantity.setToBigInteger(new BigInteger("9223372036854775808"));
-        assertFalse("One greater than max long long should not fit", quantity.fitsInLong());
+        assertFalse("One greater than max long should not fit", quantity.fitsInLong());
+        assertEquals("toLong(true) should truncate", 223372036854775808L, quantity.toLong(true));
+        try {
+            quantity.toLong(false);
+            fail("One greater than max long is not convertible to long");
+        } catch (ArithmeticException | AssertionError e) {
+            // expected
+        }
         quantity.setToBigInteger(new BigInteger("9223372046854775806"));
         assertFalse("A number between max long and 10^20 should not fit", quantity.fitsInLong());
         quantity.setToBigInteger(new BigInteger("9223372046800000000"));
@@ -652,12 +664,12 @@ public class DecimalQuantityTest extends TestFmwk {
                 {"scientific",    0.012, "1,2E-2",  0L, 0.012, new BigDecimal("0.012"), "0.012", -2, -2},
 
                 {"",              999.9, "999,9",     999L,  999.9,  new BigDecimal("999.9"), "999.9", 0, 0},
-                {"compact-long",  999.9, "1 millier", 1000L, 1000.0, new BigDecimal("1000"),  "1000",  3, 3},
+                {"compact-long",  999.9, "mille",     1000L, 1000.0, new BigDecimal("1000"),  "1000",  3, 3},
                 {"compact-short", 999.9, "1 k",       1000L, 1000.0, new BigDecimal("1000"),  "1000",  3, 3},
                 {"scientific",    999.9, "9,999E2",   999L,  999.9,  new BigDecimal("999.9"), "999.9", 2, 2},
 
                 {"",              1000.0, "1 000",     1000L, 1000.0, new BigDecimal("1000"), "1000", 0, 0},
-                {"compact-long",  1000.0, "1 millier", 1000L, 1000.0, new BigDecimal("1000"), "1000", 3, 3},
+                {"compact-long",  1000.0, "mille",     1000L, 1000.0, new BigDecimal("1000"), "1000", 3, 3},
                 {"compact-short", 1000.0, "1 k",       1000L, 1000.0, new BigDecimal("1000"), "1000", 3, 3},
                 {"scientific",    1000.0, "1E3",       1000L, 1000.0, new BigDecimal("1000"), "1000", 3, 3},
         };
index 66a688039bafd98547c5cfe4921116df8e126194..cb57092d31a30945c5c2f626827b80e8ab1bcbc7 100644 (file)
@@ -443,16 +443,14 @@ public class NumberFormatterApiTest extends TestFmwk {
                 1e7,
                 "1000\u842C");
 
-        if (!logKnownIssue("21258", "StandardPlural cannot handle keywords 1, 0")) {
-            assertFormatSingle(
-                    "Compact with plural form =1 (ICU-21258)",
-                    "compact-long",
-                    "K",
-                    NumberFormatter.with().notation(Notation.compactLong()),
-                    ULocale.FRANCE,
-                    1e3,
-                    "mille");
-        }
+        assertFormatSingle(
+                "Compact with plural form =1 (ICU-21258)",
+                "compact-long",
+                "KK",
+                NumberFormatter.with().notation(Notation.compactLong()),
+                ULocale.FRANCE,
+                1e3,
+                "mille");
 
         assertFormatSingle(
                 "Compact Infinity",