/*
 * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleUnaryOperator;
import java.util.function.DoubleToIntFunction;
import static java.lang.Double.longBitsToDouble;

/*
 * Shared static test methods for numerical tests.  Sharing these
 * helper test methods avoids repeated functions in the various test
 * programs.  The test methods return 1 for a test failure and 0 for
 * success.  The order of arguments to the test methods is generally
 * the test name, followed by the test arguments, the computed result,
 * and finally the expected result.
 */

public class Tests {
    private Tests(){}; // do not instantiate

    // Used to create a NaN value at runtime; mark as volatile to foil
    // compile-time constant folding.
    static volatile double zero = 0.0;

    private static final double PLATFORM_NAN = zero / zero;

    public static final double[] NaNs = {
            Double.NaN,
            PLATFORM_NAN,
            bitwiseNegate(PLATFORM_NAN),
            // Exotic NaN bit patterns. Includes values that would
            // *not* be considered a NaN if only the high-order
            // 32-bits were examined.
            longBitsToDouble(0x7FF0_0000_0000_0001L),
            longBitsToDouble(0xFFF0_0000_0000_0001L),
            longBitsToDouble(0x7FF8_5555_5555_5555L),
            longBitsToDouble(0xFFF8_5555_5555_5555L),
            longBitsToDouble(0x7FFF_FFFF_FFFF_FFFFL),
            longBitsToDouble(0xFFFF_FFFF_FFFF_FFFFL),
            longBitsToDouble(0x7FF0_0000_7FFF_FFFFL),
            longBitsToDouble(0xFFF0_0000_7FFF_FFFFL),
            longBitsToDouble(0x7FF0_Dead_Beef_0000L),
            longBitsToDouble(0xFFF0_Dead_Beef_0000L),
            longBitsToDouble(0x7FF0_Cafe_Babe_0000L),
            longBitsToDouble(0xFFF0_Cafe_Babe_0000L),
    };

    public static double bitwiseNegate(double d) {
        long SIGNBIT = 0x8000_0000_0000_0000L;
        return longBitsToDouble(Double.doubleToRawLongBits(d) ^ SIGNBIT );
    }

    public static String toHexString(float f) {
        if (!Float.isNaN(f))
            return Float.toHexString(f);
        else
            return "NaN(0x" + Integer.toHexString(Float.floatToRawIntBits(f)) + ")";
    }

    public static String toHexString(double d) {
        if (!Double.isNaN(d))
            return Double.toHexString(d);
        else
            return "NaN(0x" + Long.toHexString(Double.doubleToRawLongBits(d)) + ")";
    }

    /**
     * Return the floating-point value next larger in magnitude.
     */
    public static double nextOut(double d) {
        if (d != 0.0)
            return (d > 0.0) ? Math.nextUp(d) : Math.nextDown(d);
        else
            return Math.copySign(Double.MIN_VALUE, d);
    }

