ale*_* jw -1 c floating-point int printf
#include <stdio.h>
int main(void) {
printf("%d\n", 50.2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
〜当我执行它时.
50.2的二进制是(0100 0010 0100 1000 1100 1100 1100 1101).
所以,我预计1,112,067,277,但是,值不是,也不是固定的.
每次都会改变这些值,为什么?
看似随机值的原因是,在您的平台上printf()需要浮点/双参数的其他寄存器中的整数参数.在x86_64上,例如%esi(int)与%xmm0(float)
根据C标准,这是可以的,因为你因为错误的转换说明符而调用了未定义的行为.
问题是你在printf中使用了错误的格式说明符,%d而不是%f.这会调用未定义的行为.
每当您调用未定义的行为时,都不会有任何确定性或预期的输出.当你有未定义的行为时,编译器可以继续进行奇怪的假设,例如"从未使用过这个浮点字面值,所以不需要为它分配内存".这意味着您可能最终打印垃圾内存位置甚至导致程序崩溃.因此,分析未定义行为给出某种结果的原因并不是一项有意义的任务.
为了保证确定性行为,您必须执行以下操作:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
int main(void)
{
const double number = 50.2;
union
{
double d;
uint8_t u8 [sizeof(double)];
} u = { number };
printf("Binary representation of %f:\n", number);
for(size_t i=0; i<sizeof(double); i++)
{
printf("%.2" PRIx8 " ", u.u8[i]);
}
printf("\n\n");
printf("Integer (nonsense) representation of %f:\n", number);
int i;
memcpy(&i, u.u8, sizeof(int));
printf("%d", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Binary representation of 50.200000:
9a 99 99 99 99 19 49 40
Integer (nonsense) representation of 50.200000:
-1717986918
Run Code Online (Sandbox Code Playgroud)
这是在一台机器上,其中double是8字节和整数4字节/小端,这意味着你将4个最低有效字节作为一些无意义输出(即数字9999999Ah).