]> granicus.if.org Git - icu/commitdiff
ICU-10361 DecimalFormat, remove number size restrictions that were limiting the abili...
authorAndy Heninger <andy.heninger@gmail.com>
Tue, 17 Sep 2013 21:56:23 +0000 (21:56 +0000)
committerAndy Heninger <andy.heninger@gmail.com>
Tue, 17 Sep 2013 21:56:23 +0000 (21:56 +0000)
X-SVN-Rev: 34366

icu4c/source/i18n/decimfmt.cpp
icu4c/source/i18n/numfmt.cpp
icu4c/source/i18n/unicode/numfmt.h
icu4c/source/test/intltest/numrgts.cpp
icu4c/source/test/intltest/numrgts.h

index 281384e98f462c5b8ddbfe62c32364f991405f00..10229d0301d021af42b4f5eb6ed72208e7adc557 100644 (file)
@@ -5270,7 +5270,7 @@ DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern,
                 setMinimumIntegerDigits(minInt);
                 setMaximumIntegerDigits(fUseExponentialNotation
                     ? digitLeftCount + getMinimumIntegerDigits()
-                    : kDoubleIntegerDigits);
+                    : NumberFormat::gDefaultMaxIntegerDigits);
                 setMaximumFractionDigits(decimalPos >= 0
                     ? (digitTotalCount - decimalPos) : 0);
                 setMinimumFractionDigits(decimalPos >= 0
@@ -5461,11 +5461,11 @@ DecimalFormat::applyPatternInternally(const UnicodeString& pluralCount,
 
 /**
  * Sets the maximum number of digits allowed in the integer portion of a
- * number. This override limits the integer digit count to 309.
+ * number. 
  * @see NumberFormat#setMaximumIntegerDigits
  */
 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
-    NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
+    NumberFormat::setMaximumIntegerDigits(_min(newValue, gDefaultMaxIntegerDigits));
 #if UCONFIG_FORMAT_FASTPATHS_49
     handleChanged();
 #endif
index 779b699d92f430bad524841267f9847ae34b0f51..be05b42516c97c3d5fd87b74bbc068a4fa29662a 100644 (file)
@@ -95,8 +95,9 @@ static const UChar gSlash = 0x2f;
 // If the maximum base 10 exponent were 4, then the largest number would
 // be 99,999 which has 5 digits.
 // On IEEE754 systems gMaxIntegerDigits is 308 + possible denormalized 15 digits + rounding digit
-static const int32_t gMaxIntegerDigits = DBL_MAX_10_EXP + DBL_DIG + 1;
-static const int32_t gMinIntegerDigits = 127;
+// With big decimal, the max exponent is 999,999,999 and the max number of digits is the same, 999,999,999
+const int32_t NumberFormat::gDefaultMaxIntegerDigits = 2000000000;
+const int32_t NumberFormat::gDefaultMinIntegerDigits = 127;
 
 static const UChar * const gLastResortNumberPatterns[UNUM_FORMAT_STYLE_COUNT] = {
     NULL,  // UNUM_PATTERN_DECIMAL
@@ -215,7 +216,7 @@ SimpleNumberFormatFactory::getSupportedIDs(int32_t &count, UErrorCode& status) c
 // default constructor
 NumberFormat::NumberFormat()
 :   fGroupingUsed(TRUE),
-    fMaxIntegerDigits(gMaxIntegerDigits),
+    fMaxIntegerDigits(gDefaultMaxIntegerDigits),
     fMinIntegerDigits(1),
     fMaxFractionDigits(3), // invariant, >= minFractionDigits
     fMinFractionDigits(0),
@@ -1046,7 +1047,7 @@ int32_t NumberFormat::getMaximumIntegerDigits() const
 void
 NumberFormat::setMaximumIntegerDigits(int32_t newValue)
 {
-    fMaxIntegerDigits = uprv_max(0, uprv_min(newValue, gMaxIntegerDigits));
+    fMaxIntegerDigits = uprv_max(0, uprv_min(newValue, gDefaultMaxIntegerDigits));
     if(fMinIntegerDigits > fMaxIntegerDigits)
         fMinIntegerDigits = fMaxIntegerDigits;
 }
@@ -1068,7 +1069,7 @@ NumberFormat::getMinimumIntegerDigits() const
 void
 NumberFormat::setMinimumIntegerDigits(int32_t newValue)
 {
-    fMinIntegerDigits = uprv_max(0, uprv_min(newValue, gMinIntegerDigits));
+    fMinIntegerDigits = uprv_max(0, uprv_min(newValue, gDefaultMinIntegerDigits));
     if(fMinIntegerDigits > fMaxIntegerDigits)
         fMaxIntegerDigits = fMinIntegerDigits;
 }
@@ -1090,7 +1091,7 @@ NumberFormat::getMaximumFractionDigits() const
 void
 NumberFormat::setMaximumFractionDigits(int32_t newValue)
 {
-    fMaxFractionDigits = uprv_max(0, uprv_min(newValue, gMaxIntegerDigits));
+    fMaxFractionDigits = uprv_max(0, uprv_min(newValue, gDefaultMaxIntegerDigits));
     if(fMaxFractionDigits < fMinFractionDigits)
         fMinFractionDigits = fMaxFractionDigits;
 }
@@ -1112,7 +1113,7 @@ NumberFormat::getMinimumFractionDigits() const
 void
 NumberFormat::setMinimumFractionDigits(int32_t newValue)
 {
-    fMinFractionDigits = uprv_max(0, uprv_min(newValue, gMinIntegerDigits));
+    fMinFractionDigits = uprv_max(0, uprv_min(newValue, gDefaultMinIntegerDigits));
     if (fMaxFractionDigits < fMinFractionDigits)
         fMaxFractionDigits = fMinFractionDigits;
 }
index b482be6c2dd75021209c531486bb162d0a09f379..1630657b6018b4fcd18607a3a0d602b627c22494 100644 (file)
@@ -1004,6 +1004,12 @@ private:
     int32_t     fMinIntegerDigits;
     int32_t     fMaxFractionDigits;
     int32_t     fMinFractionDigits;
+
+  protected:
+    static const int32_t gDefaultMaxIntegerDigits;
+    static const int32_t gDefaultMinIntegerDigits;
+  private:
     UBool      fParseIntegerOnly;
     UBool      fLenient; // TRUE => lenient parse is enabled
 
index b96fe1b096017a48a00cef729445375693665d08..4f9c55aae7aac42279346af802be1402823f2a5c 100644 (file)
@@ -172,6 +172,7 @@ NumberFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const cha
         CASE(62,Test9109);
         CASE(63,Test9780);
         CASE(64,Test9677);
+        CASE(65,Test10361);
 
         default: name = ""; break;
     }
@@ -2986,5 +2987,37 @@ void NumberFormatRegressionTest::Test9677(void) {
   }
 }
 
+void NumberFormatRegressionTest::Test10361(void) {
+    // DecimalFormat/NumberFormat were artificially limiting the number of digits,
+    //    preventing formatting of big decimals.
+    UErrorCode status = U_ZERO_ERROR;
+    LocalPointer<DecimalFormat> df(new DecimalFormat("###.##", status));
+    TEST_CHECK_STATUS(status);
+
+    // Create a decimal number with a million digits.
+    const int32_t NUMSIZE=1000000;
+    char *num = new char[NUMSIZE];
+    for (int32_t i=0; i<NUMSIZE; i++) {
+        num[i] = '0' + (i+1) % 10;
+    }
+    num[NUMSIZE-3] = '.';
+    num[NUMSIZE-1] = 0;
+
+    UnicodeString    s;
+    Formattable      fmtable;
+    fmtable.setDecimalNumber(num, status);
+    TEST_CHECK_STATUS(status);
+
+    FieldPosition pos(UNUM_DECIMAL_SEPARATOR_FIELD);
+    df->format(fmtable, s, pos, status);
+    TEST_CHECK_STATUS(status);
+    TEST_ASSERT(999999 == s.length());
+    TEST_ASSERT(999997 == pos.getBeginIndex());
+    TEST_ASSERT(999998 == pos.getEndIndex());
+
+    UnicodeString expected(num, -1, US_INV);
+    TEST_ASSERT(expected == s);
+    delete [] num;
+}
 
 #endif /* #if !UCONFIG_NO_FORMATTING */
index 96dc2995752ee9a61fcc60eda33f88225a213e15..3d07865880251c3d5ad8354e8fa85ca40dc5bdc7 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.
  ***********************************************************************/
 
@@ -94,6 +94,7 @@ public:
     void Test9109(void);
     void Test9780(void);
     void Test9677(void);
+    void Test10361(void);
 protected:
     UBool failure(UErrorCode status, const UnicodeString& msg, UBool possibleDataError=FALSE);
     UBool failure(UErrorCode status, const UnicodeString& msg, const char *l, UBool possibleDataError=FALSE);