0

I'm new to C coding, and could appreciate some help with my doubt. I've recently witnessed strange nature of output in C for int and float values.

    int main()
{   
    int x=1;
    while(x==1)
     { 
       printf("%d\n",x);
       x=x-1;
     }
  return 0;
}

According to me, code for int datatype works fine, and I got output as expected.I expect the same for float datatype, but it shows no output. I don't understand this.

 //Same code for float
 int main()
{ 
  float x=1.1;
  while(x==1.1)
  {
    printf("%f\n",x);
    x=x-0.1;
  }
return 0;
}

NOTE that when i put x=(Any integer) [at both places, in the code], it gives expected output,but whenever i put decimal, it doesn't give output as i expect for code with int. This is my first time and first question on Stack Overflow. I would appreciate some tips.English is not my first language, kindly bear with me.

  • Try `printf("%.20f, %.20f, %.20f\n",x, 1.1, 1.1f);` for more insight. – chux - Reinstate Monica May 09 '20 at 07:35
  • @chux-ReinstateMonica Unfortunately, this didn't help. – Learning Codes May 09 '20 at 07:45
  • 1
    Change your `float` to a `double`. As it is, you're taking a `float` `1.1`, which is an inexact value, and comparing it to a `double` `1.1`. This is done by converting the `float` to a `double` and then comparing them. But the converted value is less accurate than the `double 1.1`, so they compare as unequal. In general, comparing floating point values for equality is dicey. Just because they're mathematically the same doesn't mean their floating point representations are identical. – Tom Karzes May 09 '20 at 07:48
  • 2
    Unfortunately saying "Unfortunately, this didn't help" does not help. What did you see? what was expected? – chux - Reinstate Monica May 09 '20 at 07:48
  • @chux-ReinstateMonica It's a float vs. double accuracy problem. See my comment for an explanation of why the second loop exits immediately, without printing anything. – Tom Karzes May 09 '20 at 07:51
  • @tom, That is a reasonable but only one of various possible explanations. The issue can run deeper. The effect of `FLT_EVAL_METHOD` and optimization levels affects things too. – chux - Reinstate Monica May 09 '20 at 07:55
  • 1
    @chux-ReinstateMonica Yes, it's hard to predict how it will behave, but it does explain the control flow problem. Exact floating point comparisons are almost always a bad idea. – Tom Karzes May 09 '20 at 07:57
  • @TomKarzes Thanks for help, I didn't know what a **double** is so far. I have tried your suggestion and it worked! – Learning Codes May 09 '20 at 07:59
  • @LearningCodes There are two basic types of floating point in C: `float` and `double`. Usually `float` is 32-bits and `double` is 64 bits (I'm not sure how strict the standard is about this, but this what you normally see). That means that a `double` is much more accurate than a `float`. I almost never use `float` in C - I always use `double`. Note that floating point arithmetic is done in double precision, do using `double` results in more direct code. – Tom Karzes May 09 '20 at 08:06
  • @LearningCodes it might work now, but you should still avoid comparing floating point values like that. It's better to get into the habit of not comparing for equality at all (and instead only use < or >). Or, if you really have to, check if the absolute difference of the two numbers is smaller than some threshold (so they don't have to be exactly equal) – Felix G May 09 '20 at 08:10
  • @FelixG Thanks for your suggestion, I'll keep that in mind. I encountered that code in an exercise of Book 'Let Us C'. – Learning Codes May 09 '20 at 08:25
  • Try this code (https://codeshare.io/ax4eZX) and inspect deeply the bit representation to make a distinction b/w (1) a *floating point literal* `1.1` which is treated as a *double* (2) and a type `float` literal `1.1f`. – ssd May 09 '20 at 08:49
  • In C, `1.1` is a constant of type `double`. In the formats used for `float` and `double`, when 1.1 is converted to `double`, the result is the nearest representable value, which is, in hexadecimal, 1.199999999999A. When this is converted to `float`, the result is 1.19999A. So `float x=1.1;` sets x to 1.19999A. But `x==1.1` compares that 1.9999A to 1.199999999999A. So they are not equal. – Eric Postpischil May 09 '20 at 11:05

0 Answers0