Tim
Tim

Reputation: 427

Program for float and doubles and how to print floats?

Currently I'm new with C and for a course I'm doing an assignment. The assignment is to write two programs that calculate tan(x) with x incrementing from 0 to pi/2. One program has to work with float numbers and the other program needs to work with double precision numbers. The goal of the assignment is to become aware of the differences in output, since it's part of scientific programming course.

So far I wrote this program:

#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 = %f, tan = %f\n", x, tan(x));
    }
    
    exit(0);
}

I got feedback that the output is double. Yesterday I started a thread related to this code, but since different questions rose up, it seemed appropriate to start a new one.

The general principal of the loop works, but I'm stuck in what to do next.

Let's first work on the double-version of the program. Since I need to calculate tan(x) and x is not 100% exact, due to the decimal incrementation, I think it's important to define the variables as double. Yesterday I learnt that the output of the printf function is double. Therefore I assume that code is correct for the goal to calculate in double.

Here I have a little side question. I also printed .20f and it gave me that specific window. I learned a bit about 32- and 64-bit. Double is 64-bit and can store 15 decimal places in the memory.

Question: Has the above code achieved the double precision goal?

Question: Where do the other decimals (16th to 20th) come from if the memory was already exceeded?

For the float version of the program, I need to define the variables as float.

double x;
double pi;

becomes

float x;
float pi;

Then comes the printf statement and here it becomes a bit confusing, because I know now that the printf function gives output in double precision. But I want single precision and still get it printed. I couldn't find another function that specifically prints in single precision.

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

int main()
{
    float x;

    float pi;
    pi = M_PI;

    for (x = 0; x <= pi / 2; x += pi / 20)
    {
        printf("x = %f, tan = %f\n", x, tan(x));
    }

    exit(0);
}

Question: How do I print in single precision?

Question: What do I need to change in the last program to achieve the goal of the float-program?

I'm eager to learn, but it's a bit hard since we're not allowed at the university anymore due Covid-19. I hope someone could give me feedback.

Thanks, Ter

Upvotes: 0

Views: 633

Answers (2)

chux
chux

Reputation: 153338

Has the above code achieved the the double precision goal?

No. "%f" only prints 6 places after the decimal point, even when not informative for large values and insufficient for tiny ones. To print all the precision, use "%a" - yet this is not a decimal output.

// printf("x = %f, tan = %f\n",x, tan(x));
printf("x = %a, tan = %a\n",x, tan(x));

To print in decimal, and with sufficient informative precision, use "%.*e" or "%.*g". Details.

printf("x = %.*e, tan = %.*e\n",DBL_DECIMAL_DIG-1,x, DBL_DECIMAL_DIG-1,tan(x));
printf("x = %.*g, tan = %.*g\n",DBL_DECIMAL_DIG  ,x, DBL_DECIMAL_DIG  ,tan(x));

Where do the other decimals (16th to 20th) come from if the memory was already exceeded?

This is an artifact of a decimal output, yet the floating point value is encoded with a binary significand. Exact printing of some double takes hundreds of digits. Frequently DBL_DIG to DBL_DECIMAL_DIG significant digits are useful: typically 15 to 17.

How do I print in single precision?
What do I need to change in the last program to achieve the goal of the float-program?

Use float variables and functions and print in exponential notation. Use FLT_DECIMAL_DIG instead of DBL_DECIMAL_DIG.

// printf("x = %f, tan = %f\n",x, tan(x));
printf("x = %.*e, tan = %.*e\n",FLT_DECIMAL_DIG-1,x, FLT_DECIMAL_DIG-1, tanf(x));

For float, often the default of 6 places is OK.

printf("x = %e, tan = %e\n", x, tanf(x));
printf("x = %g, tan = %g\n", x, tanf(x));

  double d = M_PI / 20;
  printf("x = %a, tan = %a\n", d, tan(d));
  printf("x = %.*e, tan = %.*e\n", DBL_DECIMAL_DIG - 1, d, DBL_DECIMAL_DIG - 1, tan(d));
  printf("x = %.*g, tan = %.*g\n", DBL_DECIMAL_DIG, d, DBL_DECIMAL_DIG, tan(d));

  float f = M_PI / 20;
  printf("x = %a, tan = %a\n", f, tan(f));
  printf("x = %.*e, tan = %.*e\n", FLT_DECIMAL_DIG - 1, f, FLT_DECIMAL_DIG - 1, tanf(f));
  printf("x = %e, tan = %e\n", f, tanf(f));
  printf("x = %g, tan = %g\n", f, tanf(f));

x = 0x1.41b2f769cf0ep-3, tan = 0x1.445f0fbb1cf91p-3
x = 1.5707963267948966e-01, tan = 1.5838444032453627e-01
x = 0.15707963267948966, tan = 0.15838444032453627
x = 0x1.41b2f8p-3, tan = 0x1.445f1p-3
x = 1.57079637e-01, tan = 1.58384442e-01
x = 1.570796e-01, tan = 1.583844e-01
x = 0.15708, tan = 0.158384

Upvotes: 2

john
john

Reputation: 87959

printf always prints double but that also means it can print floats since any float can be converted to a double without loss of accuracy. Just because printf prints a double doesn't mean that it can somehow magically add precision to a float.

A double is binary, so it's not meaningful to say that it can store 15 decimal digits. What is true is that the first fifteen decimal digits printed will be accurate.

Upvotes: 3

Related Questions