Introduction
Introduction Statistics Contact Development Disclaimer Help
zstr.c - libzahl - big integer library
git clone git://git.suckless.org/libzahl
Log
Files
Refs
README
LICENSE
---
zstr.c (2963B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "internals.h"
3
4 #include <stdio.h>
5
6 #define num libzahl_tmp_str_num
7 #define rem libzahl_tmp_str_rem
8
9 /* All 19 you see here is derived from that 10¹⁹ is the largest
10 * power of than < 2⁶⁴, and 64 is the number of bits in
11 * zahl_char_t. If zahl_char_t is chanced, the value 19, and
12 * the cast to unsigned long long must be changed accordingly. */
13
14
15 #define S1(P) P"0" P"1" P"2" P"3" P"4" P"5" P"6" …
16 #define S2(P) S1(P"0")S1(P"1")S1(P"2")S1(P"3")S1(P"4")S1(P"5")S1(P"6")S…
17
18
19 static inline O2 void
20 sprintint_fix(char *buf, zahl_char_t v)
21 {
22 const char *partials = S2("");
23 uint16_t *buffer = (uint16_t *)(buf + 1);
24
25 buffer[8] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
26 buffer[7] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
27 buffer[6] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
28 buffer[5] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
29 buffer[4] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
30 buffer[3] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
31 buffer[2] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
32 buffer[1] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
33 buffer[0] = *(const uint16_t *)(partials + 2 * (v % 100)), v /= …
34 *buf = (char)('0' + v);
35 buf[19] = 0;
36 }
37
38 static inline void
39 cmemmove(char *d, const char *s, long n)
40 {
41 while (n--)
42 *d++ = *s++;
43 }
44
45 static inline size_t
46 sprintint_min(char *buf, zahl_char_t v)
47 {
48 long i = 0, j;
49 sprintint_fix(buf, v);
50 for (; buf[i] == '0'; i++);
51 cmemmove(buf, buf + i, j = 19 - i);
52 buf[j] = 0;
53 return (size_t)j;
54 }
55
56
57 char *
58 zstr(z_t a, char *b, size_t n)
59 {
60 char buf[19 + 1];
61 size_t len, neg, last, tot = 0;
62 char overridden = 0;
63
64 if (unlikely(zzero(a))) {
65 if (unlikely(!b) && unlikely(!(b = malloc(2))))
66 libzahl_memfailure();
67 b[0] = '0';
68 b[1] = 0;
69 return b;
70 }
71
72 if (!n) {
73 /* Calculate a value that is at least the number of
74 * digits required to store the string. The overshoot
75 * is not too signicant. */
76 n = (20 * BITS_PER_CHAR / 64 + (BITS_PER_CHAR == 8)) * a…
77 /* Note, depends on a ≠ as ensure above. */
78 }
79
80 if (unlikely(!b) && unlikely(!(b = libzahl_temp_allocation = mal…
81 libzahl_memfailure();
82
83 neg = znegative(a);
84 zabs(num, a);
85 b[0] = '-';
86 b += neg;
87 n -= neg;
88 n = (last = n) > 19 ? (n - 19) : 0;
89
90 for (;;) {
91 zdivmod(num, rem, num, libzahl_const_1e19);
92 if (likely(!zzero(num))) {
93 sprintint_fix(b + n, zzero(rem) ? 0 : rem->chars…
94 b[n + 19] = overridden;
95 overridden = b[n];
96 n = (last = n) > 19 ? (n - 19) : 0;
97 tot += 19;
98 } else {
99 len = sprintint_min(buf, rem->chars[0]);
100 if (tot) {
101 memcpy(b, buf, len);
102 memmove(b + len, b + last, tot + 1);
103 } else {
104 memcpy(b, buf, len + 1);
105 }
106 break;
107 }
108 }
109
110 libzahl_temp_allocation = 0;
111 return b - neg;
112 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.