无符号整数溢出

21

当我溢出unsigned int时,它会包含什么?具体而言,我想使用两个unsigned int进行乘法运算:在乘法完成后,unsigned int中会有什么?

unsigned int someint = 253473829*13482018273;

这似乎是 https://dev59.com/3nVC5IYBdhLWcg3wvTxa 的重复。 - Niklas B.
2
为什么不试一下,看看你会得到什么?通常情况下,当无符号整数溢出时,它会回滚到零。因此,UINT_MAX + 5会回滚并变成4。 - Some programmer dude
这将是最大无符号整数值与溢出值之间的差异。让我们简单点说吧。假设最大无符号整数为5。您想要加上2 * 4,这将使最终值为3而不是8。 - Security Hound
https://dev59.com/GXNA5IYBdhLWcg3wX8rk - Stefan Birladeanu
3个回答

29

unsigned数字不会溢出,而是利用取模的性质来完成环绕。

例如,当unsigned int为32位时,结果将是:(a * b) mod 2^32


正如CharlesBailey所指出的那样,253473829*13482018273 在进行转换之前可能会使用有符号乘法,因此在乘法之前应该明确使用unsigned

unsigned int someint = 253473829U * 13482018273U;

2
@Zhenya 是的,在C和C++中都是这样。 - Pubby
2
@Ramhound:当然很重要。如果标准没有定义这种行为(就像对于有符号整数类型没有定义一样),那么你就不能依赖它。 - Mike Seymour
1
@Mr.Anubis:不,只有无符号整数类型。有符号和浮点数溢出会导致未定义的行为。 - Mike Seymour
2
这个答案不一定相关。根据编译器的限制,表达式 253473829*13482018273 可能使用有符号整数算术,在结果转换为 unsigned int 之前可能会溢出。 - CB Bailey
1
@CharlesBailey:问题是关于两个“unsigned int”相乘,即使示例代码显示其他内容。 - Mike Seymour
显示剩余6条评论

7

无符号整数溢出与其有符号对应相比,表现出良好的行为。

值基本上会“环绕”回来。它通常用于倒计数、哈希/模函数中,非常安全且常用。


2
我的意思是将其作为比较,试图通过将其与类似的东西联系起来来解释它。稍后我用“环绕位”来限定我的陈述。啊,技术细节。 - evandrix

-3

这可能有点取决于你的编译器。我多年前就遇到了这样的错误,有时你会得到运行时错误,其他时候它会基本上“回卷”到一个非常小的数字,这是由于截去最高位比特并留下余数造成的。例如,如果它是32位无符号整数,而您的乘法结果将是34位数字,则会截去高阶2位并给您余数。您可能需要在您的编译器上尝试一下才能确定具体情况,这可能与使用不同编译器时得到的情况不同,特别是如果溢出发生在表达式的中间,而最终结果在无符号整数范围内。


“Unsigned” 溢出不依赖于编译器,其标准化的语义是环绕。只有 “signed” 溢出会导致未定义的值,并且可能因此而依赖于编译器。 - cmaster - reinstate monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接