6.35.toFixed(1) == 6.3인 이유는 무엇일까요?
중요도: 4
이 문서에 따르면 Math.round
와 toFixed
는 둘 다 가장 가까운 어림수를 구해줍니다. 0..4
는 버림하고, 5..9
는 올림합니다.
예시:
alert( 1.35.toFixed(1) ); // 1.4
위 예시와 유사한 아래의 경우, 6.35
가 6.4
가 아닌 6.3
으로 반올림되는 이유는 무엇일까요?
alert( 6.35.toFixed(1) ); // 6.3
어떻게 하면 6.35
를 제대로 반올림할 수 있을까요?
10진법으로 나타낸 소수 6.35
는 내부적으로는 2진법 무한소수입니다. 따라서 이 경우에도 어김없이 정밀도 손실이 발생합니다.
아래 코드를 살펴봅시다.
alert( 6.35.toFixed(20) ); // 6.34999999999999964473
정밀도 손실은 수를 증가시킬 수도, 감소시킬 수도 있습니다. 위 예시에서는 수가 아주 약간 작아졌습니다. 따라서 반올림하면 버림이 일어납니다.
1.35
의 경우에는 어떨까요?
alert( 1.35.toFixed(20) ); // 1.35000000000000008882
이번에는 정밀도 손실로 수가 약간 증가했습니다. 따라서 반올림하면 올림이 일어납니다.
6.35
를 제대로 반올림하려면 어떻게 해야 할까요?
반올림하기 전에 이 수를 정수에 가깝게 만들어야 합니다.
alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000
63.5
에서는 정밀도 손실이 전혀 발생하지 않습니다. 소수 부분인 0.5
가 정확히 1/2
이기 때문입니다. 2진법 체계에서 2
의 거듭제곱으로 나눈 값은 정확하게 저장되기 때문에 제대로 반올림할 수 있습니다.
alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(반올림됨) -> 6.4