본문 바로가기

Embedded Programming/C/C++

4 byte float format (float 형의 실수 저장 방식)

일반 정수형 자료형은 보수법을 이용해 음수와 양수를 저장하지만, 

실수형 자료형인 float 는 부동 소수점 방식과 부호 비트 방식을 사용하여 데이터를 저장합니다.


float 자료형은 4 bytes의 크기 안에서 비트 별로 쪼개서 데이터를 저장하는데

첫번째 1bit 는 부호를, 그 다음 비트부터 8bit 만큼은 지수를, 나머지 23 bit는 가수를 저장합니다.

예를 들어, 100.34라는 실수가 있을 때 1.0034x10₂의 형태로 표현하는 것인데,

소수점의 위치를 지정해주는 지수(10₂)와 1.0034라는 가수부분으로 나눌 수 있다.


float형은 이 부동 소수점 방식에 최초 1bit를 부호비트로 할당하는 것이다.


이를 직접 확인해보는 C 프로그램을 작성해보자.





float형 변수 fNum에 담긴 값을 char형 포인터로 1byte씩 출력해보니 

16진수 80 42 1C 46 로 출력이 된다.

이는 little endian 방식에 따라 저장된 것이므로  원래 값은 46 1C 42 80이 되겠다.


과연 이 값이 어떻게 나온것인지 한번 차근차근 풀어보기로 한다.

우선 공학용 계산기로 46 1C 42 80를 2진수로 바꿔 보았다.

0100 0110 0001 1100 0100 0010 1000 1010 이라는 32bit값이 나온다.

이를 아까 말한 실수 저장 방식에 따라 나눠보면




와 같은 모양이 나온다. 


10000.625f를 우선 2진수로 변환하면 10 0111 0001 0000.101(2) 가 된다. 

(알아서 계산해보자-_-;)

이를 다시 부동 소수점 형식으로 바꾸면, 1.0011100010000101 x 2(13승) 이 된다

여기서 13이라는 지수부분을 2진수로 변환하면 1101이 되어야 하는데 1000 1100이라는 

이상한 값이 들어가 있다.


이는 지수부분을 저장할 때는 특이한 방식을 이용하기 때문이다.

8비트로 표현할 수 있는 수의 범위는 0~255까지인데, 지수가 음수인 경우도 있으므로 

음수도 표현해야 한다.

하지만 여기서는 2의 보수법을 사용하지 않고 127을 0으로 간주하는 방식을 사용한다.

즉, 13은 13+127= 140을 집어 넣는것이다.


그리고 나머지 가수는 소수점 이하자리를 차례대로 입력해주는 것이다.


위의 값을 다시 1byte 단위로 쪼개 보았을 때, 16진수로 아래 그림과 같은 값이 나온다.


결국 맨위의 소스파일에서 출력한 80 42 1C 46 라는 값이 

little endian 방식에 의해 순서가 바뀌어 들어가 있음을 확인할 수 있다.