summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-06-27 06:33:31 +0000
committerJim Meyering <jim@meyering.net>2000-06-27 06:33:31 +0000
commit99c1d22a9933ac676bc51ff80ea2b1ab3ded75c8 (patch)
tree10ad55875b208e2e3a5da2ef878aeeca73cbe296 /src
parentb07eb28c608b05492e4aa247f4c64cf67350634f (diff)
downloadcoreutils-99c1d22a9933ac676bc51ff80ea2b1ab3ded75c8.tar.xz
(show_dev): Round disk usage percentage up, not to nearest value.
Use integer arithmetic if it's easy. Fix bug when converting twos-complement negative values to floating point.
Diffstat (limited to 'src')
-rw-r--r--src/df.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/df.c b/src/df.c
index a6bc20c05..828f45681 100644
--- a/src/df.c
+++ b/src/df.c
@@ -210,7 +210,8 @@ excluded_fstype (const char *fstype)
}
/* Like human_readable_inexact, except return "-" if the argument is -1,
- and return the negative of N if NEGATIVE is 1. */
+ and if NEGATIVE is 1 then N represents a negative number, expressed
+ in two's complement. */
static char const *
df_readable (int negative, uintmax_t n, char *buf,
int from_block_size, int t_output_block_size,
@@ -356,29 +357,37 @@ show_dev (const char *disk, const char *mount_point, const char *fstype,
buf[2], input_units, output_units,
posix_format ? human_ceiling : human_floor));
- if (used != -1 && available != -1)
+ if (used == -1 || available == -1)
+ ;
+ else if (!negate_used
+ && used <= TYPE_MAXIMUM (uintmax_t) / 100
+ && used + available != 0
+ && (used + available < used) == negate_available)
{
- /* The following floating-point calculations can suffer from
- minor rounding errors, but making them precise requires
+ uintmax_t u100 = used * 100;
+ uintmax_t nonroot_total = used + available;
+ pct = u100 / nonroot_total + (u100 % nonroot_total != 0);
+ }
+ else
+ {
+ /* The calculation cannot be done easily with integer
+ arithmetic. Fall back on floating point. This can suffer
+ from minor rounding errors, but doing it exactly requires
multiple precision arithmetic, and it's not worth the
aggravation. */
-
- double u = used;
- double a = available;
- double nonroot_total = ((negate_used ? - u : u)
- + (negate_available ? - a : a));
+ double u = negate_used ? - (double) - used : used;
+ double a = negate_available ? - (double) - available : available;
+ double nonroot_total = u + a;
if (nonroot_total)
{
+ double ipct;
pct = u * 100 / nonroot_total;
+ ipct = (long) pct;
- if (posix_format)
- {
- /* Like `pct = ceil (pct);', but avoid ceil so that
- the math library needn't be linked. */
- double ipct = (long) pct;
- if (ipct - 1 < pct && pct <= ipct + 1)
- pct = ipct + (ipct < pct);
- }
+ /* Like `pct = ceil (dpct);', but avoid ceil so that
+ the math library needn't be linked. */
+ if (ipct - 1 < pct && pct <= ipct + 1)
+ pct = ipct + (ipct < pct);
}
}