libzahl

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

commit 787dbbf337bb238bea30d66d4bf43907bca20e19
parent ee47da9c3992a846f3fb236e7796dbb88d44819c
Author: Mattias Andrée <maandree@kth.se>
Date:   Tue,  1 Mar 2016 19:22:26 +0100

Add zcmp, zcmpi, zcmpu, zcmpmag, zset, zseti, and zsetu

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

Diffstat:
Msrc/internals.h | 15+++------------
Asrc/zcmp.c | 11+++++++++++
Asrc/zcmpi.c | 14++++++++++++++
Asrc/zcmpmag.c | 29+++++++++++++++++++++++++++++
Asrc/zcmpu.c | 14++++++++++++++
Asrc/zset.c | 22++++++++++++++++++++++
Asrc/zseti.c | 14++++++++++++++
Asrc/zsetu.c | 24++++++++++++++++++++++++
8 files changed, 131 insertions(+), 12 deletions(-)

diff --git a/src/internals.h b/src/internals.h @@ -7,18 +7,7 @@ #define BITS_IN_LAST_CHAR(bits) ((bits) & (BITS_PER_CHAR - 1)) #define LIST_TEMPS\ - X(libzahl_tmp_a)\ - X(libzahl_tmp_b)\ - X(libzahl_tmp_c)\ - X(libzahl_tmp_d)\ - X(libzahl_tmp_e)\ - X(libzahl_tmp_f)\ - X(libzahl_tmp_g)\ - X(libzahl_tmp_i)\ - X(libzahl_tmp_j)\ - X(libzahl_tmp_k)\ - X(libzahl_tmp_l)\ - X(libzahl_tmp_m) + X(libzahl_tmp_cmp) #define X(x) extern z_t x; LIST_TEMPS @@ -28,3 +17,5 @@ extern jmp_buf libzahl_jmp_buf; extern int libzahl_set_up; #define FAILURE_JUMP() (longjmp(libzahl_jmp_buf, 1)) + +#define SET_SIGNUM(a, signum) ((a)->sign = (signum)) diff --git a/src/zcmp.c b/src/zcmp.c @@ -0,0 +1,11 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +int +zcmp(z_t a, z_t b) +{ + if (zsignum(a) != zsignum(b)) + return zsignum(a) < zsignum(b) ? -1 : zsignum(a) > zsignum(b); + return zsignum(a) * zcmpmag(a, b); +} diff --git a/src/zcmpi.c b/src/zcmpi.c @@ -0,0 +1,14 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +int +zcmpi(z_t a, long long int b) +{ + if (!b) + return zsignum(a); + if (zzero(a)) + return b > 0 ? -1 : b < 0; + zseti(zahl_tmp_cmp, b); + return zcmp(a, zahl_tmp_cmp); +} diff --git a/src/zcmpmag.c b/src/zcmpmag.c @@ -0,0 +1,29 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +int +zcmpmag(z_t a, z_t b) +{ + size_t i, j; + if (zzero(a)) + return -!zzero(b); + if (zzero(b)) + return 1; + i = a->used - 1; + j = b->used - 1; + for (; i > j; i--) { + if (a->chars[i]) + return +1; + a->used--; + } + for (; j > i; j--) { + if (b->chars[j]) + return -1; + b->used--; + } + for (; i; i--) + if (a->chars[i] != b->chars[i]) + return (a->chars[i] > b->chars[i]) * 2 - 1; + return a->chars[0] < b->chars[0] ? -1 : a->chars[0] > b->chars[0]; +} diff --git a/src/zcmpu.c b/src/zcmpu.c @@ -0,0 +1,14 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +int +zcmpu(z_t a, unsigned long long int b) +{ + if (!b) + return zsignum(a); + if (zsignum(a) <= 0) + return -1; + zsetu(zahl_tmp_cmp, b); + return zcmp(a, zahl_tmp_cmp); +} diff --git a/src/zset.c b/src/zset.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + +#include <stdlib.h> +#include <string.h> + + +void +zset(z_t a, z_t b) +{ + if (zzero(b)) { + SET_SIGNUM(a, 0); + } else { + if (a->alloced < b->alloced) { + a->alloced = b->alloced; + a->chars = realloc(a->chars, b->alloced * sizeof(*(a->chars))); + } + a->sign = b->sign; + a->used = b->used; + memcpy(a->chars, b->chars, b->used * sizeof(*(a->chars))); + } +} diff --git a/src/zseti.c b/src/zseti.c @@ -0,0 +1,14 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + + +void +zseti(z_t a, long long int b) +{ + if (b >= 0) { + zsetu(a, (unsigned long long int)b); + } else { + zsetu(a, (unsigned long long int)-b); + SET_SIGNUM(a, -1); + } +} diff --git a/src/zsetu.c b/src/zsetu.c @@ -0,0 +1,24 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + +#define CHARS_PER_TYPE(t) (sizeof(t) / (BITS_PER_CHAR >> 3)) + + +void +zsetu(z_t a, unsigned long long int b) +{ + if (!b) { + SET_SIGNUM(a, 0); + return; + } + if (a->alloced < CHARS_PER_TYPE(b)) { + a->alloced = CHARS_PER_TYPE(b); + a->chars = realloc(a->chars, CHARS_PER_TYPE(b) * sizeof(*(a->chars))) + } + SET_SIGNUM(a, 1); + a->used = 0; + while (b) { + a->chars[a->used++] = (uint32_t)b; + b >>= BITS_PER_CHAR; + } +}