[gcalctool/gcalctool-newui2] ...



commit 874264f5424fa2d2834e5de3aafd6aa05ceea4e6
Author: Robert Ancell <robert ancell gmail com>
Date:   Sun Jul 12 13:30:28 2009 +0800

    ...

 src/calctool.c         |    1 -
 src/mp-convert.c       |    1 +
 src/mp-equation.c      |    1 +
 src/mp-internal.h      |   12 +--
 src/mp-trigonometric.c |   17 +---
 src/mp.c               |  245 ++++--------------------------------------------
 6 files changed, 25 insertions(+), 252 deletions(-)
---
diff --git a/src/calctool.c b/src/calctool.c
index 27a47fa..daffe2f 100644
--- a/src/calctool.c
+++ b/src/calctool.c
@@ -206,7 +206,6 @@ init_state(void)
     gboolean use_default_digits = FALSE;
 
     acc              = MAX_DIGITS + 12;     /* MP internal accuracy. */
-    mp_init(acc);
 
     v->error         = FALSE;          /* No calculator error initially. */
 
diff --git a/src/mp-convert.c b/src/mp-convert.c
index eccaf4e..875400a 100644
--- a/src/mp-convert.c
+++ b/src/mp-convert.c
@@ -2,6 +2,7 @@
 /*  $Header$
  *
  *  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
+ *  Copyright (c) 2008-2009 Robert Ancell
  *           
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/src/mp-equation.c b/src/mp-equation.c
index fada9e0..fa52d22 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -2,6 +2,7 @@
 /*  $Header$
  *
  *  Copyright (C) 2004-2008 Sami Pietila
+ *  Copyright (c) 2008-2009 Robert Ancell
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/src/mp-internal.h b/src/mp-internal.h
index f6ba4ea..1de26c6 100644
--- a/src/mp-internal.h
+++ b/src/mp-internal.h
@@ -2,6 +2,7 @@
 /*  $Header$
  *
  *  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
+ *  Copyright (c) 2008-2009 Robert Ancell
  *           
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -32,17 +33,8 @@
 #define min(a, b)   ((a) <= (b) ? (a) : (b))
 #define max(a, b)   ((a) >= (b) ? (a) : (b))
 
-/* Evil global variables that must be removed */
-struct {
-    /* Min/max exponent value */
-    // FIXME: MP.m modified inside functions, needs to be fixed to be thread safe
-    int m;
-} MP;
-
-#define MP_BASE 10000
-
 //2E0 BELOW ENSURES AT LEAST ONE GUARD DIGIT
-//MP.t = (int) ((float) (accuracy) * log((float)10.) / log((float) MP.b) + (float) 2.0);
+//MP.t = (int) ((float) (accuracy) * log((float)10.) / log((float) MP_BASE) + (float) 2.0);
 //if (MP.t > MP_SIZE) {
 //    mperr("MP_SIZE TOO SMALL IN CALL TO MPSET, INCREASE MP_SIZE AND DIMENSIONS OF MP ARRAYS TO AT LEAST %d ***", MP.t);
 //    MP.t = MP_SIZE;
diff --git a/src/mp-trigonometric.c b/src/mp-trigonometric.c
index e809c82..c46f2c4 100644
--- a/src/mp-trigonometric.c
+++ b/src/mp-trigonometric.c
@@ -2,6 +2,7 @@
 /*  $Header$
  *
  *  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
+ *  Copyright (c) 2008-2009 Robert Ancell
  *           
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -645,19 +646,9 @@ mp_cosh(const MPNumber *x, MPNumber *z)
     }
 
     mp_abs(x, &t);
-
-    /*  IF ABS(X) TOO LARGE MP_EPOWY WILL PRINT ERROR MESSAGE
-     *  INCREASE M TO AVOID OVERFLOW WHEN COSH(X) REPRESENTABLE
-     */
-    MP.m += 2;
     mp_epowy(&t, &t);
     mp_reciprocal(&t, z);
     mp_add(&t, z, z);
