[gcalctool] more documentation in mp.h



commit 339fe3433e8aeea9366fc7a413e0a211508d0b09
Author: Robert Ancell <robert ancell gmail com>
Date:   Fri May 8 12:11:20 2009 +1000

    more documentation in mp.h
---
 gcalctool/calctool.c    |    2 +-
 gcalctool/mp-binary.c   |    3 +-
 gcalctool/mp-internal.h |    6 ++
 gcalctool/mp.c          |  158 ++++++++++++++++++++++++-----------------------
 gcalctool/mp.h          |   22 +++----
 gcalctool/unittest.c    |    5 ++
 6 files changed, 104 insertions(+), 92 deletions(-)

diff --git a/gcalctool/calctool.c b/gcalctool/calctool.c
index 7a712d4..af346e8 100644
--- a/gcalctool/calctool.c
+++ b/gcalctool/calctool.c
@@ -254,7 +254,7 @@ init_state(void)
     int acc, i;
 
     acc              = MAX_DIGITS + 12;     /* MP internal accuracy. */
-    mp_init(acc, MP_SIZE);
+    mp_init(acc);
 
     v->error         = FALSE;  /* No calculator error initially. */
     v->radix         = get_radix();    /* Locale specific radix string. */
diff --git a/gcalctool/mp-binary.c b/gcalctool/mp-binary.c
index 6e00f4e..8bbf3c7 100644
--- a/gcalctool/mp-binary.c
+++ b/gcalctool/mp-binary.c
@@ -1,5 +1,6 @@
 #include "mp.h"
-#include "calctool.h" // FIXME
+#include "mp-internal.h"
+#include "calctool.h" // FIXME: Used for MAX_DIGITS
 
 static char digits[] = "0123456789ABCDEF";
 
diff --git a/gcalctool/mp-internal.h b/gcalctool/mp-internal.h
index 4601444..876d0b3 100644
--- a/gcalctool/mp-internal.h
+++ b/gcalctool/mp-internal.h
@@ -24,6 +24,11 @@
 
 #include <glib/gi18n.h>
 
+/* If we're not using GNU C, elide __attribute__ */
+#ifndef __GNUC__
+#  define  __attribute__(x)  /*NOTHING*/
+#endif
+
 #define min(a, b)   ((a) <= (b) ? (a) : (b))
 #define max(a, b)   ((a) >= (b) ? (a) : (b))
 
@@ -40,6 +45,7 @@ struct {
     int m;
 } MP;
 
+void mperr(const char *format, ...) __attribute__((format(printf, 1, 2)));
 void mpchk();
 void mpgcd(int *, int *);
 void mpmul2(const MPNumber *, int, MPNumber *, int);
diff --git a/gcalctool/mp.c b/gcalctool/mp.c
index 821e8bc..d11b8ed 100644
--- a/gcalctool/mp.c
+++ b/gcalctool/mp.c
@@ -39,6 +39,86 @@ static void mpmaxr(MPNumber *);
 static void mpovfl(MPNumber *, const char *);
 static void mpunfl(MPNumber *);
 
