0

I have a code which calculate binomial coefficient, but when number is bigger then 20, it start to calculate wrong, where is the problem? Thanks

#include <iostream>
using namespace std;

long int bin(long int x)
{
    if(x==0)
        return 1;
    long int r = x;
    for(int i = r-1;i>0;i--)
    {
        r = r*i;
    }
    return r;
}
int main()
{
    cout << "Write n and k: " << endl;
    long int n=0;
    long int k=0;
    cin >> n;
    cin >> k;
    long int result = 0;
    long int fn = bin(n);
    long int fk = bin(k);
    long int fnk = bin(n-k);


    result = fn/(fk*fnk);

    cout << endl << "C = " << result << endl;


    return 0;
}

for example 12 and 5 = 792 which is correct, but 20 and 4 = -2 which is not correct

user1751550
  • 85
  • 2
  • 7
  • 2
    You are exceeding the range of `long int` with those factorials; you may get a bit further with the ["alternate definition"](http://en.wikipedia.org/wiki/Binomial_coefficient#Multiplicative_formula) of the binomial coefficient. – Matteo Italia Oct 31 '12 at 11:15

3 Answers3

2

Your bin function computes the factorial. The factorial of 21 doesn't fit in a long.

You're already relying on an implementation detail. long is only required to be 32 bits, but on your system it's 64. If it were only 32, then you'd fail much sooner.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • Ah.. thans, so actually the program is correct but the data types are not large enought. – user1751550 Oct 31 '12 at 11:17
  • Yes, you could use a larger type (which requires a library like GMP) or you could re-write the code to do the multiplications and divisions in a different order so that the intermediate values in your calculation are smaller. – Steve Jessop Oct 31 '12 at 11:20
  • @SteveJessop: true, but won't solve the issue completely, because the central binomial coefficient still grows (almost) exponentially. – Yakov Galka Oct 31 '12 at 11:22
  • @ybungalobill: agreed, changing the order of calculations allows computing some coefficients that the current code can't, but of course still doesn't allow computing arbitrarily large results. The central coefficient grows *actually* exponentially, since the sum of coefficients is `2^n`, there are `n+1` of them, and the largest value in any set is greater than or equal to the mean. – Steve Jessop Oct 31 '12 at 11:24
2

20! = 2432902008176640000, which is far beyond what long int can hold (typically 2147483647). Use double instead.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
2

You are calculating the factorial of n using

bin(n);

You are running past the limit of long when n is >=20.

As @SteveJessop pointed out in the comments, You would overrun the limit even if you used unsigned long long (the longest fixed-point type) which has a range from 0 to 18446744073709551615

You could use an int-array to store your result as detailed here.

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191