bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with coreutils-6.10.176-383b1.tar.gz


From: Jim Meyering
Subject: Re: Problems with coreutils-6.10.176-383b1.tar.gz
Date: Mon, 14 Apr 2008 19:13:24 +0200

Peter Fales <address@hidden> wrote:
> I'm testing the latest coreutils snapshot (6.10.176-383b1) on several
> platforms and on three of them, the seq command is failing in "make check"
>
> On Solaris 8 (sparc), Solaris 8 (intel), and SGI Irix 6.2, the command;
>
>       src/seq 0.8 0.1 0.90000000000000000000
>
> prints
>
>       0.8
>
> On the other platforms (and with earlier releases of the seq command), it
> prints the expected:
>
>       0.8
>       0.9

Thanks again, Peter.
I finally did get access to a Solaris 8 system and fixed it.
Here's what I've just pushed:

        seq: work around floating point inaccuracies on more systems
        * src/seq.c: Include <math.h> for fabs.
        Include <float.h> for DBL_EPSILON.
        (abs_rel_diff): New function.
        (print_numbers): Use abs_rel_diff rather than a strict equality test.
        Without this change, Solaris 8 and Irix 6.2 would fail the float-6
        test.  Reported by Peter Fales in
        http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/13183
        * src/c99-to-c89.diff: Adjust seq.c offsets.

---
 src/seq.c           |   12 +++++++++++-
 src/c99-to-c89.diff |   16 ++++++++--------
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/src/seq.c b/src/seq.c
index 64bbeee..7fc89ad 100644
--- a/src/seq.c
+++ b/src/seq.c
@@ -20,6 +20,8 @@
 #include <getopt.h>
 #include <stdio.h>
 #include <sys/types.h>
+#include <math.h>
+#include <float.h>

 #include "system.h"
 #include "c-strtod.h"
@@ -259,6 +261,14 @@ long_double_format (char const *fmt, struct layout *layout)
   return NULL;
 }

+/* Return the absolute relative difference from x to y.  */
+static double
+abs_rel_diff (double x, double y)
+{
+  double s = (y == 0.0 ? 1 : y);
+  return fabs ((y - x) / s);
+}
+
 /* Actually print the sequence of numbers in the specified range, with the
    given or default stepping and format.  */

@@ -300,7 +310,7 @@ print_numbers (char const *fmt, struct layout layout,
              x_str[x_strlen - layout.suffix_len] = '\0';

              if (xstrtold (x_str + layout.prefix_len, NULL, &x_val, c_strtold)
-                 && x_val == last)
+                 && abs_rel_diff (x_val, last) < DBL_EPSILON)
                {
                  char *x0_str = NULL;
                  if (asprintf (&x0_str, fmt, x0) < 0)
diff --git a/src/c99-to-c89.diff b/src/c99-to-c89.diff
index 052b606..8158019 100644
--- a/src/c99-to-c89.diff
+++ b/src/c99-to-c89.diff
@@ -124,9 +124,9 @@ diff -upr src/rm.c src/rm.c
 +  }
  }
 diff -upr src/seq.c src/seq.c
---- src/seq.c  2007-07-23 12:56:20.000000000 +0200
-+++ src/seq.c  2007-07-23 13:03:12.000000000 +0200
-@@ -164,6 +164,7 @@ scan_arg (const char *arg)
+--- src/seq.c  2008-04-14 11:17:15.000000000 +0200
++++ src/seq.c  2008-04-14 11:26:57.000000000 +0200
+@@ -166,6 +166,7 @@ scan_arg (const char *arg)
                        : (decimal_point == arg                /* .#  -> 0.# */
                           || ! ISDIGIT (decimal_point[-1]))); /* -.# -> 0.# */
        }
@@ -134,7 +134,7 @@ diff -upr src/seq.c src/seq.c
        char const *e = strchr (arg, 'e');
        if (! e)
        e = strchr (arg, 'E');
-@@ -172,6 +173,7 @@ scan_arg (const char *arg)
+@@ -174,6 +175,7 @@ scan_arg (const char *arg)
          long exponent = strtol (e + 1, NULL, 10);
          ret.precision += exponent < 0 ? -exponent : 0;
        }
@@ -142,7 +142,7 @@ diff -upr src/seq.c src/seq.c
      }

    return ret;
-@@ -339,6 +341,7 @@ get_default_format (operand first, opera
+@@ -349,6 +351,7 @@ get_default_format (operand first, opera
          size_t last_width = last.width + (prec - last.precision);
          if (last.precision && prec == 0)
            last_width--;  /* don't include space for '.' */
@@ -150,7 +150,7 @@ diff -upr src/seq.c src/seq.c
          size_t width = MAX (first_width, last_width);
          if (width <= INT_MAX)
            {
-@@ -346,6 +349,7 @@ get_default_format (operand first, opera
+@@ -356,6 +359,7 @@ get_default_format (operand first, opera
              sprintf (format_buf, "%%0%d.%dLf", w, prec);
              return format_buf;
            }
@@ -158,7 +158,7 @@ diff -upr src/seq.c src/seq.c
        }
        else
        {
-@@ -434,6 +438,7 @@ main (int argc, char **argv)
+@@ -444,6 +448,7 @@ main (int argc, char **argv)
    if (format_str)
      {
        validate_format (format_str);
@@ -166,7 +166,7 @@ diff -upr src/seq.c src/seq.c
        char const *f = long_double_format (format_str, &layout);
        if (! f)
        {
-@@ -441,6 +446,7 @@ main (int argc, char **argv)
+@@ -451,6 +456,7 @@ main (int argc, char **argv)
          usage (EXIT_FAILURE);
        }
        format_str = f;
--
1.5.5.50.gab781




reply via email to

[Prev in Thread] Current Thread [Next in Thread]