]> granicus.if.org Git - icu/commitdiff
ICU-13634 Fixing significant digit display on zero when minInt is zero.
authorShane Carr <shane@unicode.org>
Fri, 30 Mar 2018 08:21:06 +0000 (08:21 +0000)
committerShane Carr <shane@unicode.org>
Fri, 30 Mar 2018 08:21:06 +0000 (08:21 +0000)
X-SVN-Rev: 41178

icu4c/source/i18n/number_decimalquantity.cpp
icu4c/source/i18n/number_rounding.cpp
icu4c/source/test/intltest/numbertest_api.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalQuantity_AbstractBCD.java
icu4j/main/classes/core/src/com/ibm/icu/number/Rounder.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java

index a63044f9812c228774d7a0185ecfd4a09442ff17..bb731938f1212965fb4b8ced5d52e8f6c2ef63e1 100644 (file)
@@ -149,6 +149,12 @@ void DecimalQuantity::setIntegerLength(int32_t minInt, int32_t maxInt) {
     U_ASSERT(minInt >= 0);
     U_ASSERT(maxInt >= minInt);
 
+    // Special behavior: do not set minInt to be less than what is already set.
+    // This is so significant digits rounding can set the integer length.
+    if (minInt < lReqPos) {
+        minInt = lReqPos;
+    }
+
     // Save values into internal state
     // Negation is safe for minFrac/maxFrac because -Integer.MAX_VALUE > Integer.MIN_VALUE
     lOptPos = maxInt;
index 80120261e1cde41a44bed13646bd99f73261976c..b5e37194f8dd91a9c6841222ea160ab059621d44 100644 (file)
@@ -342,6 +342,10 @@ void Rounder::apply(impl::DecimalQuantity &value, UErrorCode& status) const {
             value.setFractionLength(
                     uprv_max(0, -getDisplayMagnitudeSignificant(value, fUnion.fracSig.fMinSig)),
                     INT32_MAX);
+            // Make sure that digits are displayed on zero.
+            if (value.isZero() && fUnion.fracSig.fMinSig > 0) {
+                value.setIntegerLength(1, INT32_MAX);
+            }
             break;
 
         case RND_FRACTION_SIGNIFICANT: {
index 9fe790cd4a69558529a56334838d01e9c78f1362..a6d1a3553c6b40a28d257c96e901ccac460f8132 100644 (file)
@@ -910,6 +910,24 @@ void NumberFormatterApiTest::roundingFigures() {
             Locale::getEnglish(),
             9.99999,
             u"10.0");
+
+    assertFormatSingle(
+            u"Fixed Significant on zero with lots of integer width",
+            u"@ integer-width/+000",
+            NumberFormatter::with().rounding(Rounder::fixedDigits(1))
+                    .integerWidth(IntegerWidth::zeroFillTo(3)),
+            Locale::getEnglish(),
+            0,
+            "000");
+
+    assertFormatSingle(
+            u"Fixed Significant on zero with zero integer width",
+            u"@ integer-width/+",
+            NumberFormatter::with().rounding(Rounder::fixedDigits(1))
+                    .integerWidth(IntegerWidth::zeroFillTo(0)),
+            Locale::getEnglish(),
+            0,
+            "0");
 }
 
 void NumberFormatterApiTest::roundingFractionFigures() {
index b5afb37e2e6dac215c8d64dd2fedd86feb80e825..d513ef3c1601a32a1a8dec13e175504172d11cbf 100644 (file)
@@ -142,6 +142,12 @@ public abstract class DecimalQuantity_AbstractBCD implements DecimalQuantity {
         assert minInt >= 0;
         assert maxInt >= minInt;
 
+        // Special behavior: do not set minInt to be less than what is already set.
+        // This is so significant digits rounding can set the integer length.
+        if (minInt < lReqPos) {
+            minInt = lReqPos;
+        }
+
         // Save values into internal state
         // Negation is safe for minFrac/maxFrac because -Integer.MAX_VALUE > Integer.MIN_VALUE
         lOptPos = maxInt;
index 9cec17b8af6cb82de84c566e419d5643b53c680c..47b6df70843ead9201143b5bc8fb0478b4b69b1f 100644 (file)
@@ -609,6 +609,10 @@ public abstract class Rounder implements Cloneable {
             value.roundToMagnitude(getRoundingMagnitudeSignificant(value, maxSig), mathContext);
             value.setFractionLength(Math.max(0, -getDisplayMagnitudeSignificant(value, minSig)),
                     Integer.MAX_VALUE);
+            // Make sure that digits are displayed on zero.
+            if (value.isZero() && minSig > 0) {
+                value.setIntegerLength(1, Integer.MAX_VALUE);
+            }
         }
 
         /**
index fad64604d95904e0647d07c5e9c982e1feeabd81..b9ca3976f3086c8c4ea65052c3e75a910933545a 100644 (file)
@@ -894,6 +894,22 @@ public class NumberFormatterApiTest {
                 ULocale.ENGLISH,
                 9.99999,
                 "10.0");
+
+        assertFormatSingle(
+                "Fixed Significant on zero with zero integer width",
+                "@ integer-width/+",
+                NumberFormatter.with().rounding(Rounder.fixedDigits(1)).integerWidth(IntegerWidth.zeroFillTo(0)),
+                ULocale.ENGLISH,
+                0,
+                "0");
+
+        assertFormatSingle(
+                "Fixed Significant on zero with lots of integer width",
+                "@ integer-width/+000",
+                NumberFormatter.with().rounding(Rounder.fixedDigits(1)).integerWidth(IntegerWidth.zeroFillTo(3)),
+                ULocale.ENGLISH,
+                0,
+                "000");
     }
 
     @Test