게임개발/스터디

[스터디] 부동소수점 오차가 나는 이유

감물 2024. 5. 11. 16:49

* 컴퓨터가 실수를 표현하는 방식

 

2바이트의 메모리를 가지고 소수점 이하의 값을 갖는 실수의 표현방식을 나름대로 상상해보자. 가장 쉽게 생각할 수 있는 방식은 다음과 같다.

 

"일단 2바이트를 나눠! 그래서 반은 소수점 이상을, 나머지 반은 소수점 이하를 표현하는 거야!"

 

그래서 다음과 같이 실수를 표현하기로 결정했다고 가정하자.

 

 

 

위의 그림과 같이 실수를 표현한다면, 부호비트가 1이므로 음수, 소수점 이상이 0000001이므로 1, 소수점 이하가 00000101이므로 5이다. 따라서, -1.5를 뜻하는 것이라고 주장할 수 있다. 뭐 생각은 좋았다. 그러나 이렇게 실수를 표현한다면, 2바이트를 가지고 나타낼 수 있는 실수의 수가 몇 개나 되겠는가? 이런 식으로 표현한다면, 복잡한 실수는 도대체 몇 바이트가 있어야 표현이 가능하겠는가? 예를 들어서 27123.0102312를 표현하려면 몇 바이트가 소모되겠는가? 이러한 방식으로는 우리에게 필요한 충분한 범위의 실수를 표현하지 못한다. 그래서 컴퓨터가 적은 비트수를 가지고, 넓은 범위의 실수를 표현하기 위해서 하나의 식을 정리하기에 이른다. 

 

 

 

위의 식에는 변수 m과 변수 e가 존재한다. 이 식이 어떻게 도출된 식인지에 대한 사항은 언급하지 않겠다. 다만 이러한 식을 이용하면 적은 비트 수를 가지고도 보다 넓은 범위의 실수를 표현할 수 있다. 대략 눈짐작으로 m과 e에 적당한 값을 넣어보자. 표현할 수 있는 값의 범위가 조금 전에 비해서 비교할 수 없을 만큼 넓어졌음을 알 수 있다. 따라서 컴퓨터는 이러한 형식의 식을 미리 정의해 놓고, 메모리에 할당된 데이터의 일부 비트는 m의 값을 정하는데, 또 일부 비트는 e의 값을 정하는데 사용하는 방식으로 실수를 표현한다.

 

 

* 컴퓨터가 실수를 표현하는 방식에는 오차가 존재한다.

컴퓨터가 실수를 어떻게 표현하는지 대략 이해했을 것이다. 적은 비트 수를 가지고도 넓은 범위의 실수를 표현할 수 있다는 것도 이해했을 것이다. 그러나 이렇게 장점만 있는 것은 아니다. 

 

"넓은 범위의 실수를 표현할 수 있지만, 실수의 표현에 오차가 존재한다."

 

그렇다면 오차가 존재하는 이유는 무엇일까? 위에 보인 형식의 식으로는 모든 실수를 정확히 표현할 수 없기 때문이다. 한가지 간단한 예를 들어보겠다. 0.0은 소수점 이상이 0이고, 소수점 이하가 0인 실수이다. 그럼 위의 식의 m과 e에 적절한 값을 대입해서 0.0을 만들어 보자. 가능한가? 불가능하다. 2의 n승은 절대로 0이 될수 없기 때문이다. 이렇듯 컴퓨터는 우리가 표현하고자 하는 실수의 값을 정확하게 표현하는 것이 아니라, 아주 가까운, 문제가 없을 만큼의 근차치를 통해서 실수를 표현하게 된다. 따라서 실수를 표현하는데 있어서 오차가 존재하는 것은 당연한 일이며, 이러한 오차를 가리켜 '부동 소수점 오차'라 한다. 이는 컴퓨터가 소수점 이하의 수를 표현하는데 있어서 부동 소수점 방식을 사용하기 때문이다.

 

"컴퓨터는 실수를 100% 정확히 표현하지 못한다. 다만 근사치를 표현할 뿐이다."

 

 

 

조 : 윤성우의 열혈 C 프로그래밍