-
-    /*  RESTORE M.  IF RESULT OVERFLOWS OR UNDERFLOWS, mp_divide_integer WILL
-     *  ACT ACCORDINGLY.
-     */
-    MP.m -= 2;
     mp_divide_integer(z, 2, z);
 }
 
@@ -693,15 +684,9 @@ mp_sinh(const MPNumber *x, MPNumber *z)
      *  INCREASE M TO AVOID OVERFLOW IF SINH(X) REPRESENTABLE
      */
     else {
-        MP.m += 2;
         mp_epowy(&t2, &t2);
         mp_reciprocal(&t2, z);
         mp_subtract(&t2, z, z);
-
-        /*  RESTORE M.  IF RESULT OVERFLOWS OR UNDERFLOWS, mp_divide_integer AT
-         *  STATEMENT 30 WILL ACT ACCORDINGLY.
-         */
-        MP.m -= 2;
     }
 
     /* DIVIDE BY TWO AND RESTORE SIGN */
diff --git a/src/mp.c b/src/mp.c
index 45e9a53..94e8e74 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -2,6 +2,7 @@
 /*  $Header$
  *
  *  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
+ *  Copyright (c) 2008-2009 Robert Ancell
  *           
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,63 +29,8 @@
 #include "mp-internal.h"
 #include "calctool.h" // FIXME: Required for doerr() and MAXLINE
 
-/*  SETS X TO THE LARGEST POSSIBLE POSITIVE MP NUMBER
- *  CHECK LEGALITY OF B, T, M AND MXR
- */
-static void
-mpmaxr(MPNumber *x)
-{
-    int i, it;
-
-    it = MP_BASE - 1;
 
-    /* SET FRACTION DIGITS TO B-1 */
-    for (i = 0; i < MP_T; i++)
-        x->fraction[i] = it;
-
-    /* SET SIGN AND EXPONENT */
-    x->sign = 1;
-    x->exponent = MP.m;
-}
-
-
-/*  CALLED ON MULTIPLE-PRECISION OVERFLOW, IE WHEN THE
- *  EXPONENT OF MP NUMBER X WOULD EXCEED M.
- *  AT PRESENT EXECUTION IS TERMINATED WITH AN ERROR MESSAGE
- *  AFTER CALLING MPMAXR(X), BUT IT WOULD BE POSSIBLE TO RETURN,
- *  POSSIBLY UPDATING A COUNTER AND TERMINATING EXECUTION AFTER
- *  A PRESET NUMBER OF OVERFLOWS.  ACTION COULD EASILY BE DETERMINED
- *  BY A FLAG IN LABELLED COMMON.
- *  M MAY HAVE BEEN OVERWRITTEN, SO CHECK B, T, M ETC.
- */
-static void
-mpovfl(MPNumber *x, const char *error)
-{
-    fprintf(stderr, "%s\n", error);
-    
-    /* SET X TO LARGEST POSSIBLE POSITIVE NUMBER */
-    mpmaxr(x);
-
-    /* TERMINATE EXECUTION BY CALLING MPERR */
-    mperr("*** CALL TO MPOVFL, MP OVERFLOW OCCURRED ***");
-}
-
-
-/*  CALLED ON MULTIPLE-PRECISION UNDERFLOW, IE WHEN THE
- *  EXPONENT OF MP NUMBER X WOULD BE LESS THAN -M.
- *  SINCE M MAY HAVE BEEN OVERWRITTEN, CHECK B, T, M ETC.
- */
-static void
-mpunfl(MPNumber *z)
-{
-    /*  THE UNDERFLOWING NUMBER IS SET TO ZERO
-     *  AN ALTERNATIVE WOULD BE TO CALL MPMINR (X) AND RETURN,
-     *  POSSIBLY UPDATING A COUNTER AND TERMINATING EXECUTION
-     *  AFTER A PRESET NUMBER OF UNDERFLOWS.  ACTION COULD EASILY
-     *  BE DETERMINED BY A FLAG IN LABELLED COMMON.
-     */
-    mp_set_from_integer(0, z);
-}
+// FIXME: Re-add overflow and underflow detection
 
 
 /*  ROUTINE CALLED BY MP_DIVIDE AND MP_SQRT TO ENSURE THAT
@@ -122,84 +68,6 @@ mpext(int i, int j, MPNumber *x)
 }
 
 
-/*  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;
-    //int b, n;
-
-    /* DETERMINE LARGE REPRESENTABLE INTEGER W OF FORM 2**K - 1 */
-    /*  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.
-     */
-    w = 0;
-    k = 0;
-    for (i = 1; i <= 47; ++i) {
-        int w2, wn;
-
-        /*  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;
-
-    /* B IS THE LARGEST POWER OF 2 SUCH THAT (8*B*B-1) <= W */
-    /*MP.b = 1;
-    n = (k - 3) / 2;
-    if (n > 0) {
-        for (;;) { 
-            if (n & 01)
-                MP.b *= x;
-            if (n >>= 1)
-                x *= x;
-            else
-                break;
-        }
-    }*/
-    
-    /* 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;*/
-}
-
-
 void
 mp_get_eulers(MPNumber *z)
 {
@@ -519,22 +387,6 @@ mp_integer_component(const MPNumber *x, MPNumber *z)
     }
 }
 
