summaryrefslogtreecommitdiffstats
path: root/arith.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-01-11 23:09:22 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-01-11 23:09:22 -0800
commitfc14a0592d94b1dbb502afe298a67b9b544559af (patch)
treeb7be35c9a1ec5f1dddcc14e668a030024d1198dc /arith.c
parentc1535145101cf8758f3716c2e4fd3ddaa722f21c (diff)
downloadtxr-fc14a0592d94b1dbb502afe298a67b9b544559af.tar.gz
txr-fc14a0592d94b1dbb502afe298a67b9b544559af.tar.bz2
txr-fc14a0592d94b1dbb502afe298a67b9b544559af.zip
* arith.c (rising_product): New static function.
(n_choose_k, n_perm_k): New functions. * arith.h (n_choose_k, n_perm_k): Declared. * eval.c (eval_init): New functions interned. * txr.1: Documented.
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/arith.c b/arith.c
index 445cebda..18a5fc37 100644
--- a/arith.c
+++ b/arith.c
@@ -1869,6 +1869,43 @@ val cum_norm_dist(val arg)
}
}
+static val rising_product(val m, val n)
+{
+ val acc;
+
+ if (lt(n, one))
+ return one;
+
+ if (ge(m, n))
+ return one;
+
+ if (lt(m, one))
+ m = one;
+
+ acc = m;
+
+ m = plus(m, one);
+
+ while (le(m, n)) {
+ acc = mul(acc, m);
+ m = plus(m, one);
+ }
+
+ return acc;
+}
+
+val n_choose_k(val n, val k)
+{
+ val top = rising_product(plus(minus(n, k), one), n);
+ val bottom = rising_product(one, k);
+ return trunc(top, bottom);
+}
+
+val n_perm_k(val n, val k)
+{
+ return rising_product(plus(minus(n, k), one), n);
+}
+
void arith_init(void)
{
mp_init(&NUM_MAX_MP);