memcpy 没有按预期执行
我有这段输出错误结果的代码。
#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
我期望得到
字节0xdeadbeef浮点-6.2598534e+18
编辑#1 正如所指出的,字节序可能不同,这将导致以下结果
字节0xefbeadde浮点-1.1802469e+29
我不明白的是从 float 到 unsigned int 的转换导致 0xc0000000 (同一 printf 语句中的 float 为 -2.0000 我将归因于编译器优化)
这之前在不同的版本上工作过电脑。 这可能是架构的改变。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不是memcpy的问题。
...
时,float
总是转换为double
,因此在大多数英特尔架构上你无法获得 4 个字节。0xdeadbeef
时,您假设您的架构是 BIG endian。 有许多小端架构,例如 Intel x86。It is not problem of memcpy.
float
is allways converted todouble
when passed over...
of printf, so you just can't get 4 bytes on most of intel architectures.0xdeadbeef
in this code, you assume that your architecture is BIG endian. There are many little endian architectures, for example Intel x86.您是否意识到当传递给像 printf() 这样的可变参数函数时,浮点数会提升为双精度? 因此,当您说:
您试图将两个 8 字节值视为两个 4 字节值时
价值观,给出(我相信)未定义的行为。
You do realise that floats are promoted to double when passed to a variable parameters function like printf()? So when you say:
you are trying to treat what is really two 8-byte values like two 4-byte
values, giving (I believe) undefined behaviour.
printf 中的“%x”需要一个无符号整型。 你给它一个浮点数,它会自动转换,但这不是你想要的。 你想要做类似的事情:
哦,正如其他人指出的,如果你在 x86 上,你不会看到 0xdeadbeef,更像是 0xefbeadde。
The "%x" in printf expects an unsigned int. You're giving it a float which is getting automatically converted and that's not what you want. You want to do something like:
Oh, and as someone else pointed out, if you're on x86 you're not going to see 0xdeadbeef, more like 0xefbeadde.
看看这个是否更好:
See if this is any better:
要查看参数提升,请将声明从 float 更改为 double。 在我的机器上,打印:
0xefbeadde is big-endian for deadbeaf。 double 的最后 4 个字节未定义,因此 float 后显示的数字会有所不同。
你提到它可以在另一台计算机上运行,那是什么类型的计算机? 必须是小端字节序,其中 sizeof(float) == sizeof(double) :)
To see the parameter promotion, change the declaration from float to double. On my machine, that prints:
The 0xefbeadde is big-endian for deadbeaf. The last 4 bytes of the double are undefined, so the number displayed after float will vary.
You mentioned it worked on another computer, what kind of computer was that? Must've been small endian where sizeof(float) == sizeof(double) :)