xref: /plan9/sys/src/libmp/port/mpleft.c (revision dc5a79c1208f0704eeb474acc990728f8b4854f5)
1 #include "os.h"
2 #include <mp.h>
3 #include "dat.h"
4 
5 // res = b << shift
6 void
mpleft(mpint * b,int shift,mpint * res)7 mpleft(mpint *b, int shift, mpint *res)
8 {
9 	int d, l, r, i, otop;
10 	mpdigit this, last;
11 
12 	res->sign = b->sign;
13 	if(b->top==0){
14 		res->top = 0;
15 		return;
16 	}
17 
18 	// a negative left shift is a right shift
19 	if(shift < 0){
20 		mpright(b, -shift, res);
21 		return;
22 	}
23 
24 	// b and res may be the same so remember the old top
25 	otop = b->top;
26 
27 	// shift
28 	mpbits(res, otop*Dbits + shift);	// overkill
29 	res->top = DIGITS(otop*Dbits + shift);
30 	d = shift/Dbits;
31 	l = shift - d*Dbits;
32 	r = Dbits - l;
33 
34 	if(l == 0){
35 		for(i = otop-1; i >= 0; i--)
36 			res->p[i+d] = b->p[i];
37 	} else {
38 		last = 0;
39 		for(i = otop-1; i >= 0; i--) {
40 			this = b->p[i];
41 			res->p[i+d+1] = (last<<l) | (this>>r);
42 			last = this;
43 		}
44 		res->p[d] = last<<l;
45 	}
46 	for(i = 0; i < d; i++)
47 		res->p[i] = 0;
48 
49 	// normalize
50 	while(res->top > 0 && res->p[res->top-1] == 0)
51 		res->top--;
52 }
53