将一个Integer添加到不按预期工作的浮点数

时间:2014-12-23 13:54:48

标签: c

我知道以下内容不会打印2.9或3.我可以纠正它,但我真的想了解内部发生的事情,因此它正在打印:

  

858993459

这个数字是怎么来的?

我在Windows 32位下运行

int main()
{
    double f = 1.9; 
    int t = 1;

    printf("%d\n", t+f); 

    return 0; 
}

更新

仅仅相信这将是“未定义的行为”对我来说是不可能的,所以我想进一步调查它。我发现this answer正是我想要了解的内容。

5 个答案:

答案 0 :(得分:4)

您使用了错误的格式说明符。请改用%f

根据隐式类型提升规则,在执行t+f时,t将被提升为double。您正在尝试使用double打印%d值,该值应该是int

注意:使用错误的格式说明符时,行为未定义。

相关阅读: c99标准,第7.19.6.1章,第9段,(强调我的)

  

如果转换规范无效,则行为未定义。 如果有任何参数   不是相应转换规范的正确类型,行为是   未定义。

答案 1 :(得分:4)

您尝试使用double打印%d时发生了什么事,因此printfinteger解释为double,但是为了您理解为什么要打印此值,您必须了解C语言如何存储IEEE 754 standard,C使用%d

enter image description here

所以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

计算机以不同方式存储intdouble,您可以在此处查看: http://en.wikipedia.org/wiki/Double-precision_floating-point_format