1 /* 2 * Copyright 2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4984407 5033578 27 * @summary Tests for {Math, StrictMath}.pow 28 * @compile -source 1.5 PowTests.java 29 * @run main PowTests 30 * @author Joseph D. Darcy 31 */ 32 33 public class PowTests { 34 private PowTests(){} 35 36 static final double infinityD = Double.POSITIVE_INFINITY; 37 38 static int testPowCase(double input1, double input2, double expected) { 39 int failures = 0; 40 failures += Tests.test("StrictMath.pow(double, double)", input1, input2, 41 StrictMath.pow(input1, input2), expected); 42 failures += Tests.test("Math.pow(double, double)", input1, input2, 43 Math.pow(input1, input2), expected); 44 return failures; 45 } 46 47 48 static int testStrictPowCase(double input1, double input2, double expected) { 49 int failures = 0; 50 failures += Tests.test("StrictMath.pow(double, double)", input1, input2, 51 StrictMath.pow(input1, input2), expected); 52 return failures; 53 } 54 55 static int testNonstrictPowCase(double input1, double input2, double expected) { 56 int failures = 0; 57 failures += Tests.test("Math.pow(double, double)", input1, input2, 58 Math.pow(input1, input2), expected); 59 return failures; 60 } 61 62 /* 63 * Test for bad negation implementation. 64 */ 65 static int testPow() { 66 int failures = 0; 67 68 double [][] testCases = { 69 {-0.0, 3.0, -0.0}, 70 {-0.0, 4.0, 0.0}, 71 {-infinityD, -3.0, -0.0}, 72 {-infinityD, -4.0, 0.0}, 73 }; 74 75 for (double[] testCase : testCases) { 76 failures+=testPowCase(testCase[0], testCase[1], testCase[2]); 77 } 78 79 return failures; 80 } 81 82 /* 83 * Test cross-product of different kinds of arguments. 84 */ 85 static int testCrossProduct() { 86 int failures = 0; 87 88 double testData[] = { 89 Double.NEGATIVE_INFINITY, 90 /* > -oo */ -Double.MAX_VALUE, 91 /**/ (double)Long.MIN_VALUE, 92 /**/ (double) -((1L<<53)+2L), 93 /**/ (double) -((1L<<53)), 94 /**/ (double) -((1L<<53)-1L), 95 /**/ -((double)Integer.MAX_VALUE + 4.0), 96 /**/ (double)Integer.MIN_VALUE - 1.0, 97 /**/ (double)Integer.MIN_VALUE, 98 /**/ (double)Integer.MIN_VALUE + 1.0, 99 /**/ -Math.PI, 100 /**/ -3.0, 101 /**/ -Math.E, 102 /**/ -2.0, 103 /**/ -1.0000000000000004, 104 /* < -1.0 */ -1.0000000000000002, // nextAfter(-1.0, -oo) 105 -1.0, 106 /* > -1.0 */ -0.9999999999999999, // nextAfter(-1.0, +oo) 107 /* > -1.0 */ -0.9999999999999998, 108 /**/ -0.5, 109 /**/ -1.0/3.0, 110 /* < 0.0 */ -Double.MIN_VALUE, 111 -0.0, 112 +0.0, 113 /* > 0.0 */ +Double.MIN_VALUE, 114 /**/ +1.0/3.0, 115 /**/ +0.5, 116 /**/ +0.9999999999999998, 117 /* < +1.0 */ +0.9999999999999999, // nextAfter(-1.0, +oo) 118 +1.0, 119 /* > 1.0 */ +1.0000000000000002, // nextAfter(+1.0, +oo) 120 /**/ +1.0000000000000004, 121 /**/ +2.0, 122 /**/ +Math.E, 123 /**/ +3.0, 124 /**/ +Math.PI, 125 /**/ -(double)Integer.MIN_VALUE - 1.0, 126 /**/ -(double)Integer.MIN_VALUE, 127 /**/ -(double)Integer.MIN_VALUE + 1.0, 128 /**/ (double)Integer.MAX_VALUE + 4.0, 129 /**/ (double) ((1L<<53)-1L), 130 /**/ (double) ((1L<<53)), 131 /**/ (double) ((1L<<53)+2L), 132 /**/ -(double)Long.MIN_VALUE, 133 /* < oo */ Double.MAX_VALUE, 134 Double.POSITIVE_INFINITY, 135 Double.NaN 136 }; 137 138 double NaN = Double.NaN; 139 for(double x: testData) { 140 for(double y: testData) { 141 boolean testPass = false; 142 double expected=NaN; 143 double actual; 144 145 // First, switch on y 146 if( Double.isNaN(y)) { 147 expected = NaN; 148 } else if (y == 0.0) { 149 expected = 1.0; 150 } else if (Double.isInfinite(y) ) { 151 if(y > 0) { // x ^ (+oo) 152 if (Math.abs(x) > 1.0) { 153 expected = Double.POSITIVE_INFINITY; 154 } else if (Math.abs(x) == 1.0) { 155 expected = NaN; 156 } else if (Math.abs(x) < 1.0) { 157 expected = +0.0; 158 } else { // x is NaN 159 assert Double.isNaN(x); 160 expected = NaN; 161 } 162 } else { // x ^ (-oo) 163 if (Math.abs(x) > 1.0) { 164 expected = +0.0; 165 } else if (Math.abs(x) == 1.0) { 166 expected = NaN; 167 } else if (Math.abs(x) < 1.0) { 168 expected = Double.POSITIVE_INFINITY; 169 } else { // x is NaN 170 assert Double.isNaN(x); 171 expected = NaN; 172 } 173 } /* end Double.isInfinite(y) */ 174 } else if (y == 1.0) { 175 expected = x; 176 } else if (Double.isNaN(x)) { // Now start switching on x 177 assert y != 0.0; 178 expected = NaN; 179 } else if (x == Double.NEGATIVE_INFINITY) { 180 expected = (y < 0.0) ? f2(y) :f1(y); 181 } else if (x == Double.POSITIVE_INFINITY) { 182 expected = (y < 0.0) ? +0.0 : Double.POSITIVE_INFINITY; 183 } else if (equivalent(x, +0.0)) { 184 assert y != 0.0; 185 expected = (y < 0.0) ? Double.POSITIVE_INFINITY: +0.0; 186 } else if (equivalent(x, -0.0)) { 187 assert y != 0.0; 188 expected = (y < 0.0) ? f1(y): f2(y); 189 } else if( x < 0.0) { 190 assert y != 0.0; 191 failures += testStrictPowCase(x, y, f3(x, y)); 192 failures += testNonstrictPowCase(x, y, f3ns(x, y)); 193 continue; 194 } else { 195 // go to next iteration 196 expected = NaN; 197 continue; 198 } 199 200 failures += testPowCase(x, y, expected); 201 } // y 202 } // x 203 return failures; 204 } 205 206 static boolean equivalent(double a, double b) { 207 return Double.compare(a, b) == 0; 208 } 209 210 static double f1(double y) { 211 return (intClassify(y) == 1)? 212 Double.NEGATIVE_INFINITY: 213 Double.POSITIVE_INFINITY; 214 } 215 216 217 static double f2(double y) { 218 return (intClassify(y) == 1)?-0.0:0.0; 219 } 220 221 static double f3(double x, double y) { 222 switch( intClassify(y) ) { 223 case 0: 224 return StrictMath.pow(Math.abs(x), y); 225 // break; 226 227 case 1: 228 return -StrictMath.pow(Math.abs(x), y); 229 // break; 230 231 case -1: 232 return Double.NaN; 233 // break; 234 235 default: 236 throw new AssertionError("Bad classification."); 237 // break; 238 } 239 } 240 241 static double f3ns(double x, double y) { 242 switch( intClassify(y) ) { 243 case 0: 244 return Math.pow(Math.abs(x), y); 245 // break; 246 247 case 1: 248 return -Math.pow(Math.abs(x), y); 249 // break; 250 251 case -1: 252 return Double.NaN; 253 // break; 254 255 default: 256 throw new AssertionError("Bad classification."); 257 // break; 258 } 259 } 260 261 static boolean isFinite(double a) { 262 return (0.0*a == 0); 263 } 264 265 /** 266 * Return classification of argument: -1 for non-integers, 0 for 267 * even integers, 1 for odd integers. 268 */ 269 static int intClassify(double a) { 270 if(!isFinite(a) || // NaNs and infinities 271 (a != Math.floor(a) )) { // only integers are fixed-points of floor 272 return -1; 273 } 274 else { 275 // Determine if argument is an odd or even integer. 276 277 a = StrictMath.abs(a); // absolute value doesn't affect odd/even 278 279 if(a+1.0 == a) { // a > maximum odd floating-point integer 280 return 0; // Large integers are all even 281 } 282 else { // Convert double -> long and look at low-order bit 283 long ell = (long) a; 284 return ((ell & 0x1L) == (long)1)?1:0; 285 } 286 } 287 } 288 289 public static void main(String [] argv) { 290 int failures = 0; 291 292 failures += testPow(); 293 failures += testCrossProduct(); 294 295 if (failures > 0) { 296 System.err.println("Testing pow incurred " 297 + failures + " failures."); 298 throw new RuntimeException(); 299 } 300 } 301 }