2023N/A/*
2362N/A * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
2023N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2023N/A *
2023N/A * This code is free software; you can redistribute it and/or modify it
2023N/A * under the terms of the GNU General Public License version 2 only, as
2023N/A * published by the Free Software Foundation.
2023N/A *
2023N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2023N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2023N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2023N/A * version 2 for more details (a copy is included in the LICENSE file that
2023N/A * accompanied this code).
2023N/A *
2023N/A * You should have received a copy of the GNU General Public License version
2023N/A * 2 along with this work; if not, write to the Free Software Foundation,
2023N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2023N/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.
2023N/A */
2023N/A
2023N/A/*
2023N/A * @test
2023N/A * @bug 6908131
2023N/A * @summary Check for correct implementation of Math.ceil and Math.floor
2023N/A */
2023N/A
2023N/Aimport sun.misc.FpUtils;
2023N/Aimport sun.misc.DoubleConsts;
2023N/A
2023N/Apublic class CeilAndFloorTests {
2023N/A private static int testCeilCase(double input, double expected) {
2023N/A int failures = 0;
2023N/A failures += Tests.test("Math.ceil", input, Math.ceil(input), expected);
2023N/A failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected);
2023N/A return failures;
2023N/A }
2023N/A
2023N/A private static int testFloorCase(double input, double expected) {
2023N/A int failures = 0;
2023N/A failures += Tests.test("Math.floor", input, Math.floor(input), expected);
2023N/A failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected);
2023N/A return failures;
2023N/A }
2023N/A
2023N/A private static int nearIntegerTests() {
2023N/A int failures = 0;
2023N/A
2023N/A double [] fixedPoints = {
2023N/A -0.0,
2023N/A 0.0,
2023N/A -1.0,
2023N/A 1.0,
2023N/A -0x1.0p52,
2023N/A 0x1.0p52,
2023N/A -Double.MAX_VALUE,
2023N/A Double.MAX_VALUE,
2023N/A Double.NEGATIVE_INFINITY,
2023N/A Double.POSITIVE_INFINITY,
2023N/A Double.NaN,
2023N/A };
2023N/A
2023N/A for(double fixedPoint : fixedPoints) {
2023N/A failures += testCeilCase(fixedPoint, fixedPoint);
2023N/A failures += testFloorCase(fixedPoint, fixedPoint);
2023N/A }
2023N/A
2023N/A for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) {
2023N/A double powerOfTwo = Math.scalb(1.0, i);
2023N/A double neighborDown = FpUtils.nextDown(powerOfTwo);
2023N/A double neighborUp = Math.nextUp(powerOfTwo);
2023N/A
2023N/A if (i < 0) {
2023N/A failures += testCeilCase( powerOfTwo, 1.0);
2023N/A failures += testCeilCase(-powerOfTwo, -0.0);
2023N/A
2023N/A failures += testFloorCase( powerOfTwo, 0.0);
2023N/A failures += testFloorCase(-powerOfTwo, -1.0);
2023N/A
2023N/A failures += testCeilCase( neighborDown, 1.0);
2023N/A failures += testCeilCase(-neighborDown, -0.0);
2023N/A
2023N/A failures += testFloorCase( neighborUp, 0.0);
2023N/A failures += testFloorCase(-neighborUp, -1.0);
2023N/A } else {
2023N/A failures += testCeilCase(powerOfTwo, powerOfTwo);
2023N/A failures += testFloorCase(powerOfTwo, powerOfTwo);
2023N/A
2023N/A if (neighborDown==Math.rint(neighborDown)) {
2023N/A failures += testCeilCase( neighborDown, neighborDown);
2023N/A failures += testCeilCase(-neighborDown, -neighborDown);
2023N/A
2023N/A failures += testFloorCase( neighborDown, neighborDown);
2023N/A failures += testFloorCase(-neighborDown,-neighborDown);
2023N/A } else {
2023N/A failures += testCeilCase( neighborDown, powerOfTwo);
2023N/A failures += testFloorCase(-neighborDown, -powerOfTwo);
2023N/A }
2023N/A
2023N/A if (neighborUp==Math.rint(neighborUp)) {
2023N/A failures += testCeilCase(neighborUp, neighborUp);
2023N/A failures += testCeilCase(-neighborUp, -neighborUp);
2023N/A
2023N/A failures += testFloorCase(neighborUp, neighborUp);
2023N/A failures += testFloorCase(-neighborUp, -neighborUp);
2023N/A } else {
2023N/A failures += testFloorCase(neighborUp, powerOfTwo);
2023N/A failures += testCeilCase(-neighborUp, -powerOfTwo);
2023N/A }
2023N/A }
2023N/A }
2023N/A
2023N/A for(int i = -(0x10000); i <= 0x10000; i++) {
2023N/A double d = (double) i;
2023N/A double neighborDown = FpUtils.nextDown(d);
2023N/A double neighborUp = Math.nextUp(d);
2023N/A
2023N/A failures += testCeilCase( d, d);
2023N/A failures += testCeilCase(-d, -d);
2023N/A
2023N/A failures += testFloorCase( d, d);
2023N/A failures += testFloorCase(-d, -d);
2023N/A
2023N/A if (Math.abs(d) > 1.0) {
2023N/A failures += testCeilCase( neighborDown, d);
2023N/A failures += testCeilCase(-neighborDown, -d+1);
2023N/A
2023N/A failures += testFloorCase( neighborUp, d);
2023N/A failures += testFloorCase(-neighborUp, -d-1);
2023N/A }
2023N/A }
2023N/A
2023N/A return failures;
2023N/A }
2023N/A
2023N/A public static int roundingTests() {
2023N/A int failures = 0;
2023N/A double [][] testCases = {
2023N/A { Double.MIN_VALUE, 1.0},
2023N/A {-Double.MIN_VALUE, -0.0},
2023N/A { FpUtils.nextDown(DoubleConsts.MIN_NORMAL), 1.0},
2023N/A {-FpUtils.nextDown(DoubleConsts.MIN_NORMAL), -0.0},
2023N/A { DoubleConsts.MIN_NORMAL, 1.0},
2023N/A {-DoubleConsts.MIN_NORMAL, -0.0},
2023N/A
2023N/A { 0.1, 1.0},
2023N/A {-0.1, -0.0},
2023N/A
2023N/A { 0.5, 1.0},
2023N/A {-0.5, -0.0},
2023N/A
2023N/A { 1.5, 2.0},
2023N/A {-1.5, -1.0},
2023N/A
2023N/A { 2.5, 3.0},
2023N/A {-2.5, -2.0},
2023N/A
2023N/A { FpUtils.nextDown(1.0), 1.0},
2023N/A { FpUtils.nextDown(-1.0), -1.0},
2023N/A
2023N/A { Math.nextUp(1.0), 2.0},
2023N/A { Math.nextUp(-1.0), -0.0},
2023N/A
2023N/A { 0x1.0p51, 0x1.0p51},
2023N/A {-0x1.0p51, -0x1.0p51},
2023N/A
2023N/A { FpUtils.nextDown(0x1.0p51), 0x1.0p51},
2023N/A {-Math.nextUp(0x1.0p51), -0x1.0p51},
2023N/A
2023N/A { Math.nextUp(0x1.0p51), 0x1.0p51+1},
2023N/A {-FpUtils.nextDown(0x1.0p51), -0x1.0p51+1},
2023N/A
2023N/A { FpUtils.nextDown(0x1.0p52), 0x1.0p52},
2023N/A {-Math.nextUp(0x1.0p52), -0x1.0p52-1.0},
2023N/A
2023N/A { Math.nextUp(0x1.0p52), 0x1.0p52+1.0},
2023N/A {-FpUtils.nextDown(0x1.0p52), -0x1.0p52+1.0},
2023N/A };
2023N/A
2023N/A for(double[] testCase : testCases) {
2023N/A failures += testCeilCase(testCase[0], testCase[1]);
2023N/A failures += testFloorCase(-testCase[0], -testCase[1]);
2023N/A }
2023N/A return failures;
2023N/A }
2023N/A
2023N/A public static void main(String... args) {
2023N/A int failures = 0;
2023N/A
2023N/A failures += nearIntegerTests();
2023N/A failures += roundingTests();
2023N/A
2023N/A if (failures > 0) {
2023N/A System.err.println("Testing {Math, StrictMath}.ceil incurred "
2023N/A + failures + " failures.");
2023N/A throw new RuntimeException();
2023N/A }
2023N/A }
2023N/A}