#include #include struct magnitude { size_t threshold; const char *suffix; }; #define USE_BASE2 /* This list must be in decending order of threshold */ #ifdef USE_BASE2 static struct magnitude k_magnitudes[] = { { 0x10000000000, "TiB" }, { 0x40000000, "GiB" }, { 0x100000, "MiB" }, { 0x400, "KiB" }, { 0x00, "B" }, }; #else static struct magnitude k_magnitudes[] = { { 1000000000000, "TB" }, { 1000000000, "GB" }, { 1000000, "MB" }, { 1000, "KB" }, { 0, "B" }, }; #endif static void convert(size_t *big, size_t *small, size_t val, size_t threshold) { if (!threshold) { *big = val; *small = 0; return; } *big = val / threshold; size_t rem = val % threshold; *small = (10 * rem) / threshold; } void data_size_to_string(size_t value, char *out, size_t outsz) { if (!value) { snprintf(out, outsz, "0 B"); return; } size_t def_count = sizeof(k_magnitudes) / sizeof(struct magnitude); for (size_t i = 0; i < def_count; i++) { if (value > k_magnitudes[i].threshold) { size_t big, small; convert(&big, &small, value, k_magnitudes[i].threshold); if (small) { snprintf(out, outsz, "%zu.%zu %s", big, small, k_magnitudes[i].suffix); } else { snprintf(out, outsz, "%zu %s", big, k_magnitudes[i].suffix); } return; } } *out = 0; }