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.  */