-2
#include <iostream>

using namespace std;

int getFectorial(int n)
{
    int ans = 1;
    for (int i = n; i >= 1; i--)
    {
        ans = ans * i;
    }

    return ans;
}

int printNcr(int n, int r)
{
    if (getFectorial(n) > INT_MAX)
    {
        return 0;
    }
    return (getFectorial(n)) / ((getFectorial(r)) * (getFectorial(n - r)));
}

int main()
{
    int n = 14;
    for (int row = 0; row < n; row++)
    {
        for (int col = 0; col < row + 1; col++)
        {
            cout << printNcr(row, col) << " ";
        }

        cout << endl;
    }

    return 0;
}

When I give value of n more than 13th I want integer overflow condition should be working that given in printNcr() function, but it's not working and all line after 13th are printing wrong values instead of returning false.

How to make given INT_MAX condition work?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 11
    by definition an int can never be greater than INT_MAX – pm100 Apr 26 '22 at 18:33
  • its not easy to detect signed overflow, once you overflow the product goes negative, but then it flips positive then negative. You can use unsigned instead but detecting overflow there is a mess too - see https://stackoverflow.com/questions/199333/how-do-i-detect-unsigned-integer-overflow – pm100 Apr 26 '22 at 19:01
  • It is spelled `factorial`. – n. m. could be an AI Apr 26 '22 at 20:25

2 Answers2

2

int oveflow cannot be reliably detected after it happens.

One way to detect upcoming int overflow in factorial:

int getFactorial(int n) {
  if (n <= 0) {
    return 1; // and maybe other code when n < 0
  }
  int limit = INT_MAX/n;
  int ans = 1;
  for (int i = 2; i <= n; i++) {
    if (ans >= limit) {
      return INT_MAX; // Or some other code
    }
    ans = ans * i;
  }
  return ans;
}

Another way is at startup, perform a one-time calculation for maximum n. With common 32-bit int, that limit is 12.

int getFactorial(int n) {
  if (n > getFactorial_pre_calculated_limit) {
    return INT_MAX;
  }
  ...
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

You can detect overflow by watching for negative value

int getFectorial(int n)
{
    int ans = 1;
    for (int i = n; i >= 1; i--)
    {
        ans = ans * i;
        if (ans < 0) <<<<======
            return -1;
    }

    return ans;
}

then

int printNcr(int n, int r)
{
    if (getFectorial(n) < 0)
    {
        return 0;
    }
    return (getFectorial(n)) / ((getFectorial(r)) * (getFectorial(n - r)));
}

Please note though that strictly speaking this is undefined behavior. It would be better to simply fail if you know the result is going to be too big (Ie n > 13)

Or better do it like this

int getFectorial(int n)
{
    long long ans = 1; <<<====
    for (int i = n; i >= 1; i--)
    {
        ans = ans * i;
        if (ans >INT_MAX) <<<<======
            return -1;
    }

    return (int)ans;
}

or you could throw std::overflow_error

BTW the word is factorial not fectorial

pm100
  • 48,078
  • 23
  • 82
  • 145