位操作技巧总结

几个有趣的位操作

1. 利用或操作 | 和空格将英文字符转换为小写

('a' | ' ') = 'a'
('A' | ' ') = 'a'

2. 利用与操作 & 和下划线将英文字符转换为大写

('b' & '_') = 'B'
('B' & '_') = 'B'

3. 利用异或操作 ^ 和空格进行英文字符大小写互换

('d' ^ ' ') = 'D'
('D' ^ ' ') = 'd'

以上操作能够产生奇特效果的原因在于 ASCII 编码。

4. 判断两个数是否异号

int x = -1, y = 2;
bool f = ((x ^ y) < 0); // true

int x = 3, y = 2;
bool f = ((x ^ y) < 0); // false

这个技巧还是很实用的,利 用的是补码编码的符号位。如果不用位运算来判断是否异号,需要使用 if else 分支,还挺麻烦的。读者可能想利用乘积或者商来判断两个数是否异号,但是这种处理方式可能造成溢出,从而出现错误。

5. 不用临时变量交换两个数

a ^ a = 0

a ^ 0 = a

int a = 1, b = 2;
a ^= b; // a' = a ^ b
b ^= a; // b = b ^ a' = b ^ a ^ b = a
a ^= b; // a = a' ^ b = a ^ b ^ b = a
// 现在 a = 2, b = 1

6. 加一

int n = 1;
n = -~n;
// 现在 n = 2

7. 减一

int n = 2;
n = ~-n;
// 现在 n = 1

8. 消除数字 n 的二进制表示中的最后一个 1

n & (n-1)