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