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 517 static String paddedBadStrings[]; 518 static String paddedGoodStrings[]; 519 static { 520 String pad = " \t\n\r\f\u0001\u000b\u001f"; 521 paddedBadStrings = new String[badStrings.length]; 522 for(int i = 0 ; i < badStrings.length; i++) 523 paddedBadStrings[i] = pad + badStrings[i] + pad; 524 525 paddedGoodStrings = new String[goodStrings.length]; 526 for(int i = 0 ; i < goodStrings.length; i++) 527 paddedGoodStrings[i] = pad + goodStrings[i] + pad; 528 529 } 530 531 532 /* 533 * Throws an exception if <code>Input</code> is 534 * <code>exceptionalInput</code> and {@link Double.parseDouble 535 * parseDouble} does <em>not</em> throw an exception or if 536 * <code>Input</code> is not <code>exceptionalInput</code> and 537 * <code>parseDouble</code> throws an exception. This method does 538 * not attempt to test whether the string is converted to the 539 * proper value; just whether the input is accepted appropriately 540 * or not. 541 */ 542 private static void testParsing(String [] input, 543 boolean exceptionalInput) { 544 for(int i = 0; i < input.length; i++) { 545 double d; 546 547 try { 548 d = Double.parseDouble(input[i]); 549 check(input[i]); 550 } 551 catch (NumberFormatException e) { 552 if (! exceptionalInput) { 553 throw new RuntimeException("Double.parseDouble rejected " + 554 "good string `" + input[i] + 555 "'."); 556 } 557 break; 558 } 559 if (exceptionalInput) { 560 throw new RuntimeException("Double.parseDouble accepted " + 561 "bad string `" + input[i] + 562 "'."); 563 } 564 } 565 } 566 567 /* 568 * Throws an exception if <code>Input</code> is 569 * <code>exceptionalInput</code> and the regular expression 570 * matches one of the strings or if <code>Input</code> is not 571 * <code>exceptionalInput</code> and the regular expression fails 572 * to match an input string. 573 */ 574 private static void testRegex(String [] input, boolean exceptionalInput) { 575 /* 576 * The regex below is taken from the JavaDoc for 577 * Double.valueOf. 578 */ 579 580 final String Digits = "(\\p{Digit}+)"; 581 final String HexDigits = "(\\p{XDigit}+)"; 582 // an exponent is 'e' or 'E' followed by an optionally 583 // signed decimal integer. 584 final String Exp = "[eE][+-]?"+Digits; 585 final String fpRegex = 586 ("[\\x00-\\x20]*"+ // Optional leading "whitespace" 587 "[+-]?(" + // Optional sign character 588 "NaN|" + // "NaN" string 589 "Infinity|" + // "Infinity" string 590 591 // A floating-point string representing a finite positive 592 // number without a leading sign has at most five basic pieces: 593 // Digits . Digits ExponentPart FloatTypeSuffix 594 // 595 // Since this method allows integer-only strings as input 596 // in addition to strings of floating-point literals, the 597 // two sub-patterns below are simplifications of the grammar 598 // productions from the Java Language Specification, 2nd 599 // edition, section 3.10.2. 600 601 602 // A decimal floating-point string representing a finite positive 603 // number without a leading sign has at most five basic pieces: 604 // Digits . Digits ExponentPart FloatTypeSuffix 605 // 606 // Since this method allows integer-only strings as input 607 // in addition to strings of floating-point literals, the 608 // two sub-patterns below are simplifications of the grammar 609 // productions from the Java Language Specification, 2nd 610 // edition, section 3.10.2. 611 612 // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt 613 "(((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ 614 615 // . Digits ExponentPart_opt FloatTypeSuffix_opt 616 "(\\.("+Digits+")("+Exp+")?))|"+ 617 618 // Hexadecimal strings 619 "((" + 620 // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt 621 "(0[xX]" + HexDigits + "(\\.)?)|" + 622 623 // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt 624 "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + 625 626 ")[pP][+-]?" + Digits + "))" + 627 "[fFdD]?))" + 628 "[\\x00-\\x20]*");// Optional trailing "whitespace" 629 Pattern fpPattern = Pattern.compile(fpRegex); 630 631 for(int i = 0; i < input.length; i++) { 632 Matcher m = fpPattern.matcher(input[i]); 633 if (m.matches() != ! exceptionalInput) { 634 throw new RuntimeException("Regular expression " + 635 (exceptionalInput? 636 "accepted bad": 637 "rejected good") + 638 " string `" + 639 input[i] + "'."); 640 } 641 } 642 643 } 644 645 /** 646 * For each subnormal power of two, test at boundaries of 647 * region that should convert to that value. 648 */ 649 private static void testSubnormalPowers() { 650 boolean failed = false; 651 BigDecimal TWO = BigDecimal.valueOf(2); 652 // An ulp is the same for all subnormal values 653 BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE); 654 655 // Test subnormal powers of two (except Double.MIN_VALUE) 656 for(int i = -1073; i <= -1022; i++) { 657 double d = Math.scalb(1.0, i); 658 659 /* 660 * The region [d - ulp/2, d + ulp/2] should round to d. 661 */ 662 BigDecimal d_BD = new BigDecimal(d); 663 664 BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO)); 665 BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO)); 666 667 double convertedLowerBound = Double.parseDouble(lowerBound.toString()); 668 double convertedUpperBound = Double.parseDouble(upperBound.toString()); 669 if (convertedLowerBound != d) { 670 failed = true; 671 System.out.printf("2^%d lowerBound converts as %a %s%n", 672 i, convertedLowerBound, lowerBound); 673 } 674 if (convertedUpperBound != d) { 675 failed = true; 676 System.out.printf("2^%d upperBound converts as %a %s%n", 677 i, convertedUpperBound, upperBound); 678 } 679 } 680 /* 681 * Double.MIN_VALUE 682 * The region ]0.5*Double.MIN_VALUE, 1.5*Double.MIN_VALUE[ should round to Double.MIN_VALUE . 683 */ 684 BigDecimal minValue = new BigDecimal(Double.MIN_VALUE); 685 if (Double.parseDouble(minValue.multiply(new BigDecimal(0.5)).toString()) != 0.0) { 686 failed = true; 687 System.out.printf("0.5*MIN_VALUE doesn't convert 0%n"); 688 } 689 if (Double.parseDouble(minValue.multiply(new BigDecimal(0.50000000001)).toString()) != Double.MIN_VALUE) { 690 failed = true; 691 System.out.printf("0.50000000001*MIN_VALUE doesn't convert to MIN_VALUE%n"); 692 } 693 if (Double.parseDouble(minValue.multiply(new BigDecimal(1.49999999999)).toString()) != Double.MIN_VALUE) { 694 failed = true; 695 System.out.printf("1.49999999999*MIN_VALUE doesn't convert to MIN_VALUE%n"); 696 } 697 if (Double.parseDouble(minValue.multiply(new BigDecimal(1.5)).toString()) != 2*Double.MIN_VALUE) { 698 failed = true; 699 System.out.printf("1.5*MIN_VALUE doesn't convert to 2*MIN_VALUE%n"); 700 } 701 702 if (failed) 703 throw new RuntimeException("Inconsistent conversion"); 704 } 705 706 /** 707 * For each power of two, test at boundaries of 708 * region that should convert to that value. 709 */ 710 private static void testPowers() { 711 for(int i = -1074; i <= +1023; i++) { 712 double d = Math.scalb(1.0, i); 713 BigDecimal d_BD = new BigDecimal(d); 714 715 BigDecimal lowerBound = d_BD.subtract(new BigDecimal(Math.ulp(Math.nextUp(-d))).multiply(HALF)); 716 BigDecimal upperBound = d_BD.add(new BigDecimal(Math.ulp(d)).multiply(HALF)); 717 718 check(lowerBound.toString()); 719 check(upperBound.toString()); 720 } 721 check(new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(Math.ulp(Double.MAX_VALUE)).multiply(HALF)).toString()); 722 } 723 724 private static void testStrictness() { 725 final double expected = 0x0.0000008000000p-1022; 726 // final double expected = 0x0.0000008000001p-1022; 727 boolean failed = false; 728 double conversion = 0.0; 729 double sum = 0.0; // Prevent conversion from being optimized away 730 731 //2^-1047 + 2^-1075 rounds to 2^-1047 732 String decimal = "6.631236871469758276785396630275967243399099947355303144249971758736286630139265439618068200788048744105960420552601852889715006376325666595539603330361800519107591783233358492337208057849499360899425128640718856616503093444922854759159988160304439909868291973931426625698663157749836252274523485312442358651207051292453083278116143932569727918709786004497872322193856150225415211997283078496319412124640111777216148110752815101775295719811974338451936095907419622417538473679495148632480391435931767981122396703443803335529756003353209830071832230689201383015598792184172909927924176339315507402234836120730914783168400715462440053817592702766213559042115986763819482654128770595766806872783349146967171293949598850675682115696218943412532098591327667236328125E-316"; 733 734 for(int i = 0; i <= 12_000; i++) { 735 conversion = Double.parseDouble(decimal); 736 sum += conversion; 737 if (conversion != expected) { 738 failed = true; 739 System.out.printf("Iteration %d converts as %a%n", 740 i, conversion); 741 } 742 } 743 744 System.out.println("Sum = " + sum); 745 if (failed) 746 throw new RuntimeException("Inconsistent conversion"); 747 } 748 749 public static void main(String[] args) throws Exception { 750 rudimentaryTest(); 751 752 testParsing(goodStrings, false); 753 testParsing(paddedGoodStrings, false); 754 testParsing(badStrings, true); 755 testParsing(paddedBadStrings, true); 756 757 testRegex(goodStrings, false); 758 testRegex(paddedGoodStrings, false); 759 testRegex(badStrings, true); 760 testRegex(paddedBadStrings, true); 761 762 testSubnormalPowers(); 763 testPowers(); 764 testStrictness(); 765 } 766 }