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