- int suffix, base;
-
- if (not_hr)
- sprintf(buffer, "%lu", val);
- else
- for (suffix = 0, base = 1; suffix < 5; suffix++, base <<= 10) {
- if (val < (base << 10)) {
- if (suffix && val < 10 * base)
- sprintf(buffer, "%lu.%lu%s", val / base,
- (val % base) * 10 / base, suffixes[suffix]);
- else
- sprintf(buffer, "%lu%s", val / base, suffixes[suffix]);
- break;
+ /* The code will adjust for additional (appended) units. */
+ static const char zero_and_units[] = { '0', 0, 'k', 'M', 'G', 'T' };
+ static const char fmt[] = "%Lu";
+ static const char fmt_tenths[] = "%Lu.%d%c";
+
+ static char str[21]; /* Sufficient for 64 bit unsigned integers. */
+
+ unsigned long long val;
+ int frac;
+ const char *u;
+ const char *f;
+
+ u = zero_and_units;
+ f = fmt;
+ frac = 0;
+
+ val = ((unsigned long long) size) * block_size;
+ if (val == 0) {
+ return u;
+ }
+
+ if (display_unit) {
+ val += display_unit/2; /* Deal with rounding. */
+ val /= display_unit; /* Don't combine with the line above!!! */
+ } else {
+ ++u;
+ while ((val >= KILOBYTE)
+ && (u < zero_and_units + sizeof(zero_and_units) - 1)) {
+ f = fmt_tenths;
+ ++u;
+ frac = ((((int)(val % KILOBYTE)) * 10) + (KILOBYTE/2)) / KILOBYTE;
+ val /= KILOBYTE;
+ }
+ if (frac >= 10) { /* We need to round up here. */
+ ++val;
+ frac = 0;
+ }
+#if 0
+ /* Sample code to omit decimal point and tenths digit. */
+ if ( /* no_tenths */ 1 ) {
+ if ( frac >= 5 ) {
+ ++val;