变量的值为整数和双精度

Value of variable as integer and as double

所以我有一个无符号整数Q,值为0xfccd11c0。

当我用 printf("%i", Q); 打印它时,我得到 -53669440,它是 0xfccd11c0 的有符号整数表示,所以我明白了。

但是当我用 printf("%i", (double)Q); 打印它时,我得到 939524096。我知道为了打印双精度值,您需要使用 %f 作为字符串格式,但是,仍然会发生什么转换为 double 时导致打印该值?

在函数中使用错误的格式说明符,例如 printf 会触发未定义的行为;在这种情况下,任何事情都可能发生。

在这里,Q 被(由您)显式转换为一个新的内存对象,我们称它为Q_dbl。它被传递给 printf 函数,但是当您指定 %i 参数时,这块内存被解释为整数。这是低级别发生的事情的想法。

unsigned int Q = 0xfccd11c0;

printf("%i", Q);
printf("%i", (double)Q);

auto Q_dbl = (double)Q;

printf("%f", Q_dbl);
printf("%i", Q_dbl);

代码未经测试。

Q为4241297856

(double)Q 有 64 位 IEEE-754 表示 0x41EF99A238000000

在 little-endian 中,它的低 4 字节占用与 (int)Q 相同的 space。

0x38000000 为 939524096


便捷的在线转换器:http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html

你可以很容易地模拟这段代码会发生什么:

unsigned int Q = 0xfccd11c0;
double dQ = (double)Q;
int *x = (int*)(&dQ);

*x 现在等于 939524096。

请参阅我对类似问题的回答:。基本上,C 编译器在两组不同的注册表上执行整数和浮点运算,并且 printf 从对应于格式字符串的注册表中提取它的参数。这是导致 printf 在格式字符串和传递的参数不匹配时出现奇怪行为的原因之一。

请注意,当编译器优化将参数放置在可用的注册表中而不是将它们放置在堆栈中时,这会发生在参数数量减少的情况下。