2017-07-28 58 views
0

在以下代码中,i将始终为偶数,因此商i/2应始终为整数。我是否还应该使用Math.floor(i/2)来保证安全?我在问,因为JavaScript不会将所有数字视为浮点数,所以我担心舍入误差。通过商标对数组索引

for (var i = 0; i < data.length; i = i + 2) { 
    var name = names[i/2]; 
    ... 
} 

回答

0

按照JavaScript(ECMAScript®) Language Specification如果

i <= Number.MAX_SAFE_INTEGER + 1 

然后i可以确切地表示,分工应该很好。

Number.MAX_SAFE_INTEGER的值是最大的整数n,使得n和n + 1都可以精确地表示为数值。

Number.MAX_SAFE_INTEGER的值是9007199254740991(2 -1)。

Section 12.7.3.2 Applying the/Operator

在其余的情况下,如果既没有无穷大,也不是零,也不NaN被涉及,则商被计算并舍入到使用IEEE 754-2008最接近的可表示值圆到最近,与均匀模式相关。如果幅度太大而无法表示,则操作溢出;那么结果就是无限的适当符号。如果幅度太小而无法表示,则操作下溢,结果为适当符号的零。ECMAScript语言要求支持IEEE 754-2008定义的逐渐下溢。

3

不,您不必在这种情况下使用Math.floor()

因为i总是偶数,names[1.00]也等于names[1]

要检查,请尝试下面的JavaScript控制台。

数组的长度将是20和第一10数组项将被打印

var names = ["nums1", "nums2", "nums3","nums4", "nums5", "nums6","nums7", 
 
    "nums8", "nums9","nums10", "nums11","nums12", "nums13","nums14", "nums15", 
 
    "nums16","nums17", "nums18", "nums19","nums20"]; 
 

 
for (var i = 0; i < names.length; i = i + 2) { 
 
    console.log(names[i/2]); 
 
}

+0

据我所知,它工作在这个特殊的例子,但你怎么知道有没有一些平台,让'我/ 2'将返回'1.00000002'并给出一个错误,如果我试图通过索引呢? – Roland

+0

如果我从零开始,每次迭代增加2,我不明白为什么i/2会返回除了整数之外的任何值。你能说出任何你知道的平台的例子吗? –

2

除以甚至由2的整数,只要它不会溢出

总是返回一个整数
Number.MAX_SAFE_INTEGER 

之后,整数存储为2的幂,所以它们失去精度。
然而,大于这个大小的数组在访问它们的元素时会遇到问题(因为索引得到不精确),所以可以插入数组的元素的最大数目仅限于这个最大安全整数。所以基本上你的代码总是能工作,如果不行的话,那是因为数组溢出而不是因为索引错误。不过,我比较推荐你做:

var array = ["one", "two", "three","four", "five", "six","seven", 
 
    "eight", "nine","ten", "eleven","twelve", "thirteen","fourteen", "fifteen", 
 
    "sixteen","seventeen", "eighteen", "nineteen","twenty"]; 
 
    
 
    for(var i=0,l=array.length/2;i<l;i++){ 
 
     console.log(array[i]); 
 
    }

因为它节省了这些不必要的数学运算......

+0

@anvita感谢您添加一个片段;) –

+0

您能否提供一个链接到证明您的声明的文档?谢谢 – Roland

+1

@roland *在余下的情况下,无论是无穷大,也不是零,也不涉及NaN,使用IEEE 754-2008圆到最近模式计算商并四舍五入到最接近的可表示值。如果幅度太大而无法表示,则操作溢出;那么结果就是无限的适当符号。如果幅度太小而无法表示,则操作下溢,结果为适当符号的零。 ECMAScript语言要求支持IEEE 754-2008定义的逐渐下溢* –