commit 787dbbf337bb238bea30d66d4bf43907bca20e19
Author:     Mattias Andrée <[email protected]>
AuthorDate: Tue Mar 1 19:22:26 2016 +0100
Commit:     Mattias Andrée <[email protected]>
CommitDate: Tue Mar 1 19:22:26 2016 +0100

    Add zcmp, zcmpi, zcmpu, zcmpmag, zset, zseti, and zsetu
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/src/internals.h b/src/internals.h
index ac74bd5..cc2d034 100644
--- 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
new file mode 100644
index 0000000..2a51d5e
--- /dev/null
+++ 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
new file mode 100644
index 0000000..640e340
--- /dev/null
+++ 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
new file mode 100644
index 0000000..7e4ab38
--- /dev/null
+++ 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
new file mode 100644
index 0000000..577a0f4
--- /dev/null
+++ 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
new file mode 100644
index 0000000..3598859
--- /dev/null
+++ 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
new file mode 100644
index 0000000..c42ffd6
--- /dev/null
+++ 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
new file mode 100644
index 0000000..78b78bb
--- /dev/null
+++ 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;
+       }
+}

Reply via email to