I came across the following program
class Boolean {
public static void main(String argv[]) {
boolean x;
x = 4.4f == 4.4;
System.out.println(x);
}
}
The output of the following program is false
But if we write the program in the following fashion, then
class Boolean {
public static void main(String argv[]) {
boolean x;
x = 4.5f == 4.5;
System.out.println(x);
}
}
In this case the output is true
Can somebody explain me why ??
-
3possible duplicate of What's wrong with using == to compare floats in Java?Tomasz Nurkiewicz– Tomasz Nurkiewicz2011年07月28日 08:13:52 +00:00Commented Jul 28, 2011 at 8:13
-
Other similar questions: 1, 2Tomasz Nurkiewicz– Tomasz Nurkiewicz2011年07月28日 08:14:45 +00:00Commented Jul 28, 2011 at 8:14
7 Answers 7
You generally shouldn't compare floating point values with == operator. You should use 'close enough' comparison like checking if values differ by some small value:
double epsilon = 0.000001
boolean equal = Math.abs(value1-value2) < epsilon
In your example, 4.4f is not equal to 4.4, because java defaults floating point values to double type, which is 64bit, and to compare them java casts 4.4f to double, which causes it to be slightly different from original double value 4.4(because of problems representing decimal fractions with binary).
Here's a good link on floating point numbers.
Comments
The problem is that computers like numbers to be based on base 2 and not base 10 like us.
4.4 is an infinite fraction (like 0.333333333... for us) in binary, and floats have fewer digits than doubles, so there are fewer digits in 4.4f than in 4.4 making them different.
4.5 is not an infinite fraction.
Note: Whenever you need to compare floats or doubles you should always check the size of the difference, not just check for equality.
Comments
Run this code to see how casting of float to double works for these cases
NumberFormat nf = new DecimalFormat("0.00000000000000000000");
System.out.println(nf.format(4.4f));
System.out.println(nf.format(4.4));
System.out.println(nf.format(4.5f));
System.out.println(nf.format(4.5));
Comments
That is because of a rounding error when the double gets truncated to a float. Sometimes you get it sometimes you won't.
4.4f is a float and 4.4 is a double.
Comments
Your prgramm compares a 16-bit float with 32-bit double value. Internaly it is represented a IEEE754 so the difference is a rounding error which leads in some cases to this inequality due to different precision.
Comments
This is down to the fact that a float is a not a double and you can't easily do direct comparison, because a float is just an approximation. Take a look at the following code:
public static void main(String args[]) {
double a, b;
a = 4.4f;
b = 4.5f;
System.out.println("4.4f implicitly cast to a double = "+a);
System.out.println("4.5f implicitly cast to a double = "+b);
}
You'll see that 4.4f, when implicitly cast to a double is in fact 4.400000095367432.
Comments
In addition to what everyone has said, here is a very popular example to demonstrate this thing with floating point operations.
System.out.println(0.3 - 0.2 - 0.1);
It won't print 0
. In fact, it would print a very small number as a result of the truncation errors that happen in floating point operations when certain fractions are non-terminating repeating in the binary representation.