    /**
     * Returns unbiased exponent of a {@code float}; for
     * subnormal values, the number is treated as if it were
     * normalized.  That is for all finite, non-zero, positive numbers
     * <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
     * always in the range [1, 2).
     * <p>
     * Special cases:
     * <ul>
     * <li> If the argument is NaN, then the result is 2<sup>30</sup>.
     * <li> If the argument is infinite, then the result is 2<sup>28</sup>.
     * <li> If the argument is zero, then the result is -(2<sup>28</sup>).
     * </ul>
     *
     * @param d floating-point number whose exponent is to be extracted
     * @return unbiased exponent of the argument.
     */
    public static int ilogb(double d) {
        int exponent = Math.getExponent(d);

        switch (exponent) {
        case Double.MAX_EXPONENT+1:       // NaN or infinity
            if( Double.isNaN(d) )
                return (1<<30);         // 2^30
            else // infinite value
                return (1<<28);         // 2^28

        case Double.MIN_EXPONENT-1:       // zero or subnormal
            if(d == 0.0) {
                return -(1<<28);        // -(2^28)
            }
            else {
                long transducer = Double.doubleToRawLongBits(d);

                /*
                 * To avoid causing slow arithmetic on subnormals,
                 * the scaling to determine when d's significand
                 * is normalized is done in integer arithmetic.
                 * (there must be at least one "1" bit in the
                 * significand since zero has been screened out.
                 */

                // isolate significand bits
                transducer &= DoubleConsts.SIGNIF_BIT_MASK;
                assert(transducer != 0L);

                // This loop is simple and functional. We might be
                // able to do something more clever that was faster;
                // e.g. number of leading zero detection on
                // (transducer << (# exponent and sign bits).
                while (transducer <
                       (1L << (DoubleConsts.SIGNIFICAND_WIDTH - 1))) {
                    transducer *= 2;
                    exponent--;
                }
                exponent++;
                assert( exponent >=
                        Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1) &&
                        exponent < Double.MIN_EXPONENT);
                return exponent;
            }

        default:
            assert( exponent >= Double.MIN_EXPONENT &&
                    exponent <= Double.MAX_EXPONENT);
            return exponent;
        }
    }

    /**
     * Returns unbiased exponent of a {@code float}; for
     * subnormal values, the number is treated as if it were
     * normalized.  That is for all finite, non-zero, positive numbers
     * <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
     * always in the range [1, 2).
     * <p>
     * Special cases:
     * <ul>
     * <li> If the argument is NaN, then the result is 2<sup>30</sup>.
     * <li> If the argument is infinite, then the result is 2<sup>28</sup>.
     * <li> If the argument is zero, then the result is -(2<sup>28</sup>).
     * </ul>
     *
     * @param f floating-point number whose exponent is to be extracted
     * @return unbiased exponent of the argument.
     */
     public static int ilogb(float f) {
        int exponent = Math.getExponent(f);

        switch (exponent) {
        case Float.MAX_EXPONENT+1:        // NaN or infinity
            if( Float.isNaN(f) )
                return (1<<30);         // 2^30
            else // infinite value
                return (1<<28);         // 2^28

        case Float.MIN_EXPONENT-1:        // zero or subnormal
            if(f == 0.0f) {
                return -(1<<28);        // -(2^28)
            }
            else {
                int transducer = Float.floatToRawIntBits(f);

                /*
                 * To avoid causing slow arithmetic on subnormals,
                 * the scaling to determine when f's significand
                 * is normalized is done in integer arithmetic.
                 * (there must be at least one "1" bit in the
                 * significand since zero has been screened out.
                 */

                // isolate significand bits
                transducer &= FloatConsts.SIGNIF_BIT_MASK;
                assert(transducer != 0);

                // This loop is simple and functional. We might be
                // able to do something more clever that was faster;
                // e.g. number of leading zero detection on
                // (transducer << (# exponent and sign bits).
                while (transducer <
                       (1 << (FloatConsts.SIGNIFICAND_WIDTH - 1))) {
                    transducer *= 2;
                    exponent--;
                }
                exponent++;
                assert( exponent >=
                        Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1) &&
                        exponent < Float.MIN_EXPONENT);
                return exponent;
            }

        default:
            assert( exponent >= Float.MIN_EXPONENT &&
                    exponent <= Float.MAX_EXPONENT);
            return exponent;
        }
    }

    /**
     * Returns {@code true} if the unordered relation holds
     * between the two arguments.  When two floating-point values are
     * unordered, one value is neither less than, equal to, nor
     * greater than the other.  For the unordered relation to be true,
     * at least one argument must be a {@code NaN}.
     *
     * @param arg1      the first argument
     * @param arg2      the second argument
     * @return {@code true} if at least one argument is a NaN,
     * {@code false} otherwise.
     */
     public static boolean isUnordered(float arg1, float arg2) {
        return Float.isNaN(arg1) || Float.isNaN(arg2);
    }

    /**
     * Returns {@code true} if the unordered relation holds
     * between the two arguments.  When two floating-point values are
     * unordered, one value is neither less than, equal to, nor
     * greater than the other.  For the unordered relation to be true,
     * at least one argument must be a {@code NaN}.
     *
     * @param arg1      the first argument
     * @param arg2      the second argument
     * @return {@code true} if at least one argument is a NaN,
     * {@code false} otherwise.
     */
    public static boolean isUnordered(double arg1, double arg2) {
        return Double.isNaN(arg1) || Double.isNaN(arg2);
    }

    public static int test(String testName, float input,
                           boolean result, boolean expected) {
        if (expected != result) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\n"  +
                               "\tgot       " + result   + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName, double input,
                           boolean result, boolean expected) {
        if (expected != result) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\n"  +
                               "\tgot       " + result   + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName, float input1, float input2,
                           boolean result, boolean expected) {
        if (expected != result) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
                               "\texpected  "  + expected + "\n"  +
                               "\tgot       "  + result   + ").");
            return 1;
        }
        return 0;
    }

    public static int test(String testName, double input1, double input2,
                           boolean result, boolean expected) {
        if (expected != result) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
                               "\texpected  "  + expected + "\n"  +
                               "\tgot       "  + result   + ").");
            return 1;
        }
        return 0;
    }

    public static int test(String testName, float input,
                           int result, int expected) {
        if (expected != result) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\n" +
                               "\tgot       " + result    + ").");
            return 1;
        }
        return 0;
    }

    public static int test(String testName,
                           double input,
                           DoubleToIntFunction func,
                           int expected) {
        return test(testName, input, func.applyAsInt(input), expected);
    }

    public  static int test(String testName, double input,
                            int result, int expected) {
        if (expected != result) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\n"  +
                               "\tgot       " + result   + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName, float input,
                           float result, float expected) {
        if (Float.compare(expected, result) != 0 ) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       " + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName,
                           double input,
                           DoubleUnaryOperator func,
                           double expected) {
        return test(testName, input, func.applyAsDouble(input), expected);
    }

    public static int test(String testName, double input,
                           double result, double expected) {
        if (Double.compare(expected, result ) != 0) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       " + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName,
                           float input1, double input2,
                           float result, float expected) {
        if (Float.compare(expected, result ) != 0) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName,
                           double input1, double input2,
                           DoubleBinaryOperator func,
                           double expected) {
        return test(testName, input1, input2, func.applyAsDouble(input1, input2), expected);
    }

    public static int test(String testName,
                           double input1, double input2,
                           double result, double expected) {
        if (Double.compare(expected, result ) != 0) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName,
                           float input1, int input2,
                           float result, float expected) {
        if (Float.compare(expected, result ) != 0) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\n"  +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName,
                           double input1, int input2,
                           double result, double expected) {
        if (Double.compare(expected, result ) != 0) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\n"  +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    public static int test(String testName,
                           float input1, float input2, float input3,
                           float result, float expected) {
        if (Float.compare(expected, result ) != 0) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ") and"
                                               + input3   + "\t(" + toHexString(input3) + ")\n"  +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    @FunctionalInterface
    public interface DoubleTernaryOperator {
        double applyAsDouble(double input1, double input2, double input3);
    }

    public static int test(String testName,
                           double input1, double input2, double input3,
                           DoubleTernaryOperator func, double expected) {
        return test(testName, input1, input2, input3, func.applyAsDouble(input1, input2, input3), expected);

    }

    public static int test(String testName,
                           double input1, double input2, double input3,
                           double result, double expected) {
        if (Double.compare(expected, result ) != 0) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ") and"
                                               + input3   + "\t(" + toHexString(input3) + ")\n"  +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
            return 1;
        } else {
            return 0;
        }
    }

    static int testUlpCore(double result, double expected, double ulps) {
        // We assume we won't be unlucky and have an inexact expected
        // be nextDown(2^i) when 2^i would be the correctly rounded
        // answer.  This would cause the ulp size to be half as large
        // as it should be, doubling the measured error).

        if (Double.compare(expected, result) == 0) {
            return 0;   // result and expected are equivalent
        } else {
            if( ulps == 0.0) {
                // Equivalent results required but not found
                return 1;
            } else {
                double difference = expected - result;
                if (isUnordered(expected, result) ||
                    Double.isNaN(difference) ||
                    // fail if greater than or unordered
                    !(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }
    }

    // One input argument.
    public static int testUlpDiff(String testName, double input,
                                  DoubleUnaryOperator func, double expected, double ulps) {
        return testUlpDiff(testName, input, func.applyAsDouble(input), expected, ulps);
    }

    public static int testUlpDiff(String testName, double input,
                                  double result, double expected, double ulps) {
        int code = testUlpCore(result, expected, ulps);
        if (code == 1) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
                               "\tdifference greater than ulp tolerance " + ulps);
        }
        return code;
    }

    // Two input arguments.
    public static int testUlpDiff(String testName, double input1, double input2,
                                  DoubleBinaryOperator func, double expected, double ulps) {
        return testUlpDiff(testName, input1, input2, func.applyAsDouble(input1, input2), expected, ulps);
    }

    public static int testUlpDiff(String testName, double input1, double input2,
                                  double result, double expected, double ulps) {
        int code = testUlpCore(result, expected, ulps);
        if (code == 1) {
            System.err.println("Failure for "  + testName + ":\n" +
                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       "  + result   + "\t(" + toHexString(result) + ");\n" +
                               "\tdifference greater than ulp tolerance " + ulps);
        }
        return code;
    }

    // For a successful test, the result must be within the ulp bound of
    // expected AND the result must have absolute value less than or
    // equal to absBound.
    public static int testUlpDiffWithAbsBound(String testName, double input,
                                              DoubleUnaryOperator func, double expected,
                                              double ulps, double absBound) {
        return testUlpDiffWithAbsBound(testName, input,
                                       func.applyAsDouble(input), expected,
                                       ulps, absBound);
    }

    public static int testUlpDiffWithAbsBound(String testName, double input,
                                              double result, double expected,
                                              double ulps, double absBound) {
        int code = 0;   // return code value

        if (!(StrictMath.abs(result) <= StrictMath.abs(absBound)) &&
            !Double.isNaN(expected)) {
            code = 1;
        } else
            code = testUlpCore(result, expected, ulps);

        if (code == 1) {
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
                               "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
                               "\tdifference greater than ulp tolerance " + ulps +
                               " or the result has larger magnitude than " + absBound);
        }
        return code;
    }

    // For a successful test, the result must be within the ulp bound of
    // expected AND the result must have absolute value greater than
    // or equal to the lowerBound.
    public static int testUlpDiffWithLowerBound(String testName, double input,
                                                DoubleUnaryOperator func, double expected,
                                                double ulps, double lowerBound) {
        return testUlpDiffWithLowerBound(testName, input,
                                         func.applyAsDouble(input), expected,
                                         ulps, lowerBound);
    }

    public static int testUlpDiffWithLowerBound(String testName, double input,
                                                double result, double expected,
                                                double ulps, double lowerBound) {
        int code = 0;   // return code value

        if (!(result >= lowerBound) && !Double.isNaN(expected)) {
            code = 1;
        } else {
            code = testUlpCore(result, expected, ulps);
        }

        if (code == 1) {
            System.err.println("Failure for " + testName +
                               ":\n" +
                               "\tFor input "   + input    + "\t(" + toHexString(input) + ")" +
                               "\n\texpected  " + expected + "\t(" + toHexString(expected) + ")" +
                               "\n\tgot       " + result   + "\t(" + toHexString(result) + ");" +
                               "\ndifference greater than ulp tolerance " + ulps +
                               " or result not greater than or equal to the bound " + lowerBound);
        }
        return code;
    }

    public static int testTolerance(String testName, double input,
                                    DoubleUnaryOperator func, double expected, double tolerance) {
        return testTolerance(testName, input, func.applyAsDouble(input), expected, tolerance);

    }
    public static int testTolerance(String testName, double input,
                                    double result, double expected, double tolerance) {
        if (Double.compare(expected, result ) != 0) {
            double difference = expected - result;
            if (isUnordered(expected, result) ||
                Double.isNaN(difference) ||
                // fail if greater than or unordered
                !(Math.abs((difference)/expected) <= StrictMath.pow(10, -tolerance)) ) {
                System.err.println("Failure for " + testName + ":\n" +
                                   "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                                   "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
                                   "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
                                   "\tdifference greater than tolerance 10^-" + tolerance);
                return 1;
            }
            return 0;
        } else {
            return 0;
        }
    }

    // For a successful test, the result must be within the upper and
    // lower bounds.
    public static int testBounds(String testName, double input, DoubleUnaryOperator func,
                                 double bound1, double bound2) {
        return testBounds(testName, input, func.applyAsDouble(input), bound1, bound2);
    }

    public static int testBounds(String testName, double input, double result,
                                 double bound1, double bound2) {
        if ((result >= bound1 && result <= bound2) ||
            (result <= bound1 && result >= bound2))
            return 0;
        else {
            double lowerBound = Math.min(bound1, bound2);
            double upperBound = Math.max(bound1, bound2);
            System.err.println("Failure for " + testName + ":\n" +
                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
                               "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
                               "\toutside of range\n" +
                               "\t[" + lowerBound    + "\t(" + toHexString(lowerBound) + "), " +
                               upperBound    + "\t(" + toHexString(upperBound) + ")]");
            return 1;
        }
    }
}
