[gcalctool/gcalctool-newui2] ...



commit 8c743e0738066686f59a3f7523abddfa961de688
Author: Robert Ancell <robert ancell gmail com>
Date:   Mon Jul 13 16:09:49 2009 +1000

    ...

 src/display.c            |    5 +--
 src/financial.c          |    8 +++---
 src/functions.c          |    2 +-
 src/mp-convert.c         |   35 +++++++++++------------
 src/mp-equation-parser.y |    4 +-
 src/mp-internal.h        |    1 -
 src/mp.c                 |   68 +++++++++++++++++-----------------------------
 7 files changed, 51 insertions(+), 72 deletions(-)
---
diff --git a/src/display.c b/src/display.c
index 757a3e9..6dc83db 100644
--- a/src/display.c
+++ b/src/display.c
@@ -662,9 +662,8 @@ make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *M
     mp_set_from_mp(&MPval, &MPmant);
 
     mp_set_from_integer(base, &MP1base);
-    mp_pwr_integer(&MP1base, 3, &MP3base);
-
-    mp_pwr_integer(&MP1base, 10, &MP10base);
+    mp_xpowy_integer(&MP1base, 3, &MP3base);
+    mp_xpowy_integer(&MP1base, 10, &MP10base);
 
     mp_set_from_integer(1, &MP1);
     mp_divide(&MP1, &MP10base, &MPatmp);
diff --git a/src/financial.c b/src/financial.c
index 17c6689..1058666 100644
--- a/src/financial.c
+++ b/src/financial.c
@@ -98,7 +98,7 @@ calc_fv(MPNumber *t, MPNumber *pmt, MPNumber *pint, MPNumber *n)
     MPNumber MP1, MP2, MP3, MP4;
   
     mp_add_integer(pint, 1, &MP1);
-    mp_pwr(&MP1, n, &MP2);
+    mp_xpowy(&MP1, n, &MP2);
     mp_add_integer(&MP2, -1, &MP3);
     mp_multiply(pmt, &MP3, &MP4);
     mp_divide(&MP4, pint, t);
@@ -138,7 +138,7 @@ calc_pmt(MPNumber *t, MPNumber *prin, MPNumber *pint, MPNumber *n)
 
     mp_add_integer(pint, 1, &MP1);
     mp_multiply_integer(n, -1, &MP2);
-    mp_pwr(&MP1, &MP2, &MP3);
+    mp_xpowy(&MP1, &MP2, &MP3);
     mp_multiply_integer(&MP3, -1, &MP4);
     mp_add_integer(&MP4, 1, &MP1);
     mp_divide(pint, &MP1, &MP2);
@@ -161,7 +161,7 @@ calc_pv(MPNumber *t, MPNumber *pmt, MPNumber *pint, MPNumber *n)
 
     mp_add_integer(pint, 1, &MP1);
     mp_multiply_integer(n, -1, &MP2);
-    mp_pwr(&MP1, &MP2, &MP3);
+    mp_xpowy(&MP1, &MP2, &MP3);
     mp_multiply_integer(&MP3, -1, &MP4);
     mp_add_integer(&MP4, 1, &MP1);
     mp_divide(&MP1, pint, &MP2);
@@ -185,7 +185,7 @@ calc_rate(MPNumber *t, MPNumber *fv, MPNumber *pv, MPNumber *n)
     mp_divide(fv, pv, &MP1);
     mp_set_from_integer(1, &MP2);
     mp_divide(&MP2, n, &MP3);
-    mp_pwr(&MP1, &MP3, &MP4);
+    mp_xpowy(&MP1, &MP3, &MP4);
     mp_add_integer(&MP4, -1, t);
 }
 
diff --git a/src/functions.c b/src/functions.c
index 0656aa8..d71780e 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -298,7 +298,7 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
 
         case FN_SHIFT:
             do_shift(arg);
-            return;
+            break;
 
         case FN_SET_ACCURACY:
             do_accuracy(arg);
diff --git a/src/mp-convert.c b/src/mp-convert.c
index db51dc0..71a96ae 100644
--- a/src/mp-convert.c
+++ b/src/mp-convert.c
@@ -213,30 +213,29 @@ mp_set_from_double(double dx, MPNumber *z)
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
 void
