Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/Math/HypotTests.java
41149 views
1
/*
2
* Copyright (c) 2003, 2021, 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 HypotTests
29
* @bug 4851638 4939441 8078672 8240632
30
* @summary Tests for {Math, StrictMath}.hypot (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 HypotTests {
38
private HypotTests(){}
39
40
static final double infinityD = Double.POSITIVE_INFINITY;
41
static final double NaNd = Double.NaN;
42
43
/**
44
* Given integers m and n, assuming m < n, the triple (n^2 - m^2,
45
* 2mn, and n^2 + m^2) is a Pythagorean triple with a^2 + b^2 =
46
* c^2. This methods returns a long array holding the Pythagorean
47
* triple corresponding to the inputs.
48
*/
49
static long [] pythagoreanTriple(int m, int n) {
50
long M = m;
51
long N = n;
52
long result[] = new long[3];
53
54
55
result[0] = Math.abs(M*M - N*N);
56
result[1] = Math.abs(2*M*N);
57
result[2] = Math.abs(M*M + N*N);
58
59
return result;
60
}
61
62
static int testHypot() {
63
int failures = 0;
64
65
double [][] testCases = {
66
// Special cases
67
{infinityD, infinityD, infinityD},
68
{infinityD, 0.0, infinityD},
69
{infinityD, 1.0, infinityD},
70
{infinityD, NaNd, infinityD},
71
{NaNd, NaNd, NaNd},
72
{0.0, NaNd, NaNd},
73
{1.0, NaNd, NaNd},
74
{Double.longBitsToDouble(0x7FF0000000000001L), 1.0, NaNd},
75
{Double.longBitsToDouble(0xFFF0000000000001L), 1.0, NaNd},
76
{Double.longBitsToDouble(0x7FF8555555555555L), 1.0, NaNd},
77
{Double.longBitsToDouble(0xFFF8555555555555L), 1.0, NaNd},
78
{Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), 1.0, NaNd},
79
{Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), 1.0, NaNd},
80
{Double.longBitsToDouble(0x7FFDeadBeef00000L), 1.0, NaNd},
81
{Double.longBitsToDouble(0xFFFDeadBeef00000L), 1.0, NaNd},
82
{Double.longBitsToDouble(0x7FFCafeBabe00000L), 1.0, NaNd},
83
{Double.longBitsToDouble(0xFFFCafeBabe00000L), 1.0, NaNd},
84
};
85
86
for(int i = 0; i < testCases.length; i++) {
87
failures += testHypotCase(testCases[i][0], testCases[i][1],
88
testCases[i][2]);
89
}
90
91
// Verify hypot(x, 0.0) is close to x over the entire exponent
92
// range.
93
for(int i = DoubleConsts.MIN_SUB_EXPONENT;
94
i <= Double.MAX_EXPONENT;
95
i++) {
96
double input = Math.scalb(2, i);
97
failures += testHypotCase(input, 0.0, input);
98
}
99
100
101
// Test Pythagorean triples
102
103
// Small ones
104
for(int m = 1; m < 10; m++) {
105
for(int n = m+1; n < 11; n++) {
106
long [] result = pythagoreanTriple(m, n);
107
failures += testHypotCase(result[0], result[1], result[2]);
108
}
109
}
110
111
// Big ones
112
for(int m = 100000; m < 100100; m++) {
113
for(int n = m+100000; n < 200200; n++) {
114
long [] result = pythagoreanTriple(m, n);
115
failures += testHypotCase(result[0], result[1], result[2]);
116
}
117
}
118
119
// Approaching overflow tests
120
121
/*
122
* Create a random value r with an large-ish exponent. The
123
* result of hypot(3*r, 4*r) should be approximately 5*r. (The
124
* computation of 4*r is exact since it just changes the
125
* exponent). While the exponent of r is less than or equal
126
* to (MAX_EXPONENT - 3), the computation should not overflow.
127
*/
128
java.util.Random rand = RandomFactory.getRandom();
129
for(int i = 0; i < 1000; i++) {
130
double d = rand.nextDouble();
131
// Scale d to have an exponent equal to MAX_EXPONENT -15
132
d = Math.scalb(d, Double.MAX_EXPONENT
133
-15 - Tests.ilogb(d));
134
for(int j = 0; j <= 13; j += 1) {
135
failures += testHypotCase(3*d, 4*d, 5*d, 2.5);
136
d *= 2.0; // increase exponent by 1
137
}
138
}
139
140
// Test for monotonicity failures. Fix one argument and test
141
// two numbers before and two numbers after each chosen value;
142
// i.e.
143
//
144
// pcNeighbors[] =
145
// {nextDown(nextDown(pc)),
146
// nextDown(pc),
147
// pc,
148
// nextUp(pc),
149
// nextUp(nextUp(pc))}
150
//
151
// and we test that hypot(pcNeighbors[i]) <= hypot(pcNeighbors[i+1])
152
{
153
double pcNeighbors[] = new double[5];
154
double pcNeighborsHypot[] = new double[5];
155
double pcNeighborsStrictHypot[] = new double[5];
156
157
158
for(int i = -18; i <= 18; i++) {
159
double pc = Math.scalb(1.0, i);
160
161
pcNeighbors[2] = pc;
162
pcNeighbors[1] = Math.nextDown(pc);
163
pcNeighbors[0] = Math.nextDown(pcNeighbors[1]);
164
pcNeighbors[3] = Math.nextUp(pc);
165
pcNeighbors[4] = Math.nextUp(pcNeighbors[3]);
166
167
for(int j = 0; j < pcNeighbors.length; j++) {
168
pcNeighborsHypot[j] = Math.hypot(2.0, pcNeighbors[j]);
169
pcNeighborsStrictHypot[j] = StrictMath.hypot(2.0, pcNeighbors[j]);
170
}
171
172
for(int j = 0; j < pcNeighborsHypot.length-1; j++) {
173
if(pcNeighborsHypot[j] > pcNeighborsHypot[j+1] ) {
174
failures++;
175
System.err.println("Monotonicity failure for Math.hypot on " +
176
pcNeighbors[j] + " and " +
177
pcNeighbors[j+1] + "\n\treturned " +
178
pcNeighborsHypot[j] + " and " +
179
pcNeighborsHypot[j+1] );
180
}
181
182
if(pcNeighborsStrictHypot[j] > pcNeighborsStrictHypot[j+1] ) {
183
failures++;
184
System.err.println("Monotonicity failure for StrictMath.hypot on " +
185
pcNeighbors[j] + " and " +
186
pcNeighbors[j+1] + "\n\treturned " +
187
pcNeighborsStrictHypot[j] + " and " +
188
pcNeighborsStrictHypot[j+1] );
189
}
190
191
192
}
193
194
}
195
}
196
197
198
return failures;
199
}
200
201
/**
202
* Verify +0.0 is returned if both arguments are zero.
203
*/
204
private static int testHypotZeros() {
205
return testHypotCase(0.0, 0.0, +0.0, 0.0);
206
}
207
208
static int testHypotCase(double input1, double input2, double expected) {
209
return testHypotCase(input1,input2, expected, 1);
210
}
211
212
static int testHypotCase(double input1, double input2, double expected,
213
double ulps) {
214
int failures = 0;
215
if (expected < 0.0) {
216
throw new AssertionError("Result of hypot must be greater than " +
217
"or equal to zero");
218
}
219
220
// Test Math and StrictMath methods with no inputs negated,
221
// each input negated singly, and both inputs negated. Also
222
// test inputs in reversed order.
223
224
for(int i = -1; i <= 1; i+=2) {
225
for(int j = -1; j <= 1; j+=2) {
226
double x = i * input1;
227
double y = j * input2;
228
failures += Tests.testUlpDiff("Math.hypot", x, y,
229
Math.hypot(x, y), expected, ulps);
230
failures += Tests.testUlpDiff("Math.hypot", y, x,
231
Math.hypot(y, x ), expected, ulps);
232
233
failures += Tests.testUlpDiff("StrictMath.hypot", x, y,
234
StrictMath.hypot(x, y), expected, ulps);
235
failures += Tests.testUlpDiff("StrictMath.hypot", y, x,
236
StrictMath.hypot(y, x), expected, ulps);
237
}
238
}
239
240
return failures;
241
}
242
243
public static void main(String argv[]) {
244
int failures = 0;
245
246
failures += testHypot();
247
failures += testHypotZeros();
248
249
if (failures > 0) {
250
System.err.println("Testing the hypot incurred "
251
+ failures + " failures.");
252
throw new RuntimeException();
253
}
254
}
255
256
}
257
258