실수형에서 오차가 생기는 이유

김동규·2022년 10월 26일
0

JAVA

목록 보기
10/38

🤔 컴퓨터가 실수형을 처리하는 방법

컴퓨터는 모든 수를 0과 1로 이루어진 2진수로 표현한다. 이것은 정수뿐만 아니라 소수점이 존재하는 실수도 마찬가지이다.

정수의 경우 이러한 표현이 간단하지만, 실수를 2진수로 표현하는 것은 복잡하다. 실수를 표현하기 위한 다양한 방법들이 연구되었으며 현재는 크게 2가지 방식이 존재한다.

  • 고정 소수점 (fixed point) 방식
  • 부동 소수점 (floating point) 방식

💻 고정 소수점(Fixed Point)

고정 소수점(fixed point) 방식
실수는 보통 정수부(1.xxx)와 소수부(x.1)로 나눌 수 있다.

따라서 실수를 표현하는 가장 간단한 방식은 소수부의 자릿수를 미리 정하여, 고정된 자릿수의 소수를 표현하는 것입니다.

하지만 위 방식은 정수부와 소수부의 자릿수가 크지 않으므로, 표현할 수 있는 범위가 매우 적다는 단점이 있다.

💻 부동 소수점(Floating Point)

실수는 보통 정수부와 소수부로 나뉘지만 가수부와 지수부로 나누어 표현할 수도 있다.
부동 소수점(Floating Point) 방식은 이렇게 하나의 실수를 가수부와 지수부로 나누어 표현하는 방식이다.

앞서 살펴본 고정 소수점 방식은 제한된 자릿수로 인해 표현할 수 있는 범위가 매우 작은 한계점이 있다.
하지만 부동 소수점 방식은 다음 수식을 이용하여 매우 큰 실수까지도 표현할 수 있다.

±(1.가수부)×2지수부-127

IEEE 부동 소수점 방식

현재 사용되고 있는 부동 소수점 방식은 대부분 IEEE 754 표준을 따르고 있다.

32비트의 float형 실수를 IEEE 부동 소수점 방식으로 표현하면 다음과 같다.

64비트의 double형 실수를 IEEE 부동 소수점 방식으로 표현하면 다음과 같다.

🧐 그래서 왜 문제가 생기는가?

부동 소수점 방식을 사용하면 고정 소수점 방식보다 훨씬 더 많은 범위까지 표현할 수 있지만 한계점이 없지않은것이 아니다.
부동 소수점 방식에 의한 실수의 표현은 항상 오차가 존재한다는 한계를 가지고 있다.

부동 소수점 방식에서의 오차는 위 공식에 의해 발생되는데,이 공식을 사용하면 표현할 수 있는 범위는 늘어나지만, 10진수를 정확하게 표현할 수는 없게 된다.

ex)

int i;

float sum = 0;

 

for (i = 0; i < 1000; i++)

{

    sum += 0.1;

}

 

Systemout.print(0.1을 1000번 더한 합계는 "+sum+"입니다.");

원하는 결과: 0.1을 1000번 더한 합계는 "100.000"입니다.
결과: 0.1을 1000번 더한 합계는 "99.999"입니다.

따라서 컴퓨터에서 실수를 표현하는 방법은 정확한 표현이 아닌 언제나 근사치를 표현할 뿐임을 항상 명심해야 한다.

profile
HigasiHosi

0개의 댓글