按位与

一、按位与的概念

按位与运算符为 &,它将两个操作数对应的二进制位的每一位一一对应,并进行逻辑与操作。

运算规则:两个对应位都为 1 时,结果位为 1;否则结果位为 0。

位a位ba & b
000
010
100
111

二、按位与的常见用途

1. 将操作数中的若干位置零(其他位不变)

利用 0 & x = 0 的特性,将需要清零的位与 0 进行按位与,需要保留的位与 1 进行按位与。

示例:将 char 型变量 a 的最低位置零,其余位保持不变。

a = a & 0xfe;

分析:0xfe 的二进制为 11111110(最低位为 0,其余位为 1)。a 与 0xfe 按位与后,最低位被强制清零,其余位保持原值不变。

2. 取操作数中的若干指定位

利用 x & 1 = x 的特性,将需要提取的位与 1 进行按位与,不需要的位与 0 进行按位与。

示例:假设有 char c 和 int a,取出 a 的低字节(低 8 位),置于 c 中。

c = a & 0xff;

分析:0xff 的二进制为低 8 位全 1(00000000 00000000 00000000 11111111)。a 与 0xff 按位与后,高 24 位全部清零,低 8 位保持原值,即提取了 a 的低字节。

三、代码示例

以下代码演示了按位与运算的实际应用:

#include <iostream>
using namespace std;

int main()
{
    // 示例1:将最低位置零
    unsigned char a = 0x9b;    // 二进制 10011011
    a = a & 0xfe;               // 0xfe = 11111110
    cout << "a after clear lowest bit: " << hex << (int)a << endl;
    // 结果:10011010,十六进制 9a

    // 示例2:提取低字节
    int num = 0x12345678;
    unsigned char c = num & 0xff;
    cout << "low byte of num: " << hex << (int)c << endl;
    // 结果:78

    // 示例3:判断奇偶性
    int x = 17;
    if (x & 1)
        cout << x << " is odd" << endl;
    else
        cout << x << " is even" << endl;
    // x & 1 结果为 1,说明最低位为 1,是奇数

    // 示例4:将指定位置零(第3位置零,从0开始计数)
    unsigned char flags = 0xff;    // 11111111
    flags = flags & ~(1 << 3);     // ~(1 << 3) = 11110111
    cout << "flags after clear bit 3: " << hex << (int)flags << endl;
    // 结果:f7

    // 示例5:提取指定位(取第4到第7位)
    unsigned char value = 0xab;    // 10101011
    unsigned char nibble = (value >> 4) & 0x0f;
    cout << "high nibble: " << hex << (int)nibble << endl;
    // 结果:a

    return 0;
}Code language: PHP (php)

四、注意事项

  • 按位与 & 不要与逻辑与 && 混淆。& 是对每一位进行运算,&& 是对整体布尔值进行运算。
  • 对负数进行按位与时,结果依赖于该数在计算机中的二进制表示方式(通常为补码)。
  • 将位置零时,掩码中需要清零的位设为 0,需要保留的位设为 1。
  • 提取位时,掩码中需要提取的位设为 1,其余位设为 0,然后按位与。

五、小结

  • 按位与(&)将两个操作数逐位进行逻辑与运算。
  • 主要用途:将指定位置零、提取指定位、判断奇偶、掩码操作。
  • 置零操作:目标位与 0 按位与,其余位与 1 按位与。
  • 提取操作:目标位与 1 按位与,其余位与 0 按位与。
  • 实际开发中常用于状态标志的读取和修改。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注