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 }