-/*  COMPARES MP NUMBER X WITH REAL NUMBER RI, RETURNING
- *      +1 IF X > RI,
- *       0 IF X == RI,
- *      -1 IF X < RI
- *  DIMENSION OF R IN COMMON AT LEAST 2T+6
- *  CHECK LEGALITY OF B, T, M AND MXR
- */
-static int
-mp_compare_mp_to_float(const MPNumber *x, float ri)
-{
-    MPNumber t;
-
-    /* CONVERT RI TO MULTIPLE-PRECISION AND COMPARE */
-    mp_set_from_float(ri, &t);
-    return mp_compare_mp_to_mp(x, &t);
-}
 
 /*  COMPARES THE MULTIPLE-PRECISION NUMBERS X AND Y,
  *  RETURNING +1 IF X  >  Y,
@@ -605,9 +457,6 @@ mp_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
         return;
     }
 
-    /* INCREASE M TO AVOID OVERFLOW IN MP_RECIPROCAL */
-    MP.m += 2;
-
     /* FORM RECIPROCAL OF Y */
     mp_reciprocal(y, &t);
 
@@ -621,15 +470,7 @@ mp_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
     iz3 = z->fraction[0];
     mpext(i, iz3, z);
 
-    /* RESTORE M, CORRECT EXPONENT AND RETURN */
-    MP.m -= 2;
     z->exponent += ie;
-    
-    /* Check for overflow or underflow */
-    if (z->exponent < -MP.m)
-        mpunfl(z);
-    else if (z->exponent > MP.m)
-        mpovfl(z, "*** OVERFLOW OCCURRED IN MP_DIVIDE ***");
 }
 
 
