blob: 7dd6d68075faef4d3b72cffc73f8675bf92d42d1 [file] [log] [blame]
darcy32db4492009-01-26 19:49:26 -08001/*
katlemand08780c2012-12-20 16:24:50 -08002 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
darcy32db4492009-01-26 19:49:26 -08003 * 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 *
ohair2283b9d2010-05-25 15:58:33 -070019 * 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.
darcy32db4492009-01-26 19:49:26 -080022 */
23
24/*
25 * Shared static test methods for numerical tests. Sharing these
26 * helper test methods avoids repeated functions in the various test
27 * programs. The test methods return 1 for a test failure and 0 for
28 * success. The order of arguments to the test methods is generally
29 * the test name, followed by the test arguments, the computed result,
30 * and finally the expected result.
31 */
32
33import sun.misc.FpUtils;
34
35public class Tests {
36 private Tests(){}; // do not instantiate
37
darcy1d52e122011-08-12 13:36:39 -070038 public static String toHexString(float f) {
darcy32db4492009-01-26 19:49:26 -080039 if (!Float.isNaN(f))
40 return Float.toHexString(f);
41 else
42 return "NaN(0x" + Integer.toHexString(Float.floatToRawIntBits(f)) + ")";
43 }
44
darcy1d52e122011-08-12 13:36:39 -070045 public static String toHexString(double d) {
darcy32db4492009-01-26 19:49:26 -080046 if (!Double.isNaN(d))
47 return Double.toHexString(d);
48 else
49 return "NaN(0x" + Long.toHexString(Double.doubleToRawLongBits(d)) + ")";
50 }
51
darcy1d52e122011-08-12 13:36:39 -070052 /**
53 * Return the floating-point value next larger in magnitude.
54 */
55 public static double nextOut(double d) {
56 if (d > 0.0)
57 return Math.nextUp(d);
58 else
59 return -Math.nextUp(-d);
60 }
61
darcy32db4492009-01-26 19:49:26 -080062 public static int test(String testName, float input,
63 boolean result, boolean expected) {
64 if (expected != result) {
65 System.err.println("Failure for " + testName + ":\n" +
66 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
67 "\texpected " + expected + "\n" +
68 "\tgot " + result + ").");
69 return 1;
70 }
71 else
72 return 0;
73 }
74
75 public static int test(String testName, double input,
76 boolean result, boolean expected) {
77 if (expected != result) {
78 System.err.println("Failure for " + testName + ":\n" +
79 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
80 "\texpected " + expected + "\n" +
81 "\tgot " + result + ").");
82 return 1;
83 }
84 else
85 return 0;
86 }
87
88 public static int test(String testName, float input1, float input2,
89 boolean result, boolean expected) {
90 if (expected != result) {
91 System.err.println("Failure for " + testName + ":\n" +
92 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
93 + input2 + "\t(" + toHexString(input2) + ")\n" +
94 "\texpected " + expected + "\n" +
95 "\tgot " + result + ").");
96 return 1;
97 }
98 return 0;
99 }
100
101 public static int test(String testName, double input1, double input2,
102 boolean result, boolean expected) {
103 if (expected != result) {
104 System.err.println("Failure for " + testName + ":\n" +
105 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
106 + input2 + "\t(" + toHexString(input2) + ")\n" +
107 "\texpected " + expected + "\n" +
108 "\tgot " + result + ").");
109 return 1;
110 }
111 return 0;
112 }
113
114 public static int test(String testName, float input,
115 int result, int expected) {
116 if (expected != result) {
117 System.err.println("Failure for " + testName + ":\n" +
118 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
119 "\texpected " + expected + "\n" +
120 "\tgot " + result + ").");
121 return 1;
122 }
123 return 0;
124 }
125
126 public static int test(String testName, double input,
127 int result, int expected) {
128 if (expected != result) {
129 System.err.println("Failure for " + testName + ":\n" +
130 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
131 "\texpected " + expected + "\n" +
132 "\tgot " + result + ").");
133 return 1;
134 }
135 else
136 return 0;
137 }
138
139 public static int test(String testName, float input,
140 float result, float expected) {
141 if (Float.compare(expected, result) != 0 ) {
142 System.err.println("Failure for " + testName + ":\n" +
143 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
144 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
145 "\tgot " + result + "\t(" + toHexString(result) + ").");
146 return 1;
147 }
148 else
149 return 0;
150 }
151
152
153 public static int test(String testName, double input,
154 double result, double expected) {
155 if (Double.compare(expected, result ) != 0) {
156 System.err.println("Failure for " + testName + ":\n" +
157 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
158 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
159 "\tgot " + result + "\t(" + toHexString(result) + ").");
160 return 1;
161 }
162 else
163 return 0;
164 }
165
166 public static int test(String testName,
167 float input1, double input2,
168 float result, float expected) {
169 if (Float.compare(expected, result ) != 0) {
170 System.err.println("Failure for " + testName + ":\n" +
171 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
172 + input2 + "\t(" + toHexString(input2) + ")\n" +
173 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
174 "\tgot " + result + "\t(" + toHexString(result) + ").");
175 return 1;
176 }
177 else
178 return 0;
179 }
180
181 public static int test(String testName,
182 double input1, double input2,
183 double result, double expected) {
184 if (Double.compare(expected, result ) != 0) {
185 System.err.println("Failure for " + testName + ":\n" +
186 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
187 + input2 + "\t(" + toHexString(input2) + ")\n" +
188 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
189 "\tgot " + result + "\t(" + toHexString(result) + ").");
190 return 1;
191 }
192 else
193 return 0;
194 }
195
196 public static int test(String testName,
197 float input1, int input2,
198 float result, float expected) {
199 if (Float.compare(expected, result ) != 0) {
200 System.err.println("Failure for " + testName + ":\n" +
201 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
202 + input2 + "\n" +
203 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
204 "\tgot " + result + "\t(" + toHexString(result) + ").");
205 return 1;
206 }
207 else
208 return 0;
209 }
210
211 public static int test(String testName,
212 double input1, int input2,
213 double result, double expected) {
214 if (Double.compare(expected, result ) != 0) {
215 System.err.println("Failure for " + testName + ":\n" +
216 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
217 + input2 + "\n" +
218 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
219 "\tgot " + result + "\t(" + toHexString(result) + ").");
220 return 1;
221 }
222 else
223 return 0;
224 }
225
226 static int testUlpCore(double result, double expected, double ulps) {
227 // We assume we won't be unlucky and have an inexact expected
228 // be nextDown(2^i) when 2^i would be the correctly rounded
229 // answer. This would cause the ulp size to be half as large
230 // as it should be, doubling the measured error).
231
232 if (Double.compare(expected, result) == 0) {
233 return 0; // result and expected are equivalent
234 } else {
235 if( ulps == 0.0) {
236 // Equivalent results required but not found
237 return 1;
238 } else {
239 double difference = expected - result;
240 if (FpUtils.isUnordered(expected, result) ||
241 Double.isNaN(difference) ||
242 // fail if greater than or unordered
243 !(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) {
244 return 1;
245 }
246 else
247 return 0;
248 }
249 }
250 }
251
252 // One input argument.
253 public static int testUlpDiff(String testName, double input,
254 double result, double expected, double ulps) {
255 int code = testUlpCore(result, expected, ulps);
256 if (code == 1) {
257 System.err.println("Failure for " + testName + ":\n" +
258 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
259 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
260 "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
261 "\tdifference greater than ulp tolerance " + ulps);
262 }
263 return code;
264 }
265
266 // Two input arguments.
267 public static int testUlpDiff(String testName, double input1, double input2,
268 double result, double expected, double ulps) {
269 int code = testUlpCore(result, expected, ulps);
270 if (code == 1) {
271 System.err.println("Failure for " + testName + ":\n" +
272 "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
273 + input2 + "\t(" + toHexString(input2) + ")\n" +
274 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
275 "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
276 "\tdifference greater than ulp tolerance " + ulps);
277 }
278 return code;
279 }
280
281 // For a successful test, the result must be within the ulp bound of
282 // expected AND the result must have absolute value less than or
283 // equal to absBound.
284 public static int testUlpDiffWithAbsBound(String testName, double input,
285 double result, double expected,
286 double ulps, double absBound) {
287 int code = 0; // return code value
288
289 if (!(StrictMath.abs(result) <= StrictMath.abs(absBound)) &&
290 !Double.isNaN(expected)) {
291 code = 1;
292 } else
293 code = testUlpCore(result, expected, ulps);
294
295 if (code == 1) {
296 System.err.println("Failure for " + testName + ":\n" +
297 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
298 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
299 "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
300 "\tdifference greater than ulp tolerance " + ulps +
301 " or the result has larger magnitude than " + absBound);
302 }
303 return code;
304 }
305
306 // For a successful test, the result must be within the ulp bound of
307 // expected AND the result must have absolute value greater than
308 // or equal to the lowerBound.
309 public static int testUlpDiffWithLowerBound(String testName, double input,
310 double result, double expected,
311 double ulps, double lowerBound) {
312 int code = 0; // return code value
313
314 if (!(result >= lowerBound) && !Double.isNaN(expected)) {
315 code = 1;
316 } else
317 code = testUlpCore(result, expected, ulps);
318
319 if (code == 1) {
320 System.err.println("Failure for " + testName +
321 ":\n" +
322 "\tFor input " + input + "\t(" + toHexString(input) + ")" +
323 "\n\texpected " + expected + "\t(" + toHexString(expected) + ")" +
324 "\n\tgot " + result + "\t(" + toHexString(result) + ");" +
325 "\ndifference greater than ulp tolerance " + ulps +
326 " or result not greater than or equal to the bound " + lowerBound);
327 }
328 return code;
329 }
330
331 public static int testTolerance(String testName, double input,
332 double result, double expected, double tolerance) {
333 if (Double.compare(expected, result ) != 0) {
334 double difference = expected - result;
335 if (FpUtils.isUnordered(expected, result) ||
336 Double.isNaN(difference) ||
337 // fail if greater than or unordered
338 !(Math.abs((difference)/expected) <= StrictMath.pow(10, -tolerance)) ) {
339 System.err.println("Failure for " + testName + ":\n" +
340 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
341 "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
342 "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
343 "\tdifference greater than tolerance 10^-" + tolerance);
344 return 1;
345 }
346 return 0;
347 }
348 else
349 return 0;
350 }
darcy1d52e122011-08-12 13:36:39 -0700351
352 // For a successful test, the result must be within the upper and
353 // lower bounds.
354 public static int testBounds(String testName, double input, double result,
355 double bound1, double bound2) {
356 if ((result >= bound1 && result <= bound2) ||
357 (result <= bound1 && result >= bound2))
358 return 0;
359 else {
360 double lowerBound = Math.min(bound1, bound2);
361 double upperBound = Math.max(bound1, bound2);
362 System.err.println("Failure for " + testName + ":\n" +
363 "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
364 "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
365 "\toutside of range\n" +
366 "\t[" + lowerBound + "\t(" + toHexString(lowerBound) + "), " +
367 upperBound + "\t(" + toHexString(upperBound) + ")]");
368 return 1;
369 }
370 }
darcy32db4492009-01-26 19:49:26 -0800371}