我正在尝试编写一个测试来检查两个任意整数之和是否为> 9007199254740992或< -9007199254740992。当这种情况发生时,js是否始终以可测试的方式运行?
答案 0 :(得分:1)
根据MDN,JavaScript使用double-precision floating-point format numbers中指定的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;
}
以下是2个说明性测试用例:
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只能表示每隔一个整数。从2 ^ 54 js只能表示每四个整数,依此类推。这种行为应该在任何兼容的实现中保持一致(并未对它们进行全部测试),并且是浮点数的工作方式(查看wikipedia for more info)。
请注意,对于任何数值,分别致电isNan(x+y)
或isFinite(x+y)
false
和true
即使它们位于MAX_SAFE_INTEGER范围(即使调用错误的数字结果)。
希望有所帮助。