jsguides

Number.EPSILON

Number.EPSILON

Number.EPSILON is a static numeric constant on the Number constructor. It exists so that JavaScript code can express “how close is close enough” when comparing values that IEEE-754 arithmetic has nudged away from their exact mathematical result.

Syntax

Number.EPSILON

Number.EPSILON takes no arguments. It is a property, not a method, and there is no new form and no call parens.

Description

Number.EPSILON is the difference between 1 and the smallest floating-point number greater than 1 that Number can represent. JavaScript numbers are IEEE-754 binary64 doubles with a 52-bit mantissa, so the smallest amount you can change 1.0 by is 2^-52, which is what EPSILON is.

Its approximate value is 2.220446049250313e-16, and the property descriptor makes it non-writable, non-enumerable, and non-configurable:

Object.getOwnPropertyDescriptor(Number, 'EPSILON');
// { value: 2.220446049250313e-16, writable: false, enumerable: false, configurable: false }

Because the descriptor is locked, attempts to overwrite or delete it fail in strict mode and silently no-op in sloppy mode. The same TypeError shows up if you try to redefine EPSILON via Object.defineProperty, which is why existing polyfills for this constant only assign it when missing rather than overwriting a value that is already in place:

"use strict";
Number.EPSILON = 0;
// TypeError: Cannot assign to read only property 'EPSILON'

A common point of confusion: Number.EPSILON is not Number.MIN_VALUE. MIN_VALUE (about 5e-324) is the smallest positive denormalized double; EPSILON (about 2.22e-16) is the resolution at magnitude 1. They answer different questions and differ by roughly 300 orders of magnitude.

Value

Number.EPSILON;
// 2.220446049250313e-16

Number.EPSILON.toString();
// "2.220446049250313e-16"

typeof Number.EPSILON;
// "number"

EPSILON is a regular number (not a BigInt and not a special sentinel like NaN or Infinity), so it works with any numeric operator.

Examples

The classic 0.1 + 0.2 problem

0.1 + 0.2;
// 0.30000000000000004
0.1 + 0.2 === 0.3;
// false

// The residual sits well below EPSILON
Math.abs(0.1 + 0.2 - 0.3);
// 5.551115123125783e-17
Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON;
// true

0.1 cannot be represented exactly in binary floating point, so 0.1 + 0.2 lands at 0.30000000000000004. The error is on the order of 2^-52, which is exactly the scale Number.EPSILON is designed to express.

Equality helper near magnitude 1

function equal(x, y, tolerance = Number.EPSILON) {
  return Math.abs(x - y) < tolerance;
}

equal(0.1 + 0.2, 0.3);
// true
equal(0.15 + 0.15, 0.3);
// true
equal(1, 1);
// true

Number.EPSILON is a reasonable default tolerance when both operands sit around magnitude 1 and came from arithmetic on doubles. Pass an explicit tolerance whenever that assumption breaks.

Why a flat EPSILON fails at larger magnitudes

function equal(x, y, tolerance = Number.EPSILON) {
  return Math.abs(x - y) < tolerance;
}

equal(1000.1 + 1000.2, 2000.3);
// false

Floating-point spacing grows with magnitude: the gap between adjacent doubles around 2000 is roughly 2000 * EPSILON (about 4.44e-13). Comparing 2000.3000000000003 against 2000.3 with a flat tolerance of 2.22e-16 is roughly a thousand times too tight, so the helper returns false even though the numbers are “the same” in any practical sense.

Scaled tolerance for larger magnitudes

Scale the tolerance by the operands’ magnitude instead of using a flat EPSILON:

function approxEqual(a, b, relTol = Number.EPSILON) {
  return Math.abs(a - b) < Math.max(Math.abs(a), Math.abs(b)) * relTol;
}

approxEqual(1000.1 + 1000.2, 2000.3);
// true
approxEqual(1e15 + 1, 1e15);
// true

Use a relative tolerance whenever your values can span more than one order of magnitude. A flat EPSILON is a footgun for anything outside the neighborhood of 1.

Static only

(1).EPSILON;
// undefined
(0.1).EPSILON;
// undefined

EPSILON lives on the Number constructor, not on Number.prototype. Number instances inherit nothing from it; always reach for it as Number.EPSILON.

Specifications

SpecificationStatusComment
ECMAScript 2015 (6th Edition, ES6)StandardizedIntroduced alongside Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER.
ECMAScript (latest)Living standardSection sec-number.epsilon on the ECMA-262 numbers-and-dates page.

Browser compatibility

Number.EPSILON is supported in every current engine that targets ES2015: Node.js 0.12+, all maintained Chromium, Firefox, and Safari releases (Safari 9+), and any modern mobile browser. Internet Explorer never shipped it; IE 11 partially supports ES2015 constants but lacks Number.EPSILON. No polyfill is needed in any environment you can reasonably target today.

See Also

  • Number.MAX_SAFE_INTEGER — the largest integer n such that n and n + 1 are both representable exactly; pairs naturally with EPSILON when reasoning about precision boundaries.
  • Number.isFinite() — validate inputs before doing an epsilon comparison; NaN and Infinity break the assumptions behind any tolerance check.
  • Number.prototype.toFixed() — the read-side companion to EPSILON: use it to display a number with controlled precision when comparing alone is not enough.