[C언어 소스] 실수를 메모리에 표현하는 방법을 확인하기 위한 공용체 정의하기

0에서 1 사이에도 실수는 셀 수 없다는 것을 알고 계시죠. 결국 메모리에 실수를 표현하다보면 오차가 발생할 수 있다는 것을 알아야 한다는 것이죠. 이 또한 알고 계실거예요. 그렇다면 다음의 실행 결과는 어떻게 나올까요?
printf(“%.20f\n”,0.1+0.2);
결과를 보고 “이건 뭐지?” 라는 생각을 하신 분들도 있을 거예요. 실수 표현에 오차가 있다고 하더라도 이런 정도에서 오차가 발생할 것이라 생각하기 쉽지 않죠. 사실 우리는 10진수로 사고하지만 컴퓨터에 데이터를 표현할 때는 2진수 체계를 사용합니다. 이 또한 아는 사실이겠지만 여전히 우리의 사고는 10진수 체계 속에 있다보니 오판할 때가 종종 있어요. IEEE754 표준 방식으로 4바이트 실수를 표현하는 방법을 보면 이진수 체계로 메모리에 값을 보관합니다. 이에 관한 부분은 게시글 위에 있는 동영상으로 대체할게요. C언어에서 제공하는 공용체(Union)을 이용하면 실수 표현이 메모리에 어떻게 저장하는지 유추할 수 있어요. 먼저 공용체에 float 멤버를 하나 정의합니다. 공용체에 구조체 멤버도 하나 정의합니다. 이번 구조체는 비트 필드를 이용하여 23비트, 8비트, 1비트로 나누어 멤버를 정의하세요. 가수부, 지수부, 부호부를 확인하게 위해서입니다. 공용체에 unsigned 멤버를 하나 정의하세요. 이제 공용체 멤버 중에 float 형식을 위한 멤버에 -13.625처럼 실수 값을 대입합니다. 그리고 구조체 멤버를 이용하여 부호부, 지수부, 가수부를 확인하세요. 마지막으로 usigned 멤버를 이용하여 16진수로 값을 확인하세요. 이를 통해 메모리에 어떻게 들어가는 지 알 수 있어요. 자세한 사항은 게시글 위에 동영상 강의를 참고하세요.
#include <stdio.h>
//union은 내부 멤버 중에 제일 큰 멤버 크기의 메모리를 할당합니다.
typedef union
{
    float value; //4바이트
    struct
    {
        unsigned mantissa : 23; //23비트
        unsigned exponent : 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.exponent); //%#x는 16진수로 출력하고 앞에 0x 표시
    printf("가수부:%#x\n", t.sv.mantissa);
    printf("4바이트 16진수:%#x\n", t.iv);
    return 0;
}