부동 소수점 오류에 대해서 알아보기 전에 부동 소수점이란 무엇일까
컴퓨터는 모든 수를 0과 1로 이루어진 2진수로 표현한다. 이것은 정수뿐만 아니라 소수점이 존재하는 실수도 마찬가지이다.
정수의 경우 이러한 표현이 간단하지만, 실수를 2진수로 표현하는 것은 복잡하다. 실수를 표현하기 위한 다양한 방법들이 연구되었고 현재는 크게 2가지 방식이 존재한다.
- 고정 소수점 (fixed point) 방식
- 부동 소수좀 (floating point) 방식
고정 소수점 (fixed point) 방식
실수는 보통 정수부와 소수부로 나뉘는다. 실수를 표현하는 방법은 소수부의 자릿수를 미리 정하고, 고정된 자릿수의 소수를 표현하는 것이다.
32비트 CPU에서 고정 소수점 방식을 실수로 표현하면
1비트 -> 부호
15비트 -> 정수부
16비트 -> 소수부
이런 식으로 표현이 가능하다.
하지만, 이 방식은 정수부와 소수부의 자릿수가 크지 않기 때문에, 표현할 수 있는 범위가 매우 적고, 정밀도가 낮다. 그래서 소규모 시스템에서만 간혹 쓰인다.
부동 소수점(floating point) 방식
실수는 보통 정수부와 소수부로 나뉘지만, 가수부와 지수부로 나누어 표현할 수 도 있다.
부동 소수점 방식은 실수를 a*2^b 형식으로 저장한다.
이때 a는 1보다 크거나 같고, 2보다 작은 실수이다.
±(1.가수부)×2^지수부-127
부동 소수점은 고정 소수점 방식과 달리 매우 큰 실수까지도 표현할 수 있다.
현재 대부분의 시스템에서는 부동 소수점 방식으로 실수를 표현할 수 있다.
64비트 CPU의 double형 실수를 IEEE 부동 소수점 방식으로 표현한다면
1비트 -> 부호
11비트 -> 지수부
52비트 -> 가수부
로 이루어져 있다.
부동 소수점 오류란
부동 소수점 방식은 고정 소수점 방식보다 훨씬 더 많은 범위까지 표현할 수 있지만, 항상 오차가 존재한다는 단점을 가지고 있다.
부동 소수점 방식에서 오차는 위에서 살펴본 공식에 의해 발생한다.
해당 공식을 사용하면 표현할 수 있는 범위는 늘지만, 10진수를 정확하게 표현할 수는 없다. (무한소수, 순환소수의 경우 가수부가 표현할 수 있는 비트 수를 넘어가게 되면 손실되는 부분이 생기기 때문, 실수 또한 이진수로 표현하기 때문에 가수부가 1/2^n 꼴로 표현되는 경우만 오차없이 정확하게 값이 계산된다.)
Java 예시
class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
double num = 0.1;
int one = 1;
int seven = 7;
double result = one - num * seven;
System.out.println(result);
}
}
위 코드를 실행시켜보자.
간단한 계산 문제이다. 우리 모두 암산으로 충분히 풀 수 있다. 정답은 0.3이다.
하지만 결과를 출력해보면 아래와 같은 결과가 나온다.
참고
https://velog.io/@syleemk/CS-%EB%B6%80%EB%8F%99-%EC%86%8C%EC%88%98%EC%A0%90-%EC%98%A4%EC%B0%A8
'Computer Science' 카테고리의 다른 글
[CS] JPG 와 PNG에 대해서 알아보자. (0) | 2024.06.13 |
---|