[gcalctool] Use a base-10 internal representation (Robert Ancell, Bug #585813)



commit edbf3f4d64a2a8b5aee6ee2526e7edcd8320d936
Author: Robert Ancell <robert ancell gmail com>
Date:   Sun Jul 12 12:54:59 2009 +0800

    Use a base-10 internal representation (Robert Ancell, Bug #585813)

 ChangeLog |    4 ++++
 src/mp.c  |   30 ++++++++++++++++++++----------
 2 files changed, 24 insertions(+), 10 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5cdae0c..c0ff520 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,10 @@
 gcalctool change history.
 =========================
 
+2009-07-12 Robert Ancell <robert ancell gmail com>
+
+    * Use a base-10 internal representation (Robert Ancell, Bug #585813)
+
 2009-06-30 Robert Ancell <robert ancell gmail com>
 
     * Make padding consistent in GUI (Jerry Casiano, Bug #587292)
diff --git a/src/mp.c b/src/mp.c
index 69ebaee..5689ddb 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -97,17 +97,21 @@ mpunfl(MPNumber *x)
 static int
 pow_ii(int x, int n)
 {
-    int pow = 1;
+    int p = 1;
+    
+    if (n <= 0)
+        return 1;
 
-    if (n > 0) {
-        for (;;) { 
-            if (n & 01) pow *= x;
-            if (n >>= 1) x *= x;
-            else break;
-        }
+    for (;;) { 
+        if (n & 01)
+            p *= x;
+        if (n >>= 1)
+            x *= x;
+        else
+            break;
     }
 
-    return(pow);
+    return p;
 }
 
 
@@ -171,7 +175,7 @@ mpext(int i, int j, MPNumber *x)
 void
 mp_init(int accuracy)
 {
-    int i, k, w;
+    int i, k, w, b;
 
     /* DETERMINE LARGE REPRESENTABLE INTEGER W OF FORM 2**K - 1 */
     /*  ON CYBER 76 HAVE TO FIND K <= 47, SO ONLY LOOP
@@ -208,6 +212,12 @@ mp_init(int accuracy)
     /* B IS THE LARGEST POWER OF 2 SUCH THAT (8*B*B-1) <= W */
     MP.b = pow_ii(2, (k - 3) / 2);
 
+    /* Make a multiple of 10 so fractions can be represented exactly */
+    b = 1;
+    while (MP.b % (10 * b) != MP.b)
+        b *= 10;
+    MP.b = b;
+
     /* 2E0 BELOW ENSURES AT LEAST ONE GUARD DIGIT */
     MP.t = (int) ((float) (accuracy) * log((float)10.) / log((float) MP.b) + 
                   (float) 2.0);



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