Math and Strict Math

Table 6-1. Math Methods

Method

Description double abs(double d)

float abs(float f)

int abs(int i) long abs(long l) double acos(double d)

double asin(double d)

double atan(double d)

double ceil(double d)

double cos(double d)

double exp(double d)

Return the absolute value of d. There are four special cases: abs(-0.0) = +0.0, abs(+infinity) = +infinity, abs(-infinity) = +infinity, and abs(NaN) = NaN.

Return the absolute value of f. There are four special cases: abs(-0.0) = +0.0, abs(+infinity) = +infinity, abs(-infinity) = +infinity, and abs(NaN) = NaN.

Return the absolute value of i. There is one special case: the absolute value of Integer.MIN_VALUE is Integer.MIN_VALUE.

Return the absolute value of l. There is one special case: the absolute value of Long.MIN_VALUE is Long.MIN_VALUE.

Return angle d's arc cosine within the range 0 through PI. There are three special cases: acos(anything > 1) = NaN, acos(anything < -1) = NaN, and acos(NaN) = NaN.

Return angle d's arc sine within the range -PI/2 through PI/2. There are three special cases: asin(anything > 1) = NaN, asin(anything < -1) = NaN, and asin(NaN) = NaN.

Return angle d's arc tangent within the range -PI/2 through PI/2. There are five special cases: atan(+0.0) = +0.0, atan(-0.0) = -0.0, atan(+infinity) = +PI/2,atan(-infinity) = -PI/2, and atan(NaN) = NaN.

Return the smallest value (closest to negative infinity) that is not less than d and is equal to an integer. There are six special cases: ceil(+0.0) = +0.0, ceil(-0.0) = -0.0,ceil(anything > -1.0 and < 0.0) = -0.0, ceil(+infinity) = +infinity, ceil(-infinity) = -infinity, and ceil(NaN) = NaN.

Return the cosine of angle d (expressed in radians). There are three special cases: cos(+infinity) = NaN, cos(-infinity) = NaN, and cos(NaN) = NaN.

Return Euler's number e raised to the power d. There are three special cases: exp(+infinity) = +infinity, exp(-infinity) = +0.0, and exp(NaN) = NaN.

double floor(double d) Return the largest value (closest to positive infinity) that is not greater than d and is equal to an integer. There are five special cases: floor(+0.0) = +0.0, floor(-0.0) = -0.0, floor(+infinity) = +infinity, floor(-infinity) = -infinity, and floor(NaN) = NaN.

Method

Description double log(double d)

double log10(double d)

double max(double d1, double d2)

float max(double f1, double f2)

long max(long l1, long l2)

double min(double d1, double d2)

float min(float f1, float f2)

Return the natural logarithm (base e) of d. There are six special cases: log(+0.0) = -infinity, log(-0.0) = -infinity, log(anything < 0) = NaN, log(+infinity) = +infinity, log(-infinity) = NaN, and log(NaN) = NaN.

Return the base 10 logarithm of d. There are six special cases: log10(+0.0) = -infinity, log10(-0.0) = -infinity, log10(anything < 0) = NaN, log10(+infinity) = +infinity, log10(-infinity) = NaN, and log10(NaN) = NaN.

Return the most positive (closest to positive infinity) of d1 and d2. There are four special cases: max(NaN, anything) = NaN, max(anything, NaN) = NaN, max(+0.0, -0.0) = +0.0, and max(-0.0, +0.0) = +0.0.

Return the most positive (closest to positive infinity) of f1 and f2. There are four special cases: max(NaN, anything) = NaN, max(anything, NaN) = NaN, max(+0.0, -0.0) = +0.0, and max(-0.0, +0.0) = +0.0.

Return the most positive (closest to positive infinity) of i1 and i2.

Return the most positive (closest to positive infinity) of l1 and l2.

Return the most negative (closest to negative infinity) of d1 and d2. There are four special cases: min(NaN, anything) = NaN, min(anything, NaN) = NaN, min(+0.0, -0.0) = -0.0, and min(-0.0, +0.0) = -0.0.

Return the most negative (closest to negative infinity) of f1 and f2. There are four special cases: min(NaN, anything) = NaN, min(anything, NaN) = NaN, min(+0.0, -0.0) = -0.0, and min(-0.0, +0.0) = -0.0.

Return the most negative (closest to negative infinity) of i1 and i2.

long min(long l1, long l2)

Return the most negative (closest to negative infinity) of l1 and l2.

double random()

long round(double d)

Return a pseudorandom number between 0.0 (inclusive) and 1.0 (exclusive).

Return the result of rounding d to a long integer. The result is equivalent to (long) Math.floor(d+0.5). There are seven special cases: round(+0.0) = +0.0, round(-0.0) = +0.0, round(anything > Long.MAX_VALUE) = Long.MAX_VALUE, round(anything < Long.MIN_VALUE) = Long.MIN_VALUE,

Method

Description int round(float f)

