首页 > 一道CSAPP的「有符号位加法」问题

一道CSAPP的「有符号位加法」问题

练习题2.32
原题描述:
编写函数testSubOk(x, y), 如果计算x-y不产生溢出,函数返回1.代码如下

int testSubOk(int x, int y) 
{
    return testAddOk(x, -y);
}

int testAddOk(int x, int y) {
    int sum = x + y;
    int negOver = x > 0 && y > 0 && sum <= 0;
    int posOver = x < 0 && y < 0 && sum >= 0;
    return !negOver && !posOver;   //产生溢出,返回0
}

由于题目假定返回值为0时成功,很不直观,我做了如下改动

int isAddOverflow(int x, int y)  //这是照抄书上的代码,可认为「绝对正确」
{
    int sum = x + y;
    int negOver = x < 0 && y < 0 && sum >= 0; //负数相加溢出
    int posOver = x >0 && y > 0 && sum <= 0;
    return negOver || posOver;   //任意一种溢出, 返回1
}

int isSubOverflow(int x, int y) 
{
    return isAddOverflow(x, -y);
}

问题: x和y取什么值时,isSubOverflow产生错误的结果?
解答: 当y为min时,如果此时x为一个负数,会产生「溢出返回值」, 但实际上没有溢出
理由:y为min, -y也为min,如果再加上一个负数,绝对溢出, 但是这种计算机的逻辑与实际结果不相符合

我的问题

考虑总的位数为4,取值范围[-8,7]
假设y = -8, 那么-y == ? (看理由那一段, -y == min == -8, 但是为什么?)

比如x = -3, y = -8 ,实际的结果subResult == x - y == 5
计算机的逻辑: x - y == x + (-y) == -3 + (-8) == -11产生溢出

y = 1, -y =-1; y = -5 , -y = 5; 它们都有与之对应的数
但是y = -8,没有与之对应的数, 为什么-y == -8?
如果y == 0, 那么-y == ?

按照补码的机制: -8补 == 1000

问题可以简化为

在有限位补码计数法的情况下, 计算机中如何表示「相反数」
为什么某些数的相反数「不那么直观」?

我google了,结果有计算机 表示相反数
但是它未能解决我的疑惑



因为0的存在所以负数比正数多一个,最小的负数是没有对应的正数的。
以你[-8, 7]为例, y = -8, 那么最大正数是7(0111), 8 = 7 + 1 = 0111 + 1 = 1000 = -8

【热门文章】
【热门文章】