-2

I did my research on floating point calculation and I understood how it is being stored and how inaccuracy comes but with the following case I think its a outlier . Can anyone please help why that it so .

Source Code - 
int main()
{        
          float f = 3.9999999f;
          printf("%f",f);
}

Output - 
4.000000

[Question - Why 4.000000 I did calculation but i am getting around 3.099999976158142089844]

Can anyone please Help me with this .

Compiler spec-
Using built-in specs.
COLLECT_GCC=somepath\gcc.exe

Target: mingw32
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

Video I refereed to understand floating point calculation - https://www.youtube.com/watch?v=iV-K-gNDC5A

  • 1
    "around 3.0999999761" did you mean "around 3.9999999761"? Anyway, the output is rounded (by default) to 6 decimal places. – Weather Vane Jul 09 '21 at 14:20
  • Unrelated: the float value is automatically converted to the corresponding value of type `double` for `printf()`... so just go with `double f = 3.99999999;` to begin with :-) – pmg Jul 09 '21 at 14:34
  • Start by reading https://stackoverflow.com/questions/588004/is-floating-point-math-broken... – Nate Eldredge Jul 09 '21 at 14:37
  • I don't understand your question, and the value 3.099... makes no sense, so I assume you mis-typed it. – Robert Harvey Jul 09 '21 at 14:38
  • Please tell us what you would expect to see instead of 4.000000. – TonyK Jul 09 '21 at 16:09

2 Answers2

2

In the format commonly used for float, IEEE-754 single precision a.k.a binary32, the two representable values closest to 3.9999999 are 3.9999997615814208984375 and 4. (3.9999997615814208984375 is 16,777,215•2−22.)

The distance between 3.9999997615814208984375 and 3.9999999 is about 1.4•10−7. The distance between 4 and 3.9999999 is 1•10−7. So 4 is closer to 3.9999999 than 3.9999997615814208984375 is. So a C implementation that rounds to the nearest representable value will produce 4 for 3.9999999f. Thus float f = 3.9999999f; initializes f to 4.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

Befause the difference between 4.000000 and 3.9999999 is less than FLT_EPSILON.

#include <stdio.h> /* printf() */
#include <float.h> /* FLT_EPSILON */

int main(void)
{
    float f;

    /* Prints FLT_EPSILON: 0.00000011920928955078125
       Difference between 1 and the least value greater than 1
       that is representable (for float).

       We can see that 6 zeros after decimal point are
       the default precision of 6 digits for '%f'.

       float can contain up to 23 digits in mantisa. */
    printf("%.23f\n", FLT_EPSILON);

    /* Make something smaller than 4 (anything bigger is 4):
    f = 4 - (FLT_EPSILON + 0.00000000000000000000001) */
    f = 3.99999988079071044921874F;

    /* Prints: 3.99999976158142089843750 == 4 - (FLT_EPSILON + FLT_EPSILON)
       4 - FLT_EPSILON would get rounded to 4. */
    printf("%.23f\n", f);

    /* Prints: 4.000000 */
    printf("%f\n", f);

    return 0;
}