[gnumeric] POWER: extend to three arguments for root finding.



commit 48d18d73dff98d9ae4edf0dc5e2339cccc34649e
Author: Morten Welinder <terra gnome org>
Date:   Fri Nov 2 13:51:57 2012 -0400

    POWER: extend to three arguments for root finding.

 NEWS                        |    1 +
 plugins/fn-math/ChangeLog   |    5 +++++
 plugins/fn-math/functions.c |   27 +++++++++++++++++++--------
 3 files changed, 25 insertions(+), 8 deletions(-)
---
diff --git a/NEWS b/NEWS
index 43a9a0d..f43b0f4 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Morten:
 	* Fix ods save performance problems.  [#662057]
 	* Make .gnumeric use fewer style rectangles for the same style.
 	* Short-circuit column resize for large stf imports.  [#686858]
+	* Enhance POWER to do root of negative numbers.  [#687269]
 
 Weng Xuetian:
         * Fix interaction with ibus & fcitx. [#684511]
diff --git a/plugins/fn-math/ChangeLog b/plugins/fn-math/ChangeLog
index e5319a9..3c4cbd5 100644
--- a/plugins/fn-math/ChangeLog
+++ b/plugins/fn-math/ChangeLog
@@ -1,3 +1,8 @@
+2012-11-02  Morten Welinder  <terra gnome org>
+
+	* functions.c (gnumeric_power): Extend to three arguments for root
+	calculations.
+
 2012-09-06  Morten Welinder <terra gnome org>
 
 	* Release 1.11.6
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index b0cfc8c..ae549bf 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -1213,13 +1213,16 @@ gnumeric_ln1p (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 /***************************************************************************/
 
 static GnmFuncHelp const help_power[] = {
-        { GNM_FUNC_HELP_NAME, F_("POWER:the value of @{x} raised to the power @{y}")},
+        { GNM_FUNC_HELP_NAME, F_("POWER:the value of @{x} raised to the power @{y} raised to the power of 1/@{z}")},
         { GNM_FUNC_HELP_ARG, F_("x:number")},
         { GNM_FUNC_HELP_ARG, F_("y:number")},
+        { GNM_FUNC_HELP_ARG, F_("z:number")},
 	{ GNM_FUNC_HELP_NOTE, F_("If both @{x} and @{y} equal 0, POWER returns #NUM!") },
 	{ GNM_FUNC_HELP_NOTE, F_("If @{x} = 0 and @{y} < 0, POWER returns #DIV/0!") },
 	{ GNM_FUNC_HELP_NOTE, F_("If @{x} < 0 and @{y} is not an integer, POWER returns #NUM!") },
-	{ GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
+	{ GNM_FUNC_HELP_NOTE, F_("@{z} defaults to 1") },
+	{ GNM_FUNC_HELP_NOTE, F_("If @{z} is not a positive integer, POWER returns #NUM!") },
+	{ GNM_FUNC_HELP_NOTE, F_("If @{x} < 0, @{y} is odd, and @{z} is even, POWER returns #NUM!") },
         { GNM_FUNC_HELP_EXAMPLES, "=POWER(2,7)" },
         { GNM_FUNC_HELP_EXAMPLES, "=POWER(3,3.141)" },
         { GNM_FUNC_HELP_SEEALSO, "EXP"},
@@ -1231,11 +1234,19 @@ gnumeric_power (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 {
 	gnm_float x = value_get_as_float (argv[0]);
 	gnm_float y = value_get_as_float (argv[1]);
+	gnm_float z = argv[2] ? value_get_as_float (argv[2]) : 1;
+
+	if ((x > 0) || (x == 0 && y > 0) || (x < 0 && y == gnm_floor (y))) {
+		gnm_float r = gnm_pow (x, y);
+		gboolean z_even = gnm_fmod (z, 2.0) == 0;
+		if (z <= 0 || z != gnm_floor (z) || (r < 0 && z_even))
+			return value_new_error_NUM (ei->pos);
+		if (z != 1)
+			r = (r < 0 ? -1 : +1) * gnm_pow (gnm_abs (r), 1 / z);
+		return value_new_float (r);
+	}
 
-	if ((x > 0) || (x == 0 && y > 0) || (x < 0 && y == gnm_floor (y)))
-		return value_new_float (gnm_pow (x, y));
-
-	if (x == 0 && y != 0)
+	if (x != 0 && y != 0)
 		return value_new_error_DIV0 (ei->pos);
 	else
 		return value_new_error_NUM (ei->pos);
@@ -3370,9 +3381,9 @@ GnmFuncDescriptor const math_functions[] = {
 	{ "odd" ,    "f",     help_odd,
 	  gnumeric_odd, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
-	{ "power",   "ff",       help_power,
+	{ "power",   "ff|f",       help_power,
 	  gnumeric_power, NULL, NULL, NULL,
-	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
+	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_SUPERSET, GNM_FUNC_TEST_STATUS_BASIC },
 	{ "g_product", NULL,     help_g_product,
 	  NULL, gnumeric_g_product, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]