/*
 * Copyright (c) 2003, 2023, 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.
 */

/*
 * @test
 * @bug 4074599 4939441
 * @build Tests
 * @build Log10Tests
 * @run main Log10Tests
 * @summary Tests for {Math, StrictMath}.log10
 */

import static java.lang.Double.longBitsToDouble;

public class Log10Tests {
    private Log10Tests(){}

    private static final double infinityD = Double.POSITIVE_INFINITY;
    private static final double NaNd = Double.NaN;
    private static final double LN_10 = StrictMath.log(10.0);

    // Initialize shared random number generator
    static java.util.Random rand = new java.util.Random(0L);

    private static int testLog10Case(double input, double expected) {
        int failures=0;

        failures += Tests.test("Math.log10",       input, Math::log10,       expected);
        failures += Tests.test("StrictMath.log10", input, StrictMath::log10, expected);

        return failures;
    }

    private static int testLog10() {
        int failures = 0;

        for(double nan : Tests.NaNs) {
            failures += testLog10Case(nan, NaNd);
        }

        double [][] testCases = {
            {Double.NEGATIVE_INFINITY,  NaNd},
            {-8.0,                      NaNd},
            {-1.0,                      NaNd},
            {-Double.MIN_NORMAL,        NaNd},
            {-Double.MIN_VALUE,         NaNd},
            {-0.0,                      -infinityD},
            {+0.0,                      -infinityD},
            {+1.0,                      0.0},
            {Double.POSITIVE_INFINITY,  infinityD},
        };

        // Test special cases
        for(int i = 0; i < testCases.length; i++) {
            failures += testLog10Case(testCases[i][0],
                                          testCases[i][1]);
        }

        // Test log10(10^n) == n for integer n; 10^n, n < 0 is not
        // exactly representable as a floating-point value -- up to
        // 10^22 can be represented exactly
        double testCase = 1.0;
        for(int i = 0; i < 23; i++) {
            failures += testLog10Case(testCase, i);
            testCase *= 10.0;
        }

        // Test for gross inaccuracy by comparing to log; should be
        // within a few ulps of log(x)/log(10)
        for(int i = 0; i < 10000; i++) {
            double input = Double.longBitsToDouble(rand.nextLong());
            if(! Double.isFinite(input))
                continue; // avoid testing NaN and infinite values
            else {
                input = Math.abs(input);

                double expected = StrictMath.log(input)/LN_10;
                if( ! Double.isFinite(expected))
                    continue; // if log(input) overflowed, try again
                else {
                    double result;

                    if( Math.abs(((result=Math.log10(input)) - expected)/Math.ulp(expected)) > 3) {
                        failures++;
                        System.err.println("For input " + input +
                                           ", Math.log10 was more than 3 ulps different from " +
                                           "log(input)/log(10): log10(input) = " + result +
                                           "\tlog(input)/log(10) = " + expected);
                    }

                    if( Math.abs(((result=StrictMath.log10(input)) - expected)/Math.ulp(expected)) > 3) {
                        failures++;
                        System.err.println("For input " + input +
                                           ", StrictMath.log10 was more than 3 ulps different from " +
                                           "log(input)/log(10): log10(input) = " + result +
                                           "\tlog(input)/log(10) = " + expected);
                    }
                }
            }
        }

        // Test for accuracy and monotonicity near log10(1.0).  From
        // the Taylor expansion of log,
        // log10(1+z) ~= (z -(z^2)/2)/LN_10;
        {
            double neighbors[] =        new double[40];
            double neighborsStrict[] =  new double[40];
            double z = Double.NaN;

            // Test inputs greater than 1.0.
            neighbors[0] =              Math.log10(1.0);
            neighborsStrict[0] =        StrictMath.log10(1.0);

            double input[] =  new double[40];
            int half = input.length/2;


            // Initialize input to the 40 consecutive double values
            // "centered" at 1.0.
            double up = Double.NaN;
            double down = Double.NaN;
            for(int i = 0; i < half; i++) {
                if (i == 0) {
                    input[half] = 1.0;
                    up   = Math.nextUp(1.0);
                    down = Math.nextDown(1.0);
                } else {
                    input[half + i] = up;
                    input[half - i] = down;
                    up   = Math.nextUp(up);
                    down = Math.nextDown(down);
                }
            }
            input[0] = Math.nextDown(input[1]);

            for(int i = 0; i < neighbors.length; i++) {
                neighbors[i] =          Math.log10(input[i]);
                neighborsStrict[i] =    StrictMath.log10(input[i]);

                // Test accuracy.
                z = input[i] - 1.0;
                double expected = (z - (z*z)*0.5)/LN_10;
                if ( Math.abs(neighbors[i] - expected ) > 3*Math.ulp(expected) ) {
                    failures++;
                    System.err.println("For input near 1.0 " + input[i] +
                                       ", Math.log10(1+z) was more than 3 ulps different from " +
                                       "(z-(z^2)/2)/ln(10): log10(input) = " + neighbors[i] +
                                       "\texpected about = " + expected);
                }

                if ( Math.abs(neighborsStrict[i] - expected ) > 3*Math.ulp(expected) ) {
                    failures++;
                    System.err.println("For input near 1.0 " + input[i] +
                                       ", StrictMath.log10(1+z) was more than 3 ulps different from " +
                                       "(z-(z^2)/2)/ln(10): log10(input) = " + neighborsStrict[i] +
                                       "\texpected about = " + expected);
                }

                // Test monotonicity
                if( i > 0) {
                    if( neighbors[i-1] > neighbors[i] ) {
                        failures++;
                        System.err.println("Monotonicity failure for Math.log10  at " + input[i] +
                                           " and prior value.");
                    }

                    if( neighborsStrict[i-1] > neighborsStrict[i] ) {
                        failures++;
                        System.err.println("Monotonicity failure for StrictMath.log10  at " + input[i] +
                                           " and prior value.");
                    }
                }
            }

        }

        return failures;
    }

    public static void main(String... argv) {
        int failures = 0;

        failures += testLog10();

        if (failures > 0) {
            System.err.println("Testing log10 incurred "
                               + failures + " failures.");
            throw new RuntimeException();
        }
    }
}
