개요
처음 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 형식을 사용하고 있다.
32비트 단정도(single)가 기본이며, 비트 수를 두 배
확장했다고 해서 64비트 배정도(double) 방식도 있다.
단정도(sigle precision) 표현 방식
단정도를 이해하면 배정도 방식 또한 이해할 수 있기 떄문에 단정도 방식으로 설명하고자 한다.
부호(sign)
양수와 음수를 판단하는 방법이 제일 쉽다. 가장 왼쪽 비트를 MSB
(Most Significant Bit)라고 하는데, 이 비트를 보고 판단하면 된다.
0
: 양수
1
: 음수
지수(exponent)
단정도 방식에서 지수(exponent)는 8비트로 표현된다. 여기서 간단하게 문제를 내보도록 하자.
1_00001010_00000000000000000000000
부호 / 지수 / 가수를 보기 좋게 끊어 놓았다. 위와 같은 바이너리 코드가 있다면 지수(exponent)는 몇인가? 정답은 10 (0000_1010)이다.
지수는 처럼 e로 표현된다. 여기서
바이어스 지수(biased exponent)
라는 스킬이 들어간다.
실수끼리 연산을 할 때 크기가 더 작은 실수의 가수와 지수를 조정해야 하는 이슈가 있다. 따라서 실제 지수값에 0111_1111(=127)
을 더해 모두 양수로 만들어준다. 말 그대로 BIas는 조정값이기 때문에 IEEE754에서는 +127로 고정되어 있다.
가수(mantissa 혹은 significant)
가수는 실질적인 데이터
를 의미한다. 부호와 지수가 어떻든 간에 가수
만이 의미있는 수를 담당한다.
이때 정규화
(normalized mantissa)라는 스킬이 들어간다. 정규화의 방법은 다음과 같다.
- 가수를 1.bbb...b 형식으로 표현할 수 있도록 지수를 조정한다.
- 가수를 표현할 때 bbb...b만 표현한다.
- 1은 항상 존재하기 때문에 저장할 필요가 없기 때문이다.
- 단, 숫자 0인 경우에는 가수를 모두 0으로 채운다.
실습
문제1
15.625를 단정도(single precision) 방식으로 표현하라.
풀이
15.625를 이진수로 표현하면1111.101
이 된다. (왜 1111.101이 되는가에 대해서는 설명을 생략한다.)
-
가수의 정규화를 한다.
- 1.1111_01 * 2^3이 된다. (소숫점 위치를 밀어줬으니 2^3을 해줘야 한다.)
- 1.1111_01 * 2^3이 된다. (소숫점 위치를 밀어줬으니 2^3을 해줘야 한다.)
-
지수(exponent)를 찾는다.
- 지수는 기수(base) 머리 위에 달려 있는 녀석이다. 즉, 3이다.
- 이때, 바이어스 지수로 계산해야하므로
3 +127 (Bias)
을 취한다. 130
은 이진법으로 1000_0010이다.
-
가수(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}$
좀 더 심화된 이야기
지수(exponent)는 정밀도를 결정한다.
가수(mantissa)는 표현 가능한 수의 범위를 결정한다.
IEEE 754 방식에서는 몇 가지 예외사항을 처리한다.
-
NaN
- Not a Number라는 뜻이다. 즉, 나누기 0이나, 음수에 대한 제곱근과 같은 오류를 말한다.
-
Overflow
- 주어진 정밀도 형식으로 표현할 수 있는 수의 범위보다 더 큰 수를 나타낸다. 즉 오버플로우를 의미한다.
-
일반식
- 가수 정규화와 지수 바이어스가 적용된 형식이다.
-
Underflow
- 주어진 정밀도 형식으로 표현할 수 없을 정도로 작은 수에 해당한다. 즉, 언더플로우를 의미한다.
-
Zero
- 숫자 0을 의미하며, 모든 비트들을 0으로 채우면 된다.
참고자료
한눈에 보이는 컴퓨터구조(전중남 지음, 생능출판) 186p~191p
목차
'프로그래밍 > 컴퓨터구조' 카테고리의 다른 글
그레이 코드(gray code)를 2진 코드로 변환하기 (1) | 2018.03.02 |
---|---|
[컴퓨터구조] 인터럽트(Interrupt)란? (3) | 2018.01.10 |