当传递浮点常量而不是变量时,为什么%f打印较大的值?


9

在给定程序中,为什么每个printfs 得到不同的结果?

#include <stdio.h>
int main()
{
    float c = 4.4e10;
    printf("%f\n", c);
    printf("%f\n", 4.4e10);
    return 0;
}

它显示以下输出:

44000002048.000000
44000000000.000000

4
到目前为止的答案说明这4.4e10是一个double常量,float在初始化时转换为常量,cdouble在传递到时保持为a printf。但是,您可能还想知道,添加f后缀使其成为float常数:打印4.4e10f将显示与初始化c到相同的值4.4e10f。将float常量与double常量区分开对使用浮点算法进行质量工作很重要。
Eric Postpischil

这个转换方法有什么名字吗?我想读一读。
user10056563

您是否想知道从C 转换double到的时间float?还是您想知道转换产生的值,即转换产生了什么影响?或者是其他东西?
Eric Postpischil,

既不质疑这里的答复,也不质疑标准,但是,当我还年轻的时候,C我们就使用printf("%f",x)了a floatprintf("%lf",x)a double。什么时候变了?以及如何显式地打印一个(单个)float- printf("%hf",x)
阿德里安·摩尔

2
%lfprintf中的@Adrian 与相同%f。甲float在可变参数被转换为一个double由编译器,就像一个short被转换成一个int
SS安妮

Answers:


9

A float是一种具有32位浮点数的类型,而常数4.4e10表示a double,它具有64位浮点数(即精度浮点数)

分配4.4e10给时c4.4e10无法精确表示该值(参数的尾数舍入误差),并且存储了最接近的可能值(44000002048)。当传递给时printf,它会被提升double,包括舍入误差。

在第二种情况下,该值是double整个时间,没有缩小和扩大,并且恰好是a double可以准确表示该值的情况。

如果这是不良行为,则可以c将a 声明为double更高的精度(但是请注意,最终仍然会达到精度限制)。


3

您实际上是在这里打印两种不同类型的值。

在第一种情况下,您是将值赋给type变量float。a的精度float大约是6或7个十进制数字,因此,除非可以精确表示该值,否则您会看到该类型可以表示的最接近的值。

在第二种情况下,您要传递4.4e10具有type 的常量double。此类型的精度大约为16位十进制数字,并且该值在该范围内,因此将打印准确的值。


为什么特别在末尾打印2048?
user10056563

@ user10056563因为这是可以存储在32位float中的最接近4.4e10的数字。
dbush
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.