문제

잘못된 결과를 출력하는이 코드가 있습니다.

#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 float -2.000001e+00

나는 얻을 것으로 기대한다

바이트 0xdeadbeef float -6.2598534e+18

지적한대로 #1 편집 엔디 니스가 다를 수있어 다음이 발생할 수 있습니다.

바이트 0xefbeadde float -1.1802469E+29

내가 이해하지 못하는 것은 플로트에서 서명되지 않은 int로 캐스트가 0xC0000000을 초래하는 것입니다 (동일한 printf 문의 플로트는 -2.0000입니다. 컴파일러 최적화에 귀속됩니다).

이것은 다른 컴퓨터에서 이전에 작동했습니다. 건축 변화 일 수 있습니다.

도움이 되었습니까?

해결책

memcpy의 문제가 아닙니다.

  1. float Allways가 전환됩니다 double 지나갔을 때 ... Printf의 경우 대부분의 인텔 아키텍처에서 4 바이트를 얻을 수 없습니다.
  2. 당신이 모출 할 때 0xdeadbeef 이 코드에서는 건축이 Big Endian이라고 가정합니다. 예를 들어 Intel X86과 같은 작은 엔디 언 아키텍처가 많이 있습니다.

다른 팁

Printf ()와 같은 가변 매개 변수 기능으로 전달 될 때 플로트가 두 배로 촉진된다는 것을 알고 있습니까? 그래서 당신이 말할 때 :

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

당신은 실제로 두 개의 4 바이트 값과 같은 두 개의 8 바이트 값을 취급하려고 노력하고 있으며, 정의되지 않은 행동을 제공합니다.

printf의 "%x"는 서명되지 않은 int를 기대합니다. 당신은 그것을 자동으로 변환하는 플로트를 제공하며, 당신이 원하는 것이 아닙니다. 당신은 다음과 같은 일을하고 싶습니다.

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

아, 그리고 다른 사람이 지적했듯이, 당신이 x86에 있다면 0xdeadbeef, 0xefbeadde와 같은 0xdeadbeef를 보지 못할 것입니다.

이것이 더 나은지 확인하십시오.

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

매개 변수 프로모션을 보려면 선언을 플로트에서 더블로 변경하십시오. 내 기계에서 그 인쇄 :

bytes 0xefbeadde float -1.860545e+230

0xefbeadde는 Deadbeaf의 빅 엔디언입니다. 더블의 마지막 4 바이트는 정의되지 않으므로 플로트 후 표시된 숫자는 다릅니다.

당신은 그것이 다른 컴퓨터에서 작동했다고 언급했습니다. 어떤 종류의 컴퓨터가 있었습니까? Sizeof (float) == sizeof (double)에서 작은 엔디언이었을 것입니다. :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top