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 }