1 /* 2 * Copyright (c) 2001, 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 /* 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 import java.math.BigDecimal; 31 import java.math.BigInteger; 32 import java.util.regex.*; 33 34 public class ParseDouble { 35 36 private static final BigDecimal HALF = BigDecimal.valueOf(0.5); 37 38 private static void fail(String val, double n) { 39 throw new RuntimeException("Double.parseDouble failed. String:" + 40 val + " Result:" + n); 41 } 42 43 private static void check(String val) { 44 double n = Double.parseDouble(val); 45 boolean isNegativeN = n < 0 || n == 0 && 1/n < 0; 46 double na = Math.abs(n); 47 String s = val.trim().toLowerCase(); 48 switch (s.charAt(s.length() - 1)) { 49 case 'd': 50 case 'f': 51 s = s.substring(0, s.length() - 1); 52 break; 53 } 54 boolean isNegative = false; 55 if (s.charAt(0) == '+') { 56 s = s.substring(1); 57 } else if (s.charAt(0) == '-') { 58 s = s.substring(1); 59 isNegative = true; 60 } 61 if (s.equals("nan")) { 62 if (!Double.isNaN(n)) { 63 fail(val, n); 64 } 65 return; 66 } 67 if (Double.isNaN(n)) { 68 fail(val, n); 69 } 70 if (isNegativeN != isNegative) 71 fail(val, n); 72 if (s.equals("infinity")) { 73 if (na != Double.POSITIVE_INFINITY) { 74 fail(val, n); 75 } 76 return; 77 } 78 BigDecimal bd; 79 if (s.startsWith("0x")) { 80 s = s.substring(2); 81 int indP = s.indexOf('p'); 82 long exp = Long.parseLong(s.substring(indP + 1)); 83 int indD = s.indexOf('.'); 84 String significand; 85 if (indD >= 0) { 86 significand = s.substring(0, indD) + s.substring(indD + 1, indP); 87 exp -= 4*(indP - indD - 1); 88 } else { 89 significand = s.substring(0, indP); 90 } 91 bd = new BigDecimal(new BigInteger(significand, 16)); 92 if (exp >= 0) { 93 bd = bd.multiply(BigDecimal.valueOf(2).pow((int)exp)); 94 } else { 95 bd = bd.divide(BigDecimal.valueOf(2).pow((int)-exp)); 96 } 97 } else { 98 bd = new BigDecimal(s); 99 } 100 BigDecimal l, u; 101 if (Double.isInfinite(na)) { 102 l = new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(Math.ulp(Double.MAX_VALUE)).multiply(HALF)); 103 u = null; 104 } else { 105 l = new BigDecimal(na).subtract(new BigDecimal(Math.ulp(Math.nextUp(-na))).multiply(HALF)); 106 u = new BigDecimal(na).add(new BigDecimal(Math.ulp(n)).multiply(HALF)); 107 } 108 int cmpL = bd.compareTo(l); 109 int cmpU = u != null ? bd.compareTo(u) : -1; 110 if ((Double.doubleToLongBits(n) & 1) != 0) { 111 if (cmpL <= 0 || cmpU >= 0) { 112 fail(val, n); 113 } 114 } else { 115 if (cmpL < 0 || cmpU > 0) { 116 fail(val, n); 117 } 118 } 119 } 120 121 private static void check(String val, double expected) { 122 double n = Double.parseDouble(val); 123 if (n != expected) 124 fail(val, n); 125 check(val); 126 } 127 128 private static void rudimentaryTest() { 129 check(new String(""+Double.MIN_VALUE), Double.MIN_VALUE); 130 check(new String(""+Double.MAX_VALUE), Double.MAX_VALUE); 131 132 check("10", (double) 10.0); 133 check("10.0", (double) 10.0); 134 check("10.01", (double) 10.01); 135 136 check("-10", (double) -10.0); 137 check("-10.00", (double) -10.0); 138 check("-10.01", (double) -10.01); 139 } 140 141 142 static String badStrings[] = { 143 "", 144 "+", 145 "-", 146 "+e", 147 "-e", 148 "+e170", 149 "-e170", 150 151 // Make sure intermediate white space is not deleted. 152 "1234 e10", 153 "-1234 e10", 154 155 // Control characters in the interior of a string are not legal 156 "1\u0007e1", 157 "1e\u00071", 158 159 // NaN and infinity can't have trailing type suffices or exponents 160 "NaNf", 161 "NaNF", 162 "NaNd", 163 "NaND", 164 "-NaNf", 165 "-NaNF", 166 "-NaNd", 167 "-NaND", 168 "+NaNf", 169 "+NaNF", 170 "+NaNd", 171 "+NaND", 172 "Infinityf", 173 "InfinityF", 174 "Infinityd", 175 "InfinityD", 176 "-Infinityf", 177 "-InfinityF", 178 "-Infinityd", 179 "-InfinityD", 180 "+Infinityf", 181 "+InfinityF", 182 "+Infinityd", 183 "+InfinityD", 184 185 "NaNe10", 186 "-NaNe10", 187 "+NaNe10", 188 "Infinitye10", 189 "-Infinitye10", 190 "+Infinitye10", 191 192 // Non-ASCII digits are not recognized 193 "\u0661e\u0661", // 1e1 in Arabic-Indic digits 194 "\u06F1e\u06F1", // 1e1 in Extended Arabic-Indic digits 195 "\u0967e\u0967", // 1e1 in Devanagari digits 196 197 // JCK test lex03592m3 198 ".", 199 200 // JCK test lex03592m4 201 "e42", 202 203 // JCK test lex03592m5 204 ".e42", 205 206 // JCK test lex03592m6 207 "d", 208 209 // JCK test lex03592m7 210 ".d", 211 212 // JCK test lex03592m8 213 "e42d", 214 215 // JCK test lex03592m9 216 ".e42d", 217 218 // JCK test lex03593m10 219 "1A01.01125e-10d", 220 221 // JCK test lex03593m11 222 "2;3.01125e-10d", 223 224 // JCK test lex03593m12 225 "1_34.01125e-10d", 226 227 // JCK test lex03593m14 228 "202..01125e-10d", 229 230 // JCK test lex03593m15 231 "202,01125e-10d", 232 233 // JCK test lex03593m16 234 "202.03b4e-10d", 235 236 // JCK test lex03593m18 237 "202.06_3e-10d", 238 239 // JCK test lex03593m20 240 "202.01125e-f0d", 241 242 // JCK test lex03593m21 243 "202.01125e_3d", 244 245 // JCK test lex03593m22 246 "202.01125e -5d", 247 248 // JCK test lex03593m24 249 "202.01125e-10r", 250 251 // JCK test lex03593m25 252 "202.01125e-10ff", 253 254 // JCK test lex03593m26 255 "1234L.01", 256 257 // JCK test lex03593m27 258 "12ee-2", 259 260 // JCK test lex03593m28 261 "12e-2.2.2", 262 263 // JCK test lex03593m29 264 "12.01e+", 265 266 // JCK test lex03593m30 267 "12.01E", 268 269 // Bad hexadecimal-style strings 270 271 // Two leading zeros 272 "00x1.0p1", 273 274 // Must have hex specifier 275 "1.0p1", 276 "00010p1", 277 "deadbeefp1", 278 279 // Need an explicit fully-formed exponent 280 "0x1.0p", 281 "0x1.0", 282 283 // Exponent must be in decimal 284 "0x1.0pa", 285 "0x1.0pf", 286 287 // Exponent separated by "p" 288 "0x1.0e22", 289 "0x1.0e22", 290 291 // Need a signifcand 292 "0xp22" 293 }; 294 295 static String goodStrings[] = { 296 "NaN", 297 "+NaN", 298 "-NaN", 299 "Infinity", 300 "+Infinity", 301 "-Infinity", 302 "1.1e-23f", 303 ".1e-23f", 304 "1e-23", 305 "1f", 306 "0", 307 "-0", 308 "+0", 309 "00", 310 "00", 311 "-00", 312 "+00", 313 "0000000000", 314 "-0000000000", 315 "+0000000000", 316 "1", 317 "2", 318 "1234", 319 "-1234", 320 "+1234", 321 "2147483647", // Integer.MAX_VALUE 322 "2147483648", 323 "-2147483648", // Integer.MIN_VALUE 324 "-2147483649", 325 326 "16777215", 327 "16777216", // 2^24 328 "16777217", 329 330 "-16777215", 331 "-16777216", // -2^24 332 "-16777217", 333 334 "9007199254740991", 335 "9007199254740992", // 2^53 336 "9007199254740993", 337 338 "-9007199254740991", 339 "-9007199254740992", // -2^53 340 "-9007199254740993", 341 342 "9223372036854775807", 343 "9223372036854775808", // Long.MAX_VALUE 344 "9223372036854775809", 345 346 "-9223372036854775808", 347 "-9223372036854775809", // Long.MIN_VALUE 348 "-9223372036854775810", 349 350 // Culled from JCK test lex03591m1 351 "54.07140d", 352 "7.01e-324d", 353 "2147483647.01d", 354 "1.2147483647f", 355 "000000000000000000000000001.F", 356 "1.00000000000000000000000000e-2F", 357 358 // Culled from JCK test lex03592m2 359 "2.", 360 ".0909", 361 "122112217090.0", 362 "7090e-5", 363 "2.E-20", 364 ".0909e42", 365 "122112217090.0E+100", 366 "7090f", 367 "2.F", 368 ".0909d", 369 "122112217090.0D", 370 "7090e-5f", 371 "2.E-20F", 372 ".0909e42d", 373 "122112217090.0E+100D", 374 375 // Culled from JCK test lex03594m31 -- unicode escapes 376 "\u0035\u0031\u0034\u0039\u0032\u0033\u0036\u0037\u0038\u0030.1102E-209D", 377 "1290873\u002E12301e100", 378 "1.1E-10\u0066", 379 380 // Culled from JCK test lex03595m1 381 "0.0E-10", 382 "1E10", 383 384 // Culled from JCK test lex03691m1 385 "0.f", 386 "1f", 387 "0.F", 388 "1F", 389 "0.12d", 390 "1e-0d", 391 "12.e+1D", 392 "0e-0D", 393 "12.e+01", 394 "1e-01", 395 396 // Good hex strings 397 // Vary capitalization of separators. 398 399 "0x1p1", 400 "0X1p1", 401 "0x1P1", 402 "0X1P1", 403 "0x1p1f", 404 "0X1p1f", 405 "0x1P1f", 406 "0X1P1f", 407 "0x1p1F", 408 "0X1p1F", 409 "0x1P1F", 410 "0X1P1F", 411 "0x1p1d", 412 "0X1p1d", 413 "0x1P1d", 414 "0X1P1d", 415 "0x1p1D", 416 "0X1p1D", 417 "0x1P1D", 418 "0X1P1D", 419 420 "-0x1p1", 421 "-0X1p1", 422 "-0x1P1", 423 "-0X1P1", 424 "-0x1p1f", 425 "-0X1p1f", 426 "-0x1P1f", 427 "-0X1P1f", 428 "-0x1p1F", 429 "-0X1p1F", 430 "-0x1P1F", 431 "-0X1P1F", 432 "-0x1p1d", 433 "-0X1p1d", 434 "-0x1P1d", 435 "-0X1P1d", 436 "-0x1p1D", 437 "-0X1p1D", 438 "-0x1P1D", 439 "-0X1P1D", 440 441 "0x1p-1", 442 "0X1p-1", 443 "0x1P-1", 444 "0X1P-1", 445 "0x1p-1f", 446 "0X1p-1f", 447 "0x1P-1f", 448 "0X1P-1f", 449 "0x1p-1F", 450 "0X1p-1F", 451 "0x1P-1F", 452 "0X1P-1F", 453 "0x1p-1d", 454 "0X1p-1d", 455 "0x1P-1d", 456 "0X1P-1d", 457 "0x1p-1D", 458 "0X1p-1D", 459 "0x1P-1D", 460 "0X1P-1D", 461 462 "-0x1p-1", 463 "-0X1p-1", 464 "-0x1P-1", 465 "-0X1P-1", 466 "-0x1p-1f", 467 "-0X1p-1f", 468 "-0x1P-1f", 469 "-0X1P-1f", 470 "-0x1p-1F", 471 "-0X1p-1F", 472 "-0x1P-1F", 473 "-0X1P-1F", 474 "-0x1p-1d", 475 "-0X1p-1d", 476 "-0x1P-1d", 477 "-0X1P-1d", 478 "-0x1p-1D", 479 "-0X1p-1D", 480 "-0x1P-1D", 481 "-0X1P-1D", 482 483 484 // Try different significand combinations 485 "0xap1", 486 "0xbp1", 487 "0xcp1", 488 "0xdp1", 489 "0xep1", 490 "0xfp1", 491 492 "0x1p1", 493 "0x.1p1", 494 "0x1.1p1", 495 496 "0x001p23", 497 "0x00.1p1", 498 "0x001.1p1", 499 500 "0x100p1", 501 "0x.100p1", 502 "0x1.100p1", 503 504 "0x00100p1", 505 "0x00.100p1", 506 "0x001.100p1", 507 508 // Limits 509 510 "1.7976931348623157E308", // Double.MAX_VALUE 511 "4.9e-324", // Double.MIN_VALUE 512 "2.2250738585072014e-308", // Double.MIN_NORMAL 513 514 "2.2250738585072012e-308", // near Double.MIN_NORMAL 515 516 "1.7976931348623158e+308", // near MAX_VALUE + ulp(MAX_VALUE)/2 517 "1.7976931348623159e+308", // near MAX_VALUE + ulp(MAX_VALUE) 518 519 "2.4703282292062329e-324", // above MIN_VALUE/2 520 "2.4703282292062327e-324", // MIN_VALUE/2 521 "2.4703282292062325e-324", // below MIN_VALUE/2 522 523 // 1e308 with leading zeros 524 525 "0.0000000000001e321", 526 "00.000000000000000001e326", 527 "00000.000000000000000001e326", 528 "000.0000000000000000001e327", 529 "0.00000000000000000001e328", 530 }; 531 532 static String paddedBadStrings[]; 533 static String paddedGoodStrings[]; 534 static { 535 String pad = " \t\n\r\f\u0001\u000b\u001f"; 536 paddedBadStrings = new String[badStrings.length]; 537 for(int i = 0 ; i < badStrings.length; i++) 538 paddedBadStrings[i] = pad + badStrings[i] + pad; 539 540 paddedGoodStrings = new String[goodStrings.length]; 541 for(int i = 0 ; i < goodStrings.length; i++) 542 paddedGoodStrings[i] = pad + goodStrings[i] + pad; 543 544 } 545 546 547 /* 548 * Throws an exception if <code>Input</code> is 549 * <code>exceptionalInput</code> and {@link Double.parseDouble 550 * parseDouble} does <em>not</em> throw an exception or if 551 * <code>Input</code> is not <code>exceptionalInput</code> and 552 * <code>parseDouble</code> throws an exception. This method does 553 * not attempt to test whether the string is converted to the 554 * proper value; just whether the input is accepted appropriately 555 * or not. 556 */ 557 private static void testParsing(String [] input, 558 boolean exceptionalInput) { 559 for(int i = 0; i < input.length; i++) { 560 double d; 561 562 try { 563 d = Double.parseDouble(input[i]); 564 check(input[i]); 565 } 566 catch (NumberFormatException e) { 567 if (! exceptionalInput) { 568 throw new RuntimeException("Double.parseDouble rejected " + 569 "good string `" + input[i] + 570 "'."); 571 } 572 break; 573 } 574 if (exceptionalInput) { 575 throw new RuntimeException("Double.parseDouble accepted " + 576 "bad string `" + input[i] + 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 */ 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 */ 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 */ 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 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 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 }