Commit 4d4f58b5 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder
Browse files

Fix PERMUT.

2002-07-01  Morten Welinder  <terra@diku.dk>

	* src/mathfunc.c (fact): Use table and avoid recursion.
	(permut): New function.
	(combin): Improve precision.
parent 6e01b279
2002-07-01 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (fact): Use table and avoid recursion.
(permut): New function.
(combin): Improve precision.
2002-06-27 Jody Goldberg <jody@gnome.org>
* src/sheet-view.c : move frozen panes here.
......
......@@ -34,6 +34,7 @@ Morten:
* Improve the Applix importer.
* Update mathfunc.c to R 1.5.1.
* Improve precision of HYPGEOMDIST and NEGBINOMDIST.
* Fix PERMUT crash.
Jon Kre:
* Use GsfInput in the Python plugin loader
......
2002-07-01 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (fact): Use table and avoid recursion.
(permut): New function.
(combin): Improve precision.
2002-06-27 Jody Goldberg <jody@gnome.org>
* src/sheet-view.c : move frozen panes here.
......
2002-07-01 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (fact): Use table and avoid recursion.
(permut): New function.
(combin): Improve precision.
2002-06-27 Jody Goldberg <jody@gnome.org>
* src/sheet-view.c : move frozen panes here.
......
2002-07-01 Morten Welinder <terra@diku.dk>
* functions.c (gnumeric_permut): Use permut function.
2002-06-21 Morten Welinder <terra@diku.dk>
* functions.c (gnumeric_negbinomdist): Use R's distribution
......
......@@ -1807,7 +1807,7 @@ gnumeric_permut (FunctionEvalInfo *ei, Value **argv)
k = value_get_as_int (argv[1]);
if (0 <= k && k <= n)
return value_new_float (fact (n) / fact (n - k));
return value_new_float (permut (n, k));
else
return value_new_error (ei->pos, gnumeric_err_NUM);
}
......
......@@ -4457,10 +4457,7 @@ int
gcd (int a, int b)
{
while (b != 0) {
int r;
r = a - (a / b) * b; /* r = remainder from
* dividing a by b */
int r = a % b;
a = b;
b = r;
}
......@@ -4472,24 +4469,42 @@ gnum_float
combin (int n, int k)
{
if (n >= 15) {
gnum_float res;
res = expgnum (lgamma (n + 1) - lgamma (k + 1) - lgamma (n - k + 1));
return floor (res + 0.5); /* Round, just in case. */
return floorgnum (0.5 + expgnum (lgamma (n + 1) - lgamma (k + 1) - lgamma (n - k + 1)));
} else {
gnum_float res;
return fact (n) / fact (k) / fact (n - k);
}
}
res = fact (n) / fact (k) / fact (n - k);
return res;
gnum_float
permut (int n, int k)
{
if (n >= 15) {
return floorgnum (0.5 + expgnum (lgamma (n + 1) - lgamma (n - k + 1)));
} else {
return fact (n) / fact (n - k);
}
}
gnum_float
fact (int n)
{
if (n == 0)
return 1;
return (n * fact (n - 1));
static gnum_float table[100];
static gboolean init = FALSE;
if (n < 0)
return ML_NAN;
if (n < (int)G_N_ELEMENTS (table)) {
if (!init) {
int i;
table[0] = 1;
for (i = 1; i < (int)G_N_ELEMENTS (table); i++)
table[i] = table[i - 1] * i;
init = TRUE;
}
return table[n];
} else
return floorgnum (0.5 + expgnum (lgamma (n + 1)));
}
/*
......
......@@ -127,6 +127,7 @@ gnum_float gpow10 (int n);
gnum_float gpow2 (int n);
int gcd (int a, int b);
gnum_float combin (int n, int k);
gnum_float permut (int n, int k);
gnum_float fact (int n);
/* ------------------------------------------------------------------------- */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment