How to check if overflow occured? [duplicate]
Possible Duplicate:
Best way to detect integer overflow in C/C++
This is probably a rookie question, but how can I check some overflow affected the value of my numbers in C. For example, when multiplying integers, and wa开发者_如何学JAVAiting for an integer result, if actual result was bigger than max-integer value, actual result is altered(right?). So how can I tell if something like this occured?
Signed integer overflow is like division by zero - it leads to undefined behaviour, so you have to check if it would occur before executing the potentially-overflowing operation. Once you've overflowed, all bets are off - your code could do anything.
The *_MAX
and _MIN
macros defined in <limits.h>
come in handy for this, but you need to be careful not to invoke undefined behaviour in the tests themselves. For example, to check if a * b
will overflow given int a, b;
, you can use:
if ((b > 0 && a <= INT_MAX / b && a >= INT_MIN / b) ||
(b == 0) ||
(b == -1 && a >= -INT_MAX) ||
(b < -1 && a >= INT_MAX / b && a <= INT_MIN / b))
{
result = a * b;
}
else
{
/* calculation would overflow */
}
(Note that one subtle pitfall this avoids is that you can't calculate INT_MIN / -1
- such a number isn't guaranteed to be representable and indeed causes a fatal trap on common platforms).
The C99 standard has this section explaining what undefined behavior is:
3.4.3
undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
EXAMPLE
An example of undefined behavior is the behavior on integer overflow.
So you're pretty much out of luck, there is no portable way of detecting that in the general case, after the fact.
Your compiler/implementation might have extensions/support for it though, and there are techniques to avoid these situations.
See this question for excellent advice: Best way to detect integer overflow in C/C++.
If you mean while you're programming, you can debug the code.
If you mean in runtime, you can add some conditionals that if it exceeds the limit, do something.
C doesn't know what to do when a calculation's yield would be out of range. You must evade this by testing operands.
Check this http://www.fefe.de/intof.html. It shows you how to check if actual result was bigger than max-integer value.
If the resulting number is smaller than one of the inputs.
a + b = c, if c < a => overflow. edit: to fast, this is only for addition on unsigned integers.
You cannot know, in the general case, if overflow occurred just by staring at the result. What you can do, however, is to check whether the operation would overflow separately. E.g. if you want to check whether a*b overflows, where a and b are int's, you need to solve the inequality
a * b <= INT_MAX
That is, if a <= INT_MAX / b, then the multiplication would overflow.
As long as you do your arithmetic in unsigned integers, or else can rely on implementation-specific guarantees about how signed integer overflow behaves, there are various tricks you can use.
In the case of unsigned multiplication, the simplest is:
unsigned int lhs = something, rhs = something_else;
unsigned int product = lhs * rhs;
if (lhs != 0 && product/lhs != rhs) { overflow occurred }
It's unlikely to be fast, but it's portable. The unsigned overflow check for addition is also quite simple -- pick either one of the operands, then overflow occurred if and only if the sum is less than that.
精彩评论