X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=lib%2Fhuman.c;h=0665b3f7bf25499505b2d03a99def4b2ee676f6f;hb=1ad624bbbc38cb07899152df9eafb7f5adde71b5;hp=839f9d6ea5da05e18b281879ec479ecf31c41701;hpb=c9dfa7a7e83ec9ab73e7c8c3674cefe95439db82;p=chaz%2Ftar diff --git a/lib/human.c b/lib/human.c index 839f9d6..0665b3f 100644 --- a/lib/human.c +++ b/lib/human.c @@ -26,19 +26,12 @@ #include #include -#if HAVE_LIMITS_H -# include -#endif - #if HAVE_STRING_H # include #else # include #endif -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif #if HAVE_STDLIB_H # include #endif @@ -76,6 +69,23 @@ static const char suffixes[] = 'Y' /* Yotta */ }; +/* If INEXACT_STYLE is not human_round_to_even, and if easily + possible, adjust VALUE according to the style. */ +static double +adjust_value (enum human_inexact_style inexact_style, double value) +{ + /* Do not use the floor or ceil functions, as that would mean + linking with the standard math library, which is a porting pain. + So leave the value alone if it is too large to easily round. */ + if (inexact_style != human_round_to_even && value < (uintmax_t) -1) + { + uintmax_t u = value; + value = u + (inexact_style == human_ceiling && u != value); + } + + return value; +} + /* Like human_readable_inexact, except always round to even. */ char * human_readable (uintmax_t n, char *buf, @@ -173,7 +183,7 @@ human_readable_inexact (uintmax_t n, char *buf, double damt = n * (from_block_size / (double) to_block_size); if (! base) - sprintf (buf, "%.0f", damt); + sprintf (buf, "%.0f", adjust_value (inexact_style, damt)); else { double e = 1; @@ -188,9 +198,12 @@ human_readable_inexact (uintmax_t n, char *buf, damt /= e; - sprintf (buf, "%.1f%c", damt, suffixes[power]); + sprintf (buf, "%.1f%c", adjust_value (inexact_style, damt), + suffixes[power]); if (4 < strlen (buf)) - sprintf (buf, "%.0f%c", damt, suffixes[power]); + sprintf (buf, "%.0f%c", + adjust_value (inexact_style, damt * 10) / 10, + suffixes[power]); } return buf;