부동소수점

개요

처음 C언어를 공부할 때 가장 어리둥절했던 부분이 이 부분인 듯 하다. 처음에는 왜 이걸 배우지? 라는 생각을 했지만 컴퓨터구조론에서 컴퓨터가 실수를 다루는 방식에 대해서 학습하면서 흥미롭게 느꼈다. 다만, 지수와 가수라는 용어가 자꾸 헷갈리기 때문에 영어와 같이 외우는 편이 좋다고 느꼈다.

C언어에서 변수의 자료형을 정해줄 때 다음과 같은 자료형을 사용한다.

float fnum = 3.141593f;
double dnum = 3.141592653589793;

float : 단정밀도(single precision) 32비트

double : 배정밀도(double precision) 64비트

좀 더 확장된 long double도 있지만 이는 생략하도록 하겠다. 오늘은 이 배경이 되는 IEEE 754에 대해 포스팅하고자 한다.

IEEE 754 형식

초기에는 부동소수점을 표현하기 위하여 컴퓨터마다 여러 가지 서로 다른 형식을 사용하였으나, 현재는 거의 대부분의 컴퓨터들이 호환성을 위해 미국전기전자공학회(IEEE)에서 표준화한 IEEE 754 형식을 사용하고 있다.

KakaoTalk_20171222_122202517

32비트 단정도(single)가 기본이며, 비트 수를 확장했다고 해서 64비트 정도(double) 방식도 있다.

단정도(sigle precision) 표현 방식

KakaoTalk_20171222_151953229
단정도를 이해하면 배정도 방식 또한 이해할 수 있기 떄문에 단정도 방식으로 설명하고자 한다.

부호(sign)

양수와 음수를 판단하는 방법이 제일 쉽다. 가장 왼쪽 비트를 MSB(Most Significant Bit)라고 하는데, 이 비트를 보고 판단하면 된다.

0 : 양수
1 : 음수

지수(exponent)

단정도 방식에서 지수(exponent)는 8비트로 표현된다. 여기서 간단하게 문제를 내보도록 하자.

1_00001010_00000000000000000000000


부호 / 지수 / 가수를 보기 좋게 끊어 놓았다. 위와 같은 바이너리 코드가 있다면 지수(exponent)는 몇인가? 정답은 10 (0000_1010)이다.
지수는 KakaoTalk_20171222_152001117 처럼 e로 표현된다. 여기서 바이어스 지수(biased exponent) 라는 스킬이 들어간다. 

실수끼리 연산을 할 때 크기가 더 작은 실수의 가수와 지수를 조정해야 하는 이슈가 있다.  따라서 실제 지수값에 0111_1111(=127)을 더해 모두 양수로 만들어준다. 말 그대로 BIas는 조정값이기 때문에 IEEE754에서는 +127로 고정되어 있다.

가수(mantissa 혹은 significant)

가수는 실질적인 데이터를 의미한다. 부호와 지수가 어떻든 간에 가수만이 의미있는 수를 담당한다.
이때 정규화(normalized mantissa)라는 스킬이 들어간다. 정규화의 방법은 다음과 같다.

  1. 가수를 1.bbb...b 형식으로 표현할 수 있도록 지수를 조정한다.
  2. 가수를 표현할 때 bbb...b만 표현한다.
  3. 1은 항상 존재하기 때문에 저장할 필요가 없기 때문이다.
  4. 단, 숫자 0인 경우에는 가수를 모두 0으로 채운다.

실습

문제1
15.625를 단정도(single precision) 방식으로 표현하라.

