pspp-dev
[Top][All Lists]
Advanced

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

[formatting i18n 01/14] Use new Gnulib function dtoastr() to format shor


From: Ben Pfaff
Subject: [formatting i18n 01/14] Use new Gnulib function dtoastr() to format short, accurate real numbers.
Date: Sat, 19 Feb 2011 17:42:13 -0800

%.*g with DBL_DIG + 1 as argument is simple but in rare cases it fails to
accurately format a real number.  The recently added Gnulib routine
dtoastr() always formats a real number accurately, so switch to using it
for these cases.
---
 Smake                      |    1 +
 src/data/csv-file-writer.c |    8 +++++---
 src/ui/syntax-gen.c        |   18 ++++++------------
 3 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/Smake b/Smake
index 5e05933..6d54f5b 100644
--- a/Smake
+++ b/Smake
@@ -17,6 +17,7 @@ GNULIB_MODULES = \
        crypto/md4 \
        crypto/md5 \
        dirname \
+       dtoastr \
        environ \
        fatal-signal \
        fcntl \
diff --git a/src/data/csv-file-writer.c b/src/data/csv-file-writer.c
index 70568c3..11b7429 100644
--- a/src/data/csv-file-writer.c
+++ b/src/data/csv-file-writer.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,6 +45,8 @@
 #include "libpspp/message.h"
 #include "libpspp/str.h"
 
+#include "gl/ftoastr.h"
+#include "gl/minmax.h"
 #include "gl/unlocked-io.h"
 #include "gl/xalloc.h"
 
@@ -280,7 +282,7 @@ csv_write_var__ (struct csv_writer *w, const struct csv_var 
*cv,
     csv_output_format (w, cv, value);
   else
     {
-      char s[128];
+      char s[MAX (DBL_STRLEN_BOUND, 128)];
 
       switch (cv->format.type)
         {
@@ -306,7 +308,7 @@ csv_write_var__ (struct csv_writer *w, const struct csv_var 
*cv,
         case FMT_RBHEX:
         case FMT_WKDAY:
         case FMT_MONTH:
-          snprintf (s, sizeof s, "%.*g", DBL_DIG + 1, value->f);
+          dtoastr (s, sizeof s, 0, 0, value->f);
           if (w->opts.decimal != '.')
             {
               char *cp = strchr (s, '.');
diff --git a/src/ui/syntax-gen.c b/src/ui/syntax-gen.c
index 35de44d..9221eae 100644
--- a/src/ui/syntax-gen.c
+++ b/src/ui/syntax-gen.c
@@ -30,6 +30,8 @@
 #include "libpspp/message.h"
 #include "libpspp/str.h"
 
+#include "gl/ftoastr.h"
+
 /* Appends to OUTPUT a pair of hex digits for each byte in IN. */
 static void
 syntax_gen_hex_digits (struct string *output, struct substring in)
@@ -172,18 +174,10 @@ syntax_gen_number (struct string *output,
     ds_put_cstr (output, "SYSMIS");
   else
     {
-      /* FIXME: This should consistently yield precisely the same
-         value as NUMBER on input, but its results for values
-         cannot be exactly represented in decimal are ugly: many
-         of them will have far more decimal digits than are
-         needed.  The free-format floating point output routine
-         from Steele and White, "How to Print Floating-Point
-         Numbers Accurately" is really what we want.  The MPFR
-         library has an implementation of this, or equivalent
-         functionality, in its mpfr_strtofr routine, but it would
-         not be nice to make PSPP depend on this.  Probably, we
-         should implement something equivalent to it. */
-      ds_put_format (output, "%.*g", DBL_DIG + 1, number);
+      char s[DBL_BUFSIZE_BOUND];
+
+      dtoastr (s, sizeof s, 0, 0, number);
+      ds_put_cstr (output, s);
     }
 }
 
-- 
1.7.2.3




reply via email to

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