1 /* 2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6908131 27 * @summary Check for correct implementation of Math.ceil and Math.floor 28 */ 29 30 import sun.misc.FpUtils; 31 import sun.misc.DoubleConsts; 32 33 public class CeilAndFloorTests { 34 private static int testCeilCase(double input, double expected) { 35 int failures = 0; 36 failures += Tests.test("Math.ceil", input, Math.ceil(input), expected); 37 failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected); 38 return failures; 39 } 40 41 private static int testFloorCase(double input, double expected) { 42 int failures = 0; 43 failures += Tests.test("Math.floor", input, Math.floor(input), expected); 44 failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected); 45 return failures; 46 } 47 48 private static int nearIntegerTests() { 49 int failures = 0; 50 51 double [] fixedPoints = { 52 -0.0, 53 0.0, 54 -1.0, 55 1.0, 56 -0x1.0p52, 57 0x1.0p52, 58 -Double.MAX_VALUE, 59 Double.MAX_VALUE, 60 Double.NEGATIVE_INFINITY, 61 Double.POSITIVE_INFINITY, 62 Double.NaN, 63 }; 64 65 for(double fixedPoint : fixedPoints) { 66 failures += testCeilCase(fixedPoint, fixedPoint); 67 failures += testFloorCase(fixedPoint, fixedPoint); 68 } 69 70 for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) { 71 double powerOfTwo = Math.scalb(1.0, i); 72 double neighborDown = FpUtils.nextDown(powerOfTwo); 73 double neighborUp = Math.nextUp(powerOfTwo); 74 75 if (i < 0) { 76 failures += testCeilCase( powerOfTwo, 1.0); 77 failures += testCeilCase(-powerOfTwo, -0.0); 78 79 failures += testFloorCase( powerOfTwo, 0.0); 80 failures += testFloorCase(-powerOfTwo, -1.0); 81 82 failures += testCeilCase( neighborDown, 1.0); 83 failures += testCeilCase(-neighborDown, -0.0); 84 85 failures += testFloorCase( neighborUp, 0.0); 86 failures += testFloorCase(-neighborUp, -1.0); 87 } else { 88 failures += testCeilCase(powerOfTwo, powerOfTwo); 89 failures += testFloorCase(powerOfTwo, powerOfTwo); 90 91 if (neighborDown==Math.rint(neighborDown)) { 92 failures += testCeilCase( neighborDown, neighborDown); 93 failures += testCeilCase(-neighborDown, -neighborDown); 94 95 failures += testFloorCase( neighborDown, neighborDown); 96 failures += testFloorCase(-neighborDown,-neighborDown); 97 } else { 98 failures += testCeilCase( neighborDown, powerOfTwo); 99 failures += testFloorCase(-neighborDown, -powerOfTwo); 100 } 101 102 if (neighborUp==Math.rint(neighborUp)) { 103 failures += testCeilCase(neighborUp, neighborUp); 104 failures += testCeilCase(-neighborUp, -neighborUp); 105 106 failures += testFloorCase(neighborUp, neighborUp); 107 failures += testFloorCase(-neighborUp, -neighborUp); 108 } else { 109 failures += testFloorCase(neighborUp, powerOfTwo); 110 failures += testCeilCase(-neighborUp, -powerOfTwo); 111 } 112 } 113 } 114 115 for(int i = -(0x10000); i <= 0x10000; i++) { 116 double d = (double) i; 117 double neighborDown = FpUtils.nextDown(d); 118 double neighborUp = Math.nextUp(d); 119 120 failures += testCeilCase( d, d); 121 failures += testCeilCase(-d, -d); 122 123 failures += testFloorCase( d, d); 124 failures += testFloorCase(-d, -d); 125 126 if (Math.abs(d) > 1.0) { 127 failures += testCeilCase( neighborDown, d); 128 failures += testCeilCase(-neighborDown, -d+1); 129 130 failures += testFloorCase( neighborUp, d); 131 failures += testFloorCase(-neighborUp, -d-1); 132 } 133 } 134 135 return failures; 136 } 137 138 public static int roundingTests() { 139 int failures = 0; 140 double [][] testCases = { 141 { Double.MIN_VALUE, 1.0}, 142 {-Double.MIN_VALUE, -0.0}, 143 { FpUtils.nextDown(DoubleConsts.MIN_NORMAL), 1.0}, 144 {-FpUtils.nextDown(DoubleConsts.MIN_NORMAL), -0.0}, 145 { DoubleConsts.MIN_NORMAL, 1.0}, 146 {-DoubleConsts.MIN_NORMAL, -0.0}, 147 148 { 0.1, 1.0}, 149 {-0.1, -0.0}, 150 151 { 0.5, 1.0}, 152 {-0.5, -0.0}, 153 154 { 1.5, 2.0}, 155 {-1.5, -1.0}, 156 157 { 2.5, 3.0}, 158 {-2.5, -2.0}, 159 160 { FpUtils.nextDown(1.0), 1.0}, 161 { FpUtils.nextDown(-1.0), -1.0}, 162 163 { Math.nextUp(1.0), 2.0}, 164 { Math.nextUp(-1.0), -0.0}, 165 166 { 0x1.0p51, 0x1.0p51}, 167 {-0x1.0p51, -0x1.0p51}, 168 169 { FpUtils.nextDown(0x1.0p51), 0x1.0p51}, 170 {-Math.nextUp(0x1.0p51), -0x1.0p51}, 171 172 { Math.nextUp(0x1.0p51), 0x1.0p51+1}, 173 {-FpUtils.nextDown(0x1.0p51), -0x1.0p51+1}, 174 175 { FpUtils.nextDown(0x1.0p52), 0x1.0p52}, 176 {-Math.nextUp(0x1.0p52), -0x1.0p52-1.0}, 177 178 { Math.nextUp(0x1.0p52), 0x1.0p52+1.0}, 179 {-FpUtils.nextDown(0x1.0p52), -0x1.0p52+1.0}, 180 }; 181 182 for(double[] testCase : testCases) { 183 failures += testCeilCase(testCase[0], testCase[1]); 184 failures += testFloorCase(-testCase[0], -testCase[1]); 185 } 186 return failures; 187 } 188 189 public static void main(String... args) { 190 int failures = 0; 191 192 failures += nearIntegerTests(); 193 failures += roundingTests(); 194 195 if (failures > 0) { 196 System.err.println("Testing {Math, StrictMath}.ceil incurred " 197 + failures + " failures."); 198 throw new RuntimeException(); 199 } 200 } 201 }