aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2016-03-04 10:45:10 +0100
committerMattias Andrée <maandree@kth.se>2016-03-04 10:47:53 +0100
commitaff09967d194d062ae8d83c0fbe1edf158804ef9 (patch)
tree793f32bc01e780bb6457570f9ea7a8e7ff94f7bb /src
parentAdd makefile and fix errors (diff)
downloadlibzahl-aff09967d194d062ae8d83c0fbe1edf158804ef9.tar.gz
libzahl-aff09967d194d062ae8d83c0fbe1edf158804ef9.tar.bz2
libzahl-aff09967d194d062ae8d83c0fbe1edf158804ef9.tar.xz
Clean up, fix a few bugs, and add a test
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src')
-rw-r--r--src/internals.h3
-rw-r--r--src/zadd.c3
-rw-r--r--src/zand.c3
-rw-r--r--src/zbset.c18
-rw-r--r--src/zload.c11
-rw-r--r--src/zlsh.c6
-rw-r--r--src/zmodpow.c8
-rw-r--r--src/zmul.c2
-rw-r--r--src/zor.c3
-rw-r--r--src/zpow.c8
-rw-r--r--src/zrand.c23
-rw-r--r--src/zrsh.c3
-rw-r--r--src/zset.c3
-rw-r--r--src/zsetu.c3
-rw-r--r--src/zsqr.c2
-rw-r--r--src/ztrunc.c7
-rw-r--r--src/zxor.c3
17 files changed, 62 insertions, 47 deletions
diff --git a/src/internals.h b/src/internals.h
index 77ea29b..5b1f9c3 100644
--- a/src/internals.h
+++ b/src/internals.h
@@ -62,7 +62,8 @@ extern int libzahl_set_up;
#define zmemcmp(a, b, n) memcmp(a, b, (n) * sizeof(zahl_char_t))
#define SET_SIGNUM(a, signum) ((a)->sign = (signum))
-#define SET(a, b) do { if (a != b) zset(a, b); } while (0)
+#define SET(a, b) do { if ((a) != (b)) zset(a, b); } while (0)
+#define ENSURE_SIZE(a, n) do { if ((a)->alloced < (n)) zahl_realloc(a, (n)); } while (0)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
diff --git a/src/zadd.c b/src/zadd.c
index 2aa7e38..6ab3ae8 100644
--- a/src/zadd.c
+++ b/src/zadd.c
@@ -15,8 +15,7 @@ zadd_unsigned(z_t a, z_t b, z_t c)
}
size = MAX(b->used, c->used);
- if (a->alloced < size + 1)
- zahl_realloc(a, size + 1);
+ ENSURE_SIZE(a, size + 1);
a->chars[size] = 0;
n = b->used + c->used - size;
diff --git a/src/zand.c b/src/zand.c
index 6b8dc4a..e07705a 100644
--- a/src/zand.c
+++ b/src/zand.c
@@ -28,8 +28,7 @@ found_highest:
while (n--)
a->chars[n] &= b->chars[n];
} else {
- if (a->alloced < a->used)
- zahl_realloc(a, a->used);
+ ENSURE_SIZE(a, a->used);
zmemcpy(a->chars, c->chars, a->used);
while (n--)
a->chars[n] &= b->chars[n];
diff --git a/src/zbset.c b/src/zbset.c
index d7b7784..c379e2a 100644
--- a/src/zbset.c
+++ b/src/zbset.c
@@ -5,12 +5,12 @@
void
zbset(z_t a, z_t b, size_t bit, int action)
{
- zahl_char_t x = 1;
+ zahl_char_t mask = 1;
size_t chars;
chars = FLOOR_BITS_TO_CHARS(bit);
bit = BITS_IN_LAST_CHAR(bit);
- x <<= bit;
+ mask <<= bit;
SET(a, b);
@@ -20,19 +20,19 @@ zbset(z_t a, z_t b, size_t bit, int action)
SET_SIGNUM(a, 1);
}
if (a->used <= chars) {
- if (a->alloced <= chars)
- zahl_realloc(a, chars + 1);
- zmemset(a->chars + a->used, 0, chars - a->used + 1);
+ ENSURE_SIZE(a, chars + 1);
+ zmemset(a->chars + a->used, 0, chars + 1 - a->used);
+ a->used = chars + 1;
}
}
if (action > 0) {
- a->chars[chars] |= x;
+ a->chars[chars] |= mask;
return;
} else if (action < 0) {
- a->chars[chars] ^= x;
- } else if (a->used > chars) {
- a->chars[chars] &= ~x;
+ a->chars[chars] ^= mask;
+ } else if (chars < a->used) {
+ a->chars[chars] &= ~mask;
}
while (a->used && !a->chars[a->used - 1])
diff --git a/src/zload.c b/src/zload.c
index c708453..ff54afb 100644
--- a/src/zload.c
+++ b/src/zload.c
@@ -6,11 +6,12 @@ size_t
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 = *((const size_t *)buf), buf += sizeof(size_t);
- if (a->alloced)
- zahl_realloc(a, a->alloced);
+ size_t alloced;
+ a->sign = *((const int *)buf), buf += sizeof(int);
+ a->used = *((const size_t *)buf), buf += sizeof(size_t);
+ alloced = *((const size_t *)buf), buf += sizeof(size_t);
+ if (alloced)
+ ENSURE_SIZE(a, alloced);
else
a->chars = 0;
if (!zzero(a))
diff --git a/src/zlsh.c b/src/zlsh.c
index e301d44..b631c1a 100644
--- a/src/zlsh.c
+++ b/src/zlsh.c
@@ -22,8 +22,7 @@ zlsh(z_t a, z_t b, size_t bits)
cbits = BITS_PER_CHAR - 1 - bits;
a->used = b->used + chars;
- if (a->alloced < a->used)
- zahl_realloc(a, a->used);
+ ENSURE_SIZE(a, a->used);
if (a == b)
zmemmove(a->chars + chars, b->chars, a->used);
else
@@ -36,8 +35,7 @@ zlsh(z_t a, z_t b, size_t bits)
a->chars[i] |= carry[i & 1];
}
if (carry[i & 1]) {
- if (a->alloced == a->used)
- zahl_realloc(a, a->alloced << 1);
+ ENSURE_SIZE(a, a->alloced << 1);
a->chars[i] = carry[i & 1];
a->used++;
}
diff --git a/src/zmodpow.c b/src/zmodpow.c
index fe18060..884e9ff 100644
--- a/src/zmodpow.c
+++ b/src/zmodpow.c
@@ -42,7 +42,7 @@ zmodpow(z_t a, z_t b, z_t c, z_t d)
zset(td, d);
zsetu(a, 1);
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n; i++) { /* Remember, n is floored. */
x = tc->chars[i];
for (j = BITS_PER_CHAR; j--; x >>= 1) {
if (x & 1)
@@ -50,4 +50,10 @@ zmodpow(z_t a, z_t b, z_t c, z_t d)
zmodsqr(tb, tb, td);
}
}
+ x = tc->chars[i];
+ for (; x; x >>= 1) {
+ if (x & 1)
+ zmodmul(a, a, tb, td);
+ zmodsqr(tb, tb, td);
+ }
}
diff --git a/src/zmul.c b/src/zmul.c
index 578d8a5..f237bc9 100644
--- a/src/zmul.c
+++ b/src/zmul.c
@@ -24,7 +24,7 @@ zmul(z_t a, z_t b, z_t c)
b_sign = zsignum(b);
c_sign = zsignum(c);
- if (m <= 16 && m2 <= 16) {
+ if (m <= BITS_PER_CHAR / 2 && m2 <= BITS_PER_CHAR / 2) {
zsetu(a, b->chars[0] * c->chars[0]);
SET_SIGNUM(a, b_sign * c_sign);
return;
diff --git a/src/zor.c b/src/zor.c
index 1d3952d..f594828 100644
--- a/src/zor.c
+++ b/src/zor.c
@@ -21,8 +21,7 @@ zor(z_t a, z_t b, z_t c)
m = MAX(b->used, c->used);
n = b->used + c->used - m;
- if (a->alloced < m)
- zahl_realloc(a, m);
+ ENSURE_SIZE(a, m);
if (a == b) {
zmemcpy(a->chars + n, m == b->used ? b->chars : c->chars, m - n);
diff --git a/src/zpow.c b/src/zpow.c
index 16988f7..c064f60 100644
--- a/src/zpow.c
+++ b/src/zpow.c
@@ -37,7 +37,7 @@ zpow(z_t a, z_t b, z_t c)
zset(tc, c);
zsetu(a, 1);
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n; i++) { /* Remember, n is floored. */
x = tc->chars[i];
for (j = BITS_PER_CHAR; j--; x >>= 1) {
if (x & 1)
@@ -45,4 +45,10 @@ zpow(z_t a, z_t b, z_t c)
zsqr(tb, tb);
}
}
+ x = tc->chars[i];
+ for (; x; x >>= 1) {
+ if (x & 1)
+ zmul(a, a, tb);
+ zsqr(tb, tb);
+ }
}
diff --git a/src/zrand.c b/src/zrand.c
index c5c8e8a..cb0b375 100644
--- a/src/zrand.c
+++ b/src/zrand.c
@@ -16,15 +16,16 @@
static void
zrand_get_random_bits(z_t r, size_t bits, int fd)
{
- size_t read_total, n, chars = CEILING_BITS_TO_CHARS(bits);
+ size_t read_total = 0, n, chars = CEILING_BITS_TO_CHARS(bits);
ssize_t read_just;
- uint32_t mask = 1;
+ zahl_char_t mask = 1;
+ char *buf;
- if (r->alloced < chars)
- zahl_realloc(r, chars);
+ ENSURE_SIZE(r, chars);
+ buf = (char *)(r->chars);
- for (n = chars << LB_BITS_PER_CHAR; n;) {
- read_just = read(fd, (char *)(r->chars) + read_total, n);
+ for (n = chars * sizeof(zahl_char_t); n;) {
+ read_just = read(fd, buf + read_total, n);
if (read_just < 0)
FAILURE_JUMP();
read_total += (size_t)read_just;
@@ -75,6 +76,10 @@ zrand(z_t r, enum zranddev dev, enum zranddist dist, z_t n)
switch (dist) {
case QUASIUNIFORM:
+ if (zsignum(n) < 0) {
+ errno = EDOM; /* n must be non-negative. */
+ FAILURE_JUMP();
+ }
bits = zbits(n);
zrand_get_random_bits(r, bits, fd);
zadd(r, r, libzahl_const_1);
@@ -83,10 +88,14 @@ zrand(z_t r, enum zranddev dev, enum zranddist dist, z_t n)
break;
case UNIFORM:
+ if (zsignum(n) < 0) {
+ errno = EDOM; /* n must be non-negative. */
+ FAILURE_JUMP();
+ }
bits = zbits(n);
do
zrand_get_random_bits(r, bits, fd);
- while (zcmp(r, n) > 0);
+ while (zcmpmag(r, n) > 0);
break;
default:
diff --git a/src/zrsh.c b/src/zrsh.c
index c3bd63e..c5a1a05 100644
--- a/src/zrsh.c
+++ b/src/zrsh.c
@@ -27,8 +27,7 @@ zrsh(z_t a, z_t b, size_t bits)
zmemmove(a->chars, a->chars + chars, a->used);
} else if (a != b) {
a->used = b->used - chars;
- if (a->alloced < a->used)
- zahl_realloc(a, a->used);
+ ENSURE_SIZE(a, a->used);
zmemcpy(a->chars, b->chars + chars, a->used);
}
diff --git a/src/zset.c b/src/zset.c
index 989bb1c..b67fe4a 100644
--- a/src/zset.c
+++ b/src/zset.c
@@ -8,8 +8,7 @@ zset(z_t a, z_t b)
if (zzero(b)) {
SET_SIGNUM(a, 0);
} else {
- if (a->alloced < b->alloced)
- zahl_realloc(a, b->alloced);
+ ENSURE_SIZE(a, b->alloced);
a->sign = b->sign;
a->used = b->used;
zmemcpy(a->chars, b->chars, b->used);
diff --git a/src/zsetu.c b/src/zsetu.c
index f37be7e..37fbf7c 100644
--- a/src/zsetu.c
+++ b/src/zsetu.c
@@ -11,8 +11,7 @@ zsetu(z_t a, unsigned long long int b)
SET_SIGNUM(a, 0);
return;
}
- if (a->alloced < SIZE_MULTIPLE(b, *(a->chars)))
- zahl_realloc(a, SIZE_MULTIPLE(b, *(a->chars)));
+ ENSURE_SIZE(a, SIZE_MULTIPLE(b, *(a->chars)));
SET_SIGNUM(a, 1);
a->used = 0;
while (b) {
diff --git a/src/zsqr.c b/src/zsqr.c
index be89c37..a9cebd0 100644
--- a/src/zsqr.c
+++ b/src/zsqr.c
@@ -20,7 +20,7 @@ zsqr(z_t a, z_t b)
m2 = zbits(b);
- if (m2 <= 16) {
+ if (m2 <= BITS_PER_CHAR / 2) {
zsetu(a, b->chars[0] * b->chars[0]);
SET_SIGNUM(a, 1);
return;
diff --git a/src/ztrunc.c b/src/ztrunc.c
index ffbbbe0..f86fb8e 100644
--- a/src/ztrunc.c
+++ b/src/ztrunc.c
@@ -18,9 +18,10 @@ ztrunc(z_t a, z_t b, size_t bits)
a->used = MIN(chars, b->used);
if (a->used < chars)
bits = 0;
- if (a->alloced < b->alloced)
- zahl_realloc(a, b->alloced);
- zmemcpy(a->chars, b->chars, a->used);
+ if (a != b) {
+ ENSURE_SIZE(a, b->alloced);
+ zmemcpy(a->chars, b->chars, a->used);
+ }
bits = BITS_IN_LAST_CHAR(bits);
if (bits) {
mask <<= bits;
diff --git a/src/zxor.c b/src/zxor.c
index f570fdf..fcbb3ae 100644
--- a/src/zxor.c
+++ b/src/zxor.c
@@ -26,8 +26,7 @@ zxor(z_t a, z_t b, z_t c)
return;
}
- if (a->alloced < m)
- zahl_realloc(a, m);
+ ENSURE_SIZE(a, m);
if (a == b) {
zmemcpy(a->chars + n, m == b->used ? b->chars : c->chars, m - n);