C中两个带符号的32位数字相减时如何检测溢出?
我有两个有符号整数,我想将它们相减。我需要知道它是否溢出了。
int one;
int two;
int result = two - one;
if (OVERFLOW) {
printf("overflow");
} else {
printf("no overflow");
}
类似的事情。有没有好的方法可以做到这一点?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,有符号计算中的溢出会导致 C 中未定义的行为。
其次,暂时忘记 UB 并坚持 2 补码机的典型溢出行为:溢出是通过结果“移动”到“错误方向”的事实来揭示的从第一个操作数开始,即当结果大于第一个操作数且第二个操作数为正时(或小于第一个操作数且第二个操作数为负)。
在你的情况下
Firstly, overflow in signed calculations causes undefined behavior in C.
Secondly, forgetting about UB for a second and sticking to the typical overflow behavior of a 2's complement machine: overflow is revealed by the fact that result "moves" in the "wrong direction" from the first operand, i.e when the result ends up greater than the first operand with positive second operand (or smaller than the first operand with negative second operand).
In your case
评估
ab
时需要考虑两种情况:ab
可能下溢,当且仅当b>0 && a<0
和ab < min == a
ab
可能会溢出,当且仅当b<0 && a>0
和ab> max == -b>max-a
这导致我们将
a
情况简化为There are 2 cases to consider on evaluating
a-b
:a-b
may underflow, iffb>0 && a<0
anda-b < min == a<min+b
a-b
may overflow, iffb<0 && a>0
anda-b > max == -b>max-a
This leads us on simplifying the
a
case to您可以以更高的精度进行比较。假设您有 32 位整数。您可以将它们提升为 64 位整数,进行减法,然后将该结果与其本身转换为 32 位,然后再次转换为 64 位进行比较。
我不会用
int
这样做,因为该语言不能保证大小......也许int32_t
和int64_t
来自
(来自 C99)。如果您使用的是 Windows,可以使用
ULongSub ()
等,溢出时返回错误代码。You can do it with higher precision and compare. Say you have 32-bit integers. You can promote them to 64-bit integers, subtract, then compare that result with itself cast to 32-bit and then up again to 64 bits.
I wouldn't do it this way with
int
, because the language doesn't give you guarantees on sizes... Maybeint32_t
andint64_t
from<inttypes.h>
(from C99).If you're on Windows use can use
ULongSub()
etc, which returns an error code on overflow.https://llvm.org/doxygen/MathExtras_8h_source.html
https://llvm.org/doxygen/MathExtras_8h_source.html
您需要在溢出(或下溢)发生之前捕获它。一旦发生这种情况,您就处于未定义行为境地,所有的赌注都会被取消。
You need to catch the overlow (or underflow) before it happens. Once it happens you're in Undefined Behaviour land and all bets are off.