Change many %g format specifiers to %.*g with precision DBL_DIG + 1.
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 4 Feb 2014 05:37:53 +0000 (21:37 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 4 Feb 2014 05:37:53 +0000 (21:37 -0800)
The high precision should ensure that in most cases the value is formatted
with enough digits to fully express the internal precision.  Without this
change, %g by itself only expresses 6 digits of precision, so that an
integer value like 99999999 is formatted as 1e8.  This fixes the problem.

This commit adds a test to MISSING VALUES because this was in particular
reported as a problem.

Thanks to Andre Müller <Andre.Mueller@gesis.org> for reporting this issue.

28 files changed:
src/language/dictionary/sys-file-info.c
src/language/lexer/value-parser.c
src/language/stats/autorecode.c
src/language/stats/binomial.c
src/language/stats/cochran.c
src/language/stats/crosstabs.q
src/language/stats/descriptives.c
src/language/stats/oneway.c
src/language/stats/regression.c
src/language/stats/runs.c
src/language/utilities/set.q
src/language/xforms/compute.c
src/math/categoricals.c
src/output/cairo-chart.c
src/output/charts/plot-hist-cairo.c
src/ui/gui/aggregate-dialog.c
src/ui/gui/psppire-dialog-action-binomial.c
src/ui/gui/psppire-dialog-action-chisquare.c
src/ui/gui/psppire-dialog-action-factor.c
src/ui/gui/psppire-dialog-action-logistic.c
src/ui/gui/psppire-dialog-action-oneway.c
src/ui/gui/psppire-val-chooser.c
src/ui/gui/recode-dialog.c
src/ui/gui/select-cases-dialog.c
src/ui/gui/spreadsheet-test.c
tests/data/datasheet-test.c
tests/language/dictionary/missing-values.at
utilities/pspp-dump-sav.c

index 6f73d8316595510499de223931ad45698331f9ab..2fdbdaf3c2a1609107bbb1ff9e81325407978555 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -17,6 +17,7 @@
 #include <config.h>
 
 #include <ctype.h>
+#include <float.h>
 #include <stdlib.h>
 
 #include "data/attributes.h"
@@ -560,11 +561,13 @@ describe_variable (const struct variable *v, struct tab_table *t, int r,
           double x, y;
           mv_get_range (mv, &x, &y);
           if (x == LOWEST)
-            cp += sprintf (cp, "LOWEST THRU %g", y);
+            cp += sprintf (cp, "LOWEST THRU %.*g", DBL_DIG + 1, y);
           else if (y == HIGHEST)
-            cp += sprintf (cp, "%g THRU HIGHEST", x);
+            cp += sprintf (cp, "%.*g THRU HIGHEST", DBL_DIG + 1, x);
           else
-            cp += sprintf (cp, "%g THRU %g", x, y);
+            cp += sprintf (cp, "%.*g THRU %.*g",
+                           DBL_DIG + 1, x,
+                           DBL_DIG + 1, y);
           cnt++;
         }
       for (i = 0; i < mv_n_values (mv); i++)
@@ -573,7 +576,7 @@ describe_variable (const struct variable *v, struct tab_table *t, int r,
           if (cnt++ > 0)
             cp += sprintf (cp, "; ");
           if (var_is_numeric (v))
-            cp += sprintf (cp, "%g", value->f);
+            cp += sprintf (cp, "%.*g", DBL_DIG + 1, value->f);
           else
             {
               int width = var_get_width (v);
index 9d3d77f91656efee82cb8eac2d8b14b298a97ef1..65e34a348b86b41904b8eee9ac851c243666ae18 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2009, 2010, 2011, 2014 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
@@ -18,6 +18,7 @@
 
 #include "value-parser.h"
 
+#include <float.h>
 #include <stdbool.h>
 
 #include "data/data-in.h"
@@ -62,15 +63,15 @@ parse_num_range (struct lexer *lexer,
       if (*y < *x)
         {
           double t;
-          msg (SW, _("The high end of the range (%g) is below the low end (%g).  "
-                     "The range will be treated as if reversed."),
-               *y, *x);
+          msg (SW, _("The high end of the range (%.*g) is below the low end "
+                     "(%.*g).  The range will be treated as if reversed."),
+               DBL_DIG + 1, *y, DBL_DIG + 1, *x);
           t = *x;
           *x = *y;
           *y = t;
         }
       else if (*x == *y)
-        msg (SW, _("Ends of range are equal (%g)."), *x);
+        msg (SW, _("Ends of range are equal (%.*g)."), DBL_DIG + 1, *x);
 
       return true;
     }
index 7c1b766750fb4319218c34a7ff8a30f47e9cc6fe..dc357f7c4482496be6182c8698c53e820da24503 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2012, 2013, 2014 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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <stdlib.h>
 
 #include "data/case.h"
@@ -323,7 +324,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
                                              str, src_width);
            }
          else
-           recoded_value = c_xasprintf ("%g", from->f);
+           recoded_value = c_xasprintf ("%.*g", DBL_DIG + 1, from->f);
          
          /* Remove trailing whitespace */
           len = strlen (recoded_value);
index 94d0d9721e0b7f4c543d44a975ec8b8b9b7cbed0..8439a71b93919749c551f0abf75209a8d5f28452 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2009, 2010, 2011, 2014 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
@@ -18,6 +18,7 @@
 
 #include "language/stats/binomial.h"
 
+#include <float.h>
 #include <gsl/gsl_cdf.h>
 #include <gsl/gsl_randist.h>
 
@@ -202,7 +203,8 @@ binomial_execute (const struct dataset *ds,
 
          if ( bst->cutpoint != SYSMIS)
            {
-             ds_put_format (&catstr[0], "<= %g", bst->cutpoint);
+             ds_put_format (&catstr[0], "<= %.*g",
+                             DBL_DIG + 1, bst->cutpoint);
            }
           else
             {
index 3ea8fd342b81fa45b71d78dbe03cf7200c0bbc3a..869e5f5c8332759ede3a2fc602bac0150ff88ede 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011, 2014 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
@@ -18,6 +18,7 @@
 
 #include "language/stats/cochran.h"
 
+#include <float.h>
 #include <gsl/gsl_cdf.h>
 #include <stdbool.h>
 
@@ -169,8 +170,10 @@ show_freqs_box (const struct one_sample_test *ost, const struct cochran *ct)
   tab_joint_text (table, 1, 0, 2, 0,
                  TAT_TITLE | TAB_CENTER, _("Value"));
 
-  tab_text_format (table, 1, 1, 0, _("Success (%g)"), ct->success);
-  tab_text_format (table, 2, 1, 0, _("Failure (%g)"), ct->failure);
+  tab_text_format (table, 1, 1, 0, _("Success (%.*g)"),
+                   DBL_DIG + 1, ct->success);
+  tab_text_format (table, 2, 1, 0, _("Failure (%.*g)"),
+                   DBL_DIG + 1, ct->failure);
 
   tab_hline (table, TAL_2, 0, tab_nc (table) - 1, column_headers);
   tab_vline (table, TAL_2, row_headers, 0, tab_nr (table) - 1);
index 6adae77b030a674e81035da71ea6dd245652f828..bcb5a0ebacc5c546f2ab4127c5f33280b9a60379 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -29,6 +29,7 @@
 #include <config.h>
 
 #include <ctype.h>
+#include <float.h>
 #include <gsl/gsl_cdf.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -1944,8 +1945,8 @@ display_risk (struct pivot_table *pt, struct tab_table *risk)
        case 1:
        case 2:
          if (var_is_numeric (rv))
-           sprintf (buf, _("For cohort %s = %g"),
-                    var_to_string (rv), pt->rows[i - 1].f);
+           sprintf (buf, _("For cohort %s = %.*g"),
+                    var_to_string (rv), DBL_DIG + 1, pt->rows[i - 1].f);
          else
            sprintf (buf, _("For cohort %s = %.*s"),
                     var_to_string (rv),
index 413826cc9cdaa64c7e9b10d503f80ceae15dc57c..f80965616f0c1f5fc29b04a9a788440d8471f676 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-2000, 2009-2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-2000, 2009-2014 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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <limits.h>
 #include <math.h>
 #include <stdlib.h>
@@ -1002,17 +1003,18 @@ display (struct dsc_proc *dsc)
 
       nc = 0;
       tab_text (t, nc++, i + 1, TAB_LEFT, var_to_string (dv->v));
-      tab_text_format (t, nc++, i + 1, 0, "%g", dv->valid);
+      tab_text_format (t, nc++, i + 1, 0, "%.*g", DBL_DIG + 1, dv->valid);
       if (dsc->format == DSC_SERIAL)
-       tab_text_format (t, nc++, i + 1, 0, "%g", dv->missing);
+       tab_text_format (t, nc++, i + 1, 0, "%.*g", DBL_DIG + 1, dv->missing);
 
       for (j = 0; j < DSC_N_STATS; j++)
        if (dsc->show_stats & (1ul << j))
          tab_double (t, nc++, i + 1, TAB_NONE, dv->stats[j], NULL);
     }
 
-  tab_title (t, _("Valid cases = %g; cases with missing value(s) = %g."),
-            dsc->valid, dsc->missing_listwise);
+  tab_title (t, _("Valid cases = %.*g; cases with missing value(s) = %.*g."),
+            DBL_DIG + 1, dsc->valid,
+             DBL_DIG + 1, dsc->missing_listwise);
 
   tab_submit (t);
 }
index 70e6a3d0d84c909f9c5f20a477c25a7f0b147c72..807b5dc39f10b6e8bc5f2af2eb8637b97a4796b6 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <gsl/gsl_cdf.h>
 #include <gsl/gsl_matrix.h>
 #include <math.h>
@@ -1332,7 +1333,8 @@ show_contrast_coeffs (const struct oneway_spec *cmd, const struct oneway_workspa
 
          ds_destroy (&vstr);
 
-         tab_text_format (t, count + 2, c_num + 2, TAB_RIGHT, "%g", coeffn->coeff);
+         tab_text_format (t, count + 2, c_num + 2, TAB_RIGHT, "%.*g",
+                           DBL_DIG + 1, coeffn->coeff);
        }
       ++c_num;
     }
index 07188663fed2fe50793b10affb7b3f31f7aad958..0ef739a4e04e1d31a7a53b0089322ea9b8a7ef61 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <stdbool.h>
 
 #include <gsl/gsl_cdf.h>
@@ -949,9 +950,9 @@ reg_stats_anova (const linreg * c, const struct variable *var)
 
 
   /* Degrees of freedom */
-  tab_text_format (t, 3, 1, TAB_RIGHT, "%g", c->dfm);
-  tab_text_format (t, 3, 2, TAB_RIGHT, "%g", c->dfe);
-  tab_text_format (t, 3, 3, TAB_RIGHT, "%g", c->dft);
+  tab_text_format (t, 3, 1, TAB_RIGHT, "%.*g", DBL_DIG + 1, c->dfm);
+  tab_text_format (t, 3, 2, TAB_RIGHT, "%.*g", DBL_DIG + 1, c->dfe);
+  tab_text_format (t, 3, 3, TAB_RIGHT, "%.*g", DBL_DIG + 1, c->dft);
 
   /* Mean Squares */
   tab_double (t, 4, 1, TAB_RIGHT, msm, NULL);
index b3a1b4fdd80614e432d7fcc2a81a89be942ee20a..788aae0d13f107d26f769a9068c646e17b27732f 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis. -*-c-*-
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011, 2014 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
@@ -19,6 +19,7 @@
 
 #include "language/stats/runs.h"
 
+#include <float.h>
 #include <gsl/gsl_cdf.h>
 #include <math.h>
 
@@ -164,8 +165,9 @@ runs_execute (const struct dataset *ds,
              }
            casegrouper_destroy (grouper);
            if (multimodal)
-             msg (MW, _("Multiple modes exist for variable `%s'.  Using %g as the threshold value."),
-                  var_get_name (var), run->cutpoint);
+             msg (MW, _("Multiple modes exist for variable `%s'.  "
+                         "Using %.*g as the threshold value."),
+                  var_get_name (var), DBL_DIG + 1, run->cutpoint);
          }
       }
       break;
