1 /* 2 * Copyright (c) 2016, 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 4851642 27 * @summary Tests for Math.fusedMac and StrictMath.fusedMac. 28 * @build Tests 29 * @build FusedMultiplyAddTests 30 * @run main FusedMultiplyAddTests 31 */ 32 33 /** 34 * The specifications for both Math.fusedMac and StrictMath.fusedMac 35 * are the same and both are exactly specified. Therefore, both 36 * methods are tested in this file. 37 */ 38 39 public class FusedMultiplyAddTests { 40 private FusedMultiplyAddTests(){} 41 42 private static final double Infinity = Double.POSITIVE_INFINITY; 43 private static final float InfinityF = Float.POSITIVE_INFINITY; 44 private static final double NaN = Double.NaN; 45 private static final float NaNf = Float.NaN; 46 47 public static void main(String... args) { 48 int failures = 0; 49 50 failures += testNonFiniteD(); 51 failures += testZeroesD(); 52 failures += testSimpleD(); 53 54 failures += testNonFiniteF(); 55 failures += testZeroesF(); 56 failures += testSimpleF(); 57 58 if (failures > 0) { 59 System.err.println("Testing fma incurred " 60 + failures + " failures."); 61 throw new RuntimeException(); 62 } 63 } 64 65 private static int testNonFiniteD() { 66 int failures = 0; 67 68 double [][] testCases = { 69 {Infinity, Infinity, Infinity, 70 Infinity, 71 }, 72 73 {-Infinity, Infinity, -Infinity, 74 -Infinity, 75 }, 76 77 {-Infinity, Infinity, Infinity, 78 NaN, 79 }, 80 81 {Infinity, Infinity, -Infinity, 82 NaN, 83 }, 84 85 {1.0, Infinity, 2.0, 86 Infinity, 87 }, 88 89 {1.0, 2.0, Infinity, 90 Infinity, 91 }, 92 93 {Infinity, 1.0, Infinity, 94 Infinity, 95 }, 96 97 {Double.MAX_VALUE, 2.0, -Infinity, 98 -Infinity}, 99 100 {Infinity, 1.0, -Infinity, 101 NaN, 102 }, 103 104 {-Infinity, 1.0, Infinity, 105 NaN, 106 }, 107 108 {1.0, NaN, 2.0, 109 NaN, 110 }, 111 112 {1.0, 2.0, NaN, 113 NaN, 114 }, 115 116 {Infinity, 2.0, NaN, 117 NaN, 118 }, 119 120 {NaN, 2.0, Infinity, 121 NaN, 122 }, 123 }; 124 125 for (double[] testCase: testCases) 126 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 127 128 return failures; 129 } 130 131 private static int testZeroesD() { 132 int failures = 0; 133 134 double [][] testCases = { 135 {+0.0, +0.0, +0.0, 136 +0.0, 137 }, 138 139 {-0.0, +0.0, +0.0, 140 +0.0, 141 }, 142 143 {+0.0, +0.0, -0.0, 144 +0.0, 145 }, 146 147 {+0.0, +0.0, -0.0, 148 +0.0, 149 }, 150 151 {-0.0, +0.0, -0.0, 152 -0.0, 153 }, 154 155 {-0.0, -0.0, -0.0, 156 +0.0, 157 }, 158 159 {-1.0, +0.0, -0.0, 160 -0.0, 161 }, 162 163 {-1.0, +0.0, +0.0, 164 +0.0, 165 }, 166 167 {-2.0, +0.0, -0.0, 168 -0.0, 169 }, 170 }; 171 172 for (double[] testCase: testCases) 173 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 174 175 return failures; 176 } 177 178 private static int testSimpleD() { 179 int failures = 0; 180 181 double [][] testCases = { 182 {1.0, 2.0, 3.0, 183 5.0,}, 184 185 {1.0, 2.0, -2.0, 186 0.0,}, 187 188 {5.0, 5.0, -25.0, 189 0.0,}, 190 191 {Double.MAX_VALUE, 2.0, -Double.MAX_VALUE, 192 Double.MAX_VALUE}, 193 194 {Double.MAX_VALUE, 2.0, 1.0, 195 Infinity}, 196 197 {Double.MIN_VALUE, -Double.MIN_VALUE, +0.0, 198 -0.0}, 199 200 {Double.MIN_VALUE, -Double.MIN_VALUE, -0.0, 201 -0.0}, 202 203 {Double.MIN_VALUE, Double.MIN_VALUE, +0.0, 204 +0.0}, 205 206 {Double.MIN_VALUE, Double.MIN_VALUE, -0.0, 207 +0.0}, 208 }; 209 210 for (double[] testCase: testCases) 211 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 212 213 return failures; 214 } 215 216 private static int testNonFiniteF() { 217 int failures = 0; 218 219 float [][] testCases = { 220 {1.0f, InfinityF, 2.0f, 221 InfinityF, 222 }, 223 224 {1.0f, 2.0f, InfinityF, 225 InfinityF, 226 }, 227 228 {InfinityF, 1.0f, InfinityF, 229 InfinityF, 230 }, 231 232 {Float.MAX_VALUE, 2.0f, -InfinityF, 233 -InfinityF}, 234 235 {InfinityF, 1.0f, -InfinityF, 236 NaNf, 237 }, 238 239 {-InfinityF, 1.0f, InfinityF, 240 NaNf, 241 }, 242 243 {1.0f, NaNf, 2.0f, 244 NaNf, 245 }, 246 247 {1.0f, 2.0f, NaNf, 248 NaNf, 249 }, 250 251 {InfinityF, 2.0f, NaNf, 252 NaNf, 253 }, 254 255 {NaNf, 2.0f, InfinityF, 256 NaNf, 257 }, 258 }; 259 260 for (float[] testCase: testCases) 261 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 262 263 return failures; 264 } 265 266 private static int testZeroesF() { 267 int failures = 0; 268 269 float [][] testCases = { 270 {+0.0f, +0.0f, +0.0f, 271 +0.0f, 272 }, 273 274 {-0.0f, +0.0f, +0.0f, 275 +0.0f, 276 }, 277 278 {+0.0f, +0.0f, -0.0f, 279 +0.0f, 280 }, 281 282 {+0.0f, +0.0f, -0.0f, 283 +0.0f, 284 }, 285 286 {-0.0f, +0.0f, -0.0f, 287 -0.0f, 288 }, 289 290 {-0.0f, -0.0f, -0.0f, 291 +0.0f, 292 }, 293 294 {-1.0f, +0.0f, -0.0f, 295 -0.0f, 296 }, 297 298 {-1.0f, +0.0f, +0.0f, 299 +0.0f, 300 }, 301 302 {-2.0f, +0.0f, -0.0f, 303 -0.0f, 304 }, 305 }; 306 307 for (float[] testCase: testCases) 308 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 309 310 return failures; 311 } 312 313 private static int testSimpleF() { 314 int failures = 0; 315 316 float [][] testCases = { 317 {1.0f, 2.0f, 3.0f, 318 5.0f,}, 319 320 {1.0f, 2.0f, -2.0f, 321 0.0f,}, 322 323 {5.0f, 5.0f, -25.0f, 324 0.0f,}, 325 326 {Float.MAX_VALUE, 2.0f, -Float.MAX_VALUE, 327 Float.MAX_VALUE}, 328 329 {Float.MAX_VALUE, 2.0f, 1.0f, 330 InfinityF}, 331 }; 332 333 for (float[] testCase: testCases) 334 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 335 336 return failures; 337 } 338 339 340 private static int testFusedMacCase(double input1, double input2, double input3, double expected) { 341 int failures = 0; 342 failures += Tests.test("Math.fma(double)", input1, input2, input3, 343 Math.fma(input1, input2, input3), expected); 344 failures += Tests.test("StrictMath.fma(double)", input1, input2, input3, 345 StrictMath.fma(input1, input2, input3), expected); 346 347 // Permute first two inputs 348 failures += Tests.test("Math.fma(double)", input2, input1, input3, 349 Math.fma(input2, input1, input3), expected); 350 failures += Tests.test("StrictMath.fma(double)", input2, input1, input3, 351 StrictMath.fma(input2, input1, input3), expected); 352 return failures; 353 } 354 355 private static int testFusedMacCase(float input1, float input2, float input3, float expected) { 356 int failures = 0; 357 failures += Tests.test("Math.fma(float)", input1, input2, input3, 358 Math.fma(input1, input2, input3), expected); 359 failures += Tests.test("StrictMath.fma(float)", input1, input2, input3, 360 StrictMath.fma(input1, input2, input3), expected); 361 362 // Permute first two inputs 363 failures += Tests.test("Math.fma(float)", input2, input1, input3, 364 Math.fma(input2, input1, input3), expected); 365 failures += Tests.test("StrictMath.fma(float)", input2, input1, input3, 366 StrictMath.fma(input2, input1, input3), expected); 367 return failures; 368 } 369 }