I have been thinking about integer (type int) overflows, and it occurs to me that division could overflow.
Example: On my curr
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;
}
1) Just as for any other operation in C, the application has to ensure that:
The way to ensure this is to set size limits of each operand before the operation. What limits that are suitable depends on the algorithm and the purpose of the variables.
2) If you use stdint.h of the C standard, you get guarantees of how big the variables are, portably. You should never use int
when writing portable code.
As for the case of writing a safe division routine, it would take 32 bit integers as parameters, then perform the calculation on 64 bit integers and return the result as a 32 bit integer.
#include <stdint.h>
#include <stdbool.h>
/*
Try to divide integer op1 by op2.
Return
true (success) or
false (possibly overflow prevented).
In case of success, write the quotient to res.
In case of failure, res remains untouched.
*/
bool safe_int_div (int32_t* res, int32_t op1, int32_t op2) {
if(op2 == 0)
return false;
int64_t res64 = (int64_t)op1 / (int64_t)op2;
if(res64 > INT32_MAX || res64 < INT32_MIN)
return false;
*res = (int32_t)res64_t;
return true;
}
If further information of why the division failed is desired, replace the bool with an enum.