xref: /plan9/sys/src/cmd/unix/drawterm/libmp/mpdigdiv.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include "os.h"
2*8ccd4a63SDavid du Colombier #include <mp.h>
3*8ccd4a63SDavid du Colombier #include "dat.h"
4*8ccd4a63SDavid du Colombier 
5*8ccd4a63SDavid du Colombier //
6*8ccd4a63SDavid du Colombier //	divide two digits by one and return quotient
7*8ccd4a63SDavid du Colombier //
8*8ccd4a63SDavid du Colombier void
mpdigdiv(mpdigit * dividend,mpdigit divisor,mpdigit * quotient)9*8ccd4a63SDavid du Colombier mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient)
10*8ccd4a63SDavid du Colombier {
11*8ccd4a63SDavid du Colombier 	mpdigit hi, lo, q, x, y;
12*8ccd4a63SDavid du Colombier 	int i;
13*8ccd4a63SDavid du Colombier 
14*8ccd4a63SDavid du Colombier 	hi = dividend[1];
15*8ccd4a63SDavid du Colombier 	lo = dividend[0];
16*8ccd4a63SDavid du Colombier 
17*8ccd4a63SDavid du Colombier 	// return highest digit value if the result >= 2**32
18*8ccd4a63SDavid du Colombier 	if(hi >= divisor || divisor == 0){
19*8ccd4a63SDavid du Colombier 		divisor = 0;
20*8ccd4a63SDavid du Colombier 		*quotient = ~divisor;
21*8ccd4a63SDavid du Colombier 		return;
22*8ccd4a63SDavid du Colombier 	}
23*8ccd4a63SDavid du Colombier 
24*8ccd4a63SDavid du Colombier 	// at this point we know that hi < divisor
25*8ccd4a63SDavid du Colombier 	// just shift and subtract till we're done
26*8ccd4a63SDavid du Colombier 	q = 0;
27*8ccd4a63SDavid du Colombier 	x = divisor;
28*8ccd4a63SDavid du Colombier 	for(i = Dbits-1; hi > 0 && i >= 0; i--){
29*8ccd4a63SDavid du Colombier 		x >>= 1;
30*8ccd4a63SDavid du Colombier 		if(x > hi)
31*8ccd4a63SDavid du Colombier 			continue;
32*8ccd4a63SDavid du Colombier 		y = divisor<<i;
33*8ccd4a63SDavid du Colombier 		if(x == hi && y > lo)
34*8ccd4a63SDavid du Colombier 			continue;
35*8ccd4a63SDavid du Colombier 		if(y > lo)
36*8ccd4a63SDavid du Colombier 			hi--;
37*8ccd4a63SDavid du Colombier 		lo -= y;
38*8ccd4a63SDavid du Colombier 		hi -= x;
39*8ccd4a63SDavid du Colombier 		q |= 1<<i;
40*8ccd4a63SDavid du Colombier 	}
41*8ccd4a63SDavid du Colombier 	q += lo/divisor;
42*8ccd4a63SDavid du Colombier 	*quotient = q;
43*8ccd4a63SDavid du Colombier }
44