diff --git a/top/top.c b/top/top.c index 9d0e56a..1df0588 100644 --- a/top/top.c +++ b/top/top.c @@ -1552,15 +1552,40 @@ static const char *scale_mem (int target, unsigned long num, int width, int just if (Rc.zero_suppress && 0 >= num) goto end_justifies; + i = SK_Kb; + psfx = Scaled_sfxtab; scaled_num = num; - for (i = SK_Kb, psfx = Scaled_sfxtab; i < SK_Eb; psfx++, i++) { - if (i >= target - && (width >= snprintf(buf, sizeof(buf), fmttab[i], scaled_num, *psfx))) - goto end_justifies; + + // apply the minimum scaling + while (i < target) { + psfx++; + i++; scaled_num /= 1024.0; } - // well shoot, this outta' fit... + // get it to fit in the buffer + while (i <= SK_Eb) { + // first try lopping off digits + static char fmt[SMLBUFSIZ]; + int precision = (i == 0 ? 0 : 3); + + do { + snprintf(fmt, sizeof(fmt), "%%.%uf%%c", precision); + if (snprintf(buf, sizeof(buf), fmt, scaled_num, (i > 0 ? *psfx : '\0')) <= width) { + goto end_justifies; // it fits! + } + // drop a digit off the end and try again + precision--; + } while (precision > 0); + + // dropped all digits after decimal, still too big + // scale it and try again. + psfx++; + i++; + scaled_num /= 1024.0; + } + + // everything failed snprintf(buf, sizeof(buf), "?"); end_justifies: return justify_pad(buf, width, justr);