1/* 2 * Copyright (c) 2009, 2011, 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 30public class CeilAndFloorTests { 31 private static int testCeilCase(double input, double expected) { 32 int failures = 0; 33 failures += Tests.test("Math.ceil", input, Math.ceil(input), expected); 34 failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected); 35 return failures; 36 } 37 38 private static int testFloorCase(double input, double expected) { 39 int failures = 0; 40 failures += Tests.test("Math.floor", input, Math.floor(input), expected); 41 failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected); 42 return failures; 43 } 44 45 private static int nearIntegerTests() { 46 int failures = 0; 47 48 double [] fixedPoints = { 49 -0.0, 50 0.0, 51 -1.0, 52 1.0, 53 -0x1.0p52, 54 0x1.0p52, 55 -Double.MAX_VALUE, 56 Double.MAX_VALUE, 57 Double.NEGATIVE_INFINITY, 58 Double.POSITIVE_INFINITY, 59 Double.NaN, 60 }; 61 62 for(double fixedPoint : fixedPoints) { 63 failures += testCeilCase(fixedPoint, fixedPoint); 64 failures += testFloorCase(fixedPoint, fixedPoint); 65 } 66 67 for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) { 68 double powerOfTwo = Math.scalb(1.0, i); 69 double neighborDown = Math.nextDown(powerOfTwo); 70 double neighborUp = Math.nextUp(powerOfTwo); 71 72 if (i < 0) { 73 failures += testCeilCase( powerOfTwo, 1.0); 74 failures += testCeilCase(-powerOfTwo, -0.0); 75 76 failures += testFloorCase( powerOfTwo, 0.0); 77 failures += testFloorCase(-powerOfTwo, -1.0); 78 79 failures += testCeilCase( neighborDown, 1.0); 80 failures += testCeilCase(-neighborDown, -0.0); 81 82 failures += testFloorCase( neighborUp, 0.0); 83 failures += testFloorCase(-neighborUp, -1.0); 84 } else { 85 failures += testCeilCase(powerOfTwo, powerOfTwo); 86 failures += testFloorCase(powerOfTwo, powerOfTwo); 87 88 if (neighborDown==Math.rint(neighborDown)) { 89 failures += testCeilCase( neighborDown, neighborDown); 90 failures += testCeilCase(-neighborDown, -neighborDown); 91 92 failures += testFloorCase( neighborDown, neighborDown); 93 failures += testFloorCase(-neighborDown,-neighborDown); 94 } else { 95 failures += testCeilCase( neighborDown, powerOfTwo); 96 failures += testFloorCase(-neighborDown, -powerOfTwo); 97 } 98 99 if (neighborUp==Math.rint(neighborUp)) { 100 failures += testCeilCase(neighborUp, neighborUp); 101 failures += testCeilCase(-neighborUp, -neighborUp); 102 103 failures += testFloorCase(neighborUp, neighborUp); 104 failures += testFloorCase(-neighborUp, -neighborUp); 105 } else { 106 failures += testFloorCase(neighborUp, powerOfTwo); 107 failures += testCeilCase(-neighborUp, -powerOfTwo); 108 } 109 } 110 } 111 112 for(int i = -(0x10000); i <= 0x10000; i++) { 113 double d = (double) i; 114 double neighborDown = Math.nextDown(d); 115 double neighborUp = Math.nextUp(d); 116 117 failures += testCeilCase( d, d); 118 failures += testCeilCase(-d, -d); 119 120 failures += testFloorCase( d, d); 121 failures += testFloorCase(-d, -d); 122 123 if (Math.abs(d) > 1.0) { 124 failures += testCeilCase( neighborDown, d); 125 failures += testCeilCase(-neighborDown, -d+1); 126 127 failures += testFloorCase( neighborUp, d); 128 failures += testFloorCase(-neighborUp, -d-1); 129 } 130 } 131 132 return failures; 133 } 134 135 public static int roundingTests() { 136 int failures = 0; 137 double [][] testCases = { 138 { Double.MIN_VALUE, 1.0}, 139 {-Double.MIN_VALUE, -0.0}, 140 { Math.nextDown(Double.MIN_NORMAL), 1.0}, 141 {-Math.nextDown(Double.MIN_NORMAL), -0.0}, 142 { Double.MIN_NORMAL, 1.0}, 143 {-Double.MIN_NORMAL, -0.0}, 144 145 { 0.1, 1.0}, 146 {-0.1, -0.0}, 147 148 { 0.5, 1.0}, 149 {-0.5, -0.0}, 150 151 { 1.5, 2.0}, 152 {-1.5, -1.0}, 153 154 { 2.5, 3.0}, 155 {-2.5, -2.0}, 156 157 { Math.nextDown(1.0), 1.0}, 158 { Math.nextDown(-1.0), -1.0}, 159 160 { Math.nextUp(1.0), 2.0}, 161 { Math.nextUp(-1.0), -0.0}, 162 163 { 0x1.0p51, 0x1.0p51}, 164 {-0x1.0p51, -0x1.0p51}, 165 166 { Math.nextDown(0x1.0p51), 0x1.0p51}, 167 {-Math.nextUp(0x1.0p51), -0x1.0p51}, 168 169 { Math.nextUp(0x1.0p51), 0x1.0p51+1}, 170 {-Math.nextDown(0x1.0p51), -0x1.0p51+1}, 171 172 { Math.nextDown(0x1.0p52), 0x1.0p52}, 173 {-Math.nextUp(0x1.0p52), -0x1.0p52-1.0}, 174 175 { Math.nextUp(0x1.0p52), 0x1.0p52+1.0}, 176 {-Math.nextDown(0x1.0p52), -0x1.0p52+1.0}, 177 }; 178 179 for(double[] testCase : testCases) { 180 failures += testCeilCase(testCase[0], testCase[1]); 181 failures += testFloorCase(-testCase[0], -testCase[1]); 182 } 183 return failures; 184 } 185 186 public static void main(String... args) { 187 int failures = 0; 188 189 failures += nearIntegerTests(); 190 failures += roundingTests(); 191 192 if (failures > 0) { 193 System.err.println("Testing {Math, StrictMath}.ceil incurred " 194 + failures + " failures."); 195 throw new RuntimeException(); 196 } 197 } 198} 199