본문 바로가기
컴퓨터공학

부동소수점 방식에서 0.1*0.1 이 0.01이 아닌 이유와 해결 방법

by 바코94 2024. 5. 10.

결론부터 이야기하면 부동소수점은 근사치이며 소수를 정확히 표현할 수 없다. 
부동소수점 방식을 사용할 때 0.1*0.1은 0.01이 아니다. 크롬 개발자도구 등을 열어 0.1 * 0.1 을 계산해보면 알 수 있다. 


왜 이럴까?
부동소수점 방식(IEEE 754)으로 저장된 십진수 0.1은 근사치를 사용하게 된다. 왜 근사치를 사용하는지, 왜 오차가 생기는지 알기 위해서는 0.1이  어떻게 표현되는지 알아야 한다. 이전 포스팅에서 자세한 내용을 설명했는데 링크를 남겨놓는다. (자세한 부동소수점 내용은 다음 글 참조: https://bako94.tistory.com/328)
간단히 리마인드하자면, 부동소수점 방식에서는 소수점 오른쪽에 있는 숫자들을 2진수로 변환할때 2를 곱하는 것을 반복하여 0과 1을 뽑아내게 되는데, 0.1의 경우는 2를 곱하는 과정을 무한히 반복하여도 x.0의 형태가 나오지 않기 때문이다. 0.1 ->0, 0.2 -> 0, 0.4 -> 0, 0.8 -> 0, 1.6 -> 1, 1.2 -> 1, 0.4 -> 0,... 

십진수 0.1을 IEEE 754 방식으로 표현하면 다음과 같다. 32비트 기준이며 sign bit, 지수부, 가수부 에 대한 값이다.
0 10000011 10011001100110011001100

따라서, 부동소수점 방식은 오차가 발생하며 우리가 십진수로 표기하는 0.1을 정확하게 표현할 수 없다.

 

어떻게 해결할까?
부동소수점 방식을 사용해서는 오차가 생길 수 밖에 없기 때문에, 오차가 있으면 안되는 방법은 적합하지가 않다. 따라서 고정소수점 방식과 같이 오차가 생기지 않도록하는 방법을 사용하여야 한다. 
java에서는 고정소수점 방식으로 BigDecimal 과 같은 타입을 제공한다.

결론
부동소수점 방식에서 소수점 표현은 오차가 허용되며, 돈을 다루는 것과 같이 오차가 생겨서 안되는 데이터에서는 부동소수점이 적합하지 않다.

'컴퓨터공학' 카테고리의 다른 글

부동소수점 곱셈 방법  (0) 2024.05.09
[Application Layer]HTTP  (0) 2020.05.10