[gcalctool] Support odd roots of negative numbers (Robert Ancell, Bug #576973)



commit cd9162f6787d782b301e392b736b4c326433b366
Author: Robert Ancell <robert ancell gmail com>
Date:   Mon May 11 14:16:27 2009 +1000

    Support odd roots of negative numbers (Robert Ancell, Bug #576973)
---
 ChangeLog         |    1 +
 src/mp-internal.h |    1 -
 src/mp.c          |    7 ++++++-
 src/mp.h          |    3 +++
 src/unittest.c    |   19 ++++++++++---------
 5 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 906332f..45774c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,7 @@ gcalctool change history.
 2009-05-11 Robert Ancell <robert ancell gmail com>
 
     * Really fix the license text in the about dialog (Robert Ancell, Bug #579174)
+    * Support odd roots of negative numbers (Robert Ancell, Bug #576973)
 
 2009-05-07 Robin Sonefors <ozamosi flukkost nu>
 
diff --git a/src/mp-internal.h b/src/mp-internal.h
index 803072e..2fc231a 100644
--- a/src/mp-internal.h
+++ b/src/mp-internal.h
@@ -52,6 +52,5 @@ void mpmul2(const MPNumber *, int, MPNumber *, int);
 void mp_normalize(MPNumber *, int trunc);
 void mpexp1(const MPNumber *, MPNumber *);
 void mpmulq(const MPNumber *, int, int, MPNumber *);
-void mp_reciprocal(const MPNumber *, MPNumber *);
 
 #endif /* MP_INTERNAL_H */
diff --git a/src/mp.c b/src/mp.c
index 52fb1c5..e94d218 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -2232,6 +2232,11 @@ mp_xpowy(const MPNumber *x, const MPNumber *y, MPNumber *z)
     if (mp_is_integer(y)) {
         mp_pwr_integer(x, mp_cast_to_int(y), z);
     } else {
-        mp_pwr(x, y, z);
+        MPNumber reciprocal;
+        mp_reciprocal(y, &reciprocal);
+        if (mp_is_integer(&reciprocal))
+            mp_root(x, mp_cast_to_int(&reciprocal), z);
+        else
+            mp_pwr(x, y, z);
     }
 }
diff --git a/src/mp.h b/src/mp.h
index 6a811f2..39240d3 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -125,6 +125,9 @@ void   mp_divide(const MPNumber *x, const MPNumber *y, MPNumber *z);
 /* Sets z = x ÷ y */
 void   mp_divide_integer(const MPNumber *x, int y, MPNumber *z);
 
+/* Sets z = 1 ÷ x */
+void   mp_reciprocal(const MPNumber *, MPNumber *);
+
 /* Sets z = fractional part of x */
 void   mp_fractional_component(const MPNumber *x, MPNumber *z);
 
diff --git a/src/unittest.c b/src/unittest.c
index 115baa9..24da065 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -149,15 +149,6 @@ test_parser()
     test("100%", "1", 0);
     test("1%", "0.01", 0);
 
-    test("2^2", "4", 0);
-    test("2^-1", "0.5", 0);
-    test("2^(-1)", "0.5", 0);    
-    test("-10^2", "-100", 0);
-    test("(-10)^2", "100", 0);
-    test("4^3^2", "262144", 0);
-    test("4^(3^2)", "262144", 0);    
-    test("(4^3)^2", "4096", 0);
-
     test("0!", "1", 0);
     test("1!", "1", 0);
     test("5!", "120", 0);
@@ -170,9 +161,19 @@ test_parser()
     test("2^1", "2", 0);
     test("2^2", "4", 0);
     test("2^-1", "0.5", 0);
+    test("2^(-1)", "0.5", 0);    
+    test("-10^2", "-100", 0);
+    test("(-10)^2", "100", 0);
     test("2^100", "1267650600228229401496703205376", 0);
+    test("4^3^2", "262144", 0);
+    test("4^(3^2)", "262144", 0);    
+    test("(4^3)^2", "4096", 0);
     test("Sqrt(4)", "2", 0);
     test("Sqrt(2)", "1.414213562", 0);
+    test("4^(1/2)", "2", 0);
+    test("2^(1/2)", "1.414213562", 0);
+    test("(-4)^(1/2)", "", -20001);
+    test("(-8)^(1/3)", "-2", 0);
     
     test("0 Mod 7", "0", 0);
     test("6 Mod 7", "6", 0);



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