plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

mpright.c (884B)


      1 #include "os.h"
      2 #include <mp.h>
      3 #include "dat.h"
      4 
      5 /* res = b >> shift */
      6 void
      7 mpright(mpint *b, int shift, mpint *res)
      8 {
      9 	int d, l, r, i;
     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 right shift is a left shift */
     19 	if(shift < 0){
     20 		mpleft(b, -shift, res);
     21 		return;
     22 	}
     23 
     24 	if(res != b)
     25 		mpbits(res, b->top*Dbits - shift);
     26 	d = shift/Dbits;
     27 	r = shift - d*Dbits;
     28 	l = Dbits - r;
     29 
     30 	/*  shift all the bits out == zero */
     31 	if(d>=b->top){
     32 		res->top = 0;
     33 		return;
     34 	}
     35 
     36 	/* special case digit shifts */
     37 	if(r == 0){
     38 		for(i = 0; i < b->top-d; i++)
     39 			res->p[i] = b->p[i+d];
     40 	} else {
     41 		last = b->p[d];
     42 		for(i = 0; i < b->top-d-1; i++){
     43 			this = b->p[i+d+1];
     44 			res->p[i] = (this<<l) | (last>>r);
     45 			last = this;
     46 		}
     47 		res->p[i++] = last>>r;
     48 	}
     49 	while(i > 0 && res->p[i-1] == 0)
     50 		i--;
     51 	res->top = i;
     52 	if(i==0)
     53 		res->sign = 1;
     54 }