下面的位运算符在现实世界中有哪些用例?

和 XOR 不 或 左/右转


当前回答

一个常见的用法是对齐,例如我需要我的数据在4字节或16字节的边界上对齐。这在RISC处理器中非常常见,其中未对齐的加载/存储要么代价高昂(因为它触发了一个异常处理程序,然后需要修复未对齐的加载),要么根本不允许。

对于任何以2为幂的对齐,下一个对齐的pos可以计算如下:

aligned_offset = alignment + ((current_offset - 1) & ~(alignment - 1))

所以在4字节对齐和当前偏移量为9的情况下:

aligned_offset = 4 + ((9-1) & ~(4-1)) = 4 + (8 & 0xFFFFFFFC) = 4+ 8  = 12  

所以下一个4字节的对齐偏移量是12

其他回答

我将它们用于多选择选项,这样我只存储一个值,而不是10个或更多

通常位运算比乘除运算快。所以如果你需要用一个变量x乘以9,你会用x<<3 + x这将比x*9快几个周期。如果此代码位于ISR中,则可以节省响应时间。

类似地,如果您想使用数组作为循环队列,那么使用逐位操作来处理环绕检查会更快(也更优雅)。(你的数组大小应该是2的幂)。例如:,你可以使用tail = ((tail & MASK) +1)而不是tail = ((tail +1) < size) ?尾+1:0,如果你想插入/删除。

另外,如果您想要一个错误标志将多个错误代码保存在一起,则每个位可以保存一个单独的值。您可以与它与每个单独的错误代码作为检查。这用于Unix错误代码。

此外,n位位图可以是一个非常酷而紧凑的数据结构。如果要分配一个大小为n的资源池,我们可以使用n位表示当前状态。

我们使用位标记,使会话较小的登录权限在我们的内部网站。

它们主要用于位操作(惊喜)。下面是在PHP代码库中找到的一些实际示例。

字符编码:

if (s <= 0 && (c & ~MBFL_WCSPLANE_MASK) == MBFL_WCSPLANE_KOI8R) {

数据结构:

ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;

数据库驱动程序:

dbh->transaction_flags &= ~(PDO_TRANS_ACCESS_MODE^PDO_TRANS_READONLY);

编译器实现:

opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE;

低级编程就是一个很好的例子。例如,你可能需要写一个特定的位到内存映射寄存器,以使某些硬件做你想要它做的事情:

volatile uint32_t *register = (volatile uint32_t *)0x87000000;
uint32_t          value;
uint32_t          set_bit   = 0x00010000;
uint32_t          clear_bit = 0x00001000;

value = *register;            // get current value from the register
value = value & ~clear_bit;   // clear a bit
value = value | set_bit;      // set a bit
*register = value;            // write it back to the register

同样,htonl()和htons()是使用&和|操作符实现的(在字节顺序不匹配网络顺序的机器上):

#define htons(a) ((((a) & 0xff00) >> 8) | \
                  (((a) & 0x00ff) << 8))

#define htonl(a) ((((a) & 0xff000000) >> 24) | \
                  (((a) & 0x00ff0000) >>  8) | \
                  (((a) & 0x0000ff00) <<  8) | \
                  (((a) & 0x000000ff) << 24))