I have been thinking about integer (type int) overflows, and it occurs to me that division could overflow.
Example: On my current platform, I have
INT_MIN == -INT_MAX - 1
and thus
INT_MIN < -INT_MAX
and thus
INT_MIN / -1 > -INT_MAX / -1
and thus
INT_MIN / -1 > INT_MAX.
Hence, the division ( INT_MIN / -1 ) does overflow.
So, I have two questions:
What (cross-platform) C code could one write in order to prevent division overflows (for type (signed) int)?
What guarantees (in C or C++ standard) might help to devise the code?
For example, if the standard guarantees that we have either
INT_MIN == -INT_MAX - 1
or
INT_MIN == -INT_MAX,
then the following code appears to prevent overflows.
#include <limits.h>
/*
Try to divide integer op1 by op2.
Return
0 (success) or
1 (possibly overflow prevented).
In case of success, write the quotient to res.
*/
int safe_int_div(int * res, int op1, int op2) {
/* assert(res != NULL); */
/* assert(op2 != 0); */
if ( op1 == INT_MIN && op2 == -1 ) {
return 1;
}
*res = op1 / op2;
return 0;
}
In languages where integer overflow can occur, you can reduce its likelihood by using larger integer types, like Java's long or C's long long int. If you need to store something even bigger, there are libraries built to handle arbitrarily large numbers.
An integer overflow can cause the value to wrap and become negative, which violates the program's assumption and may lead to unexpected behavior (for example, 8-bit integer addition of 127 + 1 results in −128, a two's complement of 128).
Write a “C” function, int addOvf(int* result, int a, int b) If there is no overflow, the function places the resultant = sum a+b in “result” and returns 0. Otherwise it returns -1. The solution of casting to long and adding to find detecting the overflow is not allowed.
For example, if an integer data type allows integers up to two bytes or 16 bits in length (or an unsigned number up to decimal 65,535), and two integers are to be added together that will exceed the value of 65,535, the result will be integer overflow.
What guarantees (in C or C++ standard) might help to devise the code?
C specifies signed integer representation as using 1 of 3 forms: sign and magnitude, two’s complement, or ones’ complement. Given these forms, only division by 0 and two’s complement division of INT_MIN/-1
may overflow.
What (cross-platform) C code could one write in order to prevent division overflows (for type (signed) int)?
int safe_int_div(int * res, int op1, int op2) {
if (op2 == 0) {
return 1;
}
// 2's complement detection
#if (INT_MIN != -INT_MAX)
if (op1 == INT_MIN && op2 == -1) {
return 1;
}
#endif
*res = op1 / op2;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With