diff options
| author | Mattias Andrée <maandree@kth.se> | 2016-03-03 12:47:39 +0100 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2016-03-03 12:47:39 +0100 |
| commit | 3728c12ecbe308092b213f1b664303a48858a2b8 (patch) | |
| tree | b4a42c978eb513605ef58092c84ecbecbff795dd /src/zbset.c | |
| parent | Add zdivmod (diff) | |
| download | libzahl-3728c12ecbe308092b213f1b664303a48858a2b8.tar.gz libzahl-3728c12ecbe308092b213f1b664303a48858a2b8.tar.bz2 libzahl-3728c12ecbe308092b213f1b664303a48858a2b8.tar.xz | |
Add zbset
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/zbset.c')
| -rw-r--r-- | src/zbset.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/zbset.c b/src/zbset.c new file mode 100644 index 0000000..6833e5f --- /dev/null +++ b/src/zbset.c @@ -0,0 +1,48 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + +#include <stdlib.h> +#include <string.h> + + +void +zbset(z_t a, z_t b, size_t bit, int action) +{ + zahl_char_t x = 1; + size_t chars; + + chars = FLOOR_BITS_TO_CHARS(bit); + bit = BITS_IN_LAST_CHAR(bit); + x <<= bit; + + if (a != b) + zset(a, b); + + if (action) { + if (zzero(a)) { + a->used = 0; + SET_SIGNUM(a, 1); + } + if (a->used <= chars) { + if (a->alloced <= chars) { + a->alloced = chars + 1; + a->chars = realloc(a->chars, a->alloced * sizeof(*(a->chars))); + } + memset(a->chars + a->used, 0, (chars - a->used + 1) * sizeof(*(a->chars))); + } + } + + if (action > 0) { + a->chars[chars] |= x; + return; + } else if (action < 0) { + a->chars[chars] ^= x; + } else if (a->used > chars) { + a->chars[chars] &= ~x; + } + + while (a->used && !a->chars[a->used - 1]) + a->used--; + if (!a->used) + SET_SIGNUM(a, 0); +} |
