1 /* 2 * Copyright (c) 2015, 2017, 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 8139688 27 * @key randomness 28 * @library /test/lib 29 * @build jdk.test.lib.RandomFactory 30 * @build Tests 31 * @build FdlibmTranslit 32 * @build ExpTests 33 * @run main ExpTests 34 * @summary Tests specifically for StrictMath.exp 35 */ 36 package test.java.lang.StrictMath; 37 38 import java.util.Random; 39 40 import org.testng.annotations.Test; 41 42 /** 43 * The role of this test is to verify that the FDLIBM exp algorithm is being used by running golden 44 * file style tests on values that may vary from one conforming exponential implementation to 45 * another. 46 */ 47 48 public class ExpTests { 49 ExpTests()50 private ExpTests() { 51 } 52 53 // From the fdlibm source, the overflow threshold in hex is: 54 // 0x4086_2E42_FEFA_39EF. 55 static final double EXP_OVERFLOW_THRESH = Double.longBitsToDouble(0x4086_2E42_FEFA_39EFL); 56 57 // From the fdlibm source, the underflow threshold in hex is: 58 // 0xc087_4910_D52D_3051L. 59 static final double EXP_UNDERFLOW_THRESH = Double.longBitsToDouble(0xc087_4910_D52D_3051L); 60 61 @Test testExp()62 public void testExp() { 63 double[][] testCases = { 64 // Some of these could be moved to common Math/StrictMath exp testing. 65 {Double.NaN, Double.NaN}, 66 {Double.MAX_VALUE, Double.POSITIVE_INFINITY}, 67 {Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY}, 68 {Double.NEGATIVE_INFINITY, +0.0}, 69 {EXP_OVERFLOW_THRESH, 0x1.ffff_ffff_fff2ap1023}, 70 {Math.nextUp(EXP_OVERFLOW_THRESH), Double.POSITIVE_INFINITY}, 71 {Math.nextDown(EXP_UNDERFLOW_THRESH), +0.0}, 72 {EXP_UNDERFLOW_THRESH, +Double.MIN_VALUE}, 73 }; 74 75 for (double[] testCase : testCases) { 76 testExpCase(testCase[0], testCase[1]); 77 } 78 } 79 testExpCase(double input, double expected)80 static void testExpCase(double input, double expected) { 81 Tests.test("StrictMath.exp(double)", input, 82 StrictMath.exp(input), expected); 83 } 84 85 // Initialize shared random number generator 86 private static final java.util.Random random = new Random(); 87 88 /** 89 * Test StrictMath.exp against transliteration port of exp. 90 */ 91 @Test testAgainstTranslit()92 public void testAgainstTranslit() { 93 double[] decisionPoints = { 94 // Near overflow threshold 95 EXP_OVERFLOW_THRESH - 512 * Math.ulp(EXP_OVERFLOW_THRESH), 96 97 // Near underflow threshold 98 EXP_UNDERFLOW_THRESH - 512 * Math.ulp(EXP_UNDERFLOW_THRESH), 99 100 // Straddle algorithm conditional checks 101 Double.longBitsToDouble(0x4086_2E42_0000_0000L - 512L), 102 Double.longBitsToDouble(0x3fd6_2e42_0000_0000L - 512L), 103 Double.longBitsToDouble(0x3FF0_A2B2_0000_0000L - 512L), 104 Double.longBitsToDouble(0x3e30_0000_0000_0000L - 512L), 105 106 // Other notable points 107 Double.MIN_NORMAL - Math.ulp(Double.MIN_NORMAL) * 512, 108 -Double.MIN_VALUE * 512, 109 }; 110 111 for (double decisionPoint : decisionPoints) { 112 double ulp = Math.ulp(decisionPoint); 113 testRange(decisionPoint - 1024 * ulp, ulp, 1_024); 114 } 115 116 // Try out some random values 117 for (int i = 0; i < 100; i++) { 118 double x = Tests.createRandomDouble(random); 119 testRange(x, Math.ulp(x), 100); 120 } 121 } 122 testRange(double start, double increment, int count)123 private static void testRange(double start, double increment, int count) { 124 double x = start; 125 for (int i = 0; i < count; i++, x += increment) { 126 testExpCase(x, FdlibmTranslit.Exp.compute(x)); 127 } 128 } 129 } 130