Memcpy does not do as it is supposed to

I have this bit of code that is outputting incorrect 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 i get is

bytes 0xc0000000 float -2.000001e + 00

I expect to receive

bytes 0xdeadbeef float -6.2598534e + 18

edit # 1 as mentioned, the statement may be different, resulting 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 (float in the same printf expression equal to -2.0000 I would attribute to compiler optimizations)

it worked on another computer. It could be an architecture change.

+1


a source to share


5 answers


This is not a memcpy problem.



  • float

    always converts to double

    when sent over ...

    printf, so you just can't get 4 bytes on most Intel architectures.
  • when you use 0xdeadbeef

    in this code, you assume that your architecture is BIG endian. There are many small architectures such as Intel x86.
+8


a source


Do you realize that floats are promoted to double when passing variable parameters to a function like printf ()? So when you say:

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

      



you are trying to handle what is actually two 8 byte values, such as two 4 byte values ​​giving (I believe) undefined behavior.

+6


a source


"% x" in printf expects an unsigned int. You give it a float, which is 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 won't see 0xdeadbeef anymore like 0xefbeadde.

+2


a source


See if this is better:

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

      

+1


a source


To see the parameter progress, change the declaration from float to double. On my machine, this prints:

bytes 0xefbeadde float -1.860545e+230

      

0xefbeadde is the big-endian for deadbeaf. The last 4 bytes of the double are undefined, so the number displayed after the float will change.

You mentioned that he was working on another computer, what is this computer? Must be a little endian where sizeof (float) == sizeof (double) :)

+1


a source







All Articles