# Float and Double

Float and Double store floating-point and double precision floating-point values in Float and Double objects, respectively. These classes declare the following constants:

■ MAX_VALUE identifies the maximum value that can be represented as a float or double.

■ MIN_VALUE identifies the minimum value that can be represented as a float or double.

■ NaN represents 0.0F/0.0F as a float and 0.0/0.0 as a double.

■ NEGATIVE_INFINITY represents -infinity as a float or double.

■ POSITIVE_INFINITY represents +infinity as a float or double.

Float and Double also declare the following constructors for initializing their objects:

■ Float(float value) initializes the Float object to value.

■ Float(double value) initializes the Float object to the float equivalent of value.

■ Float(String s) converts s's text to a floating-point value and stores this value in the Float object.

■ Double(double value) initializes the Double object to value.

■ Double(String s) converts s's text to a double precision floating-point value and stores this value in the Double object.

Float's constructors are complemented by float floatValue(), which returns the wrapped floating-point value. Similarly, Double's constructors are complemented by double doubleValue(), which returns the wrapped double precision floating-point value.

Float declares several utility methods in addition to floatValue(). These methods include the following:

■ static int floatToIntBits(float value) converts value to a 32-bit integer.

■ static boolean isInfinite(float f) returns true when f's value is +infinity or -infinity. A related public boolean isInfinite() method returns true when the current Float object's value is +infinity or -infinity.

■ static boolean isNaN(float f) returns true when f's value is NaN. A related public boolean isNaN() method returns true when the current Float object's value is NaN.

■ static float parseFloat(String s) parses s, returning the floatingpoint equivalent of s's textual representation of a floating-point value or throwing NumberFormatException when this representation is invalid (contains letters, for example).

Double declares several utility methods in addition to doubleValue(). These methods include the following:

■ static long doubleToLongBits(double value) converts value to a long integer.

■ static boolean isInfinite(double d) returns true when d's value is +infinity or -infinity. A related boolean isInfinite() method returns true when the current Double object's value is +infinity or -infinity.

■ static boolean isNaN(double d) returns true when d's value is NaN. A related public boolean isNaN() method returns true when the current Double object's value is NaN.

■ static double parseDouble(String s) parses s, returning the double precision floating-point equivalent of s's textual representation of a double precision floating-point value or throwing NumberFormatException when this representation is invalid.

The floatToIntBits() and doubleToIntBits() methods are used in implementations of the equals() and hashCode() methods that must take float and double fields into account. floatToIntBits() and doubleToIntBits() allow equals() and hashCode() to respond properly to the following situations:

■ equals() must return true when f1 and f2 contain Float.NaN (or d1 and d2 contain Double.NaN). If equals() was implemented in a manner similar to f1.floatValue() == f2.floatValue() (or d1.doubleValue() == d2.doubleValue()), this method would return false because NaN is not equal to anything, including itself.

■ equals() must return false when f1 contains +0.0 and f2 contains -0.0 (or vice versa), or d1 contains +0.0 and d2 contains -0.0 (or vice versa). If equals() was implemented in a manner similar to f1.floatValue() == f2.floatValue() (or d1.doubleValue() == d2.doubleValue()), this method would return true because +0.0 == -0.0 returns true.

These requirements are needed for hash-based collections (discussed in Chapter 8) to work properly. Listing 6-11 shows how they impact Float's and Double's equals() methods.

Listing 6-11. Demonstrating Float's equals() method in a NaN context and Double's equals() method in a +/-0.0 context public static void main(String[] args) {

Float f1 = new Float(Float.NaN); System.out.println(f1.floatValue()); Float f2 = new Float(Float.NaN); System.out.println(f2.floatValue()); System.out.println(f1.equals(f2)); System.out.println(Float.NaN == Float.NaN); System.out.println(); Double d1 = new Double(+0.0); System.out.println(d1.doubleValue()); Double d2 = new Double(-0.0); System.out.println(d2.doubleValue()); System.out.println(d1.equals(d2)); System.out.println(+0.0 == -0.0);

Run this application. The following output proves that Float's equals() method properly handles NaN and Double's equals() method properly handles +/-0.0:

NaN NaN true false

TIP: If you want to test a float or double value for equality with +infinity or -infinity (but not both), do not use isInfinite(). Instead, compare the value with NEGATIVE_INFINITY or POSITIVE_INFINITY via ==. For example, f == Float.NEGATIVE_INFINITY.

You will find parseFloat() and parseDouble() useful in many contexts. For example, Listing 6-12 uses parseDouble() to parse command-line arguments into doubles.

Listing 6-12. Parsing command-line arguments into double precision floating-point values public static void main(String[] args) {

System.err.println("usage: java Calc value1 op value2"); System.err.println("op is one of +, -, *, or /"); return;

double value1 = Double.parseDouble(args); double value2 = Double.parseDouble(args); if (args.equals("+"))

System.out.println(value1+value2); else if (args.equals("-"))

System.out.println(value1-value2); else if (args.equals("*"))

System.out.println(value1*value2); else if (args.equals("/"))

System.out.println(value1/value2); else

System.err.println("invalid operator: " + args);

catch (NumberFormatException nfe) {

System.err.println("Bad number format: " + nfe.getMessage());

Specify java Calc 10E+3 + 66.0 to try out the Calc application. This application responds by outputting 10066.0. If you specified java Calc 10E+3 + A instead, you would observe Bad number format: For input string: "A" as the output, which is in response to the second parseDouble() method call's throwing of a NumberFormatException object.

Although NumberFormatException describes an unchecked exception, and although unchecked exceptions are often not handled because they represent coding mistakes, NumberFormatException does not fit this pattern in this example. The exception does not arise from a coding mistake; it arises from someone passing an illegal numeric argument to the application, which cannot be avoided through proper coding.