Tim
Tim

Reputation: 427

How do I print in double precision?

I'm completely new to C and I'm trying to complete an assignment. The exercise is to print tan(x) with x incrementing from 0 to pi/2.

We need to print this in float and double. I wrote a program that seems to work, but I only printed floats, while I expected double.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    double x;
    
    double pi;
    pi = M_PI;
     
    for (x = 0; x<=pi/2; x+= pi/20)
    {
        printf("x = %lf, tan = %lf\n",x, tan(x));
        
    }
    
    exit(0);
}

My question is:

Upvotes: 4

Views: 2929

Answers (2)

ryyker
ryyker

Reputation: 23208

"...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 is assumed during computation.

"...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 their rightful place, if used carelessly they can produce misleading results.

Upvotes: 7

chux
chux

Reputation: 153303

Why do I get floats, while I defined the variables as double and used %lf in the printf function?

Code is not getting "floats", output is simply text. Even if the argument coded is a float or a double, the output is the text translation of the floating point number - often rounded.

printf() simply follows the behavior of "%lf": print a floating point value with 6 places after the decimal point. With printf(), "%lf" performs exactly like "%f".

printf("%lf\n%lf\n%f\n%f\n", 123.45, 123.45f, 123.45, 123.45f);
// 123.450000
// 123.449997
// 123.450000
// 123.449997

What do I need to change to get doubles as output?

Nothing, the output is text, not double. To see more digits, print with greater precision.

printf("%.50f\n%.25f\n", 123.45, 123.45f);
// 123.45000000000000284217094304040074348449710000000000
// 123.4499969482421875000000000

how do I manipulate the code so that my output is in float notation?

Try "%e", "%a" for exponential notation. For a better idea of how many digits to print: Printf width specifier to maintain precision of floating-point value.

printf("%.50e\n%.25e\n", 123.45, 123.45f);
printf("%a\n%a\n", 123.45, 123.45f);

// 1.23450000000000002842170943040400743484497100000000e+02
// 1.2344999694824218750000000e+02
// 0x1.edccccccccccdp+6
// 0x1.edccccp+6

printf("%.*e\n%.*e\n", DBL_DECIMAL_DIG-1, 123.45, FLT_DECIMAL_DIG-1,123.45f);
// 1.2345000000000000e+02
// 1.23449997e+02

Upvotes: 1

Related Questions