什么类型的积分是JavaScript数组的长度?环绕的危险吗?

时间:2015-10-28 18:38:45

标签: javascript arrays integer-overflow

这就是我的意思:

我有一个像

那样写作的功能
function unstable_partition ( arr, piv ) 
{
   // puts all values less than piv on the left of arr and 
   // all values greater than or equal to piv on the right side
   var i = 0, j = arr.length - 1;
   while (i < j)
   {
      if (arr[i] <= piv) ++i;
      else if (arr[j] >= piv) --j;
      else swap(arr,i,j);
   }
}

我想知道

是否有任何危险
j = arr.length - 1

一部分。我知道在C ++中,作为示例,保持数组大小的整数类型size_t是无符号的,因此如果该值为0,则0 - 1等于{{ 1}}(最大~0)会导致此特定函数出错。

现在,我知道如果我这样做,我甚至不必担心这个问题

size_t
然而,我失去了紧凑,优雅。

function unstable_partition ( arr, piv ) { // puts all values less than piv on the left of arr and // all values greater than or equal to piv on the right side var len = arr.length; if (len === 0) return; var i = 0, j = len - 1; while (i < j) { if (arr[i] <= piv) ++i; else if (arr[j] >= piv) --j; else swap(arr,i,j); } } 是否构成危险?

3 个答案:

答案 0 :(得分:4)

lengththe spec中定义为unsigned 32-bit integer。但是,任何数学运算都会将其强制转换为数字,因此最终会得到-1:

[].length - 1 // = -1

为长度指定负数应该会产生错误。尝试从数组中获取负数将返回undefiend,除非您在数组上创建了具有该名称的属性,这是可能的,因为数组只是具有魔术属性的对象,该属性比它们具有的最大正整数属性大一个

a = []
a[-2] = 'something'
a[-1] //undefined
a.length //0
a[10] = 'something'
a.length //11

答案 1 :(得分:3)

  

j = arr.length - 1会造成危险吗?

没有。所有数字在JS中都被视为64位浮点数(尽管只要它们是小整数,这可能会被引擎优化)。当您从1中减去0时,您将始终获得-1

当您询问arr.lengththe spec says&#34; 每个Array对象都有一个length属性,其值始终是小于2 32 &#34 ;.因此它在内部可以存储为无符号的32位整数,并且在setting .length上实际上是casted to one的值,但是您可以放心,该数字将适合64位浮点运算

答案 2 :(得分:1)

JavaScript只有一种数字类型 - 数字 - 对应于64位IEEE-754浮点数(C ++中的double类型),但只有一个NaN值。所以arr.length - 1

没有环绕的危险

阵列&#34;长度&#34; property返回一个Number,并且限制为0 ... 2 ^ 32-1。

范围内的整数值
  

每个Array对象都有一个length属性,其值始终是小于2 ^ 32的非负整数。 ECMAScript 2015

因此arr.length - 1将始终返回-1或0或小于2 ^ 32-2的正整数。

(顺便说一下,2 ^ 53-1是你可以安全地存储在一个数字中的最大整数,比如+1开始失去精度之类的操作.ECMAScript标准的各个部分使用它作为限制,例如{的定义{1}}但Array&#34; length&#34;属性受到进一步限制。)