我正在寻找在JavaScript中快速繁殖的方法,我发现了这个
有这个文本
Instead of multiplying, use the bit shift operation. it looks a little more complex, but once you get the hang of it, it’s pretty simple. The formula to multiply x * y is simply x << (y-1)
As a bonus, everyone else will think you’re really smart!
// multiply by 1
[1,2,3,4].forEach(function(n){ return n<<0; }) // 1,2,3,4
// multiply by 2
[1,2,3,4].forEach(function(n){ return n<<1; }) // 2,4,6,8
// multiply by 3
[1,2,3,4].forEach(function(n){ return n<<2; }) // 3,6,9,12
// etc
然而,这对我来说似乎不起作用。有谁知道什么是错的?
由于
答案 0 :(得分:7)
忽略那篇文章。它的目的是作为幽默 - 它给出的建议是故意的,也是错误的。
乘法不涉及“昂贵的对数查找表和非常幸运的猜测”,“每秒几十个猜测”。它是一种高度优化的硬件操作,任何现代CPU都可以每秒执行数亿次(或更多!)这些操作。
按位运算并不比Javascript中的乘法快。实际上,它们要慢得多 - 默认情况下,数字通常存储为双精度浮点数,因此执行按位运算需要将它们转换为整数,然后再返回。
比特移位不等同于文章所暗示的乘法。左移0和1相当于乘以1和2,模式继续<<2
和<<3
相当于乘以 4和8 ,而不是3和4。
Array.forEach
未返回值。这里使用的适当函数是Array.map
。
文章中描述的其他“Javascript hacks”更糟糕。我不打算详细介绍。
答案 1 :(得分:-1)
顺便说一句,如果您想知道它为什么不适合您,您将需要使用map
而不是forEach
,因为forEach
会忽略返回。
所以这样做:
// multiply by 1
[1,2,3,4].map(function(n){ return n<<0; }) // 1,2,3,4
// multiply by 2
[1,2,3,4].map(function(n){ return n<<1; }) // 2,4,6,8
// multiply by 4
[1,2,3,4].map(function(n){ return n<<2; }) // 4,8,12,16
// multiply by 8
[1,2,3,4].map(function(n){ return n<<3; }) // 8, 16, 24, 32
正如其他人所提到的那样 - 不要将它用于乘法。只需将此作为forEach vs map的清晰度......
答案 2 :(得分:-1)
位移与乘以任意数字不同。这就是位移如何工作的例如:
1234 >> 0 = 1234
1234 >> 1 = 0123 #discards the last digit.
0123 >> 2 = 0001 #discards the last two digit
因此,在十进制中,向右移动的数字就像整数除以10.当移位两位数时,它与除以10 ^ 2相同。
现在计算机使用二进制字。因此,我们有点位移,而不是数字移位。
10101011 >> 1 = 01010101
这基本上除以2 ^ 1.
10101011 >> n
只是除以2 ^ n。
现在以同样的方式,
10101011 << n
乘以2 ^ n。这会在二进制字后面添加n个零。
希望现在更清楚:)
干杯