整数溢出到负数

Integer overflow to negative number

本文关键字:溢出 整数      更新时间:2023-09-26

根据这个链接,我了解到在IE8中,如果数组的索引大于2147483647,则新元素的索引将为负数。

这是一个例子:

function test() { 
    var arr = new Array();         
    arr[2147483650] = 10000; 
    arr.push(10);     
    document.write(arr["-2147483645"] == 10); 
} 
test();

我不明白的是,数组中新添加的元素怎么会有-2147483645的索引,我理解负数部分,我只是不知道如何知道新索引是2147483645,而不是-2147483644-2147483651。。。

当用32位表示一个数字时,最高的位用作符号位,所以当用二进制表示2147483647这样的数字时,它是

01111...111

其中有31个1。当我们再加一个,我们得到

10000...000

其中有31个0。因此,我们已经将符号位跳变为一个表示负数的符号位。然而,由于需要避免两次表示0,我们将数字包装起来,因此它不是表示-0,而是表示负2147483648(不是2147483647,因为正侧需要表示0,但由于负侧不需要,我们得到一个"额外"的负数)。

每次我们加一个,它就会增加二进制表示,通过负数倒数

1000...00 = -2147483648 // this is 2147483648
1000...01 = -2147483647 // this is 2147483649
1000...10 = -2147483646 // this is 2147483650

依此类推。因此,2147483650被包装为-2147483646,因此,多出一个被设置为-214743645。

请参阅此处了解更多详细信息。

在您的示例中,我想指出-2147483645的索引是而不是创建的,相反,您的数组被转换为对象:

function test() { 
    var arr = new Array();         
    arr[2147483650] = 10000; 
    arr.push(10);     
    console.log(arr["-2147483645"] == 10); 
    console.log(arr)
} 
test();
// false
// [2147483650: 10000, 2147483651: 10]

我不明白的是,为什么数组中新添加的元素的索引为-2147483645

需要注意的是,JavaScript中的所有内容都是一个隐藏的对象。话虽如此,即使是Array实际上也只是一个对象。在这种情况下,您的数组实际上并没有-2147483645索引,事实上,实际上并没有发生整数溢出相反,溢出的整数会转换为字符串,并成为映射到数组对象中某个值的键

var arr = [];
arr[2147483650] = 'foo';
// The index is really just converted to a string behind the scenes
console.log(arr[2147483650] === arr["2147483650"]);
// true

如果您试图用超出范围的整数对数组进行索引,则会认为您正在创建一个对象并创建一个目标,而不是对数组进行索引号。

var arr = [];
arr[0] = 'foo';
console.log(arr);
// ["foo"]
// Has the array notation
var arr = [];
arr[2147483650] = 'bar';
console.log(arr);
// [2147483650: "bar"]
// Notice the object notation?