JavaScript 数组的长度是什么类型的积分?有环绕的危险吗?
What type of integral is a JavaScript array's length? Is there danger of wraparound?
我的意思是:
我有一个函数,我正在写
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
等于 ~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);
}
}
但后来我失去了紧凑,优雅。
j = arr.length - 1
是否构成危险?
Does j = arr.length - 1
pose a danger?
没有。所有数字在 JS 中都被视为 64 位浮点数(尽管这可能会被引擎优化,只要它们是小整数)。当您从 0
中减去 1
时,您将始终得到 -1
.
正如您询问的 arr.length
、the spec says "Every Array object has a length property whose value is always a nonnegative integer less than 232". So it internally may be stored as an unsigned 32 bit integer, and on setting .length
a value is actually casted to one,但您可以放心,该数字将适合算术运算所使用的 64 位浮点数。
length
在 the spec as an unsigned 32-bit integer 中定义。但是,任何数学运算都会将其强制转换为数字,因此您最终会得到 -1:
[].length - 1 // = -1
将负数分配给长度应该会引发错误。尝试从数组中获取负数会 return undefiend 除非你在数组上创建了一个 属性 具有该名称的名称,这是可能的,因为数组只是具有魔法的对象 属性 这比他们拥有的最大正整数 属性 大一。
a = []
a[-2] = 'something'
a[-1] //undefined
a.length //0
a[10] = 'something'
a.length //11
JavaScript 只有一种数字类型 - Number - 对应于 64 位 IEEE-754 浮点数(C++ 中的 double
类型),但只有一个 NaN 值。所以没有用 arr.length - 1
环绕的危险
数组的 "length" 属性 return 是一个数字,并且仅限于 0 ... 2^32-1 范围内的整数值。
Every Array object has a length property whose value is always a nonnegative integer less than 2^32. ECMAScript 2015
所以arr.length - 1
总是return-1或0或小于2^32-2的正整数。
(顺便说一句,2^53-1 是在 +1 之类的操作开始失去精度之前可以安全地存储在数字中的最大整数。ECMAScript 标准的各个部分都使用它作为限制,例如定义Array.prototype.push
但数组 "length" 属性 被进一步限制。)
我的意思是:
我有一个函数,我正在写
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
等于 ~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);
}
}
但后来我失去了紧凑,优雅。
j = arr.length - 1
是否构成危险?
Does
j = arr.length - 1
pose a danger?
没有。所有数字在 JS 中都被视为 64 位浮点数(尽管这可能会被引擎优化,只要它们是小整数)。当您从 0
中减去 1
时,您将始终得到 -1
.
正如您询问的 arr.length
、the spec says "Every Array object has a length property whose value is always a nonnegative integer less than 232". So it internally may be stored as an unsigned 32 bit integer, and on setting .length
a value is actually casted to one,但您可以放心,该数字将适合算术运算所使用的 64 位浮点数。
length
在 the spec as an unsigned 32-bit integer 中定义。但是,任何数学运算都会将其强制转换为数字,因此您最终会得到 -1:
[].length - 1 // = -1
将负数分配给长度应该会引发错误。尝试从数组中获取负数会 return undefiend 除非你在数组上创建了一个 属性 具有该名称的名称,这是可能的,因为数组只是具有魔法的对象 属性 这比他们拥有的最大正整数 属性 大一。
a = []
a[-2] = 'something'
a[-1] //undefined
a.length //0
a[10] = 'something'
a.length //11
JavaScript 只有一种数字类型 - Number - 对应于 64 位 IEEE-754 浮点数(C++ 中的 double
类型),但只有一个 NaN 值。所以没有用 arr.length - 1
数组的 "length" 属性 return 是一个数字,并且仅限于 0 ... 2^32-1 范围内的整数值。
Every Array object has a length property whose value is always a nonnegative integer less than 2^32. ECMAScript 2015
所以arr.length - 1
总是return-1或0或小于2^32-2的正整数。
(顺便说一句,2^53-1 是在 +1 之类的操作开始失去精度之前可以安全地存储在数字中的最大整数。ECMAScript 标准的各个部分都使用它作为限制,例如定义Array.prototype.push
但数组 "length" 属性 被进一步限制。)