Number.EPSILON
Holds the smallest gap between 1 and the next representable double, about 2.22e-16.
Number.EPSILON- Added in JavaScript ES2015
Return value
numberThe difference between 1 and the smallest floating point number greater than 1, that is 2^-52, approximately 2.220446049250313e-16.
Number.EPSILON is 2-52, the distance between 1 and the next double above it. It is a non-writable, non-enumerable, non-configurable property of Number. Its purpose is to give you a principled tolerance when comparing floating point results, instead of an invented constant like 0.00001.
The problem it solves
0.1 + 0.2 === 0.3 is false, because the sum comes out as 0.30000000000000004. Comparing with Math.abs(a - b) < Number.EPSILON reports them equal, which is almost always what you meant.
The trap: it is only correct near 1
The spacing between doubles grows with magnitude. Around 1 the gap is EPSILON; around 1,000,000 it is roughly a million times larger. So a bare EPSILON comparison fails for big values — two numbers that differ only by accumulated rounding error will look unequal. Scale the tolerance to the operands:
Math.abs(a - b) <= Number.EPSILON * Math.max(Math.abs(a), Math.abs(b))
and add a small absolute floor if either value can be near zero, where relative comparison breaks down.
When not to use it
For money, do not compare with a tolerance at all — work in integer minor units. EPSILON is for measurements, geometry and iterative numeric code.
Example
When to use it
- Compare two computed floats for practical equality
- Set a convergence threshold in an iterative calculation
- Decide whether a geometry result is effectively zero
Frequently asked questions
How do I compare two floats for equality in JavaScript?
Compare the absolute difference against a tolerance scaled to the values: Math.abs(a - b) <= Number.EPSILON * Math.max(Math.abs(a), Math.abs(b), 1). A bare === fails because of binary rounding.
Why is 0.1 + 0.2 not equal to 0.3?
Neither 0.1 nor 0.2 has an exact binary representation, so their sum lands on 0.30000000000000004, a different double from 0.3.
Is Number.EPSILON the smallest number in JavaScript?
No, that is Number.MIN_VALUE (about 5e-324). EPSILON is the gap between 1 and the next representable value, roughly 2.22e-16.
More examples
Why a fixed epsilon fails at scale
At a magnitude of one million the representable gap is far larger than EPSILON, so the tolerance must scale with the operands and usually needs a few units-in-the-last-place of slack.
const a = 1_000_000.1 + 0.2;
const b = 1_000_000.3;
console.log(a - b); // -1.1641532182693481e-10
console.log(Math.abs(a - b) < Number.EPSILON); // false — the real gap here dwarfs EPSILON
const relative = (x, y) =>
Math.abs(x - y) <= Number.EPSILON * Math.max(Math.abs(x), Math.abs(y), 1);
console.log(relative(a, b)); // true — scaling the tolerance to the magnitude fixes it
console.log(Math.abs(a - b) <= 8 * Number.EPSILON * Math.abs(b)); // true — with extra ulps of slackA reusable comparison helper
Clamping the scale at 1 supplies an absolute floor near zero while keeping the comparison relative for larger magnitudes.
function almostEqual(a, b, ulps = 4) {
if (a === b) return true;
const scale = Math.max(Math.abs(a), Math.abs(b));
return Math.abs(a - b) <= ulps * Number.EPSILON * Math.max(scale, 1);
}
console.log(almostEqual(0.1 + 0.2, 0.3)); // true
console.log(almostEqual(1e6 + 0.1 + 0.2, 1e6 + 0.3)); // true
console.log(almostEqual(0, 1e-300)); // true — absolute floor of 1
console.log(almostEqual(1, 1.0001)); // falseEpsilon is not the smallest number
MIN_VALUE is the smallest positive double; EPSILON is the resolution near 1. Adding MIN_VALUE to 1 changes nothing, which is exactly the distinction.
console.log(Number.EPSILON); // 2.220446049250313e-16
console.log(Number.MIN_VALUE); // 5e-324
console.log(Number.EPSILON > Number.MIN_VALUE); // true
// EPSILON is a gap, MIN_VALUE is a magnitude
console.log(1 + Number.MIN_VALUE === 1); // true
console.log(0 + Number.MIN_VALUE === 0); // false
Discussion