📌 Number.EPSILON (앱실론) 심도 있게 이해하기
Number.EPSILON은 자바스크립트에서 표현할 수 있는 가장 작은 부동소수점 차이값을 나타내는 상수다.
즉, 두 개의 숫자가 같다고 간주할 수 있는 최소한의 차이를 의미한다.
console.log(Number.EPSILON); // 2.220446049250313e-16
✔️ Number.EPSILON의 값은 2.220446049250313e-16 (약 2.22 × 10⁻¹⁶)이다.
이는 1과 1보다 큰 가장 작은 숫자 간의 차이를 의미한다.
자바스크립트에서 숫자는 IEEE 754 부동소수점 방식으로 저장된다.
이 방식은 정확한 소수를 저장하지 못하는 경우가 있다.
🔹 부동소수점 연산 오류 예시
console.log(0.1 + 0.2); // 0.30000000000000004 ❌
console.log(0.1 + 0.7); // 0.7999999999999999 ❌
위 코드에서 기대값은 0.3, 0.8이지만, 부동소수점 방식의 특성상 작은 오차가 발생한다.
이러한 오차 때문에 0.1 + 0.2 === 0.3을 비교하면 false가 나온다.
console.log(0.1 + 0.2 === 0.3); // false ❌
✅ Number.EPSILON을 사용하면 이 문제를 해결할 수 있다.
Number.EPSILON을 사용하면 두 숫자의 차이가 아주 작을 때, 같은 값으로 간주할 수 있다.
🔹 정확한 소수 비교 함수
function isEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // true ✅
console.log(isEqual(0.1 + 0.7, 0.8)); // true ✅
✅ 이 함수는 두 숫자의 차이가 Number.EPSILON보다 작으면 같은 값으로 판단한다.
✅ 즉, 0.1 + 0.2와 0.3이 같다고 인식하게 된다.
자바스크립트의 부동소수점 연산 방식(IEEE 754)에서 숫자는 64비트(8바이트)로 저장된다.
이 중,
• 1비트 → 부호(Sign)
• 11비트 → 지수(Exponent)
• 52비트 → 가수(Fraction)
이런 방식으로 저장되기 때문에 일부 소수를 정확하게 표현할 수 없다.
예를 들어, 0.1은 2진수로 변환하면 무한 반복되는 값이 된다.
0.1(10진수) = 0.00011001100110011...(2진수)
이러한 이유로 0.1과 같은 값을 정확하게 저장할 수 없어 연산 시 오차가 발생한다.
이때, Number.EPSILON을 이용하면 숫자 비교 시 발생하는 오차를 해결할 수 있다.
✅ 1) Math.abs()와 함께 사용하여 오차 보정
function isSame(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.log(isSame(0.1 + 0.2, 0.3)); // true
console.log(isSame(0.15 + 0.15, 0.3)); // true
👉 두 값의 차이가 Number.EPSILON보다 작으면 같다고 간주한다.
✅ 2) 배열에서 특정 값 찾기 (정확한 소수 비교)
const numbers = [0.1, 0.2, 0.3];
console.log(numbers.includes(0.1 + 0.2)); // false (부동소수점 오차 때문)
console.log(numbers.some(n => isSame(n, 0.1 + 0.2))); // true (오차 보정)
👉 includes()는 오차 때문에 false를 반환하지만, isSame()을 활용하면 정확한 비교가 가능하다.
🔹 Number.EPSILON은 아주 작은 값이지만, 모든 부동소수점 오류를 해결하는 것은 아니다.
• Number.EPSILON은 1과 1보다 큰 가장 작은 숫자 간의 차이이므로,
더 작은 값들을 비교할 때는 적절하지 않을 수 있다.
• 값의 크기에 따라 오차가 다를 수 있다.
→ 0.1과 0.2의 비교는 Number.EPSILON으로 해결되지만,
더 큰 수(예: 100000000.1과 100000000.2)는 더 큰 오차를 가질 수 있다.
🔹 오차 범위를 조정하는 방법
오차 범위를 조절하려면 비교하는 값의 크기에 따라 EPSILON을 조정해야 한다.
function isAlmostEqual(a, b, epsilon = Number.EPSILON * Math.max(1, Math.abs(a), Math.abs(b))) {
return Math.abs(a - b) < epsilon;
}
console.log(isAlmostEqual(100000000.1 + 0.2, 100000000.3)); // true
console.log(isAlmostEqual(0.1 + 0.2, 0.3)); // true
✅ 큰 숫자일수록 EPSILON을 더 크게 조정하여 비교 정확도를 높인다.
자바스크립트에서 아주 작은 숫자 차이를 나타내는 값이다.
숫자로 표현하면 0.000000000000000222 (약 2.22 × 10⁻¹⁶)
console.log(Number.EPSILON); // 2.220446049250313e-16
✅ 이 값은 자바스크립트가 표현할 수 있는 가장 작은 부동소수점 차이값이다.
✅ 두 숫자가 거의 같은지 비교할 때 사용한다.
자바스크립트에서 소수점 계산을 하면 정확한 값이 안 나올 수 있다!
console.log(0.1 + 0.2); // 0.30000000000000004 ❌ (0.3이 아님!)
console.log(0.1 + 0.7); // 0.7999999999999999 ❌ (0.8이 아님!)
✅ 소수점 연산 시 미세한 오차가 발생한다.
✅ 이 문제를 해결하려면 Number.EPSILON을 사용하면 된다!
✅ 정확한 소수점 비교 함수
function isEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // true ✅ (정확한 비교 가능!)
console.log(isEqual(0.15 + 0.15, 0.3)); // true ✅
✅ Math.abs(a - b) → 두 숫자의 차이가 Number.EPSILON보다 작으면 같은 값으로 간주한다.
✅ 즉, 0.1 + 0.2를 비교할 때 실제 값이 0.30000000000000004라도 0.3으로 인정해 준다.
✅ 배열에서 특정 값 찾을 때 (부동소수점 오차 보정)
const numbers = [0.1, 0.2, 0.3];
console.log(numbers.includes(0.1 + 0.2)); // false ❌ (오차 때문에 찾을 수 없음)
console.log(numbers.some(n => isEqual(n, 0.1 + 0.2))); // true ✅ (오차 보정으로 찾음)
✅ numbers.includes(0.1 + 0.2) → 부동소수점 오차 때문에 false가 나옴.
✅ isEqual()을 사용하면 정확하게 비교할 수 있다!
✅ 큰 숫자 비교할 때는 EPSILON 값을 조정해야 한다.
function isAlmostEqual(a, b) {
const epsilon = Number.EPSILON * Math.max(1, Math.abs(a), Math.abs(b));
return Math.abs(a - b) < epsilon;
}
console.log(isAlmostEqual(100000000.1 + 0.2, 100000000.3)); // true ✅
✅ 큰 숫자는 Number.EPSILON보다 더 큰 오차가 발생할 수 있다.
✅ 비교하는 숫자의 크기에 따라 EPSILON 값을 조정해야 한다!