diff options
Diffstat (limited to '')
-rw-r--r-- | util/suffix.c | 49 |
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; |