@@ -660,11 +501,6 @@ mp_divide_integer(const MPNumber *x, int iy, MPNumber *z)
 
     /* CHECK FOR DIVISION BY B */
     if (iy == MP_BASE) {
-        if (x->exponent <= -MP.m)
-        {
-            mpunfl(z);
-            return;
-        }
         mp_set_from_mp(x, z);
         z->exponent--;
         return;
@@ -855,7 +691,7 @@ void
 mp_epowy(const MPNumber *x, MPNumber *z)
 {
     float r__1;
-    int i, ie, ix, xs, tss;
+    int i, ix, xs, tss;
     float rx, rz, rlb;
     MPNumber t1, t2;
 
@@ -876,18 +712,7 @@ mp_epowy(const MPNumber *x, MPNumber *z)
     /*  SEE IF ABS(X) SO LARGE THAT EXP(X) WILL CERTAINLY OVERFLOW
      *  OR UNDERFLOW.  1.01 IS TO ALLOW FOR ERRORS IN ALOG.
      */
-    rlb = log((float) MP_BASE) * (float)1.01;
-    if (mp_compare_mp_to_float(x, -(double)((float) (MP.m + 1)) * rlb) < 0) {
-        /* UNDERFLOW SO CALL MPUNFL AND RETURN */
-        mpunfl(z);
-        return;
-    }
-
-    if (mp_compare_mp_to_float(x, (float) MP.m * rlb) > 0) {
-        /* OVERFLOW HERE */
-        mpovfl(z, "*** OVERFLOW IN SUBROUTINE MP_EPOWY ***");
-        return;
-    }
+    rlb = log((float)MP_BASE) * 1.01f;
 
     /* NOW SAFE TO CONVERT X TO REAL */
     rx = mp_cast_to_float(x);
@@ -899,9 +724,9 @@ mp_epowy(const MPNumber *x, MPNumber *z)
     /*  IF ABS(X) > M POSSIBLE THAT INT(X) OVERFLOWS,
      *  SO DIVIDE BY 32.
      */
-    if (fabs(rx) > (float) MP.m) {
+    /*if (fabs(rx) > (float)MP.m) {
         mp_divide_integer(&t2, 32, &t2);
-    }
+    }*/
 
     /* GET FRACTIONAL AND INTEGER PARTS OF ABS(X) */
     ix = mp_cast_to_int(&t2);
@@ -944,34 +769,24 @@ mp_epowy(const MPNumber *x, MPNumber *z)
     mp_multiply(z, &t2, z);
 
     /* MUST CORRECT RESULT IF DIVIDED BY 32 ABOVE. */
-    if (fabs(rx) > (float) MP.m && z->sign != 0) {
+    /*if (fabs(rx) > (float)MP.m && z->sign != 0) {
         for (i = 1; i <= 5; ++i) {
-            /* SAVE EXPONENT TO AVOID OVERFLOW IN MP_MULTIPLY */
+            // SAVE EXPONENT TO AVOID OVERFLOW IN MP_MULTIPLY
             ie = z->exponent;
             z->exponent = 0;
             mp_multiply(z, z, z);
             z->exponent += ie << 1;
-
-            /* CHECK FOR UNDERFLOW AND OVERFLOW */
-            if (z->exponent < -MP.m) {
-                mpunfl(z);
-                return;
-            }
-            if (z->exponent > MP.m) {
-                mpovfl(z, "*** OVERFLOW IN SUBROUTINE MP_EPOWY ***");
-                return;
-            }
         }
-    }
+    }*/
 
     /*  CHECK THAT RELATIVE ERROR LESS THAN 0.01 UNLESS ABS(X) LARGE
      *  (WHEN EXP MIGHT OVERFLOW OR UNDERFLOW)
      */
-    if (fabs(rx) > (float)10.0)
+    if (fabs(rx) > 10.0f)
         return;
 
     rz = mp_cast_to_float(z);
-    if ((r__1 = rz - exp(rx), fabs(r__1)) < rz * (float)0.01)
+    if ((r__1 = rz - exp(rx), fabs(r__1)) < rz * 0.01f)
         return;
 
     /*  THE FOLLOWING MESSAGE MAY INDICATE THAT
@@ -1013,11 +828,10 @@ mpexp1(const MPNumber *x, MPNumber *z)
     }
 
     mp_set_from_mp(x, &t1);
-    rlb = log((float) MP_BASE);
+    rlb = log((float)MP_BASE);
 
     /* COMPUTE APPROXIMATELY OPTIMAL Q (AND DIVIDE X BY 2**Q) */
-    q = (int) (sqrt((float) MP_T * (float).48 * rlb) + (float) x->exponent * 
-              (float)1.44 * rlb);
+    q = (int)(sqrt((float)MP_T * 0.48f * rlb) + (float) x->exponent * 1.44f * rlb);
 
     /* HALVE Q TIMES */
     if (q > 0) {
@@ -1268,7 +1082,7 @@ mp_ln(const MPNumber *x, MPNumber *z)
 
         /* RESTORE EXPONENT AND COMPUTE SINGLE-PRECISION LOG */
         t1.exponent = e;
-        rlx = log(rx) + (float) e * log((float) MP_BASE);
+        rlx = log(rx) + (float)e * log((float)MP_BASE);
         mp_set_from_float(-(double)rlx, &t2);
 
         /* UPDATE Z AND COMPUTE ACCURATE EXP OF APPROXIMATE LOG */
@@ -1444,14 +1258,9 @@ mpmul2(const MPNumber *x, int iy, MPNumber *z, int trunc)
 
         /* CHECK FOR MULTIPLICATION BY B */
         if (iy == MP_BASE) {
-            if (x->exponent < MP.m) {
-                mp_set_from_mp(x, z);
-                z->sign = z->sign;
-                z->exponent = x->exponent + 1;
-            }
-            else {
-                mpovfl(z, "*** OVERFLOW OCCURRED IN MPMUL2 ***");
-            }
+            mp_set_from_mp(x, z);
+            z->sign = z->sign;
+            z->exponent = x->exponent + 1;
             return;
         }
     }
@@ -1689,12 +1498,6 @@ mp_normalize(MPNumber *x, int trunc)
             }
         }
     }
