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

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

 

Math.pow(2, 53) // 9007199254740992

9007199254740992  // 9007199254740992
9007199254740993  // 9007199254740992

Math.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
// true
Number.MAX_SAFE_INTEGER === 9007199254740991
// true

Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER
// true
Number.MIN_SAFE_INTEGER === -9007199254740991
// true

上面代码中,可以看到 JavaScript 能够精确表示的极限。

 

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

 

Number.isSafeInteger('a') // false
Number.isSafeInteger(null) // false
Number.isSafeInteger(NaN) // false
Number.isSafeInteger(Infinity) // false
Number.isSafeInteger(-Infinity) // false

Number.isSafeInteger(3) // true
Number.isSafeInteger(1.2) // false
Number.isSafeInteger(9007199254740990) // true
Number.isSafeInteger(9007199254740992) // false

Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false
Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
Number.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)
// false
Number.isSafeInteger(990)
// true
Number.isSafeInteger(9007199254740993 - 990)
// true
9007199254740993 - 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

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值