diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index 281384e98f4..10229d0301d 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -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 diff --git a/icu4c/source/i18n/numfmt.cpp b/icu4c/source/i18n/numfmt.cpp index 779b699d92f..be05b42516c 100644 --- a/icu4c/source/i18n/numfmt.cpp +++ b/icu4c/source/i18n/numfmt.cpp @@ -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; } diff --git a/icu4c/source/i18n/unicode/numfmt.h b/icu4c/source/i18n/unicode/numfmt.h index b482be6c2dd..1630657b601 100644 --- a/icu4c/source/i18n/unicode/numfmt.h +++ b/icu4c/source/i18n/unicode/numfmt.h @@ -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 diff --git a/icu4c/source/test/intltest/numrgts.cpp b/icu4c/source/test/intltest/numrgts.cpp index b96fe1b0960..4f9c55aae7a 100644 --- a/icu4c/source/test/intltest/numrgts.cpp +++ b/icu4c/source/test/intltest/numrgts.cpp @@ -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 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; iformat(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 */ diff --git a/icu4c/source/test/intltest/numrgts.h b/icu4c/source/test/intltest/numrgts.h index 96dc2995752..3d078658802 100644 --- a/icu4c/source/test/intltest/numrgts.h +++ b/icu4c/source/test/intltest/numrgts.h @@ -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);