Sunday, 23 July 2017

c++ - Is it a good practice to use long int to avoid overflow?



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-





  1. declare a,b,c as long int

  2. (a-c)+b

  3. (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 is 0, the addition is safe.

  • If both operands are positive, the addition is safe if x does not exceed INT_MAX - y.

  • If both operands are negative, the addition is safe if y is no less than INT_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

casting - Why wasn't Tobey Maguire in The Amazing Spider-Man? - Movies & TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...