eme*_*gro 10 c c++ bit-manipulation objective-c
int aNumber;
aNumber = aValue / 2;
aNumber = aValue >> 1;
aNumber = aValue * 2;
aNumber = aValue << 1;
aNumber = aValue / 4;
aNumber = aValue >> 2;
aNumber = aValue * 8;
aNumber = aValue << 3;
// etc.
Run Code Online (Sandbox Code Playgroud)
什么是"最佳"的运营方式?何时更好地使用位移?
fma*_*ark 18
aValue * 8 == aValue << 3如果你使用正整数,那么这两个在你给出的例子中是功能相同的(除了最后一个,应该读取).这是乘以或由2的幂除当仅如此.
位移从不比算术慢.根据您的编译器,算术版本可能会被编译为位移版本,在这种情况下,它们都是有效的.否则,位移应该比算术快得多.
但是,算术版本通常更具可读性.因此,我几乎在所有情况下都使用算术版本,并且只有在分析显示该语句处于瓶颈时才使用位移:
程序应该编写供人们阅读,并且只是偶然为机器执行.
不同之处在于算术运算已经明确定义了结果(除非它们遇到有符号溢出).在许多情况下,班次操作没有定义结果.它们在C和C++中明确定义为无符号类型,但对于带符号类型,事情很快变得棘手.
在C++语言中,<<没有定义带符号类型的左移的算术意义.它只是移位,在右边填充零.算术意义上的含义取决于平台使用的签名表示.对于右移>>操作员来说几乎也是如此.右移负值导致实现定义的结果.
在C语言中,事物的定义略有不同.左移负值是不可能的:它会导致不确定的行为.右移负值导致实现定义的结果.
在大多数实际实现中,每个单个右移执行除以2,向负无穷大舍入.这个BTW明显不同于/2 的算术除法,因为通常(并且总是在C99中)它将向0舍入.
至于何时应该使用位移...位移位用于对位进行操作的操作.位移运算符很少用作算术运算符的替代(例如,你不应该使用移位来执行乘法/除法的常数).
位移位是一种“接近金属”的操作,大多数时候不包含任何有关您真正想要实现的目标的信息。
如果你想将一个数字除以二,请务必写成x/2。它恰好是由 实现的x >> 1,但后者隐藏了意图。
当这成为瓶颈时,修改代码。