zsets.c - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
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… | |
42 X(10) X(9) X(8) X(7) X(6) X(5) X(4) X(3) X(2) X(… | |
43 #undef X | |
44 if (!temp) | |
45 continue; | |
46 libzahl_tmp_str_num->chars[0] = (zahl_char_t)tem… | |
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 } |