位移的目的是什么
What is the purpose of bit shifting?
我在代码中遇到了以下几行
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...
........
其中.
由 0 位表示,O
由 1 位表示,因此第二行由二进制 00011000 或十进制 24 表示。现在,如果要将圆向右移动 1 个像素,您要做的是将其表示中的位向右移动 1 位。
........
....oo..
...O..O.
..O....O
..O....O
...O..O.
....oo..
........
因此,第二行现在在移位后00001100(或十进制 12)。
位移有几个用途
- 乘
- 法或除以 2 的幂
- 检查是否设置了最高或最低有效位(MSB 或 LSB),方法是在左移 [右] 后查找溢出 [或下溢]。
弱加密形式。不。
位移或位模式用于压缩文件。有些人也使用它进行加密。
一种用途是除法或乘以 2 的整数幂。
移位有很多用途。 这里可以解释得非常现实。 一个很好的例子是在组装代码时将值移动到正确的位置。 同样,左移 1 与将值乘以 2 相同,只是速度要快得多。 同样,右移与除以 2 相同。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么