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