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 }