Overflow
Sometimes, the results of working with integers may go outside the range that can be represented, that is
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:
#includeint16_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
- 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
In my opinion, that would be a valid solution when your domain values are far away from the limits of
References
Here can be found more precise and detailed explanations:
Understanding and Preventing Overflow