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 39public 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 {-2.0, +0.0, +0.0, 172 +0.0, 173 }, 174 }; 175 176 for (double[] testCase: testCases) 177 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 178 179 return failures; 180 } 181 182 private static int testSimpleD() { 183 int failures = 0; 184 185 double [][] testCases = { 186 {1.0, 2.0, 3.0, 187 5.0,}, 188 189 {1.0, 2.0, -2.0, 190 0.0,}, 191 192 {5.0, 5.0, -25.0, 193 0.0,}, 194 195 {Double.MAX_VALUE, 2.0, -Double.MAX_VALUE, 196 Double.MAX_VALUE}, 197 198 {Double.MAX_VALUE, 2.0, 1.0, 199 Infinity}, 200 201 {Double.MIN_VALUE, -Double.MIN_VALUE, +0.0, 202 -0.0}, 203 204 {Double.MIN_VALUE, -Double.MIN_VALUE, -0.0, 205 -0.0}, 206 207 {Double.MIN_VALUE, Double.MIN_VALUE, +0.0, 208 +0.0}, 209 210 {Double.MIN_VALUE, Double.MIN_VALUE, -0.0, 211 +0.0}, 212 213 {Double.MIN_VALUE, +0.0, -0.0, 214 +0.0}, 215 216 {Double.MIN_VALUE, -0.0, -0.0, 217 -0.0}, 218 219 {Double.MIN_VALUE, +0.0, +0.0, 220 +0.0}, 221 222 {Double.MIN_VALUE, -0.0, +0.0, 223 +0.0}, 224 225 {1.0+Math.ulp(1.0), 1.0+Math.ulp(1.0), -1.0-2.0*Math.ulp(1.0), 226 Math.ulp(1.0)*Math.ulp(1.0)}, 227 }; 228 229 for (double[] testCase: testCases) 230 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 231 232 return failures; 233 } 234 235 private static int testNonFiniteF() { 236 int failures = 0; 237 238 float [][] testCases = { 239 {1.0f, InfinityF, 2.0f, 240 InfinityF, 241 }, 242 243 {1.0f, 2.0f, InfinityF, 244 InfinityF, 245 }, 246 247 {InfinityF, 1.0f, InfinityF, 248 InfinityF, 249 }, 250 251 {Float.MAX_VALUE, 2.0f, -InfinityF, 252 -InfinityF}, 253 254 {InfinityF, 1.0f, -InfinityF, 255 NaNf, 256 }, 257 258 {-InfinityF, 1.0f, InfinityF, 259 NaNf, 260 }, 261 262 {1.0f, NaNf, 2.0f, 263 NaNf, 264 }, 265 266 {1.0f, 2.0f, NaNf, 267 NaNf, 268 }, 269 270 {InfinityF, 2.0f, NaNf, 271 NaNf, 272 }, 273 274 {NaNf, 2.0f, InfinityF, 275 NaNf, 276 }, 277 }; 278 279 for (float[] testCase: testCases) 280 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 281 282 return failures; 283 } 284 285 private static int testZeroesF() { 286 int failures = 0; 287 288 float [][] testCases = { 289 {+0.0f, +0.0f, +0.0f, 290 +0.0f, 291 }, 292 293 {-0.0f, +0.0f, +0.0f, 294 +0.0f, 295 }, 296 297 {+0.0f, +0.0f, -0.0f, 298 +0.0f, 299 }, 300 301 {+0.0f, +0.0f, -0.0f, 302 +0.0f, 303 }, 304 305 {-0.0f, +0.0f, -0.0f, 306 -0.0f, 307 }, 308 309 {-0.0f, -0.0f, -0.0f, 310 +0.0f, 311 }, 312 313 {-1.0f, +0.0f, -0.0f, 314 -0.0f, 315 }, 316 317 {-1.0f, +0.0f, +0.0f, 318 +0.0f, 319 }, 320 321 {-2.0f, +0.0f, -0.0f, 322 -0.0f, 323 }, 324 }; 325 326 for (float[] testCase: testCases) 327 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 328 329 return failures; 330 } 331 332 private static int testSimpleF() { 333 int failures = 0; 334 335 float [][] testCases = { 336 {1.0f, 2.0f, 3.0f, 337 5.0f,}, 338 339 {1.0f, 2.0f, -2.0f, 340 0.0f,}, 341 342 {5.0f, 5.0f, -25.0f, 343 0.0f,}, 344 345 {Float.MAX_VALUE, 2.0f, -Float.MAX_VALUE, 346 Float.MAX_VALUE}, 347 348 {Float.MAX_VALUE, 2.0f, 1.0f, 349 InfinityF}, 350 351 {1.0f+Math.ulp(1.0f), 1.0f+Math.ulp(1.0f), -1.0f-2.0f*Math.ulp(1.0f), 352 Math.ulp(1.0f)*Math.ulp(1.0f)}, 353 }; 354 355 for (float[] testCase: testCases) 356 failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]); 357 358 return failures; 359 } 360 361 362 private static int testFusedMacCase(double input1, double input2, double input3, double expected) { 363 int failures = 0; 364 failures += Tests.test("Math.fma(double)", input1, input2, input3, 365 Math.fma(input1, input2, input3), expected); 366 failures += Tests.test("StrictMath.fma(double)", input1, input2, input3, 367 StrictMath.fma(input1, input2, input3), expected); 368 369 // Permute first two inputs 370 failures += Tests.test("Math.fma(double)", input2, input1, input3, 371 Math.fma(input2, input1, input3), expected); 372 failures += Tests.test("StrictMath.fma(double)", input2, input1, input3, 373 StrictMath.fma(input2, input1, input3), expected); 374 return failures; 375 } 376 377 private static int testFusedMacCase(float input1, float input2, float input3, float expected) { 378 int failures = 0; 379 failures += Tests.test("Math.fma(float)", input1, input2, input3, 380 Math.fma(input1, input2, input3), expected); 381 failures += Tests.test("StrictMath.fma(float)", input1, input2, input3, 382 StrictMath.fma(input1, input2, input3), expected); 383 384 // Permute first two inputs 385 failures += Tests.test("Math.fma(float)", input2, input1, input3, 386 Math.fma(input2, input1, input3), expected); 387 failures += Tests.test("StrictMath.fma(float)", input2, input1, input3, 388 StrictMath.fma(input2, input1, input3), expected); 389 return failures; 390 } 391} 392