当前位置: 首页 > 知识库问答 >
问题:

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

明利
2023-03-14

对于家庭作业,我必须用C编写一个函数,将两个有符号整数相加,但如果有正溢出,则返回INT\u MAX,如果有负溢出,则返回INT\u MIN。我必须遵守非常严格的限制,我可以使用什么运算符。所有整数都是二的补码形式,右移是算术的,整数大小是可变的(我可以用sizeof(int)找到它)

我知道,如果两个输入具有相同的符号,而结果具有不同的符号,则可以检测到溢出。我已经到达了一个点,其中我有一个标志,显示等式是否溢出。我不知道如何从那里到达最终产品。这是我到目前为止得到的:

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

}

我试图遵循C(HW)中按位饱和加法所显示的答案,但我陷入了必须为除符号位之外的所有整数填充相同位的部分(1到0111...11和0到0000.00)。我不知道“移位和ORs的组合”是什么。

共有1个答案

湛嘉歆
2023-03-14

我认为你误解了答案。您应该做的是将符号位扩展到所有位,包括MSB。这可以通过取包含符号位的int来实现,例如didfoverflow,并在其补码中加1。

然后,您可以找到在出现溢出的情况下应该返回哪个溢出值。这可以通过使用扩展的signX(或signY)对INT\u MAX进行异或运算来实现。我们将此值称为溢出。最后,如下更改溢出和结果:

overflow := (extended didOverflow) AND overflow
result := (NOT (extended didOverflow)) AND result

现在,在这些赋值之后,如果扩展的溢出是1…1,那么溢出显然将保持不变<另一方面,代码>结果将等于0。

但如果didOverflow为0…0,则相反的情况适用:溢出现在为0,而结果保持不变。

在第一种情况下(其中didOverflow为1…1,表示存在溢出),溢出或结果等于溢出。在第二种情况下(没有溢出),溢出或结果等于结果。因此,无论哪种方式,溢出或结果将为我们提供正确的值。

 类似资料:
  • 有符号和无符号变量在按位运算上有区别吗?< br >例如,在处理无符号数字时:< br> 将得到00000101。 但当处理带符号的数字时会发生什么?

  • 本文向大家介绍C语言中无符号数和有符号数之间的运算,包括了C语言中无符号数和有符号数之间的运算的使用技巧和注意事项,需要的朋友参考一下 C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了。 unsigned int和int进行运算 直接看例子来说明问题吧 输出结果为: 这是因为a和b进行比较的时

  • GCC和Clang似乎对有符号整数和无符号整数之间的加法有不同的解释,这取决于它们的大小。为什么会这样?所有编译器和平台上的转换是否一致? 举个例子: 结果: 在这两种情况下,我们得到了-1,但其中一个被解释为无符号整数和下溢。我本以为两者都会以同样的方式转化。 那么,为什么编译器会以如此不同的方式转换它们,这保证了一致性吗?我用G11.1.0和Clang12.0测试了这个。以及Arch Linu

  • 我试图使用值在C#中实现以下Java函数,以便不再适用64位限制。作为一项健全性检查,我将使用的原始函数也转换为C#代码。然而,问题是,使用的版本工作时,使用的版本并不总是返回相同的结果。 C#中原始函数的实现。 而不是像原始的Java代码那样打印所有的值,我打算使用它们,这样我就可以单独返回每个值。 在组合学中,使用choose函数可以很容易地验证生成的数字集合是否具有正确的值数: 从52张扑克

  • 本文向大家介绍详解C++中new运算符和delete运算符的使用,包括了详解C++中new运算符和delete运算符的使用的使用技巧和注意事项,需要的朋友参考一下 C++ 支持使用 new 和 delete 运算符动态分配和释放对象。这些运算符为来自称为“自由存储”的池中的对象分配内存。 new 运算符调用特殊函数 operator new,delete 运算符调用特殊函数 operator de

  • 引用oracle网站“byte:字节数据类型是一个8位有符号二补码整数。它的最小值为-128,最大值为127(含)”。 在这里,前两行有效,但最后一行无效 Q1)8位有符号到底是什么意思?二进制格式的128将是1000 0000,-128需要一个额外的负号位,如果所有8位都被占用,它将适合。 Q2)对于int,有一个无符号右移运算符,但这对于字节似乎是非法的,为什么会这样。无法防止字节溢出。在in