在x + y中获取“携带”

时间:2011-05-23 01:54:28

标签: c++ c math

  

可能重复:
  Best way to detect integer overflow in C/C++

如果我有一个表达式x + y(在C或C ++中)xy都是uint64_t类型导致整数溢出,我该怎么检测它被(进位),位置溢出多少而不是另一个变量,然后计算余数?

3 个答案:

答案 0 :(得分:9)

假设您使用无符号整数,则余数将已存储在x + y的总和中。无符号整数溢出导致环绕(未定义有符号整数溢出)。请参阅评论中Pascal的标准参考。

溢出只能是1位。如果添加2个64位数,则进位位不能超过1,因此您只需要检测溢出条件。

关于如何检测溢出,有一个关于该主题的先前问题:best way to detect integer overflow

答案 1 :(得分:2)

对于z = x + y,z存储余数。溢出只能是1位,很容易检测到。如果您正在处理有符号整数,那么如果xy具有相同的符号,但z具有相反的符号,则会出现溢出。如果xy有不同的符号,则无法溢出。对于无符号整数,您只需以相同的方式检查最高位。

答案 2 :(得分:0)

C和C ++中的方法可能完全不同,因为在C ++中,您可以为您执行运算符重载工作,并将您想要保护的整数包装在某种类中(为此您需要重载必要的运算符。 C,你必须在结构中包装你想要保护的整数(以包含余数和结果)并调用一些函数来完成繁重的工作。

除此之外,两种语言中的方法是相同的:取决于您要执行的操作(在您的示例中添加),您必须弄清楚可能发生的最坏情况并处理它。

在添加的情况下,它非常简单:如果两者的总和将大于某个最大值(如果该最大值M与其中一个的差异将是这种情况操作数大于另一个操作数)你可以计算余数 - 那个太大的部分:if ((M - O1) > O2) R = O2 - (M - O1)(例如,如果M为100,O1为80,O2为30,30 - (100 - 80) = 10,这是余数。

减法的情况同样简单:如果你的第一个操作数小于第二个操作数,则余数是第二个减去第一个操作数(if (O1 < O2) { Rem = O2 - O1; Result = 0; } else { Rem = 0; Result = O1 - O2; })。

它的乘法有点困难:你最安全的选择是对值进行二进制乘法运算,并检查结果值是否超过你的位数。二进制乘法是一个很长的乘法,就像你在纸上手工进行十进制乘法一样,所以,例如,12 * 5是:

    0110
    0100
    ====
    0110
      0 
  0110  
    0   
  ++++++
  011110 = 40

如果你有一个四位整数,那么这里有一位溢出(即第4位为1,第5位为0.所以只有第4位计为溢出)。

对于师来说,你只需要关心除以0,大部分时间 - 其余部分将由你的CPU处理。

HTH

RLC