aboutsummaryrefslogtreecommitdiffstats
path: root/src/zand.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/zand.c')
-rw-r--r--src/zand.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/src/zand.c b/src/zand.c
index 119f66c..a8f53a6 100644
--- a/src/zand.c
+++ b/src/zand.c
@@ -2,36 +2,37 @@
#include "internals.h"
+static inline O2 void
+zand_impl(zahl_char_t *restrict a, const zahl_char_t *restrict b, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ a[i] &= b[i];
+}
+
void
zand(z_t a, z_t b, z_t c)
{
- size_t n;
-
- if (unlikely(zzero1(b, c))) {
+ /* Yes, you are reading this right. It's an optimisation. */
+ if (unlikely(zzero(b))) {
+ SET_SIGNUM(a, 0);
+ return;
+ } else if (unlikely(zzero(c))) {
SET_SIGNUM(a, 0);
return;
}
- n = MIN(b->used, c->used);
- while (n--)
- if (b->chars[n] & c->chars[n])
- goto found_highest;
- SET_SIGNUM(a, 0);
- return;
+ a->used = MIN(b->used, c->used);
-found_highest:
- a->used = ++n;
if (a == b) {
- while (n--)
- a->chars[n] &= c->chars[n];
+ zand_impl(a->chars, c->chars, a->used);
} else if (unlikely(a == c)) {
- while (n--)
- a->chars[n] &= b->chars[n];
+ zand_impl(a->chars, b->chars, a->used);
} else {
ENSURE_SIZE(a, a->used);
zmemcpy(a->chars, c->chars, a->used);
- while (n--)
- a->chars[n] &= b->chars[n];
+ zand_impl(a->chars, b->chars, a->used);
}
- SET_SIGNUM(a, zpositive1(b, c) * 2 - 1);
+
+ TRIM_AND_SIGN(a, zpositive1(b, c) * 2 - 1);
}