“我想有一个浓度很大的成长…”
深入理解计算机系统练习题题 2.30
写一个函数,当参数x和y相加不会产生溢出,这个函数就返回1。
int tadd_ok(int x,int y){
int sum = x+y;
int neg_over = x<0 && y<0 && sum >= 0;
int pos_over = x>=0 && y >= 0 && sum < 0;
return !neg_over && !pos_over;
}
这里没有问题
但是注意下面:
计算x-y 会不会产生溢出。
int tsub_ok(int x,int y){
return tadd_ok(x,-y)
x 和 y 取什么值时,这个函数会产生错误的结果?
这里就要涉及到补码非的特点了。
首先,考虑一个数字是补码用4个位来表示的。那么它的范围就是:-8~7
对于任意x != -8, 它的相反数就是-x(书中说的是 加法逆元)x + (-x) = 0。然而对于,x = -8 = Tmin, -x 等于什么? 不可能等于8,因为Tmax = 7。所以我们规定 -x等于它本身,即-x = Tmin。幸亏这个在补码里逻辑也是自洽的。 因为x + (-x) = 1000(B) + 1000(B) = 10000(B), 舍掉最高位,即 0000,所以x + (-x) = 0。
回到上面的问题,当y = Tmin时,对于所有x的值,该函数的结果都不正确的。而当x是负数时,该函数认为负溢出,而此时,x-y其实并没有溢出。因为x为负数,而-y为正数。