整数溢出到负数

时间:2016-01-10 09:36:55

标签: javascript arrays

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

还有这个样本:

    String[] arr = {"zsdsfc", "aazjkjf", "aabdd"};

    System.out.println("Before:" + "\n");

    for (int i = 0; i < arr.length; i++ ){

        System.out.println(arr[i]);
    }

    System.out.println();

    for (int i = 0; i < arr.length; i++ ){

        for (int j = 0; j < arr.length; j++){

            if(arr[i].compareTo(arr[j]) < 0){

                String keeper = arr[i];
                arr[i] = arr[j];
                arr[j] = keeper;
            }
        }
    }

    System.out.println("After:" + "\n");

    for (int i = 0; i < arr.length; i++ ){

        System.out.println(arr[i]);
    } 

我不明白的是,为什么新添加的数组元素的索引为function test() { var arr = new Array(); arr[2147483650] = 10000; arr.push(10); document.write(arr["-2147483645"] == 10); } test(); ,我理解消极部分,我只是不知道如何知道新索引为-2147483645,而非2147483645-2147483644 ...

2 个答案:

答案 0 :(得分:4)

当以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,因此,将其设置为-2147483645。

有关详细信息,请参阅here

答案 1 :(得分:3)

在您的示例中,我想指出-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?