[gcalctool] more documentation in mp.h
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Subject: [gcalctool] more documentation in mp.h
- Date: Thu, 7 May 2009 22:11:29 -0400 (EDT)
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]