使用C(HW)中的按位运算符饱和有符号整数加法

时间:2013-10-06 22:13:43

标签: c bit-manipulation addition

对于家庭作业,我必须在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的组合”是什么。

1 个答案:

答案 0 :(得分:2)

我认为你误解了答案。你应该做的是将符号位扩展到位的全部,包括MSB。这可以通过使用保持符号位的int来实现,例如, didOverflow,并在其补充中加1。

然后,您会发现在出现溢出的情况下应返回哪个溢出值。这可以通过使用扩展INT_MAX(或signX进行异或signY来完成,两者都可以。我们称这个值为overflow。最后,改变overflowresult,如下所示:

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都会给我们正确的价值。