T.Setso - 11 months ago 85

C Question

i posted this before, user told me to post it on codereview. i did, and they closed it...so one more time here: (i deleted the old question)

I have these formulas:

http://i.stack.imgur.com/nZzLd.png

and I need the Poisson formulas for the erlangC formula:

http://www.mitan.co.uk/erlang/elgcpois.gif

I tried to rebuild the formulas in C:

`double getPoisson(double m, double u, bool cumu)`

{

double ret = 0;

if(!cumu)

{

ret = (exp(-u)*pow(u,m)) / (factorial(m));

}

else

{

double facto = 1;

double ehu = exp(-u);

for(int i = 0; i < m; i++)

{

ret = ret + (ehu * pow(u,i)) / facto;

facto *= (i+1);

}

}

return ret;

}

The Erlang C Formula:

`double getErlangC(double m, double u, double p)`

{

double numerator = getPoisson(m, u, false);

double denominator = getPoisson(m, u, false) + (1-p) * getPoisson(m, u, true);

return numerator/denominator;

}

The main problem is, the

`m`

`getPoisson`

so it wants to calculate >170! but it cannot handle it. I think the primitive data types are too small to work correctly, or what do you say?

BTW: This is the factorial function I use for the first Poisson:

`double factorial(double n)`

{

if(n >= 1)

return n*factorial(n-1);

else

return 1;

}

Some samples:

Input:

`double l = getErlangC(50, 48, 0.96);`

printf("%g", l);

Output:

`0.694456 (correct)`

Input:

`double l = getErlangC(100, 96, 0.96);`

printf("%g", l);

Output:

`0.5872811 (correct)`

if i use a value higher than 170 for the first parameter (m) of getErlangC like:

Input:

`double l = getErlangC(500, 487, 0.974);`

printf("%g", l);

Output:

`naN (incorrect)`

Excepted:

`0.45269`

How's my approach? Would be there a better way to calculate Poisson and erlangC?

Some Info: Excel has the POISSON Function, and on Excel it works perfekt... would there be a way to see the algorithm(code) EXCEL uses for POISSON?

Answer Source

`(pow(u, m)/factorial(m))`

can be expressed as a recursive loop with each element shown as u/n where each n is an element of m!.

```
double ratio(double u, int n)
{
if(n > 0)
{
// Avoid the ratio overflow by calculating each ratio element
double val;
val = u/n;
return val*ratio(u, n-1);
}
else
{
// Avoid division by 0 as power and factorial of 0 are 1
return 1;
}
}
```

Note that if you want to avoid recursion, you can do it as a loop as well

```
double ratio(double u, int n)
{
int i;
// Avoid the ratio overflow by calculating each ratio element
// default the ratio to 1 for n == 0
double val = 1;
// calculate the next n-1 ratios and put them into the total
for (i = 1; i<=n; i++)
{
// Put in the next element of the ratio
val *= u/n;
}
// return the final value of the ratio
return val;
}
```