From b15c2bbf3b6645da7bd04bdfe1cc79ed594d6f49 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 6 Jul 2012 22:47:27 +0000 Subject: [PATCH] ICU-9416 fix number formatting for max int digits in fastpath X-SVN-Rev: 32026 --- icu4c/source/i18n/decimfmt.cpp | 12 ++++---- icu4c/source/test/cintltst/cnumtst.c | 44 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index 986243e62e6..3cb70872840 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -1109,14 +1109,14 @@ DecimalFormat::_format(int64_t number, // Slide the number to the start of the output str U_ASSERT(destIdx >= 0); int32_t length = MAX_IDX - destIdx -1; - //uprv_memmove(outputStr, outputStr+MAX_IDX-length, length); int32_t prefixLen = appendAffix(appendTo, number, handler, number<0, TRUE); - int32_t maxIntDig = getMaximumIntegerDigits(); - int32_t prependZero = getMinimumIntegerDigits() - length; + int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinned to max int digits + + int32_t prependZero = getMinimumIntegerDigits() - destlength; #ifdef FMT_DEBUG - printf("prependZero=%d, length=%d, minintdig=%d\n", prependZero, length, getMinimumIntegerDigits()); + printf("prependZero=%d, length=%d, minintdig=%d maxintdig=%d destlength=%d skip=%d\n", prependZero, length, getMinimumIntegerDigits(), maxIntDig, destlength, length-destlength); #endif int32_t intBegin = appendTo.length(); @@ -1124,7 +1124,9 @@ DecimalFormat::_format(int64_t number, appendTo.append(0x0030); // '0' } - appendTo.append(outputStr+destIdx, length); + appendTo.append(outputStr+destIdx+ + (length-destlength), // skip any leading digits + destlength); handler.addAttribute(kIntegerField, intBegin, appendTo.length()); int32_t suffixLen = appendAffix(appendTo, number, handler, number<0, FALSE); diff --git a/icu4c/source/test/cintltst/cnumtst.c b/icu4c/source/test/cintltst/cnumtst.c index 81ba501d836..50d69f1c2eb 100644 --- a/icu4c/source/test/cintltst/cnumtst.c +++ b/icu4c/source/test/cintltst/cnumtst.c @@ -41,6 +41,8 @@ static void TestNBSPInPattern(void); static void TestInt64Parse(void); static void TestParseCurrency(void); +static void TestMaxInt(void); + #define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x) void addNumForTest(TestNode** root) @@ -60,6 +62,7 @@ void addNumForTest(TestNode** root) TESTCASE(TestParseZero); TESTCASE(TestParseCurrency); TESTCASE(TestCloneWithRBNF); + TESTCASE(TestMaxInt); } /** copy src to dst with unicode-escapes for values < 0x20 and > 0x7e, null terminate if possible */ @@ -2028,4 +2031,45 @@ static void TestCloneWithRBNF(void) { log_data_err("Result from cloned formatter not identical to the original. Original: %s Cloned: %s - (Are you missing data?)",u_austrcpy(temp1, buffer),u_austrcpy(temp2,buffer_cloned)); } } + +static void TestMaxInt(void) { + UErrorCode status = U_ZERO_ERROR; + UChar pattern_hash[] = { 0x23, 0x00 }; /* "#" */ + UChar result1[1024] = { 0 }, result2[1024] = { 0 }; + int32_t len1, len2; + UChar expect[] = { 0x0039, 0x0037, 0 }; + UNumberFormat *fmt = unum_open( + UNUM_PATTERN_DECIMAL, /* style */ + &pattern_hash[0], /* pattern */ + u_strlen(pattern_hash), /* patternLength */ + 0, + 0, /* parseErr */ + &status); + if(U_FAILURE(status) || fmt == NULL) { + log_data_err("%s:%d: %s: unum_open failed with %s (Are you missing data?)\n", __FILE__, __LINE__, "TestMaxInt", u_errorName(status)); + return; + } + + unum_setAttribute(fmt, UNUM_MAX_INTEGER_DIGITS, 2); + + status = U_ZERO_ERROR; + /* #1 */ + len1 = unum_formatInt64(fmt, 1997, result1, 1024, NULL, &status); + result1[len1]=0; + if(U_FAILURE(status) || u_strcmp(expect, result1)) { + log_err("unum_formatInt64 Expected %s but got %s status %s\n", austrdup(expect), austrdup(result1), u_errorName(status)); + } + + status = U_ZERO_ERROR; + /* #2 */ + len2 = unum_formatDouble(fmt, 1997.0, result2, 1024, NULL, &status); + result2[len2]=0; + if(U_FAILURE(status) || u_strcmp(expect, result2)) { + log_err("unum_formatDouble Expected %s but got %s status %s\n", austrdup(expect), austrdup(result2), u_errorName(status)); + } + + unum_close(fmt); + +} + #endif /* #if !UCONFIG_NO_FORMATTING */ -- 2.40.0