libzahl

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

commit 8c2ad212d78184d59e4181993c195b35c4cde166
parent 4b7277e4276fd612c161bc3447f508b52ae3ed37
Author: Mattias Andrée <maandree@kth.se>
Date:   Wed, 27 Apr 2016 13:30:47 +0200

Improve library translations

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

Diffstat:
MMakefile | 9+++++++--
Mbench/benchmark.c | 10++++++++--
Mbench/libgmp.h | 14++++++++++++--
Mbench/libhebimath.h | 32++++++++++++++++++++++++--------
Mbench/libtfm.h | 16+++++++++++-----
Msrc/zsplit.c | 1+
6 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/Makefile b/Makefile @@ -107,6 +107,9 @@ BENCHMARK_CPP_libtfm = '-DBENCHMARK_LIB="libtfm.h"' BENCHMARK_CPP_hebimath = '-DBENCHMARK_LIB="libhebimath.h"' BENCHMARK_CPP_libhebimath = '-DBENCHMARK_LIB="libhebimath.h"' +BENCHMARK_C_hebimath = -static +BENCHMARK_C_libhebimath = -static + CPPFLAGS += $(BENCHMARK_CPP_$(BENCHMARK_LIB)) CFLAGS_WITHOUT_O = $$(printf '%s\n' $(CFLAGS) | sed '/^-O.*$$/d') @@ -128,10 +131,12 @@ test: test.c libzahl.a test-random.c $(CC) $(LDFLAGS) $(CFLAGS_WITHOUT_O) -O0 $(CPPFLAGS) -o $@ test.c libzahl.a benchmark: bench/benchmark.c $(BENCHMARK_DEP_$(BENCHMARK_LIB)) - $(CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -o $@ bench/benchmark.c $(BENCHMARK_LIB_$(BENCHMARK_LIB)) + $(CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -o $@ bench/benchmark.c \ + $(BENCHMARK_LIB_$(BENCHMARK_LIB)) $(BENCHMARK_C_$(BENCHMARK_LIB)) benchmark-func: bench/benchmark-func.c $(BENCHMARK_DEP_$(BENCHMARK_LIB)) - $(CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -o $@ bench/benchmark-func.c $(BENCHMARK_LIB_$(BENCHMARK_LIB)) + $(CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -o $@ bench/benchmark-func.c \ + $(BENCHMARK_LIB_$(BENCHMARK_LIB)) $(BENCHMARK_C_$(BENCHMARK_LIB)) benchmark-zrand: bench/benchmark-zrand.c libzahl.a $(CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -o $@ $^ diff --git a/bench/benchmark.c b/bench/benchmark.c @@ -99,10 +99,13 @@ main(int argc, char *argv[]) BENCHMARK(zbset(c, a, 76, -1), 1); BENCHMARK(zbset(a, a, 76, -1), 1); BENCHMARK(zbtest(a, 76), 1); +#ifndef HEBIMATH BENCHMARK(zgcd(c, a, b), 0); +#endif BENCHMARK(zmul(c, a, b), 0); BENCHMARK(zmul(c, a, a), 0); BENCHMARK(zsqr(c, a), 0); +#ifndef HEBIMATH zsets(d, "1484298084218938358480511181388394862858002249"); BENCHMARK(zmodmul(c, a, b, d), 0); BENCHMARK(zmodmul(c, a, a, d), 0); @@ -111,10 +114,11 @@ main(int argc, char *argv[]) BENCHMARK(zmodmul(c, a, a, tiny), 0); BENCHMARK(zmodsqr(c, a, tiny), 0); zsets(d, "12"); - BENCHMARK(zpow(c, a, d), 0); - BENCHMARK(zpowu(c, a, 12), 0); + BENCHMARK(zpow(c, a, d), 0); /* Memory corruption when using hebimath */ + BENCHMARK(zpowu(c, a, 12), 0); /* Memory corruption when using hebimath */ BENCHMARK(zmodpow(c, a, d, b), 0); BENCHMARK(zmodpowu(c, a, 12, b), 0); +#endif BENCHMARK(zsets(c, "5495468234592964023447280368442884381000481887"), 0); BENCHMARK(zstr_length(a, 10), 0); BENCHMARK(zstr(a, buf, 0), 0); @@ -127,9 +131,11 @@ main(int argc, char *argv[]) BENCHMARK(zdiv(c, a, b), 1); BENCHMARK(zmod(c, a, b), 1); BENCHMARK(zdivmod(c, d, a, b), 1); +#ifndef HEBIMATH BENCHMARK(zdiv(c, a, tiny), 0); BENCHMARK(zmod(c, a, tiny), 0); BENCHMARK(zdivmod(c, d, a, tiny), 0); +#endif zfree(a); zfree(b); diff --git a/bench/libgmp.h b/bench/libgmp.h @@ -64,8 +64,6 @@ zunsetup(void) #define zor mpz_ior #define zxor mpz_xor #define zbtest mpz_tstbit -#define zeven mpz_even_p /* Note, must not have side effects. */ -#define zodd mpz_odd_p /* Note, must not have side effects. */ #define zeven_nonzero zeven #define zodd_nonzero zodd #define zzero(a) (!mpz_sgn(a)) @@ -97,6 +95,18 @@ zunsetup(void) #define zmod mpz_tdiv_r #define zdivmod mpz_tdiv_qr +static inline int +zeven(z_t a) +{ + return mpz_even_p(a); +} + +static inline int +zodd(z_t a) +{ + return mpz_odd_p(a); +} + static inline void zsetu(z_t r, unsigned long long int val) { diff --git a/bench/libhebimath.h b/bench/libhebimath.h @@ -7,6 +7,7 @@ #include <stdlib.h> #define BIGINT_LIBRARY "hebimath" +#define HEBIMATH typedef hebi_int z_t[1]; @@ -311,7 +312,15 @@ zmodsqr(z_t r, const z_t a, const z_t m) static inline void zpowu(z_t r, const z_t a, unsigned long long int b) { - int neg = zsignum(a) < 0; + if (!b) { + if (zzero(a)) { + error = hebi_badvalue; + longjmp(jbuf, 1); + } + zsetu(r, 1); + return; + } + zset(_pow_a, a); zsetu(r, 1); for (; b; b >>= 1) { @@ -319,8 +328,6 @@ zpowu(z_t r, const z_t a, unsigned long long int b) zmul(r, r, _pow_a); zsqr(_pow_a, _pow_a); } - if (neg) - zneg(r, r); } static inline void @@ -332,8 +339,19 @@ zpow(z_t r, const z_t a, const z_t b) static inline void zmodpowu(z_t r, const z_t a, unsigned long long int b, const z_t m) { - int neg = zsignum(a) < 0; - zset(_pow_a, a); + if (!b) { + if (zzero(a) || zzero(m)) { + error = hebi_badvalue; + longjmp(jbuf, 1); + } + zsetu(r, 1); + return; + } else if (zzero(m)) { + error = hebi_badvalue; + longjmp(jbuf, 1); + } + + zmod(_pow_a, a, m); zset(_pow_m, m); zsetu(r, 1); for (; b; b >>= 1) { @@ -341,8 +359,6 @@ zmodpowu(z_t r, const z_t a, unsigned long long int b, const z_t m) zmodmul(r, r, _pow_a, _pow_m); zmodsqr(_pow_a, _pow_a, _pow_m); } - if (neg) - zneg(r, r); } static inline void @@ -455,7 +471,7 @@ static inline char * zstr(const z_t a, char *s, size_t n) { if (!n) - n = zstr_length(a, 10) + 1; + n = zstr_length(a, 10) * 2 + 1; try(hebi_get_str(s, n, a, 10)); return s; } diff --git a/bench/libtfm.h b/bench/libtfm.h @@ -10,7 +10,8 @@ typedef fp_int z_t[1]; static z_t _0, _1, _a, _b; -static int _tmp; +static int _tmp, error; +static jmp_buf jbuf; static inline void fp_set_int(z_t a, uint32_t d) @@ -23,7 +24,7 @@ fp_set_int(z_t a, uint32_t d) static inline void zsetup(jmp_buf env) { - (void) env; + *jbuf = *env; fp_init(_0); fp_init(_1); fp_init(_a); @@ -275,7 +276,14 @@ zrand(z_t r, int dev, int dist, z_t n) static inline void zpowu(z_t r, z_t a, unsigned long long int b) { - int neg = zsignum(a) < 0; + if (!b) { + if (zzero(a)) { + error = FP_VAL; + longjmp(jbuf, 1); + } + zsetu(r, 1); + return; + } zset(_a, a); zsetu(r, 1); for (; b; b >>= 1) { @@ -283,6 +291,4 @@ zpowu(z_t r, z_t a, unsigned long long int b) zmul(r, r, _a); zsqr(_a, _a); } - if (neg) - zneg(r, r); } diff --git a/src/zsplit.c b/src/zsplit.c @@ -6,6 +6,7 @@ void zsplit(z_t high, z_t low, z_t a, size_t delim) { if (unlikely(zzero(a))) { + /* This is for performance. */ SET_SIGNUM(high, 0); SET_SIGNUM(low, 0); return;