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 FusedMacTests
  30  * @run main FusedMacTests
  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 FusedMacTests {
  40     private FusedMacTests(){}
  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 fusedMac 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             {1.0,       Infinity,  2.0,
  70             Infinity,
  71             },
  72 
  73             {1.0,       2.0,       Infinity,
  74              Infinity,
  75             },
  76 
  77             {Infinity,  1.0,       Infinity,
  78              Infinity,
  79             },
  80 
  81             {Double.MAX_VALUE, 2.0, -Infinity,
  82              -Infinity},
  83 
  84             {Infinity,  1.0,       -Infinity,
  85              NaN,
  86             },
  87 
  88             {-Infinity, 1.0,       Infinity,
  89              NaN,
  90             },
  91 
  92             {1.0,       NaN,       2.0,
  93              NaN,
  94             },
  95 
  96             {1.0,       2.0,       NaN,
  97              NaN,
  98             },
  99 
 100             {Infinity,  2.0,       NaN,
 101              NaN,
 102             },
 103 
 104             {NaN,       2.0,       Infinity,
 105              NaN,
 106             },
 107         };
 108 
 109         for (double[] testCase: testCases)
 110             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 111 
 112         return failures;
 113     }
 114 
 115     private static int testZeroesD() {
 116         int failures = 0;
 117 
 118         double [][] testCases = {
 119             {+0.0, +0.0, +0.0,
 120              +0.0,
 121             },
 122 
 123             {-0.0, +0.0, +0.0,
 124              +0.0,
 125             },
 126 
 127             {+0.0, +0.0, -0.0,
 128              +0.0,
 129             },
 130 
 131             {+0.0, +0.0, -0.0,
 132              +0.0,
 133             },
 134 
 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             {-1.0, +0.0, -0.0,
 144              -0.0,
 145             },
 146 
 147             {-1.0, +0.0, +0.0,
 148              +0.0,
 149             },
 150 
 151             {-2.0, +0.0, -0.0,
 152              -0.0,
 153             },
 154         };
 155 
 156         for (double[] testCase: testCases)
 157             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 158 
 159         return failures;
 160     }
 161         
 162     private static int testSimpleD() {
 163         int failures = 0;
 164 
 165         double [][] testCases = {
 166             {1.0, 2.0, 3.0,
 167              5.0,},
 168 
 169             {1.0, 2.0, -2.0,
 170              0.0,},
 171 
 172             {5.0, 5.0, -25.0,
 173              0.0,},
 174 
 175             {Double.MAX_VALUE, 2.0, -Double.MAX_VALUE,
 176              Double.MAX_VALUE},
 177 
 178             {Double.MAX_VALUE, 2.0, 1.0,
 179              Infinity},
 180         };
 181 
 182         for (double[] testCase: testCases)
 183             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 184 
 185         return failures;
 186     }
 187 
 188     private static int testNonFiniteF() {
 189         int failures = 0;
 190 
 191         float [][] testCases = {
 192             {1.0f,       InfinityF,  2.0f,
 193              InfinityF,
 194             },
 195 
 196             {1.0f,       2.0f,       InfinityF,
 197              InfinityF,
 198             },
 199 
 200             {InfinityF,  1.0f,       InfinityF,
 201              InfinityF,
 202             },
 203 
 204             {Float.MAX_VALUE, 2.0f, -InfinityF,
 205              -InfinityF},
 206 
 207             {InfinityF,  1.0f,      -InfinityF,
 208              NaNf,
 209             },
 210 
 211             {-InfinityF, 1.0f,       InfinityF,
 212              NaNf,
 213             },
 214 
 215             {1.0f,       NaNf,       2.0f,
 216              NaNf,
 217             },
 218 
 219             {1.0f,       2.0f,       NaNf,
 220              NaNf,
 221             },
 222 
 223             {InfinityF,  2.0f,       NaNf,
 224              NaNf,
 225             },
 226 
 227             {NaNf,       2.0f,       InfinityF,
 228              NaNf,
 229             },
 230         };
 231 
 232         for (float[] testCase: testCases)
 233             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 234 
 235         return failures;
 236     }
 237 
 238     private static int testZeroesF() {
 239         int failures = 0;
 240 
 241         float [][] testCases = {
 242             {+0.0f, +0.0f, +0.0f,
 243              +0.0f,
 244             },
 245 
 246             {-0.0f, +0.0f, +0.0f,
 247              +0.0f,
 248             },
 249 
 250             {+0.0f, +0.0f, -0.0f,
 251              +0.0f,
 252             },
 253 
 254             {+0.0f, +0.0f, -0.0f,
 255              +0.0f,
 256             },
 257 
 258             {-0.0f, +0.0f, -0.0f,
 259              -0.0f,
 260             },
 261 
 262             {-0.0f, -0.0f, -0.0f,
 263              +0.0f,
 264             },
 265 
 266             {-1.0f, +0.0f, -0.0f,
 267              -0.0f,
 268             },
 269 
 270             {-1.0f, +0.0f, +0.0f,
 271              +0.0f,
 272             },
 273 
 274             {-2.0f, +0.0f, -0.0f,
 275              -0.0f,
 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 testSimpleF() {
 286         int failures = 0;
 287 
 288         float [][] testCases = {
 289             {1.0f, 2.0f, 3.0f,
 290              5.0f,},
 291 
 292             {1.0f, 2.0f, -2.0f,
 293              0.0f,},
 294 
 295             {5.0f, 5.0f, -25.0f,
 296              0.0f,},
 297 
 298             {Float.MAX_VALUE, 2.0f, -Float.MAX_VALUE,
 299              Float.MAX_VALUE},
 300 
 301             {Float.MAX_VALUE, 2.0f, 1.0f,
 302              InfinityF},
 303         };
 304 
 305         for (float[] testCase: testCases)
 306             failures += testFusedMacCase(testCase[0], testCase[1], testCase[2], testCase[3]);
 307 
 308         return failures;
 309     }
 310 
 311 
 312     private static int testFusedMacCase(double input1, double input2, double input3, double expected) {
 313         int failures = 0;
 314         failures += Tests.test("Math.fusedMac(double)", input1, input2, input3,
 315                                Math.fusedMac(input1, input2, input3), expected);
 316         failures += Tests.test("StrictMath.fusedMac(double)", input1, input2, input3,
 317                                StrictMath.fusedMac(input1, input2, input3), expected);
 318 
 319         // Permute first two inputs
 320         failures += Tests.test("Math.fusedMac(double)", input2, input1, input3,
 321                                Math.fusedMac(input2, input1, input3), expected);
 322         failures += Tests.test("StrictMath.fusedMac(double)", input2, input1, input3,
 323                                StrictMath.fusedMac(input2, input1, input3), expected);
 324         return failures;
 325     }
 326 
 327     private static int testFusedMacCase(float input1, float input2, float input3, float expected) {
 328         int failures = 0;
 329         failures += Tests.test("Math.fusedMac(float)", input1, input2, input3,
 330                                Math.fusedMac(input1, input2, input3), expected);
 331         failures += Tests.test("StrictMath.fusedMac(float)", input1, input2, input3,
 332                                StrictMath.fusedMac(input1, input2, input3), expected);
 333 
 334         // Permute first two inputs
 335         failures += Tests.test("Math.fusedMac(float)", input2, input1, input3,
 336                                Math.fusedMac(input2, input1, input3), expected);
 337         failures += Tests.test("StrictMath.fusedMac(float)", input2, input1, input3,
 338                                StrictMath.fusedMac(input2, input1, input3), expected);
 339         return failures;
 340     }
 341 }