memcpy 没有按预期执行

发布于 2024-07-19 11:25:48 字数 730 浏览 4 评论 0 原文

我有这段输出错误结果的代码。

#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 我将归因于编译器优化)

这之前在不同的版本上工作过电脑。 这可能是架构的改变。

I have this bit of code that is outputting the wrong results.

#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;
}

the output that I get is

bytes 0xc0000000 float -2.000001e+00

I am expecting to get

bytes 0xdeadbeef float -6.2598534e+18

edit #1
as was pointed out the endianness could be different which would result in the following

bytes 0xefbeadde float -1.1802469e+29

what I don't understand is the cast from float to unsigned int resulting in 0xc0000000 (the float in the same printf statement being -2.0000 I would attribute to compiler optimization)

this was working before on a different computer. It could be an architecture change.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一杆小烟枪 2024-07-26 11:25:48

不是memcpy的问题。

  1. 当传递给 printf 的 ... 时,float 总是转换为 double,因此在大多数英特尔架构上你无法获得 4 个字节。
  2. 当您在此代码中解释 0xdeadbeef 时,您假设您的架构是 BIG endian。 有许多小端架构,例如 Intel x86。

It is not problem of memcpy.

  1. float is allways converted to double when passed over ... of printf, so you just can't get 4 bytes on most of intel architectures.
  2. when you expacting 0xdeadbeef in this code, you assume that your architecture is BIG endian. There are many little endian architectures, for example Intel x86.
戴着白色围巾的女孩 2024-07-26 11:25:48

您是否意识到当传递给像 printf() 这样的可变参数函数时,浮点数会提升为双精度? 因此,当您说:

printf("bytes 0x%x float %e\n", flt, flt);

您试图将两个 8 字节值视为两个 4 字节值时
价值观,给出(我相信)未定义的行为。

You do realise that floats are promoted to double when passed to a variable parameters function like printf()? So when you say:

printf("bytes 0x%x float %e\n", flt, flt);

you are trying to treat what is really two 8-byte values like two 4-byte
values, giving (I believe) undefined behaviour.

乖不如嘢 2024-07-26 11:25:48

printf 中的“%x”需要一个无符号整型。 你给它一个浮点数,它会自动转换,但这不是你想要的。 你想要做类似的事情:

printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);

哦,正如其他人指出的,如果你在 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:

printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);

Oh, and as someone else pointed out, if you're on x86 you're not going to see 0xdeadbeef, more like 0xefbeadde.

末蓝 2024-07-26 11:25:48

看看这个是否更好:

printf("bytes 0x%x float %e\n", *(int *)&flt, flt);

See if this is any better:

printf("bytes 0x%x float %e\n", *(int *)&flt, flt);
ˇ宁静的妩媚 2024-07-26 11:25:48

要查看参数提升,请将声明从 float 更改为 double。 在我的机器上,打印:

bytes 0xefbeadde float -1.860545e+230

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:

bytes 0xefbeadde float -1.860545e+230

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) :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文