double signum(double d)

float signum(float f)

double sin(double d)

round(+infinity) = Long.MAX_VALUE, round(-infinity) = Long.MIN_VALUE, and round(NaN) = +0.0.

Return the result of rounding f to an integer. The result is equivalent to (int) Math.floor(f+0.5). There are seven special cases: round(+0.0) = +0.0, round(-0.0) = +0.0, round(anything > Integer.MAX_VALUE) = Integer.MAX_VALUE, round(anything < Integer.MIN_VALUE) = Integer.MIN_VALUE, round(+infinity) = Integer.MAX_VALUE,round(-infinity) = Integer.MIN_VALUE, and round(NaN) = +0.0.

Return the sign of d as -1.0 (d less than 0.0), 0.0 (d equals 0.0), and 1.0 (d greater than 0.0). There are five special cases: signum(+0.0) = +0.0, signum(-0.0) = -0.0, signum(+infinity) = +1.0, signum(-infinity) = -1.0, and signum(NaN) = NaN.

Return the sign of f as -1.0 (f less than 0.0), 0.0 (f equals 0.0), and 1.0 (f greater than 0.0). There are five special cases: signum(+0.0) = +0.0, signum(-0.0) = -0.0, signum(+infinity) = +1.0, signum(-infinity) = -1.0, and signum(NaN) = NaN.

Return the sine of angle d (expressed in radians). There are five special cases: sin(+0.0) = +0.0, sin(-0.0) = -0.0, sin(+infinity) = NaN, sin(-infinity) = NaN, and sin(NaN) = NaN.

double sqrt(double d)

double tan(double d)

Return the square root of d. There are five special cases: sqrt(+0.0) = +0.0, sqrt(-0.0) = -0.0, sqrt(anything < 0) = NaN, sqrt(+infinity) = +infinity, and sqrt(NaN) = NaN.

Return the tangent of angle d (expressed in radians). There are five special cases: tan(+0.0) = +0.0, tan(-0.0) = -0.0, tan(+infinity) = NaN, tan(-infinity) = NaN, and tan(NaN) = NaN.

double toDegrees (double angrad)

double toRadians (angdeg)

Convert angle angrad from radians to degrees via expression angrad*180/PI. There are five special cases: toDegrees(+0.0) +0.0, toDegrees(-0.0) = -0.0, toDegrees(+infinity) = +infinity, toDegrees(-infinity) = -infinity, and toDegrees(NaN) = NaN.

Convert angle angdeg from degrees to radians via expression angdeg/180*PI. There are five special cases: toRadians(+0.0) +0.0,toRadians(-0.0) = -0.0,toRadians(+infinity) = +infinity, toRadians(-infinity) = -infinity, and toRadians(NaN) = NaN.

Table 6-1 reveals a wide variety of useful math-oriented methods. For example, each abs() method returns its argument's absolute value (number without regard for sign).

abs(double) and abs(float) are useful for comparing double precision floating-point and floating-point values safely. For example, 0.3 == 0.1+0.1+0.1 evaluates to false because 0.1 has no exact representation. However, you can compare these expressions with abs() and a tolerance value, which indicates an acceptable range of error. For example, Math.abs(0.3-(0.1+0.1+0.1)) < 0.1 returns true because the absolute difference between 0.3 and 0.1+0.1+0.1 is less than a 0.1 tolerance value.

Previous chapters demonstrated other Math methods. For example, Chapter 2 demonstrated Math's sin(), toRadians(), cos(), round(double), and random() methods.

As Chapter 5's Lotto649 application revealed, random() (which returns a number that appears to be randomly chosen but is actually chosen by a predictable math calculation, and hence is pseudorandom) is useful in simulations, games, and wherever an element of chance is needed, but first its return value (0.0 to almost 1.0) must somehow be transformed into a more useful range, perhaps 0 through 49, or maybe -100 through 100. You will find Listing 6-1's rnd() method useful for making these transformations.

Listing 6-1. Converting random()'s return value Into something more useful public static int rnd(int limit) {

rnd() transforms random()'s 0.0 to almost 1.0 double precision floating-point range to a 0 through limit - 1 integer range. For example, rnd(50) returns an integer ranging from 0 through 49. Also, -100+rnd(201) transforms 0.0 to almost 1.0 into -100 through 100 by adding a suitable offset and passing an appropriate limit value.

CAUTION: Do not specify (int) Math.random()*limit because this expression always evaluates to 0. The expression first casts random()'s double precision floating-point fractional value (0.0 through 0.99999. . .) to integer 0 by truncating the fractional part, and then multiplies 0 by limit, which results in 0.

Table 6-1 also reveals some curiosities beginning with +infinity, -infinity, +0.0, -0.0, and NaN (Not a Number).

Java's floating-point calculations are capable of returning +infinity, -infinity, +0.0, -0.0, and NaN because Java largely conforms to IEEE 754

