]> sigrok.org Git - libsigrok.git/commitdiff
Format decimals correctly in sr_si_string_u64()
authorPeter Stuge <redacted>
Tue, 4 Jun 2013 00:20:57 +0000 (02:20 +0200)
committerUwe Hermann <redacted>
Wed, 7 Aug 2013 14:21:57 +0000 (16:21 +0200)
The function previously formatted 1004 as 1.4 k and 1004000 as 1.4 M.
The function now formats 1004 as 1.004 k, 1004000 as 1.004 M and
1004000000 as 1.004 G.

Fixes #73.

strutil.c

index b7b0af16d72bc9df0af4f78c658690150229a36d..4be37ca1799717f05ba4a32a60f13d32515e3454 100644 (file)
--- a/strutil.c
+++ b/strutil.c
  */
 SR_API char *sr_si_string_u64(uint64_t x, const char *unit)
 {
+       uint8_t i;
+       uint64_t quot, divisor[] = {
+               1, SR_KHZ(1), SR_MHZ(1), SR_GHZ(1),
+               SR_GHZ(1000), SR_GHZ(1000*1000), SR_GHZ(1000*1000*1000)
+       };
+       const char *p, prefix[] = "\0kMGTPE";
+       char fmt[8], fract[20] = "", *f;
+
        if (unit == NULL)
                unit = "";
 
-       if ((x >= SR_GHZ(1)) && (x % SR_GHZ(1) == 0)) {
-               return g_strdup_printf("%" PRIu64 " G%s", x / SR_GHZ(1), unit);
-       } else if ((x >= SR_GHZ(1)) && (x % SR_GHZ(1) != 0)) {
-               return g_strdup_printf("%" PRIu64 ".%" PRIu64 " G%s",
-                                      x / SR_GHZ(1), x % SR_GHZ(1), unit);
-       } else if ((x >= SR_MHZ(1)) && (x % SR_MHZ(1) == 0)) {
-               return g_strdup_printf("%" PRIu64 " M%s",
-                                      x / SR_MHZ(1), unit);
-       } else if ((x >= SR_MHZ(1)) && (x % SR_MHZ(1) != 0)) {
-               return g_strdup_printf("%" PRIu64 ".%" PRIu64 " M%s",
-                                   x / SR_MHZ(1), x % SR_MHZ(1), unit);
-       } else if ((x >= SR_KHZ(1)) && (x % SR_KHZ(1) == 0)) {
-               return g_strdup_printf("%" PRIu64 " k%s",
-                                   x / SR_KHZ(1), unit);
-       } else if ((x >= SR_KHZ(1)) && (x % SR_KHZ(1) != 0)) {
-               return g_strdup_printf("%" PRIu64 ".%" PRIu64 " k%s",
-                                   x / SR_KHZ(1), x % SR_KHZ(1), unit);
-       } else {
-               return g_strdup_printf("%" PRIu64 " %s", x, unit);
+       for (i = 0; (quot = x / divisor[i]) >= 1000; i++);
+
+       if (i) {
+               sprintf(fmt, ".%%0%dlu", i * 3);
+               f = fract + sprintf(fract, fmt, x % divisor[i]) - 1;
+
+               while (f >= fract && strchr("0.", *f))
+                       *f-- = 0;
        }
 
-       sr_err("%s: Error creating SI units string.", __func__);
-       return NULL;
+       p = prefix + i;
+
+       return g_strdup_printf("%" PRIu64 "%s %.1s%s", quot, fract, p, unit);
 }
 
 /**