Reputation: 1
int main(){
int s=200;
printf("%.12f",s/3.0);
}
How this program is giving output 66.666666666667 even though float can support up to only 6-7 decimal places?
Meanwhile,
int main(){
float s=200;
printf("%.12f",s/3);
}
gives 66.666664123535.
please help?
Upvotes: 0
Views: 604
Reputation: 224596
In most C implementations, float
and double
do not use decimal digits. They use binary.
In the first program, 3.0
is a double
, so s/3.0
is computed with double
arithmetic. In spite of f
being the initial letter of float
, %.12f
takes a double
argument, for reasons involving the history of C development. So the double
value s/3.0
is converted to decimal with 12 digits after the decimal point and printed.
In the second program, s
is a float
, so s/3
is computed with float
arithmetic. In the format you use, the result is a binary-based number, 8738133 • 2−17. The reason there are many decimal digits involved is that, while expressing 2−17 is simple using that base of 2, in decimal it is 0.00000762939453125. then 8738133 times that is 66.66666412353515625. Since you asked for only 12 digits, you see 66.6666641235. (Note: The float
value is converted to double
to be passed to printf
, but this does not change the value.)
Upvotes: 0
Reputation: 34583
There isn't any float
in the first program. %f
is double
and 3.0
is also double
. The double
type has about 16 decimal digits precision. In the second program the float
is promoted to double
for the variadic function but does not magically gain more precision.
From C11 § 6.4.4.2
4 An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double.
and C11 § 6.5.2.2
6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double.
7 If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.
Upvotes: 2
Reputation: 134406
Only if the precision was missing, it would have been taken as 6. Otherwise, if you specify the precision, it's going to honor that.
Quoting C11
, chapter 7.21.6.1/P8, (emphasis mine)
f,F
A double argument representing a floating-point number is converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; [...]
Upvotes: 1