1 /*
   2  * Copyright 2018-2019 Raffaello Giulietti
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a copy
   5  * of this software and associated documentation files (the "Software"), to deal
   6  * in the Software without restriction, including without limitation the rights
   7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8  * copies of the Software, and to permit persons to whom the Software is
   9  * furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20  * THE SOFTWARE.
  21  */
  22 
  23 package jdk.internal.math;
  24 
  25 import java.math.BigDecimal;
  26 import java.util.Random;
  27 
  28 import static java.lang.Double.*;
  29 import static java.lang.Long.numberOfTrailingZeros;
  30 import static java.lang.Math.scalb;
  31 import static jdk.internal.math.DoubleToDecimal.*;
  32 import static jdk.internal.math.MathUtils.flog10pow2;
  33 
  34 public class DoubleToDecimalChecker extends ToDecimalChecker {
  35 
  36     private double v;
  37     private final long originalBits;
  38 
  39     private DoubleToDecimalChecker(double v, String s) {
  40         super(s);
  41         this.v = v;
  42         originalBits = doubleToRawLongBits(v);
  43     }
  44 
  45     @Override
  46     BigDecimal toBigDecimal() {
  47         return new BigDecimal(v);
  48     }
  49 
  50     @Override
  51     boolean recovers(BigDecimal b) {
  52         return b.doubleValue() == v;
  53     }
  54 
  55     @Override
  56     boolean recovers(String s) {
  57         return parseDouble(s) == v;
  58     }
  59 
  60     @Override
  61     String hexBits() {
  62         return String.format("0x%01X__%03X__%01X_%04X_%04X_%04X",
  63                 (int) (originalBits >>> 63) & 0x1,
  64                 (int) (originalBits >>> 52) & 0x7FF,
  65                 (int) (originalBits >>> 48) & 0xF,
  66                 (int) (originalBits >>> 32) & 0xFFFF,
  67                 (int) (originalBits >>> 16) & 0xFFFF,
  68                 (int) originalBits & 0xFFFF);
  69     }
  70 
  71     @Override
  72     int minExp() {
  73         return MIN_EXP;
  74     }
  75 
  76     @Override
  77     int maxExp() {
  78         return MAX_EXP;
  79     }
  80 
  81     @Override
  82     int maxLen10() {
  83         return H;
  84     }
  85 
  86     @Override
  87     boolean isZero() {
  88         return v == 0;
  89     }
  90 
  91     @Override
  92     boolean isInfinity() {
  93         return v == POSITIVE_INFINITY;
  94     }
  95 
  96     @Override
  97     void negate() {
  98         v = -v;
  99     }
 100 
 101     @Override
 102     boolean isNegative() {
 103         return originalBits < 0;
 104     }
 105 
 106     @Override
 107     boolean isNaN() {
 108         return Double.isNaN(v);
 109     }
 110 
 111     private static void toDec(double v) {
 112 //        String s = Double.toString(v);
 113         String s = DoubleToDecimal.toString(v);
 114         new DoubleToDecimalChecker(v, s).assertTrue();
 115     }
 116 
 117     private static void testExtremeValues() {
 118         toDec(NEGATIVE_INFINITY);
 119         toDec(-MAX_VALUE);
 120         toDec(-MIN_NORMAL);
 121         toDec(-MIN_VALUE);
 122         toDec(-0.0);
 123         toDec(0.0);
 124         toDec(MIN_VALUE);
 125         toDec(MIN_NORMAL);
 126         toDec(MAX_VALUE);
 127         toDec(POSITIVE_INFINITY);
 128         toDec(NaN);
 129 
 130         /*
 131         Quiet NaNs have the most significant bit of the mantissa as 1,
 132         while signaling NaNs have it as 0.
 133         Exercise 4 combinations of quiet/signaling NaNs and
 134         "positive/negative" NaNs
 135          */
 136         toDec(longBitsToDouble(0x7FF8_0000_0000_0001L));
 137         toDec(longBitsToDouble(0x7FF0_0000_0000_0001L));
 138         toDec(longBitsToDouble(0xFFF8_0000_0000_0001L));
 139         toDec(longBitsToDouble(0xFFF0_0000_0000_0001L));
 140 
 141         /*
 142         All values treated specially by Schubfach
 143          */
 144         toDec(4.9E-324);
 145         toDec(9.9E-324);
 146     }
 147 
 148     /*
 149     A few "powers of 10" are incorrectly rendered by the JDK.
 150     The rendering is either too long or it is not the closest decimal.
 151      */
 152     private static void testPowersOf10() {
 153         for (int e = MIN_EXP; e <= MAX_EXP; ++e) {
 154             toDec(parseDouble("1e" + e));
 155         }
 156     }
 157 
 158     /*
 159     Many powers of 2 are incorrectly rendered by the JDK.
 160     The rendering is either too long or it is not the closest decimal.
 161      */
 162     private static void testPowersOf2() {
 163         for (double v = MIN_VALUE; v <= MAX_VALUE; v *= 2) {
 164             toDec(v);
 165         }
 166     }
 167 
 168     /*
 169     There are many doubles that are rendered incorrectly by the JDK.
 170     While the renderings correctly round back to the original value,
 171     they are longer than needed or are not the closest decimal to the double.
 172     Here are just a very few examples.
 173      */
 174     private static final String[] Anomalies = {
 175             // JDK renders these, and others, with 18 digits!
 176             "2.82879384806159E17", "1.387364135037754E18",
 177             "1.45800632428665E17",
 178 
 179             // JDK renders these longer than needed.
 180             "1.6E-322", "6.3E-322",
 181             "7.3879E20", "2.0E23", "7.0E22", "9.2E22",
 182             "9.5E21", "3.1E22", "5.63E21", "8.41E21",
 183 
 184             // JDK does not render these, and many others, as the closest.
 185             "9.9E-324", "9.9E-323",
 186             "1.9400994884341945E25", "3.6131332396758635E25",
 187             "2.5138990223946153E25",
 188     };
 189 
 190     private static void testSomeAnomalies() {
 191         for (String dec : Anomalies) {
 192             toDec(parseDouble(dec));
 193         }
 194     }
 195 
 196     /*
 197     Values are from
 198     Paxson V, "A Program for Testing IEEE Decimal-Binary Conversion"
 199     tables 3 and 4
 200      */
 201     private static final double[] PaxsonSignificands = {
 202             8_511_030_020_275_656L,
 203             5_201_988_407_066_741L,
 204             6_406_892_948_269_899L,
 205             8_431_154_198_732_492L,
 206             6_475_049_196_144_587L,
 207             8_274_307_542_972_842L,
 208             5_381_065_484_265_332L,
 209             6_761_728_585_499_734L,
 210             7_976_538_478_610_756L,
 211             5_982_403_858_958_067L,
 212             5_536_995_190_630_837L,
 213             7_225_450_889_282_194L,
 214             7_225_450_889_282_194L,
 215             8_703_372_741_147_379L,
 216             8_944_262_675_275_217L,
 217             7_459_803_696_087_692L,
 218             6_080_469_016_670_379L,
 219             8_385_515_147_034_757L,
 220             7_514_216_811_389_786L,
 221             8_397_297_803_260_511L,
 222             6_733_459_239_310_543L,
 223             8_091_450_587_292_794L,
 224 
 225             6_567_258_882_077_402L,
 226             6_712_731_423_444_934L,
 227             6_712_731_423_444_934L,
 228             5_298_405_411_573_037L,
 229             5_137_311_167_659_507L,
 230             6_722_280_709_661_868L,
 231             5_344_436_398_034_927L,
 232             8_369_123_604_277_281L,
 233             8_995_822_108_487_663L,
 234             8_942_832_835_564_782L,
 235             8_942_832_835_564_782L,
 236             8_942_832_835_564_782L,
 237             6_965_949_469_487_146L,
 238             6_965_949_469_487_146L,
 239             6_965_949_469_487_146L,
 240             7_487_252_720_986_826L,
 241             5_592_117_679_628_511L,
 242             8_887_055_249_355_788L,
 243             6_994_187_472_632_449L,
 244             8_797_576_579_012_143L,
 245             7_363_326_733_505_337L,
 246             8_549_497_411_294_502L,
 247     };
 248 
 249     private static final int[] PaxsonExponents = {
 250             -342,
 251             -824,
 252              237,
 253               72,
 254               99,
 255              726,
 256             -456,
 257              -57,
 258              376,
 259              377,
 260               93,
 261              710,
 262              709,
 263              117,
 264               -1,
 265             -707,
 266             -381,
 267              721,
 268             -828,
 269             -345,
 270              202,
 271             -473,
 272 
 273              952,
 274              535,
 275              534,
 276             -957,
 277             -144,
 278              363,
 279             -169,
 280             -853,
 281             -780,
 282             -383,
 283             -384,
 284             -385,
 285             -249,
 286             -250,
 287             -251,
 288              548,
 289              164,
 290              665,
 291              690,
 292              588,
 293              272,
 294             -448,
 295     };
 296 
 297     private static void testPaxson() {
 298         for (int i = 0; i < PaxsonSignificands.length; ++i) {
 299             toDec(scalb(PaxsonSignificands[i], PaxsonExponents[i]));
 300         }
 301     }
 302 
 303     /*
 304     Tests all integers of the form yx_xxx_000_000_000_000_000, y != 0.
 305     These are all exact doubles.
 306      */
 307     private static void testLongs() {
 308         for (int i = 10_000; i < 100_000; ++i) {
 309             toDec(i * 1e15);
 310         }
 311     }
 312 
 313     /*
 314     Tests all integers up to 1_000_000.
 315     These are all exact doubles and exercise a fast path.
 316      */
 317     private static void testInts() {
 318         for (int i = 0; i <= 1_000_000; ++i) {
 319             toDec(i);
 320         }
 321     }
 322 
 323     /*
 324     Random doubles over the whole range
 325      */
 326     private static void testRandom(int randomCount, Random r) {
 327         for (int i = 0; i < randomCount; ++i) {
 328             toDec(longBitsToDouble(r.nextLong()));
 329         }
 330     }
 331 
 332     /*
 333     Random doubles over the integer range [0, 2^52).
 334     These are all exact doubles and exercise the fast path (except 0).
 335      */
 336     private static void testRandomUnit(int randomCount, Random r) {
 337         for (int i = 0; i < randomCount; ++i) {
 338             toDec(r.nextLong() & (1L << P - 1));
 339         }
 340     }
 341 
 342     /*
 343     Random doubles over the range [0, 10^15) as "multiples" of 1e-3
 344      */
 345     private static void testRandomMilli(int randomCount, Random r) {
 346         for (int i = 0; i < randomCount; ++i) {
 347             toDec(r.nextLong() % 1_000_000_000_000_000_000L / 1e3);
 348         }
 349     }
 350 
 351     /*
 352     Random doubles over the range [0, 10^15) as "multiples" of 1e-6
 353      */
 354     private static void testRandomMicro(int randomCount, Random r) {
 355         for (int i = 0; i < randomCount; ++i) {
 356             toDec((r.nextLong() & 0x7FFF_FFFF_FFFF_FFFFL) / 1e6);
 357         }
 358     }
 359 
 360     private static void testConstants() {
 361         assertTrue(precision() == P, "P");
 362         assertTrue(flog10pow2(P) + 2 == H, "H");
 363         assertTrue(e(MIN_VALUE) == MIN_EXP, "MIN_EXP");
 364         assertTrue(e(MAX_VALUE) == MAX_EXP, "MAX_EXP");
 365     }
 366 
 367     private static int precision() {
 368         /*
 369         Given precision P, the floating point value 3 has the bits
 370         0e...e10...0
 371         where there are exactly P - 2 trailing zeroes.
 372         */
 373         return numberOfTrailingZeros(doubleToRawLongBits(3)) + 2;
 374     }
 375 
 376     public static void test(int randomCount, Random r) {
 377         testConstants();
 378         testExtremeValues();
 379         testSomeAnomalies();
 380         testPowersOf2();
 381         testPowersOf10();
 382         testPaxson();
 383         testInts();
 384         testLongs();
 385         testRandom(randomCount, r);
 386         testRandomUnit(randomCount, r);
 387         testRandomMilli(randomCount, r);
 388         testRandomMicro(randomCount, r);
 389     }
 390 
 391 }