这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战。
位操作
位操作可用于解决各种各样的问题。有时候,有的问题会明确要求用位操作来解决,而在其他情况下,位操作也是优化代码的实用技巧。写代码要熟悉位操作,同时也要熟练掌握位操作的手工运算。处理位操作问题时,务必小心翼翼,不经意间就会犯下各种小错。
手工位操作
如果你对位操作感到生疏,请尝试下列练习。第三列中的运算可以手动求解,也可以用“技巧”解决(如下所述)。为了简单起见,假设所有数都是4位数。
如果你感到困惑不解,请先按照十进制数进行运算。之后,你可以将相同的方法运用在二进制数上。请记住,^表示异或操作(XOR),~表示取反操作或否定操作(NOT)。
| 0110 + 0010 | 0011 * 0101 | 0110 + 0110 |
| 0011 + 0010 | 0011 * 0011 | 0100 * 0011 |
| 0110 - 0011 | 1101 >> 2 | 1101 ^ (~1101) |
| 1000 - 0110 | 1101 ^ 0101 | 1011 & (~0 << 2) |
答案:第1行 (1000, 1111, 1100);第2行 (0101, 1001, 1100);第3行 (0011, 0011, 1111);第4行 (0010, 1000, 1000)。
第三列问题的解决技巧如下。
(1) 0110 + 0110相当于0110 × 2,也就是将0110左移1位。
(2) 0100等于4,一个数与4相乘,相当于将这个数左移2位。于是,将0011左移2位得到1100。
(3) 逐个比特分解这一操作。一个比特与对它取反的值做异或操作,结果总是1。因此,a^(~a)的结果是一串1。
(4) ~ 0的值就是一串1,所以~0 << 2的结果为一串1后面跟2个0。将这个值与另外一个值进行“位与”操作,相当于将该值的最后2位清零。
如果你没能立刻领会这些技巧,请按照逻辑关系进行思考。
位操作原理与技巧
下列表达式在位操作中很实用。不要一味死记硬背,而应思考这些等式何以成立。在下面的示例中,“1s”和“0s”分别表示一串1和一串0。
| x ^ 0s = x | x & 0s = 0 | x | 0s = x |
| x ^ 1s = ~x | x & 1s = x | x | 1s = 1s |
| x ^ x = 0 | x & x = x | x | x = x |
要理解这些表达式的含义,你必须记住所有操作是按位进行的,某一位的运算结果不会影响其余位,也就是说,只要上述语句对某一位成立,则同样适用于一串位。