0

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.

9
  • 8
    When I saw the title of the question on the main page, I was sure it was another floating-point comparison question. Commented Aug 14, 2012 at 16:35
  • 6
    What Every Computer Scientist Should Know About Floating-Point Arithmetic Commented Aug 14, 2012 at 16:35
  • 2
    Did you try searching at all? Commented Aug 14, 2012 at 16:36
  • 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? stackoverflow.com/questions/7008649/… stackoverflow.com/questions/17333/… Commented Aug 14, 2012 at 16:39
  • 2
    So this was the trick behind your previous question: stackoverflow.com/questions/11947654/… 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? Commented Aug 14, 2012 at 16:47

8 Answers 8

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
Sign up to request clarification or add additional context in comments.

4 Comments

@user1202136: what platform did you run that test on?
@MichaelBurr: I ran it on Ubuntu 12.04 / 64 bits on an Intel processor. Why? Don't you get the same values?
@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).
@MichaelBurr: You are right. I fixed the code above. Thanks a lot for noticing.
6
if (a==0.8f)

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

Comments

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.

Comments

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))

Comments

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.

Comments

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

Comments

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) 

Comments

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) /* ... */

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.