summaryrefslogtreecommitdiffstats
path: root/util/suffix.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/suffix.c')
-rw-r--r--util/suffix.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/util/suffix.c b/util/suffix.c
index 6cd4f0b..4106958 100644
--- a/util/suffix.c
+++ b/util/suffix.c
@@ -38,25 +38,60 @@
#include <math.h>
static struct si_suffix {
- double magnitude;
+ long double magnitude;
const char *suffix;
} si_suffixes[] = {
+ {1e30, "Q"},
+ {1e27, "R"},
+ {1e24, "Y"},
+ {1e21, "Z"},
+ {1e18, "E"},
{1e15, "P"},
{1e12, "T"},
{1e9, "G"},
{1e6, "M"},
{1e3, "k"},
{1e0, ""},
- {1e-3, "m"},
- {1e-6, "u"},
- {1e-9, "n"},
- {1e-12, "p"},
- {1e-15, "f"},
{0}
};
const char *suffix_si_get(double *value)
{
+ long double value_ld = *value;
+ const char *suffix = suffix_si_get_ld(&value_ld);
+
+ *value = value_ld;
+
+ return suffix;
+}
+
+uint64_t suffix_si_parse(const char *value, bool *suffixed)
+{
+ char *suffix;
+ double ret;
+ struct si_suffix *s;
+
+ errno = 0;
+ ret = strtod(value, &suffix);
+ if (errno)
+ return 0;
+
+ for (s = si_suffixes; s->magnitude != 0; s++) {
+ if (suffix[0] == s->suffix[0]) {
+ if (suffixed && suffix[0] != '\0')
+ *suffixed = true;
+ return ret *= s->magnitude;
+ }
+ }
+
+ if (suffix[0] != '\0')
+ errno = EINVAL;
+
+ return (uint64_t)ret;
+}
+
+const char *suffix_si_get_ld(long double *value)
+{
struct si_suffix *s;
for (s = si_suffixes; s->magnitude != 0; s++) {
@@ -114,7 +149,7 @@ uint64_t suffix_binary_parse(const char *value)
{
char *suffix;
errno = 0;
- uint64_t ret = strtoll(value, &suffix, 0);
+ uint64_t ret = strtoull(value, &suffix, 0);
if (errno)
return 0;