summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2022-03-05 20:36:40 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2022-03-05 20:36:40 +0000
commit0b4e9a4f0b3bfa7d3bc3a40239b41d85a15a44be (patch)
tree61e7578506db92c72e14731f82feed6fb6a4c155 /src
parent34d47efef8978b93ca87d798b78f84f58254dd91 (diff)
downloadrspamd-0b4e9a4f0b3bfa7d3bc3a40239b41d85a15a44be.tar.gz
rspamd-0b4e9a4f0b3bfa7d3bc3a40239b41d85a15a44be.zip
[Minor] Move summation to a separate routine
Diffstat (limited to 'src')
-rw-r--r--src/libutil/util.c23
-rw-r--r--src/libutil/util.h8
2 files changed, 31 insertions, 0 deletions
diff --git a/src/libutil/util.c b/src/libutil/util.c
index e7348982b..44f40280b 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -2456,3 +2456,26 @@ rspamd_ptr_array_shuffle (GPtrArray *ar)
g_ptr_array_index (ar, i) = t;
}
}
+
+float
+rspamd_sum_floats (float *ar, gsize *nelts)
+{
+ float sum = 0.0f;
+ volatile float c = 0.0f; /* We don't want any optimisations around c */
+ gsize cnt = 0;
+
+ for (gsize i = 0; i < *nelts; i ++) {
+ float elt = ar[i];
+
+ if (!isnan(elt)) {
+ cnt ++;
+ float y = elt - c;
+ float t = sum + y;
+ c = (t - sum) - y;
+ sum = t;
+ }
+ }
+
+ *nelts = cnt;
+ return sum;
+}
diff --git a/src/libutil/util.h b/src/libutil/util.h
index 0eff1c990..1d53807d4 100644
--- a/src/libutil/util.h
+++ b/src/libutil/util.h
@@ -518,6 +518,14 @@ struct rspamd_controller_pbkdf {
extern const struct rspamd_controller_pbkdf pbkdf_list[];
+/**
+ * Sum array of floats using Kahan sum algorithm
+ * @param ar
+ * @param nelts
+ * @return
+ */
+float rspamd_sum_floats (float *ar, gsize *nelts);
+
#ifdef __cplusplus
}
#endif