1 /*
2  * Copyright (c) 2013, 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 import java.util.Random;
25 import jdk.internal.math.FloatingDecimal;
26 
27 /*
28 OldFloatingDecimalForTest
29 
30 public class OldFloatingDecimalForTest {
31   public boolean digitsRoundedUp();
32   public OldFloatingDecimalForTest(double);
33   public OldFloatingDecimalForTest(float);
34   public boolean decimalDigitsExact();
35   public java.lang.String toString();
36   public java.lang.String toJavaFormatString();
37   public void appendTo(java.lang.Appendable);
38   public static OldFloatingDecimalForTest readJavaFormatString(java.lang.String) throws java.lang.NumberFormatException;
39   public strictfp double doubleValue();
40   public strictfp float floatValue();
41 }
42 
43 jdk.internal.math.FloatingDecimal
44 
45 public class jdk.internal.math.FloatingDecimal {
46   public jdk.internal.math.FloatingDecimal();
47   public static java.lang.String toJavaFormatString(double);
48   public static java.lang.String toJavaFormatString(float);
49   public static void appendTo(double, java.lang.Appendable);
50   public static void appendTo(float, java.lang.Appendable);
51   public static double parseDouble(java.lang.String) throws java.lang.NumberFormatException;
52   public static float parseFloat(java.lang.String) throws java.lang.NumberFormatException;
53   public static jdk.internal.math.FloatingDecimal$AbstractD2ABuffer getD2ABuffer(double);
54 }
55 */
56 
57 /**
58  * @test
59  * @bug 7032154
60  * @summary unit tests of FloatingDecimal
61  * @modules java.base/jdk.internal.math
62  * @library /java/lang/Math
63  * @build DoubleConsts FloatConsts
64  * @run main TestFloatingDecimal
65  * @author Brian Burkhalter
66  * @key randomness
67  */
68 public class TestFloatingDecimal {
69     private static enum ResultType {
70         RESULT_EXCEPTION,
71         RESULT_PRINT
72     }
73 
74     private static final ResultType RESULT_TYPE = ResultType.RESULT_PRINT;
75     private static final int NUM_RANDOM_TESTS = 100000;
76 
77     private static final Random RANDOM = new Random();
78 
result(String message)79     private static void result(String message) {
80         switch (RESULT_TYPE) {
81             case RESULT_EXCEPTION:
82                 throw new RuntimeException(message);
83             case RESULT_PRINT:
84                 System.err.println(message);
85                 break;
86             default:
87                 assert false;
88         }
89     }
90 
check(String test, Object expected, Object actual)91     private static int check(String test, Object expected, Object actual) {
92         int failures = 0;
93         if(!actual.equals(expected)) {
94             failures++;
95             result("Test "+test+" expected "+expected+" but obtained "+actual);
96         }
97         return failures;
98     }
99 
testAppendToDouble()100     private static int testAppendToDouble() {
101         System.out.println("  testAppendToDouble");
102         int failures = 0;
103 
104         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
105             double[] d = new double[] {
106                 RANDOM.nextLong(),
107                 RANDOM.nextGaussian(),
108                 RANDOM.nextDouble()*Double.MAX_VALUE
109             };
110             for(int j = 0; j < d.length; j++) {
111                 OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[j]);
112                 StringBuilder sb = new StringBuilder();
113                 ofd.appendTo(sb);
114                 String oldString = sb.toString();
115                 sb = new StringBuilder();
116                 FloatingDecimal.appendTo(d[j], sb);
117                 String newString = sb.toString();
118                 failures += check("testAppendToDouble", oldString, newString);
119             }
120         }
121 
122         return failures;
123     }
124 
testAppendToFloat()125     private static int testAppendToFloat() {
126         System.out.println("  testAppendToFloat");
127         int failures = 0;
128 
129         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
130             float[] f = new float[] {
131                 RANDOM.nextLong(),
132                 (float)RANDOM.nextGaussian(),
133                 RANDOM.nextFloat()*Float.MAX_VALUE
134             };
135             for(int j = 0; j < f.length; j++) {
136                 OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[j]);
137                 StringBuilder sb = new StringBuilder();
138                 ofd.appendTo(sb);
139                 String oldString = sb.toString();
140                 sb = new StringBuilder();
141                 FloatingDecimal.appendTo(f[j], sb);
142                 String newString = sb.toString();
143                 failures += check("testAppendToFloat", oldString, newString);
144             }
145         }
146 
147         return failures;
148     }
149 
testAppendTo()150     private static int testAppendTo() {
151         System.out.println("testAppendTo");
152         int failures = 0;
153 
154         failures += testAppendToDouble();
155         failures += testAppendToFloat();
156 
157         return failures;
158     }
159 
testParseDouble()160     private static int testParseDouble() {
161         System.out.println("  testParseDouble");
162         int failures = 0;
163 
164         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
165             double[] d = new double[] {
166                 RANDOM.nextLong(),
167                 RANDOM.nextGaussian(),
168                 RANDOM.nextDouble()*Double.MAX_VALUE
169             };
170             for(int j = 0; j < d.length; j++) {
171                 OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[j]);
172                 String javaFormatString = ofd.toJavaFormatString();
173                 ofd = OldFloatingDecimalForTest.readJavaFormatString(javaFormatString);
174                 double oldDouble = ofd.doubleValue();
175                 double newDouble = FloatingDecimal.parseDouble(javaFormatString);
176                 failures += check("testParseDouble", oldDouble, newDouble);
177             }
178         }
179 
180         return failures;
181     }
182 
testParseFloat()183     private static int testParseFloat() {
184         System.out.println("  testParseFloat");
185         int failures = 0;
186 
187         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
188             float[] f = new float[] {
189                 RANDOM.nextInt(),
190                 (float)RANDOM.nextGaussian(),
191                 RANDOM.nextFloat()*Float.MAX_VALUE
192             };
193             for(int j = 0; j < f.length; j++) {
194                 OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[j]);
195                 String javaFormatString = ofd.toJavaFormatString();
196                 ofd = OldFloatingDecimalForTest.readJavaFormatString(javaFormatString);
197                 float oldFloat = ofd.floatValue();
198                 float newFloat = FloatingDecimal.parseFloat(javaFormatString);
199                 failures += check("testParseFloat", oldFloat, newFloat);
200             }
201         }
202 
203         return failures;
204     }
205 
testParse()206     private static int testParse() {
207         System.out.println("testParse");
208         int failures = 0;
209 
210         failures += testParseDouble();
211         failures += testParseFloat();
212 
213         return failures;
214     }
215 
testToJavaFormatStringDoubleFixed()216     private static int testToJavaFormatStringDoubleFixed() {
217         System.out.println("    testToJavaFormatStringDoubleFixed");
218         int failures = 0;
219 
220         double[] d = new double [] {
221             -5.9522650387500933e18, // dtoa() fast path
222             0.872989018674569,      // dtoa() fast iterative - long
223             1.1317400099603851e308  // dtoa() slow iterative
224         };
225 
226         for(int i = 0; i < d.length; i++) {
227             OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[i]);
228             failures += check("testToJavaFormatStringDoubleFixed", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(d[i]));
229         }
230 
231         return failures;
232     }
233 
testToJavaFormatStringDoubleRandom()234     private static int testToJavaFormatStringDoubleRandom() {
235         System.out.println("    testToJavaFormatStringDoubleRandom");
236         int failures = 0;
237 
238         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
239             double[] d = new double[] {
240                 RANDOM.nextLong(),
241                 RANDOM.nextGaussian(),
242                 RANDOM.nextDouble()*Double.MAX_VALUE
243             };
244             for(int j = 0; j < d.length; j++) {
245                 OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[j]);
246                 failures += check("testToJavaFormatStringDoubleRandom", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(d[j]));
247             }
248         }
249 
250         return failures;
251     }
252 
testToJavaFormatStringDouble()253     private static int testToJavaFormatStringDouble() {
254         System.out.println("  testToJavaFormatStringDouble");
255         int failures = 0;
256         failures += testToJavaFormatStringDoubleFixed();
257         failures += testToJavaFormatStringDoubleRandom();
258         return failures;
259     }
260 
testToJavaFormatStringFloatFixed()261     private static int testToJavaFormatStringFloatFixed() {
262         System.out.println("    testToJavaFormatStringFloatFixed");
263         int failures = 0;
264 
265         float[] f = new float[] {
266             -9.8784166e8f, // dtoa() fast path
267             0.70443946f,   // dtoa() fast iterative - int
268             1.8254228e37f  // dtoa() slow iterative
269         };
270 
271         for(int i = 0; i < f.length; i++) {
272             OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[i]);
273             failures += check("testToJavaFormatStringFloatFixed", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(f[i]));
274         }
275 
276         return failures;
277     }
278 
testToJavaFormatStringFloatRandom()279     private static int testToJavaFormatStringFloatRandom() {
280         System.out.println("    testToJavaFormatStringFloatRandom");
281         int failures = 0;
282 
283         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
284             float[] f = new float[] {
285                 RANDOM.nextInt(),
286                 (float)RANDOM.nextGaussian(),
287                 RANDOM.nextFloat()*Float.MAX_VALUE
288             };
289             for(int j = 0; j < f.length; j++) {
290                 OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[j]);
291                 failures += check("testToJavaFormatStringFloatRandom", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(f[j]));
292             }
293         }
294 
295         return failures;
296     }
297 
testToJavaFormatStringFloat()298     private static int testToJavaFormatStringFloat() {
299         System.out.println("  testToJavaFormatStringFloat");
300         int failures = 0;
301 
302         failures += testToJavaFormatStringFloatFixed();
303         failures += testToJavaFormatStringFloatRandom();
304 
305         return failures;
306     }
307 
testToJavaFormatString()308     private static int testToJavaFormatString() {
309         System.out.println("testToJavaFormatString");
310         int failures = 0;
311 
312         failures += testToJavaFormatStringDouble();
313         failures += testToJavaFormatStringFloat();
314 
315         return failures;
316     }
317 
main(String[] args)318     public static void main(String[] args) {
319         int failures = 0;
320 
321         failures += testAppendTo();
322         failures += testParse();
323         failures += testToJavaFormatString();
324 
325         if (failures != 0) {
326             throw new RuntimeException("" + failures + " failures while testing FloatingDecimal");
327         }
328     }
329 }
330