-1

Possible Duplicate:
Most effective way for float and double comparison
strange output in comparison of float with float literal

int main() 
{
  float a = 0.8;
  if (a == 0.8)
    printf("x\n");
  else 
    printf("y\n");

  return 0;
}

Though a is equal to 0.8, it outputs y.

Community
  • 1
  • 1
user1593308
  • 491
  • 1
  • 4
  • 5
  • 8
    When I saw the title of the question on the main page, I was sure it was another floating-point comparison question. –  Aug 14 '12 at 16:35
  • 6
    [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – chris Aug 14 '12 at 16:35
  • 2
    Did you try searching at all? – Antimony Aug 14 '12 at 16:36
  • @Antimony: What search terms should (s)he have been using, in your opinion? – Tim Pietzcker Aug 14 '12 at 16:39
  • 1
    I saw many duplicates of this on SO. Also many blogs/periodicals on the internet for this. Why haven't you looked into those? http://stackoverflow.com/questions/7008649/c-comparing-floating-point-numbers http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison – verisimilitude Aug 14 '12 at 16:39
  • 1
    searching for `[c] floating point comparison` yields some relevant [hits](http://stackoverflow.com/search?q=%5Bc%5D+floating+point+comparison) – Levon Aug 14 '12 at 16:40
  • 1
    @TimPietzcker: Try searching with `compare floating points in C` – verisimilitude Aug 14 '12 at 16:41
  • 2
    So this was the trick behind your previous question: http://stackoverflow.com/questions/11947654/why-the-control-goes-in-else-part You weren't even able to copy your assignment correctly when you asked the question for the first time? And now you still don't provide any effort of your own and we are supposed to answer this question that has been asked so many times before? – Jens Gustedt Aug 14 '12 at 16:47
  • @Tim `float not equal` would have worked – Antimony Aug 14 '12 at 17:48

8 Answers8

8

0.8 cannot be represented accurately in binary floating-point. Your code if (a == 0.8) basically compares single-precision 0.8 with double-precision 0.8, which are not equal.

To see this for yourself, try the following code:

int main()
{
    double a = 0.8f;
    double b = 0.8;

    printf("%lX\n", *(long *)&a);
    printf("%lX\n", *(long *)&b);
}

It outputs:

3FE99999A0000000
3FE999999999999A
user1202136
  • 11,171
  • 4
  • 41
  • 62
  • @user1202136: what platform did you run that test on? – Michael Burr Aug 14 '12 at 18:12
  • @MichaelBurr: I ran it on Ubuntu 12.04 / 64 bits on an Intel processor. Why? Don't you get the same values? – user1202136 Aug 14 '12 at 20:09
  • @user1202136: not even close - as H2CO3 mentions, the posted code has UB, and the amd64 doesn't simply pass varargs on the stack as on 32-bit x86 (at least for floating point args - I don't recall all the details), so you get printed data that really has nothing to do with the floating point values you're passing. The actual IEEE hex representations for `0.8` are: `3f4ccccd` (32-bit float), `3fe99999a0000000` (32-bit float converted to 64-bit double), and `3fe999999999999a` (double). – Michael Burr Aug 14 '12 at 21:21
  • @MichaelBurr: You are right. I fixed the code above. Thanks a lot for noticing. – user1202136 Aug 14 '12 at 23:19
6
if (a==0.8f)

Try this instead. By default, the type is consider to be double which has precision error in comparison.

sundar
  • 1,760
  • 12
  • 28
3

You're using a literal, 0.8, but that doesn't necessarily mean it's a float. try using:

if (a==0.8F)

instead

Also, representing fractional parts of numbers is notoriously error-prone, due to computers internally using base-2.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
1

Floating-point numbers aren't exact values. You are not supposed to compare them using == and != . Use greater than and less than operators with some reasonably small epsilon:

if ((a > 0.79) && (a < 0.81))
0

This is because floating points can't exactly represent decimals, so it isn't exactly 0.8. And you're comparing 0.8 rounded as a float to 0.8 rounded as a decimal, which aren't necessarily the same.

Antimony
  • 37,781
  • 10
  • 100
  • 107
0

floats are not always 100% accurate, they can't be because of the way that they're stored. If you say float a = 0.8, a could really be 0.800000000001 or something like that. To compensate for this, you should use some sort of threshold. try if (fabs(a-0.8) < 1.0e-5) instead

John Corbett
  • 1,595
  • 10
  • 19
0

because for floating point numbers 0.8 does not really means 0.8 but it is 0.799999999 so it happens Why it is 0.79999999
This depends on the storage of a float value. The decimal values will be stored in binary form (....,2^3,2^2,2^1,2^0,.,2^-1,2^-2,2^-3,...)

So, when 0.8 is stored in multiples of 2 as .101b(which is not 0.8 but 0.799999988).Hence its value will be less than 0.8.

if (a > 0.8) 

is also False thats why.

for your result try

if (a == 0.8f) 
NIlesh Sharma
  • 5,445
  • 6
  • 36
  • 53
0

You're comparing 2 values of different types: a is of type float, 0.8 is of type double.

before the comparison, the float value is converted to double ... but converting from double to float and back doesn't necessarily yield the same value

if (0.8 == (double)(float)0.8) /* ... */
pmg
  • 106,608
  • 13
  • 126
  • 198