1

I have a program:

int main() 
{   
        float f = 0.0f;  
        int i;  

        for (i = 0 ; i < 10 ; i++) 
                f = f + 0.1f; 

        if (f == 1.0f) 
                printf("f is 1.0 \n"); 
        else 
                printf("f is NOT 1.0\n"); 

        return 0; 
} 

It always prints f is NOT 1.0. I understand this is related to floating point precision in C. But I am not sure exactly where it is getting messed up. Can someone please explain me why it is not printing the other line?

Ronan Boiteau
  • 8,910
  • 6
  • 33
  • 52
Pkp
  • 889
  • 6
  • 19
  • 31
  • 6
    You've answered the question yourself. It's related to precision. Google will give you 1000.001 explanations. – John3136 Mar 06 '12 at 02:42

4 Answers4

5

Binary floating point cannot represent the value 0.1 exactly, because its binary expansion does not have a finite number of digits (in exactly the same way that the decimal expansion of 1/7 does not).

The binary expansion of 0.1 is

0.000110011001100110011001100...

When truncated to IEEE-754 single precision, this is approximately 0.100000001490116119 in decimal. This means that each time you add the "nearly 0.1" value to your variable, you accumulate a small error - so the final value is slightly higher than 1.0.

caf
  • 225,337
  • 36
  • 308
  • 455
3

This is equivelent to adding 0.33 together 3 times (0.99) and wondering why it is not equal to 1.0.

You may wish to read What Every Programmer Should Know About Floating Point Arithmetic

dawg
  • 90,796
  • 20
  • 120
  • 197
2

You cannot compare floats like this. You need to define a threshold and compare based on that. This blog post explains

Abhishek Chanda
  • 2,426
  • 6
  • 30
  • 59
  • Thanks a lot for the answer. I went through the link and found this other link which explained to me what i was missing. http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm – Pkp Mar 06 '12 at 02:52
2

For floating point numbers you should always use an epsilon value when comparing them:

#define EPSILON 0.00001f

inline int floatsEqual(float f1, float f2)
{
    return fabs(f1 - f2) < EPSILON; // or fabsf
}
paxdiablo
  • 814,905
  • 225
  • 1,535
  • 1,899
Richard J. Ross III
  • 54,187
  • 24
  • 128
  • 194
  • 2
    Richard, +1 since I prefer self-contained answers but the function you're looking for is `fabs` rather than `abs` - I fixed that for you :-) – paxdiablo Mar 06 '12 at 02:50
  • Thank you. This helps and explains a lot. – Pkp Mar 06 '12 at 02:54
  • 1
    @prasanna no problem, just don't forget to accept the answer! – Richard J. Ross III Mar 06 '12 at 05:52
  • Downvoted for misleading *"should always use"*. Using epsilon comparison gives inconsistent results on float value range. On extreme values comparison is only an inefficient `==`. Epsilon comparison can be useful sometimes, but only sometimes. – user694733 Feb 27 '18 at 11:31