시스템 프로그래밍 노트 2 - 실수
2019년 10월 22일
1. IEEE 실수 표현
1.1. 표현 방법
- $(-1)^s M ;2^E $
- sign bit는 수의 부호를 결정한다.
- significand는 [1.0,2.0) 사이의 값을 결정한다.(물론 예외가 딱 하나 있음)
- exponent는 값에 2의 지수의 형태로 가중치를 준다.
- 이걸 인코딩할 때는 sign bit - exponent - significand 순으로 놓는다.
1.1.1. Normalized Values
- exp가 00…0이나 11…1이 아닐 때의 일반적인 상황이다.
E = exponent - bias,bias는k가exponent비트 수일 때2^{k-1} -1.- bias를 저렇게 잡는 이유는
M = 1.xxx...x,xx---x는significand이다.
1.1.2. Denormalized Values
exp = 000...0인 경우이다.E = 1 - bias. 원래는 Normalized Value였다면0 - bias였겠지만, 예외적으로 이렇게 처리한다. 그 대신에 significand의 의미도 달라진다.M = 0.xxx...x
1.1.3. Special Values
exp = 111...1frac=000...0이면 로 해석한다. 오버플로우가 일어날 때 사용.- 응용해서 sign bit가 1이면 로 해석된다.
frac!=000...0이면 NaN(Not a Number)으로, 어떤 수로도 결정되지 않을 때 사용한다. 같은 연산의 결과이다.
1.2. Rounding
- 반올림
- 정확히 절반일 때는 LSB가 짝수가 되는 방향으로 한다.
- 모든 실수 연산의 마지막에 반드시 필요하다.
1.3. 곱셈
- $ (-1)^s M 2^E = (-1)^{s_1} M_1 2^{E_1} \times (-1)^{s_2} M_2 2^{E_2} $
s = s1 ^ s2M = M1 * M2E = E1 + E2
- 만약
M >= 2이면 M을 오른쪽으로 한 칸 밀고, E를 1 더한다. - M을 round한다.
1.4. 덧셈
- $ (-1)^s M 2^E = (-1)^{s_1} M_1 2^{E_1} + (-1)^{s_2} M_2 2^{E_2} $
E = E1underE_1 > E_2.- s, M은 정렬된 덧셈으로부터 결정된다.
M >= 2이면 M을 오른쪽으로 한 칸 밀고 E에 1 더한다.M < 1이면 M을 1이 나올 때까지 k칸 밀고 E에 k를 뺀다.- 오버플로우 처리를 한다.
- M을 round한다.
2. C 실수
float: single precision- 32bits : 1 sign, 8 exp, 23 frac
double: double precision- 64 bits: 1 sign, 11 exp, 52 frac
2.1. 변환
double/float에서int- 소수부 버림
- 0을 향한 어림
- NaN / infinity에 대해서는 일반적인 정의는 없다. 보통은
TMin
int에서double/float- 어림이 필요하면 실수의 반올림을 사용한다.