/*
 * Copyright (c) 2005, 2012, 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 6274390 7082971
 * @summary Verify {float, double}Value methods work with condensed representation
 * @run main FloatDoubleValueTests
 * @run main/othervm -XX:+AggressiveOpts FloatDoubleValueTests
 */
import java.math.*;

public class FloatDoubleValueTests {
    private static final long two2the24 = 1L<<23;
    private static final long two2the53 = 1L<<52;

    // Largest long that fits exactly in a float
    private static final long maxFltLong = (long)(Integer.MAX_VALUE & ~(0xff));

    // Largest long that fits exactly in a double
    private static final long maxDblLong = Long.MAX_VALUE & ~(0x7ffL);

    static void testDoubleValue0(long i, BigDecimal bd) {
        if (bd.doubleValue() != i ||
            bd.longValue()   != i)
            throw new RuntimeException("Unexpected equality failure for " +
                                       i + "\t" + bd);
    }

    static void testFloatValue0(long i, BigDecimal bd) {
        if (bd.floatValue() != i ||
            bd.longValue()   != i)
            throw new RuntimeException("Unexpected equality failure for " +
                                       i + "\t" + bd);
    }

    static void checkFloat(BigDecimal bd, float f) {
        float fbd = bd.floatValue();
        if (f != fbd ) {
            String message = String.format("Bad conversion:"+
                                           "got %g (%a)\texpected %g (%a)",
                                           f, f, fbd, fbd);
            throw new RuntimeException(message);
        }
    }

    static void checkDouble(BigDecimal bd, double d) {
        double dbd = bd.doubleValue();

        if (d != dbd ) {
            String message = String.format("Bad conversion:"+
                                           "got %g (%a)\texpected %g (%a)",
                                           d, d, dbd, dbd);
            throw new RuntimeException(message);
        }
    }

    // Test integral values that will convert exactly to both float
    // and double.
    static void testFloatDoubleValue() {
        long longValues[] = {
            Long.MIN_VALUE, // -2^63
            0,
            1,
            2,

            two2the24-1,
            two2the24,
            two2the24+1,

            maxFltLong-1,
            maxFltLong,
            maxFltLong+1,
        };

        for(long i : longValues) {
            BigDecimal bd1 = new BigDecimal(i);
            BigDecimal bd2 = new BigDecimal(-i);

            testDoubleValue0( i, bd1);
            testDoubleValue0(-i, bd2);

            testFloatValue0( i, bd1);
            testFloatValue0(-i, bd2);
        }

    }

    static void testDoubleValue() {
        long longValues[] = {
            Integer.MAX_VALUE-1,
            Integer.MAX_VALUE,
            (long)Integer.MAX_VALUE+1,

            two2the53-1,
            two2the53,
            two2the53+1,

            maxDblLong,
        };

        // Test integral values that will convert exactly to double
        // but not float.
        for(long i : longValues) {
            BigDecimal bd1 = new BigDecimal(i);
            BigDecimal bd2 = new BigDecimal(-i);

            testDoubleValue0( i, bd1);
            testDoubleValue0(-i, bd2);

            checkFloat(bd1, (float)i);
            checkFloat(bd2, -(float)i);
        }

        // Now check values that should not convert the same in double
        for(long i = maxDblLong; i < Long.MAX_VALUE; i++) {
            BigDecimal bd1 = new BigDecimal(i);
            BigDecimal bd2 = new BigDecimal(-i);
            checkDouble(bd1, (double)i);
            checkDouble(bd2, -(double)i);

            checkFloat(bd1, (float)i);
            checkFloat(bd2, -(float)i);
        }

        checkDouble(new BigDecimal(Long.MIN_VALUE), (double)Long.MIN_VALUE);
        checkDouble(new BigDecimal(Long.MAX_VALUE), (double)Long.MAX_VALUE);
    }

    static void testFloatValue() {
        // Now check values that should not convert the same in float
        for(long i = maxFltLong; i <= Integer.MAX_VALUE; i++) {
            BigDecimal bd1 = new BigDecimal(i);
            BigDecimal bd2 = new BigDecimal(-i);
            checkFloat(bd1, (float)i);
            checkFloat(bd2, -(float)i);

            testDoubleValue0( i, bd1);
            testDoubleValue0(-i, bd2);
        }
    }

    static void testFloatValue1() {
        checkFloat(new BigDecimal("85070591730234615847396907784232501249"), 8.507059e+37f);
        checkFloat(new BigDecimal("7784232501249e12"), 7.7842326e24f);
        checkFloat(new BigDecimal("907784232501249e-12"),907.78424f);
        checkFloat(new BigDecimal("7784e8"),7.7839997e11f);
        checkFloat(new BigDecimal("9077e-8"),9.077e-5f);

    }

    static void testDoubleValue1() {
        checkDouble(new BigDecimal("85070591730234615847396907784232501249"), 8.507059173023462e37);
        checkDouble(new BigDecimal("7784232501249e12"), 7.784232501249e24);
        checkDouble(new BigDecimal("907784232501249e-12"), 907.784232501249);
        checkDouble(new BigDecimal("7784e8"), 7.784e11);
        checkDouble(new BigDecimal("9077e-8"), 9.077e-5);

    }

    public static void main(String[] args) throws Exception {
        testFloatDoubleValue();
        testDoubleValue();
        testFloatValue();
        testFloatValue1();
        testDoubleValue1();
    }
}
