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