3

I'm trying to calculate the cumulative binomial probability of 'n' trials, with 'p' probability and 'r' as the successful outcome of each trial. I have written the following code that works sometimes, but not always:

Console.WriteLine (); Console.WriteLine ("B~(n, p)"); incorrectN: Console.WriteLine ("Enter value of 'n': "); int n = Convert.ToInt32 (Console.ReadLine ()); if (n < 0) { Console.WriteLine ("ERROR: 'n' must be greater than 0"); goto incorrectN; } incorrectP: Console.WriteLine (); Console.WriteLine ("Enter value of 'p': "); double p = Convert.ToDouble (Console.ReadLine ()); if (p > 1) { Console.WriteLine (); Console.WriteLine ("ERROR: 'p' must be between 0 and 1"); goto incorrectP; } Console.WriteLine (); incorrectS: int r = GetR(); int k = r; double binomTotal = 0; for (int j = r + 1; j > 0; j--) { int nCr = Factorial(n) / (Factorial(n - (r - k)) * Factorial(r - k)); binomTotal = binomTotal + nCr * Math.Pow(p, (r - k)) * Math.Pow(1 - p, (n - (r - k))); k--; } Console.WriteLine(); Console.WriteLine(binomTotal); 

P.S. I have written the GetR() and Factorial() functions elsewhere within the class, where GetR() asks the user for the value of 'r' and Factorial() is defined as follows:

public static int Factorial(int x) { return x <= 1 ? 1 : x * Factorial(x - 1); } 

I tested the code with values n = 10, p = 0.5 and r = 5 and the output is 0.623046875, which is correct. However, when I use n = 13, p = 0.35 and r = 7, I get 0.297403640622647 instead of 0.9538.

Any help would be much appreciated.

6
  • 3
    Where does n come from? Please post actual, tested and compiling code. Commented Feb 16, 2015 at 13:08
  • 4
    No related but ... don't use goto or the .Net evil will eat your soul on an infinite agony ... :) Commented Feb 16, 2015 at 13:16
  • 5
    Factorial(13) = 6227020800 > Int32.MaxValue = 2147483647 :) Change the return type of the factorial method to long. Commented Feb 16, 2015 at 13:17
  • 2
    It'd make sense to use double for factorials here, since the answer needn't be exact. Commented Feb 16, 2015 at 13:19
  • Would help if you gave links to some definitions as well, and maybe a brief explanation of what is possible to explain in plain English as well Commented Feb 16, 2015 at 13:22

2 Answers 2

2

In addition to your own answer:

public static double Factorial(double x) { return x <= 1 ? 1 : x * Factorial(x - 1); } 

accepts a double parameter, which means that x is not restricted to be an integer. So you could call your Factorial method like this.

var fac1 = Factorial(1.4); var fac2 = Factorial(2.7); 

However, this does not make sense since the factorial n! is defined only* for n, meaning that 1.7! is undefined.

So, instead of using double and allowing for invalid inputs, you should be using long instead, which has a greater range than int.

public static long Factorial(long x) { return x <= 1 ? 1 : x * Factorial(x - 1); } 

* there are some cases where factorials can be used with real values as well - e.g. by using the gamma function - but I don't think they're relevant to your use case and therefore you should not allow invalid parameters.

Sign up to request clarification or add additional context in comments.

Comments

1

Change:

public static int Factorial(int x) { return x <= 1 ? 1 : x * Factorial(x - 1); } 

To:

public static double Factorial(double x) { return x <= 1 ? 1 : x * Factorial(x - 1); } 

Because Factorial(13) is too large for Int32.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.