在 JavaScript 中,Number
对象是一个非常重要的内置对象,它用于表示数字。不过,JavaScript 的 Number
类型存在一些数值范围和精度方面的特性与问题,了解这些对于编写准确可靠的代码至关重要。
JavaScript 中的 Number
类型采用 IEEE 754 双精度 64 位浮点数表示。这意味着它能表示的数值范围是有限的。
安全整数是指可以精确表示并进行准确比较的整数。JavaScript 中最大安全整数由 Number.MAX_SAFE_INTEGER
表示,其值为 9007199254740991
;最小安全整数由 Number.MIN_SAFE_INTEGER
表示,值为 -9007199254740991
。
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
当我们处理的整数超出这个范围时,就可能会出现精度丢失的问题。
const num = Number.MAX_SAFE_INTEGER + 1;
const num2 = Number.MAX_SAFE_INTEGER + 2;
console.log(num === num2); // true,这显然不符合数学逻辑,是精度丢失导致的
除了安全整数范围,JavaScript 还有最大可表示数值和最小可表示数值。最大可表示数值由 Number.MAX_VALUE
表示,约为 1.7976931348623157e+308
;最小可表示数值由 Number.MIN_VALUE
表示,约为 5e-324
。
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324
当数值超过 Number.MAX_VALUE
时,会得到 Infinity
;当数值小于 Number.MIN_VALUE
时,会得到 0
。
const bigNum = Number.MAX_VALUE * 2;
console.log(bigNum); // Infinity
const smallNum = Number.MIN_VALUE / 2;
console.log(smallNum); // 0
由于 JavaScript 使用浮点数表示所有数字,在进行小数运算时会出现精度问题。
console.log(0.1 + 0.2); // 0.30000000000000004
这是因为 0.1 和 0.2 在二进制表示中是无限循环小数,而浮点数只能存储有限的位数,所以在计算时会出现舍入误差。
为了解决小数运算的精度问题,我们可以使用一些技巧。例如,将小数转换为整数进行计算,然后再转换回小数。
function add(num1, num2) {
const baseNum = Math.pow(10, Math.max(
num1.toString().split('.')[1]?.length || 0,
num2.toString().split('.')[1]?.length || 0
));
return (num1 * baseNum + num2 * baseNum) / baseNum;
}
console.log(add(0.1, 0.2)); // 0.3
特性 | 描述 | 值 |
---|---|---|
最大安全整数 | 可以精确表示并进行准确比较的最大整数 | 9007199254740991 |
最小安全整数 | 可以精确表示并进行准确比较的最小整数 | -9007199254740991 |
最大数值 | JavaScript 可表示的最大数值 | 1.7976931348623157e+308 |
最小数值 | JavaScript 可表示的最小非零正值 | 5e-324 |
在编写 JavaScript 代码时,我们要时刻注意数值的范围和精度问题,避免因为这些问题导致程序出现意外的结果。掌握这些知识,能让我们的代码更加健壮和可靠。