# Math Utilities

Java supports integer and floating-point arithmetic directly. Higher-level math operations are supported through the `java.lang.Math` class. Java provides wrapper classes for all primitive data types, so you can treat them as objects if necessary. Java also provides the `java.util.Random` class for generating random numbers.

Java handles errors in integer arithmetic by throwing an `ArithmeticException`:

```int zero = 0;

try {
int i = 72 / zero;
}
catch ( ArithmeticException e ) {
// division by zero
}```

To generate the error in this example, we created the intermediate variable `zero`. The compiler is somewhat crafty and would have caught us if we had blatantly tried to perform a division by a literal zero.

Floating-point arithmetic expressions, on the other hand, don’t throw exceptions. Instead, they take on the special out-of-range values shown in Table 9.3.

Table 9-3. Special Floating-Point Values

Value

Mathematical Representation

`POSITIVE_INFINITY`

1.0/0.0

`NEGATIVE_INFINITY`

-1.0/0.0

`NaN`

0.0/0.0

The following example generates an infinite result:

```double zero = 0.0;
double d = 1.0/zero;

if ( d == Double.POSITIVE_INFINITY )
System.out.println( "Division by zero" );```

The special value `NaN` indicates the result is “not a number.” The value `NaN` has the special distinction of not being equal to itself (`NaN != NaN` evaluates to `true`). Use `Float.isNaN( )` or `Double.isNaN( )` to test for `NaN`.

## The java.lang.Math Class

The `java.lang.Math` class provides Java’s math library. All its methods are static and used directly; you don’t have to (and you can’t) instantiate a `Math` object. We use this kind of degenerate class when we really want methods to approximate standard C-like functions. While this tactic defies the principles of object-oriented design, it makes sense in this case, as it provides a means of grouping some related utility functions in a single class. Table 9.4 summarizes the methods in `java.lang.Math`.

Table 9-4. Methods in java.lang.Math

Method

Argument Type(s)

Functionality

`Math.abs(a)`

`int`, `long`, `float`, `double`

Absolute value

`Math.acos(a)`

`double`

Arc cosine

`Math.asin(a)`

`double`

Arc sine

`Math.atan(a)`

`double`

Arc tangent

`Math.atan2(a,b)`

`double`

Angle part of rectangular-to-polar coordinate transform

`Math.ceil(a)`

`double`

Smallest whole number greater than orequal to `a`

`Math.cos(a)`

`double`

Cosine

`Math.exp(a)`

`double`

`Math.E` to the power `a`

`Math.floor(a)`

`double`

Largest whole number less than or equal to `a`

`Math.log(a)`

`double`

Natural logarithm of `a`

`Math.max(a, b)`

`int`, `long`, `float`, `double`

Maximum

`Math.min(a, b)`

`int`, `long`, `float`, `double`

Minimum

`Math.pow(a, b)`

`double`

`a` to the power `b`

`Math.random( )`

None

Random-number generator

`Math.rint(a)`

`double`

Converts double value to integral value in double format

`Math.round(a)`

`float`, `double`

Rounds to whole number

`Math.sin(a)`

`double`

Sine

`Math.sqrt(a)`

`double`

Square root

`Math.tan(a)`

`double`

Tangent

`log()`, `pow()`, and `sqrt()` can throw an `ArithmeticException`. `abs()`, `max( )`, and `min( )` are overloaded for all the scalar values, `int`, `long`, `float`, or `double`, and return the corresponding type. Versions of `Math.round( )` accept either `float` or `double` and return `int` or `long`, respectively. The rest of the methods operate on and return `double` values:

```double irrational = Math.sqrt( 2.0 );
int bigger = Math.max( 3, 4 );
long one = Math.round( 1.125798 );```

For convenience, `Math` also contains the static final double values `E` and `PI` :

`double circumference = diameter * Math.PI;`

## The java.math Class

If a `long` or a `double` just isn’t big enough for you, the `java.math` package provides two classes, `BigInteger` and `BigDecimal`, that support arbitrary-precision numbers. These are full-featured classes with a bevy of methods for performing arbitrary-precision math. In the following example, we use `BigDecimal` to add two numbers:

```try {
BigDecimal twentyone = new BigDecimal("21");
BigDecimal seven = new BigDecimal("7");

int answer= sum.intValue( );           // 28
}
catch (NumberFormatException nfe) { }
catch (ArithmeticException ae) { }```

If you implement cryptographic algorithms for fun, `BigInteger` is crucial. But other than that, you’re not likely to need these classes.

## Wrappers for Primitive Types

