算法博客之左移右移

Posted by 清水咲太 on October 5, 2024
<< >>
类型:运算符
中文名称:左移/右移运算符
原理:将二进制的数据向左/向右移动对应n位数,作用为乘以/除与对应2的n次方
一般形式:
result = a << 2; //相当于 result = a * pow(2, 2);
讲到这里,我产生了这样的疑惑:明明可以直接乘以对应数字,我何必大费周章再去新设计一个运算符呢?
对于这个问题,ChatGPT给我的解答是这样的:
1. 性能
对于某些低层次的硬件,尤其是嵌入式系统和底层编程中,移位操作比乘法运算更高效。这是因为移位操作在 CPU 中通常是一个单周期操作,而乘法运算可能需要多个时钟周期来完成。

* << 2 表示将数字的二进制位左移 2 位,这在硬件中是一个非常简单的操作,只需要移动二进制数,不涉及复杂的运算。
* 4 则需要进行一次乘法运算,通常比移位稍慢。

2. 代码简洁性和可读性
在某些场景下,移位操作可以让代码更加简洁,尤其是位操作相关的程序。在处理二进制位时,移位操作更加直观。比如:

1 << 2 直接表示将 1 左移 2 位,相当于二进制 00000001 变成 00000100,其含义清晰明了。
而 * 4 在某些情况下可能无法直观表达其意图,尤其是在与位操作相关的场景下。
例子
uint8_t flag = 1 << 3;
上面的代码直接表示 flag 的第 3 位(从 0 开始计数)为 1,这是位操作中非常常见的一种表示方式。如果用乘法来表达类似的操作,代码的意图可能会变得不那么清晰。

3. 控制特定位
移位运算符不仅仅用于简单的乘法运算,它的更大优势在于处理位运算时,可以直接操作具体的二进制位。例如,1 << 3 表示将 1 移动到第 3 位,而不仅仅是数值乘以 8。在某些场景下,移位操作的语义性更强,更适合位操作和掩码控制。

例子
如果我们想设置某个变量的第 i 位为 1,使用移位符号会非常简洁:
temp |= (1 << i); // 把第 i 位设置为 1
用乘法则无法直接做到这一点,因为乘法仅仅是数值上的变化,而不是直接对位进行操作。

总结
性能:移位操作通常比乘法快,尤其在嵌入式和低功耗系统中。
可读性:在位操作的场景下,移位更加直观,能准确表达对位的操作意图。
位操作的需要:移位不仅仅是乘法,它能够精确控制特定位,适合操作单个二进制位的场合。