以下哪一种技术是整数除2的最佳选择,为什么?

技巧1:

x = x >> 1;

技巧2:

x = x / 2;

这里x是整数。


当前回答

第一个看起来像除法吗?不。如果你想除法,用x / 2。如果可能的话,编译器可以优化它使用位移位(它被称为强度减少),这使得它成为一个无用的微优化,如果你自己做它。

其他回答

哪一个是最好的选择,为什么整数除以2?

这取决于你对最佳的定义。

如果你想让你的同事讨厌你,或者让你的代码难以阅读,我肯定会选择第一个选择。

如果你想把一个数除以2,就用第二个数。

这两者是不等价的,如果数字是负的或在更大的表达式中,它们的行为是不一样的——bitshift的优先级比+或-低,除法的优先级更高。

您应该编写代码来表达其意图。如果您关心的是性能,不要担心,优化器在这类微优化方面做得很好。

使用最能描述您要做的事情的操作。

如果你将数字作为一个比特序列来处理,请使用bitshift。 如果你把它当作一个数值,使用除法。

请注意,它们并不完全相等。对于负整数,它们可以给出不同的结果。例如:

-5 / 2  = -2
-5 >> 1 = -3

(ideone)

第一个看起来像除法吗?不。如果你想除法,用x / 2。如果可能的话,编译器可以优化它使用位移位(它被称为强度减少),这使得它成为一个无用的微优化,如果你自己做它。

使用除法(/),假设这样更清楚。编译器将相应地进行优化。

x / 2更清晰,x >> 1快不了多少(根据一个微基准测试,对于Java JVM快30%左右)。正如其他人所注意到的,对于负数,舍入略有不同,所以当您想处理负数时必须考虑这一点。一些编译器可能会自动将x / 2转换为x >> 1,如果他们知道这个数字不可能是负数(即使我无法验证这一点)。

即使x / 2可能不使用(慢)除法CPU指令,因为一些捷径是可能的,但它仍然比x >> 1慢。

(This is a C / C++ question, other programming languages have more operators. For Java there is also the unsigned right shift, x >>> 1, which is again different. It allows to correctly calculate the mean (average) value of two values, so that (a + b) >>> 1 will return the mean value even for very large values of a and b. This is required for example for binary search if the array indices can get very large. There was a bug in many versions of binary search, because they used (a + b) / 2 to calculate the average. This doesn't work correctly. The correct solution is to use (a + b) >>> 1 instead.)