gcalctool r2231 - in trunk: . gcalctool



Author: rancell
Date: Thu Sep 25 02:02:18 2008
New Revision: 2231
URL: http://svn.gnome.org/viewvc/gcalctool?rev=2231&view=rev

Log:
seventh patch from klaus


Modified:
   trunk/ChangeLog
   trunk/gcalctool/mp.c
   trunk/gcalctool/mp.h
   trunk/gcalctool/mpmath.c
   trunk/gcalctool/unittest.c

Modified: trunk/gcalctool/mp.c
==============================================================================
--- trunk/gcalctool/mp.c	(original)
+++ trunk/gcalctool/mp.c	Thu Sep 25 02:02:18 2008
@@ -44,8 +44,6 @@
 #include "calctool.h"
 #include "display.h"
 
-#define C_abs(x)    ((x) >= 0 ? (x) : -(x))
-#define dabs(x)     (double) C_abs(x)
 #define min(a, b)   ((a) <= (b) ? (a) : (b))
 #define max(a, b)   ((a) >= (b) ? (a) : (b))
 
@@ -62,24 +60,24 @@
 static int pow_ii(int, int);
 
 static void mpadd2(const int *, const int *, int *, int, int);
-static void mpadd3(const int *, const int *, int, int, int *);
+static int  mpadd3(const int *, const int *, int, int);
 static void mp_add_fraction(const int *, int, int, int *);
 static void mpart1(int, int *);
 static void mpchk(int , int );
 static float mp_cast_to_float(const int *);
 static void mp_set_from_fraction(int, int, int *);
 static void mp_set_from_float(float, int *);
-static void mpexp1(int *, int *);
+static void mpexp1(const int *, int *);
 static void mpext(int, int, int *);
 static void mpgcd(int *, int *);
-static void mplns(int *, int *);
+static void mplns(const int *, int *);
 static void mpmaxr(int *);
-static void mpmlp(int *, int *, int, int);
+static void mpmlp(int *, const int *, int, int);
 static void mpmul2(int *, int, int *, int);
 static void mpmulq(int *, int, int, int *);
 static void mpnzr(int, int *, int *, int);
 static void mpovfl(int *);
-static void mprec(int *, int *);
+static void mprec(const int *, int *);
 static void mproot(int *, int, int *);
 static void mpsin1(int *, int *, int);
 static void mpunfl(int *);
@@ -89,7 +87,7 @@
 mp_abs(const int *x, int *y)
 {
     mp_set_from_mp(x, y);
-    y[0] = C_abs(y[0]);
+    y[0] = abs(y[0]);
 }
 
 
@@ -132,7 +130,7 @@
 
     /* COMPARE SIGNS */
     sign_prod = y_sign * x[0];
-    if (C_abs(sign_prod) > 1) {
+    if (abs(sign_prod) > 1) {
         mpchk(1, 4);
         if (v->MPerrors) {
             FPRINTF(stderr, "*** SIGN NOT 0, +1 OR -1 IN MPADD2 CALL.\nPOSSIBLE OVERWRITING PROBLEM ***\n");
@@ -144,7 +142,7 @@
 
     /* COMPARE EXPONENTS */
     exp_diff = x[1] - y[1];
-    med = C_abs(exp_diff);
+    med = abs(exp_diff);
     if (exp_diff < 0) {
         /* HERE EXPONENT(Y)  >  EXPONENT(X) */
         if (med > MP.t) {
@@ -185,23 +183,22 @@
     }
     
 L10:
-    exp_result = y[1];
-    mpadd3(x, y, sign_prod, med, &exp_result);
+    exp_result = y[1] + mpadd3(x, y, sign_prod, med);
     /* NORMALIZE, ROUND OR TRUNCATE, AND RETURN */
     mpnzr(y_sign, &exp_result, z, trunc);
     return;
 
 L20:
-    exp_result = x[1];
-    mpadd3(y, x, sign_prod, med, &exp_result);
+    exp_result = x[1] + mpadd3(y, x, sign_prod, med);
     /* NORMALIZE, ROUND OR TRUNCATE, AND RETURN */
     mpnzr(x[0], &exp_result, z, trunc);
     return;
 }
 
 /* CALLED BY MPADD2, DOES INNER LOOPS OF ADDITION */
-static void
-mpadd3(const int *x, const int *y, int s, int med, int *re)
+/* return value is amount by which exponent needs to be increased. */
+static int
+mpadd3(const int *x, const int *y, int s, int med)
 {
     int c, i, j, i2, i2p, ted;
 
@@ -218,36 +215,41 @@
 
     if (s < 0) goto L130;
 
-    /* HERE DO ADDITION, EXPONENT(Y) .GE. EXPONENT(X) */
-    if (i > MP.t) {
-        do {
-            j = i - med;
-            MP.r[i - 1] = x[j + 1];
-            --i;
-        } while (i > MP.t);
+    /* HERE DO ADDITION, EXPONENT(Y) >= EXPONENT(X) */
+    while (i > MP.t) {
+      j = i - med;
+      MP.r[i - 1] = x[j + 1];
+      i--;
     }
 
     while (i > med) {
         j = i - med;
         c = y[i + 1] + x[j + 1] + c;
 
-        /* NO CARRY GENERATED HERE */
         if (c < MP.b) {
+	    /* NO CARRY GENERATED HERE */
             MP.r[i - 1] = c;
             c = 0;
-            --i;
-        /* CARRY GENERATED HERE */
         } else {
+	    /* CARRY GENERATED HERE */
             MP.r[i - 1] = c - MP.b;
             c = 1;
-            --i;
         }
+	i--;
     }
 
     while (i > 0)
     {
         c = y[i + 1] + c;
-        if (c < MP.b) goto L70;
+        if (c < MP.b) {
+	  MP.r[i - 1] = c;
+	  i--;
+	  
+	  /* NO CARRY POSSIBLE HERE */
+	  for (; i > 0; i--)
+	    MP.r[i - 1] = y[i + 1];
+	  return 0;
+	}
 
         MP.r[i - 1] = 0;
         c = 1;
@@ -262,20 +264,12 @@
             MP.r[i] = MP.r[i - 1];
         }
         MP.r[0] = 1;
-        ++(*re);
+        return 1;
     }
-    return;
-
-L70:
-    MP.r[i - 1] = c;
-    --i;
+    return 0;
 
-    /* NO CARRY POSSIBLE HERE */
-    for (; i > 0; i--)
-        MP.r[i - 1] = y[i + 1];
-    return;
 
-    /* HERE DO SUBTRACTION, ABS(Y) .GT. ABS(X) */
+    /* HERE DO SUBTRACTION, ABS(Y) > ABS(X) */
 L110:
     j = i - med;
     MP.r[i - 1] = c - x[j + 1];
@@ -307,11 +301,20 @@
 
     for (; i > 0; i--) {
         c = y[i + 1] + c;
-        if (c >= 0) goto L70;
+        if (c >= 0) {
+	  MP.r[i - 1] = c;
+	  i--;
+
+	  /* NO CARRY POSSIBLE HERE */
+	  for (; i > 0; i--)
+	    MP.r[i - 1] = y[i + 1];
+	  return 0;
+	}
 
         MP.r[i - 1] = c + MP.b;
         c = -1;
     }
+    return 0;
 }
 
 
@@ -345,7 +348,7 @@
 }
 
 
-/*  COMPUTES MP Y = ARCTAN(1/N), ASSUMING INTEGER N .GT. 1.
+/*  COMPUTES MP Y = ARCTAN(1/N), ASSUMING INTEGER N > 1.
  *  USES SERIES ARCTAN(X) = X - X**3/3 + X**5/5 - ...
  *  DIMENSION OF R IN CALLING PROGRAM MUST BE
  *  AT LEAST 2T+6
@@ -384,10 +387,7 @@
         id = b2 * 7 * b2 / (n * n);
 
     /* MAIN LOOP.  FIRST REDUCE T IF POSSIBLE */
-    do {
-        MP.t = ts + 2 + MP.r[i2] - y[1];
-        if (MP.t < 2)
-            break;
+    while  ((MP.t = ts + 2 + MP.r[i2] - y[1]) > 1) {
 
         MP.t = min(MP.t,ts);
 
@@ -410,15 +410,16 @@
 
         /* ADD TO SUM */
         mp_add(&MP.r[i2 - 1], y, y);
-    } while (MP.r[i2 - 1] != 0);
+	if (MP.r[i2 - 1] == 0) break;
+    }
     MP.t = ts;
 }
 
 
-/*  RETURNS Y = ARCSIN(X), ASSUMING ABS(X) .LE. 1,
+/*  RETURNS Y = ARCSIN(X), ASSUMING ABS(X) <= 1,
  *  FOR MP NUMBERS X AND Y.
  *  Y IS IN THE RANGE -PI/2 TO +PI/2.
- *  METHOD IS TO USE MPATAN, SO TIME IS O(M(T)T).
+ *  METHOD IS TO USE MP_ATAN, SO TIME IS O(M(T)T).
  *  DIMENSION OF R MUST BE AT LEAST 5T+12
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
@@ -435,7 +436,7 @@
     }
 
     if (x[1] <= 0) {
-        /* HERE ABS(X) .LT. 1 SO USE ARCTAN(X/SQRT(1 - X**2)) */
+        /* HERE ABS(X) < 1,  SO USE ARCTAN(X/SQRT(1 - X**2)) */
         i2 = i3 - (MP.t + 2);
         mp_set_from_integer(1, &MP.r[i2 - 1]);
         mp_set_from_mp(&MP.r[i2 - 1], &MP.r[i3 - 1]);
@@ -444,20 +445,20 @@
         mpmul(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i3 - 1]);
         mproot(&MP.r[i3 - 1], -2, &MP.r[i3 - 1]);
         mpmul(x, &MP.r[i3 - 1], y);
