26

Please look at following two code:

public static void main(String... args)
{
   System.out.println(0.5==0.5f);
}

Output : true

 public static void main(String... args)
 {
   System.out.println(0.1==0.1f);
 }

Output: false

Why is it happening so?

Anurag Shukla
  • 379
  • 1
  • 3
  • 11
  • floating point literals are double by default – WorldSEnder Jul 11 '15 at 12:36
  • 1
    Hint, what is `0.1` as a `double`? And as a `float`? – Boris the Spider Jul 11 '15 at 12:37
  • 12
    Neither of the two linked questions actually answers the given question, which is why this works fine for `0.5` but not `0.1`. This just has to do with the fact that `0.5` can be correctly represented in both 32 and 64bit IEEE-754 while `0.1` can't. – Voo Jul 11 '15 at 12:38
  • @Voo agreed. Now If you were to post that exact comment as an answer (maybe with some println)... (I'm too lazy) – Boris the Spider Jul 11 '15 at 12:40
  • @Boris Damn I was hoping you would. Done though, no println output but I think that should be reasonably easy to understand. – Voo Jul 11 '15 at 12:40
  • 3
    because `0.5 = 2^-1`, hence can be represented exactly in binary. `0.1` is not – phuclv Jul 11 '15 at 13:02

2 Answers2

43

You are comparing two types of values: double and float. Think about the limitations of size with inexact numbers.

An example:

Exact values (decimal)

value1 -> 1/2 with 5 decimals is 0.50000
value2 -> 1/2 with 10 decimals is 0.5000000000

then

value1 == value2 -> returns true

Inexact values (decimal)

value3 -> 1/3 with 5 decimals is 0.33333
value4 -> 1/3 with 10 decimals is 0.3333333333

then

value3 == value4 -> returns false because they aren't the same.

0.1 cannot be represent exactly in binary (like 1/3 in decimal) but 0.5 can be.

The binary representation of 0.1d -> 0.000(1100)1100110011...
The binary representation of 0.5d -> 0.1

JJJ
  • 32,902
  • 20
  • 89
  • 102
David Pérez Cabrera
  • 4,960
  • 2
  • 23
  • 37
20

This has to do with the fact that floating point numbers are represented in the form c*2^q. 0.5 can be represented as 1*2^-1 while 0.1 is impossible to represent accurately independent of how large you make c and q.

When comparing a float to a double, the float is cast to a double. If the number that is represented is already correctly representable as a float, it will have the same value when cast as a double, but if not, the double will have some extra significant digits and hence will compare non equal.

Voo
  • 29,040
  • 11
  • 82
  • 156