【问题标题】:Detecting if an unsigned integer overflow has occurred when adding two numbers检测两个数字相加时是否发生无符号整数溢出
【发布时间】:2016-03-01 03:05:03
【问题描述】:

这是我在尝试将两个数字相加时检测是否发生无符号整数溢出的实现。

我的系统上 unsigned int (UINT_MAX) 的最大值是 4294967295。

int check_addition_overflow(unsigned int a, unsigned int b) {
   if (a > 0 && b > (UINT_MAX - a)) {
    printf("overflow has occured\n");
   }
   return 0;
}

这似乎适用于我尝试过的值。

任何流氓案件?你认为有什么好处和坏处?

【问题讨论】:

  • 您的代码接受int,但您的文字是在谈论unsigned int ...它是什么?
  • 此代码无法编译。使用{ 而不是[
  • @Kingamere 你的函数有int 返回类型并且不返回任何东西。说真的!
  • 你必须返回一些值,但你没有。因此,即使错字被纠正。这个功能在任何情况下都不起作用。
  • @Kingamere 你能解释一下为什么a > 0 条件吗?

标签: c unsigned integer-overflow unsigned-integer


【解决方案1】:

你可以使用

if((a + b) < a)

关键是如果a + b溢出,结果会被修剪,必须低于a

考虑假设边界范围为 0 -> 9(在 10 处溢出)的情况​​:

b 最多为 9。对于任何值a,例如a + b &gt;= 10(a + 9) % 10 &lt; a
对于任何值ab 使得a + b &lt; 10,因为b 不是负数,a + b &gt;= a

【讨论】:

  • upv 因为这个解决方案更好,但这不能回答 OP 问题
  • @ouah - 谢谢。答案就在这里,因为 OP 在 cmets 中询问我是否可以解释该解决方案并且评论太长了。
【解决方案2】:

我相信 OP 指的是执行,而不是溢出。当两个有符号数的加法/减法不适合类型的位数大小 -1(减号位)时,就会发生溢出。例如,如果一个整数类型有 32 位,那么 添加 2147483647 (0x7FFFFFFF) 和 1 得到 -2 (0x80000000)。

因此,结果适合 32 位,并且没有进位。真正的结果应该是 2147483648,但这不适合 31 位。 Cpu 不知道有符号/无符号值,所以它只是将位相加,其中 0x7FFFFFFF + 1 = 0x80000000。所以第 31 位的进位被添加到第 32 位 (1 + 0 = 1),这实际上是一个符号位,将结果从 + 更改为 -。

由于符号改变,CPU会将溢出标志设置为1并将进位标志设置为0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    相关资源
    最近更新 更多