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             {-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 
 226         for (double[] testCase: testCases)
 227             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 228 
 229         return failures;
 230     }
 231 
 232     private static int testNonFiniteF() {
 233         int failures = 0;
 234 
 235         float [][] testCases = {
 236             {1.0f,       InfinityF,  2.0f,
 237              InfinityF,
 238             },
 239 
 240             {1.0f,       2.0f,       InfinityF,
 241              InfinityF,
 242             },
 243 
 244             {InfinityF,  1.0f,       InfinityF,
 245              InfinityF,
 246             },
 247 
 248             {Float.MAX_VALUE, 2.0f, -InfinityF,
 249              -InfinityF},
 250 
 251             {InfinityF,  1.0f,      -InfinityF,
 252              NaNf,
 253             },
 254 
 255             {-InfinityF, 1.0f,       InfinityF,
 256              NaNf,
 257             },
 258 
 259             {1.0f,       NaNf,       2.0f,
 260              NaNf,
 261             },
 262 
 263             {1.0f,       2.0f,       NaNf,
 264              NaNf,
 265             },
 266 
 267             {InfinityF,  2.0f,       NaNf,
 268              NaNf,
 269             },
 270 
 271             {NaNf,       2.0f,       InfinityF,
 272              NaNf,
 273             },
 274         };
 275 
 276         for (float[] testCase: testCases)
 277             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 278 
 279         return failures;
 280     }
 281 
 282     private static int testZeroesF() {
 283         int failures = 0;
 284 
 285         float [][] testCases = {
 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             {+0.0f, +0.0f, -0.0f,
 295              +0.0f,
 296             },
 297 
 298             {+0.0f, +0.0f, -0.0f,
 299              +0.0f,
 300             },
 301 
 302             {-0.0f, +0.0f, -0.0f,
 303              -0.0f,
 304             },
 305 
 306             {-0.0f, -0.0f, -0.0f,
 307              +0.0f,
 308             },
 309 
 310             {-1.0f, +0.0f, -0.0f,
 311              -0.0f,
 312             },
 313 
 314             {-1.0f, +0.0f, +0.0f,
 315              +0.0f,
 316             },
 317 
 318             {-2.0f, +0.0f, -0.0f,
 319              -0.0f,
 320             },
 321         };
 322 
 323         for (float[] testCase: testCases)
 324             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 325 
 326         return failures;
 327     }
 328         
 329     private static int testSimpleF() {
 330         int failures = 0;
 331 
 332         float [][] testCases = {
 333             {1.0f, 2.0f, 3.0f,
 334              5.0f,},
 335 
 336             {1.0f, 2.0f, -2.0f,
 337              0.0f,},
 338 
 339             {5.0f, 5.0f, -25.0f,
 340              0.0f,},
 341 
 342             {Float.MAX_VALUE, 2.0f, -Float.MAX_VALUE,
 343              Float.MAX_VALUE},
 344 
 345             {Float.MAX_VALUE, 2.0f, 1.0f,
 346              InfinityF},
 347         };
 348 
 349         for (float[] testCase: testCases)
 350             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 351 
 352         return failures;
 353     }
 354 
 355 
 356     private static int testFusedMacCase(double input1, double input2, double input3, double expected) {
 357         int failures = 0;
 358         failures += Tests.test("Math.fma(double)", input1, input2, input3,
 359                                Math.fma(input1, input2, input3), expected);
 360         failures += Tests.test("StrictMath.fma(double)", input1, input2, input3,
 361                                StrictMath.fma(input1, input2, input3), expected);
 362 
 363         // Permute first two inputs
 364         failures += Tests.test("Math.fma(double)", input2, input1, input3,
 365                                Math.fma(input2, input1, input3), expected);
 366         failures += Tests.test("StrictMath.fma(double)", input2, input1, input3,
 367                                StrictMath.fma(input2, input1, input3), expected);
 368         return failures;
 369     }
 370 
 371     private static int testFusedMacCase(float input1, float input2, float input3, float expected) {
 372         int failures = 0;
 373         failures += Tests.test("Math.fma(float)", input1, input2, input3,
 374                                Math.fma(input1, input2, input3), expected);
 375         failures += Tests.test("StrictMath.fma(float)", input1, input2, input3,
 376                                StrictMath.fma(input1, input2, input3), expected);
 377 
 378         // Permute first two inputs
 379         failures += Tests.test("Math.fma(float)", input2, input1, input3,
 380                                Math.fma(input2, input1, input3), expected);
 381         failures += Tests.test("StrictMath.fma(float)", input2, input1, input3,
 382                                StrictMath.fma(input2, input1, input3), expected);
 383         return failures;
 384     }
 385 }