GNU bug report logs - #14650
coreutils' getlimits fails to represent float limits correctly

Previous Next

Package: coreutils;

Reported by: bugdal <at> aerifal.cx

Date: Tue, 18 Jun 2013 06:41:01 UTC

Severity: normal

Done: Pádraig Brady <P <at> draigBrady.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Pádraig Brady <P <at> draigBrady.com>
Cc: tracker <at> debbugs.gnu.org
Subject: bug#14650: closed (coreutils' getlimits fails to represent float
 limits correctly)
Date: Tue, 18 Jun 2013 09:30:04 +0000
[Message part 1 (text/plain, inline)]
Your message dated Tue, 18 Jun 2013 10:29:32 +0100
with message-id <51C0287C.4000406 <at> draigBrady.com>
and subject line Re: bug#14650: coreutils' getlimits fails to represent float limits correctly
has caused the debbugs.gnu.org bug report #14650,
regarding coreutils' getlimits fails to represent float limits correctly
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs <at> gnu.org.)


-- 
14650: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14650
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: bugdal <at> aerifal.cx
To: bug-coreutils <at> gnu.org
Subject: coreutils' getlimits fails to represent float limits correctly
Date: Tue, 18 Jun 2013 02:10:21 -0400
I noticed a bug in the getlimits utility's printing of DBL_MAX, etc.
The precision at which the limits are printed is grossly insufficient
to represent the actual limits; if the output is converted back to a
floating point number of the appropriate type, the result will differ
greatly from the actual limit.

The format specifier used for printing these values is is %Le, which
gives 7 decimal digits. The number of digits needed to faithfully
represent the limits varies by type, but a safe fix would be replacing

    printf (#TYPE"_MIN=%Le\n", (long double)TYPE##_MIN); \
    printf (#TYPE"_MAX=%Le\n", (long double)TYPE##_MAX);

with:

    printf (#TYPE"_MIN=%.*Le\n", DECIMAL_DIG, (long double)TYPE##_MIN); \
    printf (#TYPE"_MAX=%.*Le\n", DECIMAL_DIG, (long double)TYPE##_MAX);

It would be possible to use appropriate precisions for each type, but
unfortunately I'm not aware of a convenient way to compute the number
of digits needed based on other properties of the type. FLT_DIG and
DBL_DIG are not the correct values for this; they deal with the
opposite round-trip. One solution would be to simply hard-code the
number of digits for float and double when they're IEEE types, and
otherwise use DECIMAL_DIG for all three types (for obscure systems
where float/double are not IEEE single/double). I believe the correct
number of digits for IEEE single or double would be 10 and 17,
respectively.

Rich


[Message part 3 (message/rfc822, inline)]
From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 14650-done <at> debbugs.gnu.org, bugdal <at> aerifal.cx
Subject: Re: bug#14650: coreutils' getlimits fails to represent float limits
 correctly
Date: Tue, 18 Jun 2013 10:29:32 +0100
On 06/18/2013 08:47 AM, Paul Eggert wrote:
> On 06/17/2013 11:10 PM, bugdal <at> aerifal.cx wrote:
>> I'm not aware of a convenient way to compute the number
>> of digits
> 
> coreutils already can do that; see lib/ftoastr.h.
> Presumably coreutils should use the ftoastr module hear.

Something like the patch below?
which changes the output from:

 FLT_MIN=1.175494e-38
 FLT_MAX=3.402823e+38
 DBL_MIN=2.225074e-308
 DBL_MAX=1.797693e+308
 LDBL_MIN=3.362103e-4932
 LDBL_MAX=1.189731e+4932

to...

 FLT_MIN=1.1754944e-38
 FLT_MAX=3.4028235e+38
 DBL_MIN=2.2250738585072014e-308
 DBL_MAX=1.7976931348623157e+308
 LDBL_MIN=3.3621031431120935063e-4932
 LDBL_MAX=1.189731495357231765e+4932

Note the difference lengths of LDBL_MIN and LDBL_MAX.

cheers,
Pádraig.

diff --git a/src/getlimits.c b/src/getlimits.c
index 7c1fbe2..dfc4b12 100644
--- a/src/getlimits.c
+++ b/src/getlimits.c
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <float.h>

+#include "ftoastr.h"
 #include "system.h"
 #include "long-options.h"

@@ -97,6 +98,19 @@ decimal_absval_add_one (char *buf)
   return result;
 }

+#define PRINT_FLOATTYPE(N, T, FTOASTR, BUFSIZE)                         \
+static void                                                             \
+N (T x)                                                                 \
+{                                                                       \
+  char buf[BUFSIZE];                                                    \
+  FTOASTR (buf, sizeof buf, FTOASTR_LEFT_JUSTIFY, 0, x);                \
+  puts (buf);                                                           \
+}
+
+PRINT_FLOATTYPE (print_FLT, float, ftoastr, FLT_BUFSIZE_BOUND)
+PRINT_FLOATTYPE (print_DBL, double, dtoastr, DBL_BUFSIZE_BOUND)
+PRINT_FLOATTYPE (print_LDBL, long double, ldtoastr, LDBL_BUFSIZE_BOUND)
+
 int
 main (int argc, char **argv)
 {
@@ -127,8 +141,8 @@ main (int argc, char **argv)
     }

 #define print_float(TYPE)                                                \
-  printf (#TYPE"_MIN=%Le\n", (long double)TYPE##_MIN);                   \
-  printf (#TYPE"_MAX=%Le\n", (long double)TYPE##_MAX);
+  printf (#TYPE"_MIN="); print_##TYPE(TYPE##_MIN);                       \
+  printf (#TYPE"_MAX="); print_##TYPE(TYPE##_MAX);

   /* Variable sized ints */
   print_int (CHAR);



This bug report was last modified 11 years and 343 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.