+
+/*  SETS BASE (B) AND NUMBER OF DIGITS (T) TO GIVE THE
+ *  EQUIVALENT OF AT LEAST IDECPL DECIMAL DIGITS.
+ *  IDECPL SHOULD BE POSITIVE.
+ *  ITMAX2 IS THE DIMENSION OF ARRAYS USED FOR MP NUMBERS,
+ *  SO AN ERROR OCCURS IF THE COMPUTED T EXCEEDS ITMAX2 - 2.
+ *  MPSET ALSO SETS
+ *        MXR = MAXDR (DIMENSION OF R IN COMMON, >= T+4), AND
+ *          M = (W-1)/4 (MAXIMUM ALLOWABLE EXPONENT),
+ *  WHERE W IS THE LARGEST INTEGER OF THE FORM 2**K-1 WHICH IS
+ *  REPRESENTABLE IN THE MACHINE, K <= 47
+ *  THE COMPUTED B AND T SATISFY THE CONDITIONS 
+ *  (T-1)*LN(B)/LN(10) >= IDECPL   AND   8*B*B-1 <= W .
+ *  APPROXIMATELY MINIMAL T AND MAXIMAL B SATISFYING
+ *  THESE CONDITIONS ARE CHOSEN.
+ *  PARAMETERS IDECPL, ITMAX2 AND MAXDR ARE INTEGERS.
+ *  BEWARE - MPSET WILL CAUSE AN INTEGER OVERFLOW TO OCCUR
+ *  ******   IF WORDLENGTH IS LESS THAN 48 BITS.
+ *           IF THIS IS NOT ALLOWABLE, CHANGE THE DETERMINATION
+ *           OF W (DO 30 ... TO 30 W = WN) OR SET B, T, M,
+ *           AND MXR WITHOUT CALLING MPSET.
+ *  FIRST SET MXR
+ */
+void
+mp_init(int accuracy)
+{
+    int i, k, w, i2, w2, wn;
+
+    /* DETERMINE LARGE REPRESENTABLE INTEGER W OF FORM 2**K - 1 */
+    w = 0;
+    k = 0;
+
+    /*  ON CYBER 76 HAVE TO FIND K <= 47, SO ONLY LOOP
+     *  47 TIMES AT MOST.  IF GENUINE INTEGER WORDLENGTH
+     *  EXCEEDS 47 BITS THIS RESTRICTION CAN BE RELAXED.
+     */
+    for (i = 1; i <= 47; ++i) {
+        /*  INTEGER OVERFLOW WILL EVENTUALLY OCCUR HERE
+         *  IF WORDLENGTH < 48 BITS
+         */
+        w2 = w + w;
+        wn = w2 + 1;
+
+        /*  APPARENTLY REDUNDANT TESTS MAY BE NECESSARY ON SOME
+         *  MACHINES, DEPENDING ON HOW INTEGER OVERFLOW IS HANDLED
+         */
+        if (wn <= w || wn <= w2 || wn <= 0)
+            break;
+        k = i;
+        w = wn;
+    }
+
+    /* SET MAXIMUM EXPONENT TO (W-1)/4 */
+    MP.m = w / 4;
+    if (accuracy <= 0) {
+        mperr("*** ACCURACY <= 0 IN CALL TO MPSET ***");
+        return;
+    }
+
+    /* B IS THE LARGEST POWER OF 2 SUCH THAT (8*B*B-1) <= W */
+    MP.b = pow_ii(2, (k - 3) / 2);
+
+    /* 2E0 BELOW ENSURES AT LEAST ONE GUARD DIGIT */
+    MP.t = (int) ((float) (accuracy) * log((float)10.) / log((float) MP.b) + 
+                  (float) 2.0);
+
+    /* SEE IF T TOO LARGE FOR DIMENSION STATEMENTS */
+    i2 = MP.t;
+    if (i2 > MP_SIZE) {
+        mperr("MP_SIZE TOO SMALL IN CALL TO MPSET, INCREASE MP_SIZE AND DIMENSIONS OF MP ARRAYS TO AT LEAST %d ***", i2);
+
+        /* REDUCE TO MAXIMUM ALLOWED BY DIMENSION STATEMENTS */
+        MP.t = MP_SIZE;
+    }
+    
+    /* CHECK LEGALITY OF B, T, M AND MXR (AT LEAST T+4) */
+    mpchk();
+}
+
+
 /* SETS Y = ABS(X) FOR MP NUMBERS X AND Y */
 void
 mp_abs(const MPNumber *x, MPNumber *y)
@@ -2110,84 +2190,6 @@ mp_root(const MPNumber *x, int n, MPNumber *z)
 }
 
 
