부동 소수점 오류
실수를 2진법으로 표현하는 방법은 고정 소수점 방식(Fixed point), 부동 소수점 방식(Floating point)이 존재한다.
고정 소수점 방식(Fixed Point)
실수를 정수부와 소수부로 나누어 사용한다. 소수부의 자릿수를 미리 정하여 고정된 자릿수의 소수를 표현하는 것
고정 소수점의 방식은 정수 부분(15bit)과 소수 부분(16bit)에 사용할 비트가 고정되어 있기 때문에 정수 부분에서 큰 실수를 표현하기가 어렵고 소수 부분에서도 정밀한 값을 표현할 수 가 없다.
부동 소수점 방식(Floating Point)
IEEE 754 표준으로 소수점이 고정되어 있지 않고 좌우로 움직일 수 있다. 가수부와 지수부로 나누어 표현하는데 이를
±(1.가수부)×2^지수부-127 로 표현한다.
sign(1bit)은 부호를 나타내고 exponent(8bit)는 소숫점이 몇칸 움직이는지 나타낸다.
이는 고정 소수점 방식과는 달리 소수점을 23bit나 사용할 수 있고 자유로이 움직일 수 있어서 표현할 수 있는 수의 범위가 매우 넓다는 장점이 있다.
반대로는 실수 연산이 부정확하다는 단점이 존재한다.
int a = 1;
double b = 0.1;
int n = 7;
double r = a - b*n;
Console.WriteLine("{0}",r);
을 실행시키면 1 - 0.7 = 0.3이 아닌
0.2999999999999가 출력이 된다.
이러한 결과가 출력되는 이유는 1/3을 10진수로 표현하기 어려운 것처럼
1/10과 같은 수를 2진법으로 표현하기 어려워 무한 소수가 되기 때문이다. 컴퓨터는 이러한 무한 소수의 어느 지점에서 값을 잘라서 반올림 하기 때문에 정확한 값이 아닌 근사치의 값을 가지게 된다.
부동 소수점의 숫자는 특정 수의 비트로만 구성되어 있기 때문에 무한한 양의 분수 값을 표현할 수 가 없다.
실수가 가장 가까운 부동 소수점 숫자로 반올림 될 때 머신 엡실론(Machine Epsilon)은 상대 오류의 상한선을 형성한다.
즉 실수를 가장 가까운 부동소수점 실수로 반올림 할 때 상대오차는 항상 머신 엡실론(Machine Epsilon) 이하라는 것이다.
연산한 값과 비교할 값의 차이가 머신 엡실론(Machine Epsilon) 보다 작거나 같다면 두 실수는 같은 값이라고 정의된다.