index 9a7e841707f535076bf1ad0126f454dd17aa1ba8..50ddd9443ed8dc92d956068e8d3d3f07b2e09fc1 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -624,7 +625,7 @@ show_blanks (const struct dataset *ds UNUSED)
 {
   return (settings_get_blanks () == SYSMIS
           ? xstrdup ("SYSMIS")
-          : xasprintf ("%g", settings_get_blanks ()));
+          : xasprintf ("%.*g", DBL_DIG + 1, settings_get_blanks ()));
 }
 
 static void
index 0ab4e3a4bb5ac44cdc6aeaf5a0251b4df2914833..00f7c5ad4706b4eec18f51872eb78640c32df110 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2014 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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <stdint.h>
 #include <stdlib.h>
 
@@ -150,9 +151,9 @@ compute_num_vec (void *compute_, struct ccase **c, casenumber case_num)
                        "as an index into vector %s."),
                  vector_get_name (compute->vector));
           else
-            msg (SW, _("When executing COMPUTE: %g is not a valid value as "
+            msg (SW, _("When executing COMPUTE: %.*g is not a valid value as "
                        "an index into vector %s."),
-                 index, vector_get_name (compute->vector));
+                 DBL_DIG + 1, index, vector_get_name (compute->vector));
           return TRNS_CONTINUE;
         }
 
