< prev index next >

test/jdk/java/text/Format/NumberFormat/BigDecimalParse.java

Print this page

  1 /*
  2  * Copyright (c) 2003, 2016, 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 4018937 8008577
 27  * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected.
 28  * @library /java/text/testlib
 29  * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalParse
 30  */
 31 
 32 import java.math.BigDecimal;
 33 import java.text.*;
 34 import java.util.*;
 35 
 36 public class BigDecimalParse extends IntlTest {

 37 
 38     public static void main(String[] args) throws Exception {
 39         Locale loc = Locale.getDefault();
 40         try {
 41             Locale.setDefault(Locale.US);
 42             new BigDecimalParse().run(args);
 43         } finally {
 44             // restore the reserved locale
 45             Locale.setDefault(loc);
 46         }
 47     }
 48 

 49     static final String nonsep_int =
 50         "123456789012345678901234567890123456789012345678901234567890" +
 51         "123456789012345678901234567890123456789012345678901234567890" +
 52         "123456789012345678901234567890123456789012345678901234567890" +
 53         "123456789012345678901234567890123456789012345678901234567890" +
 54         "123456789012345678901234567890123456789012345678901234567890" +
 55         "123456789012345678901234567890123456789012345678901234567890";
 56 
 57     static final String sep_int =
 58         "123,456,789,012,345,678,901,234,567,890," +
 59         "123,456,789,012,345,678,901,234,567,890," +
 60         "123,456,789,012,345,678,901,234,567,890," +
 61         "123,456,789,012,345,678,901,234,567,890," +
 62         "123,456,789,012,345,678,901,234,567,890," +
 63         "123,456,789,012,345,678,901,234,567,890," +
 64         "123,456,789,012,345,678,901,234,567,890," +
 65         "123,456,789,012,345,678,901,234,567,890," +
 66         "123,456,789,012,345,678,901,234,567,890," +
 67         "123,456,789,012,345,678,901,234,567,890," +
 68         "123,456,789,012,345,678,901,234,567,890," +

 91         "000,000,000,000,000,000,000,000,000,000";
 92 
 93     static final String fra =
 94         "012345678901234567890123456789012345678901234567890123456789" +
 95         "012345678901234567890123456789012345678901234567890123456789" +
 96         "012345678901234567890123456789012345678901234567890123456789" +
 97         "012345678901234567890123456789012345678901234567890123456789" +
 98         "012345678901234567890123456789012345678901234567890123456789" +
 99         "012345678901234567890123456789012345678901234567890123456789";
100 
101 
102     Number parsed = null;
103     ParsePosition pp;
104     boolean exceptionOccurred;
105     String msg;
106     DecimalFormat df;
107 
108     /**
109      * Test for normal big numbers which have the fraction part
110      */
111     void test_Parse_in_DecimalFormat_BigDecimal() {

112         df = new DecimalFormat();
113         df.setParseBigDecimal(true);
114 
115         // From: 1234...7890.012...789
116         // To:   BigDecimal 1234...7890.012...789
117         check(nonsep_int + "." + fra, new BigDecimal(nonsep_int + "." + fra));
118 
119         // From: -1,234...7,890.012...789
120         // To:   BigDecimal -1234...7890.012...789
121         check("-" + sep_int    + "." + fra,
122               new BigDecimal("-" + nonsep_int + "." + fra));
123 
124         // From: 000...0000.0...0
125         // To:   BigDecimal 0E-360
126         check(nonsep_zero + "." + nonsep_zero,
127               new BigDecimal(nonsep_zero + "." + nonsep_zero));
128 
129         // From: 0.000...0000123...789E370
130         // To:   BigDecimal 0.0123...789
131         check("0.0000000000" + nonsep_zero + fra + "E370",

133 
134         // From: 0.1123...890E-360
135         // To:   BigDecimal 1.123...890E-361
136         check("0.1" + nonsep_int + "E-360",
137               new BigDecimal("0.1" + nonsep_int + "E-360"));
138 
139         // From: 000...0000.0...0123...7890
140         // To:   BigDecimal 1.234...890E-361
141         check(nonsep_zero + "." + nonsep_zero + nonsep_int,
142               new BigDecimal(nonsep_zero + "." + nonsep_zero + nonsep_int));
143 
144         // From: 0.123...890E360
145         // To:   BigDecimal 123...890
146         check("0." + nonsep_int + "E360",
147               new BigDecimal("0." + nonsep_int + "E360"));
148     }
149 
150     /**
151      * Test for normal big numbers which have the fraction part with multiplier
152      */
153     void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() {

154         df = new DecimalFormat();
155         df.setParseBigDecimal(true);
156 
157         // From: 250,0...0,000.000...000
158         // To:   1000...0000.000...000
159         df.setMultiplier(250000000);
160         check("250,000,000," + sep_zero + "." + nonsep_zero,
161               new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
162 
163         // From: -250,0...0,000.000...000
164         // To:   -1000...0000.000...000
165         check("-250,000,000," + sep_zero + "." + nonsep_zero,
166               new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
167 
168         // From: 250,0...0,000.000...000
169         // To:   -1000...0000.000...000
170         df.setMultiplier(-250000000);
171         check("250,000,000," + sep_zero + "." + nonsep_zero,
172               new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
173 

175         // To:   1000...0000.000...000
176         check("-250,000,000," + sep_zero + "." + nonsep_zero,
177               new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
178 
179         // Confirm that ArithmeticException is handled properly
180         // From: 1000.000
181         // To:   333.333
182         df.setMultiplier(3);
183         check("1000.000", new BigDecimal("333.333"));
184 
185         // Confirm that ArithmeticException is handled properly
186         // From: 10000.0000
187         // To:   303.0303
188         df.setMultiplier(33);
189         check("10000.0000", new BigDecimal("303.0303"));
190     }
191 
192     /**
193      * Test for division by zero (BigDecimal)
194      */
195     void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() {

196         df = new DecimalFormat();
197         df.setParseBigDecimal(true);
198         df.setMultiplier(0);
199 
200         // From: 1000.000
201         // To:   Double.POSITIVE_INFINITY
202         check("1000.000", Double.POSITIVE_INFINITY);
203 
204         // From: -1000
205         // To:   Double.NEGATIVE_INFINITY
206         check("-1000", Double.NEGATIVE_INFINITY);
207 
208         // From: -0.00
209         // To:   Double.NaN
210         check("-0.00", Double.NaN);
211     }
212 
213     /**
214      * Test for division by zero (Double)
215      */
216     void test_Parse_in_DecimalFormat_Double_DivisionByZero() {

217         df = new DecimalFormat();
218         df.setParseBigDecimal(false);
219         df.setMultiplier(0);
220 
221         // From: 1000.000
222         // To:   Double.POSITIVE_INFINITY
223         check("1000.000", Double.POSITIVE_INFINITY);
224 
225         // From: -1000.000
226         // To:   Double.NEGATIVE_INFINITY
227         check("-1000.000", Double.NEGATIVE_INFINITY);
228 
229         // From: 0.0
230         // To:   Double.NaN
231         check("0.0", Double.NaN);
232 
233         // From: -0.0 (Double)
234         // To:   Double.NaN
235         check("-0.0", Double.NaN);
236 
237         // From: Double.NaN
238         // To:   Double.NaN
239         check("\ufffd", Double.NaN);
240 
241         // From: Double.POSITIVE_INFINITY
242         // To:   Double.NaN
243         check("\u221e", Double.POSITIVE_INFINITY);
244 
245         // From: Double.NEGATIVE_INFINITY
246         // To:   Double.NaN
247         check("-\u221e", Double.NEGATIVE_INFINITY);
248     }
249 
250     /**
251      * Test for division by zero (Long)
252      */
253     void test_Parse_in_DecimalFormat_Long_DivisionByZero() {

254         df = new DecimalFormat();
255         df.setParseBigDecimal(false);
256         df.setMultiplier(0);
257 
258         // From: 1000
259         // To:   Double.POSITIVE_INFINITY
260         check("1000", Double.POSITIVE_INFINITY);
261 
262         // From: -1000
263         // To:   Double.NEGATIVE_INFINITY
264         check("-1000", Double.NEGATIVE_INFINITY);
265 
266         // From: -000 (Long)
267         // To:   Double.NaN
268         check("-000", Double.NaN);
269     }
270 
271     /**
272      * Test for normal big numbers which don't have the fraction part
273      */
274     void test_Parse_in_DecimalFormat_BigInteger() {

275         df = new DecimalFormat();
276         df.setParseBigDecimal(true);
277 
278         // From: 123...890
279         // To:   BigDecimal 123...890
280         check(nonsep_int + nonsep_int, new BigDecimal(nonsep_int + nonsep_int));
281 
282         // From: 123,4...7,890
283         // To:   BigDecimal 1234...7890
284         check(sep_int + "," + sep_int, new BigDecimal(nonsep_int + nonsep_int));
285 
286         // From: -000...000123...890
287         // To:   BigDecimal -123...890
288         check("-" + nonsep_zero + nonsep_int, new BigDecimal("-" + nonsep_int));
289 
290         // From: -000,0...0,000,123,4...7,890
291         // To:   BigDecimal -123...890
292         check("-" + sep_zero + "," + sep_int, new BigDecimal("-" + nonsep_int));
293     }
294 
295     /**
296      * Test for normal big numbers which don't have the fraction part with
297      * multiplier
298      */
299     void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() {

300         df = new DecimalFormat();
301         df.setParseBigDecimal(true);
302 
303         // From: 250,0...0,000
304         // To:   1000...0000
305         df.setMultiplier(250000000);
306         check("250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
307 
308         // From: -250,0...0,000
309         // To:   -1000...0000
310         check("-250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
311 
312         // From: 250,0...0,000
313         // To:   -1000...0000
314         df.setMultiplier(-250000000);
315         check("250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
316 
317         // From: -250,0...0,000
318         // To:   1000...0000
319         check("-250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
320 
321         // From: 250,0...0,000E-360
322         // To:   -1000...0000.000...000
323         check("250,000,000," + sep_zero + "," + sep_zero + "E-360",
324               new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
325 
326         // Confirm that a division which results in a irrational number is done
327         // properly
328         // From: 1000
329         // To:   333
330         df.setMultiplier(3);
331         check("1000", new BigDecimal("333"));
332     }
333 
334     /**
335      * Test for special numbers
336      *    Double.NaN
337      *    Double.POSITIVE_INFINITY
338      *    Double.NEGATIVE_INFINITY
339      */
340     void test_Parse_in_DecimalFormat_SpecialNumber() {

341         df = new DecimalFormat();
342         df.setParseBigDecimal(true);
343 
344         String[] numbers = {
345             "0", "0.0", "25", "25.0", "25.5", "\u221e", "\ufffd",
346             "-0", "-0.0", "-25", "-25.0", "-25.5", "-\u221e",
347         };
348         int multipliers[] = {5, -5};
349         Number[][] expected = {
350             {
351                 new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
352                 new BigDecimal("5.0"), new BigDecimal("5.1"),
353                 Double.POSITIVE_INFINITY, Double.NaN,
354                 new BigDecimal("0"), new BigDecimal("0.0"),
355                 new BigDecimal("-5"), new BigDecimal("-5.0"),
356                 new BigDecimal("-5.1"),
357                 Double.NEGATIVE_INFINITY, Double.NaN,
358             },
359             {
360                 new BigDecimal("0"), new BigDecimal("0.0"),
361                 new BigDecimal("-5"), new BigDecimal("-5.0"),
362                 new BigDecimal("-5.1"),
363                 Double.NEGATIVE_INFINITY, Double.NaN,
364                 new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
365                 new BigDecimal("5.0"), new BigDecimal("5.1"),
366                 Double.POSITIVE_INFINITY,
367             },
368         };
369 
370         for (int i = 0; i < multipliers.length; i++) {
371             df.setMultiplier(multipliers[i]);
372             for (int j = 0; j < numbers.length; j++) {
373                 check(String.valueOf(numbers[j]), expected[i][j]);
374             }
375         }
376     }
377 
378     /**
379      * Test for special numbers
380      */
381     void test_Parse_in_DecimalFormat_Other() {

382         df = new DecimalFormat();
383         df.setParseBigDecimal(true);
384 
385         String[] numbers = {
386             "-9223372036854775808",     // Long.MIN_VALUE
387         };
388         int multipliers[] = {1, -1};
389         String[][] expected = {
390             {"-9223372036854775808"},   // Long.MIN_VALUE
391             {"9223372036854775808"},    // Long.MAX_VALUE+1 = abs(MIN_VALUE)
392         };
393 
394         for (int i = 0; i < multipliers.length; i++) {
395             df.setMultiplier(multipliers[i]);
396             for (int j = 0; j < numbers.length; j++) {
397                 check(String.valueOf(numbers[j]),
398                       new BigDecimal(expected[i][j]));
399             }
400         }
401     }

455 
456         "9876543210987654321098765432109876543210",
457         "-9876543210987654321098765432109876543210",
458         "9.876543210987654321098765432109876543210E44",
459         "-98765432109876543210987654321098765.43210",
460         "9876543210987654321098765432109876543210.00",
461         "-9876543210987654321098765432109876543210.00",
462         "9876543210987654321098765432109876543210.12",
463         "-9876543210987654321098765432109876543210.12",
464         "9876543210987654321098765432109876543210",
465         "-9876543210987654321098765432109876543210.00000000000000000000",
466     };
467     static final int[] parsePosition1 = {
468         60, 61, 61, 63, 64, 65, 64, 65,
469         57, 58, 59, 61, 61, 63, 60, 61, 54, 88,
470     };
471 
472     /**
473      * Test for MessageFormat: setParseIntegerOnly(false)
474      */
475     void test_Parse_in_MessageFormat_NotParseIntegerOnly() {

476         for (int i=0; i < patterns.length; i++) {
477             pp = new ParsePosition(0);
478             Object[] parsed = null;
479 
480             try {
481                 MessageFormat mf = new MessageFormat(patterns[i]);
482                 Format[] formats = mf.getFormats();
483                 for (int j=0; j < formats.length; j++) {
484                     ((DecimalFormat)formats[j]).setParseBigDecimal(true);
485                 }
486 
487                 parsed = mf.parse(from[i], pp);
488 
489                 if (pp.getErrorIndex() != -1) {
490                     errln("Case" + (i+1) +
491                           ": getErrorIndex() returns wrong value. expected:-1, got:"+
492                           pp.getErrorIndex() + " for " + from[i]);
493                 }
494                 if (pp.getIndex() != parsePosition1[i]) {
495                     errln("Case" + (i+1) +
496                           ": getIndex() returns wrong value. expected:" +
497                           parsePosition1[i] + ", got:"+ pp.getIndex() +
498                           " for " + from[i]);
499                 }
500             }
501             catch(Exception e) {
502                 errln("Unexpected exception: " + e.getMessage());
503             }
504 
505             checkType(from[i], getType(new BigDecimal(expected1[i])),
506                       getType((Number)parsed[0]));
507             checkParse(from[i], new BigDecimal(expected1[i]),
508                        (Number)parsed[0]);
509         }
510     }
511 
512     static final String[] expected2 = { // isParseIntegerOnly() == true
513         "12345678901234567890",
514         "-12345678901234567890",
515         "12345678901234567890",
516         "-12345678901234567890",
517         "12345678901234567890",
518         "-12345678901234567890",
519         "0",
520         "0",
521 
522         "9876543210987654321098765432109876543210",

541         {2, 0},         // parsing stopped at '(' because cannot find ')'
542         {2, 0},         // parsing stopped at the first numeric
543                         // because cannot find '%'
544         {2, 0},         // parsing stopped at the first numeric
545                         // because cannot find '%'
546         {28, 0},        // parsing stopped at '.'
547         {29, 0},        // parsing stopped at '.'
548 
549         {-1, 57}, {-1, 58}, {-1, 59}, {-1, 61},
550         {56, 0},        // parsing stopped at '.'
551                         // because cannot find '%'
552         {2, 0},         // parsing stopped at '(' because cannot find ')'
553         {-1, 60}, {-1, 61},
554         {28, 0},        // parsing stopped at '.'
555         {-1, 88},
556     };
557 
558     /**
559      * Test for MessageFormat: setParseIntegerOnly(true)
560      */
561     void test_Parse_in_MessageFormat_ParseIntegerOnly() {

562         for (int i=0; i < patterns.length; i++) {
563             pp = new ParsePosition(0);
564             Object[] parsed = null;
565 
566             try {
567                 MessageFormat mf = new MessageFormat(patterns[i]);
568                 Format[] formats = mf.getFormats();
569                 for (int j=0; j < formats.length; j++) {
570                     ((DecimalFormat)formats[j]).setParseBigDecimal(true);
571                     ((DecimalFormat)formats[j]).setParseIntegerOnly(true);
572                 }
573 
574                 parsed = mf.parse(from[i], pp);
575 
576                 if (pp.getErrorIndex() != parsePosition2[i][0]) {
577                     errln("Case" + (i+1) +
578                           ": getErrorIndex() returns wrong value. expected:" +
579                           parsePosition2[i][0] + ", got:"+ pp.getErrorIndex() +
580                           " for " + from[i]);
581                 }
582                 if (pp.getIndex() != parsePosition2[i][1]) {
583                     errln("Case" + (i+1) +
584                           ": getIndex() returns wrong value. expected:" +
585                           parsePosition2[i][1] + ", got:"+ pp.getIndex() +
586                           " for " + from[i]);
587                 }
588             }
589             catch(Exception e) {
590                 errln("Unexpected exception: " + e.getMessage());
591             }
592 
593             if (parsePosition2[i][0] == -1) {
594                 checkType(from[i], getType(new BigDecimal(expected2[i])),
595                           getType((Number)parsed[0]));
596                 checkParse(from[i], new BigDecimal(expected2[i]),
597                            (Number)parsed[0]);
598             }
599         }
600     }
601 
602     static final String[] from3 = {
603         "12,345,678,901,234,567,890.98765432109876543210987654321",
604         "-12,345,678,901,234,567,890.98765432109876543210987654321",
605         "9,876,543,210,987,654,321,098,765,432,109,876,543,210",
606         "-9,876,543,210,987,654,321,098,765,432,109,876,543,210",
607         "1234556790000E-8",
608     };
609     static final String[] expected3 = {
610         "12345678901234567890",
611         "-12345678901234567890",
612         "9876543210987654321098765432109876543210",
613         "-9876543210987654321098765432109876543210",
614         "12345.56790000",
615     };
616     static final int[][] parsePosition3 = {     // {errorIndex, index}
617         {-1, 26},
618         {-1, 27},
619         {-1, 53},
620         {-1, 54},
621         {-1, 16},
622     };
623 
624     /**
625      * Test for DecimalFormat: setParseIntegerOnly(true)
626      */
627     void test_Parse_in_DecimalFormat_ParseIntegerOnly() {

628         DecimalFormat df = (DecimalFormat)NumberFormat.getIntegerInstance();
629         df.setParseBigDecimal(true);
630 
631         for (int i=0; i < from3.length; i++) {
632             pp = new ParsePosition(0);
633             Number parsed = null;
634 
635             try {
636                 parsed = df.parse(from3[i], pp);
637 
638                 if (pp.getErrorIndex() != parsePosition3[i][0]) {
639                     errln("Case" + (i+1) +
640                           ": getErrorIndex() returns wrong value. expected:" +
641                           parsePosition3[i][0] + ", got:"+ pp.getErrorIndex() +
642                           " for " + from3[i]);
643                 }
644                 if (pp.getIndex() != parsePosition3[i][1]) {
645                     errln("Case" + (i+1) +
646                           ": getIndex() returns wrong value. expected:" +
647                           parsePosition3[i][1] + ", got:"+ pp.getIndex() +
648                           " for " + from3[i]);
649                 }
650             }
651             catch(Exception e) {
652                 errln("Unexpected exception: " + e.getMessage());
653             }
654 
655             if (parsePosition3[i][0] == -1) {
656                 checkType(from3[i], getType(new BigDecimal(expected3[i])),
657                           getType(parsed));
658                 checkParse(from3[i], new BigDecimal(expected3[i]), parsed);
659             }
660         }
661     }
662 
663     protected void check(String from, Number to) {
664         pp = new ParsePosition(0);
665         try {
666             parsed = df.parse(from, pp);
667         }
668         catch(Exception e) {
669             exceptionOccurred = true;
670             errln(e.getMessage());
671         }
672         if (!exceptionOccurred) {
673             checkParse(from, to, parsed);
674             checkType(from, getType(to), getType(parsed));
675             checkParsePosition(from, from.length(), pp.getIndex());
676         }
677     }
678 
679     private void checkParse(String orig, Number expected, Number got) {
680         if (!expected.equals(got)) {
681             errln("Parsing... failed." +
682                   "\n   original: " + orig +
683                   "\n   parsed:   " + got +
684                   "\n   expected: " + expected + "\n");
685         }
686     }
687 
688     private void checkType(String orig, String expected, String got) {
689         if (!expected.equals(got)) {
690             errln("Parsing... unexpected Class returned." +
691                   "\n   original: " + orig +
692                   "\n   got:      " + got +
693                   "\n   expected: " + expected + "\n");
694         }
695     }
696 
697     private void checkParsePosition(String orig, int expected, int got) {
698         if (expected != got) {
699             errln("Parsing... wrong ParsePosition returned." +
700                   "\n   original: " + orig +
701                   "\n   got:      " + got +
702                   "\n   expected: " + expected + "\n");
703         }
704     }
705 
706     private String getType(Number number) {
707         return number.getClass().getName();
708     }
709 }

  1 /*
  2  * Copyright (c) 2003, 2023, 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 4018937 8008577
 27  * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected.
 28  * @run junit/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalParse

 29  */
 30 
 31 import java.math.BigDecimal;
 32 import java.text.*;
 33 import java.util.*;
 34 
 35 import org.junit.jupiter.api.Test;
 36 import org.junit.jupiter.api.BeforeAll;
 37 
 38 import static org.junit.jupiter.api.Assertions.fail;
 39 
 40 public class BigDecimalParse {
 41 
 42     // Change JVM default Locale
 43     @BeforeAll
 44     static void initAll() {
 45         Locale.setDefault(Locale.US);

 46     }
 47 
 48 
 49     static final String nonsep_int =
 50         "123456789012345678901234567890123456789012345678901234567890" +
 51         "123456789012345678901234567890123456789012345678901234567890" +
 52         "123456789012345678901234567890123456789012345678901234567890" +
 53         "123456789012345678901234567890123456789012345678901234567890" +
 54         "123456789012345678901234567890123456789012345678901234567890" +
 55         "123456789012345678901234567890123456789012345678901234567890";
 56 
 57     static final String sep_int =
 58         "123,456,789,012,345,678,901,234,567,890," +
 59         "123,456,789,012,345,678,901,234,567,890," +
 60         "123,456,789,012,345,678,901,234,567,890," +
 61         "123,456,789,012,345,678,901,234,567,890," +
 62         "123,456,789,012,345,678,901,234,567,890," +
 63         "123,456,789,012,345,678,901,234,567,890," +
 64         "123,456,789,012,345,678,901,234,567,890," +
 65         "123,456,789,012,345,678,901,234,567,890," +
 66         "123,456,789,012,345,678,901,234,567,890," +
 67         "123,456,789,012,345,678,901,234,567,890," +
 68         "123,456,789,012,345,678,901,234,567,890," +

 91         "000,000,000,000,000,000,000,000,000,000";
 92 
 93     static final String fra =
 94         "012345678901234567890123456789012345678901234567890123456789" +
 95         "012345678901234567890123456789012345678901234567890123456789" +
 96         "012345678901234567890123456789012345678901234567890123456789" +
 97         "012345678901234567890123456789012345678901234567890123456789" +
 98         "012345678901234567890123456789012345678901234567890123456789" +
 99         "012345678901234567890123456789012345678901234567890123456789";
100 
101 
102     Number parsed = null;
103     ParsePosition pp;
104     boolean exceptionOccurred;
105     String msg;
106     DecimalFormat df;
107 
108     /**
109      * Test for normal big numbers which have the fraction part
110      */
111     @Test
112     public void test_Parse_in_DecimalFormat_BigDecimal() {
113         df = new DecimalFormat();
114         df.setParseBigDecimal(true);
115 
116         // From: 1234...7890.012...789
117         // To:   BigDecimal 1234...7890.012...789
118         check(nonsep_int + "." + fra, new BigDecimal(nonsep_int + "." + fra));
119 
120         // From: -1,234...7,890.012...789
121         // To:   BigDecimal -1234...7890.012...789
122         check("-" + sep_int    + "." + fra,
123               new BigDecimal("-" + nonsep_int + "." + fra));
124 
125         // From: 000...0000.0...0
126         // To:   BigDecimal 0E-360
127         check(nonsep_zero + "." + nonsep_zero,
128               new BigDecimal(nonsep_zero + "." + nonsep_zero));
129 
130         // From: 0.000...0000123...789E370
131         // To:   BigDecimal 0.0123...789
132         check("0.0000000000" + nonsep_zero + fra + "E370",

134 
135         // From: 0.1123...890E-360
136         // To:   BigDecimal 1.123...890E-361
137         check("0.1" + nonsep_int + "E-360",
138               new BigDecimal("0.1" + nonsep_int + "E-360"));
139 
140         // From: 000...0000.0...0123...7890
141         // To:   BigDecimal 1.234...890E-361
142         check(nonsep_zero + "." + nonsep_zero + nonsep_int,
143               new BigDecimal(nonsep_zero + "." + nonsep_zero + nonsep_int));
144 
145         // From: 0.123...890E360
146         // To:   BigDecimal 123...890
147         check("0." + nonsep_int + "E360",
148               new BigDecimal("0." + nonsep_int + "E360"));
149     }
150 
151     /**
152      * Test for normal big numbers which have the fraction part with multiplier
153      */
154     @Test
155     public void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() {
156         df = new DecimalFormat();
157         df.setParseBigDecimal(true);
158 
159         // From: 250,0...0,000.000...000
160         // To:   1000...0000.000...000
161         df.setMultiplier(250000000);
162         check("250,000,000," + sep_zero + "." + nonsep_zero,
163               new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
164 
165         // From: -250,0...0,000.000...000
166         // To:   -1000...0000.000...000
167         check("-250,000,000," + sep_zero + "." + nonsep_zero,
168               new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
169 
170         // From: 250,0...0,000.000...000
171         // To:   -1000...0000.000...000
172         df.setMultiplier(-250000000);
173         check("250,000,000," + sep_zero + "." + nonsep_zero,
174               new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
175 

177         // To:   1000...0000.000...000
178         check("-250,000,000," + sep_zero + "." + nonsep_zero,
179               new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
180 
181         // Confirm that ArithmeticException is handled properly
182         // From: 1000.000
183         // To:   333.333
184         df.setMultiplier(3);
185         check("1000.000", new BigDecimal("333.333"));
186 
187         // Confirm that ArithmeticException is handled properly
188         // From: 10000.0000
189         // To:   303.0303
190         df.setMultiplier(33);
191         check("10000.0000", new BigDecimal("303.0303"));
192     }
193 
194     /**
195      * Test for division by zero (BigDecimal)
196      */
197     @Test
198     public void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() {
199         df = new DecimalFormat();
200         df.setParseBigDecimal(true);
201         df.setMultiplier(0);
202 
203         // From: 1000.000
204         // To:   Double.POSITIVE_INFINITY
205         check("1000.000", Double.POSITIVE_INFINITY);
206 
207         // From: -1000
208         // To:   Double.NEGATIVE_INFINITY
209         check("-1000", Double.NEGATIVE_INFINITY);
210 
211         // From: -0.00
212         // To:   Double.NaN
213         check("-0.00", Double.NaN);
214     }
215 
216     /**
217      * Test for division by zero (Double)
218      */
219     @Test
220     public void test_Parse_in_DecimalFormat_Double_DivisionByZero() {
221         df = new DecimalFormat();
222         df.setParseBigDecimal(false);
223         df.setMultiplier(0);
224 
225         // From: 1000.000
226         // To:   Double.POSITIVE_INFINITY
227         check("1000.000", Double.POSITIVE_INFINITY);
228 
229         // From: -1000.000
230         // To:   Double.NEGATIVE_INFINITY
231         check("-1000.000", Double.NEGATIVE_INFINITY);
232 
233         // From: 0.0
234         // To:   Double.NaN
235         check("0.0", Double.NaN);
236 
237         // From: -0.0 (Double)
238         // To:   Double.NaN
239         check("-0.0", Double.NaN);
240 
241         // From: Double.NaN
242         // To:   Double.NaN
243         check("\ufffd", Double.NaN);
244 
245         // From: Double.POSITIVE_INFINITY
246         // To:   Double.NaN
247         check("\u221e", Double.POSITIVE_INFINITY);
248 
249         // From: Double.NEGATIVE_INFINITY
250         // To:   Double.NaN
251         check("-\u221e", Double.NEGATIVE_INFINITY);
252     }
253 
254     /**
255      * Test for division by zero (Long)
256      */
257     @Test
258     public void test_Parse_in_DecimalFormat_Long_DivisionByZero() {
259         df = new DecimalFormat();
260         df.setParseBigDecimal(false);
261         df.setMultiplier(0);
262 
263         // From: 1000
264         // To:   Double.POSITIVE_INFINITY
265         check("1000", Double.POSITIVE_INFINITY);
266 
267         // From: -1000
268         // To:   Double.NEGATIVE_INFINITY
269         check("-1000", Double.NEGATIVE_INFINITY);
270 
271         // From: -000 (Long)
272         // To:   Double.NaN
273         check("-000", Double.NaN);
274     }
275 
276     /**
277      * Test for normal big numbers which don't have the fraction part
278      */
279     @Test
280     public void test_Parse_in_DecimalFormat_BigInteger() {
281         df = new DecimalFormat();
282         df.setParseBigDecimal(true);
283 
284         // From: 123...890
285         // To:   BigDecimal 123...890
286         check(nonsep_int + nonsep_int, new BigDecimal(nonsep_int + nonsep_int));
287 
288         // From: 123,4...7,890
289         // To:   BigDecimal 1234...7890
290         check(sep_int + "," + sep_int, new BigDecimal(nonsep_int + nonsep_int));
291 
292         // From: -000...000123...890
293         // To:   BigDecimal -123...890
294         check("-" + nonsep_zero + nonsep_int, new BigDecimal("-" + nonsep_int));
295 
296         // From: -000,0...0,000,123,4...7,890
297         // To:   BigDecimal -123...890
298         check("-" + sep_zero + "," + sep_int, new BigDecimal("-" + nonsep_int));
299     }
300 
301     /**
302      * Test for normal big numbers which don't have the fraction part with
303      * multiplier
304      */
305     @Test
306     public void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() {
307         df = new DecimalFormat();
308         df.setParseBigDecimal(true);
309 
310         // From: 250,0...0,000
311         // To:   1000...0000
312         df.setMultiplier(250000000);
313         check("250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
314 
315         // From: -250,0...0,000
316         // To:   -1000...0000
317         check("-250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
318 
319         // From: 250,0...0,000
320         // To:   -1000...0000
321         df.setMultiplier(-250000000);
322         check("250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
323 
324         // From: -250,0...0,000
325         // To:   1000...0000
326         check("-250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
327 
328         // From: 250,0...0,000E-360
329         // To:   -1000...0000.000...000
330         check("250,000,000," + sep_zero + "," + sep_zero + "E-360",
331               new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
332 
333         // Confirm that a division which results in a irrational number is done
334         // properly
335         // From: 1000
336         // To:   333
337         df.setMultiplier(3);
338         check("1000", new BigDecimal("333"));
339     }
340 
341     /**
342      * Test for special numbers
343      *    Double.NaN
344      *    Double.POSITIVE_INFINITY
345      *    Double.NEGATIVE_INFINITY
346      */
347     @Test
348     public void test_Parse_in_DecimalFormat_SpecialNumber() {
349         df = new DecimalFormat();
350         df.setParseBigDecimal(true);
351 
352         String[] numbers = {
353             "0", "0.0", "25", "25.0", "25.5", "\u221e", "\ufffd",
354             "-0", "-0.0", "-25", "-25.0", "-25.5", "-\u221e",
355         };
356         int multipliers[] = {5, -5};
357         Number[][] expected = {
358             {
359                 new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
360                 new BigDecimal("5.0"), new BigDecimal("5.1"),
361                 Double.POSITIVE_INFINITY, Double.NaN,
362                 new BigDecimal("0"), new BigDecimal("0.0"),
363                 new BigDecimal("-5"), new BigDecimal("-5.0"),
364                 new BigDecimal("-5.1"),
365                 Double.NEGATIVE_INFINITY, Double.NaN,
366             },
367             {
368                 new BigDecimal("0"), new BigDecimal("0.0"),
369                 new BigDecimal("-5"), new BigDecimal("-5.0"),
370                 new BigDecimal("-5.1"),
371                 Double.NEGATIVE_INFINITY, Double.NaN,
372                 new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
373                 new BigDecimal("5.0"), new BigDecimal("5.1"),
374                 Double.POSITIVE_INFINITY,
375             },
376         };
377 
378         for (int i = 0; i < multipliers.length; i++) {
379             df.setMultiplier(multipliers[i]);
380             for (int j = 0; j < numbers.length; j++) {
381                 check(String.valueOf(numbers[j]), expected[i][j]);
382             }
383         }
384     }
385 
386     /**
387      * Test for special numbers
388      */
389     @Test
390     public void test_Parse_in_DecimalFormat_Other() {
391         df = new DecimalFormat();
392         df.setParseBigDecimal(true);
393 
394         String[] numbers = {
395             "-9223372036854775808",     // Long.MIN_VALUE
396         };
397         int multipliers[] = {1, -1};
398         String[][] expected = {
399             {"-9223372036854775808"},   // Long.MIN_VALUE
400             {"9223372036854775808"},    // Long.MAX_VALUE+1 = abs(MIN_VALUE)
401         };
402 
403         for (int i = 0; i < multipliers.length; i++) {
404             df.setMultiplier(multipliers[i]);
405             for (int j = 0; j < numbers.length; j++) {
406                 check(String.valueOf(numbers[j]),
407                       new BigDecimal(expected[i][j]));
408             }
409         }
410     }

464 
465         "9876543210987654321098765432109876543210",
466         "-9876543210987654321098765432109876543210",
467         "9.876543210987654321098765432109876543210E44",
468         "-98765432109876543210987654321098765.43210",
469         "9876543210987654321098765432109876543210.00",
470         "-9876543210987654321098765432109876543210.00",
471         "9876543210987654321098765432109876543210.12",
472         "-9876543210987654321098765432109876543210.12",
473         "9876543210987654321098765432109876543210",
474         "-9876543210987654321098765432109876543210.00000000000000000000",
475     };
476     static final int[] parsePosition1 = {
477         60, 61, 61, 63, 64, 65, 64, 65,
478         57, 58, 59, 61, 61, 63, 60, 61, 54, 88,
479     };
480 
481     /**
482      * Test for MessageFormat: setParseIntegerOnly(false)
483      */
484     @Test
485     public void test_Parse_in_MessageFormat_NotParseIntegerOnly() {
486         for (int i=0; i < patterns.length; i++) {
487             pp = new ParsePosition(0);
488             Object[] parsed = null;
489 
490             try {
491                 MessageFormat mf = new MessageFormat(patterns[i]);
492                 Format[] formats = mf.getFormats();
493                 for (int j=0; j < formats.length; j++) {
494                     ((DecimalFormat)formats[j]).setParseBigDecimal(true);
495                 }
496 
497                 parsed = mf.parse(from[i], pp);
498 
499                 if (pp.getErrorIndex() != -1) {
500                     fail("Case" + (i+1) +
501                           ": getErrorIndex() returns wrong value. expected:-1, got:"+
502                           pp.getErrorIndex() + " for " + from[i]);
503                 }
504                 if (pp.getIndex() != parsePosition1[i]) {
505                     fail("Case" + (i+1) +
506                           ": getIndex() returns wrong value. expected:" +
507                           parsePosition1[i] + ", got:"+ pp.getIndex() +
508                           " for " + from[i]);
509                 }
510             }
511             catch(Exception e) {
512                 fail("Unexpected exception: " + e.getMessage());
513             }
514 
515             checkType(from[i], getType(new BigDecimal(expected1[i])),
516                       getType((Number)parsed[0]));
517             checkParse(from[i], new BigDecimal(expected1[i]),
518                        (Number)parsed[0]);
519         }
520     }
521 
522     static final String[] expected2 = { // isParseIntegerOnly() == true
523         "12345678901234567890",
524         "-12345678901234567890",
525         "12345678901234567890",
526         "-12345678901234567890",
527         "12345678901234567890",
528         "-12345678901234567890",
529         "0",
530         "0",
531 
532         "9876543210987654321098765432109876543210",

551         {2, 0},         // parsing stopped at '(' because cannot find ')'
552         {2, 0},         // parsing stopped at the first numeric
553                         // because cannot find '%'
554         {2, 0},         // parsing stopped at the first numeric
555                         // because cannot find '%'
556         {28, 0},        // parsing stopped at '.'
557         {29, 0},        // parsing stopped at '.'
558 
559         {-1, 57}, {-1, 58}, {-1, 59}, {-1, 61},
560         {56, 0},        // parsing stopped at '.'
561                         // because cannot find '%'
562         {2, 0},         // parsing stopped at '(' because cannot find ')'
563         {-1, 60}, {-1, 61},
564         {28, 0},        // parsing stopped at '.'
565         {-1, 88},
566     };
567 
568     /**
569      * Test for MessageFormat: setParseIntegerOnly(true)
570      */
571     @Test
572     public void test_Parse_in_MessageFormat_ParseIntegerOnly() {
573         for (int i=0; i < patterns.length; i++) {
574             pp = new ParsePosition(0);
575             Object[] parsed = null;
576 
577             try {
578                 MessageFormat mf = new MessageFormat(patterns[i]);
579                 Format[] formats = mf.getFormats();
580                 for (int j=0; j < formats.length; j++) {
581                     ((DecimalFormat)formats[j]).setParseBigDecimal(true);
582                     ((DecimalFormat)formats[j]).setParseIntegerOnly(true);
583                 }
584 
585                 parsed = mf.parse(from[i], pp);
586 
587                 if (pp.getErrorIndex() != parsePosition2[i][0]) {
588                     fail("Case" + (i+1) +
589                           ": getErrorIndex() returns wrong value. expected:" +
590                           parsePosition2[i][0] + ", got:"+ pp.getErrorIndex() +
591                           " for " + from[i]);
592                 }
593                 if (pp.getIndex() != parsePosition2[i][1]) {
594                     fail("Case" + (i+1) +
595                           ": getIndex() returns wrong value. expected:" +
596                           parsePosition2[i][1] + ", got:"+ pp.getIndex() +
597                           " for " + from[i]);
598                 }
599             }
600             catch(Exception e) {
601                 fail("Unexpected exception: " + e.getMessage());
602             }
603 
604             if (parsePosition2[i][0] == -1) {
605                 checkType(from[i], getType(new BigDecimal(expected2[i])),
606                           getType((Number)parsed[0]));
607                 checkParse(from[i], new BigDecimal(expected2[i]),
608                            (Number)parsed[0]);
609             }
610         }
611     }
612 
613     static final String[] from3 = {
614         "12,345,678,901,234,567,890.98765432109876543210987654321",
615         "-12,345,678,901,234,567,890.98765432109876543210987654321",
616         "9,876,543,210,987,654,321,098,765,432,109,876,543,210",
617         "-9,876,543,210,987,654,321,098,765,432,109,876,543,210",
618         "1234556790000E-8",
619     };
620     static final String[] expected3 = {
621         "12345678901234567890",
622         "-12345678901234567890",
623         "9876543210987654321098765432109876543210",
624         "-9876543210987654321098765432109876543210",
625         "12345.56790000",
626     };
627     static final int[][] parsePosition3 = {     // {errorIndex, index}
628         {-1, 26},
629         {-1, 27},
630         {-1, 53},
631         {-1, 54},
632         {-1, 16},
633     };
634 
635     /**
636      * Test for DecimalFormat: setParseIntegerOnly(true)
637      */
638     @Test
639     public void test_Parse_in_DecimalFormat_ParseIntegerOnly() {
640         DecimalFormat df = (DecimalFormat)NumberFormat.getIntegerInstance();
641         df.setParseBigDecimal(true);
642 
643         for (int i=0; i < from3.length; i++) {
644             pp = new ParsePosition(0);
645             Number parsed = null;
646 
647             try {
648                 parsed = df.parse(from3[i], pp);
649 
650                 if (pp.getErrorIndex() != parsePosition3[i][0]) {
651                     fail("Case" + (i+1) +
652                           ": getErrorIndex() returns wrong value. expected:" +
653                           parsePosition3[i][0] + ", got:"+ pp.getErrorIndex() +
654                           " for " + from3[i]);
655                 }
656                 if (pp.getIndex() != parsePosition3[i][1]) {
657                     fail("Case" + (i+1) +
658                           ": getIndex() returns wrong value. expected:" +
659                           parsePosition3[i][1] + ", got:"+ pp.getIndex() +
660                           " for " + from3[i]);
661                 }
662             }
663             catch(Exception e) {
664                 fail("Unexpected exception: " + e.getMessage());
665             }
666 
667             if (parsePosition3[i][0] == -1) {
668                 checkType(from3[i], getType(new BigDecimal(expected3[i])),
669                           getType(parsed));
670                 checkParse(from3[i], new BigDecimal(expected3[i]), parsed);
671             }
672         }
673     }
674 
675     protected void check(String from, Number to) {
676         pp = new ParsePosition(0);
677         try {
678             parsed = df.parse(from, pp);
679         }
680         catch(Exception e) {
681             exceptionOccurred = true;
682             fail(e.getMessage());
683         }
684         if (!exceptionOccurred) {
685             checkParse(from, to, parsed);
686             checkType(from, getType(to), getType(parsed));
687             checkParsePosition(from, from.length(), pp.getIndex());
688         }
689     }
690 
691     private void checkParse(String orig, Number expected, Number got) {
692         if (!expected.equals(got)) {
693             fail("Parsing... failed." +
694                   "\n   original: " + orig +
695                   "\n   parsed:   " + got +
696                   "\n   expected: " + expected + "\n");
697         }
698     }
699 
700     private void checkType(String orig, String expected, String got) {
701         if (!expected.equals(got)) {
702             fail("Parsing... unexpected Class returned." +
703                   "\n   original: " + orig +
704                   "\n   got:      " + got +
705                   "\n   expected: " + expected + "\n");
706         }
707     }
708 
709     private void checkParsePosition(String orig, int expected, int got) {
710         if (expected != got) {
711             fail("Parsing... wrong ParsePosition returned." +
712                   "\n   original: " + orig +
713                   "\n   got:      " + got +
714                   "\n   expected: " + expected + "\n");
715         }
716     }
717 
718     private String getType(Number number) {
719         return number.getClass().getName();
720     }
721 }
< prev index next >