# Catching an Integer Overflow in a recursive function [C]

 Refresh December 2018 Views 377 time
4

UPDATE:

Thank you for the helpful comments and advice. Using what you guys said, this is what I've come up with:

``````#include <limits.h>
...
else {
int a = binom(n - 1, k - 1);
int b = binom(n - 1, k);
if(a > 0) {
if (b > INT_MAX - a) {          // case 1: integer overflow
printf("int overflow\n");
return;
}
}
else if (b < INT_MIN - a) {         // case 2: integer overflow
printf("int overflow\n");
return;
}
int c = a + b;
return c;
}
``````

I do have another question. In the above code, when I catch the integer overflow I am not returning a value -- it is simply `return;`.

One of the comments below suggested `return -1;`, however this wouldn't work work considering -1 is still a valid integer, correct?

I am not sure what to do since the return type is `int` for my function. Does `return;` work or is there a better way to do it? Also suggested was `exit(1);`, but does that exit the entire program or just the function?

ORIGINAL:

Your function should use integer arithmetic to make sure that the results are exact and also detect any integer overflows caused by exceeding the maximum allowed values.

I am trying to catch an integer overflow when computing binomial coefficients. While a simple concept, what is throwing me off is that this isn't just a one-off addition, it's a recursive algorithm that is constantly performing sums.

This is the function:

``````// recursive function to calculate binomial coefficients
int binom(int n, int k){
if(k == 0){         // base case
return 1;
}
else if (n == 0){
return 0;
}
else{
return binom(n - 1, k - 1) + binom(n - 1, k);  // recursive call

}
}
``````

Under that logic, I assume the catch should be in the recursive call statement. Something like :

`if(binom(n-1, k-1) + binom(n-1,k)) causes overflow, return error, else proceed with binom(n-1, k-1) + binom(n-1,k)`

3

Подпись переполнение не определенно поведение, вы должны проверить переполнение прежде, чем это может случиться.

``````int a, b;
int c;

...

/* Compute a + b and store the result in c */

if (a > 0) {
if (b > INT_MAX - a) {
// a + b overflows (i.e., would be > INT_MAX)
}
} else if (b < INT_MIN - a) {
// a + b overflows (i.e., would be < INT_MIN)
}

c = a + b;
``````

так что для рекурсивной функции:

``````a = binom(n - 1, k - 1);
b = binom(n - 1, k);

// if no overflow
c = a + b;

return c;
``````

В вашем примере, вы должны также проверить `n`и `k`не `== INT_MIN`иначе `- 1`операция будет также переполнение.

0

Несколько предложений:

1) Вы используете целое число; если вы работаете со строго положительными величинами, вы, вероятно, следует использовать неподписанных Int или без знака долго долго. С подписанным междунар, когда происходит арифметическое переполнение она будет переливаться к наибольшему отрицательному числу возможного

2) Компилятор будет определить символ предварительно процессора вдоль линий INT_MAX; Вы, вероятно, может хорошо использовать его, например, что-то вроде этого:

``````#inlcude <stdtypes.h>

uint32_t binom( uint32_t n, uint32_t k ){
// (...)
} else {
int32_t   A = binom( n-1, k-1 )
, B = binom( n-1, k );
if( (double)A + (double)B > INT_MAX ){
// error condition
} else {
retval = A+B;
}
}

return retval;
}
``````
0

Сделайте что-то вроде:

``````long res=(long)binom(n - 1, k - 1) + binom(n - 1, k);
if (res>INT_MAX) {
printf("int overflow\n");
exit(1);
}
return (int)res;
``````

(Если предположить , что `long`больше , чем `int`в вашей системе. Если не так, шире использовать тип)

Edit: если вы не хотите , чтобы `exit`на ошибки, вы должны решить , значение (например, `-1`), для представления ошибки. Кроме того , это лучше (и correcter) вы используете `unsigned`вместо `long`:

``````int a=binom(n - 1, k - 1),b=binom(n - 1, k);
if (a<0 || b<0 || (unsigned)a+(unsigned)b>INT_MAX) return -1;
return a+b;
``````