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/CubeRootTests.java
38812 views
1
/*
2
* Copyright (c) 2003, 2012, 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 4347132 4939441
27
* @summary Tests for {Math, StrictMath}.cbrt
28
* @author Joseph D. Darcy
29
* @key randomness
30
*/
31
32
import sun.misc.DoubleConsts;
33
34
public class CubeRootTests {
35
private CubeRootTests(){}
36
37
static final double infinityD = Double.POSITIVE_INFINITY;
38
static final double NaNd = Double.NaN;
39
40
// Initialize shared random number generator
41
static java.util.Random rand = new java.util.Random();
42
43
static int testCubeRootCase(double input, double expected) {
44
int failures=0;
45
46
double minus_input = -input;
47
double minus_expected = -expected;
48
49
failures+=Tests.test("Math.cbrt(double)", input,
50
Math.cbrt(input), expected);
51
failures+=Tests.test("Math.cbrt(double)", minus_input,
52
Math.cbrt(minus_input), minus_expected);
53
failures+=Tests.test("StrictMath.cbrt(double)", input,
54
StrictMath.cbrt(input), expected);
55
failures+=Tests.test("StrictMath.cbrt(double)", minus_input,
56
StrictMath.cbrt(minus_input), minus_expected);
57
58
return failures;
59
}
60
61
static int testCubeRoot() {
62
int failures = 0;
63
double [][] testCases = {
64
{NaNd, NaNd},
65
{Double.longBitsToDouble(0x7FF0000000000001L), NaNd},
66
{Double.longBitsToDouble(0xFFF0000000000001L), NaNd},
67
{Double.longBitsToDouble(0x7FF8555555555555L), NaNd},
68
{Double.longBitsToDouble(0xFFF8555555555555L), NaNd},
69
{Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), NaNd},
70
{Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), NaNd},
71
{Double.longBitsToDouble(0x7FFDeadBeef00000L), NaNd},
72
{Double.longBitsToDouble(0xFFFDeadBeef00000L), NaNd},
73
{Double.longBitsToDouble(0x7FFCafeBabe00000L), NaNd},
74
{Double.longBitsToDouble(0xFFFCafeBabe00000L), NaNd},
75
{Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY},
76
{Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY},
77
{+0.0, +0.0},
78
{-0.0, -0.0},
79
{+1.0, +1.0},
80
{-1.0, -1.0},
81
{+8.0, +2.0},
82
{-8.0, -2.0}
83
};
84
85
for(int i = 0; i < testCases.length; i++) {
86
failures += testCubeRootCase(testCases[i][0],
87
testCases[i][1]);
88
}
89
90
// Test integer perfect cubes less than 2^53.
91
for(int i = 0; i <= 208063; i++) {
92
double d = i;
93
failures += testCubeRootCase(d*d*d, (double)i);
94
}
95
96
// Test cbrt(2^(3n)) = 2^n.
97
for(int i = 18; i <= DoubleConsts.MAX_EXPONENT/3; i++) {
98
failures += testCubeRootCase(Math.scalb(1.0, 3*i),
99
Math.scalb(1.0, i) );
100
}
101
102
// Test cbrt(2^(-3n)) = 2^-n.
103
for(int i = -1; i >= DoubleConsts.MIN_SUB_EXPONENT/3; i--) {
104
failures += testCubeRootCase(Math.scalb(1.0, 3*i),
105
Math.scalb(1.0, i) );
106
}
107
108
// Test random perfect cubes. Create double values with
109
// modest exponents but only have at most the 17 most
110
// significant bits in the significand set; 17*3 = 51, which
111
// is less than the number of bits in a double's significand.
112
long exponentBits1 =
113
Double.doubleToLongBits(Math.scalb(1.0, 55)) &
114
DoubleConsts.EXP_BIT_MASK;
115
long exponentBits2=
116
Double.doubleToLongBits(Math.scalb(1.0, -55)) &
117
DoubleConsts.EXP_BIT_MASK;
118
for(int i = 0; i < 100; i++) {
119
// Take 16 bits since the 17th bit is implicit in the
120
// exponent
121
double input1 =
122
Double.longBitsToDouble(exponentBits1 |
123
// Significand bits
124
((long) (rand.nextInt() & 0xFFFF))<<
125
(DoubleConsts.SIGNIFICAND_WIDTH-1-16));
126
failures += testCubeRootCase(input1*input1*input1, input1);
127
128
double input2 =
129
Double.longBitsToDouble(exponentBits2 |
130
// Significand bits
131
((long) (rand.nextInt() & 0xFFFF))<<
132
(DoubleConsts.SIGNIFICAND_WIDTH-1-16));
133
failures += testCubeRootCase(input2*input2*input2, input2);
134
}
135
136
// Directly test quality of implementation properties of cbrt
137
// for values that aren't perfect cubes. Verify returned
138
// result meets the 1 ulp test. That is, we want to verify
139
// that for positive x > 1,
140
// y = cbrt(x),
141
//
142
// if (err1=x - y^3 ) < 0, abs((y_pp^3 -x )) < err1
143
// if (err1=x - y^3 ) > 0, abs((y_mm^3 -x )) < err1
144
//
145
// where y_mm and y_pp are the next smaller and next larger
146
// floating-point value to y. In other words, if y^3 is too
147
// big, making y larger does not improve the result; likewise,
148
// if y^3 is too small, making y smaller does not improve the
149
// result.
150
//
151
// ...-----|--?--|--?--|-----... Where is the true result?
152
// y_mm y y_pp
153
//
154
// The returned value y should be one of the floating-point
155
// values braketing the true result. However, given y, a
156
// priori we don't know if the true result falls in [y_mm, y]
157
// or [y, y_pp]. The above test looks at the error in x-y^3
158
// to determine which region the true result is in; e.g. if
159
// y^3 is smaller than x, the true result should be in [y,
160
// y_pp]. Therefore, it would be an error for y_mm to be a
161
// closer approximation to x^(1/3). In this case, it is
162
// permissible, although not ideal, for y_pp^3 to be a closer
163
// approximation to x^(1/3) than y^3.
164
//
165
// We will use pow(y,3) to compute y^3. Although pow is not
166
// correctly rounded, StrictMath.pow should have at most 1 ulp
167
// error. For y > 1, pow(y_mm,3) and pow(y_pp,3) will differ
168
// from pow(y,3) by more than one ulp so the comparision of
169
// errors should still be valid.
170
171
for(int i = 0; i < 1000; i++) {
172
double d = 1.0 + rand.nextDouble();
173
double err, err_adjacent;
174
175
double y1 = Math.cbrt(d);
176
double y2 = StrictMath.cbrt(d);
177
178
err = d - StrictMath.pow(y1, 3);
179
if (err != 0.0) {
180
if(Double.isNaN(err)) {
181
failures++;
182
System.err.println("Encountered unexpected NaN value: d = " + d +
183
"\tcbrt(d) = " + y1);
184
} else {
185
if (err < 0.0) {
186
err_adjacent = StrictMath.pow(Math.nextUp(y1), 3) - d;
187
}
188
else { // (err > 0.0)
189
err_adjacent = StrictMath.pow(Math.nextAfter(y1,0.0), 3) - d;
190
}
191
192
if (Math.abs(err) > Math.abs(err_adjacent)) {
193
failures++;
194
System.err.println("For Math.cbrt(" + d + "), returned result " +
195
y1 + "is not as good as adjacent value.");
196
}
197
}
198
}
199
200
201
err = d - StrictMath.pow(y2, 3);
202
if (err != 0.0) {
203
if(Double.isNaN(err)) {
204
failures++;
205
System.err.println("Encountered unexpected NaN value: d = " + d +
206
"\tcbrt(d) = " + y2);
207
} else {
208
if (err < 0.0) {
209
err_adjacent = StrictMath.pow(Math.nextUp(y2), 3) - d;
210
}
211
else { // (err > 0.0)
212
err_adjacent = StrictMath.pow(Math.nextAfter(y2,0.0), 3) - d;
213
}
214
215
if (Math.abs(err) > Math.abs(err_adjacent)) {
216
failures++;
217
System.err.println("For StrictMath.cbrt(" + d + "), returned result " +
218
y2 + "is not as good as adjacent value.");
219
}
220
}
221
}
222
223
224
}
225
226
// Test monotonicity properites near perfect cubes; test two
227
// numbers before and two numbers after; i.e. for
228
//
229
// pcNeighbors[] =
230
// {nextDown(nextDown(pc)),
231
// nextDown(pc),
232
// pc,
233
// nextUp(pc),
234
// nextUp(nextUp(pc))}
235
//
236
// test that cbrt(pcNeighbors[i]) <= cbrt(pcNeighbors[i+1])
237
{
238
239
double pcNeighbors[] = new double[5];
240
double pcNeighborsCbrt[] = new double[5];
241
double pcNeighborsStrictCbrt[] = new double[5];
242
243
// Test near cbrt(2^(3n)) = 2^n.
244
for(int i = 18; i <= DoubleConsts.MAX_EXPONENT/3; i++) {
245
double pc = Math.scalb(1.0, 3*i);
246
247
pcNeighbors[2] = pc;
248
pcNeighbors[1] = Math.nextDown(pc);
249
pcNeighbors[0] = Math.nextDown(pcNeighbors[1]);
250
pcNeighbors[3] = Math.nextUp(pc);
251
pcNeighbors[4] = Math.nextUp(pcNeighbors[3]);
252
253
for(int j = 0; j < pcNeighbors.length; j++) {
254
pcNeighborsCbrt[j] = Math.cbrt(pcNeighbors[j]);
255
pcNeighborsStrictCbrt[j] = StrictMath.cbrt(pcNeighbors[j]);
256
}
257
258
for(int j = 0; j < pcNeighborsCbrt.length-1; j++) {
259
if(pcNeighborsCbrt[j] > pcNeighborsCbrt[j+1] ) {
260
failures++;
261
System.err.println("Monotonicity failure for Math.cbrt on " +
262
pcNeighbors[j] + " and " +
263
pcNeighbors[j+1] + "\n\treturned " +
264
pcNeighborsCbrt[j] + " and " +
265
pcNeighborsCbrt[j+1] );
266
}
267
268
if(pcNeighborsStrictCbrt[j] > pcNeighborsStrictCbrt[j+1] ) {
269
failures++;
270
System.err.println("Monotonicity failure for StrictMath.cbrt on " +
271
pcNeighbors[j] + " and " +
272
pcNeighbors[j+1] + "\n\treturned " +
273
pcNeighborsStrictCbrt[j] + " and " +
274
pcNeighborsStrictCbrt[j+1] );
275
}
276
277
278
}
279
280
}
281
282
// Test near cbrt(2^(-3n)) = 2^-n.
283
for(int i = -1; i >= DoubleConsts.MIN_SUB_EXPONENT/3; i--) {
284
double pc = Math.scalb(1.0, 3*i);
285
286
pcNeighbors[2] = pc;
287
pcNeighbors[1] = Math.nextDown(pc);
288
pcNeighbors[0] = Math.nextDown(pcNeighbors[1]);
289
pcNeighbors[3] = Math.nextUp(pc);
290
pcNeighbors[4] = Math.nextUp(pcNeighbors[3]);
291
292
for(int j = 0; j < pcNeighbors.length; j++) {
293
pcNeighborsCbrt[j] = Math.cbrt(pcNeighbors[j]);
294
pcNeighborsStrictCbrt[j] = StrictMath.cbrt(pcNeighbors[j]);
295
}
296
297
for(int j = 0; j < pcNeighborsCbrt.length-1; j++) {
298
if(pcNeighborsCbrt[j] > pcNeighborsCbrt[j+1] ) {
299
failures++;
300
System.err.println("Monotonicity failure for Math.cbrt on " +
301
pcNeighbors[j] + " and " +
302
pcNeighbors[j+1] + "\n\treturned " +
303
pcNeighborsCbrt[j] + " and " +
304
pcNeighborsCbrt[j+1] );
305
}
306
307
if(pcNeighborsStrictCbrt[j] > pcNeighborsStrictCbrt[j+1] ) {
308
failures++;
309
System.err.println("Monotonicity failure for StrictMath.cbrt on " +
310
pcNeighbors[j] + " and " +
311
pcNeighbors[j+1] + "\n\treturned " +
312
pcNeighborsStrictCbrt[j] + " and " +
313
pcNeighborsStrictCbrt[j+1] );
314
}
315
316
317
}
318
}
319
}
320
321
return failures;
322
}
323
324
public static void main(String argv[]) {
325
int failures = 0;
326
327
failures += testCubeRoot();
328
329
if (failures > 0) {
330
System.err.println("Testing cbrt incurred "
331
+ failures + " failures.");
332
throw new RuntimeException();
333
}
334
}
335
336
}
337
338