Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/Math/Tests.java
41149 views
1
/*
2
* Copyright (c) 2003, 2016, 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
* Shared static test methods for numerical tests. Sharing these
26
* helper test methods avoids repeated functions in the various test
27
* programs. The test methods return 1 for a test failure and 0 for
28
* success. The order of arguments to the test methods is generally
29
* the test name, followed by the test arguments, the computed result,
30
* and finally the expected result.
31
*/
32
33
public class Tests {
34
private Tests(){}; // do not instantiate
35
36
public static String toHexString(float f) {
37
if (!Float.isNaN(f))
38
return Float.toHexString(f);
39
else
40
return "NaN(0x" + Integer.toHexString(Float.floatToRawIntBits(f)) + ")";
41
}
42
43
public static String toHexString(double d) {
44
if (!Double.isNaN(d))
45
return Double.toHexString(d);
46
else
47
return "NaN(0x" + Long.toHexString(Double.doubleToRawLongBits(d)) + ")";
48
}
49
50
/**
51
* Return the floating-point value next larger in magnitude.
52
*/
53
public static double nextOut(double d) {
54
if (d > 0.0)
55
return Math.nextUp(d);
56
else
57
return -Math.nextUp(-d);
58
}
59
60
/**
61
* Returns unbiased exponent of a {@code float}; for
62
* subnormal values, the number is treated as if it were
63
* normalized. That is for all finite, non-zero, positive numbers
64
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
65
* always in the range [1, 2).
66
* <p>
67
* Special cases:
68
* <ul>
69
* <li> If the argument is NaN, then the result is 2<sup>30</sup>.
70
* <li> If the argument is infinite, then the result is 2<sup>28</sup>.
71
* <li> If the argument is zero, then the result is -(2<sup>28</sup>).
72
* </ul>
73
*
74
* @param f floating-point number whose exponent is to be extracted
75
* @return unbiased exponent of the argument.
76
*/
77
public static int ilogb(double d) {
78
int exponent = Math.getExponent(d);
79
80
switch (exponent) {
81
case Double.MAX_EXPONENT+1: // NaN or infinity
82
if( Double.isNaN(d) )
83
return (1<<30); // 2^30
84
else // infinite value
85
return (1<<28); // 2^28
86
87
case Double.MIN_EXPONENT-1: // zero or subnormal
88
if(d == 0.0) {
89
return -(1<<28); // -(2^28)
90
}
91
else {
92
long transducer = Double.doubleToRawLongBits(d);
93
94
/*
95
* To avoid causing slow arithmetic on subnormals,
96
* the scaling to determine when d's significand
97
* is normalized is done in integer arithmetic.
98
* (there must be at least one "1" bit in the
99
* significand since zero has been screened out.
100
*/
101
102
// isolate significand bits
103
transducer &= DoubleConsts.SIGNIF_BIT_MASK;
104
assert(transducer != 0L);
105
106
// This loop is simple and functional. We might be
107
// able to do something more clever that was faster;
108
// e.g. number of leading zero detection on
109
// (transducer << (# exponent and sign bits).
110
while (transducer <
111
(1L << (DoubleConsts.SIGNIFICAND_WIDTH - 1))) {
112
transducer *= 2;
113
exponent--;
114
}
115
exponent++;
116
assert( exponent >=
117
Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1) &&
118
exponent < Double.MIN_EXPONENT);
119
return exponent;
120
}
121
122
default:
123
assert( exponent >= Double.MIN_EXPONENT &&
124
exponent <= Double.MAX_EXPONENT);
125
return exponent;
126
}
127
}
128
129
/**
130
* Returns unbiased exponent of a {@code float}; for
131
* subnormal values, the number is treated as if it were
132
* normalized. That is for all finite, non-zero, positive numbers
133
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
134
* always in the range [1, 2).
135
* <p>
136
* Special cases:
137
* <ul>
138
* <li> If the argument is NaN, then the result is 2<sup>30</sup>.
139
* <li> If the argument is infinite, then the result is 2<sup>28</sup>.
140
* <li> If the argument is zero, then the result is -(2<sup>28</sup>).
141
* </ul>
142
*
143
* @param f floating-point number whose exponent is to be extracted
144
* @return unbiased exponent of the argument.
145
*/
146
public static int ilogb(float f) {
147
int exponent = Math.getExponent(f);
148
149
switch (exponent) {
150
case Float.MAX_EXPONENT+1: // NaN or infinity
151
if( Float.isNaN(f) )
152
return (1<<30); // 2^30
153
else // infinite value
154
return (1<<28); // 2^28
155
156
case Float.MIN_EXPONENT-1: // zero or subnormal
157
if(f == 0.0f) {
158
return -(1<<28); // -(2^28)
159
}
160
else {
161
int transducer = Float.floatToRawIntBits(f);
162
163
/*
164
* To avoid causing slow arithmetic on subnormals,
165
* the scaling to determine when f's significand
166
* is normalized is done in integer arithmetic.
167
* (there must be at least one "1" bit in the
168
* significand since zero has been screened out.
169
*/
170
171
// isolate significand bits
172
transducer &= FloatConsts.SIGNIF_BIT_MASK;
173
assert(transducer != 0);
174
175
// This loop is simple and functional. We might be
176
// able to do something more clever that was faster;
177
// e.g. number of leading zero detection on
178
// (transducer << (# exponent and sign bits).
179
while (transducer <
180
(1 << (FloatConsts.SIGNIFICAND_WIDTH - 1))) {
181
transducer *= 2;
182
exponent--;
183
}
184
exponent++;
185
assert( exponent >=
186
Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1) &&
187
exponent < Float.MIN_EXPONENT);
188
return exponent;
189
}
190
191
default:
192
assert( exponent >= Float.MIN_EXPONENT &&
193
exponent <= Float.MAX_EXPONENT);
194
return exponent;
195
}
196
}
197
198
/**
199
* Returns {@code true} if the unordered relation holds
200
* between the two arguments. When two floating-point values are
201
* unordered, one value is neither less than, equal to, nor
202
* greater than the other. For the unordered relation to be true,
203
* at least one argument must be a {@code NaN}.
204
*
205
* @param arg1 the first argument
206
* @param arg2 the second argument
207
* @return {@code true} if at least one argument is a NaN,
208
* {@code false} otherwise.
209
*/
210
public static boolean isUnordered(float arg1, float arg2) {
211
return Float.isNaN(arg1) || Float.isNaN(arg2);
212
}
213
214
/**
215
* Returns {@code true} if the unordered relation holds
216
* between the two arguments. When two floating-point values are
217
* unordered, one value is neither less than, equal to, nor
218
* greater than the other. For the unordered relation to be true,
219
* at least one argument must be a {@code NaN}.
220
*
221
* @param arg1 the first argument
222
* @param arg2 the second argument
223
* @return {@code true} if at least one argument is a NaN,
224
* {@code false} otherwise.
225
*/
226
public static boolean isUnordered(double arg1, double arg2) {
227
return Double.isNaN(arg1) || Double.isNaN(arg2);
228
}
229
230
public static int test(String testName, float input,
231
boolean result, boolean expected) {
232
if (expected != result) {
233
System.err.println("Failure for " + testName + ":\n" +
234
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
235
"\texpected " + expected + "\n" +
236
"\tgot " + result + ").");
237
return 1;
238
}
239
else
240
return 0;
241
}
242
243
public static int test(String testName, double input,
244
boolean result, boolean expected) {
245
if (expected != result) {
246
System.err.println("Failure for " + testName + ":\n" +
247
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
248
"\texpected " + expected + "\n" +
249
"\tgot " + result + ").");
250
return 1;
251
}
252
else
253
return 0;
254
}
255
256
public static int test(String testName, float input1, float input2,
257
boolean result, boolean expected) {
258
if (expected != result) {
259
System.err.println("Failure for " + testName + ":\n" +
260
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
261
+ input2 + "\t(" + toHexString(input2) + ")\n" +
262
"\texpected " + expected + "\n" +
263
"\tgot " + result + ").");
264
return 1;
265
}
266
return 0;
267
}
268
269
public static int test(String testName, double input1, double input2,
270
boolean result, boolean expected) {
271
if (expected != result) {
272
System.err.println("Failure for " + testName + ":\n" +
273
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
274
+ input2 + "\t(" + toHexString(input2) + ")\n" +
275
"\texpected " + expected + "\n" +
276
"\tgot " + result + ").");
277
return 1;
278
}
279
return 0;
280
}
281
282
public static int test(String testName, float input,
283
int result, int expected) {
284
if (expected != result) {
285
System.err.println("Failure for " + testName + ":\n" +
286
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
287
"\texpected " + expected + "\n" +
288
"\tgot " + result + ").");
289
return 1;
290
}
291
return 0;
292
}
293
294
public static int test(String testName, double input,
295
int result, int expected) {
296
if (expected != result) {
297
System.err.println("Failure for " + testName + ":\n" +
298
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
299
"\texpected " + expected + "\n" +
300
"\tgot " + result + ").");
301
return 1;
302
}
303
else
304
return 0;
305
}
306
307
public static int test(String testName, float input,
308
float result, float expected) {
309
if (Float.compare(expected, result) != 0 ) {
310
System.err.println("Failure for " + testName + ":\n" +
311
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
312
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
313
"\tgot " + result + "\t(" + toHexString(result) + ").");
314
return 1;
315
}
316
else
317
return 0;
318
}
319
320
321
public static int test(String testName, double input,
322
double result, double expected) {
323
if (Double.compare(expected, result ) != 0) {
324
System.err.println("Failure for " + testName + ":\n" +
325
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
326
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
327
"\tgot " + result + "\t(" + toHexString(result) + ").");
328
return 1;
329
}
330
else
331
return 0;
332
}
333
334
public static int test(String testName,
335
float input1, double input2,
336
float result, float expected) {
337
if (Float.compare(expected, result ) != 0) {
338
System.err.println("Failure for " + testName + ":\n" +
339
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
340
+ input2 + "\t(" + toHexString(input2) + ")\n" +
341
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
342
"\tgot " + result + "\t(" + toHexString(result) + ").");
343
return 1;
344
}
345
else
346
return 0;
347
}
348
349
public static int test(String testName,
350
double input1, double input2,
351
double result, double expected) {
352
if (Double.compare(expected, result ) != 0) {
353
System.err.println("Failure for " + testName + ":\n" +
354
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
355
+ input2 + "\t(" + toHexString(input2) + ")\n" +
356
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
357
"\tgot " + result + "\t(" + toHexString(result) + ").");
358
return 1;
359
}
360
else
361
return 0;
362
}
363
364
public static int test(String testName,
365
float input1, int input2,
366
float result, float expected) {
367
if (Float.compare(expected, result ) != 0) {
368
System.err.println("Failure for " + testName + ":\n" +
369
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
370
+ input2 + "\n" +
371
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
372
"\tgot " + result + "\t(" + toHexString(result) + ").");
373
return 1;
374
}
375
else
376
return 0;
377
}
378
379
public static int test(String testName,
380
double input1, int input2,
381
double result, double expected) {
382
if (Double.compare(expected, result ) != 0) {
383
System.err.println("Failure for " + testName + ":\n" +
384
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
385
+ input2 + "\n" +
386
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
387
"\tgot " + result + "\t(" + toHexString(result) + ").");
388
return 1;
389
}
390
else
391
return 0;
392
}
393
394
public static int test(String testName,
395
float input1, float input2, float input3,
396
float result, float expected) {
397
if (Float.compare(expected, result ) != 0) {
398
System.err.println("Failure for " + testName + ":\n" +
399
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
400
+ input2 + "\t(" + toHexString(input2) + ") and"
401
+ input3 + "\t(" + toHexString(input3) + ")\n" +
402
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
403
"\tgot " + result + "\t(" + toHexString(result) + ").");
404
return 1;
405
}
406
else
407
return 0;
408
}
409
410
public static int test(String testName,
411
double input1, double input2, double input3,
412
double result, double expected) {
413
if (Double.compare(expected, result ) != 0) {
414
System.err.println("Failure for " + testName + ":\n" +
415
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
416
+ input2 + "\t(" + toHexString(input2) + ") and"
417
+ input3 + "\t(" + toHexString(input3) + ")\n" +
418
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
419
"\tgot " + result + "\t(" + toHexString(result) + ").");
420
return 1;
421
}
422
else
423
return 0;
424
}
425
426
static int testUlpCore(double result, double expected, double ulps) {
427
// We assume we won't be unlucky and have an inexact expected
428
// be nextDown(2^i) when 2^i would be the correctly rounded
429
// answer. This would cause the ulp size to be half as large
430
// as it should be, doubling the measured error).
431
432
if (Double.compare(expected, result) == 0) {
433
return 0; // result and expected are equivalent
434
} else {
435
if( ulps == 0.0) {
436
// Equivalent results required but not found
437
return 1;
438
} else {
439
double difference = expected - result;
440
if (isUnordered(expected, result) ||
441
Double.isNaN(difference) ||
442
// fail if greater than or unordered
443
!(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) {
444
return 1;
445
}
446
else
447
return 0;
448
}
449
}
450
}
451
452
// One input argument.
453
public static int testUlpDiff(String testName, double input,
454
double result, double expected, double ulps) {
455
int code = testUlpCore(result, expected, ulps);
456
if (code == 1) {
457
System.err.println("Failure for " + testName + ":\n" +
458
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
459
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
460
"\tgot " + result + "\t(" + toHexString(result) + ");\n" +
461
"\tdifference greater than ulp tolerance " + ulps);
462
}
463
return code;
464
}
465
466
// Two input arguments.
467
public static int testUlpDiff(String testName, double input1, double input2,
468
double result, double expected, double ulps) {
469
int code = testUlpCore(result, expected, ulps);
470
if (code == 1) {
471
System.err.println("Failure for " + testName + ":\n" +
472
"\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
473
+ input2 + "\t(" + toHexString(input2) + ")\n" +
474
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
475
"\tgot " + result + "\t(" + toHexString(result) + ");\n" +
476
"\tdifference greater than ulp tolerance " + ulps);
477
}
478
return code;
479
}
480
481
// For a successful test, the result must be within the ulp bound of
482
// expected AND the result must have absolute value less than or
483
// equal to absBound.
484
public static int testUlpDiffWithAbsBound(String testName, double input,
485
double result, double expected,
486
double ulps, double absBound) {
487
int code = 0; // return code value
488
489
if (!(StrictMath.abs(result) <= StrictMath.abs(absBound)) &&
490
!Double.isNaN(expected)) {
491
code = 1;
492
} else
493
code = testUlpCore(result, expected, ulps);
494
495
if (code == 1) {
496
System.err.println("Failure for " + testName + ":\n" +
497
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
498
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
499
"\tgot " + result + "\t(" + toHexString(result) + ");\n" +
500
"\tdifference greater than ulp tolerance " + ulps +
501
" or the result has larger magnitude than " + absBound);
502
}
503
return code;
504
}
505
506
// For a successful test, the result must be within the ulp bound of
507
// expected AND the result must have absolute value greater than
508
// or equal to the lowerBound.
509
public static int testUlpDiffWithLowerBound(String testName, double input,
510
double result, double expected,
511
double ulps, double lowerBound) {
512
int code = 0; // return code value
513
514
if (!(result >= lowerBound) && !Double.isNaN(expected)) {
515
code = 1;
516
} else
517
code = testUlpCore(result, expected, ulps);
518
519
if (code == 1) {
520
System.err.println("Failure for " + testName +
521
":\n" +
522
"\tFor input " + input + "\t(" + toHexString(input) + ")" +
523
"\n\texpected " + expected + "\t(" + toHexString(expected) + ")" +
524
"\n\tgot " + result + "\t(" + toHexString(result) + ");" +
525
"\ndifference greater than ulp tolerance " + ulps +
526
" or result not greater than or equal to the bound " + lowerBound);
527
}
528
return code;
529
}
530
531
public static int testTolerance(String testName, double input,
532
double result, double expected, double tolerance) {
533
if (Double.compare(expected, result ) != 0) {
534
double difference = expected - result;
535
if (isUnordered(expected, result) ||
536
Double.isNaN(difference) ||
537
// fail if greater than or unordered
538
!(Math.abs((difference)/expected) <= StrictMath.pow(10, -tolerance)) ) {
539
System.err.println("Failure for " + testName + ":\n" +
540
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
541
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
542
"\tgot " + result + "\t(" + toHexString(result) + ");\n" +
543
"\tdifference greater than tolerance 10^-" + tolerance);
544
return 1;
545
}
546
return 0;
547
}
548
else
549
return 0;
550
}
551
552
// For a successful test, the result must be within the upper and
553
// lower bounds.
554
public static int testBounds(String testName, double input, double result,
555
double bound1, double bound2) {
556
if ((result >= bound1 && result <= bound2) ||
557
(result <= bound1 && result >= bound2))
558
return 0;
559
else {
560
double lowerBound = Math.min(bound1, bound2);
561
double upperBound = Math.max(bound1, bound2);
562
System.err.println("Failure for " + testName + ":\n" +
563
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
564
"\tgot " + result + "\t(" + toHexString(result) + ");\n" +
565
"\toutside of range\n" +
566
"\t[" + lowerBound + "\t(" + toHexString(lowerBound) + "), " +
567
upperBound + "\t(" + toHexString(upperBound) + ")]");
568
return 1;
569
}
570
}
571
}
572
573