PS:本文主要介绍位运算的数学性质,和OI没有太大关联.
Part0:符号约定
\([p]\):艾弗森记号.对于命题\(p\),当\(p\)成立时,\([p]\)为\(1\),否则为\(0\).
\(x_i\):\(x\)在二进制下的第\(i\)位数.
Part1:二进制
对于任意的非负整数\(x\),众所周知,其可以表示为:
\[ x=\sum_{i=0}^n 10^i b_i \]
其中,\(n=\lfloor \log_{10} x\rfloor,b_i\in\{0,1,2,\dots,9\}(i=1,2,\dots,n)\).我们把该式中的所有\(10\)都换成\(2\),则有:
\[ x=\sum_{i=0}^n 2^i b_i \]
其中,\(n=\lfloor \log_2 x\rfloor,b_i\in\{0,1\}(i=1,2,\dots,n)\).我们将数位
\[ \overline{b_n b_{n-1} \dots b_1 b_0}_{(2)} \]
称为\(x\)的二进制(分解),这种分解是惟一的.为方便,我们在本文中简记\(x_i=b_i\),为\(x\)在二进制下的第\(i\)位数.
Part2:二进制递推式与位移运算
我们来考虑\(x,\lfloor \frac x2\rfloor,2x\)二进制之间的关系.因
\[ x=\sum_{i=0}^n 2^i x_i \]
故有
\[ \left\lfloor \frac x2\right\rfloor=\left\lfloor \frac{\sum\limits_{i=0}^n2^i x_i}2\right\rfloor=\left\lfloor \frac{\sum\limits_{i=1}^n 2^i x_i}2 + \frac{x_0}2\right\rfloor \]
显然左边的加数整除\(2\).又\(x_0\in\{0,1\}\),故\(\frac{x_0}2=0\).所以
\[ \left\lfloor \frac x2\right\rfloor=\sum_{i=1}^n 2^{i-1}x_i=\sum_{i=0}^{n-1} 2^i x_{i+1} \]
这相当于把整个二进制往右移\(1\)位,并把不为整数的部分截掉,比如,\(11=1011_{(2)}\),则
\[ \left\lfloor\frac{11}2\right\rfloor=\left\lfloor \frac{1011_{(2)}}2\right\rfloor=101_{(2)}=5 \]
再来考虑\(2x\).
因
\[ x=\sum_{i=0}^n 2^i x_i \]
故
\[ 2x=\sum_{i=0}^n 2^{i+1} x_i=\sum_{i=1}^{n+1} 2^i x_{i-1} \]
这相当于把整个二进制往左移\(1\)位,并在低位补全零,比如,\(6=110_{(2)}\),则
\[ 2\times 6=2\times{110_{(2)}}=1100_{(2)}=12 \]
更一般地,有
\[ \left\lfloor\frac{x}{2^k}\right\rfloor=\sum_{i=0}^{n-k}2^i x_{i+k}\\ 2^kx=\sum_{i=k}^{n+k}2^i x_{i-k} \]
其中\(k\in\mathbb{N}^+\).我们把这两种运算分别称为右移(right shift)和左移(left shift),分别记为
\[ x\gg k=\left\lfloor\frac{x}{2^k}\right\rfloor\\ x\ll k=2^kx \]
特别地,当\(k>n\)时,\(x\gg k=0\).右移的意义是将二进制往右移\(k\)位,并将不为整数的部分截掉;左移的意义是讲二进制往左移\(k\)位,并在低位补全零.我们很容易得到:
\[ x=(x\gg1)\ll1 + (x\bmod 2) \]
这就是二进制的递推式.亦即:
\[ x=2\left\lfloor\frac x2\right\rfloor+(x\bmod 2) \]
这样就可以快速地求出一个非负整数的二进制表示了.
Part3:与运算和或运算
对于两个非负整数\(x,y\),设
\[ x=\sum_{i=0}^n 2^ix_i,\\ y=\sum_{i=0}^m2^iy_i, \]
定义
\[ x\ \text{and}\ y=x\land y=\sum_{i=0}^{\min\{n,m\}}2^i[x_i=1\land y_i=1]=\sum_{i=0}^{\min\{n,m\}} 2^i x_iy_i=\sum_{i=0}^{\min\{n,m\}}2^i\left\lfloor\frac{x_i+y_i}2\right\rfloor \]
为\(x\)与\(y\)的与运算(and operation).而
\[ x\ \text{or}\ y=x\lor y=\sum_{i=0}^{\max\{n,m\}} 2^i[x_i=1\lor y_i=1]=\sum_{i=0}^{\max\{n,m\}} 2^i \left\lceil\frac{x_i+y_i}2\right\rceil \]
为\(x\)与\(y\)的或运算(or operation).显然有
\[ x\land y\le\max\{x,y\}\\ x\lor y\ge\min\{x,y\} \]
Part4:取反
一个数的取反运算(not operation)定义为
\[ \lnot x=\sum_{i=0}^n 2^i[x_i=0] \]
相当于把值为\(1\)的位改成\(0\),把值为\(0\)的位改成\(1\).一般地,有
\[ x+\lnot x=2^{n+1}-1,\\ \lnot\lnot x=x. \]
Part5:异或
这是我们要重点讨论的位运算.其定义为
\[ x\ \text{xor}\ y=x\oplus y=\sum_{i=0}^{\max\{n,m\}}2^i[x_i\ne y_i]=\sum_{i=0}^{\max\{n,m\}}2^i(x_i+y_i\mod 2) \]
显然有\(|x-y|\le x\oplus y\le x+y\).容易验证,异或运算(exclusive or operation,xor operation)具有以下性质:
\(1.\)交换性:\(x\oplus y=y\oplus x\).
\(2.\)结合性:\(x\oplus y\oplus z=(x\oplus y)\oplus z=x\oplus (y\oplus z)\).
\(3.\)幂零性:\(x\oplus x=0\).
\(4.\)还原性:\(x\oplus y\oplus x=y\).特别地,有\(x\oplus 0=0\oplus x=x\).
\(4'.\)转换性:\(w=x\oplus y\oplus z\Rightarrow x=w\oplus y\oplus z\).
\(5.\)与其它位运算的关系:\(x\oplus y=(\lnot x\land y)\lor(x\land\lnot y)\).
Part6:位运算方程
我们把形如只含有以下三种运算的方程叫做位运算方程(组)(bit operation equations):
\(1.\)位移常数
\(2.\)异或
\(3.\)取反
显然,这几种运算是可逆的.先来一道简单题.考虑位运算方程组
\[ \begin{cases} x\oplus y=z\\ \lnot z=4\\ x\gg 2=1 \end{cases} \]
根据第三个方程,易知
\[ x=1\ll 2=4. \]
根据第二个方程,有
\[ z=\lnot 4=3. \]
因此,
\[ y=z\oplus x=3\oplus 4=7. \]
所以原方程组的解为
\[ \begin{cases} x=4,\\ y=7,\\ z=3. \end{cases} \]
再来考虑位运算方程组:
\[ \begin{cases} x\oplus y\oplus z=w\\ (\lnot x)\oplus y=6\\ x\gg 2=1\\ z\oplus (\lnot y)=9 \end{cases} \]
显然有\(x=4\).进一步带入第二个方程有
\[ y=6\oplus(\lnot x)=6\oplus 3=5. \]
故得
\[ z=9\oplus (\lnot y)=9\oplus 2=11. \]
于是
\[ w=x\oplus y\oplus z=4\oplus 5\oplus 11=10. \]
因此原方程组的解为
\[ \begin{cases} x=4,\\ y=5,\\ z=11,\\ w=10. \end{cases} \]