变量的值为整数和双精度

Value of variable as integer and as double

本文关键字:双精度 整数 变量      更新时间:2023-10-16

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

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

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

Q 是4241297856

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

在小端序中,这个较低的 4 个字节占用的空间与 (int)Q 相同。

0x38000000 939524096


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

在函数中使用错误的格式说明符(如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);

代码未经过测试。

您可以轻松模拟使用此代码发生的情况:

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

*x 现在等于 939524096。

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

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