aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zadd.c12
-rw-r--r--src/zdivmod.c2
-rw-r--r--src/zload.c7
-rw-r--r--src/znot.c10
-rw-r--r--src/zor.c8
-rw-r--r--src/zsplit.c14
-rw-r--r--src/zsub.c39
-rw-r--r--src/zxor.c19
8 files changed, 63 insertions, 48 deletions
diff --git a/src/zadd.c b/src/zadd.c
index 73e5b42..e7d5265 100644
--- a/src/zadd.c
+++ b/src/zadd.c
@@ -9,16 +9,20 @@ zadd_unsigned(z_t a, z_t b, z_t c)
uint32_t carry[] = {0, 0};
zahl_char_t *addend;
- if (a == c) {
- zadd_unsigned(a, c, b);
+ if (zzero(b)) {
+ zabs(a, c);
+ return;
+ } else if (zzero(c)) {
+ zabs(a, b);
return;
}
size = MAX(b->used, c->used);
+ n = b->used + c->used - size;
+
ENSURE_SIZE(a, size + 1);
a->chars[size] = 0;
- n = b->used + c->used - size;
if (a == b) {
if (a->used < c->used) {
n = c->used;
@@ -56,7 +60,7 @@ zadd_unsigned(z_t a, z_t b, z_t c)
if (a->used < i)
a->used = i;
- SET_SIGNUM(a, !zzero(b) | !zzero(c));
+ SET_SIGNUM(a, 1);
}
diff --git a/src/zdivmod.c b/src/zdivmod.c
index e145c27..def98b5 100644
--- a/src/zdivmod.c
+++ b/src/zdivmod.c
@@ -32,8 +32,6 @@ zdivmod(z_t a, z_t b, z_t c, z_t d)
zseti(a, sign);
SET_SIGNUM(b, 0);
return;
- } else if (sign < 0) {
- zsub_unsigned(b, d, c);
} else {
SET(b, c);
}
diff --git a/src/zload.c b/src/zload.c
index a77ae57..3ab939d 100644
--- a/src/zload.c
+++ b/src/zload.c
@@ -8,12 +8,9 @@ zload(z_t a, const void *buffer)
const char *buf = buffer;
a->sign = *((const int *)buf), buf += sizeof(int);
a->used = *((const size_t *)buf), buf += sizeof(size_t);
- a->alloced = 0;
- if (a->sign)
+ if (a->sign) {
ENSURE_SIZE(a, a->used);
- else
- a->chars = 0;
- if (!zzero(a))
zmemcpy(a->chars, buf, a->used);
+ }
return sizeof(int) + sizeof(size_t) + (zzero(a) ? 0 : a->used * sizeof(zahl_char_t));
}
diff --git a/src/znot.c b/src/znot.c
index bcb17e2..d0e52c0 100644
--- a/src/znot.c
+++ b/src/znot.c
@@ -18,12 +18,12 @@ znot(z_t a, z_t b)
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;
+ bits = BITS_IN_LAST_CHAR(bits);
+ if (bits)
+ a->chars[a->used - 1] &= ((zahl_char_t)1 << bits) - 1;
- for (; a->used; a->used--)
- if (a->chars[a->used - 1])
- break;
+ while (a->used && !a->chars[a->used - 1])
+ a->used--;
if (!a->used)
SET_SIGNUM(a, 0);
}
diff --git a/src/zor.c b/src/zor.c
index 240024e..c50f5f8 100644
--- a/src/zor.c
+++ b/src/zor.c
@@ -20,16 +20,17 @@ zor(z_t a, z_t b, z_t c)
m = MAX(b->used, c->used);
n = b->used + c->used - m;
- a->used = m;
ENSURE_SIZE(a, m);
if (a == b) {
- zmemcpy(a->chars + n, m == b->used ? b->chars : c->chars, m - n);
+ if (b->used < c->used)
+ zmemcpy(a->chars + n, c->chars + n, m - n);
while (n--)
a->chars[n] |= c->chars[n];
} else if (a == c) {
- zmemcpy(a->chars + n, m == b->used ? b->chars : c->chars, m - n);
+ if (c->used < b->used)
+ zmemcpy(a->chars + n, b->chars + n, m - n);
while (n--)
a->chars[n] |= b->chars[n];
} else if (m == b->used) {
@@ -42,5 +43,6 @@ zor(z_t a, z_t b, z_t c)
a->chars[n] |= b->chars[n];
}
+ a->used = m;
SET_SIGNUM(a, (zsignum(b) > 0 && zsignum(c) > 0) * 2 - 1);
}
diff --git a/src/zsplit.c b/src/zsplit.c
index 384c5d7..8f51721 100644
--- a/src/zsplit.c
+++ b/src/zsplit.c
@@ -5,27 +5,17 @@
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 = FLOOR_BITS_TO_CHARS(delim);
-
if (high == a) {
- if (a->used < chars)
- SET_SIGNUM(low, 0);
- else
- ztrunc(low, a, delim);
+ 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);
+ ztrunc(low, a, delim);
}
}
diff --git a/src/zsub.c b/src/zsub.c
index 8616542..5096eb0 100644
--- a/src/zsub.c
+++ b/src/zsub.c
@@ -5,28 +5,49 @@
void
zsub_unsigned(z_t a, z_t b, z_t c)
{
- int magcmp = zcmpmag(b, c);
- z_t s;
- size_t i, n;
zahl_char_t carry[] = {0, 0};
+ zahl_char_t *s;
+ size_t i, n;
+ int magcmp;
+
+ if (zzero(b)) {
+ zabs(a, c);
+ zneg(a, a);
+ return;
+ } else if (zzero(c)) {
+ zabs(a, b);
+ return;
+ } else if (a == b || a == c) {
+ /* TODO This should not be necessary. */
+ z_t tb, tc;
+ zinit(tb);
+ zinit(tc);
+ zset(tb, b);
+ zset(tc, c);
+ zsub_unsigned(a, tb, tc);
+ zfree(tb);
+ zfree(tc);
+ return;
+ }
+ magcmp = zcmpmag(b, c);
if (magcmp <= 0) {
if (magcmp == 0) {
SET_SIGNUM(a, 0);
return;
}
SET(a, c);
- *s = *b;
+ n = MIN(a->used, b->used);
+ s = b->chars;
} else {
SET(a, b);
- *s = *c;
+ n = MIN(a->used, c->used);
+ s = c->chars;
}
- n = MIN(a->used, s->used);
-
for (i = 0; i < n; i++) {
- carry[~i & 1] = carry[i & 1] ? (a->chars[i] <= s->chars[i]) : (a->chars[i] < s->chars[i]);
- a->chars[i] -= s->chars[i];
+ carry[~i & 1] = carry[i & 1] ? (a->chars[i] <= s[i]) : (a->chars[i] < s[i]);
+ a->chars[i] -= s[i];
a->chars[i] -= carry[i & 1];
}
diff --git a/src/zxor.c b/src/zxor.c
index fcbb3ae..d152ed7 100644
--- a/src/zxor.c
+++ b/src/zxor.c
@@ -21,19 +21,16 @@ zxor(z_t a, z_t b, z_t c)
m = MAX(b->used, c->used);
n = b->used + c->used - m;
- if (n == m && !zmemcmp(b->chars, c->chars, m)) {
- SET_SIGNUM(a, 0);
- return;
- }
-
ENSURE_SIZE(a, m);
if (a == b) {
- zmemcpy(a->chars + n, m == b->used ? b->chars : c->chars, m - n);
+ if (b->used < c->used)
+ zmemcpy(a->chars + n, c->chars + n, m - n);
while (n--)
a->chars[n] ^= c->chars[n];
} else if (a == c) {
- zmemcpy(a->chars + n, m == b->used ? b->chars : c->chars, m - n);
+ if (c->used < b->used)
+ zmemcpy(a->chars + n, b->chars + n, m - n);
while (n--)
a->chars[n] ^= b->chars[n];
} else if (m == b->used) {
@@ -46,5 +43,11 @@ zxor(z_t a, z_t b, z_t c)
a->chars[n] ^= b->chars[n];
}
- SET_SIGNUM(a, 1 - 2 * ((zsignum(b) ^ zsignum(c)) < 0));
+ a->used = m;
+ while (a->used && !a->chars[a->used - 1])
+ a->used--;
+ if (a->used)
+ SET_SIGNUM(a, 1 - 2 * ((zsignum(b) ^ zsignum(c)) < 0));
+ else
+ SET_SIGNUM(a, 0);
}