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