Overflow in integer arithmetic with C

Overflow in integer arithmetic with C

Overflow

Sometimes, the results of working with integers may go outside the range that can be represented, that is, when the result of operating on two k-bit numbers is a (k+1)-bit result. Static analysis tools such as Polyspace or Sonar may also trigger a warning on an operation or in the worst case, you come upon an error in run time.

Typically, addition and multiplication are the sources of overflow, but it can appear with subtraction and the abs function.

How to overcome the problem

  • Up-casting to a larger size.

The first proposal requires to know the maximum (or minimum) value of the types you are working with. If so, it is possible to do something like this:

#include 


int16_t add_without_overflow(int16_t x, int16_t y)
{
  int32_t z = (int32_t) x + y;
    
  if (z > INT16_MAX)
  {
        z = INT16_MAX;
  }
  else if (z < INT16_MIN)
  {
        z = INT16_MIN;
  }

  return (int16_t) z;
}

This piece of code upcast the addition to larger type size, from int16 to int32, from two k-bit numbers to (k+1)-bit number. Afterward, check for overflow. That is, if your result fits in the k-bit number, you got it.

  • To compare with a well-known domain value

Maybe is not so easy to know the maximum or minimum or a certain type in the target platform. In that case, an easy way to overcome is to check the operands with a maximum or minimum of your specific domain. Suppose that we are operating on two variables which stand for the weight of two loads in grams. But we are guaranteed (by system requirements) that no load can be heavier than 5.000 grams.

It can be just put:

define MAX_LOAD_WEIGHT 5000

int16_t add_without_overflow(int16_t x, int16_t y)
{
  int16_t total = 0;
  
  if (x <= MAX_LOAD_WEIGHT && y <= MAX_LOAD_WEIGHT)
  {
        z = x+y;
  }
   
  return total;
}

Furthermore, that way the correctness of the data is checked.

Nevertheless, this approach have a drawback in my opinion. You need you be very careful with the domain ranges. Imagine that the maximum of the load could be 40,000. An addition of two the heaviest loads (40,000+40,000) results in an overflow.

In my opinion, that would be a valid solution when your domain values are far away from the limits of you type size.

References

Here can be found more precise and detailed explanations:

Understanding and Preventing Overflow

Cathing integer overflows in C

Understanding integer overflow in C/C++

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *