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