我在代码中遇到了以下几行
unsigned char A = 0xB9;
unsigned char B = 0x91;
unsigned char C = A << 3; // shift bits in A three bits to the left.
unsigned char D = B >> 2; // shift bits in B two bits to the right.
我知道它是移位的,但我不知道它的用途是什么,什么时候应该使用它?
主要用途是当您根据特定位定义较大项目的某些部分时。
举一个明显的例子,考虑一个 32 位的数字,其中包含一种颜色——红色、绿色和蓝色各 8 位,(可能)其他 8 位用于 alpha(表示该颜色/像素应该有多透明)。在十六进制中,数字看起来像:
AARRGGBB
(即,每个组件的两位数或 8 位)。
我们可以把这样的东西分解成类似的组件:
red = color & 0xff;
green = (color >> 8) & 0xff;
blue = (color >> 16> & 0xff;
alpha = (color >> 24) & 0xff;
相反,我们可以将组件放在一起:
color = (alpha << 24) | (blue << 16) | (green << 8) | red;
在处理硬件时,您通常也会像这样进行位旋转。例如,您可能有一个 16 位寄存器,其中 5 位专用于一个事物,另外 2 个位专用于其他事物,6 位专用于第三个,等等。当/如果您想更改其中之一时,您可以像上面的颜色示例一样:隔离代表一个字段的位,根据需要进行修改,然后将它们与其他位重新组合在一起。
另一个(完全不相关的)应用程序是散列等。在这里,我们通常没有这样的字段,但我们希望一些输入字节产生单个输出,输出的所有位至少在某种程度上受到输入字节的影响。为了实现这一点,大多数最终都会移位位,因此输入的每个字节至少有一些机会影响结果的不同部分。
我要补充一点,尽管相当多的旧代码使用位移来优化乘法或除以 2 的幂,但对于现代硬件和编译器来说,这通常是浪费时间。您将在现有代码中看到它,并且应该理解它试图完成的任务——但不要试图模仿它的示例。
一个示例是(单色)位图,其中每个像素由一个位表示。
假设你有一个圆圈
........
...oo...
..O..O..
.O....O.
.O....O.
..O..O..
...oo...
........
其中 a.
由 0 位表示,aO
由 1 位表示,因此第二行由二进制 00011000 或十进制 24 表示。现在,如果要将圆向右移动 1 个像素,您所做的就是移动位在其表示中向右 1 位。
........
....oo..
...O..O.
..O....O
..O....O
...O..O.
....oo..
........
所以第二行现在是移位后的 00001100,(或十进制 12)。
这是否使它更清楚一点?
位移位有几个目的
一种用途是除以或乘以 2 的整数幂。
位移或位模式用于压缩文件。有些人也将其用于加密。
移位有很多用途。在这里可以解释的不仅仅是现实。一个很好的例子是在汇编代码时将值转移到正确的位置。此外,左移 1 与将值乘以 2 相同,只是要快得多。同样,右移与除以 2 相同。