(http://en.wikipedia.org/wiki/IEEE_754), a standard for floating-point calculations. The following are the circumstances under which these special values arise:

■ +infinity returns from attempting to divide a positive number by 0.0. For example, System.out.println(1.0/0.0); outputs Infinity.

■ -infinity returns from attempting to divide a negative number by 0.0. For example, System.out.println(-1.0/0.0); outputs -Infinity.

■ NaN returns from attempting to divide 0.0 by 0.0, attempting to calculate the square root of a negative number, and attempting other strange operations. For example, System.out.println(0.0/0.0); and System.out.println(Math.sqrt(-1.0)); each output NaN.

■ +0.0 results from attempting to divide a positive number by +infinity. For example, System.out.println(1.0/(1.0/0.0)); outputs +0.0.

■ -0.0 results from attempting to divide a negative number by +infinity. For example, System.out.println(-1.0/(1.0/0.0)); outputs -0.0.

Once an operation yields +infinity, -infinity, or NaN, the rest of the expression usually equals that special value. For example, System.out.println(1.0/0.0*20.0); outputs Infinity. Also, an expression that first yields +infinity or -infinity might devolve into NaN. For example, 1.0/0.0*0.0 yields +infinity (1.0/0.0) and then NaN (+infinity*0.0).

Another curiosity is Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, and Long.MIN_VALUE. Each of these items is a primitive wrapper class constant that identifies the maximum or minimum value that can be represented by the class's associated primitive type.

Finally, you might wonder why the abs(), max(), and min() overloaded methods do not include byte and short versions, as in byte abs(byte b) and short abs(short s). There is no need for these methods because the limited ranges of bytes and short integers make them unsuitable in calculations. If you need such a method, check out Listing 6-2.

Listing 6-2. Overloaded byte abs(byte b) and short abs(short s) methods public static byte abs(byte b) {

public static short abs(short s) {

public static void main(String[] args) {

System.out.println(abs(b)); // Output: 2 short s = -3;

The (byte) and (short) casts are necessary because -b converts b's value from a byte to an int, and -s converts s's value from a short to an int. In contrast, these casts are not needed with (b < 0) and (s < 0), which automatically cast b's and s's values to an int before comparing them with int-based 0.

TIP: Their absence from Math suggests that byte and short are not very useful in method declarations. However, these types are useful when declaring arrays whose elements store small values (such as a binary file's byte values). If you declared an array of int or long to store such values, you would end up wasting heap space (and might even run out of memory).

While searching through the Java documentation for the java.lang package, you will probably encounter a class named StrictMath. Apart from a longer name, this class appears to be identical to Math. The differences between these classes can be summed up as follows:

■ StrictMath's methods return exactly the same results on all platforms. In contrast, some of Math's methods might return values that vary ever so slightly from platform to platform.

■ Because StrictMath cannot utilize platform-specific features such as an extended-precision math coprocessor, an implementation of StrictMath might be less efficient than an implementation of Math.

For the most part, Math's methods call their StrictMath counterparts. Two exceptions are toDegrees() and toRadians(). Although these methods have identical code bodies in both classes, StrictMath's implementations include reserved word strictfp in the method headers:

public static strictfp double toDegrees(double angrad) public static strictfp double toRadians(double angdeg)

Wikipedia's "strictfp" entry (http://en.wikipedia.org/wiki/Strictfp) mentions that strictfp restricts floating-point calculations to ensure portability. This reserved word accomplishes portability in the context of intermediate floating-point representations and overflows/underflows (generating a value too large or small to fit a representation).

NOTE: The previously cited "strictfp" article states that Math contains public static strictfp double abs(double); and other strictfp methods. If you check out this class's source code under Java version 6 update 16, you will not find strictfp anywhere in the source code. However, many Math methods (such as sin()) call their StrictMath counterparts, which are implemented in a platform-specific library, and the library's method implementations are strict.

Without strictfp, an intermediate calculation is not limited to the IEEE 754 32-bit and 64-bit floating-point representations that Java supports. Instead, the calculation can take advantage of a larger representation (perhaps 128 bits) on a platform that supports this representation.

An intermediate calculation that overflows/underflows when its value is represented in 32/64 bits might not overflow/underflow when its value is represented in more bits.

Because of this discrepancy, portability is compromised. strictfp levels the playing field by requiring all platforms to use 32/64 bits for intermediate calculations.

When applied to a method, strictfp ensures that all floating-point calculations performed in that method are in strict compliance. However, strictfp can be used in a class header declaration (as in public strictfp class FourierTransform) to ensure that all floating-point calculations performed in that class are strict.

NOTE: Math and StrictMath are declared final so that they cannot be extended. Also, they declare private empty noargument constructors so that they cannot be instantiated.

Math and StrictMath are examples of utility classes because they exist as placeholders for utility constants and utility (static) methods.

Was this article helpful?

0 0

Responses

  • kedija kidane
    How to call math.abs in android?
    3 years ago

Post a comment