Number.EPSILON

Number.EPSILON 静态数据属性表示 1 和大于 1 的最小浮点数之间的差。

¥The Number.EPSILON static data property represents the difference between 1 and the smallest floating point number greater than 1.

Try it

¥Value

2-52,或大约 2.2204460492503130808472633361816E-16

¥2-52, or approximately 2.2204460492503130808472633361816E-16.

Property attributes of Number.EPSILON
Writable no
Enumerable no
Configurable no

描述

¥Description

Number.EPSILON 是 1 与 Number 格式中可表示的下一个更大数字之间的差值,因为 双精度浮点格式 只有 52 位来表示 mantissa,最低位的意义为 2-52

¥Number.EPSILON is the difference between 1 and the next greater number representable in the Number format, because double precision floating point format only has 52 bits to represent the mantissa, and the lowest bit has a significance of 2-52.

请注意,浮点数的绝对精度随着数字变大而降低,因为指数增大而尾数的精度保持不变。Number.MIN_VALUE 是最小的可表示的正数,它比 Number.EPSILON 小得多。

¥Note that the absolute accuracy of floating numbers decreases as the number gets larger, because the exponent grows while the mantissa's accuracy stays the same. Number.MIN_VALUE is the smallest representable positive number, which is much smaller than Number.EPSILON.

由于 EPSILONNumber 的静态属性,因此你始终将其用作 Number.EPSILON,而不是作为数字值的属性。

¥Because EPSILON is a static property of Number, you always use it as Number.EPSILON, rather than as a property of a number value.

示例

¥Examples

测试平等

¥Testing equality

任何占用有限位数的数字编码系统,无论你选择什么基数(例如十进制或二进制),都必然无法准确表示所有数字,因为你试图使用 有限的内存量。例如,以 10 为基数(十进制)的系统无法准确表示 1/3,以 2 为基数(二进制)的系统无法准确表示 0.1。因此,例如,0.1 + 0.2 并不完全等于 0.3

¥Any number encoding system occupying a finite number of bits, of whatever base you choose (e.g. decimal or binary), will necessarily be unable to represent all numbers exactly, because you are trying to represent an infinite number of points on the number line using a finite amount of memory. For example, a base-10 (decimal) system cannot represent 1/3 exactly, and a base-2 (binary) system cannot represent 0.1 exactly. Thus, for example, 0.1 + 0.2 is not exactly equal to 0.3:

js
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false

因此,通常建议不要将浮点数与 === 进行比较。相反,如果两个数字彼此足够接近,我们可以认为它们相等。如果算术大约是 1 的大小,那么 Number.EPSILON 常量通常是一个合理的错误阈值,因为 EPSILON 本质上指定了数字 "1" 的准确程度。

¥For this reason, it is often advised that floating point numbers should never be compared with ===. Instead, we can deem two numbers as equal if they are close enough to each other. The Number.EPSILON constant is usually a reasonable threshold for errors if the arithmetic is around the magnitude of 1, because EPSILON, in essence, specifies how accurate the number "1" is.

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

const x = 0.2;
const y = 0.3;
const z = 0.1;
console.log(equal(x + z, y)); // true

然而,Number.EPSILON 不适用于任何更大规模的算术运算。如果你的数据在 103 数量级,则小数部分的精度将比 Number.EPSILON 小得多:

¥However, Number.EPSILON is inappropriate for any arithmetic operating on a larger magnitude. If your data is on the 103 order of magnitude, the decimal part will have a much smaller accuracy than Number.EPSILON:

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

const x = 1000.1;
const y = 1000.2;
const z = 2000.3;
console.log(x + y); // 2000.3000000000002; error of 10^-13 instead of 10^-16
console.log(equal(x + y, z)); // false

在这种情况下,需要更大的公差。由于比较的数字的大小约为 2000,因此诸如 2000 * Number.EPSILON 之类的乘数为此实例创建了足够的容差。

¥In this case, a larger tolerance is required. As the numbers compared have a magnitude of approximately 2000, a multiplier such as 2000 * Number.EPSILON creates enough tolerance for this instance.

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

const x = 1000.1;
const y = 1000.2;
const z = 2000.3;
console.log(equal(x + y, z, 2000 * Number.EPSILON)); // true

除了幅度之外,考虑输入的准确性也很重要。例如,如果数字是从表单输入中收集的,并且输入值只能通过 0.1(即 <input type="number" step="0.1">)步长进行调整,则通常允许更大的容差(例如 0.01)是有意义的,因为数据只有 精度为 0.1

¥In addition to magnitude, it is important to consider the accuracy of your input. For example, if the numbers are collected from a form input and the input value can only be adjusted by steps of 0.1 (i.e. <input type="number" step="0.1">), it usually makes sense to allow a much larger tolerance, such as 0.01, since the data only has a precision of 0.1.

注意:重要要点:不要简单地使用 Number.EPSILON 作为相等性测试的阈值。使用适合你要比较的数字的大小和准确性的阈值。

¥Note: Important takeaway: do not simply use Number.EPSILON as a threshold for equality testing. Use a threshold that is appropriate for the magnitude and accuracy of the numbers you are comparing.

规范

Specification
ECMAScript Language Specification
# sec-number.epsilon

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看