Number 数字
重要通知
。
基本概况
Number对象
根据语言规范,JavaScript 采用“遵循 IEEE 754 标准的双精度 64 位格式”("double-precision 64-bit format IEEE 754 values")表示数字。在JavaScript(除了BigInt)当中,并不存在整数/整型(Integer)。
注意事项
安全整数表示在 JavaScript 中能够精确表示的整数,安全整数的范围在 2 的 -53 次方到 2 的 53 次方之间(不包括两个端点),超过这个范围的整数无法精确表示,即数字有效范围为10^(-308) - 10^(308)之间。(9007 1992 5474 0991 - -9007 1992 5474 0991)
常量
- Number.EPSILON:表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。
- Number.MAX_SAFE_INTEGER:最大的安全整数 (2^53 - 1),即9007 1992 5474 0991。
- Number.MIN_SAFE_INTEGER:最小的安全整数 (-(2^53 - 1)),即-9007 1992 5474 0991。
- Number.MAX_VALUE:能表示的最大正数,MAX_VALUE 属性值接近于 1.7976931348623157e+308。大于 MAX_VALUE 的值代表 "Infinity"。 -Infinity > Number.MAX_VALUE
- Number.MIN_VALUE:能表示的最小正数即最接近 0 的正数 (实际上不会变成 0),即5e-324,小于 MIN_VALUE 的值代表 "-Infinity"。-Infinity < Number.MIN_VALUE
- Number.NaN:特殊的“非数字”值。
- Number.NEGATIVE_INFINITY:特殊的负无穷大值,在溢出时返回该值。
- Number.POSITIVE_INFINITY:特殊的正无穷大值,在溢出时返回该值。
核心方法
- number.toPrecision(x):指定精度的数字格式,x为指定的数字格式长度。
(1.335).toPrecision(20); // 输出:"1.3349999999999999645"
浮点数精度问题
注意JavaScript的安全数值区间为(Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER),因此超出该安全数值范围外的值会被影响,即产生浮点数精度问题。
console.log(0.1 + 0.2); // 输出:0.30000000000000004
解决方案:把浮点数转化为字符串,模拟实际运算的过程,例如采用第三方bignumber.js,decimal.js,以及big.js库等,这些库不仅解决了浮点数的运算精度问题,还支持了大数运算,并且修复了原生toFixed结果不准确的问题。
大数精度问题
// 9999 9999 9999 9999
console.log(9999999999999999); // 输出:1 0000 0000 0000 0000
四舍五入问题
JavaScript中四舍五入都是五(不包含五)以上入,反之则舍。
console.log(1.335.toFixed(2)); // 输出:1.33
console.log(Math.ceil(1.5)); // 输出:2
console.log(Math.floor(1.5)); // 输出:1
基础属性与方法
精度实现问题
精度误差示例
基础类库
- Number:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number
- 精度问题:https://www.runoob.com/w3cnote/js-precision-problem-and-solution.html
- bignumber.js:https://github.com/MikeMcl/bignumber.js
- decimal.js:https://github.com/MikeMcl/decimal.js
- big.js:https://github.com/MikeMcl/big.js
Number(数值)
JavaScript 能够准确表示的整数范围在-2^53到2^53之间(不含两个端点),超过这个范围,无法精确表示这个整数。 JS 中能精准表示的最大整数是 Math.pow(2, 53) 在JavaScript中数字不区分整型和浮点型,所有数字以浮点型表示; 数字有效范围为10^(-308) - 10^(308)之间; 当在JS中使用的数字大于JS所能表示的最大值时,JS就会将其输出Infinity,即无限大;反之,JS所使用的数字小于JS所能表示的最小值时,输出-Infinity。
JS 四舍五入
var num =2.446242342;
num = Math.round((num + Number.EPSILON) * 100) / 100; // 输出结果为 2.45
NaN:Not a Number 的缩写
即"不是一个数字Number"的意思,通常在进行数学运算时产生了未知的结果或错误,JS就会返回NaN。 (用0来除以0,JS就会返回NaN);在JS中使用isNaN()函数来判断运算结果是不是NaN。
精度
整数(不使用小数点或指数计数法)最多为 15 位
安全整数
安全整数表示在 JavaScript 中能够精确表示的整数,安全整数的范围在 2 的 -53 次方到 2 的 53 次方之间(不包括两个端点),超过这个范围的整数无法精确表示。
最大/最小安全整数
最大安全整数:安全整数范围的上限,即 2 的 53 次方减 1(9007 1992 5474 0991) 最小安全整数:安全整数范围的下限,即 2 的 53 次方减 1 的负数(-9007 1992 5474 0991)
特殊值
Infinity:数字超过数字上限(溢出),会被显示为无穷大(infinity)值;反之,结果为负无穷大,以-Infinity表示 NaN:
方法
toExponential() 可把对象的值转换成指数计数法 1000.toExponential(1) 1.0e+4 toFixed() 可把 Number 四舍五入为指定小数位数的数字 toPrecision() 把数字格式化为指定的长度 13.3714.toPrecision(3) 13.4 toString() 可以使用 toString() 方法 输出16进制、8进制、2进制 valueOf() 返回一个 Number 对象的基本数字值
[number].toFixed()
let result = 23.786; console.log(result.toFixed()); //24 console.log(result.toFixed(2)); //23.79
Number.isFinite()
用于检查一个数值是否为有限的( finite ),即不是 Infinity console.log( Number.isFinite(1)); // true console.log( Number.isFinite(0.1)); // true
NaN 不是有限的
console.log( Number.isFinite(NaN)); // false
console.log( Number.isFinite(Infinity)); // false
console.log( Number.isFinite(-Infinity)); // false
Number.isNaN()
用于检查一个值是否为 NaN Number.isNaN() 不存在隐式的 Number() 类型转换,非 NaN 全部返回 false
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('true'/0)); // true
console.log(Number.isNaN(111)); // false
/**
* Number.parseInt(string[, radix])
* string:要解析的值。 如果此参数不是字符串,则使用ToString抽象操作将其转换为字符串。忽略此参数中的前导空格。
* radix:一个介于2到36之间的整数,代表字符串的基数(数学数字系统中的基)。小心-这并不是默认为10。
*/
Number.parseInt('12.34'); // 12
Number.parseInt(12.34); // 12
Number.parseInt('0011', 2); // 3
// 与全局的 parseInt() 函数是同一个函数
Number.parseInt === parseInt; // true
/**
* Number.parseFloat()
* 用于把一个字符串解析成浮点数, 整数和浮点数采用的是同样的储存方法,因此 1 与 1.0 被视为相同的值
*/
Number.isInteger(1); // true
Number.isInteger(1.0); // true
Number.isInteger(1.1); // false
Number.isInteger(Math.PI); // false
Number.isInteger:数值的精度超过 53 个二进制位时,由于第 54 位及后面的位被丢弃,会产生误判
Number.isInteger(1.0000000000000001) // true
// 一个数值的绝对值小于 Number.MIN_VALUE(5E-324),即小于 JavaScript 能够分辨的最小值,会被自动转为 0,也会产生误判
Number.isInteger(5E-324); // false
Number.isInteger(5E-325); // true
/**
* Number.isSafeInteger()
* 用于判断数值是否在安全范围内
*/
Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1); // false
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1); // false
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324
// 除数
console.log(10/0); //Infinity
console.log(10/0.0); //Infinity
ES6语法
Use 0b prefix for binary, and 0o prefix for octal integer literals
Number.isNaN(): Number.isFinite():
Number.parseInt(): Number.parseFloat(): Number.isInteger(): Number.isSafeInteger():
常量
Number.EPSILON:表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。
Number.MAX_SAFE_INTEGER:最大的安全整数 (2^53 - 1) Number.MIN_SAFE_INTEGER:最小的安全整数 (-(2^53 - 1)) Number.MAX_VALUE:能表示的最大正数,MAX_VALUE 属性值接近于 1.7976931348623157e+308。大于 MAX_VALUE 的值代表 "Infinity"。 -Infinity > Number.MAX_VALUE Number.MIN_VALUE:能表示的最小正数即最接近 0 的正数 (实际上不会变成 0),即5e-324,小于 MIN_VALUE 的值代表 "-Infinity"。-Infinity < Number.MIN_VALUE Number.NaN:特殊的“非数字”值。 Number.NEGATIVE_INFINITY:特殊的负无穷大值,在溢出时返回该值。 Number.POSITIVE_INFINITY:特殊的正无穷大值,在溢出时返回该值。
浮点计算与精度误差
误差原理
JavaScript的数字都遵循IEEE 754标准构建,在内部都是64位浮点小数表示
解决方案
- https://www.runoob.com/w3cnote/js-precision-problem-and-solution.html
Number.EPSILON 属性:表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。 Number.EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16,或者 2-52。
JavaScript的数字都遵循IEEE 754标准构建,在内部都是64位浮点小数表示
JavaScript中的数字是如何编码的: https://2ality.com/2012/04/number-encoding.html toFixed()和toPrecision()
0.1 + 0.2 === 0.3 // is false 因为0.1+0.2等于0.30000000000000004
9007199254740992 + 1 // is equal to 9007199254740992
9007199254740992 + 2 // is equal to 9007199254740994
Number类型最大限制:16位
最大值:9007199254740992,超过之后会发生失真
console.log(9007199254740990); //9007199254740990
console.log(9007199254740991); //9007199254740991
console.log(9007199254740992); //9007199254740992
console.log(9007199254740993); //9007199254740992
console.log(9007199254740992 + 1); //9007199254740992
console.log(9007199254740992 + 2); //9007199254740994
console.log(9007199254740992 + 3); //9007199254740996
console.log(9007199254740992 + 4); //9007199254740996
console.log(9007199254740992 + 5); //9007199254740996
console.log(9007199254740992 + 6); //9007199254740998
console.log(9007199254740992 + 7); //9007199254741000
console.log(9007199254740992 + 8); //9007199254741000
console.log(9007199254740992 + 9); //9007199254741000
console.log(9007199254740992 + 10); //9007199254741002
解决方案
将数字转换为字符串处理
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(parseInt(0.000006)); // 0
console.log(parseInt(0.000001)); // 0
console.log(parseInt(0.0000001)); // 1
console.log(parseInt(0.0000008)); // 8
代码示例
console.log(999999999999999); //999999999999999
console.log(9999999999999999); //10000000000000000
console.log(1000000000000001); //1000000000000001
解决方案
toFixed()和toPrecision() node-bignum
输入框,限制整数位、小数位
function inputLimitIntegerDecimal(integerLength, decimalLength) {
const regExp = new RegExp(`^\\D*(\\d{${integerLength}}(?:\\.\\d{0,${decimalLength}})?).*$`, 'g')
}