1 /* 2 * Copyright (c) 2001, 2024, 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 /* 25 * @test 26 * @bug 4160406 4705734 4707389 4826774 4895911 4421494 6358355 7021568 7039369 4396272 27 * @summary Test for Double.parseDouble method and acceptance regex 28 */ 29 30 package test.java.lang.Double; 31 32 import java.math.BigDecimal; 33 import java.math.BigInteger; 34 import java.util.regex.*; 35 36 public class ParseDouble { 37 38 private static final BigDecimal HALF = BigDecimal.valueOf(0.5); 39 fail(String val, double n)40 private static void fail(String val, double n) { 41 throw new RuntimeException("Double.parseDouble failed. String:" + 42 val + " Result:" + n); 43 } 44 check(String val)45 private static void check(String val) { 46 double n = Double.parseDouble(val); 47 boolean isNegativeN = n < 0 || n == 0 && 1/n < 0; 48 double na = Math.abs(n); 49 String s = val.trim().toLowerCase(); 50 switch (s.charAt(s.length() - 1)) { 51 case 'd': 52 case 'f': 53 s = s.substring(0, s.length() - 1); 54 break; 55 } 56 boolean isNegative = false; 57 if (s.charAt(0) == '+') { 58 s = s.substring(1); 59 } else if (s.charAt(0) == '-') { 60 s = s.substring(1); 61 isNegative = true; 62 } 63 if (s.equals("nan")) { 64 if (!Double.isNaN(n)) { 65 fail(val, n); 66 } 67 return; 68 } 69 if (Double.isNaN(n)) { 70 fail(val, n); 71 } 72 if (isNegativeN != isNegative) 73 fail(val, n); 74 if (s.equals("infinity")) { 75 if (na != Double.POSITIVE_INFINITY) { 76 fail(val, n); 77 } 78 return; 79 } 80 BigDecimal bd; 81 if (s.startsWith("0x")) { 82 s = s.substring(2); 83 int indP = s.indexOf('p'); 84 long exp = Long.parseLong(s.substring(indP + 1)); 85 int indD = s.indexOf('.'); 86 String significand; 87 if (indD >= 0) { 88 significand = s.substring(0, indD) + s.substring(indD + 1, indP); 89 exp -= 4*(indP - indD - 1); 90 } else { 91 significand = s.substring(0, indP); 92 } 93 bd = new BigDecimal(new BigInteger(significand, 16)); 94 if (exp >= 0) { 95 bd = bd.multiply(BigDecimal.valueOf(2).pow((int)exp)); 96 } else { 97 bd = bd.divide(BigDecimal.valueOf(2).pow((int)-exp)); 98 } 99 } else { 100 bd = new BigDecimal(s); 101 } 102 BigDecimal l, u; 103 if (Double.isInfinite(na)) { 104 l = new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(Math.ulp(Double.MAX_VALUE)).multiply(HALF)); 105 u = null; 106 } else { 107 l = new BigDecimal(na).subtract(new BigDecimal(Math.ulp(Math.nextUp(-na))).multiply(HALF)); 108 u = new BigDecimal(na).add(new BigDecimal(Math.ulp(n)).multiply(HALF)); 109 } 110 int cmpL = bd.compareTo(l); 111 int cmpU = u != null ? bd.compareTo(u) : -1; 112 if ((Double.doubleToLongBits(n) & 1) != 0) { 113 if (cmpL <= 0 || cmpU >= 0) { 114 fail(val, n); 115 } 116 } else { 117 if (cmpL < 0 || cmpU > 0) { 118 fail(val, n); 119 } 120 } 121 } 122 check(String val, double expected)123 private static void check(String val, double expected) { 124 double n = Double.parseDouble(val); 125 if (n != expected) 126 fail(val, n); 127 check(val); 128 } 129 rudimentaryTest()130 private static void rudimentaryTest() { 131 check(new String(""+Double.MIN_VALUE), Double.MIN_VALUE); 132 check(new String(""+Double.MAX_VALUE), Double.MAX_VALUE); 133 134 check("10", (double) 10.0); 135 check("10.0", (double) 10.0); 136 check("10.01", (double) 10.01); 137 138 check("-10", (double) -10.0); 139 check("-10.00", (double) -10.0); 140 check("-10.01", (double) -10.01); 141 } 142 143 144 static String badStrings[] = { 145 "", 146 "+", 147 "-", 148 "+e", 149 "-e", 150 "+e170", 151 "-e170", 152 153 // Make sure intermediate white space is not deleted. 154 "1234 e10", 155 "-1234 e10", 156 157 // Control characters in the interior of a string are not legal 158 "1\u0007e1", 159 "1e\u00071", 160 161 // NaN and infinity can't have trailing type suffices or exponents 162 "NaNf", 163 "NaNF", 164 "NaNd", 165 "NaND", 166 "-NaNf", 167 "-NaNF", 168 "-NaNd", 169 "-NaND", 170 "+NaNf", 171 "+NaNF", 172 "+NaNd", 173 "+NaND", 174 "Infinityf", 175 "InfinityF", 176 "Infinityd", 177 "InfinityD", 178 "-Infinityf", 179 "-InfinityF", 180 "-Infinityd", 181 "-InfinityD", 182 "+Infinityf", 183 "+InfinityF", 184 "+Infinityd", 185 "+InfinityD", 186 187 "NaNe10", 188 "-NaNe10", 189 "+NaNe10", 190 "Infinitye10", 191 "-Infinitye10", 192 "+Infinitye10", 193 194 // Non-ASCII digits are not recognized 195 // Android-removed: non-ASCII digits tests 196 // "\u0661e\u0661", // 1e1 in Arabic-Indic digits 197 // "\u06F1e\u06F1", // 1e1 in Extended Arabic-Indic digits 198 // "\u0967e\u0967", // 1e1 in Devanagari digits 199 200 // JCK test lex03592m3 201 ".", 202 203 // JCK test lex03592m4 204 "e42", 205 206 // JCK test lex03592m5 207 ".e42", 208 209 // JCK test lex03592m6 210 "d", 211 212 // JCK test lex03592m7 213 ".d", 214 215 // JCK test lex03592m8 216 "e42d", 217 218 // JCK test lex03592m9 219 ".e42d", 220 221 // JCK test lex03593m10 222 "1A01.01125e-10d", 223 224 // JCK test lex03593m11 225 "2;3.01125e-10d", 226 227 // JCK test lex03593m12 228 "1_34.01125e-10d", 229 230 // JCK test lex03593m14 231 "202..01125e-10d", 232 233 // JCK test lex03593m15 234 "202,01125e-10d", 235 236 // JCK test lex03593m16 237 "202.03b4e-10d", 238 239 // JCK test lex03593m18 240 "202.06_3e-10d", 241 242 // JCK test lex03593m20 243 "202.01125e-f0d", 244 245 // JCK test lex03593m21 246 "202.01125e_3d", 247 248 // JCK test lex03593m22 249 "202.01125e -5d", 250 251 // JCK test lex03593m24 252 "202.01125e-10r", 253 254 // JCK test lex03593m25 255 "202.01125e-10ff", 256 257 // JCK test lex03593m26 258 "1234L.01", 259 260 // JCK test lex03593m27 261 "12ee-2", 262 263 // JCK test lex03593m28 264 "12e-2.2.2", 265 266 // JCK test lex03593m29 267 "12.01e+", 268 269 // JCK test lex03593m30 270 "12.01E", 271 272 // Bad hexadecimal-style strings 273 274 // Two leading zeros 275 "00x1.0p1", 276 277 // Must have hex specifier 278 "1.0p1", 279 "00010p1", 280 "deadbeefp1", 281 282 // Need an explicit fully-formed exponent 283 "0x1.0p", 284 "0x1.0", 285 286 // Exponent must be in decimal 287 "0x1.0pa", 288 "0x1.0pf", 289 290 // Exponent separated by "p" 291 "0x1.0e22", 292 "0x1.0e22", 293 294 // Need a signifcand 295 "0xp22" 296 }; 297 298 static String goodStrings[] = { 299 "NaN", 300 "+NaN", 301 "-NaN", 302 "Infinity", 303 "+Infinity", 304 "-Infinity", 305 "1.1e-23f", 306 ".1e-23f", 307 "1e-23", 308 "1f", 309 "0", 310 "-0", 311 "+0", 312 "00", 313 "00", 314 "-00", 315 "+00", 316 "0000000000", 317 "-0000000000", 318 "+0000000000", 319 "1", 320 "2", 321 "1234", 322 "-1234", 323 "+1234", 324 "2147483647", // Integer.MAX_VALUE 325 "2147483648", 326 "-2147483648", // Integer.MIN_VALUE 327 "-2147483649", 328 329 "16777215", 330 "16777216", // 2^24 331 "16777217", 332 333 "-16777215", 334 "-16777216", // -2^24 335 "-16777217", 336 337 "9007199254740991", 338 "9007199254740992", // 2^53 339 "9007199254740993", 340 341 "-9007199254740991", 342 "-9007199254740992", // -2^53 343 "-9007199254740993", 344 345 "9223372036854775807", 346 "9223372036854775808", // Long.MAX_VALUE 347 "9223372036854775809", 348 349 "-9223372036854775808", 350 "-9223372036854775809", // Long.MIN_VALUE 351 "-9223372036854775810", 352 353 // Culled from JCK test lex03591m1 354 "54.07140d", 355 "7.01e-324d", 356 "2147483647.01d", 357 "1.2147483647f", 358 "000000000000000000000000001.F", 359 "1.00000000000000000000000000e-2F", 360 361 // Culled from JCK test lex03592m2 362 "2.", 363 ".0909", 364 "122112217090.0", 365 "7090e-5", 366 "2.E-20", 367 ".0909e42", 368 "122112217090.0E+100", 369 "7090f", 370 "2.F", 371 ".0909d", 372 "122112217090.0D", 373 "7090e-5f", 374 "2.E-20F", 375 ".0909e42d", 376 "122112217090.0E+100D", 377 378 // Culled from JCK test lex03594m31 -- unicode escapes 379 "\u0035\u0031\u0034\u0039\u0032\u0033\u0036\u0037\u0038\u0030.1102E-209D", 380 "1290873\u002E12301e100", 381 "1.1E-10\u0066", 382 383 // Culled from JCK test lex03595m1 384 "0.0E-10", 385 "1E10", 386 387 // Culled from JCK test lex03691m1 388 "0.f", 389 "1f", 390 "0.F", 391 "1F", 392 "0.12d", 393 "1e-0d", 394 "12.e+1D", 395 "0e-0D", 396 "12.e+01", 397 "1e-01", 398 399 // Good hex strings 400 // Vary capitalization of separators. 401 402 "0x1p1", 403 "0X1p1", 404 "0x1P1", 405 "0X1P1", 406 "0x1p1f", 407 "0X1p1f", 408 "0x1P1f", 409 "0X1P1f", 410 "0x1p1F", 411 "0X1p1F", 412 "0x1P1F", 413 "0X1P1F", 414 "0x1p1d", 415 "0X1p1d", 416 "0x1P1d", 417 "0X1P1d", 418 "0x1p1D", 419 "0X1p1D", 420 "0x1P1D", 421 "0X1P1D", 422 423 "-0x1p1", 424 "-0X1p1", 425 "-0x1P1", 426 "-0X1P1", 427 "-0x1p1f", 428 "-0X1p1f", 429 "-0x1P1f", 430 "-0X1P1f", 431 "-0x1p1F", 432 "-0X1p1F", 433 "-0x1P1F", 434 "-0X1P1F", 435 "-0x1p1d", 436 "-0X1p1d", 437 "-0x1P1d", 438 "-0X1P1d", 439 "-0x1p1D", 440 "-0X1p1D", 441 "-0x1P1D", 442 "-0X1P1D", 443 444 "0x1p-1", 445 "0X1p-1", 446 "0x1P-1", 447 "0X1P-1", 448 "0x1p-1f", 449 "0X1p-1f", 450 "0x1P-1f", 451 "0X1P-1f", 452 "0x1p-1F", 453 "0X1p-1F", 454 "0x1P-1F", 455 "0X1P-1F", 456 "0x1p-1d", 457 "0X1p-1d", 458 "0x1P-1d", 459 "0X1P-1d", 460 "0x1p-1D", 461 "0X1p-1D", 462 "0x1P-1D", 463 "0X1P-1D", 464 465 "-0x1p-1", 466 "-0X1p-1", 467 "-0x1P-1", 468 "-0X1P-1", 469 "-0x1p-1f", 470 "-0X1p-1f", 471 "-0x1P-1f", 472 "-0X1P-1f", 473 "-0x1p-1F", 474 "-0X1p-1F", 475 "-0x1P-1F", 476 "-0X1P-1F", 477 "-0x1p-1d", 478 "-0X1p-1d", 479 "-0x1P-1d", 480 "-0X1P-1d", 481 "-0x1p-1D", 482 "-0X1p-1D", 483 "-0x1P-1D", 484 "-0X1P-1D", 485 486 487 // Try different significand combinations 488 "0xap1", 489 "0xbp1", 490 "0xcp1", 491 "0xdp1", 492 "0xep1", 493 "0xfp1", 494 495 "0x1p1", 496 "0x.1p1", 497 "0x1.1p1", 498 499 "0x001p23", 500 "0x00.1p1", 501 "0x001.1p1", 502 503 "0x100p1", 504 "0x.100p1", 505 "0x1.100p1", 506 507 "0x00100p1", 508 "0x00.100p1", 509 "0x001.100p1", 510 511 // Limits 512 513 "1.7976931348623157E308", // Double.MAX_VALUE 514 "4.9e-324", // Double.MIN_VALUE 515 "2.2250738585072014e-308", // Double.MIN_NORMAL 516 517 "2.2250738585072012e-308", // near Double.MIN_NORMAL 518 519 "1.7976931348623158e+308", // near MAX_VALUE + ulp(MAX_VALUE)/2 520 "1.7976931348623159e+308", // near MAX_VALUE + ulp(MAX_VALUE) 521 522 "2.4703282292062329e-324", // above MIN_VALUE/2 523 "2.4703282292062327e-324", // MIN_VALUE/2 524 "2.4703282292062325e-324", // below MIN_VALUE/2 525 526 // 1e308 with leading zeros 527 528 "0.0000000000001e321", 529 "00.000000000000000001e326", 530 "00000.000000000000000001e326", 531 "000.0000000000000000001e327", 532 "0.00000000000000000001e328", 533 }; 534 535 static String paddedBadStrings[]; 536 static String paddedGoodStrings[]; 537 static { 538 String pad = " \t\n\r\f\u0001\u000b\u001f"; 539 paddedBadStrings = new String[badStrings.length]; 540 for(int i = 0 ; i < badStrings.length; i++) 541 paddedBadStrings[i] = pad + badStrings[i] + pad; 542 543 paddedGoodStrings = new String[goodStrings.length]; 544 for(int i = 0 ; i < goodStrings.length; i++) 545 paddedGoodStrings[i] = pad + goodStrings[i] + pad; 546 547 } 548 549 550 /* 551 * Throws an exception if <code>Input</code> is 552 * <code>exceptionalInput</code> and {@link Double.parseDouble 553 * parseDouble} does <em>not</em> throw an exception or if 554 * <code>Input</code> is not <code>exceptionalInput</code> and 555 * <code>parseDouble</code> throws an exception. This method does 556 * not attempt to test whether the string is converted to the 557 * proper value; just whether the input is accepted appropriately 558 * or not. 559 */ testParsing(String [] input, boolean exceptionalInput)560 private static void testParsing(String [] input, 561 boolean exceptionalInput) { 562 for (String s : input) { 563 try { 564 Double.parseDouble(s); 565 check(s); 566 } catch (NumberFormatException e) { 567 if (!exceptionalInput) { 568 throw new RuntimeException("Double.parseDouble rejected " + 569 "good string `" + s + 570 "'."); 571 } 572 continue; 573 } 574 if (exceptionalInput) { 575 throw new RuntimeException("Double.parseDouble accepted " + 576 "bad string `" + s + 577 "'."); 578 } 579 } 580 } 581 582 /* 583 * Throws an exception if <code>Input</code> is 584 * <code>exceptionalInput</code> and the regular expression 585 * matches one of the strings or if <code>Input</code> is not 586 * <code>exceptionalInput</code> and the regular expression fails 587 * to match an input string. 588 */ testRegex(String [] input, boolean exceptionalInput)589 private static void testRegex(String [] input, boolean exceptionalInput) { 590 /* 591 * The regex below is taken from the JavaDoc for 592 * Double.valueOf. 593 */ 594 595 final String Digits = "(\\p{Digit}+)"; 596 final String HexDigits = "(\\p{XDigit}+)"; 597 // an exponent is 'e' or 'E' followed by an optionally 598 // signed decimal integer. 599 final String Exp = "[eE][+-]?"+Digits; 600 final String fpRegex = 601 ("[\\x00-\\x20]*"+ // Optional leading "whitespace" 602 "[+-]?(" + // Optional sign character 603 "NaN|" + // "NaN" string 604 "Infinity|" + // "Infinity" string 605 606 // A floating-point string representing a finite positive 607 // number without a leading sign has at most five basic pieces: 608 // Digits . Digits ExponentPart FloatTypeSuffix 609 // 610 // Since this method allows integer-only strings as input 611 // in addition to strings of floating-point literals, the 612 // two sub-patterns below are simplifications of the grammar 613 // productions from the Java Language Specification, 2nd 614 // edition, section 3.10.2. 615 616 617 // A decimal floating-point string representing a finite positive 618 // number without a leading sign has at most five basic pieces: 619 // Digits . Digits ExponentPart FloatTypeSuffix 620 // 621 // Since this method allows integer-only strings as input 622 // in addition to strings of floating-point literals, the 623 // two sub-patterns below are simplifications of the grammar 624 // productions from the Java Language Specification, 2nd 625 // edition, section 3.10.2. 626 627 // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt 628 "(((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ 629 630 // . Digits ExponentPart_opt FloatTypeSuffix_opt 631 "(\\.("+Digits+")("+Exp+")?))|"+ 632 633 // Hexadecimal strings 634 "((" + 635 // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt 636 "(0[xX]" + HexDigits + "(\\.)?)|" + 637 638 // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt 639 "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + 640 641 ")[pP][+-]?" + Digits + "))" + 642 "[fFdD]?))" + 643 "[\\x00-\\x20]*");// Optional trailing "whitespace" 644 Pattern fpPattern = Pattern.compile(fpRegex); 645 646 for(int i = 0; i < input.length; i++) { 647 Matcher m = fpPattern.matcher(input[i]); 648 if (m.matches() != ! exceptionalInput) { 649 throw new RuntimeException("Regular expression " + 650 (exceptionalInput? 651 "accepted bad": 652 "rejected good") + 653 " string `" + 654 input[i] + "'."); 655 } 656 } 657 658 } 659 660 /** 661 * For each subnormal power of two, test at boundaries of 662 * region that should convert to that value. 663 */ testSubnormalPowers()664 private static void testSubnormalPowers() { 665 boolean failed = false; 666 BigDecimal TWO = BigDecimal.valueOf(2); 667 // An ulp is the same for all subnormal values 668 BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE); 669 670 // Test subnormal powers of two (except Double.MIN_VALUE) 671 for(int i = -1073; i <= -1022; i++) { 672 double d = Math.scalb(1.0, i); 673 674 /* 675 * The region [d - ulp/2, d + ulp/2] should round to d. 676 */ 677 BigDecimal d_BD = new BigDecimal(d); 678 679 BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO)); 680 BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO)); 681 682 double convertedLowerBound = Double.parseDouble(lowerBound.toString()); 683 double convertedUpperBound = Double.parseDouble(upperBound.toString()); 684 if (convertedLowerBound != d) { 685 failed = true; 686 System.out.printf("2^%d lowerBound converts as %a %s%n", 687 i, convertedLowerBound, lowerBound); 688 } 689 if (convertedUpperBound != d) { 690 failed = true; 691 System.out.printf("2^%d upperBound converts as %a %s%n", 692 i, convertedUpperBound, upperBound); 693 } 694 } 695 /* 696 * Double.MIN_VALUE 697 * The region ]0.5*Double.MIN_VALUE, 1.5*Double.MIN_VALUE[ should round to Double.MIN_VALUE . 698 */ 699 BigDecimal minValue = new BigDecimal(Double.MIN_VALUE); 700 if (Double.parseDouble(minValue.multiply(new BigDecimal(0.5)).toString()) != 0.0) { 701 failed = true; 702 System.out.printf("0.5*MIN_VALUE doesn't convert 0%n"); 703 } 704 if (Double.parseDouble(minValue.multiply(new BigDecimal(0.50000000001)).toString()) != Double.MIN_VALUE) { 705 failed = true; 706 System.out.printf("0.50000000001*MIN_VALUE doesn't convert to MIN_VALUE%n"); 707 } 708 if (Double.parseDouble(minValue.multiply(new BigDecimal(1.49999999999)).toString()) != Double.MIN_VALUE) { 709 failed = true; 710 System.out.printf("1.49999999999*MIN_VALUE doesn't convert to MIN_VALUE%n"); 711 } 712 if (Double.parseDouble(minValue.multiply(new BigDecimal(1.5)).toString()) != 2*Double.MIN_VALUE) { 713 failed = true; 714 System.out.printf("1.5*MIN_VALUE doesn't convert to 2*MIN_VALUE%n"); 715 } 716 717 if (failed) 718 throw new RuntimeException("Inconsistent conversion"); 719 } 720 721 /** 722 * For each power of two, test at boundaries of 723 * region that should convert to that value. 724 */ testPowers()725 private static void testPowers() { 726 for(int i = -1074; i <= +1023; i++) { 727 double d = Math.scalb(1.0, i); 728 BigDecimal d_BD = new BigDecimal(d); 729 730 BigDecimal lowerBound = d_BD.subtract(new BigDecimal(Math.ulp(Math.nextUp(-d))).multiply(HALF)); 731 BigDecimal upperBound = d_BD.add(new BigDecimal(Math.ulp(d)).multiply(HALF)); 732 733 check(lowerBound.toString()); 734 check(upperBound.toString()); 735 } 736 check(new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(Math.ulp(Double.MAX_VALUE)).multiply(HALF)).toString()); 737 } 738 testStrictness()739 private static void testStrictness() { 740 final double expected = 0x0.0000008000000p-1022; 741 // final double expected = 0x0.0000008000001p-1022; 742 boolean failed = false; 743 double conversion = 0.0; 744 double sum = 0.0; // Prevent conversion from being optimized away 745 746 //2^-1047 + 2^-1075 rounds to 2^-1047 747 String decimal = "6.631236871469758276785396630275967243399099947355303144249971758736286630139265439618068200788048744105960420552601852889715006376325666595539603330361800519107591783233358492337208057849499360899425128640718856616503093444922854759159988160304439909868291973931426625698663157749836252274523485312442358651207051292453083278116143932569727918709786004497872322193856150225415211997283078496319412124640111777216148110752815101775295719811974338451936095907419622417538473679495148632480391435931767981122396703443803335529756003353209830071832230689201383015598792184172909927924176339315507402234836120730914783168400715462440053817592702766213559042115986763819482654128770595766806872783349146967171293949598850675682115696218943412532098591327667236328125E-316"; 748 749 for(int i = 0; i <= 12_000; i++) { 750 conversion = Double.parseDouble(decimal); 751 sum += conversion; 752 if (conversion != expected) { 753 failed = true; 754 System.out.printf("Iteration %d converts as %a%n", 755 i, conversion); 756 } 757 } 758 759 System.out.println("Sum = " + sum); 760 if (failed) 761 throw new RuntimeException("Inconsistent conversion"); 762 } 763 main(String[] args)764 public static void main(String[] args) throws Exception { 765 rudimentaryTest(); 766 767 testParsing(goodStrings, false); 768 testParsing(paddedGoodStrings, false); 769 testParsing(badStrings, true); 770 testParsing(paddedBadStrings, true); 771 772 testRegex(goodStrings, false); 773 testRegex(paddedGoodStrings, false); 774 testRegex(badStrings, true); 775 testRegex(paddedBadStrings, true); 776 777 testSubnormalPowers(); 778 testPowers(); 779 testStrictness(); 780 } 781 } 782