[Computer Architecture] Floating-point notation

컴퓨터는 숫자를 저장할때 우리들이 사용하는 10진수(decimal)을 사용하지 않는다.

true- false의 반복인 0 1 0 1 1 1 1 0 1 1 1 0 0 이런식으로 저장을 한다.

Binary , 즉, 2진수이다.

그렇다면 9.6875라는 수는 어떻게 저장할까?

일단 보면, 정규 표현(normalized form)이 존재한다.

32비트 중에 가장 최상위 왼쪽 비트(MSB)는 부호 비트이다.

1로 세트 되어 있으면 음수이고, 0으로 세트되어 있으면 양수이다.

그 다음 8비트는 지수부(exponential) 이다.

나머지 23비트는 가수부(significant, mantissa) 이다.

가수부의 표현이 두가지 존재하는데 significant 가 요즘 쓰이는 용어이고,

mantissa 는 예전에 많이 쓰이던 용어이다.

그럼 9.6875는 이진법으로 1001.1011 이다.

여기서 이제 정규표현식으로 바꿔야한다.

맨 처음 1이 남을때까지 우측으로 이동시키고 1을 만나면

정수부에 놔둔다. ( 1.0011011 )

원래 숫자로 만들려면 왼쪽으로 쉬프트가 필요하다.( 1.0011011 * 2^3 )

그리고 양수 이니까 MSB는 0이다.

그림으로 확인해보자.

이렇게 될것이다.

그리고 이것을 직접 메모리에서 확인해보자.
 
  1. #include <stdio.h>  
  2. typedef struct _X86_FLOAT  
  3. {  
  4.     union 
  5.     {  
  6.         float fValue;  
  7.         struct    
  8.         {  
  9.             unsigned mantissa : 23;  
  10.             unsigned exponent :  8;  
  11.             unsigned sign     :  1;  
  12.         };  
  13.     };  
  14. } X86_FLOAT, *PX86_FLOAT;  
  15.  
  16. int main(int argc, char* argv[])  
  17. {  
  18.     X86_FLOAT  xfValue;  
  19.  
  20.     xfValue.fValue = 9.6875;  
  21.            
  22.     return EXIT_SUCCESS;  
  23. }  
<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>#include <stdio.h> typedef struct _X86_FLOAT { union { float fValue; struct { unsigned mantissa : 23; unsigned exponent : 8; unsigned sign : 1; }; }; } X86_FLOAT, *PX86_FLOAT; int main(int argc, char* argv[]) { X86_FLOAT xfValue; xfValue.fValue = 9.6875; return EXIT_SUCCESS; } </TEXTAREA>

이것을 디버깅 창에서 직접 확인해보면,

<그림1. 변수의 내용 >

<그림2. 메모리의 상태 >

 일단 우리 x86계열 컴퓨터는 little-endian 구조를 사용하므로 구조체의 선언순서는 역순으로 하였다.

(혹시 이해가 안되면 little-endian 및 big-endian 을 조사해보면 안다.)

 그림1을 보면 mantissa 및 exponent 및 sign에 어떤 값이 들어가 있는지 보인다.

그리고 메모리 구조는 ( 당연히 공용체이기 때문에 공간은 4Byte 만큼 )

위로 스크롤