用bis和bic实现所有位级操作

在Digital Equiment 的VAX计算机中,只有两种对位的操作函数:位设置bis和位清除bic。
其中bis(x, m)表示对于m中为1的位,置x对应的位为1. bic(x, m)正好相反,对于m中为1的位,置x对应的位为0。参数m有个更常用的称谓——掩码。对于掩码你一定不陌生,子网掩码、颜色掩码... 简单地说,掩码就是个过滤器,滤掉我们不希望得到的东西。

好了,扯远了,言归正传。


1. 位或(|)的实现
首先考虑一下位或的定义,两个参数的某一位至少有一为1则结果的对应位为1。那么我们该好好利用一下掩码了,我们要做x和y的位或,首先我们把x拿出来,令结果等于x(什么?这就结束了?当然不是)。我们还缺什么?x为0而y为1的那些位,结果应该为1。那我们就把y当做掩码,筛选掉y中为0的位,把y为1的位都赋值给结果(即使x已经将结果的改位赋值为1也不影响),就可完成位或的实现。

结果:bis(x, y)


2. 位取反(~)的实现
同样利用取反的定义和掩码的作用,我们可以简单得到对x(一个字长)位取反的做法:把0xFFFFFFFF(32位机)用x做掩码,过滤掉x为1的位。

结果:bic(0xFFFFFFFF, x)


3. 位与(&)的实现
可以简单根据布尔运算:x & y = ~(~x | ~y)得到结果.
结果:bic(0xFFFFFFFF, bis(bic(0xFFFFFFFF, x), bic(0xFFFFFFFF, y)))

什么?嵌套太多头有点晕?来看看下一个吧。


4. 位异或(^)的实现
我们先来考虑异或的特点:相同为0,不同为1。为了构造这种结构,我们先来构造几个掩码:
m1 = x & y // x, y均为1的位置
m0 = ~(x | y) // x, y均为0的位置
ms = m1 | m0 // x, y相同的位置
md = ~ms // x, y不同的位置, 即x与y的位异或值!
代入得md = ~((x & y) | ~(x | y))
结果:bic(0xFFFFFFFF, bis(bic(y, bic(0xFFFFFFFF, x)), bic(0xFFFFFFFF, bis(x, y))))

结束了?No,there is still a cool solution。


5. 位异或(^)的实现ver2.0
结果:bis(bic(x, y), bic(y, x))
好吧这次先放结果,因为我也是在别处看到这个结果,觉得相当巧妙。
因为对异或的定义分析除了上述那种思路,还可以解释成(x & ~y) | (~x & y),两部分各得到一些x, y不同值的位,而且两部分互补构成完整的字长。
剩下的位操作:同或,同理可得;左移右移,暂时还没有想到。

你可能感兴趣的:(用bis和bic实现所有位级操作)