신변잡기

0.1 + 0.2 == 0.3 is false

나도한강뷰 2022. 8. 18. 00:50
print ( 0.3 - 0.2 )
print ( 0.3 - 0.2 == 0.1)

#output
0.09999999999999998
False

위와같은 문제는, 부동소수점에대한 고려를 하지않았기때문에 발생한 문제이다.

부동소수점이란, 표시되는 숫자는 10진법에 의해서 표시되지만, 실제 소수를 나타내는 부분은 2진법에의해서 구성되어있는 부분에서 생기는 차이이다.

 

이때, 지수부(소수점 앞에 부분)는 2진법의 표현으로 10진법의 모든수를 표현할 수 있지만, 가수부(fraction,소수점 뒤에 부분)는 2진법의 표현으로 10진법의 모든수를 표현할 수 없고, 그에따라서 부동소수점 문제가 발생하게 된다.

 

fraction부분은 각 소수점 자리가 1/2, 1/4, 1/8, 1/16, ... 의 크기를 가지고 있으며, 10진법으로는 0.5, 0.25, 0.125, 0.0625, ...으로 표현되게된다. 그렇게되면, 0.1이란 숫자를 만들기위해서, 1/16+ ... 과 같이 2진법으로 아무리 표현한다해도 정확한 0.1이 나오는게 아니라, 0.1000000119209290과같은 숫자로 근사하게된다.

만약 무한히 작은 2진법으로 근사하게된다면, 0.1에 거의 근사하게되겠지만, 무한히라는 단어는 사실상 구현 불가능한 용어이며, 0.1을 표현하는데 수없이 많은 용량을 할당하게된다. 그렇기에, float64와 같은 자료형의 최대범주안에서 0.1에 근사하게 된다.

 

그에 따라 0.3 -0.2같은경우 0.1이 아닌, 0.0999999999xx같은 숫자로 표현되게 되며, 0.1또한 0.1이 아닌, 0.09999999xxx같은 숫자로 표현되게 되므로, 둘의 완벽히 같은 숫자가 아니기 때문에, boolean조건에서 false로 인식하게 된다.

 

그에대한 해결 방안은, 언어마다 다르겠지만, 주로 반올림, 작은 소수점 무시 등등의 방식으로 해결하면된다.