对于家庭作业,我必须在C中编写一个函数,它将两个有符号整数相加,但如果存在正溢出则返回INT_MAX,如果存在负溢出则返回INT_MIN。在我可以使用的操作符中,我必须遵循非常严格的限制。所有整数都是二进制补码形式,右移是算术运算,整数大小是可变的(我可以用sizeof(int)<< 3)找到它。我不能使用contitionals,循环,比较运算符或转换。我只能使用按位和逻辑运算符,加法和减法,相等测试以及整数常量INT_MAX和INT_MIN。
我知道如果两个输入具有相同的符号并且结果具有不同的符号,则可以检测到溢出。我已经达到了一个标志,显示方程式是否溢出。我不知道如何从那里到最终产品。这就是我到目前为止所做的:
int saturating_add(int x, int y){
int w = sizeof(int)<<3;
int result = x+y;
int signX = (x>>w-1)&0x01;//Sign bit of X
int signY = (y>>w-1)&0x01;//Sign bit of Y
int resultSign = (result>>w-1)&0x01; //Sign bit of result
int canOverflow = ~(signX ^ signY); //If they're the same sign, they can overflow
int didOverflow = (resultSign^signX)&canOverflow; //1 if input signs are same and result sign different, 0 otherwise
}
我正在尝试按照Bitwise saturated addition in C (HW)中显示的答案,但是我被困在我必须用除了符号位(1到0111)之外的所有相同位填充整数的部分。 .11和0转到0000.00)。我不知道“轮班和OR的组合”是什么。
答案 0 :(得分:2)
我认为你误解了答案。你应该做的是将符号位扩展到位的全部,包括MSB。这可以通过使用保持符号位的int来实现,例如, didOverflow
,并在其补充中加1。
然后,您会发现在出现溢出的情况下应返回哪个溢出值。这可以通过使用扩展INT_MAX
(或signX
进行异或signY
来完成,两者都可以。我们称这个值为overflow
。最后,改变overflow
和result
,如下所示:
overflow := (extended didOverflow) AND overflow
result := (NOT (extended didOverflow)) AND result
现在,在这些分配之后,如果扩展的didOverflow
是1 ... 1,那么overflow
显然会保持不变。另一方面,result
将等于0。
但如果didOverflow
为0 ... 0,则相反:overflow
现在为0,而result
保持不变。
在第一种情况下(其中didOverflow
为1 ... 1,表示存在溢出),overflow OR result
等于overflow
。在第二种情况下(我们没有溢出),overflow OR result
等于result
。无论哪种方式,overflow OR result
都会给我们正确的价值。