Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/Math/Expm1Tests.java
38812 views
/*1* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 4851638 4900189 493944126* @summary Tests for {Math, StrictMath}.expm127* @author Joseph D. Darcy28*/2930import sun.misc.DoubleConsts;3132/*33* The Taylor expansion of expxm1(x) = exp(x) -1 is34*35* 1 + x/1! + x^2/2! + x^3/3| + ... -1 =36*37* x + x^2/2! + x^3/3 + ...38*39* Therefore, for small values of x, expxm1 ~= x.40*41* For large values of x, expxm1(x) ~= exp(x)42*43* For large negative x, expxm1(x) ~= -1.44*/4546public class Expm1Tests {4748private Expm1Tests(){}4950static final double infinityD = Double.POSITIVE_INFINITY;51static final double NaNd = Double.NaN;5253static int testExpm1() {54int failures = 0;5556double [][] testCases = {57{Double.NaN, NaNd},58{Double.longBitsToDouble(0x7FF0000000000001L), NaNd},59{Double.longBitsToDouble(0xFFF0000000000001L), NaNd},60{Double.longBitsToDouble(0x7FF8555555555555L), NaNd},61{Double.longBitsToDouble(0xFFF8555555555555L), NaNd},62{Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), NaNd},63{Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), NaNd},64{Double.longBitsToDouble(0x7FFDeadBeef00000L), NaNd},65{Double.longBitsToDouble(0xFFFDeadBeef00000L), NaNd},66{Double.longBitsToDouble(0x7FFCafeBabe00000L), NaNd},67{Double.longBitsToDouble(0xFFFCafeBabe00000L), NaNd},68{infinityD, infinityD},69{-infinityD, -1.0},70{-0.0, -0.0},71{+0.0, +0.0},72};7374// Test special cases75for(int i = 0; i < testCases.length; i++) {76failures += testExpm1CaseWithUlpDiff(testCases[i][0],77testCases[i][1], 0, null);78}798081// For |x| < 2^-54 expm1(x) ~= x82for(int i = DoubleConsts.MIN_SUB_EXPONENT; i <= -54; i++) {83double d = Math.scalb(2, i);84failures += testExpm1Case(d, d);85failures += testExpm1Case(-d, -d);86}878889// For values of y where exp(y) > 2^54, expm1(x) ~= exp(x).90// The least such y is ln(2^54) ~= 37.42994775023705; exp(x)91// overflows for x > ~= 709.89293// Use a 2-ulp error threshold to account for errors in the94// exp implementation; the increments of d in the loop will be95// exact.96for(double d = 37.5; d <= 709.5; d += 1.0) {97failures += testExpm1CaseWithUlpDiff(d, StrictMath.exp(d), 2, null);98}99100// For x > 710, expm1(x) should be infinity101for(int i = 10; i <= DoubleConsts.MAX_EXPONENT; i++) {102double d = Math.scalb(2, i);103failures += testExpm1Case(d, infinityD);104}105106// By monotonicity, once the limit is reached, the107// implemenation should return the limit for all smaller108// values.109boolean reachedLimit [] = {false, false};110111// Once exp(y) < 0.5 * ulp(1), expm1(y) ~= -1.0;112// The greatest such y is ln(2^-53) ~= -36.7368005696771.113for(double d = -36.75; d >= -127.75; d -= 1.0) {114failures += testExpm1CaseWithUlpDiff(d, -1.0, 1,115reachedLimit);116}117118for(int i = 7; i <= DoubleConsts.MAX_EXPONENT; i++) {119double d = -Math.scalb(2, i);120failures += testExpm1CaseWithUlpDiff(d, -1.0, 1, reachedLimit);121}122123// Test for monotonicity failures near multiples of log(2).124// Test two numbers before and two numbers after each chosen125// value; i.e.126//127// pcNeighbors[] =128// {nextDown(nextDown(pc)),129// nextDown(pc),130// pc,131// nextUp(pc),132// nextUp(nextUp(pc))}133//134// and we test that expm1(pcNeighbors[i]) <= expm1(pcNeighbors[i+1])135{136double pcNeighbors[] = new double[5];137double pcNeighborsExpm1[] = new double[5];138double pcNeighborsStrictExpm1[] = new double[5];139140for(int i = -50; i <= 50; i++) {141double pc = StrictMath.log(2)*i;142143pcNeighbors[2] = pc;144pcNeighbors[1] = Math.nextDown(pc);145pcNeighbors[0] = Math.nextDown(pcNeighbors[1]);146pcNeighbors[3] = Math.nextUp(pc);147pcNeighbors[4] = Math.nextUp(pcNeighbors[3]);148149for(int j = 0; j < pcNeighbors.length; j++) {150pcNeighborsExpm1[j] = Math.expm1(pcNeighbors[j]);151pcNeighborsStrictExpm1[j] = StrictMath.expm1(pcNeighbors[j]);152}153154for(int j = 0; j < pcNeighborsExpm1.length-1; j++) {155if(pcNeighborsExpm1[j] > pcNeighborsExpm1[j+1] ) {156failures++;157System.err.println("Monotonicity failure for Math.expm1 on " +158pcNeighbors[j] + " and " +159pcNeighbors[j+1] + "\n\treturned " +160pcNeighborsExpm1[j] + " and " +161pcNeighborsExpm1[j+1] );162}163164if(pcNeighborsStrictExpm1[j] > pcNeighborsStrictExpm1[j+1] ) {165failures++;166System.err.println("Monotonicity failure for StrictMath.expm1 on " +167pcNeighbors[j] + " and " +168pcNeighbors[j+1] + "\n\treturned " +169pcNeighborsStrictExpm1[j] + " and " +170pcNeighborsStrictExpm1[j+1] );171}172173174}175176}177}178179return failures;180}181182public static int testExpm1Case(double input,183double expected) {184return testExpm1CaseWithUlpDiff(input, expected, 1, null);185}186187public static int testExpm1CaseWithUlpDiff(double input,188double expected,189double ulps,190boolean [] reachedLimit) {191int failures = 0;192double mathUlps = ulps, strictUlps = ulps;193double mathOutput;194double strictOutput;195196if (reachedLimit != null) {197if (reachedLimit[0])198mathUlps = 0;199200if (reachedLimit[1])201strictUlps = 0;202}203204failures += Tests.testUlpDiffWithLowerBound("Math.expm1(double)",205input, mathOutput=Math.expm1(input),206expected, mathUlps, -1.0);207failures += Tests.testUlpDiffWithLowerBound("StrictMath.expm1(double)",208input, strictOutput=StrictMath.expm1(input),209expected, strictUlps, -1.0);210if (reachedLimit != null) {211reachedLimit[0] |= (mathOutput == -1.0);212reachedLimit[1] |= (strictOutput == -1.0);213}214215return failures;216}217218public static void main(String argv[]) {219int failures = 0;220221failures += testExpm1();222223if (failures > 0) {224System.err.println("Testing expm1 incurred "225+ failures + " failures.");226throw new RuntimeException();227}228}229}230231232