diff options
Diffstat (limited to 'src/common.c')
| -rw-r--r-- | src/common.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..0b11d57 --- /dev/null +++ b/src/common.c @@ -0,0 +1,100 @@ +/* + * common.c + * contains some common functions + * + * Copyright (c) 2026 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <math.h> +#include <stdio.h> +#include <stdint.h> +#include "common.h" + +size_t dtostr(char *buf, size_t bufsize, double realval) +{ + int slen = 0; + if (isnan(realval)) { + slen = snprintf(buf, bufsize, "nan"); + } else if (isinf(realval)) { + slen = snprintf(buf, bufsize, "%cinfinity", (realval > 0.0) ? '+' : '-'); + } else if (realval == 0.0f) { + slen = snprintf(buf, bufsize, "0.0"); + } else { + slen = snprintf(buf, bufsize, "%.*g", 17, realval); + if (slen < 0) { + return 0; + } + if (!buf || bufsize == 0) { + return (size_t)slen; + } + size_t len = (size_t)slen; + if (len >= bufsize) { + len = bufsize - 1; + } + size_t i = 0; + for (i = 0; i < len; i++) { + if (buf[i] == ',') { + buf[i] = '.'; + break; + } else if (buf[i] == '.') { + break; + } + } + return len; + } + if (slen < 0) { + return 0; + } + return (size_t)slen; +} + +/* based on https://stackoverflow.com/a/4143288 */ +#define PO10i_LIMIT (INT64_MAX/10) +int num_digits_i(int64_t i) +{ + int n; + int64_t po10; + n=1; + if (i < 0) { + i = (i == INT64_MIN) ? INT64_MAX : -i; + n++; + } + po10=10; + while (i>=po10) { + n++; + if (po10 > PO10i_LIMIT) break; + po10*=10; + } + return n; +} +#undef PO10i_LIMIT + +/* based on https://stackoverflow.com/a/4143288 */ +#define PO10u_LIMIT (UINT64_MAX/10) +int num_digits_u(uint64_t i) +{ + int n; + uint64_t po10; + n=1; + po10=10; + while (i>=po10) { + n++; + if (po10 > PO10u_LIMIT) break; + po10*=10; + } + return n; +} +#undef PO10u_LIMIT |
