【csapp 练习题2.31】你的同事对你的补码加法分析有些不耐烦,他给出了一个函数tadd_ok的实现
从概念上:
补码加减应用的是模数运算,
模数加法(减法可以转化为加法)形成阿贝尔群(Abelian group)
阿贝尔群满足交换律和结合律
所以sum-x=(x+y)-x=(x-x)+y=y
运算在数学本质上可以看出是不存在问题的
因此sum-x==y 无论是什么设置都是恒成立的
从实践上:
模数加法进行位运算,无论是是否溢出,都是数位进行模运算,对于位运算来说没有区别。
判断是否溢出只是在人为解释位串的含义。从解释的角度,在逻辑上应该是判断是否两正数加出的数是负数,两负数加出正数,才能得到是否溢出的结论。
同事为什么出错:
同事出错的原因在于将逻辑解释与位串数值两个概念混淆,认为sum=x+y在逻辑上是溢出的,因此改变了位串应有的数值结构,sum-x==y就不成立了;然而无论逻辑上是否认为溢出,位串本身就是模运算的数字,构成abel群,怎么进行加减运算都是成立的。(自己随便试一下就会发现是这样的)
本质上同事想要通过算术运算去表达逻辑上的溢出明显是不现实的,应当进行>、<、⊕ 等逻辑判断才能人为解释代码是否溢出
比如1:用(x>0&&y>0&&x+y<0)等判断是否溢出
比如2:用Cn-1进位和Cn进行逻辑异或OF=Cn-1⊕Cn来进行判断溢出