ES6-数值的扩展-安全整数和 Number.isSafeInteger()

来源:互联网 发布:错生网络剧未删减资源 编辑:程序博客网 时间:2024/06/09 21:36

JavaScript 能够准确表示的整数范围在 -2^53 到 2^53之间(不含两个端点),超过这个范围,无法精确表示这个值。

Math.pow(2, 53) // 90071992547409929007199254740992  // 90071992547409929007199254740993  // 9007199254740992Math.pow(2, 53) === Math.pow(2, 53) + 1// true
上面代码中超出2的53次方之后,这个数就精确了。

ES6 引入了 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 这两个常量,用来表示这个范围的上下限。

Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1// trueNumber.MAX_SAFE_INTEGER === 9007199254740991// trueNumber.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER// trueNumber.MIN_SAFE_INTEGER === -9007199254740991// true
上面代码中,可以看到 JavaScript 能够精确表示的极限。

Number.isSafeInteger() 则是用来判断一个整数是否落在这个范围之内。

Number.isSafeInteger('a') // falseNumber.isSafeInteger(null) // falseNumber.isSafeInteger(NaN) // falseNumber.isSafeInteger(Infinity) // falseNumber.isSafeInteger(-Infinity) // falseNumber.isSafeInteger(3) // trueNumber.isSafeInteger(1.2) // falseNumber.isSafeInteger(9007199254740990) // trueNumber.isSafeInteger(9007199254740992) // falseNumber.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // falseNumber.isSafeInteger(Number.MIN_SAFE_INTEGER) // trueNumber.isSafeInteger(Number.MAX_SAFE_INTEGER) // trueNumber.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false

isSafeInteger()这个函数的实现就是跟安全整数的两个边界值比较一下。

Number.isSafeInteger = function (n) {  return (typeof n === 'number' && //判断是否是一个数字类型    Math.round(n) === n && //判断是否是整数,Math.round()方法用于取整    Number.MIN_SAFE_INTEGER <= n && //判断是否大于最小整数    n <= Number.MAX_SAFE_INTEGER); //判断是否小于最大整数}
实际使用这个函数时,需要注意,验证运算结果是否落在安全整数的范围内,不要只验证运算结果,而要同时验证参与运算的每个值。

Number.isSafeInteger(9007199254740993)// falseNumber.isSafeInteger(990)// trueNumber.isSafeInteger(9007199254740993 - 990)// true9007199254740993 - 990// 返回结果 9007199254740002// 正确答案应该是 9007199254740003
上面代码中,9007199254740993不是一个安全整数,但是 Number.isSafeInteger 会返回结果,显示计算结果是安全的。这是因为,这个数超出了精度范围,导致在计算机内部,以9007199254740992的形式存储

9007199254740993 === 9007199254740992// true
所以根据上面的代码,如果只验证运算结果是否为安全整数,很可能得到错误的结果,下面的函数可以同时验证两个运算数金额运算结果。
function trusty(left,right) {var result = left + right;if (Number.isSafeInteger(left) &&Number.isSafeInteger(right) &&Number.isSafeInteger(result)) {return result;}throw new RangeError('Operation cannot be trusted!');}trusty(9007199254740990,3)  //RangeError: Operation cannot be trusted!trusty(2,3)  //5


原创粉丝点击