Reputation: 490
I am confused about the behavior of floating point number after seeing the result of following code snippet.
float var1 = 5.4f;
float var2 = 5.5f;
if(var1 == 5.4)
System.out.println("Matched");
else
System.out.println("Oops!!");
if(var2 == 5.5)
System.out.println("Matched");
else
System.out.println("Oops!!");
Output:
Oops!!
Matched
Is this because of decimal number that can't be represent exactly in base 2 binary format? OR Is this because of precision as I comparing a float type variable with a double type? If yes then why it works fine for next variable?
Upvotes: 9
Views: 1862
Reputation: 1500515
Is this because of decimal number that can't be represent exactly in base 2 binary format?
Yes. Basically, 5.4f
and 5.4d
are not the same, because neither of them are exact representations of 5.4.
5.5f
and 5.5d
are the same because they're both exact representations of 5.5.
Note that 5.4
is implicitly the same as 5.4d
- the default type for a floating point literal is double
. Any use of a binary operator with operands of float
and double
will promote the float
to a double
and perform the operation on two double
values.
It may make things easier to think of it in terms of decimal types. Suppose we had two types, Decimal5 and Decimal10 which are decimal numbers with 5 or 10 significant figures. Then consider "a third" and "a quarter":
A third:
Decimal5: 0.33333
Decimal10: 0.3333333333
A quarter (showing trailing zeroes just for clarity):
Decimal5: 0.25000
Decimal10: 0.2500000000
When comparing the Decimal5 value closest to a third with the Decimal10 value, the Decimal5 value would be converted to a Decimal10 value of 0.3333300000, which doesn't equal 0.3333333333. This is similar to your first example.
When comparing the values for a quarter, however, the Decimal5 value of 0.25000 is converted to 0.2500000000, which is the same as the Decimal10 value we have for a quarter. This is similar to your second example.
Of course the binary floating point types are a bit more complicated than that, with normalization, subnormal numbers etc - but for the purposes of your example, this analogy is close enough.
Upvotes: 16
Reputation: 823
If you want to compare floating point types, you must use comparing with epsilon. Here you can see all the ways you can use for comparing floating point types.
Upvotes: 0
Reputation: 785128
Replace your if condition with:
if(var1 == 5.4f)
System.out.println("Matched");
else
System.out.println("Oops!!");
if(var2 == 5.5f)
System.out.println("Matched");
else
System.out.println("Oops!!");
Then it will print Matched
both times. Reason is because without qualifier f
in the end Java treats 5.4
as double which cannot be represented accurately in comparison to 5.5
.
Upvotes: 3
Reputation: 8473
The difference is that 5.5 can be represented exactly in both float
and double
- whereas 5.4 can't be represented exactly.
reference http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Upvotes: 6
Reputation: 4600
It's easy to see:
if(var1 == 5.4f)
System.out.println("Matched");
else
System.out.println("Oops!!");
if(var2 == 5.5f)
System.out.println("Matched");
else
System.out.println("Oops!!");
Output:
Matched
Matched
The binary representation of 5.4f
and 5.4d
is not exactly the same
Upvotes: 2