在以下代码中,i
将始终为偶数,因此商i/2
应始终为整数。我是否还应该使用Math.floor(i/2)
来保证安全?我在问,因为JavaScript不会将所有数字视为浮点数,所以我担心舍入误差。通过商标对数组索引
for (var i = 0; i < data.length; i = i + 2) {
var name = names[i/2];
...
}
在以下代码中,i
将始终为偶数,因此商i/2
应始终为整数。我是否还应该使用Math.floor(i/2)
来保证安全?我在问,因为JavaScript不会将所有数字视为浮点数,所以我担心舍入误差。通过商标对数组索引
for (var i = 0; i < data.length; i = i + 2) {
var name = names[i/2];
...
}
按照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定义的逐渐下溢。
不,您不必在这种情况下使用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]);
}
除以甚至由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]);
}
因为它节省了这些不必要的数学运算......
@anvita感谢您添加一个片段;) –
您能否提供一个链接到证明您的声明的文档?谢谢 – Roland
@roland *在余下的情况下,无论是无穷大,也不是零,也不涉及NaN,使用IEEE 754-2008圆到最近模式计算商并四舍五入到最接近的可表示值。如果幅度太大而无法表示,则操作溢出;那么结果就是无限的适当符号。如果幅度太小而无法表示,则操作下溢,结果为适当符号的零。 ECMAScript语言要求支持IEEE 754-2008定义的逐渐下溢* –
据我所知,它工作在这个特殊的例子,但你怎么知道有没有一些平台,让'我/ 2'将返回'1.00000002'并给出一个错误,如果我试图通过索引呢? – Roland
如果我从零开始,每次迭代增加2,我不明白为什么i/2会返回除了整数之外的任何值。你能说出任何你知道的平台的例子吗? –