20. 실수 형식의 메모리 구조

어려울 수 있는 내용이지만 프로그래밍할 때 크게 중요한 내용은 아니예요.
실수 형식은 근사치라는 정도로 이해해도 큰 문제는 없어요.
그래도 한 번 살펴보세요.

컴퓨터에서 실수는 어떻게 표현하고 어떻게 메모리에 저장될까요?
C언어에서 실수는 부호 비트와 지수부와 실수부로 나누어 메모리에 저장하고 있어요.

float은 상위 1비트가 부호 비트이고 이어지는 8개의 비트에 지수부를 표현하고 나머지 23개의 비트에 가수부를 표현한답니다.

4바이트 실수 메모리 구조

그리고 지수부는 밑수를 2로 할 때의 지수를 나타내는데 0승일 때가 0111 1111으로 표현하고 있어요.
1승일 때 1000 0000, 2승일 때는 1000 0001 이죠.
물론 -1승일 때는 0111 1110 입니다.

-13.625를 float 형 변수에 대입할 때 메모리에 어떻게 저장되는지 살펴봅시다.
10진수 -13.625를 이진수로 표현해야 메모리에 어떻게 저장하는지 알 수 있겠죠.
-13.625 = – (13 + 0.625) = -(8 + 4 +1 + 0.5 + 0.125) = -(2진수 1101.101)
따라서 -13.625는 (2진수 -1.101101) * (2의 3승)로 표현할 수 있겠죠.

먼저 부호는 음수이므로 1로 기록해요.

지수부는 3승이므로 1000 0010 이죠.
16진수로 0x82예요.

그리고 2진수의 가수부는 언제나 1.으로 시작하게 표현할 수 있어서 1.은 생략해서 표현한답니다.
즉 가수부는 101 1010 0000 0000 0000 0000 이예요.
16진수로 0x5a0000이죠.

전체 4바이트를 2진수로 표현하면 1100 0001 0101 1010 0000 0000 0000 0000
전체 4바이트를 16진수로 표현하면 0xc15a0000입니다.

◈ 실수 형식 메모리 구조 확인하기

#include <stdio.h>
//union은 내부 멤버 중에 제일 큰 멤버 크기의 메모리를 할당합니다.
typedef union
{
    float value; //4바이트
    struct
    { 
        unsigned exponent:23; //23비트
        unsigned mantissa:8; //8비트
        unsigned sign:1; //1비트
    }sv; //4바이트
    unsigned iv;//4바이트    
}test;
 
int main(void)
{
    test t;
    t.value = -13.625;
    printf("부호부:%u\n",t.sv.sign); //%u는 부호없는 정수로 출력
    printf("지수부:%#x\n",t.sv.mantissa); //%#x는 16진수로 출력하고 앞에 0x 표시
    printf("가수부:%#x\n",t.sv.exponent);
    printf("4바이트 16진수:%#x\n",t.iv);    
    return 0;
}

◈ 실행 결과

부호부:1
지수부:0x82
가수부:0x5a0000
4바이트 16진수:0xc15a0000