diff --git a/programs/util.c b/programs/util.c index 964d60ee2..c8f6d1886 100644 --- a/programs/util.c +++ b/programs/util.c @@ -305,37 +305,55 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { UTIL_HumanReadableSize_t hrs; - if (size >= (1ull << 60)) { - hrs.value = (float)size / (1ull << 60); - hrs.suffix = "E"; - } else if (size >= (1ull << 50)) { - hrs.value = (float)size / (1ull << 50); - hrs.suffix = "P"; - } else if (size >= (1ull << 40)) { - hrs.value = (float)size / (1ull << 40); - hrs.suffix = "T"; - } else if (size >= (1ull << 30)) { - hrs.value = (float)size / (1ull << 30); - hrs.suffix = "G"; - } else if (size >= (1ull << 20)) { - hrs.value = (float)size / (1ull << 20); - hrs.suffix = "M"; - } else if (size >= (1ull << 10)) { - hrs.value = (float)size / (1ull << 10); - hrs.suffix = "K"; - } else { - hrs.value = (float)size; - hrs.suffix = ""; - } - if (hrs.value >= 100 || (U64)hrs.value == size) { - hrs.precision = 0; - } else if (hrs.value >= 10) { - hrs.precision = 1; - } else if (hrs.value > 1) { - hrs.precision = 2; + if (g_utilDisplayLevel > 2) { + /* In verbose mode, do not scale sizes down, except in the case of + * values that exceed the integral precision of a double. */ + if (size >= (1ull << 53)) { + hrs.value = (double)size / (1ull << 20); + hrs.suffix = "M"; + /* At worst, a double representation of a maximal size will be + * accurate to better than tens of kilobytes. */ + hrs.precision = 2; + } else { + hrs.value = (double)size; + hrs.suffix = ""; + hrs.precision = 0; + } } else { - hrs.precision = 3; + /* In regular mode, scale sizes down and use suffixes. */ + if (size >= (1ull << 60)) { + hrs.value = (double)size / (1ull << 60); + hrs.suffix = "E"; + } else if (size >= (1ull << 50)) { + hrs.value = (double)size / (1ull << 50); + hrs.suffix = "P"; + } else if (size >= (1ull << 40)) { + hrs.value = (double)size / (1ull << 40); + hrs.suffix = "T"; + } else if (size >= (1ull << 30)) { + hrs.value = (double)size / (1ull << 30); + hrs.suffix = "G"; + } else if (size >= (1ull << 20)) { + hrs.value = (double)size / (1ull << 20); + hrs.suffix = "M"; + } else if (size >= (1ull << 10)) { + hrs.value = (double)size / (1ull << 10); + hrs.suffix = "K"; + } else { + hrs.value = (double)size; + hrs.suffix = ""; + } + + if (hrs.value >= 100 || (U64)hrs.value == size) { + hrs.precision = 0; + } else if (hrs.value >= 10) { + hrs.precision = 1; + } else if (hrs.value > 1) { + hrs.precision = 2; + } else { + hrs.precision = 3; + } } return hrs; diff --git a/programs/util.h b/programs/util.h index 63cd0c378..f146f3a08 100644 --- a/programs/util.h +++ b/programs/util.h @@ -177,7 +177,7 @@ U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); * precision, value, suffix order to a "%.*f%s" format string. */ typedef struct { - float value; + double value; int precision; const char* suffix; } UTIL_HumanReadableSize_t; diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 9e2133c4f..32cd5af86 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1146,8 +1146,9 @@ int main(int const argCount, const char* argv[]) (void)singleThread; (void)nbWorkers; #endif -#ifdef UTIL_HAS_CREATEFILELIST g_utilDisplayLevel = g_displayLevel; + +#ifdef UTIL_HAS_CREATEFILELIST if (!followLinks) { unsigned u, fileNamesNb; unsigned const nbFilenames = (unsigned)filenames->tableSize;