@@ -208,9 +209,9 @@ compute_str_vec (void *compute_, struct ccase **c, casenumber case_num)
         }
       else if (rindx < 1 || rindx > vector_get_var_cnt (compute->vector))
         {
-          msg (SW, _("When executing COMPUTE: %g is not a valid value as "
+          msg (SW, _("When executing COMPUTE: %.*g is not a valid value as "
                      "an index into vector %s."),
-               index, vector_get_name (compute->vector));
+               DBL_DIG + 1, index, vector_get_name (compute->vector));
           return TRNS_CONTINUE;
         }
 
index d89dfdbb26b2c583513ff6d266ca4f2ac2e5a032..b1afd11c8ca4db16b549782a6f6b7fee6af95ca9 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2011, 2012, 2014 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
@@ -19,6 +19,7 @@
 #include "math/categoricals.h"
 #include "math/interaction.h"
 
+#include <float.h>
 #include <stdio.h>
 
 #include "data/case.h"
@@ -252,7 +253,7 @@ categoricals_dump (const struct categoricals *cat)
 
                  assert (vn->var == var);
 
-                 printf ("%g(%d)", val->f, valn->index);
+                 printf ("%.*g(%d)", DBL_DIG + 1, val->f, valn->index);
                  if (vv < iact->n_vars - 1)
                    printf (", ");
                }
index 42d1248146c2100a290f414dee04d1a0f6f9fd02..88e70493d6585c0f2e8b84f66c760f76e1bdd9db 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2009, 2010, 2011, 2014 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
@@ -367,7 +367,8 @@ xrchart_write_scale (cairo_t *cr, struct xrchart_geometry *geom,
     {
       double pos = (s + lower) * tick_interval;
       draw_tick (cr, geom, orient, false,
-                s * tick_interval * geom->axis[orient].scale, "%g", pos);
+                s * tick_interval * geom->axis[orient].scale, "%.*g",
+                 DBL_DIG + 1, pos);
     }
 }
 
