检测两个数相加时是否发生无符号整数溢出

Detecting if an unsigned integer overflow has occurred when adding two numbers

这是我的实现,用于检测在尝试添加两个数字时是否发生 unsigned int 溢出。

我的系统上 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;
}

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

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

你可以使用

if((a + b) < a)

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

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

b最多可以是9个。对于满足 a + b >= 10(a + 9) % 10 < a.
的任何值 a 对于 ab 使得 a + b < 10 的任何值,因为 b 不是负数,a + b >= a.

我相信 OP 指的是结转,而不是溢出。当两个有符号数的 addition/subtraction 不适合类型的位数 -1(减号位)时,会发生溢出。例如,如果整数类型有 32 位,则 添加 2147483647 (0x7FFFFFFF) 和 1 给我们 -2 (0x80000000).

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

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