-
-    /* Check for over and underflow */
-    if (x->exponent > MP.m)
-        mpovfl(x, "*** OVERFLOW OCCURRED IN MP_NORMALIZE ***");
-    else if (x->exponent < -MP.m)
-        mpunfl(x);
 }
 
 
@@ -1817,9 +1620,6 @@ mp_reciprocal(const MPNumber *x, MPNumber *z)
 
     ex = x->exponent;
 
-    /* TEMPORARILY INCREASE M TO AVOID OVERFLOW */
-    MP.m += 2;
-
     /* SET EXPONENT TO ZERO SO RX NOT TOO LARGE OR SMALL. */
     /* work-around to avoid touching X */
     mp_set_from_mp(x, &tmp_x);
@@ -1827,7 +1627,7 @@ mp_reciprocal(const MPNumber *x, MPNumber *z)
     rx = mp_cast_to_float(&tmp_x);
 
     /* USE SINGLE-PRECISION RECIPROCAL AS FIRST APPROXIMATION */
-    mp_set_from_float((float)1. / rx, &t1);
+    mp_set_from_float(1.0f / rx, &t1);
 
     /* CORRECT EXPONENT OF FIRST APPROXIMATION */
     t1.exponent -= ex;
@@ -1874,11 +1674,6 @@ mp_reciprocal(const MPNumber *x, MPNumber *z)
 
     /* MOVE RESULT TO Y AND RETURN AFTER RESTORING T */
     mp_set_from_mp(&t1, z);
-
-    /* RESTORE M AND CHECK FOR OVERFLOW (UNDERFLOW IMPOSSIBLE) */
-    MP.m -= 2;
-    if (z->exponent > MP.m)
-        mpovfl(z, "*** OVERFLOW OCCURRED IN MP_RECIPROCAL ***");
 }
 
 
@@ -1946,8 +1741,8 @@ mp_root(const MPNumber *x, int n, MPNumber *z)
     }
 
     /* USE SINGLE-PRECISION ROOT FOR FIRST APPROXIMATION */
-    r__1 = exp(((float) (np * ex - x->exponent) * log((float) MP_BASE) - 
-           log((fabs(rx)))) / (float) np);
+    r__1 = exp(((float)(np * ex - x->exponent) * log((float)MP_BASE) -
+           log((fabs(rx)))) / (float)np);
     mp_set_from_float(r__1, &t1);
 
     /* SIGN OF APPROXIMATION SAME AS THAT OF X */



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