Fixed floating point rounding problem
authorJohn Darrington <john@darrington.wattle.id.au>
Tue, 30 Dec 2003 14:25:24 +0000 (14:25 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Tue, 30 Dec 2003 14:25:24 +0000 (14:25 +0000)
ChangeLog
configure.ac
src/Makefile.am
src/frequencies.q
src/output.h
tests/command/percentiles.sh

index e4d7e3b335eb8055ecdbc70c142b43c75f650c03..195f028aff831207c964e30f88a16ec036029820 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Tue Dec 30 22:23:40 WST 2003 John Darrington <john@darrington.wattle.id.au>
+       
+       * Fixed floating point rounding bug in percentiles calculation
+
 Sat Dec 27 16:16:49 2003  Ben Pfaff  <blp@gnu.org>
 
        * configure.ac: Add -Wmissing-prototypes flag to gcc.
index be5cbc2033079f45ea903f3a0028cd0b1343a9ba..3975bff3df08465ba940aea8b4daade73516f82c 100644 (file)
@@ -10,6 +10,9 @@ dnl Checks for programs.
 AC_GNU_SOURCE
 AC_PROG_CC
 
+AM_CONDITIONAL(cc_is_gcc, test x"$GCC" = x"yes" )
+
+
 dnl Internationalization macros.
 AM_GNU_GETTEXT
 AM_GNU_GETTEXT_VERSION dnl Prevents autoreconf complaint.
@@ -89,15 +92,7 @@ AC_CHECK_FUNCS([gethostname strstr strtod __setfpucw isinf isnan finite \
 
 AC_PROG_LN_S
 
-dnl This must be after other tests so warnings don't provoke errors above.
-if test "$ac_cv_c_compiler_gnu" = yes; then
-       CFLAGS="-g -Wall -W -Wno-uninitialized -Wwrite-strings \
--Wstrict-prototypes -Wpointer-arith -Wno-sign-compare -Wmissing-prototypes"
-       if test "$CC_OPTIONS" != ""; then
-               CFLAGS="$CFLAGS $CC_OPTIONS"
-       fi
-fi
-AC_SUBST(CFLAGS)
+
 
 AH_BOTTOM([#include <pref.h>])
 
index 906f25cd1e02b770a6f5236f5151c9916810dabd..329711e2a51379c464992cdb8e2f2e8ff311c078 100644 (file)
@@ -11,6 +11,11 @@ bin_PROGRAMS = pspp
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/lib  \
 -I$(top_srcdir)/intl
 
+if cc_is_gcc
+AM_CFLAGS=-Wall -W -Wno-uninitialized -Wwrite-strings -Wstrict-prototypes \
+-Wpointer-arith -Wno-sign-compare -Wmissing-prototypes 
+endif
+
 DISTCLEANFILES = foo $(q_sources_c)
 MAINTAINERCLEANFILES = Makefile.in
 EXTRA_DIST = $(q_sources_q) q2c.c
index 90385935ed98400831424ff2fd04e0680a86dc51..52f23357473e628f85839a9aca55d57da507ae61 100644 (file)
@@ -981,7 +981,7 @@ dump_full (struct variable * v)
   struct freq *f;
   struct tab_table *t;
   int r;
-  double cum_percent = 0.0;
+  double cum_total = 0.0;
   double cum_freq = 0.0;
 
   struct init
@@ -1030,7 +1030,7 @@ dump_full (struct variable * v)
 
       percent = f->c / v->p.frq.tab.total_cases * 100.0;
       valid_percent = f->c / v->p.frq.tab.valid_cases * 100.0;
-      cum_percent += valid_percent;
+      cum_total += valid_percent;
 
       if (lab)
        {
@@ -1043,7 +1043,7 @@ dump_full (struct variable * v)
       tab_float (t, 1 + lab, r, TAB_NONE, f->c, 8, 0);
       tab_float (t, 2 + lab, r, TAB_NONE, percent, 5, 1);
       tab_float (t, 3 + lab, r, TAB_NONE, valid_percent, 5, 1);
-      tab_float (t, 4 + lab, r, TAB_NONE, cum_percent, 5, 1);
+      tab_float (t, 4 + lab, r, TAB_NONE, cum_total, 5, 1);
       r++;
     }
   for (; f < &v->p.frq.tab.valid[n_categories]; f++)
@@ -1107,7 +1107,7 @@ dump_condensed (struct variable * v)
   struct freq *f;
   struct tab_table *t;
   int r;
-  double cum_percent = 0.0;
+  double cum_total = 0.0;
 
   n_categories = v->p.frq.tab.n_valid + v->p.frq.tab.n_missing;
   t = tab_create (4, n_categories + 2, 0);
@@ -1126,12 +1126,12 @@ dump_condensed (struct variable * v)
       double percent;
 
       percent = f->c / v->p.frq.tab.total_cases * 100.0;
-      cum_percent += f->c / v->p.frq.tab.valid_cases * 100.0;
+      cum_total += f->c / v->p.frq.tab.valid_cases * 100.0;
 
       tab_value (t, 0, r, TAB_NONE, &f->v, &v->print);
       tab_float (t, 1, r, TAB_NONE, f->c, 8, 0);
       tab_float (t, 2, r, TAB_NONE, percent, 3, 0);
-      tab_float (t, 3, r, TAB_NONE, cum_percent, 3, 0);
+      tab_float (t, 3, r, TAB_NONE, cum_total, 3, 0);
       r++;
     }
   for (; f < &v->p.frq.tab.valid[n_categories]; f++)
@@ -1164,7 +1164,7 @@ calc_stats (struct variable * v, double d[frq_n_stats])
   struct freq *f;
   int most_often;
 
-  double cum_percent;
+  double cum_total;
   int i = 0;
   double previous_value;
 
@@ -1175,14 +1175,14 @@ calc_stats (struct variable * v, double d[frq_n_stats])
   X_bar /= W;
 
   /* Calculate percentiles. */
-  cum_percent = 0;
+  cum_total = 0;
   previous_value = SYSMIS;
   for (f = v->p.frq.tab.valid; f < v->p.frq.tab.missing; f++)
     {
-      cum_percent += f->c / v->p.frq.tab.valid_cases;
+      cum_total += f->c ;
       for (; i < n_percentiles; i++) 
         {
-          if (cum_percent <= percentiles[i])
+          if (cum_total / v->p.frq.tab.valid_cases < percentiles[i])
             break;
 
           percentile_values[i] = previous_value;
index 00e5b23db6ac9bc8dedc118b2b1084999278c4b0..98f8d4f122368d82828c99f8d703f2051f460a1b 100644 (file)
@@ -29,6 +29,7 @@ struct rect
     int x2, y2;                        /* Lower right, not part of the rectangle. */
   };
 
+#if 0
 #if __GNUC__ > 1 && defined(__OPTIMIZE__)
 extern inline int width (rect r) __attribute__ ((const));
 extern inline int height (rect r) __attribute__ ((const));
@@ -45,11 +46,13 @@ height (rect r)
   return r.y2 - r.y1 + 1;
 }
 #else /* !__GNUC__ */
+/* Be carefull of these ... they use the argument more than once. */
 #define width(R)                               \
        ((R).x2 - (R).x1 + 1)
 #define height(R)                              \
        ((R).y2 - (R).y1 + 1)
 #endif /* !__GNUC__ */
+#endif
 
 /* Color descriptor. */
 struct color
index 0d722300cfc73ea2ffa6435994a1bdd66d45960f..aa7d81a8031f5168fe4022326de1402929fd3d5e 100755 (executable)
@@ -110,7 +110,7 @@ Maximum         .100
 Sum             .550
 Percentile 5    .   
 Percentile 10   .010
-Percentile 29   .030
+Percentile 29   .020
 Percentile 90   .090
 EOF
 if [ $? -ne 0 ] ; then fail ; fi