test/java/lang/Math/Expm1Tests.java

Print this page




   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 4851638 4900189 4939441
  27  * @summary Tests for {Math, StrictMath}.expm1



  28  * @author Joseph D. Darcy
  29  */
  30 
  31 import sun.misc.DoubleConsts;
  32 
  33 /*
  34  * The Taylor expansion of expxm1(x) = exp(x) -1 is
  35  *
  36  * 1 + x/1! + x^2/2! + x^3/3| + ... -1 =
  37  *
  38  * x + x^2/2! + x^3/3 + ...
  39  *
  40  * Therefore, for small values of x, expxm1 ~= x.
  41  *
  42  * For large values of x, expxm1(x) ~= exp(x)
  43  *
  44  * For large negative x, expxm1(x) ~= -1.
  45  */
  46 
  47 public class Expm1Tests {
  48 
  49     private Expm1Tests(){}
  50 
  51     static final double infinityD = Double.POSITIVE_INFINITY;


  63             {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
  64             {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
  65             {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
  66             {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
  67             {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
  68             {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
  69             {infinityD,                 infinityD},
  70             {-infinityD,                -1.0},
  71             {-0.0,                      -0.0},
  72             {+0.0,                      +0.0},
  73         };
  74 
  75         // Test special cases
  76         for(int i = 0; i < testCases.length; i++) {
  77             failures += testExpm1CaseWithUlpDiff(testCases[i][0],
  78                                                  testCases[i][1], 0, null);
  79         }
  80 
  81 
  82         // For |x| < 2^-54 expm1(x) ~= x
  83         for(int i = DoubleConsts.MIN_SUB_EXPONENT; i <= -54; i++) {
  84             double d = Math.scalb(2, i);
  85             failures += testExpm1Case(d, d);
  86             failures += testExpm1Case(-d, -d);
  87         }
  88 
  89 
  90         // For values of y where exp(y) > 2^54, expm1(x) ~= exp(x).
  91         // The least such y is ln(2^54) ~= 37.42994775023705; exp(x)
  92         // overflows for x > ~= 709.8
  93 
  94         // Use a 2-ulp error threshold to account for errors in the
  95         // exp implementation; the increments of d in the loop will be
  96         // exact.
  97         for(double d = 37.5; d <= 709.5; d += 1.0) {
  98             failures += testExpm1CaseWithUlpDiff(d, StrictMath.exp(d), 2, null);
  99         }
 100 
 101         // For x > 710, expm1(x) should be infinity
 102         for(int i = 10; i <= DoubleConsts.MAX_EXPONENT; i++) {
 103             double d = Math.scalb(2, i);
 104             failures += testExpm1Case(d, infinityD);
 105         }
 106 
 107         // By monotonicity, once the limit is reached, the
 108         // implemenation should return the limit for all smaller
 109         // values.
 110         boolean reachedLimit [] = {false, false};
 111 
 112         // Once exp(y) < 0.5 * ulp(1), expm1(y) ~= -1.0;
 113         // The greatest such y is ln(2^-53) ~= -36.7368005696771.
 114         for(double d = -36.75; d >= -127.75; d -= 1.0) {
 115             failures += testExpm1CaseWithUlpDiff(d, -1.0, 1,
 116                                                  reachedLimit);
 117         }
 118 
 119         for(int i = 7; i <= DoubleConsts.MAX_EXPONENT; i++) {
 120             double d = -Math.scalb(2, i);
 121             failures += testExpm1CaseWithUlpDiff(d, -1.0, 1, reachedLimit);
 122         }
 123 
 124         // Test for monotonicity failures near multiples of log(2).
 125         // Test two numbers before and two numbers after each chosen
 126         // value; i.e.
 127         //
 128         // pcNeighbors[] =
 129         // {nextDown(nextDown(pc)),
 130         // nextDown(pc),
 131         // pc,
 132         // nextUp(pc),
 133         // nextUp(nextUp(pc))}
 134         //
 135         // and we test that expm1(pcNeighbors[i]) <= expm1(pcNeighbors[i+1])
 136         {
 137             double pcNeighbors[] = new double[5];
 138             double pcNeighborsExpm1[] = new double[5];
 139             double pcNeighborsStrictExpm1[] = new double[5];




   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 4851638 4900189 4939441
  27  * @summary Tests for {Math, StrictMath}.expm1
  28  * @library /lib/testlibrary
  29  * @build jdk.testlibrary.DoubleUtils jdk.testlibrary.FloatUtils
  30  * @run main Expm1Tests
  31  * @author Joseph D. Darcy
  32  */
  33 
  34 import static jdk.testlibrary.DoubleUtils.*;
  35 
  36 /*
  37  * The Taylor expansion of expxm1(x) = exp(x) -1 is
  38  *
  39  * 1 + x/1! + x^2/2! + x^3/3| + ... -1 =
  40  *
  41  * x + x^2/2! + x^3/3 + ...
  42  *
  43  * Therefore, for small values of x, expxm1 ~= x.
  44  *
  45  * For large values of x, expxm1(x) ~= exp(x)
  46  *
  47  * For large negative x, expxm1(x) ~= -1.
  48  */
  49 
  50 public class Expm1Tests {
  51 
  52     private Expm1Tests(){}
  53 
  54     static final double infinityD = Double.POSITIVE_INFINITY;


  66             {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
  67             {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
  68             {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
  69             {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
  70             {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
  71             {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
  72             {infinityD,                 infinityD},
  73             {-infinityD,                -1.0},
  74             {-0.0,                      -0.0},
  75             {+0.0,                      +0.0},
  76         };
  77 
  78         // Test special cases
  79         for(int i = 0; i < testCases.length; i++) {
  80             failures += testExpm1CaseWithUlpDiff(testCases[i][0],
  81                                                  testCases[i][1], 0, null);
  82         }
  83 
  84 
  85         // For |x| < 2^-54 expm1(x) ~= x
  86         for(int i = MIN_SUB_EXPONENT; i <= -54; i++) {
  87             double d = Math.scalb(2, i);
  88             failures += testExpm1Case(d, d);
  89             failures += testExpm1Case(-d, -d);
  90         }
  91 
  92 
  93         // For values of y where exp(y) > 2^54, expm1(x) ~= exp(x).
  94         // The least such y is ln(2^54) ~= 37.42994775023705; exp(x)
  95         // overflows for x > ~= 709.8
  96 
  97         // Use a 2-ulp error threshold to account for errors in the
  98         // exp implementation; the increments of d in the loop will be
  99         // exact.
 100         for(double d = 37.5; d <= 709.5; d += 1.0) {
 101             failures += testExpm1CaseWithUlpDiff(d, StrictMath.exp(d), 2, null);
 102         }
 103 
 104         // For x > 710, expm1(x) should be infinity
 105         for(int i = 10; i <= Double.MAX_EXPONENT; i++) {
 106             double d = Math.scalb(2, i);
 107             failures += testExpm1Case(d, infinityD);
 108         }
 109 
 110         // By monotonicity, once the limit is reached, the
 111         // implemenation should return the limit for all smaller
 112         // values.
 113         boolean reachedLimit [] = {false, false};
 114 
 115         // Once exp(y) < 0.5 * ulp(1), expm1(y) ~= -1.0;
 116         // The greatest such y is ln(2^-53) ~= -36.7368005696771.
 117         for(double d = -36.75; d >= -127.75; d -= 1.0) {
 118             failures += testExpm1CaseWithUlpDiff(d, -1.0, 1,
 119                                                  reachedLimit);
 120         }
 121 
 122         for(int i = 7; i <= Double.MAX_EXPONENT; i++) {
 123             double d = -Math.scalb(2, i);
 124             failures += testExpm1CaseWithUlpDiff(d, -1.0, 1, reachedLimit);
 125         }
 126 
 127         // Test for monotonicity failures near multiples of log(2).
 128         // Test two numbers before and two numbers after each chosen
 129         // value; i.e.
 130         //
 131         // pcNeighbors[] =
 132         // {nextDown(nextDown(pc)),
 133         // nextDown(pc),
 134         // pc,
 135         // nextUp(pc),
 136         // nextUp(nextUp(pc))}
 137         //
 138         // and we test that expm1(pcNeighbors[i]) <= expm1(pcNeighbors[i+1])
 139         {
 140             double pcNeighbors[] = new double[5];
 141             double pcNeighborsExpm1[] = new double[5];
 142             double pcNeighborsStrictExpm1[] = new double[5];