]> granicus.if.org Git - icu/commitdiff
ICU-20425 Strip trailing zeros from Java rounding increment
authorShane F. Carr <shane@unicode.org>
Tue, 21 Sep 2021 07:33:11 +0000 (07:33 +0000)
committerShane F. Carr <shane@unicode.org>
Wed, 22 Sep 2021 03:28:06 +0000 (22:28 -0500)
See #1726

icu4c/source/test/intltest/numfmtst.cpp
icu4c/source/test/intltest/numfmtst.h
icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java

index ee74b3bbe1f2f7e6600da803ee2b540513e742ed..34e81d473a6e60e2ec515fd5d95a1b7878188e59 100644 (file)
@@ -247,6 +247,8 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(Test20961_CurrencyPluralPattern);
   TESTCASE_AUTO(Test21134_ToNumberFormatter);
   TESTCASE_AUTO(Test13733_StrictAndLenient);
+  TESTCASE_AUTO(Test20425_IntegerIncrement);
+  TESTCASE_AUTO(Test20425_FractionWithIntegerIncrement);
   TESTCASE_AUTO(Test21232_ParseTimeout);
   TESTCASE_AUTO(Test10997_FormatCurrency);
   TESTCASE_AUTO_END;
@@ -10039,6 +10041,26 @@ void NumberFormatTest::Test13733_StrictAndLenient() {
     }
 }
 
+void NumberFormatTest::Test20425_IntegerIncrement() {
+    IcuTestErrorCode status(*this, "Test20425_IntegerIncrement");
+
+    DecimalFormat df("##00", status);
+    df.setRoundingIncrement(1);
+    UnicodeString actual;
+    df.format(1235.5, actual, status);
+    assertEquals("Should round to integer", u"1236", actual);
+}
+
+void NumberFormatTest::Test20425_FractionWithIntegerIncrement() {
+    IcuTestErrorCode status(*this, "Test20425_FractionWithIntegerIncrement");
+
+    DecimalFormat df("0.0", status);
+    df.setRoundingIncrement(1);
+    UnicodeString actual;
+    df.format(8.6, actual, status);
+    assertEquals("Should have a fraction digit", u"9.0", actual);
+}
+
 void NumberFormatTest::Test21232_ParseTimeout() {
     IcuTestErrorCode status(*this, "Test21232_ParseTimeout");
 
index 8dffb9440aacedf8eecbb55725ee7d4af1dcb9d7..8af7d6e37ead1450fb5087ffbceedda70dad808b 100644 (file)
@@ -303,6 +303,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
     void Test20961_CurrencyPluralPattern();
     void Test21134_ToNumberFormatter();
     void Test13733_StrictAndLenient();
+    void Test20425_IntegerIncrement();
+    void Test20425_FractionWithIntegerIncrement();
     void Test21232_ParseTimeout();
     void Test10997_FormatCurrency();
 
index a795ca7649fcce74a30dc7204737a41d66b3a021..2ed5f1c2bc42ef9d92f333a1a62f4ea5c2bc4e03 100644 (file)
@@ -175,6 +175,9 @@ final class NumberPropertyMapper {
             if (PatternStringUtils.ignoreRoundingIncrement(roundingIncrement, maxFrac)) {
                 rounding = Precision.constructFraction(minFrac, maxFrac);
             } else {
+                if (minFrac > roundingIncrement.scale()) {
+                    roundingIncrement = roundingIncrement.setScale(minFrac);
+                }
                 rounding = Precision.constructIncrement(roundingIncrement);
             }
         } else if (explicitMinMaxSig) {
index 3a969dbaccc46a2e69d0206a02889eff39e6d100..667e2951c91300db101bd0168b8a0ae93a8cb889 100644 (file)
@@ -1248,7 +1248,10 @@ public class DecimalFormat extends NumberFormat {
     if (increment == 0) {
       setRoundingIncrement((java.math.BigDecimal) null);
     } else {
-      java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(increment);
+      // ICU-20425: Since doubles have no concept of trailing zeros, we should strip
+      // trailing zeros from the BigDecimal.
+      java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(increment)
+        .stripTrailingZeros();
       setRoundingIncrement(javaBigDecimal);
     }
   }
index 83b60041778e2e9da4e7835a987a77dcb18c757e..4489446c53eb4e65ec67066aecf3839bfdc3f847 100644 (file)
@@ -4104,7 +4104,7 @@ public class NumberFormatTest extends TestFmwk {
             new SetMxFrAndRndIncrItem( "15 en_US DEC 1/1/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  3, 0.02,   "#,##0.02#",  0.128, "0.12"  ), // use incr
             new SetMxFrAndRndIncrItem( "16 en_US DEC 1/2/2/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  2, 0.02,   "#,##0.02",   0.128, "0.12"  ), // use incr
             new SetMxFrAndRndIncrItem( "17 en_US DEC 1/2/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  3, 0.02,   "#,##0.02#",  0.128, "0.12"  ), // use incr
-            new SetMxFrAndRndIncrItem( "18 en_US DEC 1/3/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  3,  3, 0.02,   "#,##0.020",  0.128, "0.12"  ), // use incr; expFmt != ICU4C
+            new SetMxFrAndRndIncrItem( "18 en_US DEC 1/3/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  3,  3, 0.02,   "#,##0.020",  0.128, "0.120" ), // use incr
 
             new SetMxFrAndRndIncrItem( "20 en_US DEC 1/1/1/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  1, 0.0075, "#,##0.0",    0.019, "0.0"    ),
             new SetMxFrAndRndIncrItem( "21 en_US DEC 1/1/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  2, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
@@ -4134,6 +4134,9 @@ public class NumberFormatTest extends TestFmwk {
                 double  testIncr = item.roundIncr;
                 for (; testIncr > ((int)testIncr); testIncr *= 10.0, fracForRoundIncr++);
             }
+            if (fracForRoundIncr < item.minFrac) {
+                fracForRoundIncr = item.minFrac;
+            }
 
             int minInt = df.getMinimumIntegerDigits();
             if (minInt != item.minInt) {
@@ -6907,6 +6910,22 @@ public class NumberFormatTest extends TestFmwk {
         }
     }
 
+    @Test
+    public void Test20425_IntegerIncrement() {
+        DecimalFormat df = new DecimalFormat("##00");
+        df.setRoundingIncrement(1);
+        String actual = df.format(1235.5);
+        assertEquals("Should round to integer", "1236", actual);
+    }
+
+    @Test
+    public void Test20425_FractionWithIntegerIncrement() {
+        DecimalFormat df = new DecimalFormat("0.0");
+        df.setRoundingIncrement(1);
+        String actual = df.format(8.6);
+        assertEquals("Should have a fraction digit", "9.0", actual);
+    }
+
     @Test
     public void Test21232_ParseTimeout() throws ParseException {
         DecimalFormat df = new DecimalFormat();