In languages like Smalltalk, numbers and other simple types are objects, which makes for an elegant language design, but has trade-offs in efficiency and complexity. By contrast, there is a schism in the Java world between class types (i.e., objects) and primitive types (i.e., numbers, characters, and boolean values). Java accepts this trade-off simply for efficiency reasons. When you’re crunching numbers, you want your computations to be lightweight; having to use objects for primitive types would seriously affect performance. For the times you want to treat values as objects, Java supplies a wrapper class for each of the primitive types, as shown in Table 9.5.

Table 9-5. Primitive Type Wrappers

Primitive

Wrapper

`void`

`java.lang.Void`

`boolean`

`java.lang.Boolean`

`char`

`java.lang.Character`

`byte`

`java.lang.Byte`

`short`

`java.lang.Short`

`int`

`java.lang.Integer`

`long`

`java.lang.Long`

`float`

`java.lang.Float`

`double`

`java.lang.Double`

An instance of a wrapper class encapsulates a single value of its corresponding type. It’s an immutable object that serves as a container to hold the value and let us retrieve it later. You can construct a wrapper object from a primitive value or from a `String` representation of the value. The following statements are equivalent:

```Float pi = new Float( 3.14 );
Float pi = new Float( "3.14" );```

Wrapper classes throw a `NumberFormatException` when there is an error in parsing a string:

```try {
Double bogus = new Double( "huh?" );
}
catch ( NumberFormatException e ) {     // bad number
}```

You should arrange to catch this exception if you want to deal with it. Otherwise, since it’s a subclass of `RuntimeException`, it will propagate up the call stack and cause a runtime error if not caught.

Sometimes you’ll use the wrapper classes simply to parse the `String` representation of a number:

```String sheep = getParameter("sheep");
int n = new Integer( sheep ).intValue( );```

Here we are retrieving the value of the `sheep` parameter. This value is returned as a `String`, so we need to convert it to a numeric value before we can use it. Every wrapper class provides methods to get primitive values out of the wrapper; we are using `intValue( )` to retrieve an `int` out of `Integer`. Since parsing a `String` representation of a number is such a common thing to do, the `Integer` and `Long` classes also provide the static methods `Integer.parseInt()` and `Long.parseLong( )` that read a `String` and return the appropriate type. So the second line in the previous example is equivalent to:

`int n = Integer.parseInt( sheep );`

Likewise, the `Float` and `Double` classes provide the static methods `Float.parseFloat()` and `Double.parseDouble( )`, for parsing strings into floating-point primitives.

All wrappers provide access to their values in various forms. You can retrieve scalar values with the methods `doubleValue()` , `floatValue()`, `longValue( )`, and `intValue( )`:

```Double size = new Double ( 32.76 );

double d = size.doubleValue( );     // 32.76
float f = size.floatValue( );       // 32.76
long l = size.longValue( );         // 32
int i = size.intValue( );           // 32```

This code is equivalent to casting the primitive double value to the various types.

You also need a wrapper when you want to use a primitive value in a situation that requires an object. As you’ll see shortly, a `Vector` is an extensible array of `Object`s. We can use wrappers to hold numbers in a `Vector`, along with other objects:

```Vector myNumbers = new Vector( );
Integer thirtyThree = new Integer( 33 );

Here we have created an `Integer` wrapper object so that we can insert the number into the `Vector`, using `addElement( )` . Later, when we are extracting elements from the `Vector`, we can recover the `int` value as follows:

```Integer theNumber = (Integer)myNumbers.firstElement( );
int n = theNumber.intValue( );           // 33```

## Random Numbers

You can use the `java.util.Random` class to generate random values. It’s a pseudo-random number generator that can be initialized with a 48-bit seed.[31] The default constructor uses the current time as a seed, but if you want a repeatable sequence, specify your own seed with:

```long seed = mySeed;
Random rnums = new Random( seed );```

This code creates a random-number generator. Once you have a generator, you can ask for random values of various types using the methods listed in Table 9.6.

Table 9-6. Random Number Methods

Method

Range

`nextBoolean( )`

true or false

`nextInt( )`

-2147483648 to 2147483647

`nextInt(int n)`

0 to (n - 1) inclusive

`nextLong( )`

-9223372036854775808 to 9223372036854775807

`nextFloat( )`

-1.0 to 1.0

`nextDouble( )`

-1.0 to 1.0

By default, the values are uniformly distributed. You can use the `nextGaussian( )` method to create a Gaussian (bell curve) distribution of `double` values, with a mean of 0.0 and a standard deviation of 1.0.

The `static` method `Math.random( )` retrieves a random `double` value. This method initializes a `private` random-number generator in the `Math` class, using the default `Random` constructor. So every call to `Math.random( )` corresponds to a call to `nextDouble( )` on that random-number generator.

[31] The generator uses a linear congruential formula. See The Art of Computer Programming, Volume 2, “Semi-numerical Algorithms,” by Donald Knuth (Addison-Wesley).

Get Learning Java now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.