libzahl

big integer library
git clone git://git.suckless.org/libzahl
Log | Files | Refs | README | LICENSE

commit eb13267f82e848d9a9b38a2791e5c7008bf8d157
parent c3f264e8d9a9fc363fedbabbd4f27be2c6e014d4
Author: Mattias Andrée <maandree@kth.se>
Date:   Wed, 27 Apr 2016 00:39:31 +0200

zstr: add new parameter, n: the known limit out the length of the output

Signed-off-by: Mattias Andrée <maandree@kth.se>

Diffstat:
Mbench/benchmark-func.c | 6++++--
Mbench/benchmark.c | 3++-
Mbench/libgmp.h | 2+-
Mbench/libhebimath.h | 4++--
Mbench/libtfm.h | 2+-
Mbench/libtommath.h | 2+-
Mman/zstr.3 | 18+++++++++++++++++-
Msrc/zstr.c | 30++++++++++++++++++++++--------
Mtest-generate.py | 142++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtest.c | 116++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mzahl.h | 2+-
11 files changed, 181 insertions(+), 146 deletions(-)

diff --git a/bench/benchmark-func.c b/bench/benchmark-func.c @@ -164,7 +164,8 @@ FUNCTION_2D(bench_zcmp, zcmp(temp2, *a),) FUNCTION_2D(bench_sqr_zmul, zmul(temp, *a, temp2),) FUNCTION_2D(bench_zsqr, zsqr(temp, *a),) FUNCTION_2D(bench_zstr_length, zstr_length(*a, 10),) -FUNCTION_2D(bench_zstr, zstr(*a, buf),) +FUNCTION_2D(bench_zstr, zstr(*a, buf, sizeof(buf) - 1),) +FUNCTION_2D(bench_auto_zstr, zstr(*a, buf, 0),) FUNCTION_2D(bench_zsave, zsave(*a, buf),) FUNCTION_2D(bench_zload, zload(temp, buf), zsave(*a, buf)) FUNCTION_2D(bench_zbset_set, zbset(temp, *a, 2, 1),) @@ -175,7 +176,7 @@ FUNCTION_2D(bench_self_zbset_clear, zbset(temp2, temp2, 2, 0),) FUNCTION_2D(bench_self_zbset_flip, zbset(temp2, temp2, 2, -1),) FUNCTION_2D(bench_zbtest, zbtest(*a, 2),) FUNCTION_2D(bench_zptest, zptest(temp, *a, 5),) -FUNCTION_2D(bench_zsets, zsets(temp, buf), zstr(*a, buf)) +FUNCTION_2D(bench_zsets, zsets(temp, buf), zstr(*a, buf, sizeof(buf) - 1)) FUNCTION_2D(bench_zlsh, zlsh(temp, *a, 1),) FUNCTION_2D(bench_zrsh, zrsh(temp, *a, 1),) FUNCTION_2D(bench_ztrunc, ztrunc(temp, *a, i / 2),) @@ -231,6 +232,7 @@ struct function functions[] = { {F(zsqr), 1, 4097, 64, FULL, 0, 0, 0, 0, 10, 20}, {F(zstr_length), 1, 4097, 64, FULL, 0, 0, 0, 0, 10, 20}, {F(zstr), 1, 4097, 64, FULL, 0, 0, 0, 0, 10, 20}, + {F(auto_zstr), 1, 4097, 64, FULL, 0, 0, 0, 0, 10, 20}, {F(zsave), 1, 4097, 64, FULL, 0, 0, 0, 0, 1000, M_MAX}, {F(zload), 1, 4097, 64, FULL, 0, 0, 0, 0, 1000, M_MAX}, diff --git a/bench/benchmark.c b/bench/benchmark.c @@ -117,7 +117,8 @@ main(int argc, char *argv[]) BENCHMARK(zmodpowu(c, a, 12, b), 0); BENCHMARK(zsets(c, "5495468234592964023447280368442884381000481887"), 0); BENCHMARK(zstr_length(a, 10), 0); - BENCHMARK(zstr(a, buf), 0); + BENCHMARK(zstr(a, buf, 0), 0); + BENCHMARK(zstr(a, buf, sizeof(buf) - 1), 0); BENCHMARK(zrand(c, DEFAULT_RANDOM, QUASIUNIFORM, a), 0); BENCHMARK(zrand(c, DEFAULT_RANDOM, UNIFORM, a), 0); BENCHMARK(zptest(d, a, 5), 0); diff --git a/bench/libgmp.h b/bench/libgmp.h @@ -91,7 +91,7 @@ zunsetup(void) #define zmodpowu mpz_powm_ui #define zsets(a, s) mpz_set_str(a, s, 10) #define zstr_length(a, b) (mpz_sizeinbase(a, 10) + (zsignum(a) < 0)) -#define zstr(a, s) mpz_get_str(s, 10, a) +#define zstr(a, s, n) ((void)n, mpz_get_str(s, 10, a)) #define zptest(w, a, t) mpz_probab_prime_p(a, t) /* Note, the witness is not returned. */ #define zdiv mpz_tdiv_q #define zmod mpz_tdiv_r diff --git a/bench/libhebimath.h b/bench/libhebimath.h @@ -79,11 +79,11 @@ zunsetup(void) #define zpow(r, a, b) zpowu(r, a, hebi_get_u(b)) #define zmodpow(r, a, b, m) zmodpowu(r, a, hebi_get_u(b), m) #define zsets(a, s) hebi_set_str(a, s, 0, 10) -#define zstr(a, s) hebi_get_str(s, sizeof(s), a, 10) /* Assumes s is [], not * */ +#define zstr(a, s, n) hebi_get_str(s, n ? n : zstr_length(a, 10) + 1, a, 10) #define zdiv(q, a, b) hebi_div(q, 0, a, b) #define zmod(r, a, b) hebi_div(_a, r, a, b) #define zdivmod(q, r, a, b) hebi_div(q, r, a, b) -#define zsave(a, s) zstr(a, s) +#define zsave(a, s) zstr(a, s, sizeof(s) - 1) #define zload(a, s) zsets(a, s) static size_t diff --git a/bench/libtfm.h b/bench/libtfm.h @@ -83,7 +83,7 @@ zunsetup(void) #define zmodpowu(r, a, b, m) (fp_set_int(_b, b), fp_exptmod(a, _b, m, r)) #define zsets(a, s) fp_read_radix(a, s, 10) #define zstr_length(a, b) (fp_radix_size(a, b, &_tmp), _tmp) -#define zstr(a, s) fp_toradix(a, s, 10) +#define zstr(a, s, n) ((void)n, fp_toradix(a, s, 10)) #define zptest(w, a, t) fp_isprime_ex(a, t) /* Note, the witness is not returned. */ #define zload(a, s) fp_read_signed_bin(a, (unsigned char *)s, _tmp) #define zdiv(r, a, b) fp_div(a, b, r, 0) diff --git a/bench/libtommath.h b/bench/libtommath.h @@ -83,7 +83,7 @@ zunsetup(void) #define zmodpowu(r, a, b, m) (mp_set_int(_b, b), mp_exptmod(a, _b, m, r)) #define zsets(a, s) mp_read_radix(a, s, 10) #define zstr_length(a, b) (mp_radix_size(a, b, &_tmp), _tmp) -#define zstr(a, s) mp_toradix(a, s, 10) +#define zstr(a, s, n) ((void)n, mp_toradix(a, s, 10)) #define zptest(w, a, t) (mp_prime_is_prime(a, t, &_tmp), _tmp) /* Note, the witness is not returned. */ #define zload(a, s) mp_read_signed_bin(a, (unsigned char *)s, _tmp) #define zdiv(r, a, b) mp_div(a, b, r, 0) diff --git a/man/zstr.3 b/man/zstr.3 @@ -5,7 +5,7 @@ zstr - Create a string representation of a big integer .nf #include <zahl.h> -char *zstr(z_t \fIa\fP, char *\fIstr\fP); +char *zstr(z_t \fIa\fP, char *\fIstr\fP, size_t \fIn\fP); .fi .SH DESCRIPTION .B zstr @@ -19,6 +19,22 @@ is is .BR 0 , .B zstr create a new allocation. +.P +.I n +must be either be zero or a value at least +as great as the length of the resulting string. +If both +.I n +and +.I str +are nonzero, +.I n +must be at least the allocation size of +.I str +minus 1. Proper value for +.I n +can be calculated using +.BR zstr_length (3). .SH RETURN VALUE .I str is returned unless diff --git a/src/zstr.c b/src/zstr.c @@ -55,10 +55,10 @@ sprintint_min(char *buf, zahl_char_t v) char * -zstr(z_t a, char *b) +zstr(z_t a, char *b, size_t n) { char buf[19 + 1]; - size_t n, len, neg; + size_t len, neg, last, tot = 0; char overridden = 0; if (unlikely(zzero(a))) { @@ -69,7 +69,17 @@ zstr(z_t a, char *b) return b; } - n = zstr_length(a, 10); + if (!n) { + /* This is not the most efficient way to handle this. It should + * be faster to allocate buffers that sprintint_fix and + * sprintint_min print to, and then allocate `b` and copy the + * buffers in reverse order into `b`. However, that is an overly + * complicated solution. You probably already know the maximum + * length or do not care about performance. Another disadvantage + * with calculating the length before-hand, means that it is not + * possible to reallocate `b` if it is too small. */ + n = zstr_length(a, 10); + } if (unlikely(!b) && unlikely(!(b = malloc(n + 1)))) libzahl_memfailure(); @@ -79,7 +89,7 @@ zstr(z_t a, char *b) b[0] = '-'; b += neg; n -= neg; - n = n > 19 ? (n - 19) : 0; + n = (last = n) > 19 ? (n - 19) : 0; for (;;) { zdivmod(num, rem, num, libzahl_const_1e19); @@ -87,12 +97,16 @@ zstr(z_t a, char *b) sprintint_fix(b + n, zzero(rem) ? 0 : rem->chars[0]); b[n + 19] = overridden; overridden = b[n]; - n = n > 19 ? (n - 19) : 0; + n = (last = n) > 19 ? (n - 19) : 0; + tot += 19; } else { len = sprintint_min(buf, rem->chars[0]); - if (overridden) - buf[len] = b[n + len]; - memcpy(b + n, buf, len + 1); + if (tot) { + memcpy(b, buf, len); + memmove(b + len, b + last, tot + 1); + } else { + memcpy(b, buf, len + 1); + } break; } } diff --git a/test-generate.py b/test-generate.py @@ -56,7 +56,7 @@ def zabs(): print('zabs(b, a);') print('zabs(a, a);') print('assert(zcmp(a, b), == 0);') - print('assert_s(zstr(a, buf), "%i");' % abs(a)) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % abs(a)) def zadd(): bits = random.randint(0, LIMIT) @@ -70,9 +70,9 @@ def zadd(): print('zset(d, b);') print('zadd(d, a, d);') print('zadd(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) def zadd_unsigned(): bits = random.randint(0, LIMIT) @@ -86,13 +86,13 @@ def zadd_unsigned(): print('zset(d, b);') print('zadd_unsigned(d, a, d);') print('zadd_unsigned(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) c = abs(b) * 2 print('zadd_unsigned(c, b, b);') print('zadd_unsigned(b, b, b);') - print('assert_s(zstr(c, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) print('assert(zcmp(b, c), == 0);') def zand(): @@ -109,14 +109,14 @@ def zand(): print('zset(d, b);') print('zand(d, a, d);') print('zand(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) print('zsets(a, "%i");' % a) print('zand(d, a, a);') print('zand(a, a, a);') - print('assert_s(zstr(d, buf), "%i");' % a) - print('assert_s(zstr(a, buf), "%i");' % a) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % a) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % a) def zbits(): bits = random.randint(0, LIMIT) @@ -142,20 +142,20 @@ def zbset(): print('zsets(a, "%i");' % a) print('zset(d, a);') print('zbset(b, a, %i, 1);' % b) - print('assert_s(zstr(b, buf), "%i");' % cs) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % cs) print('zbset(b, a, %i, 0);' % b) - print('assert_s(zstr(b, buf), "%i");' % cc) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % cc) print('zbset(b, a, %i, -1);' % b) - print('assert_s(zstr(b, buf), "%i");' % cf) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % cf) print('zset(a, d);') print('zbset(a, a, %i, 1);' % b) - print('assert_s(zstr(a, buf), "%i");' % cs) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % cs) print('zset(a, d);') print('zbset(a, a, %i, 0);' % b) - print('assert_s(zstr(a, buf), "%i");' % cc) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % cc) print('zset(a, d);') print('zbset(a, a, %i, -1);' % b) - print('assert_s(zstr(a, buf), "%i");' % cf) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % cf) def zbtest(): bits = random.randint(0, LIMIT) @@ -211,7 +211,7 @@ def zlsh(): print('zlsh(b, a, %i);' % bits) print('zlsh(a, a, %i);' % bits) print('assert(zcmp(a, b), == 0);') - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) def zneg(): bits = random.randint(0, LIMIT) @@ -220,7 +220,7 @@ def zneg(): print('zneg(b, a);') print('zneg(a, a);') print('assert(zcmp(a, b), == 0);') - print('assert_s(zstr(a, buf), "%i");' % -a) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % -a) def zor(): bits = random.randint(0, LIMIT) @@ -236,14 +236,14 @@ def zor(): print('zset(d, b);') print('zor(d, a, d);') print('zor(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) print('zsets(a, "%i");' % a) print('zor(d, a, a);') print('zor(a, a, a);') - print('assert_s(zstr(d, buf), "%i");' % a) - print('assert_s(zstr(a, buf), "%i");' % a) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % a) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % a) def zrsh(): bits = random.randint(0, LIMIT) @@ -254,7 +254,7 @@ def zrsh(): print('zrsh(b, a, %i);' % bits) print('zrsh(a, a, %i);' % bits) print('assert(zcmp(a, b), == 0);') - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) def zsplit(): bits = random.randint(0, LIMIT) @@ -266,11 +266,11 @@ def zsplit(): print('zsets(a, "%i");' % a) print('zset(b, a);') print('zsplit(b, d, b, %i);' % bits) - print('assert_s(zstr(b, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zsplit(c, d, a, %i);' % bits) print('assert(zcmp(b, c), == 0);') - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zsplit(c, a, a, %i);' % bits) print('assert(zcmp(a, d), == 0);') print('assert(zcmp(b, c), == 0);') @@ -279,7 +279,7 @@ def zstr(): bits = random.randint(0, LIMIT) a = random.randint(-(1 << bits), 1 << bits) print('zsets(a, "%i");' % a) - print('assert_s(zstr(a, buf), "%i");' % a) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % a) def zstr_length(): bits = random.randint(0, LIMIT) @@ -299,9 +299,9 @@ def zsub(): print('zset(d, b);') print('zsub(d, a, d);') print('zsub(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) def zsub_unsigned(): bits = random.randint(0, LIMIT) @@ -315,9 +315,9 @@ def zsub_unsigned(): print('zset(d, b);') print('zsub_unsigned(d, a, d);') print('zsub_unsigned(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) print('zsub_unsigned(a, b, b);') print('assert(zzero(a), == 1);') print('zsub_unsigned(b, b, b);') @@ -332,7 +332,7 @@ def ztrunc(): print('ztrunc(b, a, %i);' % bits) print('ztrunc(a, a, %i);' % bits) print('assert(zcmp(a, b), == 0);') - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) def zxor(): bits = random.randint(0, LIMIT) @@ -348,9 +348,9 @@ def zxor(): print('zset(d, b);') print('zxor(d, a, d);') print('zxor(a, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % c) - print('assert_s(zstr(a, buf), "%i");' % c) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) print('zsets(a, "%i");' % a) print('zxor(d, a, a);') print('zxor(a, a, a);') @@ -455,8 +455,8 @@ def zdivmod(): print('zsets(a, "%i");' % a) print('zsets(b, "%i");' % b) print('zdivmod(c, d, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zdivmod(a, b, a, b);') print('assert(zcmp(a, c), == 0);') print('assert(zcmp(b, d), == 0);') @@ -476,20 +476,20 @@ def zdivmod(): print('zsets(a, "%i");' % a) print('zsets(b, "%i");' % b) print('zdivmod(a, d, a, b);') - print('assert_s(zstr(a, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zdivmod(c, b, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(b, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % d) a = bp * a_sign b = bp * b_sign (c, d) = (div(a, b), mod(a, b)) print('zsets(a, "%i");' % a) print('zsets(b, "%i");' % b) print('zdivmod(c, d, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zdivmod(a, b, a, b);') print('assert(zcmp(a, c), == 0);') print('assert(zcmp(b, d), == 0);') @@ -509,12 +509,12 @@ def zdivmod(): print('zsets(a, "%i");' % a) print('zsets(b, "%i");' % b) print('zdivmod(a, d, a, b);') - print('assert_s(zstr(a, buf), "%i");' % c) - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zdivmod(c, b, a, b);') - print('assert_s(zstr(c, buf), "%i");' % c) - print('assert_s(zstr(b, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % c) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % d) def zmul(): bits = random.randint(0, LIMIT) @@ -566,53 +566,53 @@ def zmodmul(): print('zsets(b, "%i");' % b) print('zsets(c, "%i");' % c) print('zmodmul(d, a, b, c);') - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zmodmul(a, a, b, c);') - print('assert_s(zstr(a, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zmodmul(b, a, b, c);') - print('assert_s(zstr(b, buf), "%i");' % d) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % d) print('zsets(b, "%i");' % b) print('zmodmul(c, a, b, c);') - print('assert_s(zstr(c, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % d) print('zsets(c, "%i");' % c) print('zmodmul(d, b, a, c);') - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zmodmul(a, b, a, c);') - print('assert_s(zstr(a, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zmodmul(b, b, a, c);') - print('assert_s(zstr(b, buf), "%i");' % d) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % d) print('zsets(b, "%i");' % b) print('zmodmul(c, b, a, c);') - print('assert_s(zstr(c, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % d) print('zsets(c, "%i");' % c) d = mod(a * a, c) print('zmodmul(d, a, a, c);') - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('zmodmul(a, a, a, c);') - print('assert_s(zstr(a, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zmodmul(c, a, a, c);') - print('assert_s(zstr(c, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % d) if a != 0: d = mod(a * b, a) print('zsets(d, "%i");' % d) print('zmodmul(c, a, b, a);') - print('assert_s(zstr(c, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % d) print('zmodmul(a, a, b, a);') - print('assert_s(zstr(a, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zmodmul(b, a, b, a);') - print('assert_s(zstr(b, buf), "%i");' % d) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % d) print('zsets(b, "%i");' % b) print('zmodmul(c, b, a, a);') - print('assert_s(zstr(c, buf), "%i");' % d) + print('assert_s(zstr(c, buf, BUF_N), "%i");' % d) print('zmodmul(a, b, a, a);') - print('assert_s(zstr(a, buf), "%i");' % d) + print('assert_s(zstr(a, buf, BUF_N), "%i");' % d) print('zsets(a, "%i");' % a) print('zmodmul(b, b, a, a);') - print('assert_s(zstr(b, buf), "%i");' % d) + print('assert_s(zstr(b, buf, BUF_N), "%i");' % d) print('zmodmul(b, a, a, a);') print('assert(zzero(b), == 1);') print('zmodmul(a, a, a, a);') @@ -739,7 +739,7 @@ def zmodpow(): print('zsets(d, "%i");' % d) print('zmodpow(d, a, b, c);') print('zmodpow(a, a, b, c);') - print('assert_s(zstr(d, buf), "%i");' % d) + print('assert_s(zstr(d, buf, BUF_N), "%i");' % d) print('assert(zcmp(a, d), == 0);') print('zsets(a, "%i");' % a) print('zmodpow(b, a, b, c);') diff --git a/test.c b/test.c @@ -67,6 +67,8 @@ main(void) static jmp_buf env, env2; static size_t n; +#define BUF_N (sizeof(buf) - 1) + if (setjmp(env)) { zperror(0); ret = 2; @@ -711,7 +713,7 @@ main(void) assert_zu(zstr_length(_2, 10), 2); zneg(_2, _2); assert_zu(zstr_length(a, 10), 4); - zstr(a, buf); + zstr(a, buf, 0); assert_s(buf, "1234"); zsets(a, "-1234"); zseti(b, -1234); @@ -720,9 +722,9 @@ main(void) assert(zcmp(a, b), == 0); assert(zcmpmag(a, c), == 0); assert(zcmp(a, c), < 0); - zstr(a, buf); + zstr(a, buf, 0); assert_s(buf, "-1234"); - assert_s(zstr(a, buf), "-1234"); + assert_s(zstr(a, buf, 0), "-1234"); zsetu(d, 100000UL); zrand(a, FAST_RANDOM, UNIFORM, d); @@ -828,87 +830,87 @@ main(void) assert_nr((zneg(_1, _1), zmodpowu(a, _1, 0, _0))); zneg(_1, _1); zsetu(a, 1LL); - assert_s(zstr(a, buf), "1"); + assert_s(zstr(a, buf, 1), "1"); zsetu(a, 10LL); - assert_s(zstr(a, buf), "10"); + assert_s(zstr(a, buf, 2), "10"); zsetu(a, 100LL); - assert_s(zstr(a, buf), "100"); + assert_s(zstr(a, buf, 3), "100"); zsetu(a, 1000LL); - assert_s(zstr(a, buf), "1000"); + assert_s(zstr(a, buf, 4), "1000"); zsetu(a, 10000LL); - assert_s(zstr(a, buf), "10000"); + assert_s(zstr(a, buf, BUF_N), "10000"); zsetu(a, 100000LL); - assert_s(zstr(a, buf), "100000"); + assert_s(zstr(a, buf, BUF_N), "100000"); zsetu(a, 1000000LL); - assert_s(zstr(a, buf), "1000000"); + assert_s(zstr(a, buf, BUF_N), "1000000"); zsetu(a, 10000000LL); - assert_s(zstr(a, buf), "10000000"); + assert_s(zstr(a, buf, BUF_N), "10000000"); zsetu(a, 100000000LL); - assert_s(zstr(a, buf), "100000000"); + assert_s(zstr(a, buf, BUF_N), "100000000"); zsetu(a, 999999999LL); - assert_s(zstr(a, buf), "999999999"); + assert_s(zstr(a, buf, BUF_N), "999999999"); zsetu(a, 1000000000LL); - assert_s(zstr(a, buf), "1000000000"); + assert_s(zstr(a, buf, BUF_N), "1000000000"); zsetu(a, 1000000001LL); - assert_s(zstr(a, buf), "1000000001"); + assert_s(zstr(a, buf, BUF_N), "1000000001"); zsetu(a, 2000000000LL); - assert_s(zstr(a, buf), "2000000000"); + assert_s(zstr(a, buf, BUF_N), "2000000000"); zsetu(a, 2050000000LL); - assert_s(zstr(a, buf), "2050000000"); + assert_s(zstr(a, buf, BUF_N), "2050000000"); zsetu(a, 2100000000LL); - assert_s(zstr(a, buf), "2100000000"); + assert_s(zstr(a, buf, BUF_N), "2100000000"); zsetu(a, 2140000000LL); - assert_s(zstr(a, buf), "2140000000"); + assert_s(zstr(a, buf, BUF_N), "2140000000"); zsetu(a, 2147000000LL); - assert_s(zstr(a, buf), "2147000000"); + assert_s(zstr(a, buf, BUF_N), "2147000000"); zsetu(a, 2147483000LL); - assert_s(zstr(a, buf), "2147483000"); + assert_s(zstr(a, buf, BUF_N), "2147483000"); zsetu(a, 2147483640LL); - assert_s(zstr(a, buf), "2147483640"); + assert_s(zstr(a, buf, BUF_N), "2147483640"); zsetu(a, 2147483646LL); - assert_s(zstr(a, buf), "2147483646"); + assert_s(zstr(a, buf, BUF_N), "2147483646"); zseti(a, 2147483647LL); - assert_s(zstr(a, buf), "2147483647"); + assert_s(zstr(a, buf, BUF_N), "2147483647"); zseti(a, -2147483647LL); - assert_s(zstr(a, buf), "-2147483647"); + assert_s(zstr(a, buf, BUF_N), "-2147483647"); zseti(a, -2147483647LL - 1LL); - assert_s(zstr(a, buf), "-2147483648"); + assert_s(zstr(a, buf, BUF_N), "-2147483648"); zsetu(a, 2147483647ULL); - assert_s(zstr(a, buf), "2147483647"); + assert_s(zstr(a, buf, BUF_N), "2147483647"); zsetu(a, 2147483648ULL); - assert_s(zstr(a, buf), "2147483648"); + assert_s(zstr(a, buf, BUF_N), "2147483648"); zsetu(a, 2147483649ULL); - assert_s(zstr(a, buf), "2147483649"); + assert_s(zstr(a, buf, BUF_N), "2147483649"); zsetu(a, 3000000000ULL); - assert_s(zstr(a, buf), "3000000000"); + assert_s(zstr(a, buf, BUF_N), "3000000000"); zsetu(a, 3100000000ULL); - assert_s(zstr(a, buf), "3100000000"); + assert_s(zstr(a, buf, BUF_N), "3100000000"); zsetu(a, 3200000000ULL); - assert_s(zstr(a, buf), "3200000000"); + assert_s(zstr(a, buf, BUF_N), "3200000000"); zsetu(a, 3300000000ULL); - assert_s(zstr(a, buf), "3300000000"); + assert_s(zstr(a, buf, BUF_N), "3300000000"); zsetu(a, 3400000000ULL); - assert_s(zstr(a, buf), "3400000000"); + assert_s(zstr(a, buf, BUF_N), "3400000000"); zsetu(a, 3500000000ULL); - assert_s(zstr(a, buf), "3500000000"); + assert_s(zstr(a, buf, BUF_N), "3500000000"); zsetu(a, 3600000000ULL); - assert_s(zstr(a, buf), "3600000000"); + assert_s(zstr(a, buf, BUF_N), "3600000000"); zsetu(a, 3700000000ULL); - assert_s(zstr(a, buf), "3700000000"); + assert_s(zstr(a, buf, BUF_N), "3700000000"); zsetu(a, 3800000000ULL); - assert_s(zstr(a, buf), "3800000000"); + assert_s(zstr(a, buf, BUF_N), "3800000000"); zsetu(a, 3900000000ULL); - assert_s(zstr(a, buf), "3900000000"); + assert_s(zstr(a, buf, BUF_N), "3900000000"); zsetu(a, 3999999999ULL); - assert_s(zstr(a, buf), "3999999999"); + assert_s(zstr(a, buf, BUF_N), "3999999999"); zsetu(a, 4000000000ULL); - assert_s(zstr(a, buf), "4000000000"); + assert_s(zstr(a, buf, BUF_N), "4000000000"); zsetu(a, 4000000001ULL); assert_zu(zstr_length(a, 10), 10); - assert_s(zstr(a, buf), "4000000001"); + assert_s(zstr(a, buf, BUF_N), "4000000001"); zsetu(a, 4000000000ULL); zsetu(b, 4000000000ULL); @@ -998,40 +1000,40 @@ main(void) assert(zcmp(c, d), == 0); zsetu(a, 4294967294ULL); - assert_s(zstr(a, buf), "4294967294"); + assert_s(zstr(a, buf, BUF_N), "4294967294"); zsetu(a, 4294967295ULL); - assert_s(zstr(a, buf), "4294967295"); + assert_s(zstr(a, buf, BUF_N), "4294967295"); zsetu(a, 4294967296ULL); - assert_s(zstr(a, buf), "4294967296"); + assert_s(zstr(a, buf, BUF_N), "4294967296"); zsetu(a, 4294967297ULL); - assert_s(zstr(a, buf), "4294967297"); + assert_s(zstr(a, buf, BUF_N), "4294967297"); zseti(a, 9223372036854775807LL); - assert_s(zstr(a, buf), "9223372036854775807"); + assert_s(zstr(a, buf, BUF_N), "9223372036854775807"); zseti(a, -9223372036854775807LL); - assert_s(zstr(a, buf), "-9223372036854775807"); + assert_s(zstr(a, buf, BUF_N), "-9223372036854775807"); zseti(a, -9223372036854775807LL - 1LL); - assert_s(zstr(a, buf), "-9223372036854775808"); + assert_s(zstr(a, buf, BUF_N), "-9223372036854775808"); zsetu(a, 18446744073709551614ULL); - assert_s(zstr(a, buf), "18446744073709551614"); + assert_s(zstr(a, buf, BUF_N), "18446744073709551614"); zsetu(a, 18446744073709551615ULL); - assert_s(zstr(a, buf), "18446744073709551615"); + assert_s(zstr(a, buf, BUF_N), "18446744073709551615"); zadd(a, a, _1); - assert_s(zstr(a, buf), "18446744073709551616"); + assert_s(zstr(a, buf, BUF_N), "18446744073709551616"); zadd(a, a, _1); - assert_s(zstr(a, buf), "18446744073709551617"); + assert_s(zstr(a, buf, BUF_N), "18446744073709551617"); zsets(a, "1000000000000000000000000000000"); - assert_s(zstr(a, buf), "1000000000000000000000000000000"); + assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000"); zsets(a, "+1000000000000000000000000000000"); - assert_s(zstr(a, buf), "1000000000000000000000000000000"); + assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000"); zsets(a, "-1000000000000000000000000000000"); - assert_s(zstr(a, buf), "-1000000000000000000000000000000"); + assert_s(zstr(a, buf, BUF_N), "-1000000000000000000000000000000"); zsetu(a, 1000000000000000ULL); zsqr(a, a); - assert_s(zstr(a, buf), "1000000000000000000000000000000"); + assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000"); #include "test-random.c" diff --git a/zahl.h b/zahl.h @@ -151,7 +151,7 @@ void zrand(z_t, enum zranddev, enum zranddist, z_t); /* String conversion. */ -char *zstr(z_t, char *); /* Write a in decimal onto b. */ +char *zstr(z_t, char *, size_t); /* Write a in decimal onto b. c is the output size or 0. */ int zsets(z_t, const char *); /* a := b */ /* Length of a in radix b. */