]> granicus.if.org Git - icu/commitdiff
ICU-9416 fix number formatting for max int digits in fastpath
authorSteven R. Loomis <srl@icu-project.org>
Fri, 6 Jul 2012 22:47:27 +0000 (22:47 +0000)
committerSteven R. Loomis <srl@icu-project.org>
Fri, 6 Jul 2012 22:47:27 +0000 (22:47 +0000)
X-SVN-Rev: 32026

icu4c/source/i18n/decimfmt.cpp
icu4c/source/test/cintltst/cnumtst.c

index 986243e62e622f74257beb5998e387a894d2342b..3cb7087284004e39321b054e4a0dafc5ff624b01 100644 (file)
@@ -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);
index 81ba501d836a29d5822affbb5824f437694416aa..50d69f1c2ebdfd2986c8b2bc1a50323d06c049de 100644 (file)
@@ -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 */