gnumeric r16853 - in trunk: . plugins/fn-financial src
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16853 - in trunk: . plugins/fn-financial src
- Date: Fri, 3 Oct 2008 23:55:55 +0000 (UTC)
Author: mortenw
Date: Fri Oct 3 23:55:55 2008
New Revision: 16853
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16853&view=rev
Log:
2008-10-03 Morten Welinder <terra gnome org>
* functions.c (gnumeric_xirr): Use float_range_function2d to
handle pairing. Fixes #554732.
2008-10-03 Morten Welinder <terra gnome org>
* src/collect.c (float_range_function2d): New function.
(float_range_function2): Implement in terms on
float_range_function2d.
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/plugins/fn-financial/ChangeLog
trunk/plugins/fn-financial/functions.c
trunk/src/collect.c
trunk/src/collect.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Fri Oct 3 23:55:55 2008
@@ -46,6 +46,7 @@
* Fix SUMIF crash. [#552006]
* Fix NETWORKDAYS problem. [#553047]
* Bring SUMX2MY2, SUMX2PY2, and SUMXMY2 into 21st century. [#554040]
+ * Fix XIRR problem with missing data. [#554732]
Nakai:
* Enable Perl plugin again. [#553939]
Modified: trunk/plugins/fn-financial/functions.c
==============================================================================
--- trunk/plugins/fn-financial/functions.c (original)
+++ trunk/plugins/fn-financial/functions.c Fri Oct 3 23:55:55 2008
@@ -1935,66 +1935,47 @@
};
typedef struct {
- int n;
- gnm_float *values;
- gnm_float *dates;
+ int n;
+ const gnm_float *values;
+ const gnm_float *dates;
} gnumeric_xirr_t;
static GoalSeekStatus
xirr_npv (gnm_float rate, gnm_float *y, void *user_data)
{
- gnumeric_xirr_t *p = user_data;
- gnm_float *values, *dates, sum;
- int i, n;
-
- values = p->values;
- dates = p->dates;
- n = p->n;
-
- sum = 0;
- for (i = 0; i < n; i++) {
- gnm_float d = dates[i] - dates[0];
+ const gnumeric_xirr_t *p = user_data;
+ gnm_float sum = 0;
+ int i;
+
+ for (i = 0; i < p->n; i++) {
+ gnm_float d = p->dates[i] - p->dates[0];
if (d < 0)
return GOAL_SEEK_ERROR;
- sum += values[i] / pow1p (rate, d / 365.0);
+ sum += p->values[i] / pow1p (rate, d / 365.0);
}
*y = sum;
return GOAL_SEEK_OK;
}
-static GnmValue *
-gnumeric_xirr (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+static int
+gnm_range_xirr (gnm_float const *xs, const gnm_float *ys,
+ int n, gnm_float *res, gpointer user)
{
- GoalSeekData data;
- GoalSeekStatus status;
- GnmValue *result = NULL;
gnumeric_xirr_t p;
- gnm_float rate0;
- int n, d_n;
+ gnm_float rate0 = *(gnm_float *)user;
+ GoalSeekData data;
+ GoalSeekStatus status;
+
+ p.dates = ys;
+ p.values = xs;
+ p.n = n;
goal_seek_initialize (&data);
data.xmin = -1;
data.xmax = MIN (1000, data.xmax);
- rate0 = argv[2] ? value_get_as_float (argv[2]) : 0.1;
-
- p.values = collect_floats_value (argv[0], ei->pos,
- COLLECT_COERCE_STRINGS,
- &n, &result);
- p.dates = NULL;
-
- if (result != NULL)
- goto out;
-
- p.dates = collect_floats_value (argv[1], ei->pos,
- COLLECT_COERCE_STRINGS,
- &d_n, &result);
- if (result != NULL)
- goto out;
-
- p.n = n;
status = goal_seek_newton (&xirr_npv, NULL, &data, &p, rate0);
if (status != GOAL_SEEK_OK) {
int i;
@@ -2007,16 +1988,30 @@
}
}
- if (status == GOAL_SEEK_OK)
- result = value_new_float (data.root);
- else
- result = value_new_error_NUM (ei->pos);
+ if (status == GOAL_SEEK_OK) {
+ *res = data.root;
+ return 0;
+ }
- out:
- g_free (p.values);
- g_free (p.dates);
+ return 1;
+}
- return result;
+
+static GnmValue *
+gnumeric_xirr (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+ gnm_float rate0 = argv[2] ? value_get_as_float (argv[2]) : 0.1;
+
+ /* Strings in a constant array need to be coerced -- finfuns.xls */
+ /* FIXME: check strings in ranges and weep. */
+ return float_range_function2d (argv[0], argv[1],
+ ei,
+ gnm_range_xirr,
+ COLLECT_IGNORE_BLANKS |
+ COLLECT_COERCE_STRINGS |
+ COLLECT_IGNORE_BOOLS,
+ GNM_ERROR_VALUE,
+ &rate0);
}
/***************************************************************************/
Modified: trunk/src/collect.c
==============================================================================
--- trunk/src/collect.c (original)
+++ trunk/src/collect.c Fri Oct 3 23:55:55 2008
@@ -342,11 +342,12 @@
}
GnmValue *
-float_range_function2 (GnmValue const *val0, GnmValue const *val1,
- GnmFuncEvalInfo *ei,
- float_range_function2_t func,
- CollectFlags flags,
- GnmStdError func_error)
+float_range_function2d (GnmValue const *val0, GnmValue const *val1,
+ GnmFuncEvalInfo *ei,
+ float_range_function2d_t func,
+ CollectFlags flags,
+ GnmStdError func_error,
+ gpointer data)
{
gnm_float *vals0, *vals1;
int n0, n1;
@@ -403,7 +404,7 @@
}
}
- if (func (vals0, vals1, n0, &fres))
+ if (func (vals0, vals1, n0, &fres, data))
res = value_new_error_std (ei->pos, func_error);
else
res = value_new_float (fres);
@@ -414,6 +415,20 @@
return res;
}
+GnmValue *
+float_range_function2 (GnmValue const *val0, GnmValue const *val1,
+ GnmFuncEvalInfo *ei,
+ float_range_function2_t func,
+ CollectFlags flags,
+ GnmStdError func_error)
+{
+ return float_range_function2d (val0, val1, ei,
+ (float_range_function2d_t)func,
+ flags,
+ func_error,
+ NULL);
+}
+
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
Modified: trunk/src/collect.h
==============================================================================
--- trunk/src/collect.h (original)
+++ trunk/src/collect.h Fri Oct 3 23:55:55 2008
@@ -29,12 +29,9 @@
typedef int (*float_range_function_t) (gnm_float const *, int, gnm_float *);
typedef int (*float_range_function2_t) (gnm_float const *, gnm_float const *, int, gnm_float *);
+typedef int (*float_range_function2d_t) (gnm_float const *, gnm_float const *, int, gnm_float *, gpointer);
typedef int (*string_range_function_t) (GPtrArray *, char**);
-/*gnm_float *collect_floats (int argc, GnmExprConstPtr const *argv,
- GnmEvalPos const *ep, CollectFlags flags,
- int *n, GnmValue **error, GSList **info);*/
-
gnm_float *collect_floats_value (GnmValue const *val,
GnmEvalPos const *ep,
CollectFlags flags,
@@ -56,6 +53,13 @@
CollectFlags flags,
GnmStdError func_error);
+GnmValue *float_range_function2d (GnmValue const *val0, GnmValue const *val1,
+ GnmFuncEvalInfo *ei,
+ float_range_function2d_t func,
+ CollectFlags flags,
+ GnmStdError func_error,
+ gpointer data);
+
GnmValue *string_range_function (int argc, GnmExprConstPtr const *argv,
GnmFuncEvalInfo *ei,
string_range_function_t func,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]