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