Search code examples
c++ccross-platformstandardsinteger-overflow

Integer division overflows


The Problem

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.


The Questions

So, I have two questions:

  1. What (cross-platform) C code could one write in order to prevent division overflows (for type (signed) int)?

  2. 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;
}

Solution

  • 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.

    Update: 2023: C23 is expected only support two’s complement.

    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;
    }