memcpy não fazer, uma vez que é suposto
Pergunta
Eu tenho este pedaço de código que está a emitir os resultados errados.
#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;
}
a saída que eu vejo é
bytes 0xC0000000 flutuador -2.000001e + 00
Eu estou esperando para começar
bytes 0xDEADBEEF flutuador -6.2598534e + 18
edição # 1 como foi salientado o endianness poderia ser diferente o que resultaria na seguinte
bytes 0xefbeadde flutuador -1.1802469e + 29
O que eu não entendo é o elenco de float para int não assinado resultando em 0xC0000000 (o flutuador no mesmo estar declaração printf -2,0000 eu atribuiria a otimização do compilador)
este foi trabalhar antes em um computador diferente. Poderia ser uma mudança de arquitetura.
Solução
Não é problema de memcpy.
-
float
é allways convertido paradouble
quando passou...
de printf, então você simplesmente não pode obter 4 bytes na maioria das arquiteturas Intel. - quando você expacting
0xdeadbeef
neste código, você assumir que a sua arquitetura é Big Endian. Há muitas arquiteturas endian pouco, por exemplo Intel x86.
Outras dicas
Você percebe que flutua são promovidos para o dobro quando passado para uma função parâmetros variáveis ??como printf ()? Então, quando você diz:
printf("bytes 0x%x float %e\n", flt, flt);
você está tentando tratar o que é realmente dois valores de 8 bytes como dois de 4 bytes valores, dando (creio eu) um comportamento indefinido.
O "% x" em printf espera um int não assinado. Você está dando-lhe uma bóia que está sendo convertido automaticamente e não é isso que você quer. Você quer fazer algo como:
printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);
Oh, e como alguém fora pontas, se você estiver em x86 você não vai ver 0xDEADBEEF, mais como 0xefbeadde.
Veja se isso é melhor:
printf("bytes 0x%x float %e\n", *(int *)&flt, flt);
Para ver a promoção parâmetro, alterar a declaração de float para double. Na minha máquina, que imprime:
bytes 0xefbeadde float -1.860545e+230
O 0xefbeadde é big-endian para deadbeaf. Os últimos 4 bytes da dupla está indefinido, de modo que o número exibido após o flutuador irá variar.
Você mencionou que funcionou em outro computador, que tipo de computador que foi isso? Deve ter sido pequeno endian onde sizeof (float) == sizeof (double):)