From a626bacf8e45af60727882250f9d3abeb15ff3cd Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 2 Mar 2016 09:59:52 +0100 Subject: Add zsets and zstr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/zstr.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/zstr.c (limited to 'src/zstr.c') diff --git a/src/zstr.c b/src/zstr.c new file mode 100644 index 0000000..a1d4d13 --- /dev/null +++ b/src/zstr.c @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include "internals" + +#define num libzahl_tmp_str_num +#define rem libzahl_tmp_str_rem + +/* All 9 you see here is derived from that 10⁹ is the largest + * power of than < 2³², and 32 is the number of bits in + * zahl_char_t. If zahl_char_t is chanced, the value 9, and + * the cast to unsigned long must be changed accordingly. */ + + +char * +zstr(z_t a, char *b) +{ + size_t n; + char overridden; + int neg; + + if (zzero(a)) { + if (!b) { + b = malloc(2); + if (!b) + FAILURE_JUMP(); + } + b[0] = '0'; + b[1] = 0; + return b; + } + + n = zstr_length(a, 10); + if (!b) { + b = malloc(n + 1); + if (!b) + FAILURE_JUMP(); + } + + neg = zsignum(a) < 0; + zabs(num, a); + n -= neg; + n = n > 9 ? (n - 9) : 0; + b[0] = '-'; + b += neg; + overridden = 0; + + for (;;) { + zdivmod(num, rem, num, libzahl_const_1e9); + if (!zzero(num)) { + sprintf(b + n, "%09lu", (unsigned long)(rem->chars[0])); + b[n + 9] = overridden; + overridden = b[n + (9 - 1)]; + n = n > 9 ? (n - 9) : 0; + } else { + n += sprintf(b + n, "%lu", (unsigned long)(rem->chars[0])); + b[n] = overridden; + break; + } + } + + return b - neg; +} -- cgit v1.2.3-70-g09d2