2011-09-17 2014 views
3

我正在阅读underscore.js代码。我发现这个:“>> 1”是什么意思?

var mid = (low + high) >> 1; 

>> 1是做什么的?为什么它有用?

+0

作者可能认为'>> 1'会比'/ 2'效率更高。在大多数语言中,这是不正确的;例如,C编译器可能会为这两者生成相同的代码。我不知道这是否适用于JavaScript。 –

+0

@Keith:JavaScript会切换到分区的浮点值,所以使用shift可以将所有内容保存在整数区域中,而无需使用'Math.floor'。 –

回答

7

它将左侧的位向右移一位。这相当于除以2.

在'古代的时代'中,这比简单的划分要快,尽管我怀疑它会在下划线的情况下产生很大的变化。

+0

downvote的原因? –

+0

严格来说,它等于*整数除法* 2,向负无穷大舍入。 (我不是downvoter。) –

+0

严格来说,2是一个整数:),但指向 –

1

这是一个按位右移。对于整数,相当于除以二;对于JavaScript数字,它与Math.floor((low + high)/2)大致相同,但完全避免了浮点数。

+0

谢谢。更隐晦的版本比你更高效? – Randomblue

+0

@Randomblue:是的,这个转换应该更快,因为一切都应该以整数完成,并且避免了'Math.floor'函数调用。我不知道这个差异是否与体面的JavaScript实现有很大关系。 –

0

它可能在那里保持整数值。在这里除以2可能会在某些情况下将结果转换为浮点数,例如,如果(low + high)是奇数。

这两种操作并非完全等同:

> (5+2)/2 
3.5 
> (5+2)>>1 
3 

对于这个特殊的用途,不过,也有better idioms寻找两个数字的中点。

1

>>是传播右移运算符的符号。它将(low + high)的位模式右移1,最左边的位被复制到左边。它实际上与Math.floor((low + high)/2)相同。

如果我没有指出使用(low + high) >> 1来计算二进制搜索中可能导致溢出的数组中点的细微错误,那我就会失职。 (low + high) >>> 1其中>>>是零填充右移运算符,没有溢出错误。

+0

谢谢。我在哪里可以找到关于这个溢出错误的更多信息? – Randomblue

+0

https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_shift_operators是一个很好的资源。 –

+0

您可以在这里阅读http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html上的溢出错误。这是多年来JDK中的一个错误。这同样适用于JavaScript中的按位操作,因为它们具有相同的语义。 –