From 722d896a394329ad9da31575439e1a082161fa6b Mon Sep 17 00:00:00 2001 From: John Darrington Date: Tue, 30 Dec 2003 14:25:24 +0000 Subject: [PATCH] Fixed floating point rounding problem --- ChangeLog | 4 ++++ configure.ac | 13 ++++--------- src/Makefile.am | 5 +++++ src/frequencies.q | 20 ++++++++++---------- src/output.h | 3 +++ tests/command/percentiles.sh | 2 +- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4d7e3b3..195f028a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Tue Dec 30 22:23:40 WST 2003 John Darrington + + * Fixed floating point rounding bug in percentiles calculation + Sat Dec 27 16:16:49 2003 Ben Pfaff * configure.ac: Add -Wmissing-prototypes flag to gcc. diff --git a/configure.ac b/configure.ac index be5cbc20..3975bff3 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ]) diff --git a/src/Makefile.am b/src/Makefile.am index 906f25cd..329711e2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/frequencies.q b/src/frequencies.q index 90385935..52f23357 100644 --- a/src/frequencies.q +++ b/src/frequencies.q @@ -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; diff --git a/src/output.h b/src/output.h index 00e5b23d..98f8d4f1 100644 --- a/src/output.h +++ b/src/output.h @@ -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 diff --git a/tests/command/percentiles.sh b/tests/command/percentiles.sh index 0d722300..aa7d81a8 100755 --- a/tests/command/percentiles.sh +++ b/tests/command/percentiles.sh @@ -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 -- 2.30.2