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