-1

Consider below two snippets

int main() {
    float a = 1.5;
    if(a == 1.5) cout << "Yes\n";
    else cout << "No\n";
    return 0;
}

Output : Yes.

int main() {
    float a = 0.7;
    if(a == 0.7) cout << "Yes\n";
    else cout << "No\n";
    return 0;
}

Output: No.

Why is the output different in the two case? I know that by default floating point constants are double so comparison in second snippet between a float ( a ) and double ( 0.7 ) becomes false and output is No. But I couldn't figure out so as why the output is Yes in case of first snippet. Please help!

Kevin
  • 2,813
  • 3
  • 20
  • 30
Learner
  • 27
  • 5
  • Trying it with a `double` is more interesting: literals can effectively be represented with higher precision than a `double`. – Bathsheba Aug 14 '15 at 11:17

1 Answers1

1

The reason for this is that most floats aren't stored in an exact value in the computer. So using equality on floats is never a good idea. What you should do is check if the difference between two floats is less than a threshold. Something like:

if (abs(a - 0.7) < 0.00001)
  cout << "Yes" 
else
  cout << "No"

The reason your equality was true in the earlier case is that 1.5 can be represented exactly as a float, whereas 0.7 cannot. To understand the reason, you should look at the way floats are stored in memory. Another line of thought is that the binary representation of 1.5 is 1 for the part before decimal, and 1 for the part after the decimal, whereas 0.7 in binary will have a never terminating sequence after the decimal. If you can't write it on paper, how do you expect to even store all those infinite bits in memory (let alone 64 bits).

Check out this link for why floats can't be stored as exact numbers: Why Are Floating Point Numbers Inaccurate?

Community
  • 1
  • 1
therainmaker
  • 4,253
  • 1
  • 22
  • 41
  • 2
    your code snippet is seriously flawed. your condition translates to `(a < 1.500001)` when it should be `(1.5 - eps < a < 1.5 + eps)` where `eps` is some appropriate small value. – 463035818_is_not_an_ai Aug 14 '15 at 11:18
  • well, now the number is `0.7` and not `1.5`, but the problem remains the same – 463035818_is_not_an_ai Aug 14 '15 at 11:19
  • @tobi303 thank you for that. Really stupid of me. And that is what I have explained, that equality is working for 1.5 but not 0.7 – therainmaker Aug 14 '15 at 11:22
  • yes much better now. Honestly I do not like your argumentation too much, because one could implement numbers with a base 0.7 where 0.7 would be exactly representable. I mean its just a matter of convention what tiny subset of all numbers can be represented exactly. Nevertheless, +1 ;) – 463035818_is_not_an_ai Aug 14 '15 at 11:25
  • ps: after all, numbers are just symbols. You can declare the symbol `1` to represent the value `0.7` and suddenly you can represent the value `0.7` exactly. However, I guess I am going to much esoteric now ;) – 463035818_is_not_an_ai Aug 14 '15 at 11:28
  • 0.5 is stored "as an exact value". So your leading statement is a bit misleading. – juanchopanza Aug 14 '15 at 11:30
  • @juanchopanza : I have gone on to argue about 1.5 being stored exactly. It logically extends to 0.5 being stored exactly. – therainmaker Aug 14 '15 at 17:44
  • @tobi303: I have very poorly worded the answer. I was sitting somewhere outside and was about to leave when I saw the question. So thought of just answering it quickly and leaving. In retrospect, I should've written a better answer – therainmaker Aug 14 '15 at 17:45