| /* |
| * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* |
| * @test |
| * @bug 4103117 4331084 4488017 4490929 6255285 6268365 |
| * @summary Tests the BigDecimal string constructor. |
| */ |
| |
| import java.math.*; |
| import java.util.Random; |
| |
| public class StringConstructor { |
| |
| private static int seed = new Random().nextInt(); |
| private static Random rnd = new Random(seed); |
| |
| public static void main(String[] args) throws Exception { |
| constructWithError(""); |
| constructWithError("+"); |
| constructWithError("-"); |
| constructWithError("+e"); |
| constructWithError("-e"); |
| constructWithError("e+"); |
| constructWithError("1.-0"); |
| constructWithError(".-123"); |
| constructWithError("-"); |
| constructWithError("--1.1"); |
| constructWithError("-+1.1"); |
| constructWithError("+-1.1"); |
| constructWithError("1-.1"); |
| constructWithError("1+.1"); |
| constructWithError("1.111+1"); |
| constructWithError("1.111-1"); |
| constructWithError("11.e+"); |
| constructWithError("11.e-"); |
| constructWithError("11.e+-"); |
| constructWithError("11.e-+"); |
| constructWithError("11.e-+1"); |
| constructWithError("11.e+-1"); |
| |
| // Range checks |
| constructWithError("1e"+Integer.MIN_VALUE); |
| constructWithError("10e"+Integer.MIN_VALUE); |
| constructWithError("0.01e"+Integer.MIN_VALUE); |
| constructWithError("1e"+((long)Integer.MIN_VALUE-1)); |
| constructWithError("1e"+((long)Integer.MAX_VALUE + 1)); |
| |
| leadingExponentZeroTest(); |
| nonAsciiZeroTest(); |
| |
| // Roundtrip tests |
| for (int i=0; i<100; i++) { |
| int size = rnd.nextInt(100) + 1; |
| BigInteger bi = new BigInteger(size, rnd); |
| if (rnd.nextBoolean()) |
| bi = bi.negate(); |
| int decimalLength = bi.toString().length(); |
| int scale = rnd.nextInt(decimalLength); |
| BigDecimal bd = new BigDecimal(bi, scale); |
| String bdString = bd.toString(); |
| // System.err.println("bi" + bi.toString() + "\tscale " + scale); |
| // System.err.println("bd string: " + bdString); |
| BigDecimal bdDoppel = new BigDecimal(bdString); |
| if (!bd.equals(bdDoppel)) { |
| System.err.println("Random number seed = " + seed); |
| System.err.println("bd string: scale: " + bd.scale() + |
| "\t" + bdString); |
| System.err.println("bd doppel: scale: " + bdDoppel.scale() + |
| "\t" + bdDoppel.toString()); |
| throw new RuntimeException("String constructor failure."); |
| } |
| } |
| } |
| |
| |
| /* |
| * Verify precision is set properly if the significand has |
| * non-ASCII leading zeros. |
| */ |
| private static void nonAsciiZeroTest() { |
| String values[] = { |
| "00004e5", |
| "\u0660\u0660\u0660\u06604e5", |
| }; |
| |
| BigDecimal expected = new BigDecimal("4e5"); |
| |
| for(String s : values) { |
| BigDecimal tmp = new BigDecimal(s); |
| // System.err.println("Testing " + s); |
| if (! expected.equals(tmp) || tmp.precision() != 1) { |
| System.err.println("Bad conversion of " + s + "got " + |
| tmp + "precision = " + tmp.precision()); |
| throw new RuntimeException("String constructor failure."); |
| } |
| } |
| |
| } |
| |
| private static void leadingExponentZeroTest() { |
| BigDecimal twelve = new BigDecimal("12"); |
| BigDecimal onePointTwo = new BigDecimal("1.2"); |
| |
| String start = "1.2e0"; |
| String end = "1"; |
| String middle = ""; |
| |
| // Test with more excess zeros than the largest number of |
| // decimal digits needed to represent a long |
| int limit = ((int)Math.log10(Long.MAX_VALUE)) + 6; |
| for(int i = 0; i < limit; i++, middle += "0") { |
| String t1 = start + middle; |
| String t2 = t1 + end; |
| |
| // System.out.println(i + "\t" + t1 + "\t" + t2); |
| testString(t1, onePointTwo); |
| testString(t2, twelve); |
| } |
| } |
| |
| private static void testString(String s, BigDecimal expected) { |
| testString0(s, expected); |
| testString0(switchZero(s), expected); |
| } |
| |
| private static void testString0(String s, BigDecimal expected) { |
| if (!expected.equals(new BigDecimal(s))) |
| throw new RuntimeException(s + " is not equal to " + expected); |
| } |
| |
| private static String switchZero(String s) { |
| return s.replace('0', '\u0660'); // Arabic-Indic zero |
| } |
| |
| private static void constructWithError(String badString) { |
| try { |
| BigDecimal d = new BigDecimal(badString); |
| throw new RuntimeException(badString + " accepted"); |
| } catch(NumberFormatException e) { |
| } |
| } |
| } |