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