Mercurial > hg > octave-nkf > gnulib-hg
changeset 2593:3ebe28cfe9b4
(adjust_value): New function.
(human_readable_inexact): Apply rounding style even when
printing approximate values.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Fri, 16 Jun 2000 12:51:28 +0000 |
parents | d9dcaaf41e49 |
children | 6b6374f18593 |
files | lib/human.c |
diffstat | 1 files changed, 64 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/human.c +++ b/lib/human.c @@ -76,6 +76,23 @@ '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, @@ -117,10 +134,6 @@ int base; int to_block_size; int tenths = 0; - int multiplier; - int divisor; - int r2; - int r10; int power; char *p; @@ -151,49 +164,58 @@ /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE units. */ - if (to_block_size <= from_block_size - ? (from_block_size % to_block_size != 0 - || (multiplier = from_block_size / to_block_size, - (amt = n * multiplier) / multiplier != n)) - : (from_block_size == 0 - || to_block_size % from_block_size != 0 - || (divisor = to_block_size / from_block_size, - r10 = (n % divisor) * 10, - r2 = (r10 % divisor) * 2, - amt = n / divisor, - tenths = r10 / divisor, - rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2), - 0))) - { - /* Either the result cannot be computed easily using uintmax_t, - or from_block_size is zero. Fall back on floating point. - FIXME: This can yield answers that are slightly off. */ + { + int multiplier; + int divisor; + int r2; + int r10; + if (to_block_size <= from_block_size + ? (from_block_size % to_block_size != 0 + || (multiplier = from_block_size / to_block_size, + (amt = n * multiplier) / multiplier != n)) + : (from_block_size == 0 + || to_block_size % from_block_size != 0 + || (divisor = to_block_size / from_block_size, + r10 = (n % divisor) * 10, + r2 = (r10 % divisor) * 2, + amt = n / divisor, + tenths = r10 / divisor, + rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2), + 0))) + { + /* Either the result cannot be computed easily using uintmax_t, + or from_block_size is zero. Fall back on floating point. + FIXME: This can yield answers that are slightly off. */ - double damt = n * (from_block_size / (double) to_block_size); + double damt = n * (from_block_size / (double) to_block_size); - if (! base) - sprintf (buf, "%.0f", damt); - else - { - double e = 1; - power = 0; + if (! base) + sprintf (buf, "%.0f", adjust_value (inexact_style, damt)); + else + { + double e = 1; + power = 0; + + do + { + e *= base; + power++; + } + while (e * base <= damt && power < sizeof suffixes - 1); - do - { - e *= base; - power++; - } - while (e * base <= damt && power < sizeof suffixes - 1); + damt /= e; - damt /= e; + sprintf (buf, "%.1f%c", adjust_value (inexact_style, damt), + suffixes[power]); + if (4 < strlen (buf)) + sprintf (buf, "%.0f%c", + adjust_value (inexact_style, damt * 10) / 10, + suffixes[power]); + } - sprintf (buf, "%.1f%c", damt, suffixes[power]); - if (4 < strlen (buf)) - sprintf (buf, "%.0f%c", damt, suffixes[power]); - } - - return buf; - } + return buf; + } + } /* Use power of BASE notation if adjusted AMT is large enough. */