809N/A/*
2362N/A * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
809N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
809N/A *
809N/A * This code is free software; you can redistribute it and/or modify it
809N/A * under the terms of the GNU General Public License version 2 only, as
809N/A * published by the Free Software Foundation.
809N/A *
809N/A * This code is distributed in the hope that it will be useful, but WITHOUT
809N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
809N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
809N/A * version 2 for more details (a copy is included in the LICENSE file that
809N/A * accompanied this code).
809N/A *
809N/A * You should have received a copy of the GNU General Public License version
809N/A * 2 along with this work; if not, write to the Free Software Foundation,
809N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
809N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
809N/A */
809N/A
809N/A/*
809N/A * Shared static test methods for numerical tests. Sharing these
809N/A * helper test methods avoids repeated functions in the various test
809N/A * programs. The test methods return 1 for a test failure and 0 for
809N/A * success. The order of arguments to the test methods is generally
809N/A * the test name, followed by the test arguments, the computed result,
809N/A * and finally the expected result.
809N/A */
809N/A
809N/Aimport sun.misc.FpUtils;
809N/A
809N/Apublic class Tests {
809N/A private Tests(){}; // do not instantiate
809N/A
809N/A private static String toHexString(float f) {
809N/A if (!Float.isNaN(f))
809N/A return Float.toHexString(f);
809N/A else
809N/A return "NaN(0x" + Integer.toHexString(Float.floatToRawIntBits(f)) + ")";
809N/A }
809N/A
809N/A private static String toHexString(double d) {
809N/A if (!Double.isNaN(d))
809N/A return Double.toHexString(d);
809N/A else
809N/A return "NaN(0x" + Long.toHexString(Double.doubleToRawLongBits(d)) + ")";
809N/A }
809N/A
809N/A public static int test(String testName, float input,
809N/A boolean result, boolean expected) {
809N/A if (expected != result) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\n" +
809N/A "\tgot " + result + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName, double input,
809N/A boolean result, boolean expected) {
809N/A if (expected != result) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\n" +
809N/A "\tgot " + result + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName, float input1, float input2,
809N/A boolean result, boolean expected) {
809N/A if (expected != result) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\t(" + toHexString(input2) + ")\n" +
809N/A "\texpected " + expected + "\n" +
809N/A "\tgot " + result + ").");
809N/A return 1;
809N/A }
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName, double input1, double input2,
809N/A boolean result, boolean expected) {
809N/A if (expected != result) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\t(" + toHexString(input2) + ")\n" +
809N/A "\texpected " + expected + "\n" +
809N/A "\tgot " + result + ").");
809N/A return 1;
809N/A }
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName, float input,
809N/A int result, int expected) {
809N/A if (expected != result) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\n" +
809N/A "\tgot " + result + ").");
809N/A return 1;
809N/A }
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName, double input,
809N/A int result, int expected) {
809N/A if (expected != result) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\n" +
809N/A "\tgot " + result + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName, float input,
809N/A float result, float expected) {
809N/A if (Float.compare(expected, result) != 0 ) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A
809N/A public static int test(String testName, double input,
809N/A double result, double expected) {
809N/A if (Double.compare(expected, result ) != 0) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName,
809N/A float input1, double input2,
809N/A float result, float expected) {
809N/A if (Float.compare(expected, result ) != 0) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\t(" + toHexString(input2) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName,
809N/A double input1, double input2,
809N/A double result, double expected) {
809N/A if (Double.compare(expected, result ) != 0) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\t(" + toHexString(input2) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName,
809N/A float input1, int input2,
809N/A float result, float expected) {
809N/A if (Float.compare(expected, result ) != 0) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A public static int test(String testName,
809N/A double input1, int input2,
809N/A double result, double expected) {
809N/A if (Double.compare(expected, result ) != 0) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ").");
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A
809N/A static int testUlpCore(double result, double expected, double ulps) {
809N/A // We assume we won't be unlucky and have an inexact expected
809N/A // be nextDown(2^i) when 2^i would be the correctly rounded
809N/A // answer. This would cause the ulp size to be half as large
809N/A // as it should be, doubling the measured error).
809N/A
809N/A if (Double.compare(expected, result) == 0) {
809N/A return 0; // result and expected are equivalent
809N/A } else {
809N/A if( ulps == 0.0) {
809N/A // Equivalent results required but not found
809N/A return 1;
809N/A } else {
809N/A double difference = expected - result;
809N/A if (FpUtils.isUnordered(expected, result) ||
809N/A Double.isNaN(difference) ||
809N/A // fail if greater than or unordered
809N/A !(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) {
809N/A return 1;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A }
809N/A }
809N/A
809N/A // One input argument.
809N/A public static int testUlpDiff(String testName, double input,
809N/A double result, double expected, double ulps) {
809N/A int code = testUlpCore(result, expected, ulps);
809N/A if (code == 1) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
809N/A "\tdifference greater than ulp tolerance " + ulps);
809N/A }
809N/A return code;
809N/A }
809N/A
809N/A // Two input arguments.
809N/A public static int testUlpDiff(String testName, double input1, double input2,
809N/A double result, double expected, double ulps) {
809N/A int code = testUlpCore(result, expected, ulps);
809N/A if (code == 1) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor inputs " + input1 + "\t(" + toHexString(input1) + ") and "
809N/A + input2 + "\t(" + toHexString(input2) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
809N/A "\tdifference greater than ulp tolerance " + ulps);
809N/A }
809N/A return code;
809N/A }
809N/A
809N/A // For a successful test, the result must be within the ulp bound of
809N/A // expected AND the result must have absolute value less than or
809N/A // equal to absBound.
809N/A public static int testUlpDiffWithAbsBound(String testName, double input,
809N/A double result, double expected,
809N/A double ulps, double absBound) {
809N/A int code = 0; // return code value
809N/A
809N/A if (!(StrictMath.abs(result) <= StrictMath.abs(absBound)) &&
809N/A !Double.isNaN(expected)) {
809N/A code = 1;
809N/A } else
809N/A code = testUlpCore(result, expected, ulps);
809N/A
809N/A if (code == 1) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
809N/A "\tdifference greater than ulp tolerance " + ulps +
809N/A " or the result has larger magnitude than " + absBound);
809N/A }
809N/A return code;
809N/A }
809N/A
809N/A // For a successful test, the result must be within the ulp bound of
809N/A // expected AND the result must have absolute value greater than
809N/A // or equal to the lowerBound.
809N/A public static int testUlpDiffWithLowerBound(String testName, double input,
809N/A double result, double expected,
809N/A double ulps, double lowerBound) {
809N/A int code = 0; // return code value
809N/A
809N/A if (!(result >= lowerBound) && !Double.isNaN(expected)) {
809N/A code = 1;
809N/A } else
809N/A code = testUlpCore(result, expected, ulps);
809N/A
809N/A if (code == 1) {
809N/A System.err.println("Failure for " + testName +
809N/A ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")" +
809N/A "\n\texpected " + expected + "\t(" + toHexString(expected) + ")" +
809N/A "\n\tgot " + result + "\t(" + toHexString(result) + ");" +
809N/A "\ndifference greater than ulp tolerance " + ulps +
809N/A " or result not greater than or equal to the bound " + lowerBound);
809N/A }
809N/A return code;
809N/A }
809N/A
809N/A public static int testTolerance(String testName, double input,
809N/A double result, double expected, double tolerance) {
809N/A if (Double.compare(expected, result ) != 0) {
809N/A double difference = expected - result;
809N/A if (FpUtils.isUnordered(expected, result) ||
809N/A Double.isNaN(difference) ||
809N/A // fail if greater than or unordered
809N/A !(Math.abs((difference)/expected) <= StrictMath.pow(10, -tolerance)) ) {
809N/A System.err.println("Failure for " + testName + ":\n" +
809N/A "\tFor input " + input + "\t(" + toHexString(input) + ")\n" +
809N/A "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" +
809N/A "\tgot " + result + "\t(" + toHexString(result) + ");\n" +
809N/A "\tdifference greater than tolerance 10^-" + tolerance);
809N/A return 1;
809N/A }
809N/A return 0;
809N/A }
809N/A else
809N/A return 0;
809N/A }
809N/A}