除了快速数学之外,有没有什么好理由使用位移?

时间:2010-09-11 22:53:30

标签: bit-manipulation bit-shift

我理解按位操作以及它们如何用于不同目的,例如:权限。但是,我似乎不明白比特移位运算符的用途。我理解他们是如何工作的,但我想不出任何我可能想要使用它们的场景,除非我想做一些非常快速的乘法或除法。有没有其他理由使用位移?

4 个答案:

答案 0 :(得分:11)

有很多原因,这里有一些:

  1. 假设您将黑白图像表示为一系列位,并且您希望在此图像中一般设置一个像素。例如,您的字节偏移可以是x>> 3,并且您的位偏移可以是x& 0x7,您可以通过以下方式设置该位:byte = byte | (1<(x& 0x7));
  2. 实现数据压缩算法,其中处理可变长度比特序列,例如霍夫曼编码。
  3. 您正在与某些硬件进行交互,例如一个串行通信设备,你需要读取或设置一些控制位。
  4. 由于这些和其他原因,大多数处理器具有位移和/或旋转指令以及其他逻辑指令(和/或/ xor / not)。

    历史上,乘法和除法明显变慢,因为它们是更复杂的操作,而某些CPU根本没有这些。

    另见: Have you ever had to use bit shifting in real projects?

答案 1 :(得分:6)

正如您所指出的,左移与乘以2相同。至少在我们谈论无符号数量的时候。签名数量的“左移”的含义是......语言相关的。

使用现代编译器,写“i = x * 2”之间真的没什么区别和“i = x <&lt; 1;”编译器将生成最有效的代码。所以从这个意义上讲,没有理由倾向于转换乘法。

有些算法通过将数量左移一位然后将低位设置为0或1来工作。一些简单的压缩算法就是这样工作的。例如,如果您的累计值在变量x中,并且当前值(0或1)在y中,那么写“x =(x <&lt; 1)| y”更有意义,而不是“x =(x * 2)+ y”。两者都做同样的事情,但第一个更符合符号正确。你不必想,“哦,对,乘以2与左移相同。”

另外,当你谈到移位的算法时,向左或向右移动特定数量的位比向你想要乘以或除以2的倍数更方便。

所以,虽然转换而不是乘法通常没有性能上的好处 - 至少在使用高级语言时却没有 - 有时候有能力转移使你正在做的事情更容易被理解。

答案 2 :(得分:4)

在数值计算中,有很多地方经常使用位移操作。例如,Bitboard是一种数据结构,通常用于棋盘游戏中以用于棋盘表示。一些最强大的国际象棋引擎使用这种数据结构主要是为了移动生成和评估的速度和易用性。这些程序大量使用位操作,并且特别是在许多上下文中使用位移操作 - 例如查找位掩码,在板上生成新的移动,非常快速地计算对数等。甚至可以使用非常先进的数值计算通过巧妙地使用位操作来优雅地完成。查看this site有关小巧的黑客攻击 - 很多算法都使用移位运算符。位移操作通常用于器件驱动程序编程,编解码器开发,嵌入式系统编程等。

答案 3 :(得分:1)

移位允许访问变量中的特定位。表达式(n >> p) & ((1 << m) - 1)检索变量m的{​​{1}}位部分,右侧偏移量为n位。

这允许程序使用不是8位倍数的整数,这对数据压缩非常有用。

例如,我在Netflix Prize程序中使用它将记录(22位用户ID + 15位电影ID + 12位日期+ 3位评级)打包到p (有12位备用)。

一个非常常见的特殊情况是将8 uint64_t个变量打包到每个字节中。 (Unix文件权限,黑白位图,CPU flags registers等)

此外,位操作用于UTF-8,这是一种非常流行的字符编码。 Unicode字符通过将它们的位分布在1,2,3或4个字节来表示。