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/Math/IeeeRecommendedTests.java
38812 views
1
/*
2
* Copyright (c) 2003, 2011, 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 4860891 4826732 4780454 4939441 4826652
27
* @summary Tests for IEEE 754[R] recommended functions and similar methods
28
* @author Joseph D. Darcy
29
* @key randomness
30
*/
31
32
import sun.misc.FpUtils;
33
import sun.misc.DoubleConsts;
34
import sun.misc.FloatConsts;
35
36
public class IeeeRecommendedTests {
37
private IeeeRecommendedTests(){}
38
39
static final float NaNf = Float.NaN;
40
static final double NaNd = Double.NaN;
41
static final float infinityF = Float.POSITIVE_INFINITY;
42
static final double infinityD = Double.POSITIVE_INFINITY;
43
44
static final float Float_MAX_VALUEmm = 0x1.fffffcP+127f;
45
static final float Float_MAX_SUBNORMAL = 0x0.fffffeP-126f;
46
static final float Float_MAX_SUBNORMALmm = 0x0.fffffcP-126f;
47
48
static final double Double_MAX_VALUEmm = 0x1.ffffffffffffeP+1023;
49
static final double Double_MAX_SUBNORMAL = 0x0.fffffffffffffP-1022;
50
static final double Double_MAX_SUBNORMALmm = 0x0.ffffffffffffeP-1022;
51
52
// Initialize shared random number generator
53
static java.util.Random rand = new java.util.Random();
54
55
/**
56
* Returns a floating-point power of two in the normal range.
57
*/
58
static double powerOfTwoD(int n) {
59
return Double.longBitsToDouble((((long)n + (long)DoubleConsts.MAX_EXPONENT) <<
60
(DoubleConsts.SIGNIFICAND_WIDTH-1))
61
& DoubleConsts.EXP_BIT_MASK);
62
}
63
64
/**
65
* Returns a floating-point power of two in the normal range.
66
*/
67
static float powerOfTwoF(int n) {
68
return Float.intBitsToFloat(((n + FloatConsts.MAX_EXPONENT) <<
69
(FloatConsts.SIGNIFICAND_WIDTH-1))
70
& FloatConsts.EXP_BIT_MASK);
71
}
72
73
/* ******************** getExponent tests ****************************** */
74
75
/*
76
* The tests for getExponent should test the special values (NaN, +/-
77
* infinity, etc.), test the endpoints of each binade (set of
78
* floating-point values with the same exponent), and for good
79
* measure, test some random values within each binade. Testing
80
* the endpoints of each binade includes testing both positive and
81
* negative numbers. Subnormal values with different normalized
82
* exponents should be tested too. Both Math and StrictMath
83
* methods should return the same results.
84
*/
85
86
/*
87
* Test Math.getExponent and StrictMath.getExponent with +d and -d.
88
*/
89
static int testGetExponentCase(float f, int expected) {
90
float minus_f = -f;
91
int failures=0;
92
93
failures+=Tests.test("Math.getExponent(float)", f,
94
Math.getExponent(f), expected);
95
failures+=Tests.test("Math.getExponent(float)", minus_f,
96
Math.getExponent(minus_f), expected);
97
98
failures+=Tests.test("StrictMath.getExponent(float)", f,
99
StrictMath.getExponent(f), expected);
100
failures+=Tests.test("StrictMath.getExponent(float)", minus_f,
101
StrictMath.getExponent(minus_f), expected);
102
return failures;
103
}
104
105
/*
106
* Test Math.getExponent and StrictMath.getExponent with +d and -d.
107
*/
108
static int testGetExponentCase(double d, int expected) {
109
double minus_d = -d;
110
int failures=0;
111
112
failures+=Tests.test("Math.getExponent(double)", d,
113
Math.getExponent(d), expected);
114
failures+=Tests.test("Math.getExponent(double)", minus_d,
115
Math.getExponent(minus_d), expected);
116
117
failures+=Tests.test("StrictMath.getExponent(double)", d,
118
StrictMath.getExponent(d), expected);
119
failures+=Tests.test("StrictMath.getExponent(double)", minus_d,
120
StrictMath.getExponent(minus_d), expected);
121
return failures;
122
}
123
124
public static int testFloatGetExponent() {
125
int failures = 0;
126
float [] specialValues = {NaNf,
127
Float.POSITIVE_INFINITY,
128
+0.0f,
129
+1.0f,
130
+2.0f,
131
+16.0f,
132
+Float.MIN_VALUE,
133
+Float_MAX_SUBNORMAL,
134
+FloatConsts.MIN_NORMAL,
135
+Float.MAX_VALUE
136
};
137
138
int [] specialResults = {Float.MAX_EXPONENT + 1, // NaN results
139
Float.MAX_EXPONENT + 1, // Infinite results
140
Float.MIN_EXPONENT - 1, // Zero results
141
0,
142
1,
143
4,
144
FloatConsts.MIN_EXPONENT - 1,
145
-FloatConsts.MAX_EXPONENT,
146
FloatConsts.MIN_EXPONENT,
147
FloatConsts.MAX_EXPONENT
148
};
149
150
// Special value tests
151
for(int i = 0; i < specialValues.length; i++) {
152
failures += testGetExponentCase(specialValues[i], specialResults[i]);
153
}
154
155
156
// Normal exponent tests
157
for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {
158
int result;
159
160
// Create power of two
161
float po2 = powerOfTwoF(i);
162
163
failures += testGetExponentCase(po2, i);
164
165
// Generate some random bit patterns for the significand
166
for(int j = 0; j < 10; j++) {
167
int randSignif = rand.nextInt();
168
float randFloat;
169
170
randFloat = Float.intBitsToFloat( // Exponent
171
(Float.floatToIntBits(po2)&
172
(~FloatConsts.SIGNIF_BIT_MASK)) |
173
// Significand
174
(randSignif &
175
FloatConsts.SIGNIF_BIT_MASK) );
176
177
failures += testGetExponentCase(randFloat, i);
178
}
179
180
if (i > FloatConsts.MIN_EXPONENT) {
181
float po2minus = Math.nextAfter(po2,
182
Float.NEGATIVE_INFINITY);
183
failures += testGetExponentCase(po2minus, i-1);
184
}
185
}
186
187
// Subnormal exponent tests
188
189
/*
190
* Start with MIN_VALUE, left shift, test high value, low
191
* values, and random in between.
192
*
193
* Use nextAfter to calculate, high value of previous binade,
194
* loop count i will indicate how many random bits, if any are
195
* needed.
196
*/
197
198
float top=Float.MIN_VALUE;
199
for( int i = 1;
200
i < FloatConsts.SIGNIFICAND_WIDTH;
201
i++, top *= 2.0f) {
202
203
failures += testGetExponentCase(top,
204
FloatConsts.MIN_EXPONENT - 1);
205
206
// Test largest value in next smaller binade
207
if (i >= 3) {// (i == 1) would test 0.0;
208
// (i == 2) would just retest MIN_VALUE
209
testGetExponentCase(Math.nextAfter(top, 0.0f),
210
FloatConsts.MIN_EXPONENT - 1);
211
212
if( i >= 10) {
213
// create a bit mask with (i-1) 1's in the low order
214
// bits
215
int mask = ~((~0)<<(i-1));
216
float randFloat = Float.intBitsToFloat( // Exponent
217
Float.floatToIntBits(top) |
218
// Significand
219
(rand.nextInt() & mask ) ) ;
220
221
failures += testGetExponentCase(randFloat,
222
FloatConsts.MIN_EXPONENT - 1);
223
}
224
}
225
}
226
227
return failures;
228
}
229
230
231
public static int testDoubleGetExponent() {
232
int failures = 0;
233
double [] specialValues = {NaNd,
234
infinityD,
235
+0.0,
236
+1.0,
237
+2.0,
238
+16.0,
239
+Double.MIN_VALUE,
240
+Double_MAX_SUBNORMAL,
241
+DoubleConsts.MIN_NORMAL,
242
+Double.MAX_VALUE
243
};
244
245
int [] specialResults = {Double.MAX_EXPONENT + 1, // NaN results
246
Double.MAX_EXPONENT + 1, // Infinite results
247
Double.MIN_EXPONENT - 1, // Zero results
248
0,
249
1,
250
4,
251
DoubleConsts.MIN_EXPONENT - 1,
252
-DoubleConsts.MAX_EXPONENT,
253
DoubleConsts.MIN_EXPONENT,
254
DoubleConsts.MAX_EXPONENT
255
};
256
257
// Special value tests
258
for(int i = 0; i < specialValues.length; i++) {
259
failures += testGetExponentCase(specialValues[i], specialResults[i]);
260
}
261
262
263
// Normal exponent tests
264
for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {
265
int result;
266
267
// Create power of two
268
double po2 = powerOfTwoD(i);
269
270
failures += testGetExponentCase(po2, i);
271
272
// Generate some random bit patterns for the significand
273
for(int j = 0; j < 10; j++) {
274
long randSignif = rand.nextLong();
275
double randFloat;
276
277
randFloat = Double.longBitsToDouble( // Exponent
278
(Double.doubleToLongBits(po2)&
279
(~DoubleConsts.SIGNIF_BIT_MASK)) |
280
// Significand
281
(randSignif &
282
DoubleConsts.SIGNIF_BIT_MASK) );
283
284
failures += testGetExponentCase(randFloat, i);
285
}
286
287
if (i > DoubleConsts.MIN_EXPONENT) {
288
double po2minus = Math.nextAfter(po2,
289
Double.NEGATIVE_INFINITY);
290
failures += testGetExponentCase(po2minus, i-1);
291
}
292
}
293
294
// Subnormal exponent tests
295
296
/*
297
* Start with MIN_VALUE, left shift, test high value, low
298
* values, and random in between.
299
*
300
* Use nextAfter to calculate, high value of previous binade;
301
* loop count i will indicate how many random bits, if any are
302
* needed.
303
*/
304
305
double top=Double.MIN_VALUE;
306
for( int i = 1;
307
i < DoubleConsts.SIGNIFICAND_WIDTH;
308
i++, top *= 2.0f) {
309
310
failures += testGetExponentCase(top,
311
DoubleConsts.MIN_EXPONENT - 1);
312
313
// Test largest value in next smaller binade
314
if (i >= 3) {// (i == 1) would test 0.0;
315
// (i == 2) would just retest MIN_VALUE
316
testGetExponentCase(Math.nextAfter(top, 0.0),
317
DoubleConsts.MIN_EXPONENT - 1);
318
319
if( i >= 10) {
320
// create a bit mask with (i-1) 1's in the low order
321
// bits
322
long mask = ~((~0L)<<(i-1));
323
double randFloat = Double.longBitsToDouble( // Exponent
324
Double.doubleToLongBits(top) |
325
// Significand
326
(rand.nextLong() & mask ) ) ;
327
328
failures += testGetExponentCase(randFloat,
329
DoubleConsts.MIN_EXPONENT - 1);
330
}
331
}
332
}
333
334
return failures;
335
}
336
337
338
/* ******************** nextAfter tests ****************************** */
339
340
static int testNextAfterCase(float start, double direction, float expected) {
341
int failures=0;
342
float minus_start = -start;
343
double minus_direction = -direction;
344
float minus_expected = -expected;
345
346
failures+=Tests.test("Math.nextAfter(float,double)", start, direction,
347
Math.nextAfter(start, direction), expected);
348
failures+=Tests.test("Math.nextAfter(float,double)", minus_start, minus_direction,
349
Math.nextAfter(minus_start, minus_direction), minus_expected);
350
351
failures+=Tests.test("StrictMath.nextAfter(float,double)", start, direction,
352
StrictMath.nextAfter(start, direction), expected);
353
failures+=Tests.test("StrictMath.nextAfter(float,double)", minus_start, minus_direction,
354
StrictMath.nextAfter(minus_start, minus_direction), minus_expected);
355
return failures;
356
}
357
358
static int testNextAfterCase(double start, double direction, double expected) {
359
int failures=0;
360
361
double minus_start = -start;
362
double minus_direction = -direction;
363
double minus_expected = -expected;
364
365
failures+=Tests.test("Math.nextAfter(double,double)", start, direction,
366
Math.nextAfter(start, direction), expected);
367
failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction,
368
Math.nextAfter(minus_start, minus_direction), minus_expected);
369
370
failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction,
371
StrictMath.nextAfter(start, direction), expected);
372
failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction,
373
StrictMath.nextAfter(minus_start, minus_direction), minus_expected);
374
return failures;
375
}
376
377
public static int testFloatNextAfter() {
378
int failures=0;
379
380
/*
381
* Each row of the testCases matrix represents one test case
382
* for nexAfter; given the input of the first two columns, the
383
* result in the last column is expected.
384
*/
385
float [][] testCases = {
386
{NaNf, NaNf, NaNf},
387
{NaNf, 0.0f, NaNf},
388
{0.0f, NaNf, NaNf},
389
{NaNf, infinityF, NaNf},
390
{infinityF, NaNf, NaNf},
391
392
{infinityF, infinityF, infinityF},
393
{infinityF, -infinityF, Float.MAX_VALUE},
394
{infinityF, 0.0f, Float.MAX_VALUE},
395
396
{Float.MAX_VALUE, infinityF, infinityF},
397
{Float.MAX_VALUE, -infinityF, Float_MAX_VALUEmm},
398
{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE},
399
{Float.MAX_VALUE, 0.0f, Float_MAX_VALUEmm},
400
401
{Float_MAX_VALUEmm, Float.MAX_VALUE, Float.MAX_VALUE},
402
{Float_MAX_VALUEmm, infinityF, Float.MAX_VALUE},
403
{Float_MAX_VALUEmm, Float_MAX_VALUEmm, Float_MAX_VALUEmm},
404
405
{FloatConsts.MIN_NORMAL, infinityF, FloatConsts.MIN_NORMAL+
406
Float.MIN_VALUE},
407
{FloatConsts.MIN_NORMAL, -infinityF, Float_MAX_SUBNORMAL},
408
{FloatConsts.MIN_NORMAL, 1.0f, FloatConsts.MIN_NORMAL+
409
Float.MIN_VALUE},
410
{FloatConsts.MIN_NORMAL, -1.0f, Float_MAX_SUBNORMAL},
411
{FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},
412
413
{Float_MAX_SUBNORMAL, FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},
414
{Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL},
415
{Float_MAX_SUBNORMAL, 0.0f, Float_MAX_SUBNORMALmm},
416
417
{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL},
418
{Float_MAX_SUBNORMALmm, 0.0f, Float_MAX_SUBNORMALmm-Float.MIN_VALUE},
419
{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm},
420
421
{Float.MIN_VALUE, 0.0f, 0.0f},
422
{-Float.MIN_VALUE, 0.0f, -0.0f},
423
{Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE},
424
{Float.MIN_VALUE, 1.0f, 2*Float.MIN_VALUE},
425
426
// Make sure zero behavior is tested
427
{0.0f, 0.0f, 0.0f},
428
{0.0f, -0.0f, -0.0f},
429
{-0.0f, 0.0f, 0.0f},
430
{-0.0f, -0.0f, -0.0f},
431
{0.0f, infinityF, Float.MIN_VALUE},
432
{0.0f, -infinityF, -Float.MIN_VALUE},
433
{-0.0f, infinityF, Float.MIN_VALUE},
434
{-0.0f, -infinityF, -Float.MIN_VALUE},
435
{0.0f, Float.MIN_VALUE, Float.MIN_VALUE},
436
{0.0f, -Float.MIN_VALUE, -Float.MIN_VALUE},
437
{-0.0f, Float.MIN_VALUE, Float.MIN_VALUE},
438
{-0.0f, -Float.MIN_VALUE, -Float.MIN_VALUE}
439
};
440
441
for(int i = 0; i < testCases.length; i++) {
442
failures += testNextAfterCase(testCases[i][0], testCases[i][1],
443
testCases[i][2]);
444
}
445
446
return failures;
447
}
448
449
public static int testDoubleNextAfter() {
450
int failures =0;
451
452
/*
453
* Each row of the testCases matrix represents one test case
454
* for nexAfter; given the input of the first two columns, the
455
* result in the last column is expected.
456
*/
457
double [][] testCases = {
458
{NaNd, NaNd, NaNd},
459
{NaNd, 0.0d, NaNd},
460
{0.0d, NaNd, NaNd},
461
{NaNd, infinityD, NaNd},
462
{infinityD, NaNd, NaNd},
463
464
{infinityD, infinityD, infinityD},
465
{infinityD, -infinityD, Double.MAX_VALUE},
466
{infinityD, 0.0d, Double.MAX_VALUE},
467
468
{Double.MAX_VALUE, infinityD, infinityD},
469
{Double.MAX_VALUE, -infinityD, Double_MAX_VALUEmm},
470
{Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE},
471
{Double.MAX_VALUE, 0.0d, Double_MAX_VALUEmm},
472
473
{Double_MAX_VALUEmm, Double.MAX_VALUE, Double.MAX_VALUE},
474
{Double_MAX_VALUEmm, infinityD, Double.MAX_VALUE},
475
{Double_MAX_VALUEmm, Double_MAX_VALUEmm, Double_MAX_VALUEmm},
476
477
{DoubleConsts.MIN_NORMAL, infinityD, DoubleConsts.MIN_NORMAL+
478
Double.MIN_VALUE},
479
{DoubleConsts.MIN_NORMAL, -infinityD, Double_MAX_SUBNORMAL},
480
{DoubleConsts.MIN_NORMAL, 1.0f, DoubleConsts.MIN_NORMAL+
481
Double.MIN_VALUE},
482
{DoubleConsts.MIN_NORMAL, -1.0f, Double_MAX_SUBNORMAL},
483
{DoubleConsts.MIN_NORMAL, DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},
484
485
{Double_MAX_SUBNORMAL, DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},
486
{Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL},
487
{Double_MAX_SUBNORMAL, 0.0d, Double_MAX_SUBNORMALmm},
488
489
{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL},
490
{Double_MAX_SUBNORMALmm, 0.0d, Double_MAX_SUBNORMALmm-Double.MIN_VALUE},
491
{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm},
492
493
{Double.MIN_VALUE, 0.0d, 0.0d},
494
{-Double.MIN_VALUE, 0.0d, -0.0d},
495
{Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE},
496
{Double.MIN_VALUE, 1.0f, 2*Double.MIN_VALUE},
497
498
// Make sure zero behavior is tested
499
{0.0d, 0.0d, 0.0d},
500
{0.0d, -0.0d, -0.0d},
501
{-0.0d, 0.0d, 0.0d},
502
{-0.0d, -0.0d, -0.0d},
503
{0.0d, infinityD, Double.MIN_VALUE},
504
{0.0d, -infinityD, -Double.MIN_VALUE},
505
{-0.0d, infinityD, Double.MIN_VALUE},
506
{-0.0d, -infinityD, -Double.MIN_VALUE},
507
{0.0d, Double.MIN_VALUE, Double.MIN_VALUE},
508
{0.0d, -Double.MIN_VALUE, -Double.MIN_VALUE},
509
{-0.0d, Double.MIN_VALUE, Double.MIN_VALUE},
510
{-0.0d, -Double.MIN_VALUE, -Double.MIN_VALUE}
511
};
512
513
for(int i = 0; i < testCases.length; i++) {
514
failures += testNextAfterCase(testCases[i][0], testCases[i][1],
515
testCases[i][2]);
516
}
517
return failures;
518
}
519
520
/* ******************** nextUp tests ********************************* */
521
522
public static int testFloatNextUp() {
523
int failures=0;
524
525
/*
526
* Each row of testCases represents one test case for nextUp;
527
* the first column is the input and the second column is the
528
* expected result.
529
*/
530
float testCases [][] = {
531
{NaNf, NaNf},
532
{-infinityF, -Float.MAX_VALUE},
533
{-Float.MAX_VALUE, -Float_MAX_VALUEmm},
534
{-FloatConsts.MIN_NORMAL, -Float_MAX_SUBNORMAL},
535
{-Float_MAX_SUBNORMAL, -Float_MAX_SUBNORMALmm},
536
{-Float.MIN_VALUE, -0.0f},
537
{-0.0f, Float.MIN_VALUE},
538
{+0.0f, Float.MIN_VALUE},
539
{Float.MIN_VALUE, Float.MIN_VALUE*2},
540
{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL},
541
{Float_MAX_SUBNORMAL, FloatConsts.MIN_NORMAL},
542
{FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL+Float.MIN_VALUE},
543
{Float_MAX_VALUEmm, Float.MAX_VALUE},
544
{Float.MAX_VALUE, infinityF},
545
{infinityF, infinityF}
546
};
547
548
for(int i = 0; i < testCases.length; i++) {
549
failures+=Tests.test("Math.nextUp(float)",
550
testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);
551
552
failures+=Tests.test("StrictMath.nextUp(float)",
553
testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);
554
}
555
556
return failures;
557
}
558
559
560
public static int testDoubleNextUp() {
561
int failures=0;
562
563
/*
564
* Each row of testCases represents one test case for nextUp;
565
* the first column is the input and the second column is the
566
* expected result.
567
*/
568
double testCases [][] = {
569
{NaNd, NaNd},
570
{-infinityD, -Double.MAX_VALUE},
571
{-Double.MAX_VALUE, -Double_MAX_VALUEmm},
572
{-DoubleConsts.MIN_NORMAL, -Double_MAX_SUBNORMAL},
573
{-Double_MAX_SUBNORMAL, -Double_MAX_SUBNORMALmm},
574
{-Double.MIN_VALUE, -0.0d},
575
{-0.0d, Double.MIN_VALUE},
576
{+0.0d, Double.MIN_VALUE},
577
{Double.MIN_VALUE, Double.MIN_VALUE*2},
578
{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL},
579
{Double_MAX_SUBNORMAL, DoubleConsts.MIN_NORMAL},
580
{DoubleConsts.MIN_NORMAL, DoubleConsts.MIN_NORMAL+Double.MIN_VALUE},
581
{Double_MAX_VALUEmm, Double.MAX_VALUE},
582
{Double.MAX_VALUE, infinityD},
583
{infinityD, infinityD}
584
};
585
586
for(int i = 0; i < testCases.length; i++) {
587
failures+=Tests.test("Math.nextUp(double)",
588
testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);
589
590
failures+=Tests.test("StrictMath.nextUp(double)",
591
testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);
592
}
593
594
return failures;
595
}
596
597
/* ******************** nextDown tests ********************************* */
598
599
public static int testFloatNextDown() {
600
int failures=0;
601
602
/*
603
* Each row of testCases represents one test case for nextDown;
604
* the first column is the input and the second column is the
605
* expected result.
606
*/
607
float testCases [][] = {
608
{NaNf, NaNf},
609
{-infinityF, -infinityF},
610
{-Float.MAX_VALUE, -infinityF},
611
{-Float_MAX_VALUEmm, -Float.MAX_VALUE},
612
{-Float_MAX_SUBNORMAL, -FloatConsts.MIN_NORMAL},
613
{-Float_MAX_SUBNORMALmm, -Float_MAX_SUBNORMAL},
614
{-0.0f, -Float.MIN_VALUE},
615
{+0.0f, -Float.MIN_VALUE},
616
{Float.MIN_VALUE, 0.0f},
617
{Float.MIN_VALUE*2, Float.MIN_VALUE},
618
{Float_MAX_SUBNORMAL, Float_MAX_SUBNORMALmm},
619
{FloatConsts.MIN_NORMAL, Float_MAX_SUBNORMAL},
620
{FloatConsts.MIN_NORMAL+
621
Float.MIN_VALUE, FloatConsts.MIN_NORMAL},
622
{Float.MAX_VALUE, Float_MAX_VALUEmm},
623
{infinityF, Float.MAX_VALUE},
624
};
625
626
for(int i = 0; i < testCases.length; i++) {
627
failures+=Tests.test("Math.nextDown(float)",
628
testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]);
629
630
failures+=Tests.test("StrictMath.nextDown(float)",
631
testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]);
632
}
633
634
return failures;
635
}
636
637
638
public static int testDoubleNextDown() {
639
int failures=0;
640
641
/*
642
* Each row of testCases represents one test case for nextDown;
643
* the first column is the input and the second column is the
644
* expected result.
645
*/
646
double testCases [][] = {
647
{NaNd, NaNd},
648
{-infinityD, -infinityD},
649
{-Double.MAX_VALUE, -infinityD},
650
{-Double_MAX_VALUEmm, -Double.MAX_VALUE},
651
{-Double_MAX_SUBNORMAL, -DoubleConsts.MIN_NORMAL},
652
{-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL},
653
{-0.0d, -Double.MIN_VALUE},
654
{+0.0d, -Double.MIN_VALUE},
655
{Double.MIN_VALUE, 0.0d},
656
{Double.MIN_VALUE*2, Double.MIN_VALUE},
657
{Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm},
658
{DoubleConsts.MIN_NORMAL, Double_MAX_SUBNORMAL},
659
{DoubleConsts.MIN_NORMAL+
660
Double.MIN_VALUE, DoubleConsts.MIN_NORMAL},
661
{Double.MAX_VALUE, Double_MAX_VALUEmm},
662
{infinityD, Double.MAX_VALUE},
663
};
664
665
for(int i = 0; i < testCases.length; i++) {
666
failures+=Tests.test("Math.nextDown(double)",
667
testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]);
668
669
failures+=Tests.test("StrictMath.nextDown(double)",
670
testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]);
671
}
672
673
return failures;
674
}
675
676
677
/* ********************** boolean tests ****************************** */
678
679
/*
680
* Combined tests for boolean functions, isFinite, isInfinite,
681
* isNaN, isUnordered.
682
*/
683
684
public static int testFloatBooleanMethods() {
685
int failures = 0;
686
687
float testCases [] = {
688
NaNf,
689
-infinityF,
690
infinityF,
691
-Float.MAX_VALUE,
692
-3.0f,
693
-1.0f,
694
-FloatConsts.MIN_NORMAL,
695
-Float_MAX_SUBNORMALmm,
696
-Float_MAX_SUBNORMAL,
697
-Float.MIN_VALUE,
698
-0.0f,
699
+0.0f,
700
Float.MIN_VALUE,
701
Float_MAX_SUBNORMALmm,
702
Float_MAX_SUBNORMAL,
703
FloatConsts.MIN_NORMAL,
704
1.0f,
705
3.0f,
706
Float_MAX_VALUEmm,
707
Float.MAX_VALUE
708
};
709
710
for(int i = 0; i < testCases.length; i++) {
711
// isNaN
712
failures+=Tests.test("FpUtils.isNaN(float)", testCases[i],
713
FpUtils.isNaN(testCases[i]), (i ==0));
714
715
// isFinite
716
failures+=Tests.test("Float.isFinite(float)", testCases[i],
717
Float.isFinite(testCases[i]), (i >= 3));
718
719
// isInfinite
720
failures+=Tests.test("FpUtils.isInfinite(float)", testCases[i],
721
FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
722
723
// isUnorderd
724
for(int j = 0; j < testCases.length; j++) {
725
failures+=Tests.test("FpUtils.isUnordered(float, float)", testCases[i],testCases[j],
726
FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
727
}
728
}
729
730
return failures;
731
}
732
733
public static int testDoubleBooleanMethods() {
734
int failures = 0;
735
boolean result = false;
736
737
double testCases [] = {
738
NaNd,
739
-infinityD,
740
infinityD,
741
-Double.MAX_VALUE,
742
-3.0d,
743
-1.0d,
744
-DoubleConsts.MIN_NORMAL,
745
-Double_MAX_SUBNORMALmm,
746
-Double_MAX_SUBNORMAL,
747
-Double.MIN_VALUE,
748
-0.0d,
749
+0.0d,
750
Double.MIN_VALUE,
751
Double_MAX_SUBNORMALmm,
752
Double_MAX_SUBNORMAL,
753
DoubleConsts.MIN_NORMAL,
754
1.0d,
755
3.0d,
756
Double_MAX_VALUEmm,
757
Double.MAX_VALUE
758
};
759
760
for(int i = 0; i < testCases.length; i++) {
761
// isNaN
762
failures+=Tests.test("FpUtils.isNaN(double)", testCases[i],
763
FpUtils.isNaN(testCases[i]), (i ==0));
764
765
// isFinite
766
failures+=Tests.test("Double.isFinite(double)", testCases[i],
767
Double.isFinite(testCases[i]), (i >= 3));
768
769
// isInfinite
770
failures+=Tests.test("FpUtils.isInfinite(double)", testCases[i],
771
FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
772
773
// isUnorderd
774
for(int j = 0; j < testCases.length; j++) {
775
failures+=Tests.test("FpUtils.isUnordered(double, double)", testCases[i],testCases[j],
776
FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
777
}
778
}
779
780
return failures;
781
}
782
783
/* ******************** copySign tests******************************** */
784
785
public static int testFloatCopySign() {
786
int failures = 0;
787
788
// testCases[0] are logically positive numbers;
789
// testCases[1] are negative numbers.
790
float testCases [][] = {
791
{+0.0f,
792
Float.MIN_VALUE,
793
Float_MAX_SUBNORMALmm,
794
Float_MAX_SUBNORMAL,
795
FloatConsts.MIN_NORMAL,
796
1.0f,
797
3.0f,
798
Float_MAX_VALUEmm,
799
Float.MAX_VALUE,
800
infinityF,
801
},
802
{-infinityF,
803
-Float.MAX_VALUE,
804
-3.0f,
805
-1.0f,
806
-FloatConsts.MIN_NORMAL,
807
-Float_MAX_SUBNORMALmm,
808
-Float_MAX_SUBNORMAL,
809
-Float.MIN_VALUE,
810
-0.0f}
811
};
812
813
float NaNs[] = {Float.intBitsToFloat(0x7fc00000), // "positive" NaN
814
Float.intBitsToFloat(0xFfc00000)}; // "negative" NaN
815
816
// Tests shared between raw and non-raw versions
817
for(int i = 0; i < 2; i++) {
818
for(int j = 0; j < 2; j++) {
819
for(int m = 0; m < testCases[i].length; m++) {
820
for(int n = 0; n < testCases[j].length; n++) {
821
// copySign(magnitude, sign)
822
failures+=Tests.test("Math.copySign(float,float)",
823
testCases[i][m],testCases[j][n],
824
Math.copySign(testCases[i][m], testCases[j][n]),
825
(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
826
827
failures+=Tests.test("StrictMath.copySign(float,float)",
828
testCases[i][m],testCases[j][n],
829
StrictMath.copySign(testCases[i][m], testCases[j][n]),
830
(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
831
}
832
}
833
}
834
}
835
836
// For rawCopySign, NaN may effectively have either sign bit
837
// while for copySign NaNs are treated as if they always have
838
// a zero sign bit (i.e. as positive numbers)
839
for(int i = 0; i < 2; i++) {
840
for(int j = 0; j < NaNs.length; j++) {
841
for(int m = 0; m < testCases[i].length; m++) {
842
// copySign(magnitude, sign)
843
844
failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==
845
Math.abs(testCases[i][m])) ? 0:1;
846
847
848
failures+=Tests.test("StrictMath.copySign(float,float)",
849
testCases[i][m], NaNs[j],
850
StrictMath.copySign(testCases[i][m], NaNs[j]),
851
Math.abs(testCases[i][m]) );
852
}
853
}
854
}
855
856
return failures;
857
}
858
859
public static int testDoubleCopySign() {
860
int failures = 0;
861
862
// testCases[0] are logically positive numbers;
863
// testCases[1] are negative numbers.
864
double testCases [][] = {
865
{+0.0d,
866
Double.MIN_VALUE,
867
Double_MAX_SUBNORMALmm,
868
Double_MAX_SUBNORMAL,
869
DoubleConsts.MIN_NORMAL,
870
1.0d,
871
3.0d,
872
Double_MAX_VALUEmm,
873
Double.MAX_VALUE,
874
infinityD,
875
},
876
{-infinityD,
877
-Double.MAX_VALUE,
878
-3.0d,
879
-1.0d,
880
-DoubleConsts.MIN_NORMAL,
881
-Double_MAX_SUBNORMALmm,
882
-Double_MAX_SUBNORMAL,
883
-Double.MIN_VALUE,
884
-0.0d}
885
};
886
887
double NaNs[] = {Double.longBitsToDouble(0x7ff8000000000000L), // "positive" NaN
888
Double.longBitsToDouble(0xfff8000000000000L), // "negative" NaN
889
Double.longBitsToDouble(0x7FF0000000000001L),
890
Double.longBitsToDouble(0xFFF0000000000001L),
891
Double.longBitsToDouble(0x7FF8555555555555L),
892
Double.longBitsToDouble(0xFFF8555555555555L),
893
Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),
894
Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),
895
Double.longBitsToDouble(0x7FFDeadBeef00000L),
896
Double.longBitsToDouble(0xFFFDeadBeef00000L),
897
Double.longBitsToDouble(0x7FFCafeBabe00000L),
898
Double.longBitsToDouble(0xFFFCafeBabe00000L)};
899
900
// Tests shared between Math and StrictMath versions
901
for(int i = 0; i < 2; i++) {
902
for(int j = 0; j < 2; j++) {
903
for(int m = 0; m < testCases[i].length; m++) {
904
for(int n = 0; n < testCases[j].length; n++) {
905
// copySign(magnitude, sign)
906
failures+=Tests.test("MathcopySign(double,double)",
907
testCases[i][m],testCases[j][n],
908
Math.copySign(testCases[i][m], testCases[j][n]),
909
(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
910
911
failures+=Tests.test("StrictMath.copySign(double,double)",
912
testCases[i][m],testCases[j][n],
913
StrictMath.copySign(testCases[i][m], testCases[j][n]),
914
(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
915
}
916
}
917
}
918
}
919
920
// For Math.copySign, NaN may effectively have either sign bit
921
// while for StrictMath.copySign NaNs are treated as if they
922
// always have a zero sign bit (i.e. as positive numbers)
923
for(int i = 0; i < 2; i++) {
924
for(int j = 0; j < NaNs.length; j++) {
925
for(int m = 0; m < testCases[i].length; m++) {
926
// copySign(magnitude, sign)
927
928
failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==
929
Math.abs(testCases[i][m])) ? 0:1;
930
931
932
failures+=Tests.test("StrictMath.copySign(double,double)",
933
testCases[i][m], NaNs[j],
934
StrictMath.copySign(testCases[i][m], NaNs[j]),
935
Math.abs(testCases[i][m]) );
936
}
937
}
938
}
939
940
941
return failures;
942
}
943
944
/* ************************ scalb tests ******************************* */
945
946
static int testScalbCase(float value, int scale_factor, float expected) {
947
int failures=0;
948
949
failures+=Tests.test("Math.scalb(float,int)",
950
value, scale_factor,
951
Math.scalb(value, scale_factor), expected);
952
953
failures+=Tests.test("Math.scalb(float,int)",
954
-value, scale_factor,
955
Math.scalb(-value, scale_factor), -expected);
956
957
failures+=Tests.test("StrictMath.scalb(float,int)",
958
value, scale_factor,
959
StrictMath.scalb(value, scale_factor), expected);
960
961
failures+=Tests.test("StrictMath.scalb(float,int)",
962
-value, scale_factor,
963
StrictMath.scalb(-value, scale_factor), -expected);
964
return failures;
965
}
966
967
public static int testFloatScalb() {
968
int failures=0;
969
int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
970
FloatConsts.SIGNIFICAND_WIDTH + 1;
971
972
973
// Arguments x, where scalb(x,n) is x for any n.
974
float [] identityTestCases = {NaNf,
975
-0.0f,
976
+0.0f,
977
infinityF,
978
-infinityF
979
};
980
981
float [] subnormalTestCases = {
982
Float.MIN_VALUE,
983
3.0f*Float.MIN_VALUE,
984
Float_MAX_SUBNORMALmm,
985
Float_MAX_SUBNORMAL
986
};
987
988
float [] someTestCases = {
989
Float.MIN_VALUE,
990
3.0f*Float.MIN_VALUE,
991
Float_MAX_SUBNORMALmm,
992
Float_MAX_SUBNORMAL,
993
FloatConsts.MIN_NORMAL,
994
1.0f,
995
2.0f,
996
3.0f,
997
(float)Math.PI,
998
Float_MAX_VALUEmm,
999
Float.MAX_VALUE
1000
};
1001
1002
int [] oneMultiplyScalingFactors = {
1003
FloatConsts.MIN_EXPONENT,
1004
FloatConsts.MIN_EXPONENT+1,
1005
-3,
1006
-2,
1007
-1,
1008
0,
1009
1,
1010
2,
1011
3,
1012
FloatConsts.MAX_EXPONENT-1,
1013
FloatConsts.MAX_EXPONENT
1014
};
1015
1016
int [] manyScalingFactors = {
1017
Integer.MIN_VALUE,
1018
Integer.MIN_VALUE+1,
1019
-MAX_SCALE -1,
1020
-MAX_SCALE,
1021
-MAX_SCALE+1,
1022
1023
2*FloatConsts.MIN_EXPONENT-1, // -253
1024
2*FloatConsts.MIN_EXPONENT, // -252
1025
2*FloatConsts.MIN_EXPONENT+1, // -251
1026
1027
FpUtils.ilogb(Float.MIN_VALUE)-1, // -150
1028
FpUtils.ilogb(Float.MIN_VALUE), // -149
1029
-FloatConsts.MAX_EXPONENT, // -127
1030
FloatConsts.MIN_EXPONENT, // -126
1031
1032
-2,
1033
-1,
1034
0,
1035
1,
1036
2,
1037
1038
FloatConsts.MAX_EXPONENT-1, // 126
1039
FloatConsts.MAX_EXPONENT, // 127
1040
FloatConsts.MAX_EXPONENT+1, // 128
1041
1042
2*FloatConsts.MAX_EXPONENT-1, // 253
1043
2*FloatConsts.MAX_EXPONENT, // 254
1044
2*FloatConsts.MAX_EXPONENT+1, // 255
1045
1046
MAX_SCALE-1,
1047
MAX_SCALE,
1048
MAX_SCALE+1,
1049
Integer.MAX_VALUE-1,
1050
Integer.MAX_VALUE
1051
};
1052
1053
// Test cases where scaling is always a no-op
1054
for(int i=0; i < identityTestCases.length; i++) {
1055
for(int j=0; j < manyScalingFactors.length; j++) {
1056
failures += testScalbCase(identityTestCases[i],
1057
manyScalingFactors[j],
1058
identityTestCases[i]);
1059
}
1060
}
1061
1062
// Test cases where result is 0.0 or infinity due to magnitude
1063
// of the scaling factor
1064
for(int i=0; i < someTestCases.length; i++) {
1065
for(int j=0; j < manyScalingFactors.length; j++) {
1066
int scaleFactor = manyScalingFactors[j];
1067
if (Math.abs(scaleFactor) >= MAX_SCALE) {
1068
float value = someTestCases[i];
1069
failures+=testScalbCase(value,
1070
scaleFactor,
1071
Math.copySign( (scaleFactor>0?infinityF:0.0f), value) );
1072
}
1073
}
1074
}
1075
1076
// Test cases that could be done with one floating-point
1077
// multiply.
1078
for(int i=0; i < someTestCases.length; i++) {
1079
for(int j=0; j < oneMultiplyScalingFactors.length; j++) {
1080
int scaleFactor = oneMultiplyScalingFactors[j];
1081
float value = someTestCases[i];
1082
1083
failures+=testScalbCase(value,
1084
scaleFactor,
1085
value*powerOfTwoF(scaleFactor));
1086
}
1087
}
1088
1089
// Create 2^MAX_EXPONENT
1090
float twoToTheMaxExp = 1.0f; // 2^0
1091
for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++)
1092
twoToTheMaxExp *=2.0f;
1093
1094
// Scale-up subnormal values until they all overflow
1095
for(int i=0; i < subnormalTestCases.length; i++) {
1096
float scale = 1.0f; // 2^j
1097
float value = subnormalTestCases[i];
1098
1099
for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1100
int scaleFactor = j;
1101
1102
failures+=testScalbCase(value,
1103
scaleFactor,
1104
(FpUtils.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ?
1105
Math.copySign(infinityF, value) : // overflow
1106
// calculate right answer
1107
twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1108
scale*=2.0f;
1109
}
1110
}
1111
1112
// Scale down a large number until it underflows. By scaling
1113
// down MAX_NORMALmm, the first subnormal result will be exact
1114
// but the next one will round -- all those results can be
1115
// checked by halving a separate value in the loop. Actually,
1116
// we can keep halving and checking until the product is zero
1117
// since:
1118
//
1119
// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1120
// it will round *up*
1121
//
1122
// 2. When rounding first occurs in the expected product, it
1123
// too rounds up, to 2^-MAX_EXPONENT.
1124
//
1125
// Halving expected after rounding happends to give the same
1126
// result as the scalb operation.
1127
float expected = Float_MAX_VALUEmm *0.5f;
1128
for(int i = -1; i > -MAX_SCALE; i--) {
1129
failures+=testScalbCase(Float_MAX_VALUEmm, i, expected);
1130
1131
expected *= 0.5f;
1132
}
1133
1134
// Tricky rounding tests:
1135
// Scale down a large number into subnormal range such that if
1136
// scalb is being implemented with multiple floating-point
1137
// multiplies, the value would round twice if the multiplies
1138
// were done in the wrong order.
1139
1140
float value = 0x8.0000bP-5f;
1141
expected = 0x1.00001p-129f;
1142
1143
for(int i = 0; i < 129; i++) {
1144
failures+=testScalbCase(value,
1145
-127-i,
1146
expected);
1147
value *=2.0f;
1148
}
1149
1150
return failures;
1151
}
1152
1153
static int testScalbCase(double value, int scale_factor, double expected) {
1154
int failures=0;
1155
1156
failures+=Tests.test("Math.scalb(double,int)",
1157
value, scale_factor,
1158
Math.scalb(value, scale_factor), expected);
1159
1160
failures+=Tests.test("Math.scalb(double,int)",
1161
-value, scale_factor,
1162
Math.scalb(-value, scale_factor), -expected);
1163
1164
failures+=Tests.test("StrictMath.scalb(double,int)",
1165
value, scale_factor,
1166
StrictMath.scalb(value, scale_factor), expected);
1167
1168
failures+=Tests.test("StrictMath.scalb(double,int)",
1169
-value, scale_factor,
1170
StrictMath.scalb(-value, scale_factor), -expected);
1171
1172
return failures;
1173
}
1174
1175
public static int testDoubleScalb() {
1176
int failures=0;
1177
int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
1178
DoubleConsts.SIGNIFICAND_WIDTH + 1;
1179
1180
1181
// Arguments x, where scalb(x,n) is x for any n.
1182
double [] identityTestCases = {NaNd,
1183
-0.0,
1184
+0.0,
1185
infinityD,
1186
};
1187
1188
double [] subnormalTestCases = {
1189
Double.MIN_VALUE,
1190
3.0d*Double.MIN_VALUE,
1191
Double_MAX_SUBNORMALmm,
1192
Double_MAX_SUBNORMAL
1193
};
1194
1195
double [] someTestCases = {
1196
Double.MIN_VALUE,
1197
3.0d*Double.MIN_VALUE,
1198
Double_MAX_SUBNORMALmm,
1199
Double_MAX_SUBNORMAL,
1200
DoubleConsts.MIN_NORMAL,
1201
1.0d,
1202
2.0d,
1203
3.0d,
1204
Math.PI,
1205
Double_MAX_VALUEmm,
1206
Double.MAX_VALUE
1207
};
1208
1209
int [] oneMultiplyScalingFactors = {
1210
DoubleConsts.MIN_EXPONENT,
1211
DoubleConsts.MIN_EXPONENT+1,
1212
-3,
1213
-2,
1214
-1,
1215
0,
1216
1,
1217
2,
1218
3,
1219
DoubleConsts.MAX_EXPONENT-1,
1220
DoubleConsts.MAX_EXPONENT
1221
};
1222
1223
int [] manyScalingFactors = {
1224
Integer.MIN_VALUE,
1225
Integer.MIN_VALUE+1,
1226
-MAX_SCALE -1,
1227
-MAX_SCALE,
1228
-MAX_SCALE+1,
1229
1230
2*DoubleConsts.MIN_EXPONENT-1, // -2045
1231
2*DoubleConsts.MIN_EXPONENT, // -2044
1232
2*DoubleConsts.MIN_EXPONENT+1, // -2043
1233
1234
FpUtils.ilogb(Double.MIN_VALUE)-1, // -1076
1235
FpUtils.ilogb(Double.MIN_VALUE), // -1075
1236
-DoubleConsts.MAX_EXPONENT, // -1023
1237
DoubleConsts.MIN_EXPONENT, // -1022
1238
1239
-2,
1240
-1,
1241
0,
1242
1,
1243
2,
1244
1245
DoubleConsts.MAX_EXPONENT-1, // 1022
1246
DoubleConsts.MAX_EXPONENT, // 1023
1247
DoubleConsts.MAX_EXPONENT+1, // 1024
1248
1249
2*DoubleConsts.MAX_EXPONENT-1, // 2045
1250
2*DoubleConsts.MAX_EXPONENT, // 2046
1251
2*DoubleConsts.MAX_EXPONENT+1, // 2047
1252
1253
MAX_SCALE-1,
1254
MAX_SCALE,
1255
MAX_SCALE+1,
1256
Integer.MAX_VALUE-1,
1257
Integer.MAX_VALUE
1258
};
1259
1260
// Test cases where scaling is always a no-op
1261
for(int i=0; i < identityTestCases.length; i++) {
1262
for(int j=0; j < manyScalingFactors.length; j++) {
1263
failures += testScalbCase(identityTestCases[i],
1264
manyScalingFactors[j],
1265
identityTestCases[i]);
1266
}
1267
}
1268
1269
// Test cases where result is 0.0 or infinity due to magnitude
1270
// of the scaling factor
1271
for(int i=0; i < someTestCases.length; i++) {
1272
for(int j=0; j < manyScalingFactors.length; j++) {
1273
int scaleFactor = manyScalingFactors[j];
1274
if (Math.abs(scaleFactor) >= MAX_SCALE) {
1275
double value = someTestCases[i];
1276
failures+=testScalbCase(value,
1277
scaleFactor,
1278
Math.copySign( (scaleFactor>0?infinityD:0.0), value) );
1279
}
1280
}
1281
}
1282
1283
// Test cases that could be done with one floating-point
1284
// multiply.
1285
for(int i=0; i < someTestCases.length; i++) {
1286
for(int j=0; j < oneMultiplyScalingFactors.length; j++) {
1287
int scaleFactor = oneMultiplyScalingFactors[j];
1288
double value = someTestCases[i];
1289
1290
failures+=testScalbCase(value,
1291
scaleFactor,
1292
value*powerOfTwoD(scaleFactor));
1293
}
1294
}
1295
1296
// Create 2^MAX_EXPONENT
1297
double twoToTheMaxExp = 1.0; // 2^0
1298
for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++)
1299
twoToTheMaxExp *=2.0;
1300
1301
// Scale-up subnormal values until they all overflow
1302
for(int i=0; i < subnormalTestCases.length; i++) {
1303
double scale = 1.0; // 2^j
1304
double value = subnormalTestCases[i];
1305
1306
for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1307
int scaleFactor = j;
1308
1309
failures+=testScalbCase(value,
1310
scaleFactor,
1311
(FpUtils.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ?
1312
Math.copySign(infinityD, value) : // overflow
1313
// calculate right answer
1314
twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1315
scale*=2.0;
1316
}
1317
}
1318
1319
// Scale down a large number until it underflows. By scaling
1320
// down MAX_NORMALmm, the first subnormal result will be exact
1321
// but the next one will round -- all those results can be
1322
// checked by halving a separate value in the loop. Actually,
1323
// we can keep halving and checking until the product is zero
1324
// since:
1325
//
1326
// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1327
// it will round *up*
1328
//
1329
// 2. When rounding first occurs in the expected product, it
1330
// too rounds up, to 2^-MAX_EXPONENT.
1331
//
1332
// Halving expected after rounding happends to give the same
1333
// result as the scalb operation.
1334
double expected = Double_MAX_VALUEmm *0.5f;
1335
for(int i = -1; i > -MAX_SCALE; i--) {
1336
failures+=testScalbCase(Double_MAX_VALUEmm, i, expected);
1337
1338
expected *= 0.5;
1339
}
1340
1341
// Tricky rounding tests:
1342
// Scale down a large number into subnormal range such that if
1343
// scalb is being implemented with multiple floating-point
1344
// multiplies, the value would round twice if the multiplies
1345
// were done in the wrong order.
1346
1347
double value = 0x1.000000000000bP-1;
1348
expected = 0x0.2000000000001P-1022;
1349
for(int i = 0; i < DoubleConsts.MAX_EXPONENT+2; i++) {
1350
failures+=testScalbCase(value,
1351
-1024-i,
1352
expected);
1353
value *=2.0;
1354
}
1355
1356
return failures;
1357
}
1358
1359
/* ************************* ulp tests ******************************* */
1360
1361
1362
/*
1363
* Test Math.ulp and StrictMath.ulp with +d and -d.
1364
*/
1365
static int testUlpCase(float f, float expected) {
1366
float minus_f = -f;
1367
int failures=0;
1368
1369
failures+=Tests.test("Math.ulp(float)", f,
1370
Math.ulp(f), expected);
1371
failures+=Tests.test("Math.ulp(float)", minus_f,
1372
Math.ulp(minus_f), expected);
1373
failures+=Tests.test("StrictMath.ulp(float)", f,
1374
StrictMath.ulp(f), expected);
1375
failures+=Tests.test("StrictMath.ulp(float)", minus_f,
1376
StrictMath.ulp(minus_f), expected);
1377
return failures;
1378
}
1379
1380
static int testUlpCase(double d, double expected) {
1381
double minus_d = -d;
1382
int failures=0;
1383
1384
failures+=Tests.test("Math.ulp(double)", d,
1385
Math.ulp(d), expected);
1386
failures+=Tests.test("Math.ulp(double)", minus_d,
1387
Math.ulp(minus_d), expected);
1388
failures+=Tests.test("StrictMath.ulp(double)", d,
1389
StrictMath.ulp(d), expected);
1390
failures+=Tests.test("StrictMath.ulp(double)", minus_d,
1391
StrictMath.ulp(minus_d), expected);
1392
return failures;
1393
}
1394
1395
public static int testFloatUlp() {
1396
int failures = 0;
1397
float [] specialValues = {NaNf,
1398
Float.POSITIVE_INFINITY,
1399
+0.0f,
1400
+1.0f,
1401
+2.0f,
1402
+16.0f,
1403
+Float.MIN_VALUE,
1404
+Float_MAX_SUBNORMAL,
1405
+FloatConsts.MIN_NORMAL,
1406
+Float.MAX_VALUE
1407
};
1408
1409
float [] specialResults = {NaNf,
1410
Float.POSITIVE_INFINITY,
1411
Float.MIN_VALUE,
1412
powerOfTwoF(-23),
1413
powerOfTwoF(-22),
1414
powerOfTwoF(-19),
1415
Float.MIN_VALUE,
1416
Float.MIN_VALUE,
1417
Float.MIN_VALUE,
1418
powerOfTwoF(104)
1419
};
1420
1421
// Special value tests
1422
for(int i = 0; i < specialValues.length; i++) {
1423
failures += testUlpCase(specialValues[i], specialResults[i]);
1424
}
1425
1426
1427
// Normal exponent tests
1428
for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {
1429
float expected;
1430
1431
// Create power of two
1432
float po2 = powerOfTwoF(i);
1433
expected = Math.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH-1));
1434
1435
failures += testUlpCase(po2, expected);
1436
1437
// Generate some random bit patterns for the significand
1438
for(int j = 0; j < 10; j++) {
1439
int randSignif = rand.nextInt();
1440
float randFloat;
1441
1442
randFloat = Float.intBitsToFloat( // Exponent
1443
(Float.floatToIntBits(po2)&
1444
(~FloatConsts.SIGNIF_BIT_MASK)) |
1445
// Significand
1446
(randSignif &
1447
FloatConsts.SIGNIF_BIT_MASK) );
1448
1449
failures += testUlpCase(randFloat, expected);
1450
}
1451
1452
if (i > FloatConsts.MIN_EXPONENT) {
1453
float po2minus = Math.nextAfter(po2,
1454
Float.NEGATIVE_INFINITY);
1455
failures += testUlpCase(po2minus, expected/2.0f);
1456
}
1457
}
1458
1459
// Subnormal tests
1460
1461
/*
1462
* Start with MIN_VALUE, left shift, test high value, low
1463
* values, and random in between.
1464
*
1465
* Use nextAfter to calculate, high value of previous binade,
1466
* loop count i will indicate how many random bits, if any are
1467
* needed.
1468
*/
1469
1470
float top=Float.MIN_VALUE;
1471
for( int i = 1;
1472
i < FloatConsts.SIGNIFICAND_WIDTH;
1473
i++, top *= 2.0f) {
1474
1475
failures += testUlpCase(top, Float.MIN_VALUE);
1476
1477
// Test largest value in next smaller binade
1478
if (i >= 3) {// (i == 1) would test 0.0;
1479
// (i == 2) would just retest MIN_VALUE
1480
testUlpCase(Math.nextAfter(top, 0.0f),
1481
Float.MIN_VALUE);
1482
1483
if( i >= 10) {
1484
// create a bit mask with (i-1) 1's in the low order
1485
// bits
1486
int mask = ~((~0)<<(i-1));
1487
float randFloat = Float.intBitsToFloat( // Exponent
1488
Float.floatToIntBits(top) |
1489
// Significand
1490
(rand.nextInt() & mask ) ) ;
1491
1492
failures += testUlpCase(randFloat, Float.MIN_VALUE);
1493
}
1494
}
1495
}
1496
1497
return failures;
1498
}
1499
1500
public static int testDoubleUlp() {
1501
int failures = 0;
1502
double [] specialValues = {NaNd,
1503
Double.POSITIVE_INFINITY,
1504
+0.0d,
1505
+1.0d,
1506
+2.0d,
1507
+16.0d,
1508
+Double.MIN_VALUE,
1509
+Double_MAX_SUBNORMAL,
1510
+DoubleConsts.MIN_NORMAL,
1511
+Double.MAX_VALUE
1512
};
1513
1514
double [] specialResults = {NaNf,
1515
Double.POSITIVE_INFINITY,
1516
Double.MIN_VALUE,
1517
powerOfTwoD(-52),
1518
powerOfTwoD(-51),
1519
powerOfTwoD(-48),
1520
Double.MIN_VALUE,
1521
Double.MIN_VALUE,
1522
Double.MIN_VALUE,
1523
powerOfTwoD(971)
1524
};
1525
1526
// Special value tests
1527
for(int i = 0; i < specialValues.length; i++) {
1528
failures += testUlpCase(specialValues[i], specialResults[i]);
1529
}
1530
1531
1532
// Normal exponent tests
1533
for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {
1534
double expected;
1535
1536
// Create power of two
1537
double po2 = powerOfTwoD(i);
1538
expected = Math.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH-1));
1539
1540
failures += testUlpCase(po2, expected);
1541
1542
// Generate some random bit patterns for the significand
1543
for(int j = 0; j < 10; j++) {
1544
long randSignif = rand.nextLong();
1545
double randDouble;
1546
1547
randDouble = Double.longBitsToDouble( // Exponent
1548
(Double.doubleToLongBits(po2)&
1549
(~DoubleConsts.SIGNIF_BIT_MASK)) |
1550
// Significand
1551
(randSignif &
1552
DoubleConsts.SIGNIF_BIT_MASK) );
1553
1554
failures += testUlpCase(randDouble, expected);
1555
}
1556
1557
if (i > DoubleConsts.MIN_EXPONENT) {
1558
double po2minus = Math.nextAfter(po2,
1559
Double.NEGATIVE_INFINITY);
1560
failures += testUlpCase(po2minus, expected/2.0f);
1561
}
1562
}
1563
1564
// Subnormal tests
1565
1566
/*
1567
* Start with MIN_VALUE, left shift, test high value, low
1568
* values, and random in between.
1569
*
1570
* Use nextAfter to calculate, high value of previous binade,
1571
* loop count i will indicate how many random bits, if any are
1572
* needed.
1573
*/
1574
1575
double top=Double.MIN_VALUE;
1576
for( int i = 1;
1577
i < DoubleConsts.SIGNIFICAND_WIDTH;
1578
i++, top *= 2.0f) {
1579
1580
failures += testUlpCase(top, Double.MIN_VALUE);
1581
1582
// Test largest value in next smaller binade
1583
if (i >= 3) {// (i == 1) would test 0.0;
1584
// (i == 2) would just retest MIN_VALUE
1585
testUlpCase(Math.nextAfter(top, 0.0f),
1586
Double.MIN_VALUE);
1587
1588
if( i >= 10) {
1589
// create a bit mask with (i-1) 1's in the low order
1590
// bits
1591
int mask = ~((~0)<<(i-1));
1592
double randDouble = Double.longBitsToDouble( // Exponent
1593
Double.doubleToLongBits(top) |
1594
// Significand
1595
(rand.nextLong() & mask ) ) ;
1596
1597
failures += testUlpCase(randDouble, Double.MIN_VALUE);
1598
}
1599
}
1600
}
1601
1602
return failures;
1603
}
1604
1605
public static int testFloatSignum() {
1606
int failures = 0;
1607
float testCases [][] = {
1608
{NaNf, NaNf},
1609
{-infinityF, -1.0f},
1610
{-Float.MAX_VALUE, -1.0f},
1611
{-FloatConsts.MIN_NORMAL, -1.0f},
1612
{-1.0f, -1.0f},
1613
{-2.0f, -1.0f},
1614
{-Float_MAX_SUBNORMAL, -1.0f},
1615
{-Float.MIN_VALUE, -1.0f},
1616
{-0.0f, -0.0f},
1617
{+0.0f, +0.0f},
1618
{Float.MIN_VALUE, 1.0f},
1619
{Float_MAX_SUBNORMALmm, 1.0f},
1620
{Float_MAX_SUBNORMAL, 1.0f},
1621
{FloatConsts.MIN_NORMAL, 1.0f},
1622
{1.0f, 1.0f},
1623
{2.0f, 1.0f},
1624
{Float_MAX_VALUEmm, 1.0f},
1625
{Float.MAX_VALUE, 1.0f},
1626
{infinityF, 1.0f}
1627
};
1628
1629
for(int i = 0; i < testCases.length; i++) {
1630
failures+=Tests.test("Math.signum(float)",
1631
testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);
1632
failures+=Tests.test("StrictMath.signum(float)",
1633
testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);
1634
}
1635
1636
return failures;
1637
}
1638
1639
public static int testDoubleSignum() {
1640
int failures = 0;
1641
double testCases [][] = {
1642
{NaNd, NaNd},
1643
{-infinityD, -1.0},
1644
{-Double.MAX_VALUE, -1.0},
1645
{-DoubleConsts.MIN_NORMAL, -1.0},
1646
{-1.0, -1.0},
1647
{-2.0, -1.0},
1648
{-Double_MAX_SUBNORMAL, -1.0},
1649
{-Double.MIN_VALUE, -1.0d},
1650
{-0.0d, -0.0d},
1651
{+0.0d, +0.0d},
1652
{Double.MIN_VALUE, 1.0},
1653
{Double_MAX_SUBNORMALmm, 1.0},
1654
{Double_MAX_SUBNORMAL, 1.0},
1655
{DoubleConsts.MIN_NORMAL, 1.0},
1656
{1.0, 1.0},
1657
{2.0, 1.0},
1658
{Double_MAX_VALUEmm, 1.0},
1659
{Double.MAX_VALUE, 1.0},
1660
{infinityD, 1.0}
1661
};
1662
1663
for(int i = 0; i < testCases.length; i++) {
1664
failures+=Tests.test("Math.signum(double)",
1665
testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);
1666
failures+=Tests.test("StrictMath.signum(double)",
1667
testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);
1668
}
1669
1670
return failures;
1671
}
1672
1673
1674
public static void main(String argv[]) {
1675
int failures = 0;
1676
1677
failures += testFloatGetExponent();
1678
failures += testDoubleGetExponent();
1679
1680
failures += testFloatNextAfter();
1681
failures += testDoubleNextAfter();
1682
1683
failures += testFloatNextUp();
1684
failures += testDoubleNextUp();
1685
1686
failures += testFloatNextDown();
1687
failures += testDoubleNextDown();
1688
1689
failures += testFloatBooleanMethods();
1690
failures += testDoubleBooleanMethods();
1691
1692
failures += testFloatCopySign();
1693
failures += testDoubleCopySign();
1694
1695
failures += testFloatScalb();
1696
failures += testDoubleScalb();
1697
1698
failures += testFloatUlp();
1699
failures += testDoubleUlp();
1700
1701
failures += testFloatSignum();
1702
failures += testDoubleSignum();
1703
1704
if (failures > 0) {
1705
System.err.println("Testing the recommended functions incurred "
1706
+ failures + " failures.");
1707
throw new RuntimeException();
1708
}
1709
}
1710
}
1711
1712