/* * Copyright 1999-2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package java.lang; import java.util.Random; import sun.misc.FpUtils; /** * The class {@code StrictMath} contains methods for performing basic * numeric operations such as the elementary exponential, logarithm, * square root, and trigonometric functions. * *
To help ensure portability of Java programs, the definitions of * some of the numeric functions in this package require that they * produce the same results as certain published algorithms. These * algorithms are available from the well-known network library * {@code netlib} as the package "Freely Distributable Math * Library," {@code fdlibm}. These * algorithms, which are written in the C programming language, are * then to be understood as executed with all floating-point * operations following the rules of Java floating-point arithmetic. * *
The Java math library is defined with respect to * {@code fdlibm} version 5.3. Where {@code fdlibm} provides * more than one definition for a function (such as * {@code acos}), use the "IEEE 754 core function" version * (residing in a file whose name begins with the letter * {@code e}). The methods which require {@code fdlibm} * semantics are {@code sin}, {@code cos}, {@code tan}, * {@code asin}, {@code acos}, {@code atan}, * {@code exp}, {@code log}, {@code log10}, * {@code cbrt}, {@code atan2}, {@code pow}, * {@code sinh}, {@code cosh}, {@code tanh}, * {@code hypot}, {@code expm1}, and {@code log1p}. * * @author unascribed * @author Joseph D. Darcy * @since 1.3 */ public final class StrictMath { /** * Don't let anyone instantiate this class. */ private StrictMath() { } /** * The {@code double} value that is closer than any other to * e, the base of the natural logarithms. */ public static final double E = 2.7182818284590452354; /** * The {@code double} value that is closer than any other to * pi, the ratio of the circumference of a circle to its * diameter. */ public static final double PI = 3.14159265358979323846; /** * Returns the trigonometric sine of an angle. Special cases: *
f1 - f2
× n,
* where n is the mathematical integer closest to the exact
* mathematical value of the quotient {@code f1/f2}, and if two
* mathematical integers are equally close to {@code f1/f2},
* then n is the integer that is even. If the remainder is
* zero, its sign is the same as the sign of the first argument.
* Special cases:
* (In the foregoing descriptions, a floating-point value is
* considered to be an integer if and only if it is finite and a
* fixed point of the method {@link #ceil ceil} or,
* equivalently, a fixed point of the method {@link #floor
* floor}. A value is a fixed point of a one-argument
* method if and only if the result of applying the method to the
* value is equal to the value.)
*
* @param a base.
* @param b the exponent.
* @return the value {@code a}{@code b}.
*/
public static double pow(double x, double y){
/* __ieee754_pow(x,y) return x**y
*
* n
* Method: Let x = 2 * (1+f)
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53-24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating muti-precision
* arithmetic, where |y'|<=0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
*
* Special cases:
* 1. (anything) ** 0 is 1
* 2. (anything) ** 1 is itself
* 3. (anything) ** NAN is NAN
* 4. NAN ** (anything except 0) is NAN
* 5. +-(|x| > 1) ** +INF is +INF
* 6. +-(|x| > 1) ** -INF is +0
* 7. +-(|x| < 1) ** +INF is +0
* 8. +-(|x| < 1) ** -INF is +INF
* 9. +-1 ** +-INF is NAN
* 10. +0 ** (+anything except 0, NAN) is +0
* 11. -0 ** (+anything except 0, NAN, odd integer) is +0
* 12. +0 ** (-anything except 0, NAN) is +INF
* 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
* 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
* 15. +INF ** (+anything except 0,NAN) is +INF
* 16. +INF ** (-anything except 0,NAN) is +0
* 17. -INF ** (anything) = -0 ** (-anything)
* 18. (-anything) ** (integer) is
(-1)**(integer)*(+anything**integer)
* 19. (-anything except 0 and inf) ** (non-integer) is NAN
*
* Accuracy:
* pow(x,y) returns x**y nearly rounded. In particular
* pow(integer,integer)
* always returns the correct integer provided it is
* representable.
*
*/
//i0 = ((*(int*)&one)>>29)^1; i1=1-i0;
long xb = Double.doubleToRawLongBits(x);
int hx = (int) (xb >> 32);
int lx = (int) xb&0x7fffffff; //unsigned
int ix = hx & 0x7fffffff;
xb = Double.doubleToRawLongBits(y);
int hy = (int) (xb >> 32);
int ly = (int) xb& 0x7fffffff; //unsigned
int iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if((iy|ly)==0) return one;
/* +-NaN return x+y */
if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
return x+y;
/* determine if y is an odd int when x < 0
* yisint = 0 ... y is not an integer
* yisint = 1 ... y is an odd int
* yisint = 2 ... y is an even int
*/
int yisint = 0;
if(hx<0) {
if(iy>=0x43400000) yisint = 2; /* even integer y */
else if(iy>=0x3ff00000) {
int k = (iy>>20)-0x3ff; /* exponent */
if(k>20) {
int j = ly>>(52-k);
if((j<<(52-k))==ly) yisint = 2-(j&1);
} else if(ly==0) {
int j = iy>>(20-k);
if((j<<(20-k))==iy) yisint = 2-(j&1);
}
}
}
/* special value of y */
if(ly==0) {
if (iy==0x7ff00000) { /* y is +-inf */
if(((ix-0x3ff00000)|lx)==0)
return y - y; /* inf**+-1 is NaN */
return (ix >= 0x3ff00000) ? /* (|x|>1)**+-inf = inf,0 */
(hy>=0)? y: zero : /* (|x|<1)**-,+inf = inf,0 */
(hy<0)?-y: zero;
}
if(iy==0x3ff00000) { /* y is +-1 */
return (hy<0) ? one/x : x;
}
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x3fe00000) { /* y is 0.5 */
if(hx>=0) /* x >= +0 */
return Math.sqrt(x);
}
}
double ax = abs(x);
/* special value of x */
if(lx==0) {
if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
double z = ax; /*x is +-0,+-inf,+-1*/
if(hy<0) z = one/z; /* z = (1/|x|) */
if(hx<0) {
if(((ix-0x3ff00000)|yisint)==0) {
z = (z-z)/(z-z); /* (-1)**non-int is NaN */
} else if(yisint==1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
}
int n = (hx>>31)+1;
/* (x<0)**(non-int) is NaN */
if((n|yisint)==0) return (x-x)/(x-x);
double s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
double t1,t2;
/* |y| is huge */
if(iy>0x41e00000) { /* if |y| > 2**31 */
if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
}
/* over/underflow if x is not close to one */
if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
double t = ax-one; /* t has 20 trailing zeros */
double w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
double u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
double v = t*ivln2_l-w*ivln2;
t1 = clearLow32bits(u+v);
t2 = v-(t1-u);
} else {
n = 0;
/* take care subnormal number */
if(ix<0x00100000)
{ax *= two53; n -= 53; ix = __HI(ax); }
n += ((ix)>>20)-0x3ff;
int j = ix&0x000fffff;
/* determine interval */
ix = j|0x3ff00000; /* normalize ix */
int k=0;
if(j<=0x3988E) ; /* |x| {@code (int)Math.floor(a + 0.5f)}
*
* Special cases:
* {@code (long)Math.floor(a + 0.5d)}
*
* Special cases:
* When this method is first called, it creates a single new
* pseudorandom-number generator, exactly as if by the expression
* This method is properly synchronized to allow correct use by
* more than one thread. However, if many threads need to generate
* pseudorandom numbers at a great rate, it may reduce contention
* for each thread to have its own pseudorandom number generator.
*
* @return a pseudorandom {@code double} greater than or equal
* to {@code 0.0} and less than {@code 1.0}.
* @see java.util.Random#nextDouble()
*/
public static double random() {
if (randomNumberGenerator == null) {
initRNG();
}
return randomNumberGenerator.nextDouble();
}
/**
* Returns the absolute value of an {@code int} value..
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
*
* Note that if the argument is equal to the value of
* {@link Integer#MIN_VALUE}, the most negative representable
* {@code int} value, the result is that same value, which is
* negative.
*
* @param a the argument whose absolute value is to be determined.
* @return the absolute value of the argument.
*/
public static int abs(int a) {
return (a < 0) ? -a : a;
}
/**
* Returns the absolute value of a {@code long} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
*
* Note that if the argument is equal to the value of
* {@link Long#MIN_VALUE}, the most negative representable
* {@code long} value, the result is that same value, which
* is negative.
*
* @param a the argument whose absolute value is to be determined.
* @return the absolute value of the argument.
*/
public static long abs(long a) {
return (a < 0) ? -a : a;
}
/**
* Returns the absolute value of a {@code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* {@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
/**
* Returns the absolute value of a {@code double} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* {@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
/**
* Returns the greater of two {@code int} values. That is, the
* result is the argument closer to the value of
* {@link Integer#MAX_VALUE}. If the arguments have the same value,
* the result is that same value.
*
* @param a an argument.
* @param b another argument.
* @return the larger of {@code a} and {@code b}.
*/
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
/**
* Returns the greater of two {@code long} values. That is, the
* result is the argument closer to the value of
* {@link Long#MAX_VALUE}. If the arguments have the same value,
* the result is that same value.
*
* @param a an argument.
* @param b another argument.
* @return the larger of {@code a} and {@code b}.
*/
public static long max(long a, long b) {
return (a >= b) ? a : b;
}
private final static long
negativeZeroFloatBits = Float.floatToIntBits(-0.0f),
negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d);
/**
* Returns the greater of two {@code float} values. That is,
* the result is the argument closer to positive infinity. If the
* arguments have the same value, the result is that same
* value. If either value is NaN, then the result is NaN. Unlike
* the numerical comparison operators, this method considers
* negative zero to be strictly smaller than positive zero. If one
* argument is positive zero and the other negative zero, the
* result is positive zero.
*
* @param a an argument.
* @param b another argument.
* @return the larger of {@code a} and {@code b}.
*/
public static float max(float a, float b) {
if (a != a) {
return a; // a is NaN
}
if ((a == 0.0f) && (b == 0.0f)
&& (Float.floatToIntBits(a) == negativeZeroFloatBits)) {
return b;
}
return (a >= b) ? a : b;
}
/**
* Returns the greater of two {@code double} values. That
* is, the result is the argument closer to positive infinity. If
* the arguments have the same value, the result is that same
* value. If either value is NaN, then the result is NaN. Unlike
* the numerical comparison operators, this method considers
* negative zero to be strictly smaller than positive zero. If one
* argument is positive zero and the other negative zero, the
* result is positive zero.
*
* @param a an argument.
* @param b another argument.
* @return the larger of {@code a} and {@code b}.
*/
public static double max(double a, double b) {
if (a != a) {
return a; // a is NaN
}
if ((a == 0.0d) && (b == 0.0d)
&& (Double.doubleToLongBits(a) == negativeZeroDoubleBits)) {
return b;
}
return (a >= b) ? a : b;
}
/**
* Returns the smaller of two {@code int} values. That is,
* the result the argument closer to the value of
* {@link Integer#MIN_VALUE}. If the arguments have the same
* value, the result is that same value.
*
* @param a an argument.
* @param b another argument.
* @return the smaller of {@code a} and {@code b}.
*/
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
/**
* Returns the smaller of two {@code long} values. That is,
* the result is the argument closer to the value of
* {@link Long#MIN_VALUE}. If the arguments have the same
* value, the result is that same value.
*
* @param a an argument.
* @param b another argument.
* @return the smaller of {@code a} and {@code b}.
*/
public static long min(long a, long b) {
return (a <= b) ? a : b;
}
/**
* Returns the smaller of two {@code float} values. That is,
* the result is the value closer to negative infinity. If the
* arguments have the same value, the result is that same
* value. If either value is NaN, then the result is NaN. Unlike
* the numerical comparison operators, this method considers
* negative zero to be strictly smaller than positive zero. If
* one argument is positive zero and the other is negative zero,
* the result is negative zero.
*
* @param a an argument.
* @param b another argument.
* @return the smaller of {@code a} and {@code b.}
*/
public static float min(float a, float b) {
if (a != a) {
return a; // a is NaN
}
if ((a == 0.0f) && (b == 0.0f)
&& (Float.floatToIntBits(b) == negativeZeroFloatBits)) {
return b;
}
return (a <= b) ? a : b;
}
/**
* Returns the smaller of two {@code double} values. That
* is, the result is the value closer to negative infinity. If the
* arguments have the same value, the result is that same
* value. If either value is NaN, then the result is NaN. Unlike
* the numerical comparison operators, this method considers
* negative zero to be strictly smaller than positive zero. If one
* argument is positive zero and the other is negative zero, the
* result is negative zero.
*
* @param a an argument.
* @param b another argument.
* @return the smaller of {@code a} and {@code b}.
*/
public static double min(double a, double b) {
if (a != a) {
return a; // a is NaN
}
if ((a == 0.0d) && (b == 0.0d)
&& (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) {
return b;
}
return (a <= b) ? a : b;
}
/**
* Returns the size of an ulp of the argument. An ulp of a
* {@code double} value is the positive distance between this
* floating-point value and the {@code double} value next
* larger in magnitude. Note that for non-NaN x,
* Special Cases:
* Special Cases:
* Special Cases:
* Special Cases:
* Special cases:
* Special cases:
* Special cases:
* Special cases:
* Special cases:
* Special cases:
* Special cases:
* Special cases:
* Special Cases:
* Special Cases:
* Special cases:
* Special cases:
*
*
* @param a a floating-point value to be rounded to an integer.
* @return the value of the argument rounded to the nearest
* {@code int} value.
* @see java.lang.Integer#MAX_VALUE
* @see java.lang.Integer#MIN_VALUE
*/
public static int round(float a) {
return (int) floor(a + 0.5f);
}
/**
* Returns the closest {@code long} to the argument. The result
* is rounded to an integer by adding 1/2, taking the floor of the
* result, and casting the result to type {@code long}. In other
* words, the result is equal to the value of the expression:
*
*
* @param a a floating-point value to be rounded to a
* {@code long}.
* @return the value of the argument rounded to the nearest
* {@code long} value.
* @see java.lang.Long#MAX_VALUE
* @see java.lang.Long#MIN_VALUE
*/
public static long round(double a) {
return (long) floor(a + 0.5d);
}
private static Random randomNumberGenerator;
private static synchronized void initRNG() {
if (randomNumberGenerator == null) {
randomNumberGenerator = new Random();
}
}
/**
* Returns a {@code double} value with a positive sign, greater
* than or equal to {@code 0.0} and less than {@code 1.0}.
* Returned values are chosen pseudorandomly with (approximately)
* uniform distribution from that range.
*
* {@code new java.util.Random}
This
* new pseudorandom-number generator is used thereafter for all
* calls to this method and is used nowhere else.
*
*
* In other words, the result is the same as the value of the expression:
*
* In other words, the result is the same as the value of the expression:
* ulp(-x) == ulp(x)
.
*
*
*
*
* @param d the floating-point value whose ulp is to be returned
* @return the size of an ulp of the argument
* @author Joseph D. Darcy
* @since 1.5
*/
public static double ulp(double d) {
return sun.misc.FpUtils.ulp(d);
}
/**
* Returns the size of an ulp of the argument. An ulp of a
* {@code float} value is the positive distance between this
* floating-point value and the {@code float} value next
* larger in magnitude. Note that for non-NaN x,
* ulp(-x) == ulp(x)
.
*
*
*
*
* @param f the floating-point value whose ulp is to be returned
* @return the size of an ulp of the argument
* @author Joseph D. Darcy
* @since 1.5
*/
public static float ulp(float f) {
return sun.misc.FpUtils.ulp(f);
}
/**
* Returns the signum function of the argument; zero if the argument
* is zero, 1.0 if the argument is greater than zero, -1.0 if the
* argument is less than zero.
*
*
*
*
* @param d the floating-point value whose signum is to be returned
* @return the signum function of the argument
* @author Joseph D. Darcy
* @since 1.5
*/
public static double signum(double d) {
return sun.misc.FpUtils.signum(d);
}
/**
* Returns the signum function of the argument; zero if the argument
* is zero, 1.0f if the argument is greater than zero, -1.0f if the
* argument is less than zero.
*
*
*
*
* @param f the floating-point value whose signum is to be returned
* @return the signum function of the argument
* @author Joseph D. Darcy
* @since 1.5
*/
public static float signum(float f) {
return sun.misc.FpUtils.signum(f);
}
private static final double shuge = 1.0e307;
/**
* Returns the hyperbolic sine of a {@code double} value.
* The hyperbolic sine of x is defined to be
* (ex - e-x)/2
* where e is {@linkplain Math#E Euler's number}.
*
*
*
*
*
* @param x The number whose hyperbolic sine is to be returned.
* @return The hyperbolic sine of {@code x}.
* @since 1.5
*/
public static double sinh(double x) {
/* __ieee754_sinh(x)
* Method :
* mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
* 1. Replace x by |x| (sinh(-x) = -sinh(x)).
* 2.
* E + E/(E+1)
* 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
* 2
*
* 22 <= x <= lnovft : sinh(x) := exp(x)/2
* lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
* ln2ovft < x : sinh(x) := x*shuge (overflow)
*
* Special cases:
* sinh(x) is |x| if x is +INF, -INF, or NaN.
* only sinh(0)=0 is exact for finite x.
*/
final long xb = Double.doubleToLongBits(x);
final double h = (xb >> 32) < 0 ? -0.5 : 0.5;
final int ix = (int) ((xb >> 32) & 0x7fffffff);
if(ix >= 0x7ff00000) { /* x is INF or NaN */
return x+x;
}
/* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
if (ix < 0x40360000) { /* |x|<22 */
if (ix<0x3e300000) /* |x|<2**-28 */
if(shuge+x>one) {
return x;/* sinh(tiny) = tiny with inexact */
}
final double t = expm1(abs(x));
return (ix<0x3ff00000) ? h*(2.0*t-t*t/(t+one)) : h*(t+t/(t+one));
}
/* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
if (ix < 0x40862E42) return h*exp(abs(x));
// |x| in [log(Double.MAX_VALUE), overflowthreshold]
if (ix < 0x408633ce || (ix == 0x408633ce &&
(xb & 0x00000000ffffffffL) <= 0x8fb9f87dL)){
final double w = exp(0.5 * abs(x));
return (h * w) * w;
}
/* |x| > overflowthresold, sinh(x) overflow */
return x*shuge;
}
/**
* Returns the hyperbolic cosine of a {@code double} value.
* The hyperbolic cosine of x is defined to be
* (ex + e-x)/2
* where e is {@linkplain Math#E Euler's number}.
*
*
*
*
*
* @param x The number whose hyperbolic cosine is to be returned.
* @return The hyperbolic cosine of {@code x}.
* @since 1.5
*/
public static double cosh(double x) {
/* __ieee754_cosh(x)
* Method :
* mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
* 1. Replace x by |x| (cosh(x) = cosh(-x)).
* 2.
* [ exp(x) - 1 ]^2
* 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
* 2*exp(x)
*
* exp(x) + 1/exp(x)
* ln2/2 <= x <= 22 : cosh(x) := -------------------
* 2
* 22 <= x <= lnovft : cosh(x) := exp(x)/2
* lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
* ln2ovft < x : cosh(x) := huge*huge (overflow)
*
* Special cases:
* cosh(x) is |x| if x is +INF, -INF, or NaN.
* only cosh(0)=1 is exact for finite x.
*/
final long xb = Double.doubleToRawLongBits(x);
final int ix = ((int) (xb >> 32)) & 0x7fffffff;
/* x is INF or NaN */
if(ix>=0x7ff00000){
return x*x;
}
/* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
if (ix < 0x3fd62e43) {
final double t = expm1(abs(x));
final double w = one + t;
// for tiny arguments return 1.
return (ix < 0x3c800000) ? w : one + (t * t) / (w + w);
}
/* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
if (ix < 0x40360000) {
final double t = exp(abs(x));
return half * t + half / t;
}
/* |x| in [22, log(maxdouble)] return half*exp(|x|) */
if (ix < 0x40862e42) {
return half * exp(abs(x));
}
/* |x| in [log(maxdouble), overflowthresold] */
if (ix < 0x408633ce || (ix == 0x408633ce &&
(xb & 0x00000000ffffffffL) <= 0x8fb9f87dL)){
final double w = exp(half * abs(x));
return (half * w) * w;
}
/* |x| > overflowthresold, cosh(x) overflow */
return huge*huge;
}
/**
* Returns the hyperbolic tangent of a {@code double} value.
* The hyperbolic tangent of x is defined to be
* (ex - e-x)/(ex + e-x),
* in other words, {@linkplain Math#sinh
* sinh(x)}/{@linkplain Math#cosh cosh(x)}. Note
* that the absolute value of the exact tanh is always less than
* 1.
*
*
*
*
*
* @param x The number whose hyperbolic tangent is to be returned.
* @return The hyperbolic tangent of {@code x}.
* @since 1.5
*/
public static double tanh(double x) {
/* Tanh(x)
* Return the Hyperbolic Tangent of x
*
* Method :
* x -x
* e - e
* 0. tanh(x) is defined to be -----------
* x -x
* e + e
* 1. reduce x to non-negative by tanh(-x) = -tanh(x).
* 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
* -t
* 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
* t + 2
* 2
* 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
* t + 2
* 22.0 < x <= INF : tanh(x) := 1.
*
* Special cases:
* tanh(NaN) is NaN;
* only tanh(0)=0 is exact for finite argument.
*/
/* High word of |x|. */
final int hx = (int) (Double.doubleToRawLongBits(x) >> 32);
final int ix = hx & 0x7fffffff;
/* x is INF or NaN */
if (ix >= 0x7ff00000) {
return hx>=0 ?
one / x + one : /* tanh(+-inf)=+-1 */
one / x - one; /* tanh(NaN) = NaN */
}
double z;
/* |x| < 22 */
if (ix < 0x40360000) { /* |x|<22 */
if (ix < 0x3c800000) { /* |x|<2**-55 */
return x * (one + x); /* tanh(small) = small */
}
x = abs(x);
if (ix >= 0x3ff00000) { /* |x|>=1 */
z = one - two / (expm1(2.0d * x) + two);
} else {
double t = expm1(-two * x);
z = -t / (t + two);
}
/* |x| > 22, return +-1 */
} else {
z = one - tiny; /* raised inexact flag */
}
return hx >= 0 ? z : 0.0d - z;
}
private static final double TWOpow1022 = setHigh32bits(0x7fd00000);
private static final long
onebits = Double.doubleToLongBits(one),
clearHighmask = 0x00000000FFFFFFFFL,
onebitshigh = onebits&clearHighmask,
zerobitshigh = Double.doubleToLongBits(zero)&clearHighmask;
/**
* Returns sqrt(x2 +y2)
* without intermediate overflow or underflow.
*
*
*
*
*
* @param x a value
* @param y a value
* @return sqrt(x2 +y2)
* without intermediate overflow or underflow
* @since 1.5
*/
public static double hypot(double a, double b) {
/* __ieee754_hypot(x,y)
*
* Method :
* If (assume round-to-nearest) z=x*x+y*y
* has error less than sqrt(2)/2 ulp, than
* sqrt(z) has error less than 1 ulp (exercise).
*
* So, compute sqrt(x*x+y*y) with some care as
* follows to get the error below 1 ulp:
*
* Assume x>y>0;
* (if possible, set rounding to round-to-nearest)
* 1. if x > 2y use
* x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
* where x1 = x with lower 32 bits cleared, x2 = x-x1; else
* 2. if x <= 2y use
* t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
* where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
* y1= y with lower 32 bits chopped, y2 = y-y1.
*
* NOTE: scaling may be necessary if some argument is too
* large or too tiny
*
* Special cases:
* hypot(x,y) is INF if x or y is +INF or -INF; else
* hypot(x,y) is NAN if x or y is NAN.
*
* Accuracy:
* hypot(x,y) returns sqrt(x^2+y^2) with error less
* than 1 ulps (units in the last place)
*/
long hx = (Double.doubleToRawLongBits(a) >>> 32)&0x7fffffff;
long hy = (Double.doubleToRawLongBits(b) >>> 32)&0x7fffffff;
if(hy > hx) {
double at = a;
a=b;
b=at;
long j=hx;
hx=hy;
hy=j;
}
a= abs(a);
b= abs(b);
//a = setHigh32bits(a,hx);
// b = setHigh32bits(b,hy);
//System.err.println("a1 ");
if (hx - hy > 0x3c00000) {
return a + b;
} /* x/y > 2**60 */
//System.err.println("a2");
int k = 0;
if (hx > 0x5f300000) { /* a>2**500 */
// System.err.println("b1 "+hx +" >= "+ 0x7ff00000);
if (hx >= 0x7ff00000) { /* Inf or NaN */
// System.err.println("b2");
return Double.isInfinite(a) || Double.isInfinite(b) ?
Double.POSITIVE_INFINITY :
Double.NaN;
}
/* scale a and b by 2**-600 */
k = 600;
a = setHigh32bits(a, hx -= 0x25800000);
b = setHigh32bits(b, hy -= 0x25800000);
}
if (hy < 0x20b00000) { /* b < 2**-500 */
if (hy <= 0x000fffff) { /* subnormal b or 0 */
//if ((hy | (bbits&clearHighmask)) == 0) {
if ((hy | __LO(b)) == 0) {
return a;
}
b *= TWOpow1022;
a *= TWOpow1022;
k -= 1022;
} else { /* scale a and b by 2^600 */
k -= 600;
a = setHigh32bits(a, hx += 0x25800000); /* a *= 2^600 */
b = setHigh32bits(b, hy += 0x25800000); /* b *= 2^600 */
}
}
/* medium size a and b */
double w = a - b;
if (w > b) {
final double t1 = Double.longBitsToDouble(hx << 32);
w = t1*t1 - (b * -b - (a - t1) * (a + t1));
} else {
final double y1 = Double.longBitsToDouble(hy << 32);
final double t1 = Double.longBitsToDouble((hx+0x00100000) << 32);
w = t1*y1 - (w * -w - (t1*(b - y1) + b*((a+a)-t1)));
}
w = java.lang.StrictMath.sqrt(w);
return k!=0 ? w*setHhighbitsAddSome(onebits, (long)k << (20+32)) : w;
}
/* scaled coefficients related to expm1 */
private static final double
Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
/**
* Returns ex -1. Note that for values of
* x near 0, the exact sum of
* {@code expm1(x)} + 1 is much closer to the true
* result of ex than {@code exp(x)}.
*
*
*
*
* @param x the exponent to raise e to in the computation of
* e{@code x} -1.
* @return the value e{@code x} - 1.
* @since 1.5
*/
public static double expm1(double x) {
/* expm1(x)
* Returns exp(x)-1, the exponential of x minus 1.
*
* Method
* 1. Argument reduction:
* Given x, find r and integer k such that
*
* x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
*
* Here a correction term c will be computed to compensate
* the error in r when rounded to a floating-point number.
*
* 2. Approximating expm1(r) by a special rational function on
* the interval [0,0.34658]:
* Since
* r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
* we define R1(r*r) by
* r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
* That is,
* R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
* = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
* = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
* We use a special Reme algorithm on [0,0.347] to generate
* a polynomial of degree 5 in r*r to approximate R1. The
* maximum error of this polynomial approximation is bounded
* by 2**-61. In other words,
* R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
* where Q1 = -1.6666666666666567384E-2,
* Q2 = 3.9682539681370365873E-4,
* Q3 = -9.9206344733435987357E-6,
* Q4 = 2.5051361420808517002E-7,
* Q5 = -6.2843505682382617102E-9;
* (where z=r*r, and the values of Q1 to Q5 are listed below)
* with error bounded by
* | 5 | -61
* | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
* | |
*
* expm1(r) = exp(r)-1 is then computed by the following
* specific way which minimize the accumulation rounding error:
* 2 3
* r r [ 3 - (R1 + R1*r/2) ]
* expm1(r) = r + --- + --- * [--------------------]
* 2 2 [ 6 - r*(3 - R1*r/2) ]
*
* To compensate the error in the argument reduction, we use
* expm1(r+c) = expm1(r) + c + expm1(r)*c
* ~ expm1(r) + c + r*c
* Thus c+r*c will be added in as the correction terms for
* expm1(r+c). Now rearrange the term to avoid optimization
* screw up:
* ( 2 2 )
* ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
* expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
* ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
* ( )
*
* = r - E
* 3. Scale back to obtain expm1(x):
* From step 1, we have
* expm1(x) = either 2^k*[expm1(r)+1] - 1
* = or 2^k*[expm1(r) + (1-2^-k)]
* 4. Implementation notes:
* (A). To save one multiplication, we scale the coefficient Qi
* to Qi*2^i, and replace z by (x^2)/2.
* (B). To achieve maximum accuracy, we compute expm1(x) by
* (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
* (ii) if k=0, return r-E
* (iii) if k=-1, return 0.5*(r-E)-0.5
* (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
* else return 1.0+2.0*(r-E);
* (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
* (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
* (vii) return 2^k(1-((E+2^-k)-r))
*
* Special cases:
* expm1(INF) is INF, expm1(NaN) is NaN;
* expm1(-INF) is -1, and
* for finite argument, only expm1(0)=0 is exact.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Misc. info.
* For IEEE double
* if x > 7.09782712893383973096e+02 then expm1(x) overflow
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
long xb = Double.doubleToRawLongBits(x);
int hx = (int) (xb >> 32); /* high word of x UNSIGNED */
final boolean xsbzero = (hx & 0x80000000)==0; /* sign bit of x */
//double y = xsbzero ? x : 0.0d - x; /* y = |x| */
hx &= 0x7fffffff; /* high word of |x| */
/* filter out huge and non-finite argument */
if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */
if (hx >= 0x40862E42) { /* if |x|>=709.78... */
if (hx >= 0x7ff00000) {
return (((hx & 0xfffff) | (int)xb) != 0) ?
x + x : /* NaN */
xsbzero ? x : -1.0 ; /* exp(+-inf)={inf,-1} */
}
if (x > o_threshold) {
return huge*huge; /* overflow */
}
}
/* x < -56*ln2, return -1.0 with inexact */
if (!xsbzero && (x + tiny < 0.0) ) { /* raise inexact */
return tiny - one; /* return -1 */
}
}
double hi,lo,c=0;
int k = 0;
/* argument reduction */
if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
if (xsbzero) {
hi = x - ln2_hi;
lo = ln2_lo;
k = 1;
} else {
hi = x + ln2_hi;
lo = -ln2_lo;
k = -1;
}
} else {
// loss of precision here ?:
k = (int) (invln2 * x + (xsbzero ? 0.5 : - 0.5));
hi = x - k * ln2_hi; /* t*ln2_hi is exact here */
lo = k * ln2_lo;
}
x = hi - lo;
c = (hi - x) - lo;
} else if (hx < 0x3c900000) { /* when |x|<2**-54, return x */
/* return x with inexact flags when x!=0 */
return x - ((huge + x) - (huge + x));
}
/* x is now in primary range */
final double hfx = 0.5 * x;
final double hxs = x * hfx;
final double r1 = one + hxs * (Q1 + hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
final double t = 3.0 - r1 * hfx;
double e = hxs * ((r1 - t) / (6.0 - x * t));
if (k == 0) {
return x - (x * e - hxs); /* c is 0 */
}
e = (x * (e - c) - c) - hxs;
if (k == -1) {
return 0.5 * (x - e) - 0.5;
}
if (k == 1) {
return x < -0.25 ? -2.0 * (e - (x + 0.5)) : one + 2.0 * (x - e);
}
if (k <= -2 || k > 56) { /* suffice to return exp(x)-1 */
/* add k to y's exponent */
return setHhighbitsAddSome(one - (e - x), (long)k << (20+32)) - one;
}
final double y = k < 20 ? /* 1-2^-k */
setHigh32bitsDontMask(onebitshigh,0x3ff00000-(0x200000>>k))-(e-x) :
(x-(e+setHigh32bitsDontMask(onebitshigh,(0x3ff-k)<<20)))+one;//2^-k
/* add k to y's exponent */
return setHhighbitsAddSome(y, (long)k << (20+32));
}
private static final double
Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
/**
* Returns the natural logarithm of the sum of the argument and 1.
* Note that for small values {@code x}, the result of
* {@code log1p(x)} is much closer to the true result of ln(1
* + {@code x}) than the floating-point evaluation of
* {@code log(1.0+x)}.
*
*
*
*
*
* @param x a value
* @return the value ln({@code x} + 1), the natural
* log of {@code x} + 1
* @since 1.5
*/
public static double log1p(double x) {
/* double log1p(double x)
*
* Method :
* 1. Argument Reduction: find k and f such that
* 1+x = 2^k * (1+f),
* where sqrt(2)/2 < 1+f < sqrt(2) .
*
* Note. If k=0, then f=x is exact. However, if k!=0, then f
* may not be representable exactly. In that case, a correction
* term is need. Let u=1+x rounded. Let c = (1+x)-u, then
* log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
* and add back the correction term c/u.
* (Note: when x > 2**53, one can simply return log(x))
*
* 2. Approximation of log1p(f).
* Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
* = 2s + 2/3 s**3 + 2/5 s**5 + .....,
* = 2s + s*R
* We use a special Reme algorithm on [0,0.1716] to generate
* a polynomial of degree 14 to approximate R The maximum error
* of this polynomial approximation is bounded by 2**-58.45. In
* other words,
* 2 4 6 8 10 12 14
* R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s
* (the values of Lp1 to Lp7 are listed in the program)
* and
* | 2 14 | -58.45
* | Lp1*s +...+Lp7*s - R(z) | <= 2
* | |
* Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
* In order to guarantee error in log below 1ulp, we compute log
* by
* log1p(f) = f - (hfsq - s*(hfsq+R)).
*
* 3. Finally, log1p(x) = k*ln2 + log1p(f).
* = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
* Here ln2 is split into two floating point number:
* ln2_hi + ln2_lo,
* where n*ln2_hi is always exact for |n| < 2000.
*
* Special cases:
* log1p(x) is NaN with signal if x < -1 (including -INF) ;
* log1p(+INF) is +INF; log1p(-1) is -INF with signal;
* log1p(NaN) is that NaN with no signal.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*
* Note: Assuming log() return accurate answer, the following
* algorithm can be used to compute log1p(x) to within a few ULP:
*
* u = 1+x;
* if(u==1.0) return x ; else
* return log(u)*(x/(u-1.0));
*
* See HP-15C Advanced Functions Handbook, p.193.
*/
double f = 0 ;
int k=1, hu=0;
final int hx = __HI(x); /* high word of x */
final int ax = hx & 0x7fffffff;
if (hx < 0x3FDA827A) { /* x < 0.41422 */
if (ax >= 0x3ff00000) { /* x <= -1.0 */
return x == -1.0d ? -two54 / zero : /* log1p(-1)=-inf */
(x - x) / (x - x); /* log1p(x<-1)=NaN */
}
if (ax < 0x3e200000) { /* |x| < 2**-29 */
if (two54 + x > zero /* raise inexact */
&& ax < 0x3c900000) /* |x| < 2**-54 */ {
return x;
}
return x - x * x * 0.5;
}
if (hx > 0 || hx <= ((int) 0xbfd2bec3)) { /* -0.2929
*
* @param f a {@code float} value
* @since 1.6
*/
public static int getExponent(float f) {
return sun.misc.FpUtils.getExponent(f);
}
/**
* Returns the unbiased exponent used in the representation of a
* {@code double}. Special cases:
*
*
*
* @param d a {@code double} value
* @since 1.6
*/
public static int getExponent(double d) {
return sun.misc.FpUtils.getExponent(d);
}
/**
* Returns the floating-point number adjacent to the first
* argument in the direction of the second argument. If both
* arguments compare as equal the second argument is returned.
*
*
*
*
* @param start starting floating-point value
* @param direction value indicating which of
* {@code start}'s neighbors or {@code start} should
* be returned
* @return The floating-point number adjacent to {@code start} in the
* direction of {@code direction}.
* @since 1.6
*/
public static double nextAfter(double start, double direction) {
return sun.misc.FpUtils.nextAfter(start, direction);
}
/**
* Returns the floating-point number adjacent to the first
* argument in the direction of the second argument. If both
* arguments compare as equal a value equivalent to the second argument
* is returned.
*
*
*
*
* @param start starting floating-point value
* @param direction value indicating which of
* {@code start}'s neighbors or {@code start} should
* be returned
* @return The floating-point number adjacent to {@code start} in the
* direction of {@code direction}.
* @since 1.6
*/
public static float nextAfter(float start, double direction) {
return sun.misc.FpUtils.nextAfter(start, direction);
}
/**
* Returns the floating-point value adjacent to {@code d} in
* the direction of positive infinity. This method is
* semantically equivalent to {@code nextAfter(d,
* Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
* implementation may run faster than its equivalent
* {@code nextAfter} call.
*
*
*
*
* @param d starting floating-point value
* @return The adjacent floating-point value closer to positive
* infinity.
* @since 1.6
*/
public static double nextUp(double d) {
return sun.misc.FpUtils.nextUp(d);
}
/**
* Returns the floating-point value adjacent to {@code f} in
* the direction of positive infinity. This method is
* semantically equivalent to {@code nextAfter(f,
* Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
* implementation may run faster than its equivalent
* {@code nextAfter} call.
*
*
*
*
* @param f starting floating-point value
* @return The adjacent floating-point value closer to positive
* infinity.
* @since 1.6
*/
public static float nextUp(float f) {
return sun.misc.FpUtils.nextUp(f);
}
/**
* Return {@code d} ×
* 2{@code scaleFactor} rounded as if performed
* by a single correctly rounded floating-point multiply to a
* member of the double value set. See the Java
* Language Specification for a discussion of floating-point
* value sets. If the exponent of the result is between {@link
* Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
* answer is calculated exactly. If the exponent of the result
* would be larger than {@code Double.MAX_EXPONENT}, an
* infinity is returned. Note that if the result is subnormal,
* precision may be lost; that is, when {@code scalb(x, n)}
* is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
* x. When the result is non-NaN, the result has the same
* sign as {@code d}.
*
*
*
*
* @param d number to be scaled by a power of two.
* @param scaleFactor power of 2 used to scale {@code d}
* @return {@code d} × 2{@code scaleFactor}
* @since 1.6
*/
public static double scalb(double d, int scaleFactor) {
return sun.misc.FpUtils.scalb(d, scaleFactor);
}
/**
* Return {@code f} ×
* 2{@code scaleFactor} rounded as if performed
* by a single correctly rounded floating-point multiply to a
* member of the float value set. See the Java
* Language Specification for a discussion of floating-point
* value sets. If the exponent of the result is between {@link
* Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
* answer is calculated exactly. If the exponent of the result
* would be larger than {@code Float.MAX_EXPONENT}, an
* infinity is returned. Note that if the result is subnormal,
* precision may be lost; that is, when {@code scalb(x, n)}
* is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
* x. When the result is non-NaN, the result has the same
* sign as {@code f}.
*
*
*
*
* @param f number to be scaled by a power of two.
* @param scaleFactor power of 2 used to scale {@code f}
* @return {@code f} × 2{@code scaleFactor}
* @since 1.6
*/
public static float scalb(float f, int scaleFactor) {
return sun.misc.FpUtils.scalb(f, scaleFactor);
}
public static double setHhighbitsAddSome(double x, long highadd) {
return setHhighbitsAddSome(Double.doubleToRawLongBits(x), highadd);
}
public static double setHhighbitsORSome(double x, long highOR) {
return Double.longBitsToDouble(
Double.doubleToRawLongBits(x) | (highOR<<32) );
}
public static double setHhighbitsAddSome(long xl, long highadd) {
return Double.longBitsToDouble((xl&clearHighmask)|(xl + highadd));
}
private static int __HI(double x) {
return (int) (Double.doubleToRawLongBits(x) >> 32);
}
private static int __LO(double x) {
return (int) Double.doubleToRawLongBits(x);
}
private static double clearLow32bits(double x){
return Double.longBitsToDouble(
Double.doubleToRawLongBits(x) & 0xFFFFFFFF00000000L);
}
private static double setHigh32bits(double x, long newhigh) {
return setHigh32bits(Double.doubleToRawLongBits(x), newhigh);
}
private static double setHigh32bitsXOR(double x, long toXor) {
return Double.longBitsToDouble((Double.doubleToRawLongBits(x))^toXor);
}
private static double addToHighBits(double x, long toadd) {
return addToHighBits(Double.doubleToRawLongBits(x), toadd);
}
private static double addToHighBits(long x, long toadd) {
return Double.longBitsToDouble(
(x&clearHighmask) | (((x>>32) + toadd)<<32) );
}
private static double setHigh32bits(long x, long newhigh) {
return Double.longBitsToDouble(
(x&clearHighmask) | (newhigh << 32));
}
private static double setHigh32bitsDontMask(long x, long newhigh) {
return Double.longBitsToDouble(x | (newhigh << 32));
}
private static double setHigh32bits(long newhigh) {
return Double.longBitsToDouble((newhigh << 32));
}
}