Search code examples
cfloating-pointdouble

Why is double printing the same value as float in C when they have different sizes?


I need to do calculations using π. When I checked precision of M_PI, it only printed 7 decimal digits. So I #defined my own MY_PI. But I am still facing the same problem. double should support 15-17 decimal digits. Why am I only getting 6

#define MY_PI 3.1415926535897932384626433832795028841971
#include<stdio.h>
#include<math.h>
int main()
{
    printf("%f\n%lf\n%20lf\n",M_PI,M_PI,M_PI);
    printf("%d\n%d\n",sizeof(float),sizeof(double));
    printf("%f\n%lf\n%20lf\n",MY_PI,MY_PI,MY_PI);
    return 0;
}

Executing the code results in this,

3.141593
3.141593
            3.141593
4
8
3.141593
3.141593
            3.141593

Process returned 0 (0x0)   execution time : 0.080 s
Press any key to continue.



Solution

  • C does not pass type information about arguments to a function. printf takes all type information from the format string you pass it.

    For historical reasons, both %f and %lf tell printf to expect a double argument. Per C 2018 7.21.6.1 8, %f instructs printf:

    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;…

    Thus six digits are printed merely because that is the default, not because of anything particularly to do with the type. To see more digits, request more digits:

    printf("%.60f\n", M_PI);
    

    This will commonly print:

    3.141592653589793115997963468544185161590576171875000000000000
    

    Note that %20f requests a field width of 20 characters. A field width is typically used for spacing, to help align columns of data over multiple lines. To satisfy a field width, spaces are used for padding. The code above uses %.60f to request precision, which controls the number of digits produced.