index a9a5d44f58b475aef164f8fe9077008d4264ece8..93133c2e9e0acb46d93dab01a15f40fc8b234080 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2011, 2014 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
@@ -18,6 +18,7 @@
 
 #include "output/charts/plot-hist.h"
 
+#include <float.h>
 #include <gsl/gsl_randist.h>
 
 #include "data/val-type.h"
@@ -103,7 +104,8 @@ hist_draw_bar (cairo_t *cr, const struct xrchart_geometry *geom,
 
   if (label)
     draw_tick (cr, geom, SCALE_ABSCISSA, bins > 10,
-              x_pos + width / 2.0, "%g", (upper + lower) / 2.0);
+              x_pos + width / 2.0, "%.*g",
+               DBL_DIG + 1, (upper + lower) / 2.0);
 }
 
 void
index 60a8d9f96364cf04595cfb64f4104c689afb275d..e89943b6c4ad027f1c0362d6556ae1930780a9f8 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2010, 2011, 2012, 2013  Free Software Foundation
+   Copyright (C) 2010, 2011, 2012, 2013, 2014  Free Software Foundation
 
    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
@@ -18,6 +18,7 @@
 
 #include "dialog-common.h"
 
+#include <float.h>
 #include <gl/c-xvasprintf.h>
 #include <language/stats/aggregate.h>
 
@@ -432,11 +433,11 @@ on_acr_change (const struct aggregate *agg, GtkTreeView *tv)
   gtk_entry_set_text (GTK_ENTRY (agg->summary_var_label_entry), label);
   gtk_entry_set_text (GTK_ENTRY (agg->summary_sv_entry), srcvar);
   
-  text = c_xasprintf ("%g", arg1);
+  text = c_xasprintf ("%.*g", DBL_DIG + 1, arg1);
   gtk_entry_set_text (GTK_ENTRY (agg->summary_arg1_entry), text);
   g_free (text);
 
-  text = c_xasprintf ("%g", arg2);
+  text = c_xasprintf ("%.*g", DBL_DIG + 1, arg2);
   gtk_entry_set_text (GTK_ENTRY (agg->summary_arg2_entry), text);
   g_free (text);
 
@@ -681,10 +682,10 @@ append_summary_spec (const struct aggregate *agg, GtkTreeIter *iter, GString *st
       ds_put_cstr (&dss, srcvar);
 
       if ( arity > 0)
-       ds_put_c_format (&dss, ", %g", arg1);
+       ds_put_c_format (&dss, ", %.*g", DBL_DIG + 1, arg1);
 
       if ( arity > 1)
-       ds_put_c_format (&dss, ", %g", arg2);
+       ds_put_c_format (&dss, ", %.*g", DBL_DIG + 1, arg2);
 
       ds_put_cstr (&dss, ")");
 
index 2641684c1ca762d85818cff1cc435ee54854bd06..8c91ca3e059ea587f2a80c2c3d5c4968b1106dd2 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2012  Free Software Foundation
+   Copyright (C) 2012, 2014  Free Software Foundation
 
    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
@@ -20,6 +20,8 @@
 #include "psppire-dialog-action-binomial.h"
 #include "psppire-value-entry.h"
 
+#include <float.h>
+
 #include "dialog-common.h"
 #include "helper.h"
 #include <ui/syntax-gen.h>
@@ -141,7 +143,7 @@ generate_syntax (PsppireDialogAction *a)
   ds_init_cstr (&str, "NPAR TEST\n\t/BINOMIAL");
 
   if ( get_proportion (scd, &prop))
-    ds_put_c_format (&str, "(%g)", prop);
+    ds_put_c_format (&str, "(%.*g)", DBL_DIG + 1, prop);
 
   ds_put_cstr (&str, " =");
 
index 36c68c064e42d68f0c996eafb7f3ff07530a0c57..5ee3e879913ec8e1debd3b15578e9369eabc008d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2010, 2011, 2012, 2013  Free Software Foundation
+   Copyright (C) 2010, 2011, 2012, 2013, 2014  Free Software Foundation
 
    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
@@ -19,6 +19,8 @@
 
 #include "psppire-dialog-action-chisquare.h"
 
+#include <float.h>
+
 #include "psppire-var-view.h"
 
 #include "psppire-dialog.h"
@@ -80,7 +82,7 @@ generate_syntax (PsppireDialogAction *act)
 
          gtk_tree_model_get (GTK_TREE_MODEL (ls), &iter, 0, &v, -1);
 
-         ds_put_c_format (&dss, " %g", v);
+         ds_put_c_format (&dss, " %.*g", DBL_DIG + 1, v);
        }
     }
 
index 2c6b3e63b3882dbebe273838e1e2cfc84ce94d41..e1edf4a4839303560d0cc8c544d15ee4b70fdae8 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2009, 2010, 2011, 2012  Free Software Foundation
+   Copyright (C) 2009, 2010, 2011, 2012, 2014  Free Software Foundation
 
    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
