zrsh.c - 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 … | |
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 } |