26

我们知道Java 不处理下溢和上溢,但是 Javascript 是如何处理整数的呢?

它会回到最小值/最大值吗?如果是,哪个最小值/最大值?

我需要拆分一个字符串并根据其字符计算一个哈希值。

4

3 回答 3

33

在一个简单的测试中,当我尝试这个时:

var max = Number.MAX_VALUE;
var x = max + 10;

var min = Number.MIN_VALUE;
var y = min / 10;

我发现它x具有max相同的值(在 Chrome、IE 和 Firefox 中),所以看起来一些溢出只是与最大值挂钩。而且,y被挂钩,0所以一些下溢似乎归零。

啊,但事情没那么简单。并非所有上溢都转到Number.MAX_VALUE,也不是所有下溢都转到Number.MIN_VALUE。如果你这样做:

var max = Number.MAX_VALUE;
var z = max * 2;

那么,zInfinity

事实证明,这取决于您上溢/下溢的程度。如果你走得太远,你会得到 INFINITY。这是因为使用了 IEEE 754 舍入到最近的模式,其中最大值可以被认为比无穷大更接近。有关详细信息,请参阅添加到 Number.MAX_VALUE。根据该答案, 1.7976931348623158 × 10 308或更大的值四舍五入到无穷大。Number.MAX_VALUE 之间的值将四舍五入为 Number.MAX_VALUE。

为了让事情变得更加复杂,还有一些 Javascript 支持的逐渐下溢。这是浮点值的尾数有前导零的地方。逐渐下溢允许浮点表示一些较小的数字,没有它就无法表示,但它们以降低的精度表示。

您可以确切地看到限制在哪里:

>>> Number.MAX_VALUE + 9.979201e291
1.7976931348623157e+308
>>> Number.MAX_VALUE + 9.979202e291
Infinity

这是一个可运行的代码段,您可以在任何浏览器中尝试:

var max = Number.MAX_VALUE;
var x = max + 10;

var min = Number.MIN_VALUE;
var y = min / 10;

var z = max * 2;

document.getElementById("max").innerHTML = max;
document.getElementById("max10").innerHTML = x;
document.getElementById("min").innerHTML = min;
document.getElementById("min10").innerHTML = y;
document.getElementById("times2").innerHTML = z;
body {
    font-family: "Courier New"; 
    white-space:nowrap;
}
Number.MAX_VALUE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= <span id="max"></span><br>
Number.MAX_VALUE + 10 = <span id="max10"></span><br>
<br>
Number.MIN_VALUE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= <span id="min"></span><br>
Number.MIN_VALUE / 10 = <span id="min10"></span><br>  
<br>
Number.MAX_VALUE * 2 &nbsp;= <span id="times2"></span><br>

于 2013-09-27T15:51:37.187 回答
4

最大值和最小值为+/- 9007199254740992

试试这些数字类型属性

alert([Number.MAX_VALUE, Number.MIN_VALUE]);

来自 ECMAScript 2020 语言规范的“数字类型”部分:

请注意,所有大小不大于 2 53的正负数学整数都可以用 Number 类型表示(实际上,数学整数 0 有两种表示形式,+0 和 -0)。

测试:

var x = 9007199254740992;
var y = -x;
x == x + 1; // true !
y == y - 1; // also true !
于 2013-09-27T15:46:20.527 回答
0

Number

在 JavaScript 中,数字类型是 64 位 IEEE 754 浮点数,它不是整数。所以它不遵循其他语言中常见的整数溢出/下溢行为模式。

作为浮点数,基数部分使用 53 位。它可以表示范围Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER(-2 53 +1 到 2 53 -1) 的数字,而不会出现浮点错误。对于超出此范围的数字,它可能会四舍五入到最接近的可用数字,或者如果它太大,则可能是无穷大。

位运算符

按位运算符处理操作数 32 位整数。常见的整数溢出可能与其他语言一样发生。计算后只能保留最后 32 位。例如,3<<31将结果-2147483648

>>>将操作数视为无符号 32 位整数。所有其他运算符将操作数视为带符号的 32 位整数。如果你想将有符号整数转换为无符号整数,你可以写value >>> 0来解决这个问题。要转换回来,请使用value | 0.

如果你想用 33 移动一个整数,它实际上会被移动 1。

BigInt

就像 Java 一样java.math.BigIntegerBigInt支持无界整数(但仍受内存限制)。所以这里可能永远不会发生整数溢出。

类型数组

对于 TypedArray 类型,当分配的整数超出支持范围时,它会被截断,就像其他语言在转换整数时所做的那样,通过保留最低有效位。例如new Int8Array([1000])[0]得到-24.

asm.js

此处适用于按位运算符的相同规则。该值将作为什么| 0>>> 0做什么被运回。

于 2021-03-10T03:41:41.620 回答