Suppose I have declared following variables :
some_dataType a,b,c; //a,b,c are positive
int res;
res=a+b-c;
And I have been provided with the information that the variable res
cannot cross integer limit. Just to avoid overflow from the expression a+b
in a+b-c
I have following options-
- declare a,b,c as long int
(a-c)
+b(long int)
(a+b-c) //or some other type casting
My question is which of the above is good practice. Also, just to escape from all this, I prefer doing option 1. But it may increase the memory size of the program (not for this program though, but for large applications).
Assumption : long int is greater than int Thanks @Retired Ninja
Answer
There's no simple, general, portable way to avoid integer overflow.
Using a wider integer type is not a general solution, because there's no guarantee that there is a wider integer type. It's very common for the types int
and long
to be the same size on some systems. 32-bit systems typically make both int
and long
32 bits; even some 64-bit systems do the same thing. And some 64-bit systems make both int
and long
64 bits.
You wrote:
And I have been provided with the information that the variable
res
cannot cross integer limit.
It's best to be careful with terminology. Although the type name int
is obviously an abbreviation of the word "integer", the words are not synonymous. In C and C++, int
is just one of several integer types; others include unsigned char
and long long
.
Presumably what you mean is that the value of res
must not be outside the range of type int
, which is INT_MIN
to INT_MAX
.
If you use long long
for the result, it's likely that you can avoid overflow; you can then compare the result to the values INT_MIN
and INT_MAX
, and take whatever corrective action is appropriate if it's out of range. But it's still possible for both int
and long long
to be 64 bits. What you do with that depends on how portable your code needs to be.
You cannot safely check whether a signed integer addition or subtraction overflowed after the fact. An overflow in signed arithmetic causes undefined behavior. Typically the result wraps around, but in principle your program could crash before you have a chance to examine the result.
Some compilers might provide functions that perform safe signed arithmetic and tell you whether there was an overflow. Consult your compiler's documentation.
There are ways to test the operands before performing the operation. They're complicated, and I'm too lazy to work out the details, but briefly:
- If the operands of
+
are of opposite signs, or if one operand is0
, the addition is safe. - If both operands are positive, the addition is safe if
x
does not exceedINT_MAX - y
. - If both operands are negative, the addition is safe if
y
is no less thanINT_MIN - y
.
I do not guarantee that the above is completely correct *I just wrote it off the top of my head), but in most cases it's probably more effort than it's worth.
No comments:
Post a Comment