HARSH PARMAR
HARSH PARMAR

Reputation: 37

Floating point constant

For the following code:

#include<stdio.h>

int main()
{
    float a = 0.7;
    printf("%.10f %.10f\n", 0.7f, a);
    return 0;
}

The output I get is:

0.7000000000 0.6999999881

Please explain why a is printed as 0.6999999881 while the literal constant is printed as 0.7000000000 ?

Is the use of a floating point constant in this case compiler-dependent?

Upvotes: 1

Views: 712

Answers (2)

Luis Colorado
Luis Colorado

Reputation: 12708

The reason you get different values is that, as you are passing to printf(3) (which is a vararg function) as an unchecked parameter, the compiler does a cast to (double) (and an optimization i'm guessing) converting the 0.7f literal to a 0.7D before passing it to printf, so you are actually passing two different values to printf, the first is (double)0.7f, and the second is the stored value of variable a, converted to a (double).

Upvotes: 0

Pascal Cuoq
Pascal Cuoq

Reputation: 80335

Obtaining “0.7000000000” as the string printed for printf("%.10f",0.7f) is normal behavior if the compiler defines FLT_EVAL_METHOD as 1 or 2.

Indeed, in that mode, floating-point constants can be represented at a precision beyond that of their type (C11 5.2.4.2.2:9):

Except for assignment and cast (which remove all extra range and precision), the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.

In other words, printing 0.7000000000 0.6999999881 FLT_EVAL_METHOD=2 is one possible behavior for the modified program below.

#include<stdio.h>
#include <float.h>

int main()
{
    float a=0.7;
    printf("%.10f %.10f FLT_EVAL_METHOD=%d\n",0.7f, a, (int)FLT_EVAL_METHOD);
    return 0;
}

Because the compiler defines FLT_EVAL_METHOD to 2, printf("%.10f %.10f", 0.7f, 0.7) is treated as if it was printf("%.10f %.10f", (double)0.7L, (double)0.7L). Similarly, printf("%.60Lf %.60Lf\n", (long double)0.7f, (long double)0.7) is equivalent to printf("%.60Lf %.60Lf\n", 0.7L, 0.7L).

Upvotes: 4

Related Questions