我有一些输出错误结果的代码。
#include <stdio.h>
#include <string.h>
int main()
{
unsigned char bytes[4];
float flt=0;
bytes[0]=0xde;
bytes[1]=0xad;
bytes[2]=0xbe;
bytes[3]=0xef;
memcpy( &flt, bytes, 4);
printf("bytes 0x%x float %e\n", flt, flt);
return 0;
}
我得到的输出是
字节0xc0000000浮点-2.000001e + 00
我期待得到
bytes 0xdeadbeef float -6.2598534e + 18
编辑#1 正如所指出的那样,字节序可能会有所不同,这将导致以下
bytes 0xefbeadde float -1.1802469e + 29
我不明白的是从float到unsigned int的转换导致0xc0000000(同一个printf语句中的float为-2.0000我将属于编译器优化)
之前在另一台计算机上工作过。这可能是一次架构改变。
答案 0 :(得分:8)
这不是memcpy的问题。
float
在通过double
printf传递时始终转换为...
,因此您无法在大多数英特尔架构上获得4个字节。0xdeadbeef
时,您认为您的体系结构是BIG端。有许多小端架构,例如Intel x86。答案 1 :(得分:6)
你是否意识到当传递给像printf()这样的变量参数函数时,浮点数会被提升为double?所以当你说:
printf("bytes 0x%x float %e\n", flt, flt);
您正在尝试处理真正的两个8字节值,如两个4字节 价值观,给予(我相信)未定义的行为。
答案 2 :(得分:2)
printf中的“%x”需要一个unsigned int。你给它一个浮动,它会自动转换,这不是你想要的。你想做类似的事情:
printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);
哦,就像其他人指出的那样,如果你在x86上,你就不会看到0xdeadbeef,更像是0xefbeadde。
答案 3 :(得分:1)
看看这是否更好:
printf("bytes 0x%x float %e\n", *(int *)&flt, flt);
答案 4 :(得分:1)
要查看参数提升,请将声明从float更改为double。在我的机器上,打印:
bytes 0xefbeadde float -1.860545e+230
0xefbeadde是deadbeaf的大端。双精度的最后4个字节是未定义的,因此浮点数后显示的数字会有所不同。
你提到它在另一台计算机上运行,那是什么类型的计算机?一定是小端,其中sizeof(float)== sizeof(double):)