布尔代数起源于1850年前后乔治·布尔的工作,最简单的布尔代数是在二元集合{0, 1}基础上的定义。布尔运算 ~、&、|、^分别对应逻辑运算NOT、AND、OR、XOR,如下表所示。其中 ~为一元运算,其他三个为二元运算。
图中表格以竖轴为变量某一位的取值、横轴为掩码对应位的取值,表格中为运算结果的值,观察分析可以得到以下几点:
- 对& 运算,若掩码取值为1,结果为变量位原本的值;若掩码取值为0,则结果为0
- 对 | 运算,若掩码取值为0,结果为变量位原本的值;若掩码取值为1,则结果为1
- 对^ 运算,若掩码取值为0,结果为变量位原本的值;若掩码取值为1,则结果为变量位的补码
例一
x = 0x87654321,若给定以下要求及结果,写出各个表达式。
- x的最低有效字节,其他位均置为0。[0x00000021]
保留x的最低有效字节,即保留变量位原本的值,这一点&|^都可以做到;而其他位均置为0,只有&运算+对应掩码位取0可以做到,又有&运算+对应掩码位取1可以做到保留原本位的值。
因此,表达式为x & 0xFF; - 除了x的最低有效字节外,其他的位都取补,最低有效字节保持不变。[0x789ABC21]
最低有效字节保持不变,同1),三种运算都能做到;而其他位都取补,只有^运算+对应掩码位取1可以做到,又有 ^运算+对应掩码位取0可以做到保留原本位的值。
因此,表达式为x ^ FFFFFF00。但是,该表达式只能工作在32位机器上,修改为x ^ 0xFF。(0xFF:高位的0都变为1,最低的8位变为0。 - x的最低有效字节设置成全1,其他字节都保持不变。[0x876543FF]
设置成1,只有 | 运算+对应掩码位取1可以做到,又有 | 运算+对应掩码位取0可以做到保留原本位的值。
因此,表达式位x | 0xFF。
例二
现在有两个函数bis(int x, int m)和bic(int x, int m),输入都是一个数据字x和一个掩码字m,生成的结果z是根据掩码m的位来修改x的位得到的。使用bis,在m为1的每个位置上,将z对应的位设置为1;使用bic指令,在m为1的位置上,将z对应的位设置为0。
如何只使用上面两个函数实现异或^运算?
解法一:
bic(x,y)得到的结果中,值为1的位置,要求在x中为1且在y中为0;
同理,bic(y,x)得到的结果中,值为1的位置,要求在y中为1且在x中为0;
上述的两种位置是x和y中一个取值为1,另一个取值为0的位置。因此,只要把bic(x,y)和bic(y,x)的结果加起来就可以
而bis(x,y)将y中为1的位置处的x置为1,y中为0的位置x保持。因此可以满足上面结果相加的要求。
故 x ^ y = bis(bic(x,y), bic(y,x))
解法二:
仔细分析,bic(x,m)等价于x | m;bis(x, m)等价于 x & ~m。
题中:
“在m为1的每个位置上,将z对应的位设置为1”可以用 | 运算实现,因此bic(x, m)价于x | m;
“m为1的位置上,将z对应的位设置为0”可以理解成:~m为0的位置上,将z对应的位置设置为0。这可以用&运算实现,因此bis(x, m)等价于 x & ~m。
由于x ^ y = (x & ~y) | ( ~x & y),所以x ^ y = bis(bic(x,y), bic(y,x))。