]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libmp/port/mpleft.c
merge
[plan9front.git] / sys / src / libmp / port / mpleft.c
1 #include "os.h"
2 #include <mp.h>
3 #include "dat.h"
4
5 // res = b << shift
6 void
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 zero or 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         res->flags |= b->flags & MPtimesafe;
50         mpnorm(res);
51 }