]> granicus.if.org Git - icu/commitdiff
ICU-10045 Formatting with significant digits to work correctly with 0 in C++
authorTravis Keep <keep94@gmail.com>
Tue, 2 Apr 2013 22:01:33 +0000 (22:01 +0000)
committerTravis Keep <keep94@gmail.com>
Tue, 2 Apr 2013 22:01:33 +0000 (22:01 +0000)
X-SVN-Rev: 33485

icu4c/source/i18n/decimfmt.cpp
icu4c/source/test/intltest/numfmtst.cpp
icu4c/source/test/intltest/numfmtst.h

index 6c3a9825a2a69ede4960e9fc30f26ae82493ab37..d38eae5694894ddf52591ad3048c82ad3b23676e 100644 (file)
@@ -1802,6 +1802,14 @@ DecimalFormat::subformat(UnicodeString& appendTo,
             count = 0;
         }
 
+        // This handles the special case of formatting 0. For zero only, we count the
+        // zero to the left of the decimal point as one signficant digit. Ordinarily we
+        // do not count any leading 0's as significant. If the number we are formatting
+        // is not zero, then either sigCount or digits.getDecimalAt() will be non-zero.
+        if (sigCount == 0 && digits.getDecimalAt() == 0) {
+          sigCount = 1;
+        }
+
         for (i=0; i < count; ++i) {
             // Here is where we escape from the loop.  We escape
             // if we've output the maximum fraction digits
index 9168a19a10d6461d39daf53144ecd3fd9180bfcd..cea63bdaf412eb1133eeb314e8bf2f492e4cabc2 100644 (file)
@@ -118,6 +118,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(Test9087);
   TESTCASE_AUTO(TestFormatFastpaths);
   TESTCASE_AUTO(TestFormattableSize);
+  TESTCASE_AUTO(TestSignificantDigits);
   TESTCASE_AUTO_END;
 }
 
@@ -6695,4 +6696,55 @@ void NumberFormatTest::TestFormattableSize(void) {
   }
 }
 
+void NumberFormatTest::TestSignificantDigits(void) {
+  double input[] = {
+        0, 0,
+        123, -123,
+        12345, -12345,
+        123.45, -123.45,
+        123.44501, -123.44501,
+        0.001234, -0.001234,
+        0.00000000123, -0.00000000123,
+        0.0000000000000000000123, -0.0000000000000000000123,
+        1.2, -1.2,
+        0.0000000012344501, -0.0000000012344501,
+        123445.01, -123445.01,
+        12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
+    };
+    const char* expected[] = {
+        "0.00", "0.00",
+        "123", "-123",
+        "12345", "-12345",
+        "123.45", "-123.45",
+        "123.45", "-123.45",
+        "0.001234", "-0.001234",
+        "0.00000000123", "-0.00000000123",
+        "0.0000000000000000000123", "-0.0000000000000000000123",
+        "1.20", "-1.20",
+        "0.0000000012345", "-0.0000000012345",
+        "123450", "-123450",
+        "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
+    };
+
+    UErrorCode status = U_ZERO_ERROR;
+    Locale locale("en_US");
+    DecimalFormat* numberFormat = static_cast<DecimalFormat*>(
+            NumberFormat::createInstance(locale, status));
+    numberFormat->setSignificantDigitsUsed(TRUE);
+    numberFormat->setMinimumSignificantDigits(3);
+    numberFormat->setMaximumSignificantDigits(5);
+    numberFormat->setGroupingUsed(false);
+    
+    UnicodeString result;
+    UnicodeString expectedResult;
+    for (int i = 0; i < sizeof(input)/sizeof(double); ++i) {
+        numberFormat->format(input[i], result);
+        expectedResult = UNICODE_STRING_SIMPLE(expected[i]);
+        if (result != expectedResult) {
+          errln((UnicodeString)"Expected: '" + expectedResult + "' got '" + result);
+        }
+        result.remove();
+    }
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */
index d46add7ca3a870e0a1c0644016f05fba8ab6f309..4f164a780ab8e3ff1d84342730b423e8492bbf4b 100644 (file)
@@ -1,6 +1,6 @@
 /************************************************************************
  * COPYRIGHT:
- * Copyright (c) 1997-2012, International Business Machines Corporation
+ * Copyright (c) 1997-2013, International Business Machines Corporation
  * and others. All Rights Reserved.
  ************************************************************************/
 
@@ -162,6 +162,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
 
     void TestEnumSet();
 
+    void TestSignificantDigits();
+
  private:
 
     static UBool equalValue(const Formattable& a, const Formattable& b);