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 * @summary Confirm that the negative multiplier works as expected.
27 * @bug 4833877
28 */
29
30import java.math.*;
31import java.text.*;
32import java.util.*;
33
34public class Bug4833877 {
35
36    static DecimalFormat df;
37
38    static boolean err = false;
39
40    public static void main(String[] args) throws Exception {
41
42        Locale defaultLoc = Locale.getDefault();
43        Locale.setDefault(Locale.US);
44
45        /* ================================================================ */
46
47        df = new DecimalFormat();
48        df.setMaximumFractionDigits(50);
49        df.setMultiplier(4);
50
51        /*
52         * Test for double/Double
53         */
54        checkFormat(252.5252525252525, "1,010.10101010101");
55        checkParse("-1,010.10101010101", -252.5252525252525);
56
57        checkFormat(-2222.2222, "-8,888.8888");
58        checkParse("8888.8888", 2222.2222);
59
60        /*
61         * Test for long/Long
62         */
63        checkFormat(1000L, "4,000");
64        checkParse("-4,000", -1000L);
65
66        checkFormat(-250L, "-1,000");
67        checkParse("1000", 250L);
68
69        /* ---------------------------------------------------------------- */
70
71        df.setParseBigDecimal(true);
72
73        /*
74         * Test for BigDecimal
75         */
76        checkFormat(new BigDecimal("22222.222222222222222222222"),
77                    "88,888.888888888888888888888");
78        checkParse("-88,888.888888888888888888888",
79                    new BigDecimal("-22222.222222222222222222222"));
80
81        checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
82                    "-4,444,444,444,444,444,444.444444444444444444");
83        checkParse("4444444444444444444.444444444444444444",
84                    new BigDecimal("1111111111111111111.111111111111111111"));
85
86        /*
87         * Test for BigInteger
88         */
89        checkFormat(new BigInteger("22222222222222222222222222"),
90                    "88,888,888,888,888,888,888,888,888");
91        checkParse("-88,888,888,888,888,888,888,888,888",
92                    new BigDecimal("-22222222222222222222222222"));
93
94        checkFormat(new BigInteger("-1111111111111111111111111"),
95                    "-4,444,444,444,444,444,444,444,444");
96        checkParse("4444444444444444444444444",
97                    new BigDecimal("1111111111111111111111111"));
98
99        /* ---------------------------------------------------------------- */
100
101        df.setParseBigDecimal(false);
102        df.setMultiplier(-4);
103
104        /*
105         * Test for double/Double
106         */
107        checkFormat(252.5252525252525, "-1,010.10101010101");
108        checkParse("-1,010.10101010101", 252.5252525252525);
109
110        checkFormat(-2222.2222, "8,888.8888");
111        checkParse("8888.8888", -2222.2222);
112
113        /*
114         * Test for long/Long
115         */
116        checkFormat(1000L, "-4,000");
117        checkParse("-4,000", 1000L);
118
119        checkFormat(-250L, "1,000");
120        checkParse("1000", -250L);
121
122        /* ---------------------------------------------------------------- */
123
124        df.setParseBigDecimal(true);
125
126        /*
127         * Test for BigDecimal
128         */
129        checkFormat(new BigDecimal("22222.222222222222222222222"),
130                    "-88,888.888888888888888888888");
131        checkParse("-88,888.888888888888888888888",
132                    new BigDecimal("22222.222222222222222222222"));
133
134        checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
135                   "4,444,444,444,444,444,444.444444444444444444");
136        checkParse("4444444444444444444.444444444444444444",
137                    new BigDecimal("-1111111111111111111.111111111111111111"));
138
139        /*
140         * Test for BigInteger
141         */
142        checkFormat(new BigInteger("22222222222222222222222222"),
143                    "-88,888,888,888,888,888,888,888,888");
144        checkParse("-88,888,888,888,888,888,888,888,888",
145                    new BigDecimal("22222222222222222222222222"));
146
147        checkFormat(new BigInteger("-1111111111111111111111111"),
148                   "4,444,444,444,444,444,444,444,444");
149        checkParse("4444444444444444444444444",
150                    new BigDecimal("-1111111111111111111111111"));
151
152        /* ---------------------------------------------------------------- */
153
154        df.setParseBigDecimal(false);
155        df.setMultiplier(-3);
156
157        /*
158         * Test for double/Double
159         */
160        checkFormat(3333.3333333, "-9,999.9999999");
161        checkParse("-10,000.00000000000", 3333.3333333333335);// rounding error
162
163        df.setParseIntegerOnly(true);
164        checkFormat(-3333.3333333, "9,999.9999999");
165        checkParse("10,000.00000000000", -3333L);
166        df.setParseIntegerOnly(false);
167        checkFormat(-3333.3333333, "9,999.9999999");
168        checkParse("10,000.00000000000", -3333.3333333333335);// rounding error
169
170        /*
171         * Test for long/Long
172         */
173        checkFormat(3333L, "-9,999");
174        df.setParseIntegerOnly(true);
175        checkParse("-10,000", 3333L);
176        df.setParseIntegerOnly(false);
177        checkParse("-10000", 3333.3333333333335);// rounding error
178
179        checkFormat(-3333L, "9,999");
180        df.setParseIntegerOnly(true);
181        checkParse("10,000", -3333L);
182        df.setParseIntegerOnly(false);
183        checkParse("10000", -3333.3333333333335);// rounding error
184
185        /* ---------------------------------------------------------------- */
186
187        df.setParseBigDecimal(true);
188
189        /*
190         * Test for BigDecimal
191         */
192        checkFormat(new BigDecimal("33333.333333333333333333333"),
193                    "-99,999.999999999999999999999");
194        checkParse("-100,000.000000000000000000000",
195                    new BigDecimal("33333.333333333333333333333"));
196
197        checkFormat(new BigDecimal("-33333.333333333333333333333"),
198                    "99,999.999999999999999999999");
199        checkParse("100,000.000000000000000000000",
200                    new BigDecimal("-33333.333333333333333333333"));
201
202        /*
203         * Test for BigInteger
204         */
205        checkFormat(new BigInteger("33333333333333333333333333"),
206                    "-99,999,999,999,999,999,999,999,999");
207        checkParse("-100,000,000,000,000,000,000,000,000",
208                    new BigDecimal("33333333333333333333333333"));
209
210        checkFormat(new BigInteger("-33333333333333333333333333"),
211                    "99,999,999,999,999,999,999,999,999");
212        df.setParseIntegerOnly(true);
213        checkParse("100,000,000,000,000,000,000,000,000.000",
214                    new BigDecimal("-33333333333333333333333333"));
215        df.setParseIntegerOnly(false);
216        checkParse("100,000,000,000,000,000,000,000,000.000",
217                    new BigDecimal("-33333333333333333333333333.333"));
218
219        /* ================================================================ */
220
221        df = new DecimalFormat("0.#E0;-0.#E0");
222        df.setMaximumFractionDigits(50);
223        df.setMultiplier(4);
224
225        /*
226         * Test for double/Double
227         */
228        checkFormat(252.5252525252525, "1.01010101010101E3");
229        checkParse("-1.01010101010101E3", -2.525252525252525E2);
230
231        checkFormat(-2222.2222, "-8.8888888E3");
232        checkParse("8888.8888", 2.2222222E3);
233
234        /*
235         * Test for long/Long
236         */
237        checkFormat(1000L, "4E3");
238        checkParse("-4E3", -1000L);
239
240        checkFormat(-250L, "-1E3");
241        checkParse("1000", 250L);
242
243        /* ---------------------------------------------------------------- */
244
245        df.setParseBigDecimal(true);
246
247        /*
248         * Test for BigDecimal
249         */
250
251        checkFormat(new BigDecimal("22222.222222222222222222222"),
252                    "8.8888888888888888888888888E4");
253        checkParse("-8.8888888888888888888888888E4",
254                    new BigDecimal("-2.2222222222222222222222222E4"));
255
256        checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
257                    "-4.444444444444444444444444444444444444E18");
258        checkParse("4444444444444444444.444444444444444444",
259                    new BigDecimal("1111111111111111111.111111111111111111"));
260
261        /*
262         * Test for BigInteger
263         */
264        checkFormat(new BigInteger("22222222222222222222222222"),
265                    "8.8888888888888888888888888E25");
266        checkParse("-8.8888888888888888888888888E25",
267                    new BigDecimal("-22222222222222222222222222"));
268
269        checkFormat(new BigInteger("-1111111111111111111111111"),
270                    "-4.444444444444444444444444E24");
271        checkParse("4444444444444444444444444",
272                    new BigDecimal("1111111111111111111111111"));
273
274        /* ---------------------------------------------------------------- */
275
276        df.setParseBigDecimal(false);
277        df.setMultiplier(-4);
278
279        /*
280         * Test for double/Double
281         */
282        checkFormat(252.5252525252525, "-1.01010101010101E3");
283        checkParse("-1.01010101010101E3", 2.525252525252525E2);
284
285        checkFormat(-2222.2222, "8.8888888E3");
286        checkParse("8888.8888", -2.2222222E3);
287
288        /*
289         * Test for long/Long
290         */
291        checkFormat(1000L, "-4E3");
292        checkParse("-4E3", 1000L);
293
294        checkFormat(-250L, "1E3");
295        checkParse("1000", -250L);
296
297        /* ---------------------------------------------------------------- */
298
299        df.setParseBigDecimal(true);
300
301        /*
302         * Test for BigDecimal
303         */
304
305        checkFormat(new BigDecimal("22222.222222222222222222222"),
306                   "-8.8888888888888888888888888E4");
307        checkParse("-8.8888888888888888888888888E4",
308                    new BigDecimal("2.2222222222222222222222222E4"));
309
310        checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
311                    "4.444444444444444444444444444444444444E18");
312        checkParse("4444444444444444444.444444444444444444",
313                    new BigDecimal("-1111111111111111111.111111111111111111"));
314
315        /*
316         * Test for BigInteger
317         */
318        checkFormat(new BigInteger("22222222222222222222222222"),
319                   "-8.8888888888888888888888888E25");
320        checkParse("-8.8888888888888888888888888E25",
321                    new BigDecimal("22222222222222222222222222"));
322
323        checkFormat(new BigInteger("-1111111111111111111111111"),
324                    "4.444444444444444444444444E24");
325        checkParse("4444444444444444444444444",
326                   new BigDecimal("-1111111111111111111111111"));
327
328        /* ---------------------------------------------------------------- */
329
330        df.setParseBigDecimal(false);
331        df.setMultiplier(-3);
332
333        /*
334         * Test for double/Double
335         */
336        checkFormat(3333.3333333, "-9.9999999999E3");
337        checkParse("-1.00000000000000E3", 3.33333333333333333E2);
338
339        df.setParseIntegerOnly(true);
340        checkFormat(-3333.3333333, "9.9999999999E3");
341        checkParse("10.00000000000000E3",-3L);
342        df.setParseIntegerOnly(false);
343        checkFormat(-3333.3333333, "9.9999999999E3");
344        checkParse("10.00000000000000E3", -3.33333333333333333E3);
345
346        /*
347         * Test for long/Long
348         */
349        checkFormat(3333L, "-9.999E3");
350        df.setParseIntegerOnly(true);
351        checkParse("-1.0E4", 0L);
352        df.setParseIntegerOnly(false);
353        checkParse("-1.0E4", 3333.3333333333335);
354
355        checkFormat(-3333L, "9.999E3");
356        df.setParseIntegerOnly(true);
357        checkParse("10.0E4", -3L);
358        df.setParseIntegerOnly(false);
359        checkParse("10.0E4", -33333.3333333333336);
360
361        /* ---------------------------------------------------------------- */
362
363        df.setParseBigDecimal(true);
364
365        /*
366         * Test for BigDecimal
367         */
368
369        checkFormat(new BigDecimal("333.333333333333333333333333"),
370                   "-9.99999999999999999999999999E2");
371        checkParse("-1.0000000000000000000000000E3",
372                    new BigDecimal("3.333333333333333333333333E2"));
373
374        df.setParseIntegerOnly(true);
375        checkFormat(new BigDecimal("-333.333333333333333333333333"),
376                   "9.99999999999999999999999999E2");
377        checkParse("10.0000000000000000000000000E3",
378                    new BigDecimal("-3"));
379        df.setParseIntegerOnly(false);
380        checkFormat(new BigDecimal("-333.333333333333333333333333"),
381                   "9.99999999999999999999999999E2");
382        checkParse("1.0000000000000000000000000E3",
383                    new BigDecimal("-3.333333333333333333333333E2"));
384
385        /*
386         * Test for BigInteger
387         */
388        checkFormat(new BigInteger("33333333333333333333333333"),
389                    "-9.9999999999999999999999999E25");
390        checkParse("-100000000000000000000000000",
391                    new BigDecimal("33333333333333333333333333"));
392
393        checkFormat(new BigInteger("-33333333333333333333333333"),
394                    "9.9999999999999999999999999E25");
395        df.setParseIntegerOnly(true);
396        checkParse("100000000000000000000000000000",
397                    new BigDecimal("-33333333333333333333333333333"));
398        df.setParseIntegerOnly(false);
399        checkParse("100000000000000000000000000.000",
400                    new BigDecimal("-33333333333333333333333333.333"));
401
402        /* ================================================================ */
403
404        Locale.setDefault(defaultLoc);
405
406        if (err) {
407            throw new RuntimeException("Wrong format/parse with DecimalFormat");
408        }
409    }
410
411    static void checkFormat(Number num, String expected) {
412        String got = df.format(num);
413        if (!got.equals(expected)) {
414            err = true;
415            System.err.println("    DecimalFormat format(" +
416                               num.getClass().getName() +
417                               ") error:" +
418                               "\n\tnumber:     " + num +
419                               "\n\tpattern:    " + df.toPattern() +
420                               "\n\tmultiplier: " + df.getMultiplier() +
421                               "\n\tgot:        " + got +
422                               "\n\texpected:   " + expected);
423        }
424    }
425
426    static void checkParse(String text, Double expected) {
427        Double got = (Double)df.parse(text, new ParsePosition(0));
428        if (!got.equals(expected)) {
429            err = true;
430            System.err.println("    DecimalFormat parse(double) error:" +
431                               "\n\ttext:       " + text +
432                               "\n\tpattern:    " + df.toPattern() +
433                               "\n\tmultiplier: " + df.getMultiplier() +
434                               "\n\tgot:        " + got +
435                               "\n\texpected:   " + expected);
436        }
437    }
438
439    static void checkParse(String text, Long expected) {
440        Long got = (Long)df.parse(text, new ParsePosition(0));
441        if (!got.equals(expected)) {
442            err = true;
443            System.err.println("    DecimalFormat parse(long) error:" +
444                               "\n\ttext:       " + text +
445                               "\n\tpattern:    " + df.toPattern() +
446                               "\n\tmultiplier: " + df.getMultiplier() +
447                               "\n\tgot:        " + got +
448                               "\n\texpected:   " + expected);
449        }
450    }
451
452    static void checkParse(String text, BigDecimal expected) {
453        BigDecimal got = (BigDecimal)df.parse(text, new ParsePosition(0));
454        if (!got.equals(expected)) {
455            err = true;
456            System.err.println("    DecimalFormat parse(BigDecimal) error:" +
457                               "\n\ttext:       " + text +
458                               "\n\tpattern:    " + df.toPattern() +
459                               "\n\tmultiplier: " + df.getMultiplier() +
460                               "\n\tgot:        " + got +
461                               "\n\texpected:   " + expected);
462        }
463    }
464}
465