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

和 XOR 不 或 左/右转


当前回答

它们主要用于位操作(惊喜)。下面是在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;

其他回答

我使用它们来实现快速BCD计算(会计师和审计员会对fp舍入感到不安)。

一个常见的用法是对齐,例如我需要我的数据在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

按位&用于屏蔽/提取字节的某一部分。

1字节变量

 01110010
&00001111 Bitmask of 0x0F to find out the lower nibble
 --------
 00000010

特别是移位运算符(<< >>)经常用于计算。

下面是一些处理将标志存储为单个位的常见习惯用法。

enum CDRIndicators {
  Local = 1 << 0,
  External = 1 << 1,
  CallerIDMissing = 1 << 2,
  Chargeable = 1 << 3
};

unsigned int flags = 0;

设置Chargeable标志:

flags |= Chargeable;

清除CallerIDMissing标记:

flags &= ~CallerIDMissing;

测试CallerIDMissing和Chargeable是否设置:

if((flags & (CallerIDMissing | Chargeable )) == (CallerIDMissing | Chargeable)) {

}

它们主要用于位操作(惊喜)。下面是在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;