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