@@ -19,6 +19,8 @@
 
 #include "psppire-dialog-action-factor.h"
 
+#include <float.h>
+
 #include "psppire-var-view.h"
 #include "dialog-common.h"
 #include "psppire-selector.h"
@@ -71,7 +73,8 @@ generate_syntax (PsppireDialogAction *act)
   if ( rd->extraction.explicit_nfactors )
     ds_put_c_format (&str, "FACTORS (%d)", rd->extraction.n_factors);
   else
-    ds_put_c_format (&str, "MINEIGEN (%g)", rd->extraction.mineigen);
+    ds_put_c_format (&str, "MINEIGEN (%.*g)",
+                     DBL_DIG + 1, rd->extraction.mineigen);
 
   /*
     The CRITERIA = ITERATE subcommand is overloaded.
index 1908bd98c79c2532fecb0827ecec0f8ce16a4594..2eec4c6b8118dae9afb37ebbe124d8033a78f966 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008, 2010, 2011, 2012  Free Software Foundation
+   Copyright (C) 2008, 2010, 2011, 2012, 2014  Free Software Foundation
 
    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
@@ -20,6 +20,8 @@
 #include "psppire-dialog-action-logistic.h"
 #include "psppire-value-entry.h"
 
+#include <float.h>
+
 #include "dialog-common.h"
 #include "helper.h"
 #include <ui/syntax-gen.h>
@@ -165,13 +167,14 @@ generate_syntax (PsppireDialogAction *a)
 
   ds_put_cstr (&str, "\n\t/CRITERIA =");
 
-  syntax_gen_pspp (&str, " CUT(%g)", rd->cut_point);
+  syntax_gen_pspp (&str, " CUT(%.*g)", DBL_DIG + 1, rd->cut_point);
 
   syntax_gen_pspp (&str, " ITERATE(%d)", rd->max_iterations);
 
   if (rd->conf)
     {
-      syntax_gen_pspp (&str, "\n\t/PRINT = CI(%g)", rd->conf_level);
+      syntax_gen_pspp (&str, "\n\t/PRINT = CI(%.*g)",
+                       DBL_DIG + 1, rd->conf_level);
     }
 
   if (rd->constant) 
index 66b80f6417e901b8b908102e573f33d0aaf557de..c817f71f152a983d8f9515b39cc2e4c15e924c96 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2012, 2013  Free Software Foundation
+   Copyright (C) 2012, 2013, 2014  Free Software Foundation
 
    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
@@ -19,6 +19,8 @@
 
 #include "psppire-dialog-action-oneway.h"
 
+#include <float.h>
+
 #include "psppire-var-view.h"
 #include "psppire-acr.h"
 
@@ -89,7 +91,7 @@ generate_syntax (PsppireDialogAction *act)
 
          gtk_tree_model_get (GTK_TREE_MODEL (ls), &iter, 0, &v, -1);
 
-         ds_put_c_format (&dss, " %g", v);
+         ds_put_c_format (&dss, " %.*g", DBL_DIG + 1, v);
        }
     }
 
@@ -177,7 +179,7 @@ list_store_changed (PsppireDialogActionOneway *csd)
       total += v;
     }
 
-  text = g_strdup_printf ("%g", total);
+  text = g_strdup_printf ("%.*g", DBL_DIG + 1, total);
 
   gtk_entry_set_text (GTK_ENTRY (csd->ctotal), text);
 
index eb233b4ae5d2ed87fd1f536b8e85c3252c90af95..c2c273542cbb7c7872dd3b67f92027d01cc30782 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2011  Free Software Foundation
+   Copyright (C) 2011, 2014  Free Software Foundation
 
    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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <gtk/gtk.h>
 #include "dialog-common.h"
 #include "psppire-val-chooser.h"
@@ -452,7 +453,7 @@ old_value_to_string (const GValue *src, GValue *dest)
     {
     case OV_NUMERIC:
       {
-       gchar *text = g_strdup_printf ("%g", ov->v.v);
+       gchar *text = g_strdup_printf ("%.*g", DBL_DIG + 1, ov->v.v);
        g_value_set_string (dest, text);
        g_free (text);
       }
@@ -476,10 +477,10 @@ old_value_to_string (const GValue *src, GValue *dest)
 
        g_unichar_to_utf8 (0x2013, en_dash);
 
-       text = g_strdup_printf ("%g %s %g",
-                                      ov->v.range[0],
-                                      en_dash,
-                                      ov->v.range[1]);
+       text = g_strdup_printf ("%.*g %s %.*g",
+                                DBL_DIG + 1, ov->v.range[0],
+                                en_dash,
+                                DBL_DIG + 1, ov->v.range[1]);
        g_value_set_string (dest, text);
        g_free (text);
       }
@@ -491,9 +492,9 @@ old_value_to_string (const GValue *src, GValue *dest)
 
        g_unichar_to_utf8 (0x2013, en_dash);
 
-       text = g_strdup_printf ("LOWEST %s %g",
+       text = g_strdup_printf ("LOWEST %s %.*g",
                                en_dash,
-                               ov->v.range[1]);
+                               DBL_DIG + 1, ov->v.range[1]);
 
        g_value_set_string (dest, text);
        g_free (text);
@@ -506,8 +507,8 @@ old_value_to_string (const GValue *src, GValue *dest)
 
        g_unichar_to_utf8 (0x2013, en_dash);
 
-       text = g_strdup_printf ("%g %s HIGHEST",
-                               ov->v.range[0],
+       text = g_strdup_printf ("%.*g %s HIGHEST",
+                               DBL_DIG + 1, ov->v.range[0],
                                en_dash);
 
        g_value_set_string (dest, text);
@@ -548,7 +549,7 @@ old_value_append_syntax (struct string *str, const struct old_value *ov)
   switch (ov->type)
     {
     case OV_NUMERIC:
-      ds_put_c_format (str, "%g", ov->v.v);
+      ds_put_c_format (str, "%.*g", DBL_DIG + 1, ov->v.v);
       break;
     case OV_STRING:
       {
@@ -568,17 +569,17 @@ old_value_append_syntax (struct string *str, const struct old_value *ov)
       ds_put_cstr (str, "ELSE");
       break;
     case OV_RANGE:
-      ds_put_c_format (str, "%g THRU %g",
-                             ov->v.range[0],
-                             ov->v.range[1]);
+      ds_put_c_format (str, "%.*g THRU %.*g",
+                       DBL_DIG + 1, ov->v.range[0],
+                       DBL_DIG + 1, ov->v.range[1]);
       break;
     case OV_LOW_UP:
-      ds_put_c_format (str, "LOWEST THRU %g",
-                             ov->v.range[1]);
+      ds_put_c_format (str, "LOWEST THRU %*gg",
+                       DBL_DIG + 1, ov->v.range[1]);
       break;
     case OV_HIGH_DOWN:
-      ds_put_c_format (str, "%g THRU HIGHEST",
-                             ov->v.range[0]);
+      ds_put_c_format (str, "%.*g THRU HIGHEST",
+                       DBL_DIG + 1, ov->v.range[0]);
       break;
     default:
       g_warning ("Invalid type in old recode value");
@@ -612,7 +613,7 @@ psppire_val_chooser_get_status (PsppireValChooser *vr, struct old_value *ov)
 static gchar *
 num_to_string (gdouble x)
 {
-  return g_strdup_printf ("%g", x);
+  return g_strdup_printf ("%.*g", DBL_DIG + 1, x);
 }
 
 
index f8d21336e131bc4d46bc832eef937c11f28e69dc..4ef8ae216d88f3a9825bf3555a5b0d81cbc36221 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2009, 2010, 2011, 2012  Free Software Foundation
+   Copyright (C) 2007, 2009, 2010, 2011, 2012, 2014  Free Software Foundation
 
    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
@@ -30,6 +30,7 @@
 
 #include <gtk/gtk.h>
 
+#include <float.h>
 #include <xalloc.h>
 #include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
@@ -104,7 +105,7 @@ new_value_to_string (const GValue *src, GValue *dest)
     {
     case NV_NUMERIC:
       {
-       gchar *text = g_strdup_printf ("%g", nv->v.v);
+       gchar *text = g_strdup_printf ("%.*g", DBL_DIG + 1, nv->v.v);
        g_value_set_string (dest, text);
        g_free (text);
       }
@@ -314,7 +315,7 @@ recode_different_dialog (PsppireDataWindow *de)
 static gchar *
 num_to_string (gdouble x)
 {
-  return g_strdup_printf ("%g", x);
+  return g_strdup_printf ("%.*g", DBL_DIG + 1, x);
 }
 
 /* Callback which gets called when a new row is selected
@@ -956,7 +957,7 @@ new_value_append_syntax (struct string *dds, const struct new_value *nv)
   switch (nv->type)
     {
     case NV_NUMERIC:
-      ds_put_c_format (dds, "%g", nv->v.v);
+      ds_put_c_format (dds, "%.*g", DBL_DIG + 1, nv->v.v);
       break;
     case NV_STRING:
       syntax_gen_string (dds, ss_cstr (nv->v.s));
index c3bc123c051f2fd42cc8a121ba316056ee148706..2b4634808b31f8004707e8b0b844f93183fba83d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2014 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
@@ -17,6 +17,7 @@
 #include <config.h>
 
 #include "select-cases-dialog.h"
+#include <float.h>
 #include <gtk/gtk.h>
 #include "executor.h"
 #include "psppire-dialog.h"
@@ -388,9 +389,9 @@ generate_syntax_filter (const struct select_cases_dialog *scd)
            gtk_spin_button_get_value (GTK_SPIN_BUTTON (scd->spinbutton));
 
          ds_put_c_format (&dss,
-                                 "COMPUTE %s = RV.UNIFORM (0,1) < %g.\n",
+                                 "COMPUTE %s = RV.UNIFORM (0,1) < %.*g.\n",
                                  filter,
-                                 percentage / 100.0 );
+                                  DBL_DIG + 1, percentage / 100.0 );
        }
       else
        {
index bec577821a68076fc20831580b00ed1bf3739677..af0d18c81c8f6e4b082ff5092aa684198b529ceb 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2013  Free Software Foundation
+   Copyright (C) 2013, 2014  Free Software Foundation
 
    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
@@ -19,6 +19,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <gtk/gtk.h>
 
 #include "psppire-spreadsheet-model.h"
@@ -78,7 +79,7 @@ on_clicked (GtkButton *button, struct xxx *stuff)
        const int width = caseproto_get_width (proto, i);
        const union value *val = case_data_idx (c, i);
        if (0 == width)
-         printf ("%g ", val->f);
+         printf ("%.*g ", DBL_DIG + 1, val->f);
        else
          {
            char *ss = xzalloc (width + 1);
index 532b883faa1980f0671e249a27a9b1d71c5728ee..db21ff33fe658e132fa8769f15a31ab2ca887fa0 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2010, 2014 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
@@ -19,6 +19,7 @@
 #include <data/datasheet.h>
 
 #include <ctype.h>
+#include <float.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
@@ -153,9 +154,10 @@ check_datasheet_casereader (struct mc *mc, struct casereader *reader,
                 {
                   if (width == 0)
                     mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: "
-                              "%g != %g",
+                              "%.*g != %.*g",
                               row, col, n_rows, n_columns,
-                              case_num_idx (c, col), array[row][col].f);
+                              DBL_DIG + 1, case_num_idx (c, col),
+                              DBL_DIG + 1, array[row][col].f);
                   else
                     mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: "
                               "'%.*s' != '%.*s'",
@@ -217,8 +219,8 @@ check_datasheet (struct mc *mc, struct datasheet *ds,
               {
                 if (width == 0)
                   mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: "
-                            "%g != %g", row, col, n_rows, n_columns,
-                            v.f, av->f);
+                            "%.*g != %.*g", row, col, n_rows, n_columns,
+                            DBL_DIG + 1, v.f, DBL_DIG + 1, av->f);
                 else
                   mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: "
                             "'%.*s' != '%.*s'",
index 75254462aa0ea3bc39cffec96897b3cd9a7ea15a..84ee1725296e4a2d3db1f7d795958821a6d5cec9 100644 (file)
@@ -7,38 +7,159 @@ DATA LIST NOTABLE/str1 1-5 (A) str2 6-8 (A) date1 9-19 (DATE) num1 20-25
 
 * Numeric missing values.
 MISSING VALUES date1 num1 (1).
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES date1 num1 (1, 2).
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES date1 num1 (1, 2, 3).
+DISPLAY DICTIONARY date1 num1.
+MISSING VALUES date1 num1 (9999998, 9999984, 3).
+DISPLAY DICTIONARY date1 num1.
 
 * Numeric missing values using the first variable's format.
 MISSING VALUES num1 date1 ('1').
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES num1 date1 ('1', '2').
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES num1 date1 ('1', '2', '3').
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES date1 num1 ('06-AUG-05').
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES date1 num1 ('06-AUG-05', '01-OCT-78').
+DISPLAY DICTIONARY date1 num1.
 MISSING VALUES date1 num1 ('06-AUG-05', '01-OCT-78', '14-FEB-81').
+DISPLAY DICTIONARY date1 num1.
 
 * Ranges of numeric missing values.
 MISSING VALUES num1 (1 THRU 2).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (LO THRU 2).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (LOWEST THRU 2).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (1 THRU HI).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (1 THRU HIGHEST).
+DISPLAY DICTIONARY num1.
 
 * A range of numeric missing values, plus an individual value.
 MISSING VALUES num1 (1 THRU 2, 3).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (LO THRU 2, 3).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (LOWEST THRU 2, 3).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (1 THRU HI, -1).
+DISPLAY DICTIONARY num1.
 MISSING VALUES num1 (1 THRU HIGHEST, -1).
+DISPLAY DICTIONARY num1.
 
 * String missing values.
 MISSING VALUES str1 str2 longstr ('abc  ','def').
+DISPLAY DICTIONARY str1 str2 longstr.
 
 * May mix variable types when clearing missing values.
 MISSING VALUES ALL ().
+DISPLAY DICTIONARY
+])
+AT_CHECK([pspp -o pspp.csv missing-values.sps])
+AT_CHECK([sed -n '/Format/s/,.*/:/p
+s/"//g
+s/^,Missing Values: \([[^,]]*\),.*/\1/p
+/^$/p' pspp.csv
+], [0], [dnl
+date1:
+1
+num1:
+1
+
+date1:
+1; 2
+num1:
+1; 2
+
+date1:
+1; 2; 3
+num1:
+1; 2; 3
+
+date1:
+9999998; 9999984; 3
+num1:
+9999998; 9999984; 3
+
+date1:
+1
+num1:
+1
+
+date1:
+1; 2
+num1:
+1; 2
+
+date1:
+1; 2; 3
+num1:
+1; 2; 3
+
+date1:
+13342665600
+num1:
+13342665600
+
+date1:
+13342665600; 12495427200
+num1:
+13342665600; 12495427200
+
+date1:
+13342665600; 12495427200; 12570336000
+num1:
+13342665600; 12495427200; 12570336000
+
+num1:
+1 THRU 2
+
+num1:
+LOWEST THRU 2
+
+num1:
+LOWEST THRU 2
+
+num1:
+1 THRU HIGHEST
+
+num1:
+1 THRU HIGHEST
+
+num1:
+1 THRU 2; 3
+
+num1:
+LOWEST THRU 2; 3
+
+num1:
+LOWEST THRU 2; 3
+
+num1:
+1 THRU HIGHEST; -1
+
+num1:
+1 THRU HIGHEST; -1
+
+str1:
+abc  ; def  @&t@
+str2:
+abc; def
+longstr:
+abc     ; def     @&t@
+
+str1:
+str2:
+date1:
+num1:
+longstr:
 ])
