diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zand.c | 42 | ||||
| -rw-r--r-- | src/zbtest.c | 18 | ||||
| -rw-r--r-- | src/znot.c | 30 | ||||
| -rw-r--r-- | src/zor.c | 51 | ||||
| -rw-r--r-- | src/zsplit.c | 31 | ||||
| -rw-r--r-- | src/ztrunc.c | 31 | ||||
| -rw-r--r-- | src/zxor.c | 56 |
7 files changed, 259 insertions, 0 deletions
diff --git a/src/zand.c b/src/zand.c new file mode 100644 index 0000000..3156857 --- /dev/null +++ b/src/zand.c @@ -0,0 +1,42 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + +#include <string.h> + + +void +zand(z_t a, z_t b, z_t c) +{ + size_t n; + + if (zzero(b) || zzero(c)) { + SET_SIGNUM(a, 0); + return; + } + + n = b->used < c->used ? b->used : c->used; + while (n--) + if (b->chars[n] & c->chars[n]) + goto found_highest; + SET_SIGNUM(a, 0); + return; + +found_highest: + a->used = ++n; + if (a == b) { + while (n--) + a->chars[n] &= c->chars[n]; + } else if (a == c) { + while (n--) + a->chars[n] &= b->chars[n]; + } else { + if (a->alloced < a->used) { + a->alloced = a->used; + a->chars = realloc(a->chars, a->used * sizeof(*(a->chars))); + } + memcpy(a->chars, c->chars, a->used * sizeof(*(a->chars))); + while (n--) + a->chars[n] &= b->chars[n]; + } + SET_SIGNUM(a, (zsignum(b) > 0 || zsignum(c) > 0) * 2 - 1); +} diff --git a/src/zbtest.c b/src/zbtest.c new file mode 100644 index 0000000..8e9f8ff --- /dev/null +++ b/src/zbtest.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +int +zbtest(z_t a, size_t bit) +{ + size_t chars; + if (zzero(a)) + return 0; + + chars = bit >> LB_BITS_PER_CHAR; + if (chars >= a->used) + return 0; + + bit &= BITS_PER_CHAR - 1; + return (a->chars[chars] >> bit) & 1; +} diff --git a/src/znot.c b/src/znot.c new file mode 100644 index 0000000..7f2f021 --- /dev/null +++ b/src/znot.c @@ -0,0 +1,30 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +void +znot(z_t a, z_t b) +{ + size_t bits, n; + + if (zzero(b)) { + SET_SIGNUM(a, 0) + return; + } + + bits = zbits(b); + if (a != b) + zset(a, b); + SET_SIGNUM(a, -zsignum(a)); + + for (n = a->used; n--;) + a->chars[n] = ~(a->chars[n]); + bits &= BITS_PER_CHAR - 1; + a->chars[a->used - 1] &= ((zahl_char_t)1 << bits) - 1; + + while (; a->used; a->used--) + if (a->chars[a->used - 1]) + break; + if (!a->used) + SET_SIGNUM(a, 0); +} diff --git a/src/zor.c b/src/zor.c new file mode 100644 index 0000000..0f17f8d --- /dev/null +++ b/src/zor.c @@ -0,0 +1,51 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +void +zor(z_t a, z_t b, z_t c) +{ + size_t n, m; + + if (zzero(b)) { + if (zzero(c)) { + SET_SIGNUM(a, 0); + } else { + if (a != c) + zset(a, c); + } + return; + } else if (zzero(c)) { + if (a != b) + zset(a, b); + return; + } + + m = b->used > c->used ? b->used : c->used; + n = b->used + c->used - m; + + if (a->alloced < m) { + a->alloced = m; + a->chars = realloc(a->chars, m * sizeof(*(a->chars))); + } + + if (a == b) { + memcpy(a->chars + n, m == b->used ? b->chars : c->chars, (m - n) * sizeof(*(a->chars))); + while (n--) + a->chars[n] |= c->chars[n]; + } else if (a == c) { + memcpy(a->chars + n, m == b->used ? b->chars : c->chars, (m - n) * sizeof(*(a->chars))); + while (n--) + a->chars[n] |= b->chars[n]; + } else if (m == b->used) { + memcpy(a->chars, b->chars, m * sizeof(*(a->chars))); + while (n--) + a->chars[n] |= c->chars[n]; + } else { + memcpy(a->chars, c->chars, m * sizeof(*(a->chars))); + while (n--) + a->chars[n] |= b->chars[n]; + } + + SET_SIGNUM(a, (zsignum(b) > 0 && zsignum(c) > 0) * 2 - 1); +} diff --git a/src/zsplit.c b/src/zsplit.c new file mode 100644 index 0000000..40b3e54 --- /dev/null +++ b/src/zsplit.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +void +zsplit(z_t high, z_t low, z_t a, size_t delim) +{ + size_t chars; + + if (zzero(a)) { + SET_SIGNUM(high, 0); + SET_SIGNUM(low, 0); + return; + } + + chars = delim >> LB_BITS_PER_CHAR; + + if (high == a) { + if (a->used < chars) + SET_SIGNUM(low, 0); + else + ztrunc(low, a, delim); + zrsh(high, a, delim); + } else { + zrsh(high, a, delim); + if (a->used < chars) + SET_SIGNUM(low, 0); + else + ztrunc(low, a, delim); + } +} diff --git a/src/ztrunc.c b/src/ztrunc.c new file mode 100644 index 0000000..d4c31de --- /dev/null +++ b/src/ztrunc.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + +#include <stdlib.h> +#include <string.h> + + +void +ztrunc(z_t a, z_t b, size_t bits) +{ + zahl_char_t mask = 1; + size_t chars; + if (zzero(b)) { + SET_SIGNUM(a, 0); + } else { + chars = CEILING_BITS_TO_CHARS(bits); + a->sign = b->sign; + a->used = chars < b->used ? chars : b->used; + if (a->alloced < b->alloced) { + a->alloced = b->alloced; + a->chars = realloc(a->chars, b->alloced * sizeof(*(a->chars))); + } + memcpy(a->chars, b->chars, a->used * sizeof(*(a->chars))); + bits = BITS_IN_LAST_CHAR(bits); + if (bits) { + mask <<= bits; + mask -= 1; + a->chars[a->used - 1] &= mask; + } + } +} diff --git a/src/zxor.c b/src/zxor.c new file mode 100644 index 0000000..4c68448 --- /dev/null +++ b/src/zxor.c @@ -0,0 +1,56 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +void +zxor(z_t a, z_t b, z_t c) +{ + size_t n, m; + + if (zzero(b)) { + if (zzero(c)) { + SET_SIGNUM(a, 0); + } else { + if (a != c) + zset(a, c); + } + return; + } else if (zzero(c)) { + if (a != b) + zset(a, b); + return; + } + + m = b->used > c->used ? b->used : c->used; + n = b->used + c->used - m; + + if (n == m && !memcmp(b->chars, c->chars, m * sizeof(*(b->chars)))) { + SET_SIGNUM(a, 0); + return; + } + + if (a->alloced < m) { + a->alloced = m; + a->chars = realloc(a->chars, m * sizeof(*(a->chars))); + } + + if (a == b) { + memcpy(a->chars + n, m == b->used ? b->chars : c->chars, (m - n) * sizeof(*(a->chars))); + while (n--) + a->chars[n] ^= c->chars[n]; + } else if (a == c) { + memcpy(a->chars + n, m == b->used ? b->chars : c->chars, (m - n) * sizeof(*(a->chars))); + while (n--) + a->chars[n] ^= b->chars[n]; + } else if (m == b->used) { + memcpy(a->chars, b->chars, m * sizeof(*(a->chars))); + while (n--) + a->chars[n] ^= c->chars[n]; + } else { + memcpy(a->chars, c->chars, m * sizeof(*(a->chars))); + while (n--) + a->chars[n] ^= b->chars[n]; + } + + SET_SIGNUM(a, 1 - 2 * ((zsignum(b) ^ zsignum(c)) < 0); +} |
