zsets.c - libzahl - big integer library
(HTM) git clone git://git.suckless.org/libzahl
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
zsets.c (1038B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "internals.h"
3
4 #include <ctype.h>
5
6 #ifdef __GNUC__
7 # pragma GCC diagnostic ignored "-Wswitch-default"
8 #endif
9
10
11 int
12 zsets(z_t a, const char *str)
13 {
14 unsigned long long int temp = 0;
15 int neg = (*str == '-');
16 const char *str_end;
17
18 str += neg || (*str == '+');
19
20 if (check(!*str)) {
21 errno = EINVAL;
22 return -1;
23 }
24 for (str_end = str; *str_end; str_end++) {
25 if (check(!isdigit(*str_end))) {
26 errno = EINVAL;
27 return -1;
28 }
29 }
30
31 SET_SIGNUM(a, 0);
32
33 zset(libzahl_tmp_str_num, libzahl_const_1e19);
34 switch ((str_end - str) % 19) {
35 while (*str) {
36 zmul(a, a, libzahl_const_1e19);
37 temp = 0;
38 #define X(n)\
39 case n:\
40 temp *= 10, temp += *str++ & 15;
41 X(0) X(18) X(17) X(16) X(15) X(14) X(13) X(12) X(11)
42 X(10) X(9) X(8) X(7) X(6) X(5) X(4) X(3) X(2) X(1)
43 #undef X
44 if (!temp)
45 continue;
46 libzahl_tmp_str_num->chars[0] = (zahl_char_t)temp;
47 zadd(a, a, libzahl_tmp_str_num);
48 }
49 }
50
51 if (unlikely(neg))
52 SET_SIGNUM(a, -zsignum(a));
53 return 0;
54 }