几个有趣的位操作
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)