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

问题描述 投票:0回答:2

这是我的实现,用于检测尝试添加两个数字时是否发生无符号整数溢出。

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

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

这似乎符合我尝试过的值。

有无流氓案件吗?您认为优点和缺点是什么?

c unsigned integer-overflow unsigned-integer
2个回答
16
投票

你可以使用

if((a + b) < a)

重点是,如果

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

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

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


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.