-        mpatan(y, y);
+        mp_atan(y, y);
         return;
     }
 
-    /* HERE ABS(X) .GE. 1.  SEE IF X = +-1 */
+    /* HERE ABS(X) >= 1.  SEE IF X == +-1 */
     mp_set_from_integer(x[0], &MP.r[i3 - 1]);
-    if (mp_compare_mp_to_mp(x, &MP.r[i3 - 1]) != 0) {
+    if (! mp_is_equal(x, &MP.r[i3 - 1])) {
         if (v->MPerrors) {
-            FPRINTF(stderr, "*** ABS(X) .GT. 1 IN CALL TO MPASIN ***\n");
+            FPRINTF(stderr, "*** ABS(X) > 1 IN CALL TO MP_ASIN ***\n");
         }
         mperr();
     }
 
-    /* X = +-1 SO RETURN +-PI/2 */
+    /* X == +-1 SO RETURN +-PI/2 */
     mppi(y);
     mpdivi(y, MP.r[i3 - 1] << 1, y);
 }
@@ -474,11 +475,9 @@
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
 void
-mpatan(int *x, int *y)
+mp_atan(const int *x, int *y)
 {
-    float r__1;
-
-    int i, q, i2, i3, ie, ts;
+    int i, q, i2, i3, ts;
     float rx = 0.0, ry;
 
 
@@ -491,8 +490,7 @@
     }
 
     mp_set_from_mp(x, &MP.r[i3 - 1]);
-    ie = C_abs(x[1]);
-    if (ie <= 2)
+    if (abs(x[1]) <= 2)
         rx = mp_cast_to_float(x);
 
     q = 1;
@@ -518,18 +516,15 @@
     ts = MP.t;
 
     /* SERIES LOOP.  REDUCE T IF POSSIBLE. */
-    do {
-        MP.t = ts + 2 + MP.r[i3];
-        if (MP.t <= 2)
-            break;
-
+    while ( (MP.t = ts + 2 + MP.r[i3]) > 1) {
         MP.t = min(MP.t,ts);
         mpmul(&MP.r[i3 - 1], &MP.r[i2 - 1], &MP.r[i3 - 1]);
         mpmulq(&MP.r[i3 - 1], -i, i + 2, &MP.r[i3 - 1]);
         i += 2;
         MP.t = ts;
         mp_add(y, &MP.r[i3 - 1], y);
-    } while(MP.r[i3 - 1] != 0);
+	if (MP.r[i3 - 1] == 0) break;
+    }
 
     /* RESTORE T, CORRECT FOR ARGUMENT REDUCTION, AND EXIT */
     MP.t = ts;
@@ -538,16 +533,16 @@
     /*  CHECK THAT RELATIVE ERROR LESS THAN 0.01 UNLESS EXPONENT
      *  OF X IS LARGE (WHEN ATAN MIGHT NOT WORK)
      */
-    if (ie > 2)
+    if (abs(x[1]) > 2)
         return;
 
     ry = mp_cast_to_float(y);
-    if ((r__1 = ry - atan(rx), dabs(r__1)) < dabs(ry) * (float).01)
+    if (fabs(ry - atan(rx)) < fabs(ry) * (float).01)
         return;
 
     /* THE FOLLOWING MESSAGE MAY INDICATE THAT B**(T-1) IS TOO SMALL. */
     if (v->MPerrors)
-        FPRINTF(stderr, "*** ERROR OCCURRED IN MPATAN, RESULT INCORRECT ***\n");
+        FPRINTF(stderr, "*** ERROR OCCURRED IN MP_ATAN, RESULT INCORRECT ***\n");
 
     mperr();
 }
@@ -582,32 +577,25 @@
         return;
     } 
 
-    ie = 0;
-
-    while (dj >= 1.) {
-        /* INCREASE IE AND DIVIDE DJ BY 16. */
-        ++ie;
-        dj *= .0625;
-    }
+    /* INCREASE IE AND DIVIDE DJ BY 16. */
+    for (ie = 0; dj >= 1.0; ie++)
+      dj *= 1.0/16.0;
 
-    while (dj < .0625) {
-        --ie;
-        dj *= 16.;
-    }
+    for ( ; dj < 1.0/16.0; ie--)
+      dj *= 16.;
 
     /*  NOW DJ IS DY DIVIDED BY SUITABLE POWER OF 16
      *  SET EXPONENT TO 0
      */
     re = 0;
 
-    /* DB = DFLOAT(B) IS NOT ANSI STANDARD SO USE FLOAT AND DBLE */
-    db = (double) ((float) MP.b);
+    db = (double) MP.b;
 
     /* CONVERSION LOOP (ASSUME DOUBLE-PRECISION OPS. EXACT) */
