我知道以下内容不会打印2.9或3.我可以纠正它,但我真的想了解内部发生的事情,因此它正在打印:
858993459
这个数字是怎么来的?
我在Windows 32位下运行
int main()
{
double f = 1.9;
int t = 1;
printf("%d\n", t+f);
return 0;
}
更新
仅仅相信这将是“未定义的行为”对我来说是不可能的,所以我想进一步调查它。我发现this answer正是我想要了解的内容。
答案 0 :(得分:4)
您使用了错误的格式说明符。请改用%f
。
根据隐式类型提升规则,在执行t+f
时,t
将被提升为double
。您正在尝试使用double
打印%d
值,该值应该是int
。
注意:使用错误的格式说明符时,行为未定义。
相关阅读: c99
标准,第7.19.6.1章,第9段,(强调我的)
如果转换规范无效,则行为未定义。 如果有任何参数 不是相应转换规范的正确类型,行为是 未定义。 强>
答案 1 :(得分:4)
您尝试使用double
打印%d
时发生了什么事,因此printf
将integer
解释为double
,但是为了您理解为什么要打印此值,您必须了解C语言如何存储IEEE 754 standard
,C使用%d
:
所以double
将此解释为整数,当你添加一个int和一个双C时,将其保持为double
不丢失任何部分,结果为%d
,并且integer
将此总和解释为%f
,并且格式不同,您会看到垃圾。
您应该使用{{1}}代替。
答案 2 :(得分:4)
正如其他人已经提到的,这是未定义的行为。但是通过对机器架构采取一些假设,可以回答为什么打印这些数字:
使用IEEE 754 64位格式表示双精度值,2.9
的值是存储为0x4007333333333333
的值。
在Little-Endian机器中,%d
说明符将读取该值的低4字节,即0x33333333
,等于858.993.459
答案 3 :(得分:2)
你试图根据拇指规则(类型提升规则)添加整数和双精度,即当这个加法发生时,整数将被提升为double并且总和将发生并且你试图使用{{打印double值1}}格式说明符,它将导致未定义的行为。
使用%d
代替
PS:使用错误的格式指定器来打印值将导致您在此处看到的未定义行为。
答案 4 :(得分:-1)
%d
会将double
转移到int
double f = 1.9;
printf("%d\n", f);
输出:
1717986918
计算机以不同方式存储int
和double
,您可以在此处查看:
http://en.wikipedia.org/wiki/Double-precision_floating-point_format