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.

Foi útil?

Solução

Não é problema de memcpy.

  1. float é allways convertido para double quando passou ... de printf, então você simplesmente não pode obter 4 bytes na maioria das arquiteturas Intel.
  2. 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):)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top