From fd5c76edbdeb19fc1ebc12a08cdae51db3bc18f9 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Tue, 21 Sep 2021 07:33:11 +0000 Subject: [PATCH] ICU-20425 Strip trailing zeros from Java rounding increment See #1726 --- icu4c/source/test/intltest/numfmtst.cpp | 22 +++++++++++++++++++ icu4c/source/test/intltest/numfmtst.h | 2 ++ .../ibm/icu/number/NumberPropertyMapper.java | 3 +++ .../src/com/ibm/icu/text/DecimalFormat.java | 5 ++++- .../icu/dev/test/format/NumberFormatTest.java | 21 +++++++++++++++++- 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index ee74b3bbe1f..34e81d473a6 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -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"); diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h index 8dffb9440aa..8af7d6e37ea 100644 --- a/icu4c/source/test/intltest/numfmtst.h +++ b/icu4c/source/test/intltest/numfmtst.h @@ -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(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java index a795ca7649f..2ed5f1c2bc4 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java @@ -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) { diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java index 3a969dbaccc..667e2951c91 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java @@ -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); } } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java index 83b60041778..4489446c53e 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java @@ -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(); -- 2.40.0