From 6f5bfa57697dda5cc972cccf6331dc922bb8790f Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Thu, 5 Oct 2017 22:33:45 +0000 Subject: [PATCH] ICU-13310 Improving backwards compatibility of scientific notation formatting. X-SVN-Rev: 40575 --- .../ibm/icu/number/NumberPropertyMapper.java | 24 +++++++++---------- .../icu/dev/test/format/NumberFormatTest.java | 3 ++- 2 files changed, 14 insertions(+), 13 deletions(-) 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 04c8d8905af..9d681b56c7f 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 @@ -216,19 +216,17 @@ final class NumberPropertyMapper { // Scientific notation is required. // This whole section feels like a hack, but it is needed for regression tests. // The mapping from property bag to scientific notation is nontrivial due to LDML rules. - // The maximum of 8 digits has unknown origins and is not in the spec. - if (minInt > 8) { - minInt = 8; - maxInt = 8; + if (maxInt > 8) { + // But #13110: The maximum of 8 digits has unknown origins and is not in the spec. + // If maxInt is greater than 8, it is set to minInt, even if minInt is greater than 8. + maxInt = minInt; + macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt); + } else if (maxInt > minInt && minInt > 1) { + // Bug #13289: if maxInt > minInt > 1, then minInt should be 1. + minInt = 1; macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt); } - int engineering = maxInt > 8 ? minInt : maxInt < minInt ? -1 : maxInt; - engineering = (engineering < 0) ? 0 : engineering; - // Bug #13289: if maxInt > minInt > 1, then minInt should be 1. - // Clear out IntegerWidth to prevent padding extra zeros. - if (maxInt > minInt && minInt > 1) { - macros.integerWidth = null; - } + int engineering = maxInt < 0 ? -1 : maxInt; macros.notation = new ScientificNotation( // Engineering interval: engineering, @@ -241,6 +239,8 @@ final class NumberPropertyMapper { // Scientific notation also involves overriding the rounding mode. // TODO: Overriding here is a bit of a hack. Should this logic go earlier? if (macros.rounder instanceof FractionRounder) { + // For the purposes of rounding, get the original min/max int/frac, since the local variables + // have been manipulated for display purposes. int minInt_ = properties.getMinimumIntegerDigits(); int minFrac_ = properties.getMinimumFractionDigits(); int maxFrac_ = properties.getMaximumFractionDigits(); @@ -252,7 +252,7 @@ final class NumberPropertyMapper { macros.rounder = Rounder.constructSignificant(1, maxFrac_ + 1).withMode(mathContext); } else { // All other scientific patterns, which mean round to minInt+maxFrac - macros.rounder = Rounder.constructSignificant(minInt + minFrac, minInt + maxFrac) + macros.rounder = Rounder.constructSignificant(minInt_ + minFrac_, minInt_ + maxFrac_) .withMode(mathContext); } } 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 66722432681..102ca85a07a 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 @@ -5261,8 +5261,9 @@ public class NumberFormatTest extends TestFmwk { @Test public void Test13310() { + // Note: if minInt > 8, then maxInt can be greater than 8. assertEquals("Should not throw an assertion error", - "10000000.76E0", + "100000007.6E-1", new DecimalFormat("000000000.0#E0").format(10000000.76d)); } -- 2.40.0