| 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 } |