|
Sometimes when you are performing mathematical operations, the results can be erroneous. For instance, if you divide an integer with 0, mathematically the result is infinite value. But Java throws an ArithmeticException to indicate that division by 0 has occurred (chapter 9 operators). However, the operations on floating-point numbers never result in exception in Java. Instead, for each out-of range results a named constant is returned as per the IEEE 754 standard. For example, if you divide a positive floating-point number by 0.0, the result is a named constant representing positive infinity. Similarly, if you divide 0.0 by 0.0, the result is Not-a-number. The Wrapper classes Float and Double both define the named constants for positive and negative infinities as well as the non-a-number values. Table 13.6 summarizes all the named constants defined in class Float and Double. All these member variables are defined as public static and final. Hence, they are publicly accessible constant values.
Table 13.6 Named constants defined in class java.lang.Float and java.lang.Double
|
Name of the constants |
Brief description |
|
POSITIVE_INFINITY |
A constant holding the positive infinity for the given type. |
|
NEGATIVE_INFINITY |
A constant holding the positive infinity of same type as the corresponding primitive type. For example, Float. NEGATIVE_INFINITY is of type float. |
|
NaN |
A constant holding a not-a-Number (NaN) value of corresponding primitive type. For example Float.NaN is of type float |
|
MAX_VALUE1 |
A constant representing the largest positive finite value of the corresponding primitive type. |
|
MIN_VALUE1 |
A constant representing the smallest positive finite value of the corresponding primitive type. |
1 These constants are also defined in all other wrapper classes except Boolean class.
Constants to define range of primitives
The constants MAX_VALUE and MIN_VALUE are defined in almost all wrapper classes. They together define the range of the primitive for that wrapper class. For example, the range of byte can be accessed as,
byte smallestByte = Byte.MIN_VALUE; // -128 is assigned
byte largestByte = Byte.MAX_VALUE; // +127 is assigned
Constants to define infinite value
The constants POSITIVE_INFINITY and NEGATIVE_INFINITY define an infinite value. Therefore, whenever there is a floating-point division by 0.0, one of these two values represents the result. For example,
float f = 7.5f/ 0.0f; // result is positive infinity
System.out.println(Float.POSITIVE_INFINITY == f); // prints true
Remember that unlike the integer division by zero, the floating-point division by zero does not throw the ArithmeticException.
Constant to define a not-a-number value
The Float and Double class also define a constant named NaN. It represents a Not-a-Number value which is used to indicate that the mathematical operation has no result in ordinary arithmetic. For example, a division of 0 by 0 has no result in arithmetic. In case of floating-point calculation, Java represent it with a float (or double) value NaN as:
float f = 0.0f/ 0.0f;
System.out.println(f); // prints NaN
There are other floating-point calculations that result in NaN. For instance, if you try to take a square root of negative number, the operation do not have any result. Hence, it is represented as NaN. You may recall that if you invoke Math.sqrt() method by passing a negative value, it returns Double.NaN. Note that type of NaN define in Float class is the primitive type float. Similarly type of NaN define in Double class is the primitive type double.
Conparing the NaN value
The most interesting thing about the NaN value is that it is non-ordinal. It means if you compare a NaN value with another NaN value, the result is always false. For instance, all of the following comparisons are false;
System.out.println(Float.NaN == Float.NaN); // prints false
System.out.println(Float.NaN < Float.NaN); // prints false
System.out.println(Float.NaN > Float.NaN); // prints false
This is also true with Doule.NaN value. Therefore,
System.out.println(Float.NaN != Float.NaN); // always true
System.out.println(Double.NaN != Double.NaN); // always true
Comparing a NaN value resulting from an arithmetic operation with a NaN value also result in false. For example,
float f = 0.0f/ 0.0f;
System.out.println(f == Float.NaN); // prints false
Thus the bottom line is ‘comparing the NaN value with == always results in false’. Then how would you check whether a result of some arithmetic operation is NaN ? The correct way to do is the isNaN() method. Both the Float and the Double class define this method. The signature of this method in Float class is as:
static public boolean isNaN(float v)
You can use this method to check whether a result of arithmetic operation is indeed NaN as:
float f = 0.0f/ 0.0f;
System.out.println(Float.isNaN(f)); // prints true