位与(&), 位或(|), 位亦或 (^),位非 (~)

按位与(&)

按位与运算符是单个与符号(&)。如果两个位都是1,结果为1,否则结果0。如下所示:

[c gutter=”0″]
0 0 1 1 运算数1
0 1 0 1 运算数2
———-
0 0 0 1 (运算数1 & 运算数2) 运算结果
[/c]

在Arduino中,int型是16位的。所以在两个整型表达式之间使用&将会导致16个与运算同时发生。如下所示:

[c gutter=”0″]
int a = 92; // 以二进制表达 0000000001011100
int b = 101; // 以二进制表达 0000000001100101
int c = a & b; // 结果(十进制:68) 0000000001000100,
[/c]

在以上示例中,a和b均为整型数值,转换成二进制是16位的数字。对每一位使用按位与处理,且所有16位结果存入C中。运算结果为0000000001000100,即十进制的68。


按位或(|)

按位或运算符是垂直的条杆符号(|)。其运算规则是:只要任一表达式的一位为 1,则结果中的该位为 1。否则,结果中的该位为 0。如下所示:

[c gutter=”0″]
0 0 1 1 运算数1
0 1 0 1 运算数2
———-
0 1 1 1 (运算数1 | 运算数2) 运算结果
[/c]

以下是按位或运算的示例:

[c gutter=”0″]
int a = 92; // 以二进制表达 0000000001011100
int b = 101; // 以二进制表达 0000000001100101
int c = a | b; // 结果(十进制125) 0000000001111101,
[/c]


位异或(^)

位异或运算符是^符号。其运算规则是:如果两个运算位相同,则结果为0,否则为1。如下所示:

[c gutter=”0″]
0 0 1 1 运算数1
0 1 0 1 运算数2
———-
0 1 1 0 (运算数1 ^ 运算数2) 运算结果
[/c]

以下是位异或运算的示例:

[c gutter=”0″]
int a = 12; // 以二进制表达 1100
int b = 10; // 以二进制表达 1010
int c = a ^ b; // 结果 (十进制:6) 0110,
[/c]


位非(~)

按位取反运算符为波浪符“~”。按位取反操作会翻转其每一位。0变为1,1变为0。如下所示:

[c gutter=”0″]
0 1 运算数1
———-
1 0 ~ 运算数2 (按位取反运算结果)

[/c]

以下是位异或运算的示例:

[c gutter=”0″]
int a = 103; // 二进制: 0000000001100111
int b = ~a; // 二进制: 1111111110011000 = -104 (十进制)
[/c]

你可能会感到惊讶为何结果为一个负数:-104。这是因为一个整型变量的最高位是符号位。如果最高位为0,该整数为正数。如果最高位为1,该整数为负数。这里正数和负数的编码被称为二进制补码。

顺便说一句,值得注意的是,对于任何整数x, ~x 与 -x-1 相等。