一道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了,结果有计算机 表示相反数
但是它未能解决我的疑惑
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因为0的存在所以负数比正数多一个,最小的负数是没有对应的正数的。
以你[-8, 7]为例, y = -8, 那么最大正数是7(0111), 8 = 7 + 1 = 0111 + 1 = 1000 = -8