2016-10-23 4 views
-2

나는 약 1 시간 동안이 코드를 알아 내려고 노력하고 있지만 여전히 운이 없다.노동 조합 출력으로 고생하다

#include <stdio.h> 
#include <stdlib.h> 

int f(float f) 
{ 
    union un {float f; int i;} u = {f}; 

    return (u.i&0x7F800000) >> 23; 
} 

int main() 
{ 
    printf("%d\n", f(1)); 

return 0; 
} 

나는이 작품은, 내가 F (1), F를 시도했습니다 이해가 안 돼요 (2), F (3), F (4) 물론 다른 결과를 얻는. 나는 또한 노동 조합에 대해서 많이 읽었습니다. 내가 반환에서 0x7F800000을 삭제하면 결과가 동일하게 나타났습니다. 나는 u.i가 생성되는 방법을 알고 싶다. 분명히 임의의 쓰레기는 아니지만 함수 인자에서 하나가 아니다. 여기서 무슨 일이 일어나고 있고, 어떻게 작동합니까?

답변

2

이것은 실제로 부동 소수점 숫자가 메모리에서 어떻게 표현되는지 이해합니다. (IEEE 754 참조). (23) 수에 대한 지수 것 -

은 즉, 32 비트 플로팅 포인트 수는 총 개수 30

  • 비트의 부호 비트가 될 것이다하기 구조

    • 비트 31을 갖 편향된 127
    • 비트 22 - 0은 숫자의 분수 부분을 나타냅니다. 이것은 10 진수 (실제로는 2 진수) 앞의 숫자가 1이되도록 정규화됩니다.

      union un 
          { 
           float f; 
           int i; 
          }; 
      

      32 비트를 생성한다 :

    • 조합에 관해서

    는 연합시의 유형 중 하나를 수납 할 수있는 컴퓨터의 메모리 블록이므로 선언 리콜 주어진 시간에 부동 소수점 또는 정수를 저장할 수있는 메모리 블록. 이제 부동 소수점 매개 변수를 사용하여 함수를 호출하면 해당 숫자의 비트 패턴이 un의 메모리 위치에 기록됩니다. 이제 i 멤버를 사용하여 유니온에 액세스하면 비트 패턴이 정수로 처리됩니다. s는 부호 비트, 지수 e 비트 f 분수 비트를 나타내는 whese

    따라서, 32 비트 부동 소수점 숫자의 일반 레이아웃은 seee eeee efff ffff ffff ffff ffff ffff이다. 좋아, 일종의 횡설수설, 잘하면 모범이 도움이 될지도 모른다.

    4를 IEEE 부동 소수점으로 변환하려면 먼저 7을 2 진수로 변환하십시오 (저는 32 비트 숫자를 4 비트 니블로 분리했습니다).

    4 = 0000 0000 0000 0000 0000 0000 0000 0111 
    

    이제 우리는이를 정상화 할 필요가 즉 두 가지의 거듭 제곱 숫자로이 표현;

    1.11 x 2^2 
    

    여기서 우리는 두 가지의 각 전원은 (10의 힘을 다루는 유사) 장소에 오른쪽으로 진 지점을 이동 것을 기억해야합니다. 이에서

    , 우리는 이제 전체 부호 비트는 지수가 2 0

  • 그래서, 비트 패턴

    1. 수의 전체 부호가 정의를 생성하지만, 우리는 할 수 있습니다 127의 지수를 127로 바이어스합니다. 즉, -127의 지수는 0으로 저장되고 127의 지수는 255로 저장됩니다. 따라서 지수 필드는 129 또는 1000 0001이됩니다.

    2. 마침내 정규화 된 숫자는 1100 0000 0000 0000 0000 000 000이됩니다. 항상 '1'이 나오기 때문에 '1'을 생략했습니다.

    3. 비트 패턴으로 우리가 모두 함께이 퍼팅 :

      0000 0000 0000 0000 이제

    = 0100 0000 1110 0000

    네, 여기에 마지막으로 조금있는 비트 단위 0x7F800000으로 을 이진수로 쓰면 0111 1111 1000 0000 0000 0000 0000 0000이됩니다.이 값을 IEEE 부동 소수점 숫자의 일반적인 배치와 비교하면 마스크로 선택하는 부분이 지수 비트가되는 것을 볼 수 있습니다. 왼쪽으로 23 비트.

    그래서 프로그램은 부동 소수점 수의 바이어스 된 지수를 인쇄하고 있습니다. 예를 들어,

    #include <stdio.h> 
        #include <stdlib.h> 
    
        int f(float f) 
        { 
         union un {float f; int i;} u = {f}; 
    
         return (u.i&0x7F800000) >> 23; 
        } 
    
        int main() 
        { 
         printf("%d\n", f(7)); 
         return 0; 
        } 
    

    은 우리가 예상 한대로 129의 출력을 제공합니다.