这是练习题2.13,此题要求我们只使用给定函数bis,bic实现异或^运算符,并且兼容64位/32位机器。只看答案我感到毫无头绪,于是想自己写出解题思路。(为了尽量写详细,所以有些您觉得简单的地方,请耐心)
一、我们首先尝试理解题目,通过我们位运算基础,我们想到要将x,y转换成2进制来讨论。
我们把x,y二进制形式的对应的位称为对应位。
例x:10011
y:10111
^_^这里每一列都是一组对应位,分别在x,y的位置相同。
bis(x,y)位设置,作用是y对应位为1的x的对应位置1
bic(x,y)位清除,作用是y对应位为1的x的对应位置0
我们先概括一下这两个函数的作用,和异或^的要求,把位的所有可能值传入。
例:下图描述了x,y的对应位可能存在的所有情况
x对应位 | 1 | 0 | 0 | 1 |
y对应位 | 0 | 1 | 0 | 1 |
bis(x,y) | 1 | 1 | 0 | 1 |
bic(x,y) | 1 | 0 | 0 | 0 |
x^y | 1 | 1 | 0 | 0 |
bic(y,x) | 0 | 1 | 0 | 0 |
我们发现bis是“有1为1,全0为0”这不正是或,“|”的操作嘛!
不过貌似c语言没有bic这样的运算符,很奇怪的是只有x对应位为1,y对应位为0结果才为1,其他组合全是0。显然,bic的结果与参数顺序有关。
怎么会有这样的运算符?
我们再来看看异或运算结果是“对应位 不同为1,对应位相同为0”。
我们只调用一次函数的话,并没有得到想要的异或的结果,但我们发现离结果只差最后一步,如果能把把bis的最右边那一列的结果置0,结果不就是异或的结果嘛!等等!置0不就是bic的操作嘛!或者将第二列的bic结果置1同样能得到异或的答案!
诶!我们发现最后一行的bic逆序的参数版,正好与我们需要置bic正序结果1的位对应位为1。
我们把它们的结果使用bis嵌套结合。
bis(bic(x,y),bic(y,x));
正好得到了对应位相同为0,对应位不同为1的操作
举一反三,同样的解题思路我们还能做出与操作,读者不妨自己试试。
答案是:bis(bic(x,y),y);