/* * @(#)StrictMath.java 1.26 04/06/14 * * Copyright 2004 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 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 * netlib as the package "Freely Distributable Math * Library," 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 * fdlibm version 5.3. Where fdlibm provides * more than one definition for a function (such as * acos), use the "IEEE 754 core function" version * (residing in a file whose name begins with the letter * e). The methods which require fdlibm * semantics are sin, cos, tan, * asin, acos, atan, * exp, log, log10, * cbrt, atan2, pow, * sinh, cosh, tanh, * hypot, expm1, and log1p. * * @author unascribed * @author Joseph D. Darcy * @version 1.26, 06/14/04 * @since 1.3 */ public final class StrictMath { /** * Don't let anyone instantiate this class. */ private StrictMath() {} /** * The double value that is closer than any other to * e, the base of the natural logarithms. */ public static final double E = 2.7182818284590452354; /** * The 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: *

* * @param a an angle, in radians. * @return the sine of the argument. */ public static native double sin(double a); /** * Returns the trigonometric cosine of an angle. Special cases: * * * @param a an angle, in radians. * @return the cosine of the argument. */ public static native double cos(double a); /** * Returns the trigonometric tangent of an angle. Special cases: * * * @param a an angle, in radians. * @return the tangent of the argument. */ public static native double tan(double a); /** * Returns the arc sine of an angle, in the range of -pi/2 through * pi/2. Special cases: * * * @param a the value whose arc sine is to be returned. * @return the arc sine of the argument. */ public static native double asin(double a); /** * Returns the arc cosine of an angle, in the range of 0.0 through * pi. Special case: * * * @param a the value whose arc cosine is to be returned. * @return the arc cosine of the argument. */ public static native double acos(double a); /** * Returns the arc tangent of an angle, in the range of -pi/2 * through pi/2. Special cases: * * * @param a the value whose arc tangent is to be returned. * @return the arc tangent of the argument. */ public static native double atan(double a); /** * Converts an angle measured in degrees to an approximately * equivalent angle measured in radians. The conversion from * degrees to radians is generally inexact. * * @param angdeg an angle, in degrees * @return the measurement of the angle angdeg * in radians. */ public static strictfp double toRadians(double angdeg) { return angdeg / 180.0 * PI; } /** * Converts an angle measured in radians to an approximately * equivalent angle measured in degrees. The conversion from * radians to degrees is generally inexact; users should * not expect cos(toRadians(90.0)) to exactly * equal 0.0. * * @param angrad an angle, in radians * @return the measurement of the angle angrad * in degrees. */ public static strictfp double toDegrees(double angrad) { return angrad * 180.0 / PI; } /** * Returns Euler's number e raised to the power of a * double value. Special cases: * * * @param a the exponent to raise e to. * @return the value ea, * where e is the base of the natural logarithms. */ public static native double exp(double a); /** * Returns the natural logarithm (base e) of a double * value. Special cases: * * * @param a a value * @return the value ln a, the natural logarithm of * a. */ public static native double log(double a); /** * Returns the base 10 logarithm of a double value. * Special cases: * * * * @param a a value * @return the base 10 logarithm of a. * @since 1.5 */ public static native double log10(double a); /** * Returns the correctly rounded positive square root of a * double value. * Special cases: * * Otherwise, the result is the double value closest to * the true mathematical square root of the argument value. * * @param a a value. * @return the positive square root of a. */ public static native double sqrt(double a); /** * Returns the cube root of a double value. For * positive finite x, cbrt(-x) == * -cbrt(x); that is, the cube root of a negative value is * the negative of the cube root of that value's magnitude. * Special cases: * * * * @param a a value. * @return the cube root of a. * @since 1.5 */ public static native double cbrt(double a); /** * Computes the remainder operation on two arguments as prescribed * by the IEEE 754 standard. * The remainder value is mathematically equal to * f1 - f2 × n, * where n is the mathematical integer closest to the exact * mathematical value of the quotient f1/f2, and if two * mathematical integers are equally close to 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: * * * @param f1 the dividend. * @param f2 the divisor. * @return the remainder when f1 is divided by * f2. */ public static native double IEEEremainder(double f1, double f2); /** * Returns the smallest (closest to negative infinity) * double value that is greater than or equal to the * argument and is equal to a mathematical integer. Special cases: * Note * that the value of StrictMath.ceil(x) is exactly the * value of -StrictMath.floor(-x). * * @param a a value. * @return the smallest (closest to negative infinity) * floating-point value that is greater than or equal to * the argument and is equal to a mathematical integer. */ public static native double ceil(double a); /** * Returns the largest (closest to positive infinity) * double value that is less than or equal to the * argument and is equal to a mathematical integer. Special cases: * * * @param a a value. * @return the largest (closest to positive infinity) * floating-point value that less than or equal to the argument * and is equal to a mathematical integer. */ public static native double floor(double a); /** * Returns the double value that is closest in value * to the argument and is equal to a mathematical integer. If two * double values that are mathematical integers are * equally close to the value of the argument, the result is the * integer value that is even. Special cases: * * * @param a a value. * @return the closest floating-point value to a that is * equal to a mathematical integer. * @author Joseph D. Darcy */ public static double rint(double a) { /* * If the absolute value of a is not less than 2^52, it * is either a finite integer (the double format does not have * enough significand bits for a number that large to have any * fractional portion), an infinity, or a NaN. In any of * these cases, rint of the argument is the argument. * * Otherwise, the sum (twoToThe52 + a ) will properly round * away any fractional portion of a since ulp(twoToThe52) == * 1.0; subtracting out twoToThe52 from this sum will then be * exact and leave the rounded integer portion of a. * * This method does *not* need to be declared strictfp to get * fully reproducible results. Whether or not a method is * declared strictfp can only make a difference in the * returned result if some operation would overflow or * underflow with strictfp semantics. The operation * (twoToThe52 + a ) cannot overflow since large values of a * are screened out; the add cannot underflow since twoToThe52 * is too large. The subtraction ((twoToThe52 + a ) - * twoToThe52) will be exact as discussed above and thus * cannot overflow or meaningfully underflow. Finally, the * last multiply in the return statement is by plus or minus * 1.0, which is exact too. */ double twoToThe52 = (double)(1L << 52); // 2^52 double sign = FpUtils.rawCopySign(1.0, a); // preserve sign info a = Math.abs(a); if (a < twoToThe52) { // E_min <= ilogb(a) <= 51 a = ((twoToThe52 + a ) - twoToThe52); } return sign * a; // restore original sign } /** * Converts rectangular coordinates (xy) * to polar (r, theta). * This method computes the phase theta by computing an arc tangent * of y/x in the range of -pi to pi. Special * cases: * * * @param y the ordinate coordinate * @param x the abscissa coordinate * @return the theta component of the point * (rtheta) * in polar coordinates that corresponds to the point * (xy) in Cartesian coordinates. */ public static native double atan2(double y, double x); /** * Returns the value of the first argument raised to the power of the * second 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 ab. */ public static native double pow(double a, double b); /** * Returns the closest int 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 int. * In other words, the result is equal to the value of the expression: *

(int)Math.floor(a + 0.5f)
*

* Special cases: *

* * @param a a floating-point value to be rounded to an integer. * @return the value of the argument rounded to the nearest * 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 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 long. In other * words, the result is equal to the value of the expression: *

(long)Math.floor(a + 0.5d)
*

* Special cases: *

* * @param a a floating-point value to be rounded to a * long. * @return the value of the argument rounded to the nearest * 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 double value with a positive sign, greater * than or equal to 0.0 and less than 1.0. * Returned values are chosen pseudorandomly with (approximately) * uniform distribution from that range. * *

When this method is first called, it creates a single new * pseudorandom-number generator, exactly as if by the expression *

new java.util.Random
This * new pseudorandom-number generator is used thereafter for all * calls to this method and is used nowhere else. * *

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 double greater than or equal * to 0.0 and less than 1.0. * @see java.util.Random#nextDouble() */ public static double random() { if (randomNumberGenerator == null) initRNG(); return randomNumberGenerator.nextDouble(); } /** * Returns the absolute value of an 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 * Integer.MIN_VALUE, the most negative representable * 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. * @see java.lang.Integer#MIN_VALUE */ public static int abs(int a) { return (a < 0) ? -a : a; } /** * Returns the absolute value of a 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 * Long.MIN_VALUE, the most negative representable * 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. * @see java.lang.Long#MIN_VALUE */ public static long abs(long a) { return (a < 0) ? -a : a; } /** * Returns the absolute value of a 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: *

* In other words, the result is the same as the value of the expression: *

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 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: * * In other words, the result is the same as the value of the expression: *

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 int values. That is, the * result is the argument closer to the value of * 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 a and b. * @see java.lang.Long#MAX_VALUE */ public static int max(int a, int b) { return (a >= b) ? a : b; } /** * Returns the greater of two long values. That is, the * result is the argument closer to the value of * 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 a and b. * @see java.lang.Long#MAX_VALUE */ public static long max(long a, long b) { return (a >= b) ? a : b; } private static long negativeZeroFloatBits = Float.floatToIntBits(-0.0f); private static long negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d); /** * Returns the greater of two 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 a and 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 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 a and 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 int values. That is, * the result the argument closer to the value of * 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 a and b. * @see java.lang.Long#MIN_VALUE */ public static int min(int a, int b) { return (a <= b) ? a : b; } /** * Returns the smaller of two long values. That is, * the result is the argument closer to the value of * 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 a and b. * @see java.lang.Long#MIN_VALUE */ public static long min(long a, long b) { return (a <= b) ? a : b; } /** * Returns the smaller of two 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 a and 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 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 a and 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 * double value is the positive distance between this * floating-point value and the double value next * larger in magnitude. Note that for non-NaN x, * ulp(-x) == ulp(x). * *

Special Cases: *

* * @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 * float value is the positive distance between this * floating-point value and the float value next * larger in magnitude. Note that for non-NaN x, * ulp(-x) == ulp(x). * *

Special Cases: *

* * @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. * *

Special Cases: *

* * @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. * *

Special Cases: *

* * @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); } /** * Returns the hyperbolic sine of a double value. * The hyperbolic sine of x is defined to be * (ex - e-x)/2 * where e is {@linkplain Math#E Euler's number}. * *

Special cases: *

* * @param x The number whose hyperbolic sine is to be returned. * @return The hyperbolic sine of x. * @since 1.5 */ public static native double sinh(double x); /** * Returns the hyperbolic cosine of a double value. * The hyperbolic cosine of x is defined to be * (ex + e-x)/2 * where e is {@linkplain Math#E Euler's number}. * *

Special cases: *

* * @param x The number whose hyperbolic cosine is to be returned. * @return The hyperbolic cosine of x. * @since 1.5 */ public static native double cosh(double x); /** * Returns the hyperbolic tangent of a 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. * *

Special cases: *

* * @param x The number whose hyperbolic tangent is to be returned. * @return The hyperbolic tangent of x. * @since 1.5 */ public static native double tanh(double x); /** * Returns sqrt(x2 +y2) * without intermediate overflow or underflow. * *

Special cases: *

* * @param x a value * @param y a value * @return sqrt(x2 +y2) * without intermediate overflow or underflow * @since 1.5 */ public static native double hypot(double x, double y); /** * Returns ex -1. Note that for values of * x near 0, the exact sum of * expm1(x) + 1 is much closer to the true * result of ex than exp(x). * *

Special cases: *

* * @param x the exponent to raise e to in the computation of * ex -1. * @return the value ex - 1. */ public static native double expm1(double x); /** * Returns the natural logarithm of the sum of the argument and 1. * Note that for small values x, the result of * log1p(x) is much closer to the true result of ln(1 * + x) than the floating-point evaluation of * log(1.0+x). * *

Special cases: * *

* * @param x a value * @return the value ln(x + 1), the natural * log of x + 1 */ public static native double log1p(double x); }