在《深入理解计算机系统》一书的第二章35页,有一个很有意思的小问题。
讲20世纪70年代末到80年代末,Digital Equipment的VAX计算机很流行。但是它却没有布尔运算AND和OR指令,只有bis(位设置)和bic(位清除)两种指令。输入都为一个数x和一个掩码m
其中,两个函数均在m为1的每个位置上,对x相应位置设置为1。
现在,要求只用这两个函数来实现C语言的|和^运算。且不使用任何其他的C语言运算
一开始第一个想法:自然是建立bis与bic与传统逻辑或与非之间的联系。
只要证明能用bis与bic表示非运算,以及'与''或'运算两者任意之一,就可以证明这两个函数是逻辑完备的。
'或' 性质显然:bis(x , y) = x | y
接下来就是表示非了:
bic(~0, x) = ~x
看上去好像问题已经解决了:建立了bis,bic与或非的联系。使用德摩根律得到'与'的表示:x & y = ~(~x | ~y)
接下来只要将异或表示为几种基本逻辑运算的组合:x ^ y = (x | y) & ~(x & y)
然后再翻译为bis,bic语言就行。
不过还没有结束。
题目的要求是不使用任何其他的C语言运算。
而在'非'的实现中
bic(~0, x) = ~x 里面却是对0做了一次取反运算。
或许说用0xfffff…..ffff 一堆1来代替0,就可以省掉这次运算了。但很明显,这种投机取巧的丑陋做法是不好的。
所以最终还是要祭出逻辑学的终极大杀器——真值表
|
x |
y |
bis(x,y) |
bic(x,y) |
x ^ y |
|
0 |
0 |
0 |
0 |
0 |
|
0 |
1 |
1 |
0 |
1 |
|
1 |
0 |
1 |
1 |
1 |
|
1 |
1 |
1 |
0 |
0 |
嗯。。通过观察可以发现,若是想要用bis,bic拼凑出x^y的真值。
我们可以用两个次序相反的x,y进行bic运算,然后得到01和10对应的两个1,将它们一并,就得到了x^y
而并的实现,就是使用一次bis
所以最终的答案是
x^y = bis(bic(x,y),bic(y,x))
浙公网安备 33010602011771号