Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/Double/ParseDouble.java
38813 views
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
}
767
768