-AT_CHECK([pspp -O format=csv missing-values.sps])
 AT_CLEANUP
 
 AT_SETUP([MISSING VALUES invalid cases])
index ceabd1d57d4b3df973bfdf6129addc1777e1e675..788c34f76b7527612eaefe03cbfecc73d68fa1f5 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -18,6 +18,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <float.h>
 #include <getopt.h>
 #include <inttypes.h>
 #include <limits.h>
@@ -332,7 +333,7 @@ read_header (struct sfm_reader *r)
           : "<error>");
   printf ("\t%17s: %"PRId32"\n", "Weight index", weight_index);
   printf ("\t%17s: %"PRId32"\n", "Number of cases", ncases);
-  printf ("\t%17s: %g\n", "Compression bias", r->bias);
+  printf ("\t%17s: %.*g\n", "Compression bias", DBL_DIG + 1, r->bias);
   printf ("\t%17s: %s\n", "Creation date", creation_date);
   printf ("\t%17s: %s\n", "Creation time", creation_time);
   printf ("\t%17s: \"%s\"\n", "File label", file_label);
@@ -476,11 +477,11 @@ read_variable_record (struct sfm_reader *r)
             {
               double low = read_float (r);
               double high = read_float (r);
-              printf (" %g...%g", low, high);
+              printf (" %.*g...%.*g", DBL_DIG + 1, low, DBL_DIG + 1, high);
               missing_value_code = -missing_value_code - 2;
             }
           for (i = 0; i < missing_value_code; i++)
