/* Copyright (C) 1994 by Thomas Glen Smith. All Rights Reserved. */
/* binomp APL2 V1.0.0 **************************************************
* binomial. *
***********************************************************************/
#define INCLUDES 0
#include "includes.h"
void binomp(m,n,ret)
double *m,*n,*ret;
{
Binomp; Factorl; Floor; Mod;
extern int aplerr;
double a,b,c,den,k,num,p,q,r,s;
a = *m; /* Left. */
b = *n; /* Right. */
for(;;) { /* So I can use break. */
if (floor(a) == a && floor(b) == b) { /* a, b are integers */
if (a == b || a == 0e0) {
*ret = 1e0;
break;
}
if (b < 0e0 && a < b) { /* return (-1*b_a)X1!(|a+1) */
p = -(b+1); /* New left = _right+1. */
q = -(a+1); /* New right = -left+1. */
binomp(&p,&q,&r);
s = mod(b - a, 2e0) == 0e0 ? 1e0 : -1e0;
*ret = s * r;
break;
}
if (b >= 0e0)
if (a > b || a < 0e0) {
*ret = 0e0;
break;
}
else;
else if (a < 0e0 && a > b) {
*ret = 0e0;
break;
}
k = b - a;
num = b;
while((b -= 1e0) > k) num *= b;
den = a;
while((a -= 1e0) > 1e0) den *= a;
*ret = num / den;
} else { /* either a or b isn't an integer */
if (b < 0e0 && floor(b) == b /* b is a negative integer */
&& floor(a) != a /* *m is not an integer */) {
aplerr = 40;
*ret = 0e0;
break;
}
*ret = (factorl(b) / (factorl(a) * factorl(b - a)));
}
break;
} /* end for(;;) */
}