-
부동 소수점 표현System Programming 2019. 9. 22. 03:10
부동 소수점
부동은 不動이 아닌, 浮動-즉 떠서 움직인다는 뜻이다. 원어는 Floating point인데, floating을 번역하다 보니 이렇게 된 것이다. 소수점의 위치가 수에 따라 달라진다.
부동 소수점의 원리는 과학적 기수법의 그것과 흡사하다. 수를 \(x\times 2^y\) 형태로 나타내는 것이 근간이 된다. 즉 과학적 기수법의 2진법에서의 형태라 생각하면 좋다.
실질적으로 이용되는 IEEE 표준은 $$(-1)^sM2^2$$ 형태로 수를 나타낸다. 각각의 수가 의미하는 것은...
- s는 sign bit다. 양수는 0, 음수는 1이다.
- M은 [1.0, 2.0) 사이의 비율 이진수, 즉 유효숫자이다. 십진법에서 유효숫자는 [1.0, 10.0)이란 걸 생각하면 쉽다.
- E는 2의 지수. 당연히 음수도 가능하다.
이를 이용하여 -10을 부동 소수점 표기법으로 나타내면...
-10=-1*1.25*8=\((-1)^1\times 1.01_{(2)}\times2^3\).
즉 s=1, M=1.01, E=3인 수는 십진법으로 -10이다.
인코딩
s, M, E를 컴퓨터에서는 s, exp, frac이라는 형태로 저장한다. 물론 이들을 그대로 저장하지는 않고, 약간의 변형된 방식으로 저장한다.
- s는 그대로 저장된다.
- M은 frac이 나타내며, n비트이다.
- E는 exp가 나타내며, k비트이다.
s-exp-frac의 순서로 저장된다.
비트 요구량
단일 정밀도: 32비트. s-1, exp-8, frac-23. C언어의 float가 이것이다.
이중 정밀도: 64비트. s-1, exp-11, frac-52. C언어의 double이 이것이다.
확장 정밀도: 80비트. s-1, exp-15, frac-63 또는 64. 인텔에서만 이용한다.
exp에 따른 분류
정규화 값
exp가 000...0 또는 111...1이 아닌 경우를 의미한다. 이는 E를 bias를 이용해서 해석해야 한다는 것을 의미하며, E=exp-bias가 된다. bias 값은 \(2^k-1\), 즉 단일에서 127, 이중에서 1023이며, 이는 지수 값의 범위를 단일 정밀도에서는 -126~127, 이중 정밀도에서 -1022~1023으로 조절할 수 있게 하는 것이다.
frac은 \(0.f_{n-1}...f_1f_0\)으로 나타낸다. (예: M=1.1010이면 frac은 1010 이후 0 반복) 이는 이진 소수점의 위치는 MBS의 가장 왼쪽에 존재한다는 것을 뜻한다. 즉 M 값은 1+frac이 된다. 이는 M을 1.xxx 형태(=[1.0, 2.0))로 나타낸다는 것을 의미하며, 소수점 앞의 1을 나타내는 비트 하나를 절약할 수 있다.
비정규화 값
exp가 000...0인 경우를 의미한다. E는 1-bias로 고정되며, M은 frac과 동일하다. 비정규화 값은 frac의 비트를 전부 0으로 통일해서 0을 나타내거나, 0에 매우 가까운 값들을 나타낼 때 이용한다.
특수 값
exp가 1..1인 경우를 의미한다. frac 비트가 모두 0이면 무한대이며(부호는 s를 따라간다), 그 외의 경우는 NaN=Not a Number라는 연산에서의 오류(허수 등)을 표기한다.
근사법
IEEE 부동소수점은 올림, 버림, 반올림이 아닌 4가지 근사값을 제시한다.
- 짝수근사법(Round-To-Even): '가장 가까운 값'. 가장 덜 중요한 숫자가 짝수가 되도록 근사한다. 1.5는 1이 아니라 2로, -2.5도 -3이 아니라 -2로.
- 영방향근사(Round Toward-Zero): 양수는 내림, 음수는 올림. 즉 절댓값을 내림.
- 하향근사(Round-Down): 내림. 즉 양수는 절댓값을 내림, 음수는 절댓값을 올림.
- 상향근사(Round-Up): 올림. 즉 양수는 절댓값을 올림, 음수는 절댓값을 내림.
짝수근사는 좀 이상해 보이지만, 이걸로 평균을 내면 실제 평균과 비슷해지기 때문에 쓰이기도 하고,(평균 위 값, 아래 값의 양이 비슷해짐.) 정수로 근사하지 않을 경우에도 사용되고(1.234999: 1.23, 1.235001: 1.24, 1.235000: 1.24, 1.245000: 1.24), 이진수 비트에서 LSB가 0이 되게 유도한다.
부동소수점 연산
덧셈
두 수의 합에서 E가 더 큰 쪽에 맞춰간다. M이 2보다 크다면 M을 우측 시프트하고, E를 증가시킨다. M이 1보다 작다면, M을 k만큼 왼쪽으로 시프트하고, k만큼 E를 줄인다. E가 범위를 벗어나면 오버플로우.
곱셈
s, M, E가 각각 s1, M1, E1인 수와 s2, M2, E2인 수를 곱할 경우, s는 s1^s2, M은 M1*M2, E는 E1+E2가 된다. 그 이후, M이 2보다 크면 M을 우측 시프트하고 E를 증가시킨다. 역시 E가 범위를 벗어나면 오버플로우. M을 frac에 맞도록 근사한다.
'System Programming' 카테고리의 다른 글
조건 코드 (0) 2019.10.02 프로그램 작동의 기초 (0) 2019.10.01 수 표기 1편 (0) 2019.09.11