"...but I only printed floats
, while I expected double
"
You are actually outputting double
values.
float
arguments to variadic functions (including printf()) are implicitly promoted to double
in general. reference.
So even if your statement
printf("x = %lf, tan = %lf\n",x, tan(x));
were changed to:
printf("x = %f, tan = %f\n",x, tan(x));
It would still output double
as both "%f"
and "%lf"
are used as double
format specifiers for printf()
(and other variadic functions).
Edit to address following statement/questions in comments:
"I know that a double notation has 15 digits of [precision]."
Yes. But there is a difference between the actual IEEE 754
specified characteristics of the float
/double
data types, and the way that they can be _made to appear using format specifiers in the printf()
function.
In simplest terms:
double
has double (2x) the precision of a float
.
float
is a 32 bit IEEE 754 single precision Floating Point Number with 1 bit for the sign, 8 bits for the exponent, and 24* for the value, resulting in 7 decimal digits of precision.
double
is a 64 bit IEEE 754 double precision Floating Point Number with 1 bit for the sign, 11 bits for the exponent, and 53* bits for the value resulting in 15 decimal digits of precision.
*
- including the implicit bit (which always equals 1 for normal numbers, and 0 for subnormal numbers. This implicit bit is not stored in memory), but not the sign bit.
"...But with %.20f I was able to print more digits, how is that possible and where do the digits come from?"
The extra digits are inaccuracies caused by binary representation of analog numbers, coupled with using a width specifier to force more information to display than what is actually represented by the stored value.
Although width specifiers have there rightful place, they can also result in providing misleading results.