我正试图写一个测试来检查两个任意整数的和是否> 9007199254740992或<-9007199254740992。当这种情况发生时,js是否始终以可测试的方式运行?
根据MDN, JavaScript使用IEEE 754中指定的双精度浮点格式数字。
因此实际安全边界为max == Math.pow(2,53)-1
和min == -(Math.pow(2, 53)-1)
。这些被封装在ECMAScript 6 Number
类常量中:
Number.MAX_SAFE_INTEGER; // == 9007199254740991
Number.MIN_SAFE_INTEGER; // == -9007199254740991
考虑到这些限制,这里有一个函数应该满足您的要求,以显示在添加时何时可以溢出或下溢:
function additionWillOverflow(x,y) {
if( y > 0 ) {
return x > Number.MAX_SAFE_INTEGER - y;
}
return x < Number.MIN_SAFE_INTEGER - y;
}
这里有两个说明性的测试用例:
var x = 9007199254740990;
var y = 3;
console.log( additionWillOverflow(x,y) ); // true
console.log( x + y ); // 9007199254740992(!) - overflow
x = -9007199254740990;
y = -3;
console.log( additionWillOverflow(x,y) ); // true
console.log( x + y ); // -9007199254740992(!) - underflow
由于上面提到的浮点表示,从2^53开始,javascript只能表示每秒钟整数。From 2^54 js只能表示每四个整数,以此类推。这种行为在任何兼容的实现中都应该是一致的(还没有全部测试过),并且是浮点数的工作方式(查看维基百科了解更多信息)。
注意,对于任何数值,调用isNan(x+y)
或isFinite(x+y)
分别返回false
和true
,即使它们在MAX_SAFE_INTEGER范围之外(即使调用错误的数字结果)。
希望对你有帮助。