按位取反

一、按位取反的概念

按位取反运算符为 ~,是一个单目运算符。其作用是对一个二进制数的每一位进行取反操作:0 变为 1,1 变为 0。

运算规则:

位a~a
01
10

二、运算示例

假设有一个 unsigned char 类型的变量 a,其值为 0x4A(二进制 01001010),对其执行按位取反:

unsigned char a = 0x4A;    // 01001010
unsigned char b = ~a;     // 10110101,即 0xB5Code language: JavaScript (javascript)

分析:a 的每一位都被翻转,得到结果 0xB5。

注意:如果操作数是有符号类型,取反后的结果可能表示一个负数(取决于该类型的编码方式,通常为补码)。例如 char 类型(有符号)变量值为 5(00000101),取反后为 11111010,在补码表示下这是 -6。

三、常见用途

1. 配合按位与将指定位置零

按位取反常与按位与结合使用,用于构造掩码并将特定位清零。

示例:将 int 型变量 flags 的第 3 位(从 0 开始计数)清零,其余位保持不变。

flags = flags & ~(1 << 3);

分析:1 << 3 得到 00000000 00000000 00000000 00001000,取反后得到 11111111 11111111 11111111 11110111。再与 flags 按位与,即可将第 3 位清零,其余位不变。

2. 构造掩码

通过取反操作可以快速构造某些位模式。例如构造低 8 位全 1 的掩码:~0 在 32 位系统上会得到全 1,再根据需要移位或截断。

四、代码示例

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

#include <iostream>
using namespace std;

int main()
{
    // 示例1:基本取反
    unsigned char a = 0x4A;    // 01001010
    unsigned char b = ~a;     // 10110101
    cout << "a = " << hex << (int)a << endl;   // 输出 4a
    cout << "~a = " << hex << (int)b << endl;  // 输出 b5

    // 示例2:有符号数的取反
    char c = 5;    // 00000101
    char d = ~c;   // 11111010,补码表示 -6
    cout << "c = " << dec << (int)c << endl;   // 输出 5
    cout << "~c = " << (int)d << endl;          // 输出 -6

    // 示例3:配合按位与将指定位置零
    int flags = 0xFFFF;
    flags = flags & ~(1 << 3);    // 将第3位清零
    cout << "flags after clear bit 3: " << hex << flags << endl; // 输出 fff7

    // 示例4:配合按位与将多个位清零
    unsigned char status = 0xFF;  // 11111111
    status = status & ~(0x03);    // 将低2位清零,0x03取反为11111100
    cout << "status after clear low 2 bits: " << hex << (int)status << endl; // 输出 fc

    // 示例5:构造掩码
    unsigned int mask = ~0;      // 所有位全1
    cout << "mask = " << hex << mask << endl;

    return 0;
}Code language: PHP (php)

五、注意事项

  • 按位取反 ~ 不要与逻辑非 ! 混淆。~ 是对每一位进行取反,! 是对整体布尔值取反(非0变为0,0变为1)。
  • 取反操作的结果类型与操作数类型相同,如果操作数是较小类型(如 char),在执行运算时会被提升为 int,取反后再截断回原类型。
  • 对有符号数取反时,结果通常以补码形式解释,可能得到负数。
  • 在嵌入式编程和底层开发中,~ 常用于寄存器位的清零操作。

六、小结

  • 按位取反(~)是单目运算符,对操作数的每一位取反。
  • 常见用途:配合按位与将指定位置零、构造掩码。
  • 注意区分 ~ 和 ! 的不同作用。
  • 有符号数取反后可能变为负数,需注意类型提升和截断。
Previous:
Next:

发表回复

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