解释这个功能

时间:2011-09-21 21:14:09

标签: c comparison bit-manipulation bitwise-operators

有人可以向我解释为什么有人会想要使用按位比较吗? 例如:

int f(int x) {
return x & (x-1); 
}
int main(){
  printf("F(10) = %d", f(10));
}

这就是我真正想知道的:“为什么检查公共设置位”

x是任何正数。

8 个答案:

答案 0 :(得分:4)

按位操作有三个原因:

  • 您可以使用尽可能少的空间来存储信息
  • 您可以在单个CPU指令中比较/修改整个寄存器(例如,32位,64位或128位,具体取决于您的处理器),通常需要一个时钟周期。这意味着与普通算术相比,你可以做很多工作(某些类型)盲目
  • 很酷,有趣,有趣。程序员喜欢这些东西,当效率/性能方面的技术没有区别时,它们通常可以成为差异化因素。

你可以将它用于各种非常方便的东西。例如,在我的数据库中,我可以在很小的空间中存储大量关于我的客户的真/假信息(单个字节可以存储8个不同的真/假事实),然后使用'&'查询其状态的操作:

  • 我的客户是男性还是单身,还是吸烟者?

    if (customerFlags & (maleFlag | singleFlag | smokerFlag) ==
    (maleFlag | singleFlag | smokerFlag))

  • 我的客户(男性或单身或吸烟者的任何组合?)

    if (customerFlags & (maleFlag | singleFlag | smokerFlag) != 0)

  • 我的客户不是男性而不是单身而不是吸烟者吗?

    if (customerFlags & (maleFlag | singleFlag | smokerFlag) == 0)

除了“检查公共位”之外,您还可以执行以下操作:

  • 某些算术,例如value & 15相当于value % 16。这仅适用于某些数字,但如果您可以使用它,那么它可以是一个很好的优化。

  • 数据打包/拆包。例如颜色通常表示为包含Alpha,Red,Green和Blue字节值的32位整数。可以使用类似red = (value >> 16) & 255;的表达式提取红色值(将值向下移动16位位置,然后删除底部字节)

    • 数据处理和调配。使用按位运算可以实现一些巧妙的技巧。例如,交换两个整数值而无需使用第三个临时变量,或将ARGB颜色值转换为另一种格式(例如RGBA或BGRA)

答案 1 :(得分:2)

Ur示例是“测试数字是偶数还是奇数”:

unsigned int number = ...;
bool isOdd = (0 != (number & 1));

更复杂的用途包括位掩码(单个整数中的多个布尔值,每个占用一位空间)和加密/散列(通常涉及位移,异或等)。

答案 2 :(得分:1)

你给出的例子有点奇怪,但我会在嵌入式代码中一直使用按位比较。

我经常会遇到如下代码:

volatile uint32_t *flags = 0x000A000;
bool flagA = *flags & 0x1;
bool flagB = *flags & 0x2;
bool flagC = *flags & 0x4;

答案 3 :(得分:1)

这不是一个按位比较。它不返回布尔值。

按位运算符用于读取和修改数字的各个位。

n &   0x8   // Peek at bit3
n |=  0x8   // Set bit3
n &= ~0x8   // Clear bit3
n ^=  0x8   // Toggle bit3

使用位以节省空间。在char中,8个字符比8位需要更多的内存。

以下示例使用给定的子网IP地址和子网的子网掩码来获取IP子网的范围。

uint32_t mask = (((255 << 8) | 255) << 8) | 255) << 8) | 255;
uint32_t ip   = (((192 << 8) | 168) << 8) |   3) << 8) |   4;

uint32_t first = ip & mask;
uint32_t last  = ip | ~mask;

答案 4 :(得分:0)

e.g。如果你有多个状态标志以节省空间,你可能想把每个标志放一点。

所以x,如果声明为一个字节,将有8个标志。

答案 5 :(得分:0)

我认为你的意思是按位组合(在你的情况下是一个按位AND操作)。在字节,字或双字值作为位集合处理的情况下,这是一种非常常见的操作,例如状态信息,例如在SCADA或控制程序中。

答案 6 :(得分:0)

您的示例测试x是否最多设置1位。如果x是2的幂,则f返回0,如果不是,则{0}返回非零。

答案 7 :(得分:-1)

您的特定示例测试二进制表示中的两个连续位是1