컴퓨터는 숫자를 2진수로 저장하여 계산합니다.
이때 만일 2진수로 변환하고자 하는수가 소수타입이라면 어떻게 될까요?
0.5 => 0.1
0.25 => 0.01
0.75 => 0.11
0.3 => 0.0100110011001.....(무한소수)
위의 예시 케이스들을 보면 알 수 있다시피, 2의 제곱 꼴의 합으로 소수를 표현해야 하므로 몇 가지의 케이스(분모가 2의 거듭제곱 꼴)를 제외하고는 소수들을 정확하게 표현하기에는 한계가 있습니다.
그래서 이런 문제가 눈앞에서 발생하곤 합니다.
우리의 JS가 또...🤦 라고 생각 할 수 있지만 사실 이는 JS만의 문제는 아닙니다.
사실 파이썬을 포함한 많은 언어가 이렇습니다.
서치하면서 몇가지 글들을 살펴보니까 JS는 부동소수점 방식을 사용해서 그렇다고 이야기하는데.. 부동소수점 방식이든, 고정소수점 방식이든 둘 다 오차가 발생합니다. 소수부를 이진수로 표현하고자 하기때문에 오차가 나는 것이니까요.
이런 오차를 해결하기 위한 방법으로 어떤것들이 있는지 알아봅시다.
Number.prototype.toFixed()
를 사용하면 파라미터로 주어진 자릿수까지 반올림한 결과를 문자열로 리턴합니다.
문자타입으로 리턴하므로 다음 계산에서 사용하기 위해서는 숫자형으로 변환해야 합니다.
10ⁿ(n=소수점 최대 길이) 만큼 곱해줘서 정수로 만들고, 계산 후 마지막에 다시 10ⁿ만큼 나누는 방법입니다.
Math.ceil
, Math.floor
, Math.trunc
, Math.round
와 같은 정수형 변환 메서드들을 사용하는 방법입니다.
정수로만 변환이 가능하므로 소수 계산을 위해서는 자릿수 보정이 필요합니다.
Source Code
위의 소스코드를 보면 decimal.js 에서 소수점 오차문제를 어떻게 해결하고 있는지 알 수 있습니다.