diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c index 2919578870054837a42c9f56e2c58af0393be106..706b0fc84a093fc636c812947ed4d95165a1852a 100644 --- a/plugins/fn-math/functions.c +++ b/plugins/fn-math/functions.c @@ -13,6 +13,7 @@ #include "sheet.h" #include "str.h" #include "mathfunc.h" +#include "rangefunc.h" #include "collect.h" #include "auto-format.h" diff --git a/plugins/fn-stat/functions.c b/plugins/fn-stat/functions.c index a094cb30b327abecc114591f39e0ae680dc11533..581b6c3313967c3f5280d432343d87e916575837 100644 --- a/plugins/fn-stat/functions.c +++ b/plugins/fn-stat/functions.c @@ -11,6 +11,7 @@ #include "func-util.h" #include "parse-util.h" #include "mathfunc.h" +#include "rangefunc.h" #include "regression.h" #include "sheet.h" #include "cell.h" @@ -21,27 +22,6 @@ #include #include -static guint -float_hash (const gnum_float *d) -{ - guint h = 0; - size_t i; - const unsigned char *p = (const unsigned char *)d; - - for (i = 0; i < sizeof (gnum_float); i++) - h ^= h / 3 + (h << 9) + p[i]; - - return h; -} - -static gint -float_equal (const gnum_float *a, const gnum_float *b) -{ - if (*a == *b) - return 1; - return 0; -} - static gint float_compare (const gnum_float *a, const gnum_float *b) { @@ -735,50 +715,6 @@ static char *help_mode = { "@SEEALSO=AVERAGE,MEDIAN") }; -static void -cb_range_mode (gpointer key, gpointer value, gpointer user_data) -{ - g_free (value); -} - -static int -range_mode (const gnum_float *xs, int n, gnum_float *res) -{ - GHashTable *h; - int i; - gnum_float mode = 0; - int dups = 0; - - if (n <= 1) return 1; - - h = g_hash_table_new ((GHashFunc)float_hash, - (GCompareFunc)float_equal); - for (i = 0; i < n; i++) { - int *pdups = g_hash_table_lookup (h, &xs[i]); - - if (pdups) - (*pdups)++; - else { - pdups = g_new (int, 1); - *pdups = 1; - g_hash_table_insert (h, (gpointer)(&xs[i]), pdups); - } - - if (*pdups > dups) { - dups = *pdups; - mode = xs[i]; - } - } - g_hash_table_foreach (h, cb_range_mode, NULL); - g_hash_table_destroy (h); - - if (dups <= 1) - return 1; - - *res = mode; - return 0; -} - static Value * gnumeric_mode (FunctionEvalInfo *ei, GList *expr_node_list) { @@ -2379,29 +2315,12 @@ static char *help_median = { "@SEEALSO=AVERAGE,COUNT,COUNTA,DAVERAGE,MODE,SUM") }; -/* Special Excel-meaning of median. */ -static int -range_excel_median (const gnum_float *xs, int n, gnum_float *res) -{ - if (n > 0) { - /* OK, so we ignore the constness here. Tough. */ - qsort ((gnum_float *) xs, n, sizeof (xs[0]), - (void *) &float_compare); - if (n & 1) - *res = xs[n / 2]; - else - *res = (xs[n / 2 - 1] + xs[n / 2]) / 2; - return 0; - } else - return 1; -} - static Value * gnumeric_median (FunctionEvalInfo *ei, GList *expr_node_list) { return float_range_function (expr_node_list, ei, - range_excel_median, + range_median_inter, COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS | COLLECT_IGNORE_BLANKS, diff --git a/src/functions/fn-math.c b/src/functions/fn-math.c index 2919578870054837a42c9f56e2c58af0393be106..706b0fc84a093fc636c812947ed4d95165a1852a 100644 --- a/src/functions/fn-math.c +++ b/src/functions/fn-math.c @@ -13,6 +13,7 @@ #include "sheet.h" #include "str.h" #include "mathfunc.h" +#include "rangefunc.h" #include "collect.h" #include "auto-format.h" diff --git a/src/functions/fn-stat.c b/src/functions/fn-stat.c index a094cb30b327abecc114591f39e0ae680dc11533..581b6c3313967c3f5280d432343d87e916575837 100644 --- a/src/functions/fn-stat.c +++ b/src/functions/fn-stat.c @@ -11,6 +11,7 @@ #include "func-util.h" #include "parse-util.h" #include "mathfunc.h" +#include "rangefunc.h" #include "regression.h" #include "sheet.h" #include "cell.h" @@ -21,27 +22,6 @@ #include #include -static guint -float_hash (const gnum_float *d) -{ - guint h = 0; - size_t i; - const unsigned char *p = (const unsigned char *)d; - - for (i = 0; i < sizeof (gnum_float); i++) - h ^= h / 3 + (h << 9) + p[i]; - - return h; -} - -static gint -float_equal (const gnum_float *a, const gnum_float *b) -{ - if (*a == *b) - return 1; - return 0; -} - static gint float_compare (const gnum_float *a, const gnum_float *b) { @@ -735,50 +715,6 @@ static char *help_mode = { "@SEEALSO=AVERAGE,MEDIAN") }; -static void -cb_range_mode (gpointer key, gpointer value, gpointer user_data) -{ - g_free (value); -} - -static int -range_mode (const gnum_float *xs, int n, gnum_float *res) -{ - GHashTable *h; - int i; - gnum_float mode = 0; - int dups = 0; - - if (n <= 1) return 1; - - h = g_hash_table_new ((GHashFunc)float_hash, - (GCompareFunc)float_equal); - for (i = 0; i < n; i++) { - int *pdups = g_hash_table_lookup (h, &xs[i]); - - if (pdups) - (*pdups)++; - else { - pdups = g_new (int, 1); - *pdups = 1; - g_hash_table_insert (h, (gpointer)(&xs[i]), pdups); - } - - if (*pdups > dups) { - dups = *pdups; - mode = xs[i]; - } - } - g_hash_table_foreach (h, cb_range_mode, NULL); - g_hash_table_destroy (h); - - if (dups <= 1) - return 1; - - *res = mode; - return 0; -} - static Value * gnumeric_mode (FunctionEvalInfo *ei, GList *expr_node_list) { @@ -2379,29 +2315,12 @@ static char *help_median = { "@SEEALSO=AVERAGE,COUNT,COUNTA,DAVERAGE,MODE,SUM") }; -/* Special Excel-meaning of median. */ -static int -range_excel_median (const gnum_float *xs, int n, gnum_float *res) -{ - if (n > 0) { - /* OK, so we ignore the constness here. Tough. */ - qsort ((gnum_float *) xs, n, sizeof (xs[0]), - (void *) &float_compare); - if (n & 1) - *res = xs[n / 2]; - else - *res = (xs[n / 2 - 1] + xs[n / 2]) / 2; - return 0; - } else - return 1; -} - static Value * gnumeric_median (FunctionEvalInfo *ei, GList *expr_node_list) { return float_range_function (expr_node_list, ei, - range_excel_median, + range_median_inter, COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS | COLLECT_IGNORE_BLANKS,