如何以双精度打印?

Tim*_*Tim 2 c floating-point double

我对 C 完全陌生,我正在尝试完成一项任务。练习是打印 tan(x),x 从 0 递增到 pi/2。

我们需要在 float 和 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);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 为什么我得到浮点数,而我将变量定义为 double 并在 printf 函数中使用 %lf ?

  • 我需要改变什么才能获得双打作为输出?

ryy*_*ker 5

“...但我只打印了floats,而我预期的double

您实际上是在输出double值。

float参数可变参数功能(包括printf()的)被隐式提升到double一般。 参考

所以即使你的陈述

printf("x = %lf, tan = %lf\n",x, tan(x));
Run Code Online (Sandbox Code Playgroud)

改为:

    printf("x = %f, tan = %f\n",x, tan(x));
Run Code Online (Sandbox Code Playgroud)

它仍然会输出double为两者"%f""%lf"并用作(和其他可变参数函数)的double格式说明符printf()

编辑以解决评论中的以下声明/问题:

“我知道双重符号有 15 位 [精度]。”

是的。但是/数据类型的实际IEEE 754指定特征与在函数中使用格式说明符可以_使它们出现的方式之间存在差异。floatdoubleprintf()

简单来说:

  • double具有 a 的双倍(2x) 精度float

  • float是一个 32 位的IEEE 754单精度浮点数,其中 1 位是符号,8 位是指数,24 *是值,得到 7位十进制数的精度。

  • double是一个 64 位IEEE 754双精度浮点数,其中 1 位是符号,11 位是指数,53 *位是产生 15位十进制精度的值。

* - 包括隐式位(对于正常数总是等于 1,对于次正规数总是等于 0。这个隐式位不存储在内存中),但不包括符号位。

“...但是使用 %.20f 我能够打印更多数字,这怎么可能,这些数字来自哪里?”

额外的数字是由模拟数字的二进制表示引起的不准确,再加上使用宽度说明符强制显示比存储值实际表示的信息更多的信息。

尽管宽度说明符有其应有的地位,但它们也可能导致提供误导性的结果。