-mp_set_from_integer(int ix, MPNumber *z)
+mp_set_from_integer(int x, MPNumber *z)
 {
     memset(z, 0, sizeof(MPNumber));
 
-    if (ix == 0) {
-        z->exponent = 1;
-        return;
-    }
-
-    if (ix < 0) {
-        ix = -ix;
+    if (x < 0) {
+        x = -x;
         z->sign = -1;
     }
-    else
+    else if (x > 0)
         z->sign = 1;
-
-    /* SET EXPONENT TO T */
-    z->exponent = MP_T;
-
-    /* INSERT IX */
-    z->fraction[MP_T - 1] = ix;
-
-    /* NORMALIZE BY CALLING MPMUL2 */
-    mpmul2(z, 1, z, 1);
+    else
+        z->sign = 0; /* Optimisation for indicating zero */
+
+    z->exponent = 1;
+    z->fraction[0] = x;
+    while (z->fraction[0] >= MP_BASE) {
+        int i;
+        for (i = z->exponent; i >= 0; i--)
+            z->fraction[i] = z->fraction[i-1];
+        z->fraction[0] = z->fraction[1] / MP_BASE;
+        z->fraction[1] = z->fraction[1] % MP_BASE;
+        z->exponent++;
+    }
 }
 
 /* CONVERTS THE RATIONAL NUMBER I/J TO MULTIPLE PRECISION Q. */
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 77dd5ba..86329ea 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -122,7 +122,7 @@ exp:
   '(' exp ')' {mp_set_from_mp(&$2, &$$);}
 | '|' exp '|' {mp_abs(&$2, &$$);}
 | exp '^' exp {mp_xpowy(&$1, &$3, &$$);}
-| exp tSUPNUM {mp_pwr_integer(&$1, $2, &$$);}
+| exp tSUPNUM {mp_xpowy_integer(&$1, $2, &$$);}
 | exp tINVERSE {mp_reciprocal(&$1, &$$);}
 | exp '!' {mp_factorial(&$1, &$$);}
 | tVARIABLE {get_variable(yyscanner, $1, &$$); free($1);}
@@ -150,7 +150,7 @@ exp:
 
 function:
   tFUNCTION exp {get_function(yyscanner, $1, &$2, &$$); free($1);}
-| tFUNCTION tSUPNUM exp {get_function(yyscanner, $1, &$3, &$$); mp_pwr_integer(&$$, $2, &$$); free($1);}
+| tFUNCTION tSUPNUM exp {get_function(yyscanner, $1, &$3, &$$); mp_xpowy_integer(&$$, $2, &$$); free($1);}
 | tSUBNUM tROOT exp {mp_root(&$3, $1, &$$);}
 | tROOT exp {mp_sqrt(&$2, &$$);}
 | tROOT3 exp {mp_root(&$2, 3, &$$);}
diff --git a/src/mp-internal.h b/src/mp-internal.h
index d47695b..d289c1a 100644
--- a/src/mp-internal.h
+++ b/src/mp-internal.h
@@ -43,7 +43,6 @@
 
 void mperr(const char *format, ...) __attribute__((format(printf, 1, 2)));
 void mpgcd(int *, int *);
-void mpmul2(const MPNumber *, int, MPNumber *, int);
 void mp_normalize(MPNumber *, int trunc);
 
 #endif /* MP_INTERNAL_H */
diff --git a/src/mp.c b/src/mp.c
index 9400f3e..69cf983 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -1232,7 +1232,7 @@ mp_multiply(const MPNumber *x, const MPNumber *y, MPNumber *z)
  *  EVEN IF SOME DIGITS ARE GREATER THAN B-1.
  *  RESULT IS ROUNDED IF TRUNC == 0, OTHERWISE TRUNCATED.
  */
-void
+static void
 mpmul2(const MPNumber *x, int iy, MPNumber *z, int trunc)
 {
     int c, i, c1, c2, j1, j2;
@@ -1380,7 +1380,7 @@ mp_multiply_fraction(const MPNumber *x, int numerator, int denominator, MPNumber
         mp_divide_integer(x, is * js, z);
     } else {
         mp_divide_integer(x, js, z);
-        mpmul2(z, is, z, 0);
+        mp_multiply_integer(z, is, z);
     }
 }
 
@@ -1512,8 +1512,8 @@ mp_pwr(const MPNumber *x, const MPNumber *y, MPNumber *z)
         return;
     }
     
-    /* 0^0 = 1 */
-    if (x->sign == 0 && y->sign == 0) {
+    /* x^0 = 1 */
+    if (y->sign == 0) {
         mp_set_from_integer(1, z);
         return;
     }
@@ -1789,6 +1789,7 @@ mp_factorial(const MPNumber *x, MPNumber *z)
     }
     if (!mp_is_natural(x)) {
         mperr("Cannot take factorial of non-natural number");
+        return;
     }
 
     /* Convert to integer - if couldn't be converted then the factorial would be too big anyway */
@@ -1840,50 +1841,31 @@ mp_xpowy(const MPNumber *x, const MPNumber *y, MPNumber *z)
 void
 mp_xpowy_integer(const MPNumber *x, int n, MPNumber *z)
 {
-    int n2, ns;
+    int i;
     MPNumber t;
-   
-    n2 = n;
-    if (n2 < 0) {
-        /* N < 0 */
-        n2 = -n2;
-        if (x->sign == 0) {
-            mperr("*** ATTEMPT TO RAISE ZERO TO NEGATIVE POWER IN CALL TO SUBROUTINE mp_xpowy_integer ***");
-            mp_set_from_integer(0, z);
-            return;
-        }
-    } else if (n2 == 0) {
-        /* N == 0, RETURN Y = 1. */
-        mp_set_from_integer(1, z);
+    
+    /* x^-n invalid */
+    if (x->sign == 0 && n < 0) {
+        mperr("*** ATTEMPT TO RAISE ZERO TO NEGATIVE POWER IN CALL TO SUBROUTINE mp_xpowy_integer ***");
+        return;
+    }
+    
+    /* 0^n = 0 */
+    if (x->sign == 0) {
+        mp_set_from_integer(0, z);
         return;
-    } else {
-        /* N > 0 */
-        if (x->sign == 0) {
-            mp_set_from_integer(0, z);
-            return;
-        }
     }
 
-    /* MOVE X */
-    mp_set_from_mp(x, z);
-
-    /* IF N < 0 FORM RECIPROCAL */
-    if (n < 0)
-        mp_reciprocal(z, z);
-    mp_set_from_mp(z, &t);
+    if (n < 0) {
+        mp_reciprocal(x, &t);
+        n = -n;
+    }
+    else
+        mp_set_from_mp(x, &t);
 
-    /* SET PRODUCT TERM TO ONE */
+    /* Multply x n times */
     mp_set_from_integer(1, z);
-
-    /* MAIN LOOP, LOOK AT BITS OF N2 FROM RIGHT */
-    while(1) {
-        ns = n2;
-        n2 /= 2;
-        if (n2 << 1 != ns)
-            mp_multiply(z, &t, z);
-        if (n2 <= 0)
-            return;
-        
-        mp_multiply(&t, &t, &t);
+    for (i = 0; i < n; i++) {
+        mp_multiply(z, &t, z);
     }
 }



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