libzahl

big integer library
git clone git://git.suckless.org/libzahl
Log | Files | Refs | README | LICENSE

zrsh.c (906B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include "internals.h"
      3 
      4 
      5 void
      6 zrsh(z_t a, z_t b, size_t bits)
      7 {
      8 	size_t i, chars, cbits;
      9 
     10 	if (unlikely(!bits)) {
     11 		SET(a, b);
     12 		return;
     13 	}
     14 
     15 	chars = FLOOR_BITS_TO_CHARS(bits);
     16 
     17 	if (unlikely(zzero(b) || chars >= b->used || zbits(b) <= bits)) {
     18 		SET_SIGNUM(a, 0);
     19 		return;
     20 	}
     21 
     22 	bits = BITS_IN_LAST_CHAR(bits);
     23 	cbits = BITS_PER_CHAR - bits;
     24 
     25 	if (likely(chars) && likely(a == b)) {
     26 		a->used -= chars;
     27 		zmemmove(a->chars, a->chars + chars, a->used);
     28 	} else if (unlikely(a != b)) {
     29 		a->used = b->used - chars;
     30 		ENSURE_SIZE(a, a->used);
     31 		zmemcpy(a->chars, b->chars + chars, a->used);
     32 	}
     33 
     34 	if (unlikely(bits)) { /* This if statement is very important in C. */
     35 		a->chars[0] >>= bits;
     36 		for (i = 1; i < a->used; i++) {
     37 			a->chars[i - 1] |= a->chars[i] << cbits;
     38 			a->chars[i] >>= bits;
     39 		}
     40 		TRIM_NONZERO(a);
     41 	}
     42 
     43 	SET_SIGNUM(a, zsignum(b));
     44 }