-            printf (" %g", read_float (r));
+            printf (" %.*g", DBL_DIG + 1, read_float (r));
         }
       else if (width > 0)
         {
@@ -509,7 +510,7 @@ print_untyped_value (struct sfm_reader *r, char raw_value[8])
     if (!isprint (raw_value[n_printable]))
       break;
 
-  printf ("%g/\"%.*s\"", value, n_printable, raw_value);
+  printf ("%.*g/\"%.*s\"", DBL_DIG + 1, value, n_printable, raw_value);
 }
 
 /* Reads value labels from sysfile R and inserts them into the
@@ -718,20 +719,20 @@ read_machine_float_info (struct sfm_reader *r, size_t size, size_t count)
     sys_error (r, "Bad size (%zu) or count (%zu) on extension 4.",
                size, count);
 
-  printf ("\tsysmis: %g (%a)\n", sysmis, sysmis);
+  printf ("\tsysmis: %.*g (%a)\n", DBL_DIG + 1, sysmis, sysmis);
   if (sysmis != SYSMIS)
-    sys_warn (r, "File specifies unexpected value %g (%a) as %s.",
-              sysmis, sysmis, "SYSMIS");
+    sys_warn (r, "File specifies unexpected value %.*g (%a) as %s.",
+              DBL_DIG + 1, sysmis, sysmis, "SYSMIS");
 
-  printf ("\thighest: %g (%a)\n", highest, highest);
+  printf ("\thighest: %.*g (%a)\n", DBL_DIG + 1, highest, highest);
   if (highest != HIGHEST)
-    sys_warn (r, "File specifies unexpected value %g (%a) as %s.",
-              highest, highest, "HIGHEST");
+    sys_warn (r, "File specifies unexpected value %.*g (%a) as %s.",
+              DBL_DIG + 1, highest, highest, "HIGHEST");
 
-  printf ("\tlowest: %g (%a)\n", lowest, lowest);
+  printf ("\tlowest: %.*g (%a)\n", DBL_DIG + 1, lowest, lowest);
   if (lowest != LOWEST && lowest != SYSMIS)
-    sys_warn (r, "File specifies unexpected value %g (%a) as %s.",
-              lowest, lowest, "LOWEST");
+    sys_warn (r, "File specifies unexpected value %.*g (%a) as %s.",
+              DBL_DIG + 1, lowest, lowest, "LOWEST");
 }
 
 static void
@@ -1254,7 +1255,7 @@ read_simple_compressed_data (struct sfm_reader *r, int max_cases)
           switch (opcode)
             {
             default:
-              printf ("%g", opcode - r->bias);
+              printf ("%.*g", DBL_DIG + 1, opcode - r->bias);
               if (width != 0)
                 printf (", but this is a string variable (width=%d)", width);
               printf ("\n");