1 /* 2 ******************************************************************************* 3 * Copyright (C) 1996-2009, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.test.format; 8 9 import java.text.ParseException; 10 import java.util.Locale; 11 12 import com.ibm.icu.dev.test.TestFmwk; 13 import com.ibm.icu.impl.Utility; 14 import com.ibm.icu.text.DecimalFormat; 15 import com.ibm.icu.text.DecimalFormatSymbols; 16 import com.ibm.icu.text.NumberFormat; 17 18 /** 19 * @test 20 * General test of Big NumberFormat 21 */ 22 public class BigNumberFormatTest extends TestFmwk { 23 24 static final int ILLEGAL = -1; 25 main(String[] args)26 public static void main(String[] args) throws Exception { 27 new BigNumberFormatTest().run(args); 28 } 29 TestExponent()30 public void TestExponent() { 31 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US); 32 DecimalFormat fmt1 = new DecimalFormat("0.###E0", US); 33 DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US); 34 Number n = new Long(1234); 35 expect(fmt1, n, "1.234E3"); 36 expect(fmt2, n, "1.234E+3"); 37 expect(fmt1, "1.234E3", n); 38 expect(fmt1, "1.234E+3", n); // Either format should parse "E+3" 39 expect(fmt2, "1.234E+3", n); 40 } 41 42 /** 43 * Test the functioning of the secondary grouping value. 44 */ TestSecondaryGrouping()45 public void TestSecondaryGrouping() { 46 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US); 47 DecimalFormat f = new DecimalFormat("#,##,###", US); 48 expect(f, new Long(123456789), "12,34,56,789"); 49 expectPat(f, "#,##,###"); 50 f.applyPattern("#,###"); 51 f.setSecondaryGroupingSize(4); 52 expect(f, new Long(123456789), "12,3456,789"); 53 expectPat(f, "#,####,###"); 54 55 // On Sun JDK 1.2-1.3, the hi_IN locale uses '0' for a zero digit, 56 // but on IBM JDK 1.2-1.3, the locale uses U+0966. 57 f = (DecimalFormat) NumberFormat.getInstance(new Locale("hi", "IN")); 58 String str = transmute("1,87,65,43,210", 59 f.getDecimalFormatSymbols().getZeroDigit()); 60 expect(f, new Long(1876543210), str); 61 } 62 expectPad(DecimalFormat fmt, String pat, int pos)63 private void expectPad(DecimalFormat fmt, String pat, int pos) { 64 expectPad(fmt, pat, pos, 0, (char)0); 65 } 66 expectPad(DecimalFormat fmt, String pat, int pos, int width, char pad)67 private void expectPad(DecimalFormat fmt, String pat, 68 int pos, int width, char pad) { 69 int apos = 0, awidth = 0; 70 char apad = 0; 71 try { 72 fmt.applyPattern(pat); 73 apos = fmt.getPadPosition(); 74 awidth = fmt.getFormatWidth(); 75 apad = fmt.getPadCharacter(); 76 } catch (IllegalArgumentException e) { 77 apos = -1; 78 awidth = width; 79 apad = pad; 80 } 81 if (apos == pos && awidth == width && apad == pad) { 82 logln("Ok \"" + pat + "\" pos=" + apos + 83 ((pos == -1) ? "" : " width=" + awidth + " pad=" + apad)); 84 } else { 85 logln("FAIL \"" + pat + "\" pos=" + apos + 86 " width=" + awidth + " pad=" + apad + 87 ", expected " + pos + " " + width + " " + pad); 88 } 89 } 90 91 /** 92 */ TestPatterns()93 public void TestPatterns() { 94 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US); 95 DecimalFormat fmt = new DecimalFormat("#", US); 96 97 expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, '^'); 98 expectPad(fmt, "$*^#", DecimalFormat.PAD_AFTER_PREFIX, 2, '^'); 99 expectPad(fmt, "#*^", DecimalFormat.PAD_BEFORE_SUFFIX, 1, '^'); 100 expectPad(fmt, "#$*^", DecimalFormat.PAD_AFTER_SUFFIX, 2, '^'); 101 expectPad(fmt, "$*^$#", ILLEGAL); 102 expectPad(fmt, "#$*^$", ILLEGAL); 103 expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat.PAD_BEFORE_SUFFIX, 104 12, 'x'); 105 expectPad(fmt, "''#0*x", DecimalFormat.PAD_BEFORE_SUFFIX, 106 3, 'x'); 107 expectPad(fmt, "'I''ll'*a###.##", DecimalFormat.PAD_AFTER_PREFIX, 108 10, 'a'); 109 110 fmt.applyPattern("AA#,##0.00ZZ"); 111 fmt.setPadCharacter('^'); 112 113 fmt.setFormatWidth(10); 114 115 fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX); 116 expectPat(fmt, "*^AA#,##0.00ZZ"); 117 118 fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX); 119 expectPat(fmt, "AA#,##0.00*^ZZ"); 120 121 fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX); 122 expectPat(fmt, "AA#,##0.00ZZ*^"); 123 124 // 12 3456789012 125 String exp = "AA*^#,##0.00ZZ"; 126 fmt.setFormatWidth(12); 127 fmt.setPadPosition(DecimalFormat.PAD_AFTER_PREFIX); 128 expectPat(fmt, exp); 129 130 fmt.setFormatWidth(13); 131 // 12 34567890123 132 expectPat(fmt, "AA*^##,##0.00ZZ"); 133 134 fmt.setFormatWidth(14); 135 // 12 345678901234 136 expectPat(fmt, "AA*^###,##0.00ZZ"); 137 138 fmt.setFormatWidth(15); 139 // 12 3456789012345 140 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case 141 142 fmt.setFormatWidth(16); 143 // 12 34567890123456 144 expectPat(fmt, "AA*^#,###,##0.00ZZ"); 145 } 146 expectPat(DecimalFormat fmt, String exp)147 private void expectPat(DecimalFormat fmt, String exp) { 148 String pat = fmt.toPattern(); 149 if (pat.equals(exp)) { 150 logln("Ok \"" + pat + '"'); 151 } else { 152 errln("FAIL \"" + pat + "\", expected \"" + exp + '"'); 153 } 154 } 155 156 /** 157 * Test the handling of the AlphaWorks BigDecimal 158 */ TestAlphaBigDecimal()159 public void TestAlphaBigDecimal() { 160 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US); 161 /*For ICU compatibility [Richard/GCL]*/ 162 expect(NumberFormat.getScientificInstance(Locale.US), 163 new Number[] { new com.ibm.icu.math.BigDecimal("12345.678901"), 164 }, 165 "1.2345678901E4"); 166 expect(new DecimalFormat("##0.####E0", US), 167 new Number[] { new com.ibm.icu.math.BigDecimal("12345.4999"), 168 new com.ibm.icu.math.BigDecimal("12344.5001"), 169 }, 170 "12.345E3"); 171 expect(new DecimalFormat("##0.####E0", US), 172 new Number[] { new com.ibm.icu.math.BigDecimal("12345.5000"), 173 new com.ibm.icu.math.BigDecimal("12346.5000"), 174 }, 175 "12.346E3"); 176 } 177 178 /** 179 */ TestScientific()180 public void TestScientific() { 181 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US); 182 /*For ICU compatibility [Richard/GCL]*/ 183 expect(NumberFormat.getScientificInstance(Locale.US), 184 new Number[] { new Double(12345.678901), 185 new java.math.BigDecimal("12345.678901"), 186 }, 187 "1.2345678901E4"); 188 expect(new DecimalFormat("##0.###E0", US), 189 new Double(12345), 190 "12.34E3"); 191 expect(new DecimalFormat("##0.###E0", US), 192 new Double(12345.00001), 193 "12.35E3"); 194 expect(new DecimalFormat("##0.####E0", US), 195 new Number[] { new Integer(12345), 196 new Long(12345), 197 new java.math.BigDecimal("12345.4999"), 198 new java.math.BigDecimal("12344.5001"), 199 }, 200 "12.345E3"); 201 expect(new DecimalFormat("##0.####E0", US), 202 new Number[] { new java.math.BigDecimal("12345.5000"), 203 new java.math.BigDecimal("12346.5000"), 204 }, 205 "12.346E3"); 206 /*For ICU compatibility [Richard/GCL]*/ 207 expect(NumberFormat.getScientificInstance(Locale.FRANCE), 208 new Double(12345.678901), 209 "1,2345678901E4"); 210 expect(new DecimalFormat("##0.####E0", US), 211 new Double(789.12345e-9), 212 "789.12E-9"); 213 expect(new DecimalFormat("##0.####E0", US), 214 new Double(780.e-9), 215 "780E-9"); 216 expect(new DecimalFormat(".###E0", US), 217 new Double(45678), 218 ".457E5"); 219 expect(new DecimalFormat(".###E0", US), 220 new Long(0), 221 ".0E0"); 222 expect(new DecimalFormat[] { new DecimalFormat("#E0", US), 223 new DecimalFormat("##E0", US), 224 new DecimalFormat("####E0", US), 225 new DecimalFormat("0E0", US), 226 new DecimalFormat("00E0", US), 227 new DecimalFormat("000E0", US), 228 }, 229 new Long(45678000), 230 new String[] { "4.5678E7", 231 "45.678E6", 232 "4567.8E4", 233 "5E7", 234 "46E6", 235 "457E5", 236 } 237 ); 238 expect(new DecimalFormat("###E0", US), 239 new Object[] { new Double(0.0000123), "12.3E-6", 240 new Double(0.000123), "123E-6", 241 new java.math.BigDecimal("0.00123"), "1.23E-3", // Cafe VM messes up Double(0.00123) 242 new Double(0.0123), "12.3E-3", 243 new Double(0.123), "123E-3", 244 new Double(1.23), "1.23E0", 245 new Double(12.3), "12.3E0", 246 new Double(123), "123E0", 247 new Double(1230), "1.23E3", 248 }); 249 expect(new DecimalFormat("0.#E+00", US), 250 new Object[] { new Double(0.00012), "1.2E-04", 251 new Long(12000), "1.2E+04", 252 }); 253 } 254 255 /** 256 */ TestPad()257 public void TestPad() { 258 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US); 259 expect(new DecimalFormat("*^##.##", US), 260 new Object[] { new Long(0), "^^^^0", 261 new Double(-1.3), "^-1.3", 262 } 263 ); 264 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US), 265 new Object[] { new Long(0), "0.0E0______ g-m/s^2", 266 new Double(1.0/3), "333.333E-3_ g-m/s^2", 267 } 268 ); 269 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US), 270 new Object[] { new Long(0), "0.0______ g-m/s^2", 271 new Double(1.0/3), "0.33333__ g-m/s^2", 272 } 273 ); 274 expect(new DecimalFormat("*x#,###,###,##0.00;*x(#,###,###,##0.00)", US), 275 new Object[] { 276 new Long(-100), "xxxxxxxx(100.00)", 277 new Long(-1000), "xxxxxx(1,000.00)", 278 new Long(-1000000), "xx(1,000,000.00)", 279 new Long(-1000000000), "(1,000,000,000.00)", 280 }); 281 } 282 expect(NumberFormat fmt, Object[] data)283 private void expect(NumberFormat fmt, Object[] data) { 284 for (int i=0; i<data.length; i+=2) { 285 expect(fmt, (Number) data[i], (String) data[i+1]); 286 } 287 } 288 expect(Object fmto, Object numo, Object expo)289 private void expect(Object fmto, Object numo, Object expo) { 290 NumberFormat fmt = null, fmts[] = null; 291 Number num = null, nums[] = null; 292 String exp = null, exps[] = null; 293 if (fmto instanceof NumberFormat[]) { 294 fmts = (NumberFormat[]) fmto; 295 } else { 296 fmt = (NumberFormat) fmto; 297 } 298 if (numo instanceof Number[]) { 299 nums = (Number[]) numo; 300 } else { 301 num = (Number) numo; 302 } 303 if (expo instanceof String[]) { 304 exps = (String[]) expo; 305 } else { 306 exp = (String) expo; 307 } 308 int n = 1; 309 if (fmts != null) { 310 n = Math.max(n, fmts.length); 311 } 312 if (nums != null) { 313 n = Math.max(n, nums.length); 314 } 315 if (exps != null) { 316 n = Math.max(n, exps.length); 317 } 318 for (int i=0; i<n; ++i) { 319 expect(fmts == null ? fmt : fmts[i], 320 nums == null ? num : nums[i], 321 exps == null ? exp : exps[i]); 322 } 323 } 324 showNumber(Number n)325 private static String showNumber(Number n) { 326 String cls = n.getClass().getName(); 327 if (!(n instanceof com.ibm.icu.math.BigDecimal 328 || n instanceof java.math.BigDecimal)) { 329 int i = cls.lastIndexOf('.'); 330 cls = cls.substring(i+1); 331 } 332 return n.toString() + " (" + cls + ')'; 333 } 334 expect(NumberFormat fmt, Number n, String exp)335 private void expect(NumberFormat fmt, Number n, String exp) { 336 String saw = fmt.format(n); 337 String pat = ((DecimalFormat) fmt).toPattern(); 338 if (saw.equals(exp)) { 339 logln("Ok " + showNumber(n) + " x " + 340 pat + " = " + 341 Utility.escape(saw)); 342 } else { 343 errln("FAIL " + showNumber(n) + " x " + 344 pat + " = \"" + 345 Utility.escape(saw) + ", expected " + Utility.escape(exp)); 346 } 347 } 348 expect(NumberFormat fmt, String str, Number exp)349 private void expect(NumberFormat fmt, String str, Number exp) { 350 Number saw = null; 351 try { 352 saw = fmt.parse(str); 353 } catch (ParseException e) { 354 saw = null; 355 } 356 String pat = ((DecimalFormat) fmt).toPattern(); 357 if (saw.equals(exp)) { 358 logln("Ok \"" + str + "\" x " + 359 pat + " = " + 360 showNumber(saw)); 361 } else { 362 errln("FAIL \"" + str + "\" x " + 363 pat + " = " + 364 showNumber(saw) + ", expected " + showNumber(exp)); 365 } 366 } 367 368 /** 369 * Given a string composed of [0-9] and other chars, convert the 370 * [0-9] chars to be offsets 0..9 from 'zero'. 371 */ transmute(String str, char zero)372 private static String transmute(String str, char zero) { 373 StringBuffer buf = new StringBuffer(); 374 for (int i=0; i<str.length(); ++i) { 375 char c = str.charAt(i); 376 if (c >= '0' && c <= '9') { 377 c = (char) (c - '0' + zero); 378 } 379 buf.append(c); 380 } 381 return buf.toString(); 382 } 383 Test4161100()384 public void Test4161100() { 385 NumberFormat f = NumberFormat.getInstance(); 386 f.setMinimumFractionDigits(1); 387 f.setMaximumFractionDigits(1); 388 double a = -0.09; 389 String s = f.format(a); 390 logln(a + " x " + 391 ((DecimalFormat) f).toPattern() + " = " + 392 s); 393 if (!s.equals("-0.1")) { 394 errln("FAIL"); 395 } 396 } 397 TestBigDecimalJ28()398 public void TestBigDecimalJ28() { 399 String[] DATA = { 400 "1", "1E0", 401 "-1", "-1E0", 402 "0", "0E0", 403 "12e34", "1.2E35", 404 "-12.3e-45", "-1.23E-44", 405 "0.73e-7", "7.3E-8", 406 }; 407 NumberFormat fmt = NumberFormat.getScientificInstance(Locale.US); 408 logln("Pattern: " + ((DecimalFormat)fmt).toPattern()); 409 for (int i=0; i<DATA.length; i+=2) { 410 String input = DATA[i]; 411 String exp = DATA[i+1]; 412 com.ibm.icu.math.BigDecimal bd = new com.ibm.icu.math.BigDecimal(input); 413 String output = fmt.format(bd); 414 if (output.equals(exp)) { 415 logln("input=" + input + " num=" + bd + " output=" + output); 416 } else { 417 errln("FAIL: input=" + input + " num=" + bd + " output=" + output + 418 " expected=" + exp); 419 } 420 } 421 } TestBigDecimalRounding()422 public void TestBigDecimalRounding() { 423 // jb 3657 424 java.text.DecimalFormat jdkFormat=new java.text.DecimalFormat("###,###,###,##0"); 425 com.ibm.icu.text.DecimalFormat icuFormat=new com.ibm.icu.text.DecimalFormat("###,###,###,##0"); 426 String[] values = { 427 "-1.74", "-1.24", "-0.74", "-0.24", "0.24", "0.74", "1.24", "1.74" 428 }; 429 for (int i = 0; i < values.length; ++i) { 430 String val = values[i]; 431 java.math.BigDecimal bd = new java.math.BigDecimal(val); 432 String jdk = jdkFormat.format(bd); 433 String icu = icuFormat.format(bd); 434 logln("Format of BigDecimal " + val + " by JDK is " + jdk); 435 logln("Format of BigDecimal " + val + " by ICU is " + icu); 436 if (!jdk.equals(icu)) { 437 errln("BigDecimal jdk: " + jdk + " != icu: " + icu); 438 } 439 440 double d = bd.doubleValue(); 441 jdk = jdkFormat.format(d); 442 icu = icuFormat.format(d); 443 logln("Format of double " + val + " by JDK is " + jdk); 444 logln("Format of double " + val + " by ICU is " + icu); 445 if (!jdk.equals(icu)) { 446 errln("double jdk: " + jdk + " != icu: " + icu); 447 } 448 } 449 } 450 } 451