-/*  SETS BASE (B) AND NUMBER OF DIGITS (T) TO GIVE THE
- *  EQUIVALENT OF AT LEAST IDECPL DECIMAL DIGITS.
- *  IDECPL SHOULD BE POSITIVE.
- *  ITMAX2 IS THE DIMENSION OF ARRAYS USED FOR MP NUMBERS,
- *  SO AN ERROR OCCURS IF THE COMPUTED T EXCEEDS ITMAX2 - 2.
- *  MPSET ALSO SETS
- *        MXR = MAXDR (DIMENSION OF R IN COMMON, >= T+4), AND
- *          M = (W-1)/4 (MAXIMUM ALLOWABLE EXPONENT),
- *  WHERE W IS THE LARGEST INTEGER OF THE FORM 2**K-1 WHICH IS
- *  REPRESENTABLE IN THE MACHINE, K <= 47
- *  THE COMPUTED B AND T SATISFY THE CONDITIONS 
- *  (T-1)*LN(B)/LN(10) >= IDECPL   AND   8*B*B-1 <= W .
- *  APPROXIMATELY MINIMAL T AND MAXIMAL B SATISFYING
- *  THESE CONDITIONS ARE CHOSEN.
- *  PARAMETERS IDECPL, ITMAX2 AND MAXDR ARE INTEGERS.
- *  BEWARE - MPSET WILL CAUSE AN INTEGER OVERFLOW TO OCCUR
- *  ******   IF WORDLENGTH IS LESS THAN 48 BITS.
- *           IF THIS IS NOT ALLOWABLE, CHANGE THE DETERMINATION
- *           OF W (DO 30 ... TO 30 W = WN) OR SET B, T, M,
- *           AND MXR WITHOUT CALLING MPSET.
- *  FIRST SET MXR
- */
-void
-mp_init(int idecpl, int itmax2)
-{
-    int i, k, w, i2, w2, wn;
-
-    /* DETERMINE LARGE REPRESENTABLE INTEGER W OF FORM 2**K - 1 */
-    w = 0;
-    k = 0;
-
-    /*  ON CYBER 76 HAVE TO FIND K <= 47, SO ONLY LOOP
-     *  47 TIMES AT MOST.  IF GENUINE INTEGER WORDLENGTH
-     *  EXCEEDS 47 BITS THIS RESTRICTION CAN BE RELAXED.
-     */
-    for (i = 1; i <= 47; ++i) {
-        /*  INTEGER OVERFLOW WILL EVENTUALLY OCCUR HERE
-         *  IF WORDLENGTH < 48 BITS
-         */
-        w2 = w + w;
-        wn = w2 + 1;
-
-        /*  APPARENTLY REDUNDANT TESTS MAY BE NECESSARY ON SOME
-         *  MACHINES, DEPENDING ON HOW INTEGER OVERFLOW IS HANDLED
-         */
-        if (wn <= w || wn <= w2 || wn <= 0)
-            break;
-        k = i;
-        w = wn;
-    }
-
-    /* SET MAXIMUM EXPONENT TO (W-1)/4 */
-    MP.m = w / 4;
-    if (idecpl <= 0) {
-        mperr("*** IDECPL <= 0 IN CALL TO MPSET ***");
-        return;
-    }
-
-    /* B IS THE LARGEST POWER OF 2 SUCH THAT (8*B*B-1) <= W */
-    MP.b = pow_ii(2, (k - 3) / 2);
-
-    /* 2E0 BELOW ENSURES AT LEAST ONE GUARD DIGIT */
-    MP.t = (int) ((float) (idecpl) * log((float)10.) / log((float) MP.b) + 
-                  (float) 2.0);
-
-    /* SEE IF T TOO LARGE FOR DIMENSION STATEMENTS */
-    i2 = MP.t;
-    if (i2 > itmax2) {
-        mperr("ITMAX2 TOO SMALL IN CALL TO MPSET, INCREASE ITMAX2 AND DIMENSIONS OF MP ARRAYS TO AT LEAST %d ***", i2);
-
-        /* REDUCE TO MAXIMUM ALLOWED BY DIMENSION STATEMENTS */
-        MP.t = itmax2;
-    }
-    
-    /* CHECK LEGALITY OF B, T, M AND MXR (AT LEAST T+4) */
-    mpchk();
-}
-
 /*  RETURNS Z = SQRT(X), USING SUBROUTINE MP_ROOT IF X > 0.
  *  DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 4T+10
  *  (BUT Z.EXP MAY BE R(3T+9)).  X AND Z ARE MP NUMBERS.
diff --git a/gcalctool/mp.h b/gcalctool/mp.h
index 9302a3d..a64ac97 100644
--- a/gcalctool/mp.h
+++ b/gcalctool/mp.h
@@ -40,8 +40,10 @@
 #ifndef MP_H
 #define MP_H
 
-#define MP_SIZE      1000     /* Size of the multiple precision values. */
+/* Size of the multiple precision values */
+#define MP_SIZE 1000
 
+/* Object for a high precision floating point number representation */
 typedef struct
 {
    /* Sign (+1, -1) or 0 for the value zero */
@@ -54,14 +56,10 @@ typedef struct
    int fraction[MP_SIZE]; // Size MP.t?
 } MPNumber;
 
-/* If we're not using GNU C, elide __attribute__ */
-#ifndef __GNUC__
-#  define  __attribute__(x)  /*NOTHING*/
-#endif
-
-void   mp_init(int, int);
-
-void   mperr(const char *format, ...) __attribute__((format(printf, 1, 2)));
+/* Initialise the MP state.  Must be called only once and before any other MP function
+ * 'accuracy' is the requested accuracy required.
+ */
+void   mp_init(int accuracy);
 
 /* Returns:
  *  0 if x == y
@@ -79,19 +77,19 @@ int    mp_is_negative(const MPNumber *x);
 /* Return true if x is integer */
 int    mp_is_integer(const MPNumber *x);
 
-/* Return true if x is a natural number (an integer >= 0) */
+/* Return true if x is a natural number (an integer â?¥ 0) */
 int    mp_is_natural(const MPNumber *x);
 
 /* Return true if x == y */
 int    mp_is_equal(const MPNumber *x, const MPNumber *y);
 
-/* Return true if x >= y */
+/* Return true if x â?¥ y */
 int    mp_is_greater_equal(const MPNumber *x, const MPNumber *y);
 
 /* Return true if x > y */
 int    mp_is_greater_than(const MPNumber *x, const MPNumber *y);
 
-/* Return true if x <= y */
+/* Return true if x â?¤ y */
 int    mp_is_less_equal(const MPNumber *x, const MPNumber *y);
 
 /* Return true if x < y */
diff --git a/gcalctool/unittest.c b/gcalctool/unittest.c
index e7ddc88..e99e7b1 100644
--- a/gcalctool/unittest.c
+++ b/gcalctool/unittest.c
@@ -31,6 +31,11 @@
 
 static int fails = 0;
 
+/* If we're not using GNU C, elide __attribute__ */
+#ifndef __GNUC__
+#  define  __attribute__(x)  /*NOTHING*/
+#endif
+
 static void pass(const char *format, ...) __attribute__((format(printf, 1, 2)));
 static void fail(const char *format, ...) __attribute__((format(printf, 1, 2)));
 



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