[gnumeric] SUMPRODUCT: improve accuracy
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] SUMPRODUCT: improve accuracy
- Date: Fri, 25 Nov 2011 18:51:06 +0000 (UTC)
commit 0492a6e9dbae404e055e9ace3066497f97a8af6d
Author: Morten Welinder <terra gnome org>
Date: Fri Nov 25 13:50:50 2011 -0500
SUMPRODUCT: improve accuracy
configure.in | 2 +-
plugins/fn-math/ChangeLog | 4 ++++
plugins/fn-math/functions.c | 21 +++++++++++++++------
src/numbers.h | 24 ++++++++++++++++++++++++
4 files changed, 44 insertions(+), 7 deletions(-)
---
diff --git a/configure.in b/configure.in
index bd05d56..3b6daef 100644
--- a/configure.in
+++ b/configure.in
@@ -145,7 +145,7 @@ PKG_PROG_PKG_CONFIG(0.18)
dnl *****************************
libspreadsheet_reqs="
- libgoffice-${GOFFICE_API_VER} >= 0.9.0
+ libgoffice-${GOFFICE_API_VER} >= 0.9.1
libgsf-1 >= 1.14.18
libxml-2.0 >= 2.4.12
"
diff --git a/plugins/fn-math/ChangeLog b/plugins/fn-math/ChangeLog
index 1883e9e..85152a4 100644
--- a/plugins/fn-math/ChangeLog
+++ b/plugins/fn-math/ChangeLog
@@ -1,3 +1,7 @@
+2011-11-25 Morten Welinder <terra gnome org>
+
+ * functions.c (gnumeric_sumproduct_common): Improve accuracy.
+
2011-11-24 Morten Welinder <terra gnome org>
* Release 1.11.0
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index 108541a..931c6f9 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -3056,17 +3056,26 @@ gnumeric_sumproduct_common (gboolean ignore_bools, GnmFuncEvalInfo *ei,
*/
result = value_new_error_VALUE (ei->pos);
} else {
- gnm_float sum = 0;
+
+ void *state = gnm_accumulator_start ();
+ GnmAccumulator *acc = gnm_accumulator_new ();
int j;
for (j = 0; j < sizex * sizey; j++) {
- gnm_float product = data[0][j];
- for (i = 1; i < argc; i++)
- product *= data[i][j];
- sum += product;
+ int i;
+ GnmQuad product;
+ gnm_quad_init (&product, data[0][j]);
+ for (i = 1; i < argc; i++) {
+ GnmQuad q;
+ gnm_quad_init (&q, data[i][j]);
+ gnm_quad_mul (&product, &product, &q);
+ }
+ gnm_accumulator_add_quad (acc, &product);
}
- result = value_new_float (sum);
+ result = value_new_float (gnm_accumulator_value (acc));
+ gnm_accumulator_free (acc);
+ gnm_accumulator_end (state);
}
done:
diff --git a/src/numbers.h b/src/numbers.h
index 2c8ee4e..112f339 100644
--- a/src/numbers.h
+++ b/src/numbers.h
@@ -120,6 +120,18 @@ gnm_float gnm_yn (int n, gnm_float x);
#define GNM_EPSILON LDBL_EPSILON
#define GNM_const(_c) _c ## L
+#define GnmQuad GOQuadl
+#define gnm_quad_init go_quad_initl
+#define gnm_quad_mul go_quad_mull
+#define GnmAccumulator GOAccumulatorl
+#define gnm_accumulator_start go_accumulator_startl
+#define gnm_accumulator_end go_accumulator_endl
+#define gnm_accumulator_new go_accumulator_newl
+#define gnm_accumulator_free go_accumulator_freel
+#define gnm_accumulator_add go_accumulator_addl
+#define gnm_accumulator_add_quad go_accumulator_add_quadl
+#define gnm_accumulator_value go_accumulator_valuel
+
#else /* !GNM_WITH_LONG_DOUBLE */
typedef double gnm_float;
@@ -190,6 +202,18 @@ typedef double gnm_float;
#define GNM_EPSILON DBL_EPSILON
#define GNM_const(_c) _c
+#define GnmQuad GOQuad
+#define gnm_quad_init go_quad_init
+#define gnm_quad_mul go_quad_mul
+#define GnmAccumulator GOAccumulator
+#define gnm_accumulator_start go_accumulator_start
+#define gnm_accumulator_end go_accumulator_end
+#define gnm_accumulator_new go_accumulator_new
+#define gnm_accumulator_free go_accumulator_free
+#define gnm_accumulator_add go_accumulator_add
+#define gnm_accumulator_add_quad go_accumulator_add_quad
+#define gnm_accumulator_value go_accumulator_value
+
#endif
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]