1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /***************************************************************************************** 5 * 6 * Copyright (C) 1996-2016, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 **/ 9 10 /** 11 * Port From: JDK 1.4b1 : java.text.Format.NumberRegression 12 * Source File: java/text/format/NumberRegression.java 13 **/ 14 15 /** 16 * @test 1.49 01/05/21 17 * @bug 4052223 4059870 4061302 4062486 4066646 4068693 4070798 4071005 4071014 18 * 4071492 4071859 4074454 4074620 4075713 4083018 4086575 4087244 4087245 19 * 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713 20 * 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840 21 * 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198 22 * 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742 23 * 4217661 4243011 4243108 4330377 4233840 24 * @summary Regression tests for NumberFormat and associated classes 25 */ 26 27 package android.icu.dev.test.format; 28 29 import java.io.ByteArrayInputStream; 30 import java.io.ByteArrayOutputStream; 31 import java.io.IOException; 32 import java.io.InvalidObjectException; 33 import java.io.ObjectInputStream; 34 import java.io.ObjectOutputStream; 35 import java.io.Serializable; 36 import java.math.BigInteger; 37 import java.text.FieldPosition; 38 import java.text.ParseException; 39 import java.text.ParsePosition; 40 import java.util.Date; 41 import java.util.Locale; 42 43 import org.junit.Ignore; 44 import org.junit.Test; 45 46 import android.icu.dev.test.TestFmwk; 47 import android.icu.impl.ICUData; 48 import android.icu.impl.ICUResourceBundle; 49 import android.icu.text.DateFormat; 50 import android.icu.text.DecimalFormat; 51 import android.icu.text.DecimalFormatSymbols; 52 import android.icu.text.NumberFormat; 53 import android.icu.util.GregorianCalendar; 54 import android.icu.util.ULocale; 55 import android.icu.util.VersionInfo; 56 57 public class NumberRegressionTests extends TestFmwk { 58 private static final char EURO = '\u20ac'; 59 60 /** 61 * NumberFormat.equals comparing with null should always return false. 62 */ 63 @Test 64 public void Test4075713(){ 65 66 try { 67 MyNumberFormat tmp = new MyNumberFormat(); 68 if (!tmp.equals(null)) 69 logln("NumberFormat.equals passed"); 70 } catch (NullPointerException e) { 71 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); 72 } 73 } 74 75 /** 76 * NumberFormat.equals comparing two obj equal even the setGroupingUsed 77 * flag is different. 78 */ 79 @Test 80 public void Test4074620() { 81 82 MyNumberFormat nf1 = new MyNumberFormat(); 83 MyNumberFormat nf2 = new MyNumberFormat(); 84 85 nf1.setGroupingUsed(false); 86 nf2.setGroupingUsed(true); 87 88 if (nf1.equals(nf2)) errln("Test for bug 4074620 failed"); 89 else logln("Test for bug 4074620 passed."); 90 return; 91 } 92 93 94 /** 95 * DecimalFormat.format() incorrectly uses maxFractionDigits setting. 96 */ 97 @Test 98 public void Test4088161 (){ 99 DecimalFormat df = new DecimalFormat(); 100 double d = 100; 101 df.setMinimumFractionDigits(0); 102 df.setMaximumFractionDigits(16); 103 StringBuffer sBuf1 = new StringBuffer(""); 104 FieldPosition fp1 = new FieldPosition(0); 105 logln("d = " + d); 106 logln("maxFractionDigits = " + df.getMaximumFractionDigits()); 107 logln(" format(d) = '" + df.format(d, sBuf1, fp1) + "'"); 108 df.setMaximumFractionDigits(17); 109 StringBuffer sBuf2 = new StringBuffer(""); 110 FieldPosition fp2 = new FieldPosition(0); 111 logln("maxFractionDigits = " + df.getMaximumFractionDigits()); 112 df.format(d, sBuf2, fp2); 113 if (!sBuf2.toString().equals("100")) 114 errln(" format(d) = '" + sBuf2 + "'"); 115 } 116 /** 117 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat. 118 * DecimalFormat(String, DecimalFormatSymbols). 119 */ 120 @Test 121 public void Test4087245 (){ 122 DecimalFormatSymbols symbols = new DecimalFormatSymbols(); 123 DecimalFormat df = new DecimalFormat("#,##0.0", symbols); 124 long n = 123; 125 StringBuffer buf1 = new StringBuffer(); 126 StringBuffer buf2 = new StringBuffer(); 127 logln("format(" + n + ") = " + 128 df.format(n, buf1, new FieldPosition(0))); 129 symbols.setDecimalSeparator('p'); // change value of field 130 logln("format(" + n + ") = " + 131 df.format(n, buf2, new FieldPosition(0))); 132 if (!buf1.toString().equals(buf2.toString())) 133 errln("Test for bug 4087245 failed"); 134 } 135 /** 136 * DecimalFormat.format() incorrectly formats 0.0 137 */ 138 @Test 139 public void Test4087535 () 140 { 141 DecimalFormat df = new DecimalFormat(); 142 df.setMinimumIntegerDigits(0); 143 144 double n = 0; 145 String buffer = new String(); 146 buffer = df.format(n); 147 if (buffer.length() == 0) 148 errln(n + ": '" + buffer + "'"); 149 n = 0.1; 150 buffer = df.format(n); 151 if (buffer.length() == 0) 152 errln(n + ": '" + buffer + "'"); 153 } 154 155 /** 156 * DecimalFormat.format fails when groupingSize is set to 0. 157 */ 158 @Test 159 public void Test4088503 (){ 160 DecimalFormat df = new DecimalFormat(); 161 df.setGroupingSize(0); 162 StringBuffer sBuf = new StringBuffer(""); 163 FieldPosition fp = new FieldPosition(0); 164 try { 165 logln(df.format(123, sBuf, fp).toString()); 166 } catch (Exception foo) { 167 errln("Test for bug 4088503 failed."); 168 } 169 170 } 171 /** 172 * NumberFormat.getCurrencyInstance is wrong. 173 */ 174 @Test 175 public void Test4066646 () { 176 //float returnfloat = 0.0f; //The variable is never used 177 assignFloatValue(2.04f); 178 assignFloatValue(2.03f); 179 assignFloatValue(2.02f); 180 assignFloatValue(0.0f); 181 } 182 183 public float assignFloatValue(float returnfloat) 184 { 185 logln(" VALUE " + returnfloat); 186 NumberFormat nfcommon = NumberFormat.getCurrencyInstance(Locale.US); 187 nfcommon.setGroupingUsed(false); 188 189 String stringValue = nfcommon.format(returnfloat).substring(1); 190 if (Float.valueOf(stringValue).floatValue() != returnfloat) 191 errln(" DISPLAYVALUE " + stringValue); 192 return returnfloat; 193 } // End Of assignFloatValue() 194 195 /** 196 * DecimalFormat throws exception when parsing "0" 197 */ 198 @Test 199 public void Test4059870() { 200 DecimalFormat format = new DecimalFormat("00"); 201 try { 202 logln(format.parse("0").toString()); 203 } catch (Exception e) { errln("Test for bug 4059870 failed : " + e); } 204 } 205 /** 206 * DecimalFormatSymbol.equals should always return false when 207 * comparing with null. 208 */ 209 210 @Test 211 public void Test4083018 (){ 212 DecimalFormatSymbols dfs = new DecimalFormatSymbols(); 213 try { 214 if (!dfs.equals(null)) 215 logln("Test Passed!"); 216 } catch (Exception foo) { 217 errln("Test for bug 4083018 failed => Message : " + foo.getMessage()); 218 } 219 } 220 /** 221 * DecimalFormat does not round up correctly. 222 */ 223 @Test 224 public void Test4071492 (){ 225 double x = 0.00159999; 226 NumberFormat nf = NumberFormat.getInstance(); 227 nf.setMaximumFractionDigits(4); 228 String out = nf.format(x); 229 logln("0.00159999 formats with 4 fractional digits to " + out); 230 String expected = "0.0016"; 231 if (!out.equals(expected)) 232 errln("FAIL: Expected " + expected); 233 } 234 235 /** 236 * A space as a group separator for localized pattern causes 237 * wrong format. WorkAround : use non-breaking space. 238 */ 239 @Test 240 public void Test4086575() { 241 242 NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); 243 logln("nf toPattern1: " + ((DecimalFormat)nf).toPattern()); 244 logln("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern()); 245 246 // No group separator 247 logln("...applyLocalizedPattern ###,00;(###,00) "); 248 ((DecimalFormat)nf).applyLocalizedPattern("###,00;(###,00)"); 249 logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); 250 logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); 251 252 logln("nf: " + nf.format(1234)); // 1234,00 253 logln("nf: " + nf.format(-1234)); // (1234,00) 254 255 // Space as group separator 256 257 logln("...applyLocalizedPattern # ###,00;(# ###,00) "); 258 ((DecimalFormat)nf).applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)"); 259 logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); 260 logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); 261 String buffer = nf.format(1234); 262 if (!buffer.equals("1\u00a0234,00")) 263 errln("nf : " + buffer); // Expect 1 234,00 264 buffer = nf.format(-1234); 265 if (!buffer.equals("(1\u00a0234,00)")) 266 errln("nf : " + buffer); // Expect (1 234,00) 267 268 // Erroneously prints: 269 // 1234,00 , 270 // (1234,00 ,) 271 272 } 273 /** 274 * DecimalFormat.parse returns wrong value 275 */ 276 @Test 277 public void Test4068693() 278 { 279 logln("----- Test Application -----"); 280 //ParsePosition pos; 281 DecimalFormat df = new DecimalFormat(); 282 Number d = df.parse("123.55456", new ParsePosition(0)); 283 if (!d.toString().equals("123.55456")) { 284 errln("Result -> " + d.doubleValue()); 285 } 286 } 287 288 /* bugs 4069754, 4067878 289 * null pointer thrown when accessing a deserialized DecimalFormat 290 * object. 291 */ 292 @Test 293 public void Test4069754() throws Exception 294 { 295 //try { 296 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 297 ObjectOutputStream oos = new ObjectOutputStream(baos); 298 myformat it = new myformat(); 299 logln(it.Now()); 300 oos.writeObject(it); 301 oos.flush(); 302 baos.close(); 303 logln("Save OK!"); 304 byte [] bytes = baos.toByteArray(); 305 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); 306 myformat o = (myformat)ois.readObject(); 307 ois.close(); 308 it.Now(); 309 logln("Load OK!"); 310 if (!o._dateFormat.equals(it._dateFormat)) { 311 throw new Exception("The saved and loaded object are not equals!"); 312 } 313 logln("Compare OK!"); 314 //} catch (Exception foo) { 315 //errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); 316 //} 317 } 318 319 /** 320 * DecimalFormat.applyPattern(String) allows illegal patterns 321 */ 322 @Test 323 public void Test4087251 (){ 324 DecimalFormat df = new DecimalFormat(); 325 try { 326 df.applyPattern("#.#.#"); 327 logln("toPattern() returns \"" + df.toPattern() + "\""); 328 errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); 329 } catch (IllegalArgumentException e) { 330 logln("Caught Illegal Argument Error !"); 331 } 332 // Second test; added 5/11/98 when reported to fail on 1.2b3 333 try { 334 df.applyPattern("#0.0#0#0"); 335 logln("toPattern() returns \"" + df.toPattern() + "\""); 336 errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); 337 } catch (IllegalArgumentException e) { 338 logln("Ok - IllegalArgumentException for #0.0#0#0"); 339 } 340 } 341 342 /** 343 * DecimalFormat.format() loses precision 344 */ 345 @Test 346 public void Test4090489 (){ 347 DecimalFormat df = new DecimalFormat(); 348 df.setMinimumFractionDigits(10); 349 df.setGroupingUsed(false); 350 double d = 1.000000000000001E7; 351 java.math.BigDecimal bd = new java.math.BigDecimal(d); 352 StringBuffer sb = new StringBuffer(""); 353 FieldPosition fp = new FieldPosition(0); 354 logln("d = " + d); 355 logln("BigDecimal.toString(): " + bd.toString()); 356 df.format(d, sb, fp); 357 if (!sb.toString().equals("10000000.0000000100")) { 358 errln("DecimalFormat.format(): " + sb.toString()); 359 } 360 } 361 362 /** 363 * DecimalFormat.format() loses precision 364 */ 365 @Test 366 public void Test4090504 () 367 { 368 double d = 1; 369 logln("d = " + d); 370 DecimalFormat df = new DecimalFormat(); 371 StringBuffer sb; 372 FieldPosition fp; 373 try { 374 for (int i = 17; i <= 20; i++) { 375 df.setMaximumFractionDigits(i); 376 sb = new StringBuffer(""); 377 fp = new FieldPosition(0); 378 logln(" getMaximumFractionDigits() = " + i); 379 logln(" formated: " + df.format(d, sb, fp)); 380 } 381 } catch (Exception foo) { 382 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage()); 383 } 384 } 385 /** 386 * DecimalFormat.parse(String str, ParsePosition pp) loses precision 387 */ 388 @Test 389 public void Test4095713 () 390 { 391 DecimalFormat df = new DecimalFormat(); 392 String str = "0.1234"; 393 Double d1 = new Double(str); 394 Number d2 = df.parse(str, new ParsePosition(0)); 395 logln(d1.toString()); 396 if (d2.doubleValue() != d1.doubleValue()) 397 errln("Bug 4095713 test failed, new double value : " + d2.doubleValue()); 398 } 399 400 /** 401 * DecimalFormat.parse() fails when multiplier is not set to 1 402 */ 403 @Test 404 public void Test4092561 () 405 { 406 Locale savedLocale = Locale.getDefault(); 407 Locale.setDefault(Locale.US); 408 DecimalFormat df = new DecimalFormat(); 409 String str = Long.toString(Long.MIN_VALUE); 410 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); 411 df.setMultiplier(100); 412 Number num = df.parse(str, new ParsePosition(0)); 413 if (num.doubleValue() != -9.223372036854776E16) { 414 errln("Bug 4092561 test failed when multiplier is set to not 1."); 415 } 416 Locale.setDefault(savedLocale); 417 } 418 419 /** 420 * DecimalFormat: Negative format ignored. 421 */ 422 @Test 423 public void Test4092480 () 424 { 425 DecimalFormat dfFoo = new DecimalFormat("000"); 426 427 try { 428 dfFoo.applyPattern("0000;-000"); 429 if (!dfFoo.toPattern().equals("#0000")) 430 errln("dfFoo.toPattern : " + dfFoo.toPattern()); 431 logln(dfFoo.format(42)); 432 logln(dfFoo.format(-42)); 433 dfFoo.applyPattern("000;-000"); 434 if (!dfFoo.toPattern().equals("#000")) 435 errln("dfFoo.toPattern : " + dfFoo.toPattern()); 436 logln(dfFoo.format(42)); 437 logln(dfFoo.format(-42)); 438 439 dfFoo.applyPattern("000;-0000"); 440 if (!dfFoo.toPattern().equals("#000")) 441 errln("dfFoo.toPattern : " + dfFoo.toPattern()); 442 logln(dfFoo.format(42)); 443 logln(dfFoo.format(-42)); 444 445 dfFoo.applyPattern("0000;-000"); 446 if (!dfFoo.toPattern().equals("#0000")) 447 errln("dfFoo.toPattern : " + dfFoo.toPattern()); 448 logln(dfFoo.format(42)); 449 logln(dfFoo.format(-42)); 450 } catch (Exception foo) { 451 errln("Message " + foo.getMessage()); 452 } 453 } 454 /** 455 * NumberFormat.getCurrencyInstance() produces format that uses 456 * decimal separator instead of monetary decimal separator. 457 * 458 * Rewrote this test not to depend on the actual pattern. Pattern should 459 * never contain the monetary separator! Decimal separator in pattern is 460 * interpreted as monetary separator if currency symbol is seen! 461 */ 462 @Test 463 public void Test4087244 () { 464 Locale de = new Locale("pt", "PT"); 465 DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(de); 466 DecimalFormatSymbols sym = df.getDecimalFormatSymbols(); 467 sym.setMonetaryDecimalSeparator('$'); 468 df.setDecimalFormatSymbols(sym); 469 char decSep = sym.getDecimalSeparator(); 470 char monSep = sym.getMonetaryDecimalSeparator(); 471 //char zero = sym.getZeroDigit(); //The variable is never used 472 if (decSep == monSep) { 473 errln("ERROR in test: want decimal sep != monetary sep"); 474 } else { 475 df.setMinimumIntegerDigits(1); 476 df.setMinimumFractionDigits(2); 477 String str = df.format(1.23); 478 String monStr = "1" + monSep + "23"; 479 String decStr = "1" + decSep + "23"; 480 if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) { 481 logln("OK: 1.23 -> \"" + str + "\" contains \"" + 482 monStr + "\" and not \"" + decStr + '"'); 483 } else { 484 errln("FAIL: 1.23 -> \"" + str + "\", should contain \"" + 485 monStr + 486 "\" and not \"" + decStr + '"'); 487 } 488 } 489 } 490 /** 491 * Number format data rounding errors for locale FR 492 */ 493 @Test 494 public void Test4070798 () { 495 NumberFormat formatter; 496 String tempString; 497 /* User error : 498 String expectedDefault = "-5\u00a0789,987"; 499 String expectedCurrency = "5\u00a0789,98\u00a0F"; 500 String expectedPercent = "-578\u00a0998%"; 501 */ 502 String expectedDefault = "-5\u00a0789,988"; 503 String expectedCurrency = "5\u00a0789,99\u00a0" + EURO; // euro 504 String expectedPercent = "-578\u00a0999\u00a0%"; 505 506 formatter = NumberFormat.getNumberInstance(Locale.FRANCE); 507 tempString = formatter.format (-5789.9876); 508 509 if (tempString.equals(expectedDefault)) { 510 logln ("Bug 4070798 default test passed."); 511 } else { 512 errln("Failed:" + 513 " Expected " + expectedDefault + 514 " Received " + tempString ); 515 } 516 517 518 formatter = NumberFormat.getCurrencyInstance(Locale.FRANCE); 519 tempString = formatter.format( 5789.9876 ); 520 521 if (tempString.equals(expectedCurrency) ) { 522 logln ("Bug 4070798 currency test assed."); 523 } else { 524 errln("Failed:" + 525 " Expected " + expectedCurrency + 526 " Received " + tempString ); 527 } 528 529 530 formatter = NumberFormat.getPercentInstance(Locale.FRANCE); 531 tempString = formatter.format (-5789.9876); 532 533 if (tempString.equals(expectedPercent) ) { 534 logln ("Bug 4070798 percentage test passed."); 535 } else { 536 errln("Failed:" + 537 " Expected " + expectedPercent + 538 " Received " + tempString ); 539 } 540 } 541 /** 542 * Data rounding errors for French (Canada) locale 543 */ 544 @Test 545 public void Test4071005 () { 546 547 NumberFormat formatter; 548 String tempString; 549 /* user error : 550 String expectedDefault = "-5 789,987"; 551 String expectedCurrency = "5 789,98\u00a0$"; 552 String expectedPercent = "-578 998%"; 553 */ 554 String expectedDefault = "-5\u00a0789,988"; 555 String expectedCurrency = "5\u00a0789,99\u00a0$"; 556 String expectedPercent = "-578\u00a0999\u00A0%"; 557 558 formatter = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH); 559 tempString = formatter.format (-5789.9876); 560 if (tempString.equals(expectedDefault)) { 561 logln ("Bug 4071005 default test passed."); 562 } else { 563 errln("Failed:" + 564 " Expected " + expectedDefault + 565 " Received " + tempString ); 566 } 567 568 formatter = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH); 569 tempString = formatter.format( 5789.9876 ) ; 570 571 if (tempString.equals(expectedCurrency) ) { 572 logln ("Bug 4071005 currency test passed."); 573 } else { 574 errln("Failed:" + 575 " Expected " + expectedCurrency + 576 " Received " + tempString ); 577 } 578 formatter = NumberFormat.getPercentInstance(Locale.CANADA_FRENCH); 579 tempString = formatter.format (-5789.9876); 580 581 if (tempString.equals(expectedPercent) ) { 582 logln ("Bug 4071005 percentage test passed."); 583 } else { 584 errln("Failed:" + 585 " Expected " + expectedPercent + 586 " Received " + tempString ); 587 } 588 } 589 590 /** 591 * Data rounding errors for German (Germany) locale 592 */ 593 @Test 594 public void Test4071014 () { 595 NumberFormat formatter; 596 String tempString; 597 /* user error : 598 String expectedDefault = "-5.789,987"; 599 String expectedCurrency = "5.789,98\u00a0DM"; 600 String expectedPercent = "-578.998%"; 601 */ 602 String expectedDefault = "-5.789,988"; 603 String expectedCurrency = "5.789,99\u00a0" + EURO; 604 String expectedPercent = "-578.999\u00a0%"; 605 606 formatter = NumberFormat.getNumberInstance(Locale.GERMANY); 607 tempString = formatter.format (-5789.9876); 608 609 if (tempString.equals(expectedDefault)) { 610 logln ("Bug 4071014 default test passed."); 611 } else { 612 errln("Failed:" + 613 " Expected " + expectedDefault + 614 " Received " + tempString ); 615 } 616 617 formatter = NumberFormat.getCurrencyInstance(Locale.GERMANY); 618 tempString = formatter.format( 5789.9876 ) ; 619 620 if (tempString.equals(expectedCurrency) ) { 621 logln ("Bug 4071014 currency test passed."); 622 } else { 623 errln("Failed:" + 624 " Expected " + expectedCurrency + 625 " Received " + tempString ); 626 } 627 628 formatter = NumberFormat.getPercentInstance(Locale.GERMANY); 629 tempString = formatter.format (-5789.9876); 630 631 if (tempString.equals(expectedPercent) ) { 632 logln ("Bug 4071014 percentage test passed."); 633 } else { 634 errln("Failed:" + 635 " Expected " + expectedPercent + 636 " Received " + tempString ); 637 } 638 639 } 640 /** 641 * Data rounding errors for Italian locale number formats 642 * Note- with the Euro, there is no need for currency rounding anymore 643 */ 644 @Test 645 public void Test4071859 () { 646 NumberFormat formatter; 647 String tempString; 648 /* user error : 649 String expectedDefault = "-5.789,987"; 650 String expectedCurrency = "-L.\u00a05.789,98"; 651 String expectedPercent = "-578.998%"; 652 */ 653 String expectedDefault = "-5.789,988"; 654 String expectedCurrency = "-5.789,99\u00A0" + EURO; 655 String expectedPercent = "-578.999%"; 656 657 formatter = NumberFormat.getNumberInstance(Locale.ITALY); 658 tempString = formatter.format (-5789.9876); 659 660 if (tempString.equals(expectedDefault)) { 661 logln ("Bug 4071859 default test passed."); 662 } else { 663 errln("a) Failed:" + 664 " Expected " + expectedDefault + 665 " Received " + tempString ); 666 } 667 668 formatter = NumberFormat.getCurrencyInstance(Locale.ITALY); 669 tempString = formatter.format( -5789.9876 ) ; 670 671 if (tempString.equals(expectedCurrency) ) { 672 logln ("Bug 4071859 currency test passed."); 673 } else { 674 errln("b) Failed:" + 675 " Expected " + expectedCurrency + 676 " Received " + tempString ); 677 } 678 679 formatter = NumberFormat.getPercentInstance(Locale.ITALY); 680 tempString = formatter.format (-5789.9876); 681 682 if (tempString.equals(expectedPercent) ) { 683 logln ("Bug 4071859 percentage test passed."); 684 } else { 685 errln("c) Failed:" + 686 " Expected " + expectedPercent + 687 " Received " + tempString ); 688 } 689 690 } 691 /* bug 4071859 692 * Test rounding for nearest even. 693 */ 694 @Test 695 public void Test4093610() 696 { 697 DecimalFormat df = new DecimalFormat("#0.#"); 698 roundingTest(df, 12.35, "12.4"); 699 roundingTest(df, 12.45, "12.4"); 700 roundingTest(df, 12.452,"12.5"); 701 roundingTest(df, 12.55, "12.6"); 702 roundingTest(df, 12.65, "12.6"); 703 roundingTest(df, 12.652,"12.7"); 704 roundingTest(df, 12.75, "12.8"); 705 roundingTest(df, 12.752,"12.8"); 706 roundingTest(df, 12.85, "12.8"); 707 roundingTest(df, 12.852,"12.9"); 708 roundingTest(df, 12.95, "13"); 709 roundingTest(df, 12.952,"13"); 710 711 } 712 void roundingTest(DecimalFormat df, double x, String expected) 713 { 714 String out = df.format(x); 715 logln("" + x + " formats with 1 fractional digits to " + out); 716 if (!out.equals(expected)) errln("FAIL: Expected " + expected); 717 } 718 /** 719 * Tests the setMaximumFractionDigits limit. 720 */ 721 @Test 722 public void Test4098741() 723 { 724 try { 725 NumberFormat fmt = NumberFormat.getPercentInstance(); 726 fmt.setMaximumFractionDigits(20); 727 logln(fmt.format(.001)); 728 } catch (Exception foo) { 729 warnln("Bug 4098471 failed with exception thrown : " + foo.getMessage()); 730 } 731 } 732 /** 733 * Tests illegal pattern exception. 734 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated. 735 * Part2 has been fixed. 736 */ 737 @Test 738 public void Test4074454() 739 { 740 try { 741 DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#"); 742 logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used" 743 logln("Inconsistent negative pattern is fine."); 744 DecimalFormat newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces"); 745 String tempString = newFmt.format(3456.78); 746 if (!tempString.equals("3,456.78 p'ieces")) 747 errln("Failed! 3456.78 p'ieces expected, but got : " + tempString); 748 } catch (Exception foo) { 749 warnln("An exception was thrown for any inconsistent negative pattern."); 750 } 751 } 752 /** 753 * Tests all different comments. 754 * Response to some comments : 755 * [1] DecimalFormat.parse API documentation is more than just one line. 756 * This is not a reproducable doc error in 116 source code. 757 * [2] See updated javadoc. 758 * [3] Fixed. 759 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails, 760 * a null object will be returned. The unchanged parse position also 761 * reflects an error. 762 * NumberFormat.parse(String) : If parsing fails, an ParseException 763 * will be thrown. 764 * See updated javadoc for more details. 765 * [5] See updated javadoc. 766 * [6] See updated javadoc. 767 * [7] This is a correct behavior if the DateFormat object is linient. 768 * Otherwise, an IllegalArgumentException will be thrown when formatting 769 * "January 35". See GregorianCalendar class javadoc for more details. 770 */ 771 @Test 772 public void Test4099404() 773 { 774 try { 775 DecimalFormat fmt = new DecimalFormat("000.0#0"); 776 logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used" 777 errln("Bug 4099404 failed applying illegal pattern \"000.0#0\""); 778 } catch (Exception foo) { 779 logln("Bug 4099404 pattern \"000.0#0\" passed"); 780 } 781 try { 782 DecimalFormat fmt = new DecimalFormat("0#0.000"); 783 logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used" 784 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\""); 785 } catch (Exception foo) { 786 logln("Bug 4099404 pattern \"0#0.000\" passed"); 787 } 788 } 789 /** 790 * DecimalFormat.applyPattern doesn't set minimum integer digits 791 */ 792 @Test 793 public void Test4101481() 794 { 795 DecimalFormat sdf = new DecimalFormat("#,##0"); 796 if (sdf.getMinimumIntegerDigits() != 1) 797 errln("Minimum integer digits : " + sdf.getMinimumIntegerDigits()); 798 } 799 /** 800 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition(). 801 */ 802 @Test 803 public void Test4052223() 804 { 805 try { 806 DecimalFormat fmt = new DecimalFormat("#,#00.00"); 807 Number num = fmt.parse("abc3"); 808 errln("Bug 4052223 failed : can't parse string \"a\". Got " + num); 809 } catch (ParseException foo) { 810 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); 811 } 812 } 813 /** 814 * API tests for API addition request A9. 815 */ 816 @Test 817 public void Test4061302() 818 { 819 DecimalFormatSymbols fmt = new DecimalFormatSymbols(); 820 String currency = fmt.getCurrencySymbol(); 821 String intlCurrency = fmt.getInternationalCurrencySymbol(); 822 char monDecSeparator = fmt.getMonetaryDecimalSeparator(); 823 if (currency.equals("") || 824 intlCurrency.equals("") || 825 monDecSeparator == 0) { 826 errln("getCurrencySymbols failed, got empty string."); 827 } 828 logln("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); 829 fmt.setCurrencySymbol("XYZ"); 830 fmt.setInternationalCurrencySymbol("ABC"); 831 fmt.setMonetaryDecimalSeparator('*'); 832 currency = fmt.getCurrencySymbol(); 833 intlCurrency = fmt.getInternationalCurrencySymbol(); 834 monDecSeparator = fmt.getMonetaryDecimalSeparator(); 835 if (!currency.equals("XYZ") || 836 !intlCurrency.equals("ABC") || 837 monDecSeparator != '*') { 838 errln("setCurrencySymbols failed."); 839 } 840 logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); 841 } 842 /** 843 * API tests for API addition request A23. FieldPosition.getBeginIndex and 844 * FieldPosition.getEndIndex. 845 */ 846 @Test 847 public void Test4062486() 848 { 849 DecimalFormat fmt = new DecimalFormat("#,##0.00"); 850 StringBuffer formatted = new StringBuffer(); 851 FieldPosition field = new FieldPosition(0); 852 Double num = new Double(1234.5); 853 fmt.format(num, formatted, field); 854 if (field.getBeginIndex() != 0 && field.getEndIndex() != 5) 855 errln("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); 856 field.setBeginIndex(7); 857 field.setEndIndex(4); 858 if (field.getBeginIndex() != 7 && field.getEndIndex() != 4) 859 errln("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); 860 } 861 862 /** 863 * DecimalFormat.parse incorrectly works with a group separator. 864 */ 865 @Test 866 public void Test4108738() 867 { 868 869 DecimalFormat df = new DecimalFormat("#,##0.###", new 870 DecimalFormatSymbols(java.util.Locale.US)); 871 String text = "1.222,111"; 872 Number num = df.parse(text,new ParsePosition(0)); 873 if (!num.toString().equals("1.222")) 874 errln("\"" + text + "\" is parsed as " + num); 875 text = "1.222x111"; 876 num = df.parse(text,new ParsePosition(0)); 877 if (!num.toString().equals("1.222")) 878 errln("\"" + text + "\" is parsed as " + num); 879 } 880 881 /** 882 * DecimalFormat.format() incorrectly formats negative doubles. 883 */ 884 @Test 885 public void Test4106658() 886 { 887 Locale savedLocale = Locale.getDefault(); 888 Locale.setDefault(Locale.US); 889 DecimalFormat df = new DecimalFormat(); // Corrected; see 4147706 890 double d1 = -0.0; 891 double d2 = -0.0001; 892 StringBuffer buffer = new StringBuffer(); 893 logln("pattern: \"" + df.toPattern() + "\""); 894 df.format(d1, buffer, new FieldPosition(0)); 895 if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 896 errln(d1 + " is formatted as " + buffer); 897 } 898 buffer.setLength(0); 899 df.format(d2, buffer, new FieldPosition(0)); 900 if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 901 errln(d2 + " is formatted as " + buffer); 902 } 903 Locale.setDefault(savedLocale); 904 } 905 906 /** 907 * DecimalFormat.parse returns 0 if string parameter is incorrect. 908 */ 909 @Test 910 public void Test4106662() 911 { 912 DecimalFormat df = new DecimalFormat(); 913 String text = "x"; 914 ParsePosition pos1 = new ParsePosition(0), pos2 = new ParsePosition(0); 915 916 logln("pattern: \"" + df.toPattern() + "\""); 917 Number num = df.parse(text, pos1); 918 if (num != null) { 919 errln("Test Failed: \"" + text + "\" is parsed as " + num); 920 } 921 df = null; 922 df = new DecimalFormat("$###.00"); 923 num = df.parse("$", pos2); 924 if (num != null){ 925 errln("Test Failed: \"$\" is parsed as " + num); 926 } 927 } 928 929 /** 930 * NumberFormat.parse doesn't return null 931 */ 932 @Test 933 public void Test4114639() 934 { 935 NumberFormat format = NumberFormat.getInstance(); 936 String text = "time 10:x"; 937 ParsePosition pos = new ParsePosition(8); 938 Number result = format.parse(text, pos); 939 if (result != null) errln("Should return null but got : " + result); // Should be null; it isn't 940 } 941 942 /** 943 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG. 944 */ 945 @Test 946 public void Test4106664() 947 { 948 DecimalFormat df = new DecimalFormat(); 949 long n = 1234567890123456L; 950 int m = 12345678; 951 BigInteger bigN = BigInteger.valueOf(n); 952 bigN = bigN.multiply(BigInteger.valueOf(m)); 953 df.setMultiplier(m); 954 df.setGroupingUsed(false); 955 logln("formated: " + 956 df.format(n, new StringBuffer(), new FieldPosition(0))); 957 logln("expected: " + bigN.toString()); 958 } 959 /** 960 * DecimalFormat.format incorrectly formats -0.0. 961 */ 962 @Test 963 public void Test4106667() 964 { 965 Locale savedLocale = Locale.getDefault(); 966 Locale.setDefault(Locale.US); 967 DecimalFormat df = new DecimalFormat(); 968 df.setPositivePrefix("+"); 969 double d = -0.0; 970 logln("pattern: \"" + df.toPattern() + "\""); 971 StringBuffer buffer = new StringBuffer(); 972 df.format(d, buffer, new FieldPosition(0)); 973 if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 974 errln(d + " is formatted as " + buffer); 975 } 976 Locale.setDefault(savedLocale); 977 } 978 979 /** 980 * DecimalFormat.setMaximumIntegerDigits() works incorrectly. 981 */ 982 @Test 983 public void Test4110936() 984 { 985 NumberFormat nf = NumberFormat.getInstance(); 986 nf.setMaximumIntegerDigits(128); 987 logln("setMaximumIntegerDigits(128)"); 988 if (nf.getMaximumIntegerDigits() != 128) 989 errln("getMaximumIntegerDigits() returns " + 990 nf.getMaximumIntegerDigits()); 991 } 992 993 /** 994 * Locale data should use generic currency symbol 995 * 996 * 1) Make sure that all currency formats use the generic currency symbol. 997 * 2) Make sure we get the same results using the generic symbol or a 998 * hard-coded one. 999 */ 1000 @Test 1001 public void Test4122840() 1002 { 1003 Locale[] locales = NumberFormat.getAvailableLocales(); 1004 1005 for (int i = 0; i < locales.length; i++) { 1006 ICUResourceBundle rb = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,locales[i]); 1007 1008 // 1009 // Get the currency pattern for this locale. We have to fish it 1010 // out of the ResourceBundle directly, since DecimalFormat.toPattern 1011 // will return the localized symbol, not \00a4 1012 // 1013 String pattern = rb.getStringWithFallback("NumberElements/latn/patterns/currencyFormat"); 1014 if (pattern.indexOf('\u00A4') == -1 ) { // 'x' not "x" -- workaround bug in IBM JDK 1.4.1 1015 errln("Currency format for " + locales[i] + 1016 " does not contain generic currency symbol:" + 1017 pattern ); 1018 } 1019 1020 // Create a DecimalFormat using the pattern we got and format a number 1021 DecimalFormatSymbols symbols = new DecimalFormatSymbols(locales[i]); 1022 DecimalFormat fmt1 = new DecimalFormat(pattern, symbols); 1023 1024 String result1 = fmt1.format(1.111); 1025 1026 // 1027 // Now substitute in the locale's currency symbol and create another 1028 // pattern. Replace the decimal separator with the monetary separator. 1029 // 1030 //char decSep = symbols.getDecimalSeparator(); //The variable is never used 1031 char monSep = symbols.getMonetaryDecimalSeparator(); 1032 StringBuffer buf = new StringBuffer(pattern); 1033 for (int j = 0; j < buf.length(); j++) { 1034 if (buf.charAt(j) == '\u00a4') { 1035 String cur = "'" + symbols.getCurrencySymbol() + "'"; 1036 buf.replace(j, j+1, cur); 1037 j += cur.length() - 1; 1038 } 1039 } 1040 symbols.setDecimalSeparator(monSep); 1041 DecimalFormat fmt2 = new DecimalFormat(buf.toString(), symbols); 1042 1043 // Actual width of decimal fractions and rounding option are inherited 1044 // from the currency, not the pattern itself. So we need to force 1045 // maximum/minimumFractionDigits and rounding option for the second 1046 // DecimalForamt instance. The fix for ticket#7282 requires this test 1047 // code change to make it work properly. 1048 fmt2.setMaximumFractionDigits(fmt1.getMaximumFractionDigits()); 1049 fmt2.setMinimumFractionDigits(fmt1.getMinimumFractionDigits()); 1050 fmt2.setRoundingIncrement(fmt1.getRoundingIncrement()); 1051 1052 String result2 = fmt2.format(1.111); 1053 1054 // NOTE: en_IN is a special case (ChoiceFormat currency display name) 1055 if (!result1.equals(result2) && 1056 !locales[i].toString().equals("en_IN")) { 1057 errln("Results for " + locales[i] + " differ: " + 1058 result1 + " vs " + result2); 1059 } 1060 } 1061 } 1062 1063 /** 1064 * DecimalFormat.format() delivers wrong string. 1065 */ 1066 @Test 1067 public void Test4125885() 1068 { 1069 double rate = 12.34; 1070 DecimalFormat formatDec = new DecimalFormat ("000.00"); 1071 logln("toPattern: " + formatDec.toPattern()); 1072 String rateString= formatDec.format(rate); 1073 if (!rateString.equals("012.34")) 1074 errln("result : " + rateString + " expected : 012.34"); 1075 rate = 0.1234; 1076 formatDec = null; 1077 formatDec = new DecimalFormat ("+000.00%;-000.00%"); 1078 logln("toPattern: " + formatDec.toPattern()); 1079 rateString= formatDec.format(rate); 1080 if (!rateString.equals("+012.34%")) 1081 errln("result : " + rateString + " expected : +012.34%"); 1082 } 1083 1084 /** 1085 ** 1086 * DecimalFormat produces extra zeros when formatting numbers. 1087 */ 1088 @Test 1089 public void Test4134034() { 1090 DecimalFormat nf = new DecimalFormat("##,###,###.00"); 1091 1092 String f = nf.format(9.02); 1093 if (f.equals("9.02")) logln(f + " ok"); else errln("9.02 -> " + f + "; want 9.02"); 1094 1095 f = nf.format(0); 1096 if (f.equals(".00")) logln(f + " ok"); else errln("0 -> " + f + "; want .00"); 1097 } 1098 1099 /** 1100 * CANNOT REPRODUCE - This bug could not be reproduced. It may be 1101 * a duplicate of 4134034. 1102 * 1103 * JDK 1.1.6 Bug, did NOT occur in 1.1.5 1104 * Possibly related to bug 4125885. 1105 * 1106 * This class demonstrates a regression in version 1.1.6 1107 * of DecimalFormat class. 1108 * 1109 * 1.1.6 Results 1110 * Value 1.2 Format #.00 Result '01.20' !!!wrong 1111 * Value 1.2 Format 0.00 Result '001.20' !!!wrong 1112 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong 1113 * Value 1.2 Format #0.0# Result '1.2' 1114 * Value 1.2 Format #0.00 Result '001.20' !!!wrong 1115 * 1116 * 1.1.5 Results 1117 * Value 1.2 Format #.00 Result '1.20' 1118 * Value 1.2 Format 0.00 Result '1.20' 1119 * Value 1.2 Format 00.00 Result '01.20' 1120 * Value 1.2 Format #0.0# Result '1.2' 1121 * Value 1.2 Format #0.00 Result '1.20' 1122 */ 1123 @Test 1124 public void Test4134300() { 1125 String[] DATA = { 1126 // Pattern Expected string 1127 "#.00", "1.20", 1128 "0.00", "1.20", 1129 "00.00", "01.20", 1130 "#0.0#", "1.2", 1131 "#0.00", "1.20", 1132 }; 1133 for (int i=0; i<DATA.length; i+=2) { 1134 String result = new DecimalFormat(DATA[i]).format(1.2); 1135 if (!result.equals(DATA[i+1])) { 1136 errln("Fail: 1.2 x " + DATA[i] + " = " + result + 1137 "; want " + DATA[i+1]); 1138 } 1139 else { 1140 logln("Ok: 1.2 x " + DATA[i] + " = " + result); 1141 } 1142 } 1143 } 1144 1145 /** 1146 * Empty pattern produces double negative prefix. 1147 */ 1148 @Test 1149 public void Test4140009() { 1150 final double IN[] = { 123.456, -123.456 }; 1151 final String OUT[] = { "123.456", "-123.456" }; 1152 for (int i=0; i<2; ++i) { 1153 DecimalFormat f = null; 1154 switch (i) { 1155 case 0: 1156 f = new DecimalFormat("", 1157 new DecimalFormatSymbols(Locale.ENGLISH)); 1158 break; 1159 case 1: 1160 f = new DecimalFormat("#.#", 1161 new DecimalFormatSymbols(Locale.ENGLISH)); 1162 f.applyPattern(""); 1163 break; 1164 } 1165 for (int j=0; j<2; ++j) { 1166 assertEquals("<empty pat " + i + ">.format(" + IN[j] + ")", 1167 OUT[j], f.format(IN[j])); 1168 } 1169 } 1170 } 1171 1172 /** 1173 * BigDecimal numbers get their fractions truncated by NumberFormat. 1174 */ 1175 @Test 1176 public void Test4141750() { 1177 try { 1178 String str = "12345.67"; 1179 java.math.BigDecimal bd = new java.math.BigDecimal(str); 1180 String sd = NumberFormat.getInstance(Locale.US).format(bd); 1181 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd); 1182 } 1183 catch (Exception e) { 1184 warnln(e.toString()); 1185 //e.printStackTrace(); 1186 } 1187 } 1188 1189 /** 1190 * DecimalFormat toPattern() doesn't quote special characters or handle 1191 * single quotes. 1192 */ 1193 @Test 1194 public void Test4145457() { 1195 try { 1196 DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(); 1197 DecimalFormatSymbols sym = nf.getDecimalFormatSymbols(); 1198 sym.setDecimalSeparator('\''); 1199 nf.setDecimalFormatSymbols(sym); 1200 double pi = 3.14159; 1201 1202 String[] PATS = { "#.00 'num''ber'", "''#.00''" }; 1203 1204 for (int i=0; i<PATS.length; ++i) { 1205 nf.applyPattern(PATS[i]); 1206 String out = nf.format(pi); 1207 String pat = nf.toPattern(); 1208 double val = nf.parse(out).doubleValue(); 1209 1210 nf.applyPattern(pat); 1211 String out2 = nf.format(pi); 1212 String pat2 = nf.toPattern(); 1213 double val2 = nf.parse(out2).doubleValue(); 1214 1215 if (!pat.equals(pat2)) 1216 errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" + 1217 pat + "\" vs. \"" + pat2 + "\""); 1218 else 1219 logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"'); 1220 1221 if (val == val2 && out.equals(out2)) { 1222 logln("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" + 1223 out + "\" -> " + val + " -> \"" + 1224 out2 + "\" -> " + val2); 1225 } 1226 else { 1227 errln("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" + 1228 out + "\" -> " + val + " -> \"" + 1229 out2 + "\" -> " + val2); 1230 } 1231 } 1232 } 1233 catch (ParseException e) { 1234 errln("Fail: " + e); 1235 e.printStackTrace(); 1236 } 1237 } 1238 1239 /** 1240 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly. 1241 * CANNOT REPRODUCE 1242 * This bug is a duplicate of 4139344, which is a duplicate of 4134300 1243 */ 1244 @Test 1245 public void Test4147295() { 1246 DecimalFormat sdf = new DecimalFormat(); 1247 String pattern = "#,###"; 1248 logln("Applying pattern \"" + pattern + "\""); 1249 sdf.applyPattern(pattern); 1250 int minIntDig = sdf.getMinimumIntegerDigits(); 1251 if (minIntDig != 0) { 1252 errln("Test failed"); 1253 errln(" Minimum integer digits : " + minIntDig); 1254 errln(" new pattern: " + sdf.toPattern()); 1255 } else { 1256 logln("Test passed"); 1257 logln(" Minimum integer digits : " + minIntDig); 1258 } 1259 } 1260 1261 /** 1262 * DecimalFormat formats -0.0 as +0.0 1263 * See also older related bug 4106658, 4106667 1264 */ 1265 @Test 1266 public void Test4147706() { 1267 DecimalFormat df = new DecimalFormat("#,##0.0##"); 1268 df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH)); 1269 double d1 = -0.0; 1270 double d2 = -0.0001; 1271 StringBuffer f1 = df.format(d1, new StringBuffer(), new FieldPosition(0)); 1272 StringBuffer f2 = df.format(d2, new StringBuffer(), new FieldPosition(0)); 1273 if (!f1.toString().equals("-0.0")) { 1274 errln(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"'); 1275 } 1276 if (!f2.toString().equals("-0.0")) { 1277 errln(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"'); 1278 } 1279 } 1280 1281 /** 1282 * NumberFormat cannot format Double.MAX_VALUE 1283 */ 1284 @Test 1285 public void Test4162198() { 1286 double dbl = Double.MAX_VALUE; 1287 NumberFormat f = NumberFormat.getInstance(); 1288 f.setMaximumFractionDigits(Integer.MAX_VALUE); 1289 f.setMaximumIntegerDigits(Integer.MAX_VALUE); 1290 String s = f.format(dbl); 1291 logln("The number " + dbl + " formatted to " + s); 1292 Number n = null; 1293 try { 1294 n = f.parse(s); 1295 } catch (java.text.ParseException e) { 1296 errln("Caught a ParseException:"); 1297 e.printStackTrace(); 1298 } 1299 logln("The string " + s + " parsed as " + n); 1300 if (n.doubleValue() != dbl) { 1301 errln("Round trip failure"); 1302 } 1303 } 1304 1305 /** 1306 * NumberFormat does not parse negative zero. 1307 */ 1308 @Test 1309 public void Test4162852() throws ParseException { 1310 for (int i=0; i<2; ++i) { 1311 NumberFormat f = (i == 0) ? NumberFormat.getInstance() 1312 : NumberFormat.getPercentInstance(); 1313 double d = -0.0; 1314 String s = f.format(d); 1315 double e = f.parse(s).doubleValue(); 1316 logln("" + 1317 d + " -> " + 1318 '"' + s + '"' + " -> " + 1319 e); 1320 if (e != 0.0 || 1.0/e > 0.0) { 1321 logln("Failed to parse negative zero"); 1322 } 1323 } 1324 } 1325 1326 /** 1327 * NumberFormat truncates data 1328 */ 1329 @Test 1330 public void Test4167494() throws Exception { 1331 NumberFormat fmt = NumberFormat.getInstance(Locale.US); 1332 1333 double a = Double.MAX_VALUE; 1334 String s = fmt.format(a); 1335 double b = fmt.parse(s).doubleValue(); 1336 boolean match = a == b; 1337 if (match) { 1338 logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); 1339 } else { 1340 errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); 1341 } 1342 1343 // We don't test Double.MIN_VALUE because the locale data for the US 1344 // currently doesn't specify enough digits to display Double.MIN_VALUE. 1345 // This is correct for now; however, we leave this here as a reminder 1346 // in case we want to address this later. 1347 if (false) { 1348 a = Double.MIN_VALUE; 1349 s = fmt.format(a); 1350 b = fmt.parse(s).doubleValue(); 1351 match = a == b; 1352 if (match) { 1353 logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); 1354 } else { 1355 errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); 1356 } 1357 } 1358 } 1359 1360 /** 1361 * DecimalFormat.parse() fails when ParseIntegerOnly set to true 1362 */ 1363 @Test 1364 public void Test4170798() { 1365 Locale savedLocale = Locale.getDefault(); 1366 Locale.setDefault(Locale.US); 1367 DecimalFormat df = new DecimalFormat(); 1368 df.setParseIntegerOnly(true); 1369 Number n = df.parse("-0.0", new ParsePosition(0)); 1370 if (!(n instanceof Double) 1371 || n.intValue() != 0) { 1372 errln("FAIL: parse(\"-0.0\") returns " + 1373 n + " (" + n.getClass().getName() + ')'); 1374 } 1375 Locale.setDefault(savedLocale); 1376 } 1377 1378 /** 1379 * toPattern only puts the first grouping separator in. 1380 */ 1381 @Test 1382 public void Test4176114() { 1383 String[] DATA = { 1384 "00", "#00", 1385 "000", "#000", // No grouping 1386 "#000", "#000", // No grouping 1387 "#,##0", "#,##0", 1388 "#,000", "#,000", 1389 "0,000", "#0,000", 1390 "00,000", "#00,000", 1391 "000,000", "#,000,000", 1392 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported 1393 }; 1394 for (int i=0; i<DATA.length; i+=2) { 1395 DecimalFormat df = new DecimalFormat(DATA[i]); 1396 String s = df.toPattern(); 1397 if (!s.equals(DATA[i+1])) { 1398 errln("FAIL: " + DATA[i] + " -> " + s + ", want " + DATA[i+1]); 1399 } 1400 } 1401 } 1402 1403 /** 1404 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2 1405 */ 1406 @Test 1407 public void Test4179818() { 1408 String DATA[] = { 1409 // Input Pattern Expected output 1410 "1.2511", "#.#", "1.3", 1411 "1.2501", "#.#", "1.3", 1412 "0.9999", "#", "1", 1413 }; 1414 DecimalFormat fmt = new DecimalFormat("#", 1415 new DecimalFormatSymbols(Locale.US)); 1416 for (int i=0; i<DATA.length; i+=3) { 1417 double in = Double.valueOf(DATA[i]).doubleValue(); 1418 String pat = DATA[i+1]; 1419 String exp = DATA[i+2]; 1420 fmt.applyPattern(pat); 1421 String out = fmt.format(in); 1422 if (out.equals(exp)) { 1423 logln("Ok: " + in + " x " + pat + " = " + out); 1424 } else { 1425 errln("FAIL: " + in + " x " + pat + " = " + out + 1426 ", expected " + exp); 1427 } 1428 } 1429 } 1430 1431 @Test 1432 public void Test4185761() throws IOException, ClassNotFoundException { 1433 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1434 ObjectOutputStream oos = new ObjectOutputStream(baos); 1435 1436 NumberFormat nf = NumberFormat.getInstance(Locale.US); 1437 1438 // Set special values we are going to search for in the output byte stream 1439 // These are all legal values. 1440 nf.setMinimumIntegerDigits(0x111); // Keep under 309 1441 nf.setMaximumIntegerDigits(0x112); // Keep under 309 1442 nf.setMinimumFractionDigits(0x113); // Keep under 340 1443 nf.setMaximumFractionDigits(0x114); // Keep under 340 1444 1445 oos.writeObject(nf); 1446 oos.flush(); 1447 baos.close(); 1448 1449 byte[] bytes = baos.toByteArray(); 1450 1451 // Scan for locations of min/max int/fract values in the byte array. 1452 // At the moment (ICU4J 2.1), there is only one instance of each target pair 1453 // in the byte stream, so assume first match is it. Note this is not entirely 1454 // failsafe, and needs to be checked if we change the package or structure of 1455 // this class. 1456 // Current positions are 890, 880, 886, 876 1457 int[] offsets = new int[4]; 1458 for (int i = 0; i < bytes.length - 1; ++i) { 1459 if (bytes[i] == 0x01) { // high byte 1460 for (int j = 0; j < offsets.length; ++j) { 1461 if ((offsets[j] == 0) && (bytes[i+1] == (0x11 + j))) { // low byte 1462 offsets[j] = i; 1463 break; 1464 } 1465 } 1466 } 1467 } 1468 1469 { 1470 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); 1471 Object o = ois.readObject(); 1472 ois.close(); 1473 1474 if (!nf.equals(o)) { 1475 errln("Fail: NumberFormat serialization/equality bug"); 1476 } else { 1477 logln("NumberFormat serialization/equality is OKAY."); 1478 } 1479 } 1480 1481 // Change the values in the byte stream so that min > max. 1482 // Numberformat should catch this and throw an exception. 1483 for (int i = 0; i < offsets.length; ++i) { 1484 bytes[offsets[i]] = (byte)(4 - i); 1485 } 1486 1487 { 1488 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); 1489 try { 1490 NumberFormat format = (NumberFormat) ois.readObject(); 1491 logln("format: " + format.format(1234.56)); //fix "The variable is never used" 1492 errln("FAIL: Deserialized bogus NumberFormat with minXDigits > maxXDigits"); 1493 } catch (InvalidObjectException e) { 1494 logln("Ok: " + e.getMessage()); 1495 } 1496 } 1497 1498 // Set values so they are too high, but min <= max 1499 // Format should pass the min <= max test, and DecimalFormat should reset to current maximum 1500 // (for compatibility with versions streamed out before the maximums were imposed). 1501 for (int i = 0; i < offsets.length; ++i) { 1502 bytes[offsets[i]] = 4; 1503 } 1504 // Android patch (http://b/27855939) start. 1505 // Allow 2 billion integer digits. 1506 bytes[offsets[1]-2] = 127; 1507 1508 { 1509 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); 1510 NumberFormat format = (NumberFormat) ois.readObject(); 1511 //For compatibility with previous version 1512 if ((format.getMaximumIntegerDigits() != 2000000000) 1513 || format.getMaximumFractionDigits() != 340) { 1514 // Android patch (http://b/27855939) end. 1515 errln("FAIL: Deserialized bogus NumberFormat with values out of range," + 1516 " intMin: " + format.getMinimumIntegerDigits() + 1517 " intMax: " + format.getMaximumIntegerDigits() + 1518 " fracMin: " + format.getMinimumFractionDigits() + 1519 " fracMax: " + format.getMaximumFractionDigits()); 1520 } else { 1521 logln("Ok: Digit count out of range"); 1522 } 1523 } 1524 } 1525 1526 1527 /** 1528 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat. 1529 * This includes the minus sign, currency symbol, international currency 1530 * symbol, percent, and permille. This is filed as bugs 4212072 and 1531 * 4212073. 1532 */ 1533 // Android-changed: Added @Ignore to suppress the test; it consumes a lot of heap, permanently, 1534 // affecting later tests. http://b/62374714 1535 @Ignore 1536 @Test 1537 public void Test4212072() throws IOException, ClassNotFoundException { 1538 DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US); 1539 DecimalFormat fmt = new DecimalFormat("#", sym); 1540 1541 sym.setMinusSign('^'); 1542 fmt.setDecimalFormatSymbols(sym); 1543 if (!fmt.format(-1).equals("^1")) { 1544 errln("FAIL: -1 x (minus=^) -> " + fmt.format(-1) + 1545 ", exp ^1"); 1546 } 1547 if (!fmt.getNegativePrefix().equals("^")) { 1548 errln("FAIL: (minus=^).getNegativePrefix -> " + 1549 fmt.getNegativePrefix() + ", exp ^"); 1550 } 1551 sym.setMinusSign('-'); 1552 1553 fmt.applyPattern("#%"); 1554 sym.setPercent('^'); 1555 fmt.setDecimalFormatSymbols(sym); 1556 if (!fmt.format(0.25).equals("25^")) { 1557 errln("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) + 1558 ", exp 25^"); 1559 } 1560 if (!fmt.getPositiveSuffix().equals("^")) { 1561 errln("FAIL: (percent=^).getPositiveSuffix -> " + 1562 fmt.getPositiveSuffix() + ", exp ^"); 1563 } 1564 sym.setPercent('%'); 1565 1566 fmt.applyPattern("#\u2030"); 1567 sym.setPerMill('^'); 1568 fmt.setDecimalFormatSymbols(sym); 1569 if (!fmt.format(0.25).equals("250^")) { 1570 errln("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) + 1571 ", exp 250^"); 1572 } 1573 if (!fmt.getPositiveSuffix().equals("^")) { 1574 errln("FAIL: (permill=^).getPositiveSuffix -> " + 1575 fmt.getPositiveSuffix() + ", exp ^"); 1576 } 1577 sym.setPerMill('\u2030'); 1578 1579 fmt.applyPattern("\u00A4#.00"); 1580 sym.setCurrencySymbol("usd"); 1581 fmt.setDecimalFormatSymbols(sym); 1582 if (!fmt.format(12.5).equals("usd12.50")) { 1583 errln("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) + 1584 ", exp usd12.50"); 1585 } 1586 if (!fmt.getPositivePrefix().equals("usd")) { 1587 errln("FAIL: (currency=usd).getPositivePrefix -> " + 1588 fmt.getPositivePrefix() + ", exp usd"); 1589 } 1590 sym.setCurrencySymbol("$"); 1591 1592 fmt.applyPattern("\u00A4\u00A4#.00"); 1593 sym.setInternationalCurrencySymbol("DOL"); 1594 fmt.setDecimalFormatSymbols(sym); 1595 if (!fmt.format(12.5).equals("DOL12.50")) { 1596 errln("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) + 1597 ", exp DOL12.50"); 1598 } 1599 if (!fmt.getPositivePrefix().equals("DOL")) { 1600 errln("FAIL: (intlcurrency=DOL).getPositivePrefix -> " + 1601 fmt.getPositivePrefix() + ", exp DOL"); 1602 } 1603 sym.setInternationalCurrencySymbol("USD"); 1604 1605 if (VersionInfo.ICU_VERSION == VersionInfo.getInstance(2,2)) { 1606 // bug in 2.2 that fails this test 1607 // to be fixed in the later versions 1608 System.out.println("\n Test skipped for release 2.2"); 1609 return; 1610 } 1611 1612 // Since the pattern logic has changed, make sure that patterns round 1613 // trip properly. Test stream in/out integrity too. 1614 Locale[] avail = NumberFormat.getAvailableLocales(); 1615 for (int i=0; i<avail.length; ++i) { 1616 if ((avail[i].getLanguage().equals("ji") || avail[i].getLanguage().equals("bm")) && 1617 logKnownIssue("11234", "Symbol roundtrip issues for locales ji, bm")) { 1618 continue; 1619 } 1620 for (int j=0; j<3; ++j) { 1621 NumberFormat nf; 1622 switch (j) { 1623 case 0: 1624 nf = NumberFormat.getInstance(avail[i]); 1625 break; 1626 case 1: 1627 nf = NumberFormat.getCurrencyInstance(avail[i]); 1628 break; 1629 default: 1630 nf = NumberFormat.getPercentInstance(avail[i]); 1631 break; 1632 } 1633 DecimalFormat df = (DecimalFormat) nf; 1634 1635 // Test toPattern/applyPattern round trip 1636 String pat = df.toPattern(); 1637 DecimalFormatSymbols symb = new DecimalFormatSymbols(avail[i]); 1638 DecimalFormat f2 = new DecimalFormat(pat, symb); 1639 if (!df.equals(f2)) { 1640 errln("FAIL: " + avail[i] + " #" + j + " -> \"" + pat + 1641 "\" -> \"" + f2.toPattern() + '"'); 1642 } 1643 1644 // Test toLocalizedPattern/applyLocalizedPattern round trip 1645 pat = df.toLocalizedPattern(); 1646 try{ 1647 f2.applyLocalizedPattern(pat); 1648 1649 String s1 = f2.format(123456); 1650 String s2 = df.format(123456); 1651 if(!s1.equals(s2)){ 1652 errln("FAIL: " + avail[i] + " #" + j + " -> localized \"" + s2 + 1653 "\" -> \"" + s2 + '"'+ " in locale "+df.getLocale(ULocale.ACTUAL_LOCALE)); 1654 1655 } 1656 if (!df.equals(f2)) { 1657 errln("FAIL: " + avail[i] + " #" + j + " -> localized \"" + pat + 1658 "\" -> \"" + f2.toLocalizedPattern() + '"'+ " in locale "+df.getLocale(ULocale.ACTUAL_LOCALE)); 1659 errln("s1: "+s1+" s2: "+s2); 1660 } 1661 1662 }catch(IllegalArgumentException ex){ 1663 errln(ex.getMessage()+" for locale "+ df.getLocale(ULocale.ACTUAL_LOCALE)); 1664 } 1665 1666 1667 // Test writeObject/readObject round trip 1668 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1669 ObjectOutputStream oos = new ObjectOutputStream(baos); 1670 oos.writeObject(df); 1671 oos.flush(); 1672 baos.close(); 1673 byte[] bytes = baos.toByteArray(); 1674 ObjectInputStream ois = 1675 new ObjectInputStream(new ByteArrayInputStream(bytes)); 1676 f2 = (DecimalFormat) ois.readObject(); 1677 if (!df.equals(f2)) { 1678 errln("FAIL: Stream in/out " + avail[i] + " -> \"" + pat + 1679 "\" -> " + 1680 (f2 != null ? ("\""+f2.toPattern()+'"') : "null")); 1681 } 1682 1683 } 1684 } 1685 1686 // @since ICU 2.4 1687 // Make sure that all special characters, when quoted in a suffix or 1688 // prefix, lose their special meaning. 1689 char[] SPECIALS = { '0', ',', '.', '\u2030', '%', '#', 1690 ';', 'E', '*', '+', '-' }; 1691 sym = new DecimalFormatSymbols(Locale.US); 1692 for (int j=0; j<SPECIALS.length; ++j) { 1693 char special = SPECIALS[j]; 1694 String pat = "'" + special + "'#0'" + special + "'"; 1695 try { 1696 fmt = new DecimalFormat(pat, sym); 1697 String pat2 = fmt.toPattern(); 1698 if (!pat.equals(pat2)) { 1699 errln("FAIL: Pattern \"" + pat + "\" => toPattern() => \"" + 1700 pat2 + "\""); 1701 } 1702 String s = fmt.format(123); 1703 String exp = "" + special + "123" + special; 1704 if (!s.equals(exp)) { 1705 errln("FAIL: 123 x \"" + pat + "\" => \"" + s + "\", exp \"" + 1706 exp + "\""); 1707 } 1708 } catch (IllegalArgumentException e) { 1709 errln("FAIL: Pattern \"" + pat + "\" => " + e.getMessage()); 1710 } 1711 } 1712 } 1713 1714 /** 1715 * DecimalFormat.parse() fails for mulipliers 2^n. 1716 */ 1717 @Test 1718 public void Test4216742() throws ParseException { 1719 DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(Locale.US); 1720 long[] DATA = { Long.MIN_VALUE, Long.MAX_VALUE, -100000000L, 100000000L}; 1721 for (int i=0; i<DATA.length; ++i) { 1722 String str = Long.toString(DATA[i]); 1723 for (int m = 1; m <= 100; m++) { 1724 fmt.setMultiplier(m); 1725 long n = ((Number) fmt.parse(str)).longValue(); 1726 if (n > 0 != DATA[i] > 0) { 1727 errln("\"" + str + "\" parse(x " + fmt.getMultiplier() + 1728 ") => " + n); 1729 } 1730 } 1731 } 1732 } 1733 1734 /** 1735 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction 1736 * digits. 1737 */ 1738 @Test 1739 public void Test4217661() { 1740 Object[] DATA = { 1741 new Double(0.001), "0", 1742 new Double(1.001), "1", 1743 new Double(0.006), "0.01", 1744 new Double(1.006), "1.01", 1745 }; 1746 NumberFormat fmt = NumberFormat.getInstance(Locale.US); 1747 fmt.setMaximumFractionDigits(2); 1748 for (int i=0; i<DATA.length; i+=2) { 1749 String s = fmt.format(((Double) DATA[i]).doubleValue()); 1750 if (!s.equals(DATA[i+1])) { 1751 errln("FAIL: Got " + s + ", exp " + DATA[i+1]); 1752 } 1753 } 1754 } 1755 1756 /** 1757 * 4243011: Formatting .5 rounds to "1" instead of "0" 1758 */ 1759 @Test 1760 public void Test4243011() { 1761 double DATA[] = {0.5, 1.5, 2.5, 3.5, 4.5}; 1762 String EXPECTED[] = {"0.", "2.", "2.", "4.", "4."}; 1763 1764 DecimalFormat format = new DecimalFormat("0."); 1765 for (int i = 0; i < DATA.length; i++) { 1766 String result = format.format(DATA[i]); 1767 if (result.equals(EXPECTED[i])) { 1768 logln("OK: got " + result); 1769 } else { 1770 errln("FAIL: got " + result); 1771 } 1772 } 1773 } 1774 1775 /** 1776 * 4243108: format(0.0) gives "0.1" if preceded by parse("99.99") 1777 */ 1778 @Test 1779 public void Test4243108() { 1780 DecimalFormat f = new DecimalFormat("#.#"); 1781 String result = f.format(0.0); 1782 if (result.equals("0")) { 1783 logln("OK: got " + result); 1784 } else { 1785 errln("FAIL: got " + result); 1786 } 1787 try { 1788 double dResult = f.parse("99.99").doubleValue(); 1789 if (dResult == 99.99) { 1790 logln("OK: got " + dResult); 1791 } else { 1792 errln("FAIL: got " + dResult); 1793 } 1794 } catch (ParseException e) { 1795 errln("Caught a ParseException:"); 1796 e.printStackTrace(); 1797 } 1798 result = f.format(0.0); 1799 if (result.equals("0")) { 1800 logln("OK: got " + result); 1801 } else { 1802 errln("FAIL: got " + result); 1803 } 1804 } 1805 1806 /** 1807 * 4330377: DecimalFormat engineering notation gives incorrect results 1808 */ 1809 @Test 1810 public void test4330377() { 1811 /* 1812 double[] input = {5000.0, 500.0, 50.0, 5.0, 0.5, 0.05, 0.005, 0.0005, 1813 5050.0, 505.0, 50.5, 5.05, 0.505, 0.0505, 0.00505, 0.000505}; 1814 String[] pattern = {"000.#E0", "##0.#E0", "#00.#E0"}; 1815 String[][] expected = { 1816 // it's questionable whether "#00.#E0" should result in post-decimal 1817 // zeroes, i.e., whether "5.0E3", "5.0E0", "5.0E-3" are really good 1818 {"500E1", "5E3", "5.0E3"}, 1819 {"500E0", "500E0", "500E0"}, 1820 {"500E-1", "50E0", "50E0"}, 1821 {"500E-2", "5E0", "5.0E0"}, 1822 {"500E-3", "500E-3", "500E-3"}, 1823 {"500E-4", "50E-3", "50E-3"}, 1824 {"500E-5", "5E-3", "5.0E-3"}, 1825 {"500E-6", "500E-6", "500E-6"}, 1826 {"505E1", "5.05E3", "5.05E3"}, 1827 {"505E0", "505E0", "505E0"}, 1828 {"505E-1", "50.5E0", "50.5E0"}, 1829 {"505E-2", "5.05E0", "5.05E0"}, 1830 {"505E-3", "505E-3", "505E-3"}, 1831 {"505E-4", "50.5E-3", "50.5E-3"}, 1832 {"505E-5", "5.05E-3", "5.05E-3"}, 1833 {"505E-6", "505E-6", "505E-6"} 1834 }; 1835 for (int i = 0; i < input.length; i++) { 1836 for (int j = 0; j < pattern.length; j++) { 1837 DecimalFormat format = new DecimalFormat(pattern[j]); 1838 String result = format.format(input[i]); 1839 if (!result.equals(expected[i][j])) { 1840 errln("FAIL: input: " + input[i] + 1841 ", pattern: " + pattern[j] + 1842 ", expected: " + expected[i][j] + 1843 ", got: " + result); 1844 } 1845 } 1846 } 1847 */ 1848 } 1849 1850 /** 1851 * 4233840: NumberFormat does not round correctly 1852 */ 1853 @Test 1854 public void test4233840() { 1855 float f = 0.0099f; 1856 1857 NumberFormat nf = new DecimalFormat("0.##", new DecimalFormatSymbols(Locale.US)); 1858 nf.setMinimumFractionDigits(2); 1859 1860 String result = nf.format(f); 1861 1862 if (!result.equals("0.01")) { 1863 errln("FAIL: input: " + f + ", expected: 0.01, got: " + result); 1864 } 1865 } 1866 1867 /** 1868 * 4241880: Decimal format doesnt round a double properly when the number is less than 1 1869 */ 1870 @Test 1871 public void test4241880() { 1872 Locale savedLocale = Locale.getDefault(); 1873 Locale.setDefault(Locale.US); 1874 double[] input = { 1875 .019, .009, .015, .016, .014, 1876 .004, .005, .006, .007, .008, 1877 .5, 1.5, .05, .15, .005, 1878 .015, .0005, .0015, 1879 }; 1880 String[] pattern = { 1881 "##0%", "##0%", "##0%", "##0%", "##0%", 1882 "##0%", "##0%", "##0%", "##0%", "##0%", 1883 "#,##0", "#,##0", "#,##0.0", "#,##0.0", "#,##0.00", 1884 "#,##0.00", "#,##0.000", "#,##0.000", 1885 }; 1886 String[] expected = { 1887 "2%", "1%", "2%", "2%", "1%", 1888 "0%", "0%", "1%", "1%", "1%", 1889 "0", "2", "0.0", "0.2", "0.00", 1890 "0.02", "0.000", "0.002", 1891 }; 1892 for (int i = 0; i < input.length; i++) { 1893 DecimalFormat format = new DecimalFormat(pattern[i]); 1894 String result = format.format(input[i]); 1895 if (!result.equals(expected[i])) { 1896 errln("FAIL: input: " + input[i] + 1897 ", pattern: " + pattern[i] + 1898 ", expected: " + expected[i] + 1899 ", got: " + result); 1900 } 1901 } 1902 Locale.setDefault(savedLocale); 1903 } 1904 } 1905 1906 class myformat implements Serializable 1907 { 1908 /** 1909 * For serialization 1910 */ 1911 private static final long serialVersionUID = 4120813612616076506L; 1912 DateFormat _dateFormat = DateFormat.getDateInstance(); 1913 1914 public String Now() 1915 { 1916 GregorianCalendar calendar = new GregorianCalendar(); 1917 Date t = calendar.getTime(); 1918 String nowStr = _dateFormat.format(t); 1919 return nowStr; 1920 } 1921 } 1922 1923 class MyNumberFormat extends NumberFormat { 1924 /** 1925 * For serialization 1926 */ 1927 private static final long serialVersionUID = 1251303884737169952L; 1928 public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { 1929 return new StringBuffer(""); 1930 } 1931 public StringBuffer format(long number,StringBuffer toAppendTo, FieldPosition pos) { 1932 return new StringBuffer(""); 1933 } 1934 public Number parse(String text, ParsePosition parsePosition) { 1935 return new Integer(0); 1936 } 1937 public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) { 1938 return new StringBuffer(""); 1939 } 1940 public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) { 1941 return new StringBuffer(""); 1942 } 1943 public StringBuffer format(android.icu.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) { 1944 return new StringBuffer(""); 1945 } 1946 } 1947 1948