Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 674
Anon Avatar asked May 22 '15 10:05

Anon


People also ask

How do I fix integer overflow?

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.

What happens if integer overflow?

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

How do you calculate integer overflow?

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.

What is the integer overflow number?

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.


1 Answers

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;
}
like image 140
chux - Reinstate Monica Avatar answered Sep 18 '22 16:09

chux - Reinstate Monica