-2

Unable to find the reason for the following piece of code:

#include <stdio.h>
int main()
{
    float f = 0.1;
    if (f == 0.1)
      printf("True");
    else
      printf("False");
    return 0;
}

The output is false.

#include <stdio.h>
int main()
{
    float f = 0.1;
    if (f == (float)0.1)
      printf("True");
    else
      printf("False");
    return 0;
}

Now shows the correct output. Whats the reason behind this?

Also what is the reason of this behavior.

#include <stdio.h>
main()
{
    int n = 0, m = 0;
        if (n > 0)
            if (m > 0)
                    printf("True");
        else 
            printf("False");
}
Megharaj
  • 1,589
  • 2
  • 20
  • 32
  • 7
    Please never compare floating point numbers for equality. Floating point numbers almost never compare equal. – fuz Aug 22 '13 at 10:01
  • 1
    Duplicate literally dozens of times. –  Aug 22 '13 at 10:10
  • 1
    ..and C tag opens today's 'annoying question' competition with an old classic. (credit: [Martin James](http://stackoverflow.com/users/758133/martin-james)) – Lightness Races in Orbit Aug 22 '13 at 10:13
  • @H2CO3 thank you for pointing that. I searched previously failed to get the same. I will take a look at the answer. – Megharaj Aug 22 '13 at 10:13
  • @Megharaj You're welcome - you may also profit from reading [this](http://floating-point-gui.de) often-cited article. –  Aug 22 '13 at 10:14
  • @H2CO3 Thanks a lot for all the information. – Megharaj Aug 22 '13 at 10:15
  • @FUZxxl There are plenty of opportunities for using floating-point equality properly. Your advice is misplaced. Floating-point equality works. In this particular example it is the conversion from `double` to `float` that may produce results surprising to the naive programmer, not equality. – Pascal Cuoq Aug 22 '13 at 12:12
  • @PascalCuoq Can you elaborate? I can not figure out a sensible case where it actually makes sense to compare floating point numbers for equality; except perhaps, in case you want to sort them, but even then you can compare with greater-then. – fuz Aug 22 '13 at 12:49
  • @FUZxxl With the knowledge that `HUGE_VAL` is `+inf` for IEEE 754 systems, see this question: http://stackoverflow.com/questions/11421756/weverything-yielding-comparing-floating-point-with-or-is-unsafe . For another example, this post contains a function to convert from `double` to `unsigned long long` without using a conversion; the function uses floating-point equality: http://blog.frama-c.com/index.php?post/2013/05/01/A-conversionless-conversion-function2 – Pascal Cuoq Aug 22 '13 at 12:56
  • @PascalCuoq This is a case for which you have the function isinf() on any C99 compliant system. It is not guaranteed that if something compares equal to HUGE_VAL on non IEEE 754 compliant systems it is really equal to positive infinity. – fuz Aug 22 '13 at 13:10

2 Answers2

6

0.1 literal is double. You loose precision here float f = 0.1;

You could say we loose precision during comparison again, so why isn't f == 0.1 true anyway? Because float extends to double, not the opposite. In C smaller type always extends to the bigger one.

Simplified your example we can say that double(float(1.0)) != 1.0

Possible solutions:

  • use double instead of float as a type of f.
  • use cast as in your 2nd example
  • use float literals - replace all 0.1 with 0.1f

Better solution

Floating point variables have a lot of problems with comparisons. They, including this one, can be solved by defining your own comparison function:

bool fp_equal(double a, double b, double eps = FLT_EPSILON) {
  return fabs(a - b) < fabs(eps * a);
}

The second part of the question:

Why the answer is false is because else part always corresponds to the innermost if block. So you were confused by formatting, the code is equivalent to:

#include <stdio.h>

int main()
{
    int n = 0, m = 0;
    if (n > 0) {
        if (m > 0) {
            printf("True");
        }
        else {
            printf("False");
        }
    }
}
Community
  • 1
  • 1
sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
2

Answer to your second question (third example):

According to your indention, the code doesn't do what you exepect it to:

#include <stdio.h>
main()
{ 
    int n = 0, m = 0;
        if (n > 0)
            if (m > 0)
                 printf("True");
        else 
            printf("False");
}

Here the else belongs to the inner if, so it's equal to

#include <stdio.h>
main()
{ 
    int n = 0, m = 0;
        if (n > 0) {
            if (m > 0) {
                 printf("True");
            } else {  
                 printf("False");
            }
        }
}

but I think you meant:

#include <stdio.h>
main()
{ 
    int n = 0, m = 0;
        if (n > 0) {
            if (m > 0) {
                 printf("True");
            }
        } else {  
            printf("False");
        }
}

It's a good example for why one should alwys user brackets in if statements.

Ingo Leonhardt
  • 9,435
  • 2
  • 24
  • 33