풀이
15.625를 이진수로 표현하면1111.101이 된다. (왜 1111.101이 되는가에 대해서는 설명을 생략한다.)

  1. 가수의 정규화를 한다.

    • 1.1111_01 * 2^3이 된다. (소숫점 위치를 밀어줬으니 2^3을 해줘야 한다.)

  2. 지수(exponent)를 찾는다.

    • 지수는 기수(base) 머리 위에 달려 있는 녀석이다. 즉, 3이다.
    • 이때, 바이어스 지수로 계산해야하므로 3 +127 (Bias)을 취한다.
    • 130은 이진법으로 1000_0010이다.
  3. 가수(mantissa)를 찾는다.

    • 가수는 1.XXX에서 1 이하의 것들을 의미한다.
    • 즉, 1111_0100_0000_0000_0000_000이 된다.
    • 보기 편하게 4자리씩 끊었지만, 맨 오른쪽에서 4자리씩 끊어야 한다.


정답

0

1000_0010 

1111_0100_0000_0000_000 

0 _ 1000 0010 _ 111 1010 0000 0000 0000 0000
부호비트, 지수부, 가수부를 보기좋게 끊었다.

※ 이를 16진수로 나타내야 한다면 4자리씩 끊는게 보기 좋다.
0100_0001_0111_1010_0000_0000_0000_0000 즉, 417A가 된다.


문제2
1100_0001_0101_0000_0000_0000_0000_0000과 같이 표현되어 있는 단정도 수 N의 크기를 구하라.

풀이
보기 좋게 단정도 형식에 맞추어서 비트를 끊어준다.
1(=부호) 100000010(=지수) 10100000000000000000000(=가수)

부호(S) : 1이므로 음수란 걸 알 수 있다.
지수(e) : biased된 지수이므로 도로 -127을 빼준다
가수(M) : 1.1010

따라서 N = $(-1)^1 * 1.1101 * 2^{130-127}$ = $-1.101 * 2^3$ = $-1101_{2}$ = $-13_{10}$

좀 더 심화된 이야기

KakaoTalk_20171222_151953229
지수(exponent)는 정밀도를 결정한다.
가수(mantissa)는 표현 가능한 수의 범위를 결정한다.
KakaoTalk_20171222_175640829

스크린샷, 2017-12-22 16-22-09

스크린샷, 2017-12-22 16-26-37
IEEE 754 방식에서는 몇 가지 예외사항을 처리한다.

  1. NaN

    • Not a Number라는 뜻이다. 즉, 나누기 0이나, 음수에 대한 제곱근과 같은 오류를 말한다.
  2. Overflow

    • 주어진 정밀도 형식으로 표현할 수 있는 수의 범위보다 더 큰 수를 나타낸다. 즉 오버플로우를 의미한다.
  3. 일반식

    • 가수 정규화와 지수 바이어스가 적용된 형식이다.
  4. Underflow

    • 주어진 정밀도 형식으로 표현할 수 없을 정도로 작은 수에 해당한다. 즉, 언더플로우를 의미한다.
  5. Zero

    • 숫자 0을 의미하며, 모든 비트들을 0으로 채우면 된다.

참고자료

한눈에 보이는 컴퓨터구조(전중남 지음, 생능출판) 186p~191p

KMOOC 상명대학교 컴퓨터구조

목차


  1. 4242 2018.03.24 11:30 신고

    잘 읽었습니다. 많은 도움이 되었습니다. 감사합니다.

    • 이철규 2018.03.24 11:48 신고

      부족한 글인데 봐주셔서 감사합니다. 다시 읽어보니 오타도 좀 있고 이해하기 어려운 부분도 있었는데, 조금 더 수정을 가미했습니다. 감사합니다!

  2. 51 2018.04.05 22:06 신고

    -0.001101을 정규화하면 -1.101 인데
    이게 책에 가수를 왼쪽으로 세자리 이동시키고 ,지수값을 3 감소시킨다고 나와있는데 오른쪽으로 이동시킨거아니에요?? 점이 오른쪽으로 간거같은데 ...

    • 작성자 2018.04.06 10:10 신고

      어느 부분을 보고 말씀하시는거죠?

  3. 디공 2018.10.10 23:05 신고

    지수부가 음수가 될때 한번 예를 들어 주실수있나요?? 너무 모르겠네요ㅠㅠ 지수부가 0이나 음수일때 어떻게 표현해야하는지 모르겠어요

+ Recent posts