CS/기타

부동소수점의 정밀도 문제에 대하여

alpacadabra 2022. 10. 28. 23:42

부동소수점이란, 임의의 실수를 가수부와 지수부로 나누어 표현하는 방법이다.

소수점이 떠다니듯 움직여서 부동(浮動, float)이라고 하는데, 예를 들어 1.23 * 10^2과 12.3 * 10^1이 동일한 값을 나타내듯 소수점의 위치를 임의로 조정할 수 있기 때문에 붙여진 이름으로 추측된다.

 


 

위키백과

 

부동소수점은 컴퓨터가 실수를 근사하여 표현하는 데에 사용된다.

float 자료형의 경우, 국제 표준인 IEEE 754에 의거하여 부호 1비트, 지수 8비트, 가수 23비트로 총 32비트를 사용하는데, 여기서 지수는 bias = 127을 더함으로써 0~255의 범위가 아닌 -127~128의 범위를 가진다.

이에 float의 크기는 대략 2^-127 ~ 2^128, 즉 10^-38 ~ 10^38으로 굉장히 넓은 범위를 가지게 되나, 유효 숫자를 나타내는 가수의 비트가 한정되어 있으므로 정밀도 문제가 발생하게 된다.

 


정밀도 문제가 어떻게 발생하는지 살펴보겠다.

익히 알려진 바로, 0.1 + 0.1 == 0.2가 거짓이라는 것은 다들 알고 있을 것이다.

이는 컴퓨터가 0.1을 제대로 저장하지 못하기 때문인데, 0.1을 이진수로 변환하는 과정에서 순환이 발생하기 때문이다.

아래는 0.1을 이진수로 변환하는 과정이다.

 

0.1 * 2 = 0.2

0.2 * 2 = 0.4 << 순환

0.4 * 2 = 0.8

0.8 * 2 = 1.6

0.6 * 2 = 1.2

0.2 * 2 = 0.4 << 순환

0.4 * 2 = 0.8

0.8 * 2 = 1.6

0.6 * 2 = 1.2

0.2 * 2 = 0.4 << 순환

(반복)

 

일정 간격으로 순환이 발생하는 것을 알 수 있다.

따라서, 한정된 비트로는 이를 모두 저장할 수 없으므로 오차가 발생하게 된다.

물론 순환이 아니더라도 가수부가 매우 길다면 저장할 수 없을 것이다.

 

IEEE-754 Floating Point Converter (h-schmidt.net)

 

컨버터를 통해 확인할 수도 있다. >> https://www.h-schmidt.net/FloatConverter/IEEE754.html

0.1이 컴퓨터 상에서는 0.100000001490116119384765625로 처리되고 있었다.

 

부동소수점의 정밀도 문제는 비일비재하게 일어나므로, 실수를 연산할 때는 굉장히 신중해야 한다.