-    for (i = 1; i <= i2; ++i) {
+    for (i = 0; i < i2; i++) {
         dj = db * dj;
-        MP.r[i - 1] = (int) dj;
-        dj -= (double) ((float) MP.r[i - 1]);
+        MP.r[i] = (int) dj;
+        dj -= (double) MP.r[i];
     }
 
     /* NORMALIZE RESULT */
@@ -627,9 +615,7 @@
             mpdivi(z, tp, z);
             tp = 1;
         }
-    } else if (ie == 0) {
-        return;
-    } else {
+    } else if (ie > 0) {
         for (i = 1; i <= ie; ++i) {
             tp <<= 4;
             if (tp <= ib && tp != MP.b && i < ie)
@@ -638,12 +624,14 @@
             tp = 1;
         }
     }
+
+    return;
 }
 
 
 /*  CHECKS LEGALITY OF B, T, M AND MXR.
  *  THE CONDITION ON MXR (THE DIMENSION OF R IN COMMON) IS THAT
- *  MXR .GE. (I*T + J)
+ *  MXR >= (I*T + J)
  */
 static void
 mpchk(int i, int j)
@@ -706,17 +694,17 @@
 void
 mp_set_from_integer(int ix, int *z)
 {
-    int i;
-
     mpchk(1, 4);
+
+    if (ix == 0) {
+        z[0] = 0;
+        return;
+    }
+
     if (ix < 0) {
         ix = -ix;
         z[0] = -1;
     }
-    else if (ix == 0) {
-        z[0] = 0;
-        return;
-    }
     else
         z[0] = 1;
 
@@ -724,8 +712,7 @@
     z[1] = MP.t;
 
     /* CLEAR FRACTION */
-    for (i = 2; i <= MP.t; ++i)
-        z[i] = 0;
+    memset(&z[2], 0, (MP.t-1)*sizeof(int));
 
     /* INSERT IX */
     z[MP.t + 1] = ix;
@@ -752,10 +739,9 @@
     if (x[0] == 0)
         return 0.0;
 
-    /* DB = DFLOAT(B) IS NOT ANSI STANDARD, SO USE FLOAT AND DBLE */
-    db = (double) ((float) MP.b);
+    db = (double) MP.b;
     for (i = 1; i <= MP.t; ++i) {
-        ret_val = db * ret_val + (double) ((float) x[i + 1]);
+        ret_val = db * ret_val + (double) x[i + 1];
         tm = i;
 
         /* CHECK IF FULL DOUBLE-PRECISION ACCURACY ATTAINED */
@@ -775,7 +761,7 @@
     /* LHS SHOULD BE .LE. 0.5 BUT ALLOW FOR SOME ERROR IN DLOG */
     if (ret_val <= 0. ||
         ((d__1 = (double) ((float) x[1]) - (log(ret_val) / log((double)
-                ((float) MP.b)) + .5), C_abs(d__1)) > .6)) {
+                ((float) MP.b)) + .5), abs(d__1)) > .6)) {
         /*  FOLLOWING MESSAGE INDICATES THAT X IS TOO LARGE OR SMALL -
          *  TRY USING MPCMDE INSTEAD.
          */
@@ -799,48 +785,37 @@
  *  I.E., Y = X - INTEGER PART OF X (TRUNCATED TOWARDS 0).
  */
 void
-mpcmf(int *x, int *y)
+mpcmf(const int *x, int *y)
 {
-    int i, x2, il, ip;
+    int offset_exp;
 
-    /* RETURN 0 IF X = 0 */    
-    if (x[0] == 0) {
+    /* RETURN 0 IF X = 0
+       OR IF EXPONENT SO LARGE THAT NO FRACTIONAL PART */    
+    if (x[0] == 0  ||  x[1] >= MP.t) {
         y[0] = 0;
         return;
     }
 
-    x2 = x[1];
-
-    /* RETURN 0 IF EXPONENT SO LARGE THAT NO FRACTIONAL PART */
-    if (x2 >= MP.t)
-    {
-        y[0] = 0;
-        return;            
-    }
 
     /* IF EXPONENT NOT POSITIVE CAN RETURN X */
-    if (x2 <= 0) {
+    if (x[1] <= 0) {
         mp_set_from_mp(x, y);
         return;
     }
 
     /* CLEAR ACCUMULATOR */
-    for (i = 1; i <= x2; ++i)
-        MP.r[i - 1] = 0;
+    offset_exp = x[1];
+    memset(MP.r, 0, offset_exp*sizeof(int));
 
-    il = x2 + 1;
 
     /* MOVE FRACTIONAL PART OF X TO ACCUMULATOR */
-    for (i = il; i <= MP.t; ++i)
-        MP.r[i - 1] = x[i + 1];
+    memcpy (MP.r + offset_exp, x + (offset_exp + 2),
+	    (MP.t - offset_exp)*sizeof(int));
 
-    for (i = 1; i <= 4; ++i) {
-        ip = i + MP.t;
-        MP.r[ip - 1] = 0;
-    }
+    memset(MP.r + MP.t, 0, 4*sizeof(int));
 
     /* NORMALIZE RESULT AND RETURN */
-    mpnzr(x[0], &x2, y, 1);
+    mpnzr(x[0], &offset_exp, y, 1);
 }
 
 
@@ -860,10 +835,8 @@
     int i, j, k, j1, x2, kx, xs, izs, ret_val = 0;
 
     xs = x[0];
-    if (xs == 0)
-        return 0;
-
-    if (x[1] <= 0)
+    /* RETURN 0 IF X = 0 OR IF NUMBER FRACTION */    
+    if (xs == 0  ||  x[1] <= 0)
         return 0;
 
     x2 = x[1];
@@ -912,7 +885,7 @@
  * CHECK LEGALITY OF B, T, M AND MXR
  */
 void
-mpcmim(int *x, int *y)
+mpcmim(const int *x, int *y)
 {
     int tmp[MP_SIZE];     /* Temporary store for the number. */
     int accuracy;         /* Temporary story for the accuracy. */
@@ -967,9 +940,9 @@
 
 
 /*  COMPARES MP NUMBER X WITH INTEGER I, RETURNING
- *      +1 IF X .GT. I,
- *       0 IF X .EQ. I,
- *      -1 IF X .LT. I
+ *      +1 IF X  >  I,
+ *       0 IF X == I,
+ *      -1 IF X  <  I
  *  DIMENSION OF R IN COMMON AT LEAST 2T+6
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
@@ -1012,7 +985,6 @@
 {
     int i__1;
     float rz = 0.0;
-    float r__1;
 
     int i, tm = 0;
     float rb, rz2;
@@ -1021,8 +993,7 @@
     if (x[0] == 0) return 0.0;
 
     rb = (float) MP.b;
-    i__1 = MP.t;
-    for (i = 1; i <= i__1; ++i) {
+    for (i = 1; i <= MP.t; ++i) {
         rz = rb * rz + (float) x[i + 1];
         tm = i;
 
@@ -1042,10 +1013,10 @@
 
     if (rz <= (float)0.) goto L30;
 
-/* LHS SHOULD BE .LE. 0.5, BUT ALLOW FOR SOME ERROR IN ALOG */
+/* LHS SHOULD BE <= 0.5, BUT ALLOW FOR SOME ERROR IN ALOG */
 
-    if ((r__1 = (float) x[1] - (log(rz) / log((float) MP.b) + (float).5),
-                 dabs(r__1)) > (float).6) {
+    if (fabs((float) x[1] - (log(rz) / log((float) MP.b) + (float).5))
+	> (float).6) {
         goto L30;
     }
 
@@ -1067,37 +1038,34 @@
 
 
 /*  COMPARES THE MULTIPLE-PRECISION NUMBERS X AND Y,
- *  RETURNING +1 IF X .GT. Y,
- *            -1 IF X .LT. Y,
- *  AND        0 IF X .EQ. Y.
+ *  RETURNING +1 IF X  >  Y,
+ *            -1 IF X  <  Y,
+ *  AND        0 IF X  == Y.
  */
 static int
 mp_compare_mp_to_mp(const int *x, const int *y)
 {
-    int i__2;
-
     int i, t2;
 
     if (x[0] < y[0]) 
-        return -1;  /* X .LT. Y */
+        return -1;
     if (x[0] > y[0])
-        return 1;  /* X .GT. Y */
+        return 1;
 
-    /* SIGN(X) = SIGN(Y), SEE IF ZERO */
+    /* SIGN(X) == SIGN(Y), SEE IF ZERO */
     if (x[0] == 0)
         return 0;  /* X == Y == 0 */
 
     /* HAVE TO COMPARE EXPONENTS AND FRACTIONS */
     t2 = MP.t + 2;
     for (i = 2; i <= t2; ++i) {
-        i__2 = x[i-1] - y[i-1];
-        /* ABS(X) .LT. ABS(Y) */
-        if (i__2 < 0) {
+        int i2 = x[i-1] - y[i-1];
+        if (i2 < 0) {
+	    /* ABS(X)  <  ABS(Y) */
             return -x[0];
-        } else if (i__2 == 0) {
-            continue;
-        /* ABS(X) .GT. ABS(Y) */
-        } else {
+        }
+	if (i2 > 0) {
+            /* ABS(X)  >  ABS(Y) */
             return x[0];
         }
     }
@@ -1125,13 +1093,13 @@
     mpchk(5, 12);
     i2 = MP.t * 3 + 12;
 
-    /* SEE IF ABS(X) .LE. 1 */
+    /* SEE IF ABS(X) <= 1 */
     mp_abs(x, y);
     if (mp_compare_mp_to_int(y, 1) <= 0) {
-        /* HERE ABS(X) .LE. 1 SO USE POWER SERIES */
+        /* HERE ABS(X) <= 1 SO USE POWER SERIES */
         mpsin1(y, y, 0);
     } else {
-        /*  HERE ABS(X) .GT. 1 SO USE COS(X) = SIN(PI/2 - ABS(X)),
+        /*  HERE ABS(X) > 1 SO USE COS(X) = SIN(PI/2 - ABS(X)),
          *  COMPUTING PI/2 WITH ONE GUARD DIGIT.
          */
         ++MP.t;
@@ -1148,20 +1116,18 @@
  *  USES MPEXP, DIMENSION OF R IN COMMON AT LEAST 5T+12
  */
 void
-mpcosh(int *x, int *y)
+mpcosh(const int *x, int *y)
 {
     int i2;
 
-    if (x[0] != 0) goto L10;
-
-/* COSH(0) = 1 */
-
-    mp_set_from_integer(1, y);
-    return;
+    if (x[0] == 0) {
+      /* COSH(0) == 1 */
+      mp_set_from_integer(1, y);
+      return;
+    }
 
 /* CHECK LEGALITY OF B, T, M AND MXR */
 
-L10:
     mpchk(5, 12);
     i2 = (MP.t << 2) + 11;
     mp_abs(x, &MP.r[i2 - 1]);
@@ -1189,72 +1155,56 @@
 mp_set_from_fraction(int i, int j, int *q)
 {
     mpgcd(&i, &j);
-    if (j < 0)  goto L30;
-    else if (j == 0) goto L10;
-    else goto L40;
 
-L10:
-    if (v->MPerrors) {
-        FPRINTF(stderr, "*** J = 0 IN CALL TO MP_SET_FROM_FRACTION ***\n");
-    }
+    if (j == 0) {
+      if (v->MPerrors) {
+        FPRINTF(stderr, "*** J == 0 IN CALL TO MP_SET_FROM_FRACTION ***\n");
+      }
 
-    mperr();
-    q[0] = 0;
-    return;
+      mperr();
+      q[0] = 0;
+      return;
+    }
 
-L30:
-    i = -i;
-    j = -j;
+    if (j < 0) {
+      i = -i;
+      j = -j;
+    }
 
-L40:
     mp_set_from_integer(i, q);
     if (j != 1) mpdivi(q, j, q);
 }
 
 
+/*  CONVERTS SINGLE-PRECISION NUMBER RX TO MULTIPLE-PRECISION Z.
+ *  SOME NUMBERS WILL NOT CONVERT EXACTLY ON MACHINES
+ *  WITH BASE OTHER THAN TWO, FOUR OR SIXTEEN.
+ *  CHECK LEGALITY OF B, T, M AND MXR
+ */
 static void
 mp_set_from_float(float rx, int *z)
 {
-    int i__1;
-
     int i, k, i2, ib, ie, re, tp, rs;
     float rb, rj;
 
-/*  CONVERTS SINGLE-PRECISION NUMBER RX TO MULTIPLE-PRECISION Z.
- *  SOME NUMBERS WILL NOT CONVERT EXACTLY ON MACHINES
- *  WITH BASE OTHER THAN TWO, FOUR OR SIXTEEN.
- *  CHECK LEGALITY OF B, T, M AND MXR
- */
 
     mpchk(1, 4);
     i2 = MP.t + 4;
 
 /* CHECK SIGN */
 
-    if (rx < (float) 0.0) goto L20;
-    else if (rx == 0) goto L10;
-    else goto L30;
-
-/* IF RX = 0E0 RETURN 0 */
-
-L10:
-    z[0] = 0;
-    return;
-
-/* RX .LT. 0E0 */
-
-L20:
-    rs = -1;
-    rj = -(double)(rx);
-    goto L40;
-
-/* RX .GT. 0E0 */
-
-L30:
-    rs = 1;
-    rj = rx;
+    if (rx < (float) 0.0) {
+      rs = -1;
+      rj = -(double)(rx);
+    } else if (rx > (float) 0.0) {
+      rs = 1;
+      rj = rx;
+    } else {
+      /* IF RX = 0E0 RETURN 0 */
+      z[0] = 0;
+      return;
+    }
 
-L40:
     ie = 0;
 
 L50:
@@ -1283,11 +1233,10 @@
 
 /* CONVERSION LOOP (ASSUME SINGLE-PRECISION OPS. EXACT) */
 
-    i__1 = i2;
-    for (i = 1; i <= i__1; ++i) {
+    for (i = 0; i < i2; i++) {
         rj = rb * rj;
-        MP.r[i - 1] = (int) rj;
-        rj -= (float) MP.r[i - 1];
+        MP.r[i] = (int) rj;
+        rj -= (float) MP.r[i];
     }
 
 /* NORMALIZE RESULT */
@@ -1296,81 +1245,71 @@
 
 /* Computing MAX */
 
-    i__1 = MP.b * 7 * MP.b;
-    ib = max(i__1, 32767) / 16;
+    ib = max(MP.b * 7 * MP.b, 32767) / 16;
     tp = 1;
 
 /* NOW MULTIPLY BY 16**IE */
 
-    if (ie < 0)  goto L90;
-    else if (ie == 0) goto L130;
-    else goto L110;
-
-L90:
-    k = -ie;
-    i__1 = k;
-    for (i = 1; i <= i__1; ++i) {
+    if (ie < 0)  {
+      k = -ie;
+      for (i = 1; i <= k; ++i) {
         tp <<= 4;
         if (tp <= ib && tp != MP.b && i < k) continue;
         mpdivi(z, tp, z);
         tp = 1;
-    }
-    return;
-
-L110:
-    i__1 = ie;
-    for (i = 1; i <= i__1; ++i) {
+      }
+    } else if (ie > 0)  {
+      for (i = 1; i <= ie; ++i) {
         tp <<= 4;
         if (tp <= ib && tp != MP.b && i < ie) continue;
         mpmuli(z, tp, z);
         tp = 1;
+      }
     }
 
-L130:
     return;
 }
 
 
-void
-mpdiv(int *x, int *y, int *z)
-{
-    int i, i2, ie, iz3;
 
 /*  SETS Z = X/Y, FOR MP X, Y AND Z.
  *  DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 4T+10
  *  (BUT Z(1) MAY BE R(3T+9)).
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
+void
+mpdiv(const int *x, const int *y, int *z)
+{
+    int i, i2, ie, iz3;
 
     mpchk(4, 10);
 
 /* CHECK FOR DIVISION BY ZERO */
 
-    if (y[0] != 0) goto L20;
-
-    if (v->MPerrors) {
+    if (y[0] == 0) {
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** ATTEMPTED DIVISION BY ZERO IN CALL TO MPDIV ***\n");
+      }
+      
+      mperr();
+      z[0] = 0;
+      return;
     }
 
-    mperr();
-    z[0] = 0;
-    return;
-
-/* SPACE USED BY MPREC IS 4T+10 WORDS, BUT CAN OVERLAP SLIGHTLY. */
+/* CHECK FOR X = 0 */
 
-L20:
-    i2 = MP.t * 3 + 9;
+    if (x[0] == 0) {
+      z[0] = 0;
+      return;
+    }
 
-/* CHECK FOR X = 0 */
 
-    if (x[0] != 0) goto L30;
+/* SPACE USED BY MPREC IS 4T+10 WORDS, BUT CAN OVERLAP SLIGHTLY. */
 
-    z[0] = 0;
-    return;
+    i2 = MP.t * 3 + 9;
 
 /* INCREASE M TO AVOID OVERFLOW IN MPREC */
 
-L30:
     MP.m += 2;
 
 /* FORM RECIPROCAL OF Y */
@@ -1393,14 +1332,13 @@
 
     MP.m += -2;
     z[1] += ie;
-    if (z[1] >= -MP.m) goto L40;
+    if (z[1] < -MP.m) {
+      /* UNDERFLOW HERE */
 
-/* UNDERFLOW HERE */
-
-    mpunfl(z);
-    return;
+      mpunfl(z);
+      return;
+    }
 
-L40:
     if (z[1] <= MP.m) return;
 
 /* OVERFLOW HERE */
@@ -1417,7 +1355,7 @@
  *  THIS IS MUCH FASTER THAN DIVISION BY AN MP NUMBER.
  */
 void
-mpdivi(int *x, int iy, int *z)
+mpdivi(const int *x, int iy, int *z)
 {
     int i__1, i__2;
 
@@ -1425,22 +1363,21 @@
     int j11, kh, re, iq, ir, rs, iqj;
 
     rs = x[0];
-    if (iy < 0)  goto L30;
-    else if (iy == 0) goto L10;
-    else             goto L40;
 
-L10:
-    if (v->MPerrors) {
-        FPRINTF(stderr, "*** ATTEMPTED DIVISION BY ZERO IN CALL TO MPDIVI ***\n");
+    if (iy == 0) {
+      if (v->MPerrors) {
+	FPRINTF(stderr, "*** ATTEMPTED DIVISION BY ZERO IN CALL TO MPDIVI ***\n");
+      }
+      mperr();
+      z[0] = 0;
+      return;
     }
 
-    goto L230;
-
-L30:
-    iy = -iy;
-    rs = -rs;
+    if (iy < 0)  {
+      iy = -iy;
+      rs = -rs;
+    }
 
-L40:
     re = x[1];
 
 /* CHECK FOR ZERO DIVIDEND */
@@ -1449,22 +1386,21 @@
 
 /* CHECK FOR DIVISION BY B */
 
-    if (iy != MP.b) goto L50;
-    mp_set_from_mp(x, z);
-    if (re <= -MP.m) goto L240;
-    z[0] = rs;
-    z[1] = re - 1;
-    return;
+    if (iy == MP.b) {
+      mp_set_from_mp(x, z);
+      if (re <= -MP.m) goto L240;
+      z[0] = rs;
+      z[1] = re - 1;
+      return;
+    }
 
 /* CHECK FOR DIVISION BY 1 OR -1 */
+    if (iy == 1) {
+      mp_set_from_mp(x, z);
+      z[0] = rs;
+      return;
+    }
 
-L50:
-    if (iy != 1) goto L60;
-    mp_set_from_mp(x, z);
-    z[0] = rs;
-    return;
-
-L60:
     c = 0;
     i2 = MP.t + 4;
     i = 0;
@@ -1576,14 +1512,12 @@
 
 L190:
     iq = iq * MP.b - ir * j2;
-    if (iq >= 0) goto L200;
-
-/* HERE IQ NEGATIVE SO IR WAS TOO LARGE */
-
-    --ir;
-    iq += iy;
+    if (iq < 0) {
+      /* HERE IQ NEGATIVE SO IR WAS TOO LARGE */
+      ir--;
+      iq += iy;
+    }
 
-L200:
     if (i <= MP.t) iq += x[i + 1];
     iqj = iq / iy;
 
@@ -1602,7 +1536,6 @@
         FPRINTF(stderr, "*** INTEGER OVERFLOW IN MPDIVI, B TOO LARGE ***\n");
     }
 
-L230:
     mperr();
     z[0] = 0;
     return;
@@ -1634,8 +1567,16 @@
 }
 
 
+/*  RETURNS Y = EXP(X) FOR MP X AND Y.
+ *  EXP OF INTEGER AND FRACTIONAL PARTS OF X ARE COMPUTED
+ *  SEPARATELY.  SEE ALSO COMMENTS IN MPEXP1.
+ *  TIME IS O(SQRT(T)M(T)).
+ *  DIMENSION OF R MUST BE AT LEAST 4T+10 IN CALLING PROGRAM
+ *  CHECK LEGALITY OF B, T, M AND MXR
+ */
+
 void
-mpexp(int *x, int *y)
+mpexp(const int *x, int *y)
 {
     int i__2;
     float r__1;
@@ -1643,40 +1584,30 @@
     int i, i2, i3, ie, ix, ts, xs, tss;
     float rx, ry, rlb;
 
-/*  RETURNS Y = EXP(X) FOR MP X AND Y.
- *  EXP OF INTEGER AND FRACTIONAL PARTS OF X ARE COMPUTED
- *  SEPARATELY.  SEE ALSO COMMENTS IN MPEXP1.
- *  TIME IS O(SQRT(T)M(T)).
- *  DIMENSION OF R MUST BE AT LEAST 4T+10 IN CALLING PROGRAM
- *  CHECK LEGALITY OF B, T, M AND MXR
- */
 
     mpchk(4, 10);
     i2 = (MP.t << 1) + 7;
     i3 = i2 + MP.t + 2;
 
-/* CHECK FOR X = 0 */
-
-    if (x[0] != 0) goto L10;
-    mp_set_from_integer(1, y);
-    return;
-
-/* CHECK IF ABS(X) .LT. 1 */
-
-L10:
-    if (x[1] > 0) goto L20;
+/* CHECK FOR X == 0 */
 
-/* USE MPEXP1 HERE */
+    if (x[0] == 0)  {
+      mp_set_from_integer(1, y);
+      return;
+    }
 
-    mpexp1(x, y);
-    mp_add_integer(y, 1, y);
-    return;
+/* CHECK IF ABS(X) < 1 */
+    if (x[1] <= 0) {
+      /* USE MPEXP1 HERE */
+      mpexp1(x, y);
+      mp_add_integer(y, 1, y);
+      return;
+    }
 
 /*  SEE IF ABS(X) SO LARGE THAT EXP(X) WILL CERTAINLY OVERFLOW
  *  OR UNDERFLOW.  1.01 IS TO ALLOW FOR ERRORS IN ALOG.
  */
 
-L20:
     rlb = log((float) MP.b) * (float)1.01;
     r__1 = -(double)((float) (MP.m + 1)) * rlb;
     if (mp_compare_mp_to_float(x, r__1) >= 0) goto L40;
@@ -1715,7 +1646,7 @@
  *  SO DIVIDE BY 32.
  */
 
-    if (dabs(rx) > (float) MP.m) {
+    if (fabs(rx) > (float) MP.m) {
         mpdivi(&MP.r[i3 - 1], 32, &MP.r[i3 - 1]);
     }
 
@@ -1779,7 +1710,7 @@
 
 /* MUST CORRECT RESULT IF DIVIDED BY 32 ABOVE. */
 
-    if (dabs(rx) <= (float) MP.m || y[0] == 0) goto L110;
+    if (fabs(rx) <= (float) MP.m || y[0] == 0) goto L110;
 
     for (i = 1; i <= 5; ++i) {
 
@@ -1801,10 +1732,10 @@
  */
 
 L110:
-    if (dabs(rx) > (float)10.0) return;
+    if (fabs(rx) > (float)10.0) return;
 
     ry = mp_cast_to_float(y);
-    if ((r__1 = ry - exp(rx), dabs(r__1)) < ry * (float)0.01) return;
+    if ((r__1 = ry - exp(rx), fabs(r__1)) < ry * (float)0.01) return;
 
 /*  THE FOLLOWING MESSAGE MAY INDICATE THAT
  *  B**(T-1) IS TOO SMALL, OR THAT M IS TOO SMALL SO THE
@@ -1820,20 +1751,20 @@
 
 
 static void
-mpexp1(int *x, int *y)
+mpexp1(const int *x, int *y)
 {
     int i__1;
 
     int i, q, i2, i3, ib, ic, ts;
     float rlb;
 
-/*  ASSUMES THAT X AND Y ARE MP NUMBERS,  -1 .LT. X .LT. 1.
+/*  ASSUMES THAT X AND Y ARE MP NUMBERS,  -1 < X < 1.
  *  RETURNS Y = EXP(X) - 1 USING AN O(SQRT(T).M(T)) ALGORITHM
  *  DESCRIBED IN - R. P. BRENT, THE COMPLEXITY OF MULTIPLE-
  *  PRECISION ARITHMETIC (IN COMPLEXITY OF COMPUTATIONAL PROBLEM
  *  SOLVING, UNIV. OF QUEENSLAND PRESS, BRISBANE, 1976, 126-165).
  *  ASYMPTOTICALLY FASTER METHODS EXIST, BUT ARE NOT USEFUL
- *  UNLESS T IS VERY LARGE. SEE COMMENTS TO MPATAN AND MPPIGL.
+ *  UNLESS T IS VERY LARGE. SEE COMMENTS TO MP_ATAN AND MPPIGL.
  *  DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 3T+8
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
@@ -1844,25 +1775,22 @@
 
 /* CHECK FOR X = 0 */
 
-    if (x[0] != 0) goto L20;
-
-L10:
-    y[0] = 0;
-    return;
-
-/* CHECK THAT ABS(X) .LT. 1 */
-
-L20:
-    if (x[1] <= 0) goto L40;
+    if (x[0] == 0) {
+      y[0] = 0;
+      return;
+    }
 
-    if (v->MPerrors) {
+/* CHECK THAT ABS(X) < 1 */
+    if (x[1] > 0) {
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** ABS(X) NOT LESS THAN 1 IN CALL TO MPEXP1 ***\n");
-    }
+      }
 
-    mperr();
-    goto L10;
+      mperr();
+      y[0] = 0;
+      return;
+    }
 
-L40:
     mp_set_from_mp(x, &MP.r[i2 - 1]);
     rlb = log((float) MP.b);
 
@@ -1885,7 +1813,10 @@
     }
 
 L60:
-    if (MP.r[i2 - 1] == 0) goto L10;
+    if (MP.r[i2 - 1] == 0) {
+      y[0] = 0;
+      return;
+    }
     mp_set_from_mp(&MP.r[i2 - 1], y);
     mp_set_from_mp(&MP.r[i2 - 1], &MP.r[i3 - 1]);
     i = 1;
@@ -1957,41 +1888,39 @@
 static void
 mpgcd(int *k, int *l)
 {
-    int i, j, is, js;
+    int i, j;
 
 /*  RETURNS K = K/GCD AND L = L/GCD, WHERE GCD IS THE
  *  GREATEST COMMON DIVISOR OF K AND L.
  *  SAVE INPUT PARAMETERS IN LOCAL VARIABLES
  */
 
-    i = *k;
-    j = *l;
-    is = C_abs(i);
-    js = C_abs(j);
-    if (js == 0) goto L30;
+    i = abs(*k);
+    j = abs(*l);
+    if (j == 0) {
+      /* IF J = 0 RETURN (1, 0) UNLESS I = 0, THEN (0, 0) */
+      *k = 1;
+      *l = 0;
+      if (i == 0) *k = 0;
+      return;
+    }
 
 /* EUCLIDEAN ALGORITHM LOOP */
 
 L10:
-    is %= js;
-    if (is == 0) goto L20;
-    js %= is;
-    if (js != 0) goto L10;
-    js = is;
+    i %= j;
+    if (i == 0) goto L20;
+    j %= i;
+    if (j != 0) goto L10;
+    j = i;
 
-/* HERE JS IS THE GCD OF I AND J */
+/* HERE J IS THE GCD OF K AND L */
 
 L20:
-    *k = i / js;
-    *l = j / js;
+    *k = *k / j;
+    *l = *l / j;
     return;
 
-/* IF J = 0 RETURN (1, 0) UNLESS I = 0, THEN (0, 0) */
-
-L30:
-    *k = 1;
-    if (is == 0) *k = 0;
-    *l = 0;
 }
 
 
@@ -2025,7 +1954,7 @@
  *  FOR SMALL INTEGER X, MPLNI IS FASTER.
  *  ASYMPTOTICALLY FASTER METHODS EXIST (EG THE GAUSS-SALAMIN
  *  METHOD, SEE MPLNGS), BUT ARE NOT USEFUL UNLESS T IS LARGE.
- *  SEE COMMENTS TO MPATAN, MPEXP1 AND MPPIGL.
+ *  SEE COMMENTS TO MP_ATAN, MPEXP1 AND MPPIGL.
  *  DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 6T+14.
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
@@ -2109,13 +2038,6 @@
 }
 
 
-static void
-mplns(int *x, int *y)
-{
-    int i__2;
-
-    int i2, i3, i4, ts, it0, ts2, ts3;
-
 /*  RETURNS MP Y = LN(1+X) IF X IS AN MP NUMBER SATISFYING THE
  *  CONDITION ABS(X) .LT. 1/B, ERROR OTHERWISE.
  *  USES NEWTONS METHOD TO SOLVE THE EQUATION
@@ -2124,6 +2046,12 @@
  *  TIME IS O(SQRT(T).M(T)) AS FOR MPEXP1, SPACE = 5T+12.
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
+static void
+mplns(const int *x, int *y)
+{
+    int i__2;
+
+    int i2, i3, i4, ts, it0, ts2, ts3;
 
     mpchk(5, 12);
     i2 = (MP.t << 1) + 7;
@@ -2132,13 +2060,13 @@
 
 /* CHECK FOR X = 0 EXACTLY */
 
-    if (x[0] != 0) goto L10;
-    y[0] = 0;
-    return;
+    if (x[0] == 0)  {
+      y[0] = 0;
+      return;
+    }
 
-/* CHECK THAT ABS(X) .LT. 1/B */
+/* CHECK THAT ABS(X) < 1/B */
 
-L10:
     if (x[1] + 1 <= 0) goto L30;
 
     if (v->MPerrors) {
@@ -2251,7 +2179,7 @@
  *  WHICH SAVES TIME AT THE EXPENSE OF SPACE.
  */
 static void
-mpmlp(int *u, int *v, int w, int j)
+mpmlp(int *u, const int *v, int w, int j)
 {
     int i;
     for (i = 0; i < j; i++)
@@ -2273,7 +2201,7 @@
  *  CHECK LEGALITY OF B, T, M AND MXR
  */
 void
-mpmul(int *x, int *y, int *z)
+mpmul(const int *x, const int *y, int *z)
 {
     int i__1, i__2;
 
@@ -2571,7 +2499,7 @@
     is = i;
     js = j;
     mpgcd(&is, &js);
-    if (C_abs(is) == 1) {
+    if (abs(is) == 1) {
         /* HERE IS = +-1 */
         mpdivi(x, is * js, y);
     } else {
@@ -2614,7 +2542,7 @@
 /* CHECK THAT SIGN = +-1 */
 
 L20:
-    if (C_abs(rs) <= 1) goto L40;
+    if (abs(rs) <= 1) goto L40;
 
     if (v->MPerrors) {
         FPRINTF(stderr, "*** SIGN NOT 0, +1 OR -1 IN CALL TO MPNZR.\nPOSSIBLE OVERWRITING PROBLEM ***\n");
@@ -2794,7 +2722,7 @@
 
 /* RETURN IF ERROR IS LESS THAN 0.01 */
 
-    prec = dabs(mp_cast_to_float(x) - 3.1416);
+    prec = fabs(mp_cast_to_float(x) - 3.1416);
     if (prec < 0.01) return;
 
 /* FOLLOWING MESSAGE MAY INDICATE THAT B**(T-1) IS TOO SMALL */
@@ -2927,26 +2855,27 @@
 }
 
 
+/*  RETURNS Y = 1/X, FOR MP X AND Y.
+ *  MPROOT (X, -1, Y) HAS THE SAME EFFECT.
+ *  DIMENSION OF R MUST BE AT LEAST 4*T+10 IN CALLING PROGRAM
+ *  (BUT Y(1) MAY BE R(3T+9)).
+ *  NEWTONS METHOD IS USED, SO FINAL ONE OR TWO DIGITS MAY
+ *  NOT BE CORRECT.
+ */
+
 static void
-mprec(int *x, int *y)
+mprec(const int *x, int *y)
 {
 
 /* Initialized data */
 
     static int it[9] = { 0, 8, 6, 5, 4, 4, 4, 4, 4 };
 
-    float r__1;
+    int tmp_x[MP_SIZE];
 
     int i2, i3, ex, ts, it0, ts2, ts3;
     float rx;
 
-/*  RETURNS Y = 1/X, FOR MP X AND Y.
- *  MPROOT (X, -1, Y) HAS THE SAME EFFECT.
- *  DIMENSION OF R MUST BE AT LEAST 4*T+10 IN CALLING PROGRAM
- *  (BUT Y(1) MAY BE R(3T+9)).
- *  NEWTONS METHOD IS USED, SO FINAL ONE OR TWO DIGITS MAY
- *  NOT BE CORRECT.
- */
 
 /* CHECK LEGALITY OF B, T, M AND MXR */
 
@@ -2956,17 +2885,16 @@
 
     i2 = (MP.t << 1) + 7;
     i3 = i2 + MP.t + 2;
-    if (x[0] != 0) goto L20;
-
-    if (v->MPerrors) {
+    if (x[0] == 0) {
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** ATTEMPTED DIVISION BY ZERO IN CALL TO MPREC ***\n");
-    }
+      }
 
-    mperr();
-    y[0] = 0;
-    return;
+      mperr();
+      y[0] = 0;
+      return;
+    }
 
-L20:
     ex = x[1];
 
 /* TEMPORARILY INCREASE M TO AVOID OVERFLOW */
@@ -2975,17 +2903,15 @@
 
 /* SET EXPONENT TO ZERO SO RX NOT TOO LARGE OR SMALL. */
 
-    x[1] = 0;
-    rx = mp_cast_to_float(x);
+    /* work-around to avoid touching X */
+    mp_set_from_mp(x, tmp_x);
+    tmp_x[1] = 0;
+    rx = mp_cast_to_float(tmp_x);
 
 /* USE SINGLE-PRECISION RECIPROCAL AS FIRST APPROXIMATION */
 
-    r__1 = (float)1. / rx;
-    mp_set_from_float(r__1, &MP.r[i2 - 1]);
-
-/* RESTORE EXPONENT */
+    mp_set_from_float((float)1. / rx, &MP.r[i2 - 1]);
 
-    x[1] = ex;
 
 /* CORRECT EXPONENT OF FIRST APPROXIMATION */
 
@@ -3088,70 +3014,64 @@
 
     /* CHECK LEGALITY OF B, T, M AND MXR */
     mpchk(4, 10);
-    if (n != 1) goto L10;
-    mp_set_from_mp(x, y);
-    return;
 
-L10:
-    i2 = (MP.t << 1) + 7;
-    i3 = i2 + MP.t + 2;
-    if (n != 0) goto L30;
+    if (n == 1) {
+      mp_set_from_mp(x, y);
+      return;
+    }
 
-    if (v->MPerrors) {
+    if (n == 0) {
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** N = 0 IN CALL TO MPROOT ***\n");
+      }
+      
+      goto L50;
     }
 
-    goto L50;
-
-L30:
-    np = C_abs(n);
+    i2 = (MP.t << 1) + 7;
+    i3 = i2 + MP.t + 2;
 
-/* LOSS OF ACCURACY IF NP LARGE, SO ONLY ALLOW NP .LE. MAX (B, 64) */
+    np = abs(n);
 
-    if (np <= max(MP.b,64)) goto L60;
+/* LOSS OF ACCURACY IF NP LARGE, SO ONLY ALLOW NP <= MAX (B, 64) */
 
-    if (v->MPerrors) {
+    if (np > max(MP.b, 64)) {
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** ABS(N) TOO LARGE IN CALL TO MPROOT ***\n");
-    }
+      }
 
 L50:
-    mperr();
-    y[0] = 0;
-    return;
+      mperr();
+      y[0] = 0;
+      return;
+    }
 
 /* LOOK AT SIGN OF X */
 
-L60:
-    if (x[0] < 0)  goto L90;
-    else if (x[0] == 0) goto L70;
-    else goto L110;
-
-/* X = 0 HERE, RETURN 0 IF N POSITIVE, ERROR IF NEGATIVE */
-
-L70:
-    y[0] = 0;
-    if (n > 0) return;
+    if (x[0] == 0) {
+      /* X = 0 HERE, RETURN 0 IF N POSITIVE, ERROR IF NEGATIVE */
+      y[0] = 0;
+      if (n > 0) return;
 
-    if (v->MPerrors) {
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** X = 0 AND N NEGATIVE IN CALL TO MPROOT ***\n");
-    }
-
-    goto L50;
-
-/* X NEGATIVE HERE, SO ERROR IF N IS EVEN */
-
-L90:
-    if (np % 2 != 0) goto L110;
+      }
 
-    if (v->MPerrors) {
+      goto L50;
+    }
+    
+    if (x[0] < 0  &&  np % 2 == 0) {
+      /* X NEGATIVE HERE, SO ERROR IF N IS EVEN */
+      if (v->MPerrors) {
         FPRINTF(stderr, "*** X NEGATIVE AND N EVEN IN CALL TO MPROOT ***\n");
+      }
+      goto L50;
     }
 
-    goto L50;
+
 
 /* GET EXPONENT AND DIVIDE BY NP */
 
-L110:
     xes = x[1];
     ex = xes / np;
 
@@ -3161,7 +3081,7 @@
 
     /* USE SINGLE-PRECISION ROOT FOR FIRST APPROXIMATION */
     r__1 = exp(((float) (np * ex - xes) * log((float) MP.b) - 
-           log((dabs(rx)))) / (float) np);
+           log((fabs(rx)))) / (float) np);
     mp_set_from_float(r__1, &MP.r[i2 - 1]);
 
     /* SIGN OF APPROXIMATION SAME AS THAT OF X */
@@ -3244,13 +3164,12 @@
 
 L160:
     MP.t = ts;
-    if (n < 0) goto L170;
-
-    mppwr(&MP.r[i2 - 1], n - 1, &MP.r[i2 - 1]);
-    mpmul(x, &MP.r[i2 - 1], y);
-    return;
+    if (n >= 0) {
+      mppwr(&MP.r[i2 - 1], n - 1, &MP.r[i2 - 1]);
+      mpmul(x, &MP.r[i2 - 1], y);
+      return;
+    }
 
-L170:
     mp_set_from_mp(&MP.r[i2 - 1], y);
 }
 
@@ -3368,8 +3287,6 @@
 void
 mpsin(int *x, int *y)
 {
-    float r__1;
-
     int i2, i3, ie, xs;
     float rx = 0.0, ry;
 
@@ -3382,7 +3299,7 @@
     }
 
     xs = x[0];
-    ie = C_abs(x[1]);
+    ie = abs(x[1]);
     if (ie <= 2)
         rx = mp_cast_to_float(x);
 
@@ -3450,11 +3367,11 @@
     /*  CHECK THAT ABSOLUTE ERROR LESS THAN 0.01 IF ABS(X) .LE. 100
      *  (IF ABS(X) IS LARGE THEN SINGLE-PRECISION SIN INACCURATE)
      */
-    if (dabs(rx) > (float)100.)
+    if (fabs(rx) > (float)100.)
         return;
 
     ry = mp_cast_to_float(y);
-    if ((r__1 = ry - sin(rx), dabs(r__1)) < (float) 0.01)
+    if (fabs(ry - sin(rx)) < (float) 0.01)
         return;
 
     /*  THE FOLLOWING MESSAGE MAY INDICATE THAT
@@ -3474,7 +3391,7 @@
  *  O(SQRT(T)M(T)) AS IN MPEXP1, BUT NOT WORTHWHILE UNLESS
  *  T IS VERY LARGE.  ASYMPTOTICALLY FASTER METHODS ARE
  *  DESCRIBED IN THE REFERENCES GIVEN IN COMMENTS
- *  TO MPATAN AND MPPIGL.
+ *  TO MP_ATAN AND MPPIGL.
  *  DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 3T+8
  *  CHECK LEGALITY OF B, T, M AND MXR
  */

Modified: trunk/gcalctool/mp.h
==============================================================================
--- trunk/gcalctool/mp.h	(original)
+++ trunk/gcalctool/mp.h	Thu Sep 25 02:02:18 2008
@@ -46,16 +46,16 @@
 void mp_subtract(const int *, const int *, int *);
 
 void mpasin(int *, int *);
-void mpatan(int *, int *);
-void mpcmf(int *, int *);
-void mpcmim(int *, int *);
+void mp_atan(const int *, int *);
+void mpcmf(const int *, int *);
+void mpcmim(const int *, int *);
 void mpcos(int *, int *);
-void mpcosh(int *, int *);
-void mpdiv(int *, int *, int *);
-void mpdivi(int *, int, int *);
-void mpexp(int *, int *);
+void mpcosh(const int *, int *);
+void mpdiv(const int *, const int *, int *);
+void mpdivi(const int *, int, int *);
+void mpexp(const int *, int *);
 void mpln(int *, int *);
-void mpmul(int *, int *, int *);
+void mpmul(const int *, const int *, int *);
 void mpmuli(int *, int, int *);
 void mppi(int *);
 void mppwr(const int *, int, int *);

Modified: trunk/gcalctool/mpmath.c
==============================================================================
--- trunk/gcalctool/mpmath.c	(original)
+++ trunk/gcalctool/mpmath.c	Thu Sep 25 02:02:18 2008
@@ -357,7 +357,7 @@
         mp_subtract(MP1, MP2, MP2);
         mpsqrt(MP2, MP2);
         mpdiv(MP2, MPx, MP2);
-        mpatan(MP2, MPy);
+        mp_atan(MP2, MPy);
         if (mp_is_greater_than(MPx, MP0)) {
             mp_set_from_mp(MPy, MPretval);
         } else {
@@ -786,7 +786,7 @@
             break;
 
         case atan_t:
-            mpatan(s1, t1);
+            mp_atan(s1, t1);
             do_trig_typeconv(v->ttype, t1, t1);
             break;
 

Modified: trunk/gcalctool/unittest.c
==============================================================================
--- trunk/gcalctool/unittest.c	(original)
+++ trunk/gcalctool/unittest.c	Thu Sep 25 02:02:18 2008
@@ -83,6 +83,11 @@
     //FIXME: Need to update mperr() test("1/2", "0.5", 0);
     //FIXME: Need to update mperr() test("1/0", "", 0);
     //FIXME: Need to update mperr() test("0/0", "", 0);
+    test("2/2", "1", 0);
+    test("1203/1", "1203", 0);
+    test("-0/32352.689", "0", 0);
+    test("1/4", "0.25", 0);
+    test("(-3)/(-6)", "0.5", 0);
 
     test("1+2*3", "7", 0);    
     test("(1+2)*3", "9", 0);



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