3.445
3.445.toPrecision(3)이 3.44를 반환하는 이유는 JavaScript의 반올림 방식 때문입니다. JavaScript는 반올림에서 근사치 오차를 발생시키는 부동 소수점 방식을 사용하기 때문에, 3.445 같은 숫자는 내부적으로 정확하게 표현되지 않고 약간 차이가 있을 수 있습니다.
JavaScript의 부동 소수점 처리 방식
JavaScript는 숫자를 IEEE 754 부동 소수점 형식으로 처리합니다. 이로 인해 3.445는 실제로는 **3.4449999999...**로 저장될 수 있습니다. 따라서, toPrecision(3)은 이 값을 세 번째 자리에서 반올림하고 3.44로 처리하게 되는 것입니다.
3.435
3.435.toPrecision(3)이 3.44를 반환하는 이유는, 부동 소수점 오차가 모든 수에서 동일하게 적용되는 것이 아니기 때문입니다. JavaScript의 반올림 규칙이 작용할 때, 부동 소수점 저장 방식에 따라 숫자들이 저장되는데, 일부 수는 근사 오차가 발생하고, 일부 수는 그렇지 않습니다.
반올림 규칙과 부동 소수점의 작용 방식
JavaScript에서 toPrecision()은 반올림을 적용하기 전에 근사 오차로 인한 미세한 차이가 있습니다. 다만, 일부 숫자는 정확하게 저장되거나 반올림 오차가 발생하지 않기 때문에 정상적으로 반올림되는 경우가 있습니다. 3.435는 내부적으로 저장될 때 3.4350000000...과 같이 근사 오차가 거의 없는 상태로 저장되기 때문에 반올림 규칙에 따라 올림이 적용됩니다.
결과적으로 3.435.toPrecision(3)은 오차가 없기 때문에 3.44로 정상 반올림됩니다.
왜 3.435와 3.445의 반올림이 다르게 되는가?
5일 경우 앞자리 숫자가 짝수면 버리고, 홀수면 올림하여 짝수로 만들어준다.
"Bankers' rounding" 또는 **"반올림-to-짝수(round half to even)"**라고 불리는 반올림 방식입니다. 자바스크립트와 많은 컴퓨터 시스템에서 사용되는 이 반올림 규칙은 5일 경우 특정한 방향으로 반올림하는 방식을 지정하여, 전체적인 수치 계산에서 오차를 최소화하고 통계적으로 균형을 맞추기 위해 사용됩니다.
Bankers' Rounding 동작 방식
Bankers' rounding에서 숫자가 정확히 5일 경우:
- 앞자리 숫자가 짝수면 그대로 유지합니다.
- 앞자리 숫자가 홀수면 1을 더해 짝수로 만듭니다.
이 방식은 무작정 올림하지 않고, 통계적으로 반올림 오차가 누적되는 것을 줄이는 효과가 있습니다. 예를 들어, 많은 0.5 값들이 모여도 평균적으로 오차가 상쇄되도록 해줍니다.
예제
- 3.5 → 앞자리가 홀수(3)이므로 올림하여 4가 됩니다.
- 4.5 → 앞자리가 짝수(4)이므로 버려져서 그대로 4가 됩니다.
- 2.5 → 앞자리가 짝수(2)이므로 버려져서 그대로 2가 됩니다.
- 1.5 → 앞자리가 홀수(1)이므로 올림하여 2가 됩니다.
JavaScript에서 Bankers' Rounding의 적용
JavaScript에서는 기본적으로 toPrecision() 또는 toFixed() 같은 메서드가 이 방식을 따르지 않습니다. 하지만 JavaScript의 부동 소수점 연산 결과는 내부적으로 Bankers' rounding의 영향을 받을 수 있습니다. 이를 통해 계산 중 발생하는 미세한 오차를 줄이고, 최종적으로 숫자의 반올림이 일관되도록 돕습니다.
따라서 toPrecision()을 사용할 때에도 Bankers' rounding이 반올림 결과에 영향을 줄 수 있다는 점을 염두에 두어야 합니다.
var n = 3.445;
// 3.44499999999
document.write(n.toPrecision(2)+"<br>"); // 3.4
document.write(n.toPrecision(3)+"<br>"); // 3.45 // (3.44) **********
document.write(n.toPrecision(4)+"<br>"); // 3.445
document.write(n.toPrecision(5)+"<br>"); // 3.4450
document.write("<br>");
n=3.446;
// 3.445999999999
document.write(n.toPrecision(2)+"<br>"); // 3.4
document.write(n.toPrecision(3)+"<br>"); // 3.45
document.write(n.toPrecision(4)+"<br>"); // 3.446
document.write(n.toPrecision(5)+"<br>"); // 3.4460
document.write("<br>");
n=3.435;
// 3.43499999
document.write(n.toPrecision(2)+"<br>"); // 3.4
document.write(n.toPrecision(3)+"<br>"); // (3.44) // 3.43 **********
document.write(n.toPrecision(4)+"<br>"); // 3.435
document.write(n.toPrecision(5)+"<br>"); // 3.4350
document.write("<br>");
n=3.436; // 3.43599999
document.write(n.toPrecision(2)+"<br>"); // 3.4 // 3.4
document.write(n.toPrecision(3)+"<br>"); // 3.44 // 3.44
document.write(n.toPrecision(4)+"<br>"); // 3.436 // 3.436
document.write(n.toPrecision(5)+"<br>"); // 3.4360 // 3.4360
document.write("<br>");
var n = 3.545; // 3.544999999
document.write(n.toPrecision(2)+"<br>"); // 3.5 // 3.5
document.write(n.toPrecision(3)+"<br>"); // 3.55 // (3.54) *******
document.write(n.toPrecision(4)+"<br>"); // 3.545 // 3.545
document.write(n.toPrecision(5)+"<br>"); // 3.5450 // 3.5450
document.write("<br>");
n=3.546; // 3.545999999
document.write(n.toPrecision(2)+"<br>"); // 3.5 // 3.5
document.write(n.toPrecision(3)+"<br>"); // 3.55 // 3.55
document.write(n.toPrecision(4)+"<br>"); // 3.546 // 3.546
document.write(n.toPrecision(5)+"<br>"); // 3.5460 // 3.5460
document.write("<br>");
n=3.535; // 3.534999999
document.write(n.toPrecision(2)+"<br>"); // 3.5 // 3.5
document.write(n.toPrecision(3)+"<br>"); // (3.54) // 3.53
document.write(n.toPrecision(4)+"<br>"); // 3.535 // 3.535
document.write(n.toPrecision(5)+"<br>"); // 3.5350 // 3.5350
document.write("<br>");
n=3.536; // 3.53599999
document.write(n.toPrecision(2)+"<br>"); // 3.5 // 3.5
document.write(n.toPrecision(3)+"<br>"); // 3.54 // 3.54
document.write(n.toPrecision(4)+"<br>"); // 3.536 // 3.536
document.write(n.toPrecision(5)+"<br>"); // 3.5360 // 3.5360
document.write("<br>");
n=3.555; // 3.554999999
document.write(n.toPrecision(2)+"<br>"); // 3.6 // 3.6
document.write(n.toPrecision(3)+"<br>"); // (3.56) // 3.55 ********
document.write(n.toPrecision(4)+"<br>"); // 3.555 // 3.555
document.write(n.toPrecision(5)+"<br>"); // 3.5550 // 3.5550
document.write("<br>");
n=3.5456; // 3.54559999
document.write(n.toPrecision(2)+"<br>"); // 3.5 // 3.5
document.write(n.toPrecision(3)+"<br>"); // 3.55 // 3.55
document.write(n.toPrecision(4)+"<br>"); // 3.546 // 3.546
document.write(n.toPrecision(5)+"<br>"); // 3.5456 // 3.5456
'JAVASCRIPT' 카테고리의 다른 글
JAVASCRIPT ) 인터페이스란? (0) | 2024.10.31 |
---|---|
JAVASCRIPT ) 쿠키 사용법 (0) | 2024.10.18 |
JAVASCRIPT ) 문자열 공백 제거 함수 trim() (0) | 2024.10.15 |
JAVASCRIPT ) 전치행렬 (0) | 2024.08.26 |
JAVASCRIPT ) 부울행렬의 연산 (0) | 2024.08.26 |