JavaScript에서 숫자 연산을 하다 보면 예상치 못한 결과를 얻는 경우가 자주 있습니다. 특히 소수점이 포함된 계산에서 이러한 문제가 더 자주 발생합니다. 예를 들어, 우리가 1689와 0.015를 곱한 후 반올림을 기대할 때 발생하는 부동소수점 연산 오류를 살펴보겠습니다.
1. 문제 발생: 소수점 연산 오류
다음과 같은 간단한 곱셈 연산을 해보면:
let result = 1689 * 0.015;
console.log(result); // 예상 결과 25.335
예상한 결과는 25.335 이고, 이 값을 소수점 2자리까지 반올림한다면 25.34가 나와야 합니다.
하지만 실제 연산값은 25.334999999999997입니다. 이 숫자는 반올림 경계에 매우 가깝기 때문에 JavaScript의 기본 함수인 Math.round()
나 toFixed()
를 사용하면 원치 않는 결과가 나올 수 있습니다.
2. 기존 해결 방법: Math.round()
와 toFixed()
1) Math.round()
를 사용한 반올림
let rounded = Math.round(1689 * 0.015 * 100) / 100;
console.log(rounded); // 25.33
Math.round()
로 계산하면 결과는 25.33입니다. 우리가 기대했던 25.34와 다른 결과가 나왔습니다. 부동소수점 연산 때문에 25.334999999999997이 계산되었고, 이 값은 25.33으로 반올림됩니다.
2) toFixed()
를 사용한 반올림
let fixed = (1689 * 0.015).toFixed(2);
console.log(fixed); // "25.33"
toFixed()
를 사용해도 결과는 25.33입니다. 이 역시 우리가 원하는 25.34가 아닙니다.
이처럼 부동소수점 연산 오류는 우리가 기대한 반올림 값을 출력하지 못하게 만듭니다. 특히, 반올림 경계에 있는 경우 더 심각한 오차가 발생합니다. 이로 인해 프로그램의 신뢰성이 떨어질 수 있습니다.
3. 해결책: 외부 라이브러리 사용
이런 부동소수점 문제를 근본적으로 해결하기 위해서는 외부 라이브러리를 사용하는 것이 가장 좋은 방법입니다. 다양한 실수 연산 라이브러리 중 decimal.js
는 부동소수점 연산 오류를 해결하고, 소수점 연산에서 더 높은 정확도를 제공합니다.
4. decimal.js
로 정확한 결과 얻기
decimal.js
는 JavaScript의 기본 부동소수점 연산 방식을 벗어나 정밀한 고정 소수점 연산을 지원합니다. 이를 통해 소수점 계산에서 발생하는 모든 오차를 제거할 수 있습니다.
const Decimal = require('decimal.js');
let result = (new Decimal(1689)).times(0.015).toString();
console.log(result); // "25.34"
이제 드디어 우리가 원하는 25.34라는 정확한 값을 얻을 수 있습니다. decimal.js
는 부동소수점 오류 없이 계산을 처리해줍니다.
5. 자주 발생하는 부동소수점 문제: 0.1 + 0.2
소수점 계산에서 자주 발생하는 또 다른 문제는 0.1 + 0.2입니다. 아래 코드를 살펴보면:
let result = 0.1 + 0.2;
console.log(result); // 0.30000000000000004
이 결과는 JavaScript에서 흔히 발생하는 부동소수점 오류입니다. 일반적으로 이 문제는 Math.round()
나 toFixed()
로 해결할 수 있지만, 반올림 경계에 가까운 값에서는 제대로 동작하지 않을 수 있습니다.
부동소수점 연산이 포함된 더 복잡한 계산에서는 이러한 방법들이 신뢰할 만한 결과를 제공하지 못할 수 있습니다. 이런 상황에서는 외부 라이브러리를 사용하는 것이 최선의 방법입니다.
6. 결론: decimal.js
를 통한 정확한 실수 연산
JavaScript에서 소수점 연산을 할 때, 부동소수점 오류가 발생하여 기대한 값과 다른 결과가 나올 수 있습니다. 특히 이번 예시처럼 반올림 경계에 있는 값에서는 문제가 더 심각해질 수 있습니다. 이런 문제를 해결하기 위해 decimal.js
와 같은 라이브러리를 사용하는 것이 매우 유용합니다. 이제는 꼼수 대신 정확한 계산을 위해 외부 라이브러리를 사용하는 것이 좋습니다.
decimal.js
Cheat Sheet
다음은 decimal.js
의 자주 사용하는 기능들을 정리한 Cheat Sheet입니다. 이를 통해 복잡한 실수 연산을 더 쉽게 처리할 수 있습니다.
기본 설정
// 라이브러리 설치
npm install decimal.js
사칙연산
//**곱셈:**
let result = (new Decimal(1689)).times(0.015);
console.log(result.toString()); // "25.34"
//**덧셈:**
let sum = new Decimal(1689).plus(10); // 1689 + 10
//**뺄셈:**
let difference = new Decimal(1689).minus(10); // 1689 - 10
//**나눗셈:**
let quotient = new Decimal(1689).div(10); // 1689 / 10
반올림/내림/올림
//**소수점 이하 자리 반올림:**
result.toDecimalPlaces(2); // 소수점 2자리까지 반올림
//**내림:**
result.toDecimalPlaces(2, Decimal.ROUND_FLOOR);
//**올림:**
result.toDecimalPlaces(2, Decimal.ROUND_CEIL);
비교 연산
//**같은지 확인:**
new Decimal(1689).equals(new Decimal(1689)); // true
//**크거나 같은지 확인:**
new Decimal(1689).greaterThanOrEqualTo(1000); // true
형 변환
//**문자열로 변환:**
result.toString();
//**숫자로 변환:**
result.toNumber();
이 Cheat Sheet를 활용하면 decimal.js
를 통해 복잡한 소수점 연산을 더욱 정확하게 처리할 수 있습니다.
'WEB - PHP, JQuery, Bootstrap' 카테고리의 다른 글
가독성 높은 JavaScript Array 순회 방법 TOP 4 (2) | 2024.11.11 |
---|---|
JavaScript 정밀 연산 라이브러리 TOP 4: big.js, bignumber.js, decimal.js, math.js (5) | 2024.09.24 |
.NET Core에서 MemoryCache를 활용한 Backend 캐시 구현 가이드 (2) | 2024.09.13 |
A4 용지 출력에 맞춘 CSS 설정 (76) | 2024.07.26 |
Entity Framework 필드 유형별 DB컬럼 매핑 (0) | 2024.07.11 |