float 和 doubles 的程序以及如何打印 floats?

Program for float and doubles and how to print floats?

目前我是 C 语言的新手,正在为一门课程做作业。作业是编写两个程序来计算 tan(x)x 从 0 递增到 pi/2。一个程序必须处理浮点数,而另一个程序需要处理双精度数。作业的目标是了解输出的差异,因为它是科学编程课程的一部分。

到目前为止我写了这个程序:

#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);
}

我收到反馈说输出是双倍的。昨天我开了一个跟这段代码相关的跟帖,但是因为出现了不同的问题,所以开一个新的好像比较合适。

循环的一般原理有效,但我不知道下一步该怎么做。

我们先来做双版的程序。由于我需要计算 tan(x) 并且 x 不是 100% 精确的,由于小数增量,我认为将变量定义为 double 很重要。昨天了解到printf函数的输出是double。因此,我假设代码对于以双精度计算的目标是正确的。

这里我有一个小问题。我还打印了 .20f,它给了我特定的 window。我了解了一些关于 32 位和 64 位的知识。 Double 是 64 位的,可以在内存中存储 15 位小数。

问题:上面的代码是否达到了双精度的目的?

问题:如果内存已经超出,其他小数(16位到20位)从哪里来?

对于float版本的程序,我需要将变量定义为float。

double x;
double pi;

变成

float x;
float pi;

然后是 printf 语句,在这里它变得有点混乱,因为我现在知道 printf 函数以双精度输出。但我想要单精度并且仍然打印它。我找不到另一个专门以单精度打印的函数。

#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);
}

问:如何进行单精度打印?

问题:上一个程序需要修改什么才能达到浮动程序的目的?

我很想学习,但是有点难,因为 Covid-19 不允许我们上大学。我希望有人能给我反馈。

谢谢, 三

printf 总是打印双精度,但这也意味着它可以打印浮点数,因为任何浮点数都可以转换为双精度而不损失精度。仅仅因为 printf 打印出双精度数并不意味着它可以以某种方式神奇地增加浮点数的精度。

一个double是二进制的,所以说它可以存储15位十进制数字是没有意义的。事实是打印的前十五位十进制数字是准确的。

Has the above code achieved the the double precision goal?

没有。 "%f" 仅打印小数点后 6 位,即使对于大值没有信息,对于小值也不够。要打印所有精度,请使用 "%a" - 但这不是十进制输出。

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

要以十进制打印并具有足够的信息精度,请使用 "%.*e""%.*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?

这是十进制输出的产物,但浮点值是用二进制有效编码的。某些 double 的精确打印需要数百位数字。通常 DBL_DIGDBL_DECIMAL_DIG 有效数字是有用的:通常是 15 到 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?

使用float变量和函数并以指数表示法打印。使用 FLT_DECIMAL_DIG 而不是 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));

对于float,往往默认6个地方就可以了

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