Fix errors from make distcheck
[gcalctool.git] / src / mp.c
blob69ebaeef10a9c5d8d59073078f8ab37252af43dd
2 /* $Header$
4 * Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <errno.h>
27 #include "mp.h"
28 #include "mp-internal.h"
29 #include "calctool.h" // FIXME: Required for doerr() and MAXLINE
31 // FIXME: MP.t and MP.m modified inside functions, needs to be fixed to be thread safe
33 /* SETS X TO THE LARGEST POSSIBLE POSITIVE MP NUMBER
34 * CHECK LEGALITY OF B, T, M AND MXR
36 static void
37 mpmaxr(MPNumber *x)
39 int i, it;
41 mpchk();
42 it = MP.b - 1;
44 /* SET FRACTION DIGITS TO B-1 */
45 for (i = 0; i < MP.t; i++)
46 x->fraction[i] = it;
48 /* SET SIGN AND EXPONENT */
49 x->sign = 1;
50 x->exponent = MP.m;
54 /* CALLED ON MULTIPLE-PRECISION OVERFLOW, IE WHEN THE
55 * EXPONENT OF MP NUMBER X WOULD EXCEED M.
56 * AT PRESENT EXECUTION IS TERMINATED WITH AN ERROR MESSAGE
57 * AFTER CALLING MPMAXR(X), BUT IT WOULD BE POSSIBLE TO RETURN,
58 * POSSIBLY UPDATING A COUNTER AND TERMINATING EXECUTION AFTER
59 * A PRESET NUMBER OF OVERFLOWS. ACTION COULD EASILY BE DETERMINED
60 * BY A FLAG IN LABELLED COMMON.
61 * M MAY HAVE BEEN OVERWRITTEN, SO CHECK B, T, M ETC.
63 static void
64 mpovfl(MPNumber *x, const char *error)
66 fprintf(stderr, "%s\n", error);
68 mpchk();
70 /* SET X TO LARGEST POSSIBLE POSITIVE NUMBER */
71 mpmaxr(x);
73 /* TERMINATE EXECUTION BY CALLING MPERR */
74 mperr("*** CALL TO MPOVFL, MP OVERFLOW OCCURRED ***");
78 /* CALLED ON MULTIPLE-PRECISION UNDERFLOW, IE WHEN THE
79 * EXPONENT OF MP NUMBER X WOULD BE LESS THAN -M.
80 * SINCE M MAY HAVE BEEN OVERWRITTEN, CHECK B, T, M ETC.
82 static void
83 mpunfl(MPNumber *x)
85 mpchk();
87 /* THE UNDERFLOWING NUMBER IS SET TO ZERO
88 * AN ALTERNATIVE WOULD BE TO CALL MPMINR (X) AND RETURN,
89 * POSSIBLY UPDATING A COUNTER AND TERMINATING EXECUTION
90 * AFTER A PRESET NUMBER OF UNDERFLOWS. ACTION COULD EASILY
91 * BE DETERMINED BY A FLAG IN LABELLED COMMON.
93 x->sign = 0;
97 static int
98 pow_ii(int x, int n)
100 int pow = 1;
102 if (n > 0) {
103 for (;;) {
104 if (n & 01) pow *= x;
105 if (n >>= 1) x *= x;
106 else break;
110 return(pow);
114 /* ROUTINE CALLED BY MP_DIVIDE AND MP_SQRT TO ENSURE THAT
115 * RESULTS ARE REPRESENTED EXACTLY IN T-2 DIGITS IF THEY
116 * CAN BE. X IS AN MP NUMBER, I AND J ARE INTEGERS.
118 static void
119 mpext(int i, int j, MPNumber *x)
121 int q, s;
123 if (x->sign == 0 || MP.t <= 2 || i == 0)
124 return;
126 /* COMPUTE MAXIMUM POSSIBLE ERROR IN THE LAST PLACE */
127 q = (j + 1) / i + 1;
128 s = MP.b * x->fraction[MP.t - 2] + x->fraction[MP.t - 1];
130 /* SET LAST TWO DIGITS TO ZERO */
131 if (s <= q) {
132 x->fraction[MP.t - 2] = 0;
133 x->fraction[MP.t - 1] = 0;
134 return;
137 if (s + q < MP.b * MP.b)
138 return;
140 /* ROUND UP HERE */
141 x->fraction[MP.t - 2] = MP.b - 1;
142 x->fraction[MP.t - 1] = MP.b;
144 /* NORMALIZE X (LAST DIGIT B IS OK IN MP_MULTIPLY_INTEGER) */
145 mp_multiply_integer(x, 1, x);
149 /* SETS BASE (B) AND NUMBER OF DIGITS (T) TO GIVE THE
150 * EQUIVALENT OF AT LEAST IDECPL DECIMAL DIGITS.
151 * IDECPL SHOULD BE POSITIVE.
152 * ITMAX2 IS THE DIMENSION OF ARRAYS USED FOR MP NUMBERS,
153 * SO AN ERROR OCCURS IF THE COMPUTED T EXCEEDS ITMAX2 - 2.
154 * MPSET ALSO SETS
155 * MXR = MAXDR (DIMENSION OF R IN COMMON, >= T+4), AND
156 * M = (W-1)/4 (MAXIMUM ALLOWABLE EXPONENT),
157 * WHERE W IS THE LARGEST INTEGER OF THE FORM 2**K-1 WHICH IS
158 * REPRESENTABLE IN THE MACHINE, K <= 47
159 * THE COMPUTED B AND T SATISFY THE CONDITIONS
160 * (T-1)*LN(B)/LN(10) >= IDECPL AND 8*B*B-1 <= W .
161 * APPROXIMATELY MINIMAL T AND MAXIMAL B SATISFYING
162 * THESE CONDITIONS ARE CHOSEN.
163 * PARAMETERS IDECPL, ITMAX2 AND MAXDR ARE INTEGERS.
164 * BEWARE - MPSET WILL CAUSE AN INTEGER OVERFLOW TO OCCUR
165 * ****** IF WORDLENGTH IS LESS THAN 48 BITS.
166 * IF THIS IS NOT ALLOWABLE, CHANGE THE DETERMINATION
167 * OF W (DO 30 ... TO 30 W = WN) OR SET B, T, M,
168 * AND MXR WITHOUT CALLING MPSET.
169 * FIRST SET MXR
171 void
172 mp_init(int accuracy)
174 int i, k, w;
176 /* DETERMINE LARGE REPRESENTABLE INTEGER W OF FORM 2**K - 1 */
177 /* ON CYBER 76 HAVE TO FIND K <= 47, SO ONLY LOOP
178 * 47 TIMES AT MOST. IF GENUINE INTEGER WORDLENGTH
179 * EXCEEDS 47 BITS THIS RESTRICTION CAN BE RELAXED.
181 w = 0;
182 k = 0;
183 for (i = 1; i <= 47; ++i) {
184 int w2, wn;
186 /* INTEGER OVERFLOW WILL EVENTUALLY OCCUR HERE
187 * IF WORDLENGTH < 48 BITS
189 w2 = w + w;
190 wn = w2 + 1;
192 /* APPARENTLY REDUNDANT TESTS MAY BE NECESSARY ON SOME
193 * MACHINES, DEPENDING ON HOW INTEGER OVERFLOW IS HANDLED
195 if (wn <= w || wn <= w2 || wn <= 0)
196 break;
197 k = i;
198 w = wn;
201 /* SET MAXIMUM EXPONENT TO (W-1)/4 */
202 MP.m = w / 4;
203 if (accuracy <= 0) {
204 mperr("*** ACCURACY <= 0 IN CALL TO MPSET ***");
205 return;
208 /* B IS THE LARGEST POWER OF 2 SUCH THAT (8*B*B-1) <= W */
209 MP.b = pow_ii(2, (k - 3) / 2);
211 /* 2E0 BELOW ENSURES AT LEAST ONE GUARD DIGIT */
212 MP.t = (int) ((float) (accuracy) * log((float)10.) / log((float) MP.b) +
213 (float) 2.0);
215 /* SEE IF T TOO LARGE FOR DIMENSION STATEMENTS */
216 if (MP.t > MP_SIZE) {
217 mperr("MP_SIZE TOO SMALL IN CALL TO MPSET, INCREASE MP_SIZE AND DIMENSIONS OF MP ARRAYS TO AT LEAST %d ***", MP.t);
218 MP.t = MP_SIZE;
221 /* CHECK LEGALITY OF B, T, M AND MXR (AT LEAST T+4) */
222 mpchk();
226 /* CHECKS LEGALITY OF B, T, M AND MXR.
227 * THE CONDITION ON MXR (THE DIMENSION OF R IN COMMON) IS THAT
228 * MXR >= (I*T + J)
230 // FIXME: MP.t is changed around calls to add/subtract/multiply/divide - it should not be global
231 void
232 mpchk()
234 /* CHECK LEGALITY OF T AND M */
235 if (MP.t <= 1)
236 mperr("*** T = %d ILLEGAL IN CALL TO MPCHK, PERHAPS NOT SET BEFORE CALL TO AN MP ROUTINE ***", MP.t);
237 if (MP.m <= MP.t)
238 mperr("*** M <= T IN CALL TO MPCHK, PERHAPS NOT SET BEFORE CALL TO AN MP ROUTINE ***");
242 /* SETS Y = ABS(X) FOR MP NUMBERS X AND Y */
243 void
244 mp_abs(const MPNumber *x, MPNumber *z)
246 mp_set_from_mp(x, z);
247 if (z->sign < 0)
248 z->sign = -z->sign;
252 /* CALLED BY MPADD2, DOES INNER LOOPS OF ADDITION */
253 /* return value is amount by which exponent needs to be increased. */
254 static int
255 mp_add3(const MPNumber *x, const MPNumber *y, int *r, int s, int med)
257 int i, c;
259 /* CLEAR GUARD DIGITS TO RIGHT OF X DIGITS */
260 for(i = 3; i >= med; i--)
261 r[MP.t + i] = 0;
263 if (s >= 0) {
264 /* HERE DO ADDITION, EXPONENT(Y) >= EXPONENT(X) */
265 for (i = MP.t + 3; i >= MP.t; i--)
266 r[i] = x->fraction[i - med];
268 c = 0;
269 for (; i >= med; i--) {
270 c = y->fraction[i] + x->fraction[i - med] + c;
272 if (c < MP.b) {
273 /* NO CARRY GENERATED HERE */
274 r[i] = c;
275 c = 0;
276 } else {
277 /* CARRY GENERATED HERE */
278 r[i] = c - MP.b;
279 c = 1;
283 for (; i >= 0; i--)
285 c = y->fraction[i] + c;
286 if (c < MP.b) {
287 r[i] = c;
288 i--;
290 /* NO CARRY POSSIBLE HERE */
291 for (; i >= 0; i--)
292 r[i] = y->fraction[i];
294 return 0;
297 r[i] = 0;
298 c = 1;
301 /* MUST SHIFT RIGHT HERE AS CARRY OFF END */
302 if (c != 0) {
303 for (i = MP.t + 3; i > 0; i--)
304 r[i] = r[i - 1];
305 r[0] = 1;
306 return 1;
309 return 0;
312 c = 0;
313 for (i = MP.t + med - 1; i >= MP.t; i--) {
314 /* HERE DO SUBTRACTION, ABS(Y) > ABS(X) */
315 r[i] = c - x->fraction[i - med];
316 c = 0;
318 /* BORROW GENERATED HERE */
319 if (r[i] < 0) {
320 c = -1;
321 r[i] += MP.b;
325 for(; i >= med; i--) {
326 c = y->fraction[i] + c - x->fraction[i - med];
327 if (c >= 0) {
328 /* NO BORROW GENERATED HERE */
329 r[i] = c;
330 c = 0;
331 } else {
332 /* BORROW GENERATED HERE */
333 r[i] = c + MP.b;
334 c = -1;
338 for (; i >= 0; i--) {
339 c = y->fraction[i] + c;
341 if (c >= 0) {
342 r[i] = c;
343 i--;
345 /* NO CARRY POSSIBLE HERE */
346 for (; i >= 0; i--)
347 r[i] = y->fraction[i];
349 return 0;
352 r[i] = c + MP.b;
353 c = -1;
356 return 0;
360 /* z = x + y_sign * abs(y) */
361 static void
362 mp_add2(const MPNumber *x, const MPNumber *y, int y_sign, MPNumber *z)
364 int sign_prod;
365 int exp_diff, med;
366 int x_largest = 0;
367 MPNumber zt; // Use stack variable because of mp_normalize brokeness
369 /* X = 0 OR NEGLIGIBLE, SO RESULT = +-Y */
370 if (x->sign == 0) {
371 mp_set_from_mp(y, z);
372 z->sign = y_sign;
373 return;
376 /* Y = 0 OR NEGLIGIBLE, SO RESULT = X */
377 if (y->sign == 0 || y->sign == 0) {
378 mp_set_from_mp(x, z);
379 return;
382 /* COMPARE SIGNS */
383 sign_prod = y_sign * x->sign;
384 if (abs(sign_prod) > 1) {
385 mpchk();
386 mperr("*** SIGN NOT 0, +1 OR -1 IN MP_ADD2 CALL, POSSIBLE OVERWRITING PROBLEM ***");
387 z->sign = 0;
388 return;
391 /* COMPARE EXPONENTS */
392 exp_diff = x->exponent - y->exponent;
393 med = abs(exp_diff);
394 if (exp_diff < 0) {
395 /* HERE EXPONENT(Y) > EXPONENT(X) */
396 if (med > MP.t) {
397 /* 'y' so much larger than 'x' that 'x+-y = y'. Warning: still true with rounding?? */
398 mp_set_from_mp(y, z);
399 z->sign = y_sign;
400 return;
402 x_largest = 0;
403 } else if (exp_diff > 0) {
404 /* HERE EXPONENT(X) > EXPONENT(Y) */
405 if (med > MP.t) {
406 /* 'x' so much larger than 'y' that 'x+-y = x'. Warning: still true with rounding?? */
407 mp_set_from_mp(x, z);
408 return;
410 x_largest = 1;
411 } else {
412 /* EXPONENTS EQUAL SO COMPARE SIGNS, THEN FRACTIONS IF NEC. */
413 if (sign_prod < 0) {
414 /* Signs are not equal. find out which mantissa is larger. */
415 int j;
416 for (j = 0; j < MP.t; j++) {
417 int i = x->fraction[j] - y->fraction[j];
418 if (i == 0)
419 continue;
420 if (i < 0)
421 x_largest = 0;
422 else if (i > 0)
423 x_largest = 1;
424 break;
427 /* Both mantissas equal, so result is zero. */
428 if (j >= MP.t) {
429 z->sign = 0;
430 return;
435 /* NORMALIZE, ROUND OR TRUNCATE, AND RETURN */
436 if (x_largest) {
437 zt.sign = x->sign;
438 zt.exponent = x->exponent + mp_add3(y, x, zt.fraction, sign_prod, med);
439 } else {
440 zt.sign = y_sign;
441 zt.exponent = y->exponent + mp_add3(x, y, zt.fraction, sign_prod, med);
443 mp_normalize(&zt, 0);
444 mp_set_from_mp(&zt, z);
448 /* ADDS X AND Y, FORMING RESULT IN Z, WHERE X, Y AND Z ARE MP
449 * NUMBERS. FOUR GUARD DIGITS ARE USED, AND THEN R*-ROUNDING.
451 void
452 mp_add(const MPNumber *x, const MPNumber *y, MPNumber *z)
454 mp_add2(x, y, y->sign, z);
458 /* ADDS MULTIPLE-PRECISION X TO INTEGER Y
459 * GIVING MULTIPLE-PRECISION Z.
460 * DIMENSION OF R IN CALLING PROGRAM MUST BE
461 * AT LEAST 2T+6 (BUT Z(1) MAY BE R(T+5)).
462 * DIMENSION R(6) BECAUSE RALPH COMPILER ON UNIVAC 1100 COMPUTERS
463 * OBJECTS TO DIMENSION R(1).
464 * CHECK LEGALITY OF B, T, M AND MXR
466 void
467 mp_add_integer(const MPNumber *x, int y, MPNumber *z)
469 MPNumber t;
470 mpchk();
471 mp_set_from_integer(y, &t);
472 mp_add(x, &t, z);
476 /* ADDS THE RATIONAL NUMBER I/J TO MP NUMBER X, MP RESULT IN Y
477 * DIMENSION OF R MUST BE AT LEAST 2T+6
478 * CHECK LEGALITY OF B, T, M AND MXR
480 void
481 mp_add_fraction(const MPNumber *x, int i, int j, MPNumber *y)
483 MPNumber t;
484 mpchk();
485 mp_set_from_fraction(i, j, &t);
486 mp_add(x, &t, y);
490 /* FOR MP X AND Y, RETURNS FRACTIONAL PART OF X IN Y,
491 * I.E., Y = X - INTEGER PART OF X (TRUNCATED TOWARDS 0).
493 void
494 mp_fractional_component(const MPNumber *x, MPNumber *y)
496 /* RETURN 0 IF X = 0
497 OR IF EXPONENT SO LARGE THAT NO FRACTIONAL PART */
498 if (x->sign == 0 || x->exponent >= MP.t) {
499 y->sign = 0;
500 return;
503 /* IF EXPONENT NOT POSITIVE CAN RETURN X */
504 if (x->exponent <= 0) {
505 mp_set_from_mp(x, y);
506 return;
509 /* MOVE FRACTIONAL PART OF X TO ACCUMULATOR */
510 y->sign = x->sign;
511 y->exponent = x->exponent;
512 memset(y->fraction, 0, y->exponent*sizeof(int));
513 if (x != y)
514 memcpy(y->fraction + y->exponent, x->fraction + x->exponent,
515 (MP.t - x->exponent)*sizeof(int));
516 memset(y->fraction + MP.t, 0, 4*sizeof(int));
518 /* NORMALIZE RESULT AND RETURN */
519 mp_normalize(y, 1);
522 /* RETURNS Y = INTEGER PART OF X (TRUNCATED TOWARDS 0), FOR MP X AND Y.
523 * USE IF Y TOO LARGE TO BE REPRESENTABLE AS A SINGLE-PRECISION INTEGER.
524 * (ELSE COULD USE MPCMI).
525 * CHECK LEGALITY OF B, T, M AND MXR
527 void
528 mp_integer_component(const MPNumber *x, MPNumber *y)
530 int i;
532 mpchk();
533 mp_set_from_mp(x, y);
534 if (y->sign == 0)
535 return;
537 /* IF EXPONENT LARGE ENOUGH RETURN Y = X */
538 if (y->exponent >= MP.t) {
539 return;
542 /* IF EXPONENT SMALL ENOUGH RETURN ZERO */
543 if (y->exponent <= 0) {
544 y->sign = 0;
545 return;
548 /* SET FRACTION TO ZERO */
549 for (i = y->exponent; i < MP.t; i++) {
550 y->fraction[i] = 0;
554 /* COMPARES MP NUMBER X WITH REAL NUMBER RI, RETURNING
555 * +1 IF X > RI,
556 * 0 IF X == RI,
557 * -1 IF X < RI
558 * DIMENSION OF R IN COMMON AT LEAST 2T+6
559 * CHECK LEGALITY OF B, T, M AND MXR
561 static int
562 mp_compare_mp_to_float(const MPNumber *x, float ri)
564 MPNumber t;
565 mpchk();
567 /* CONVERT RI TO MULTIPLE-PRECISION AND COMPARE */
568 mp_set_from_float(ri, &t);
569 return mp_compare_mp_to_mp(x, &t);
572 /* COMPARES THE MULTIPLE-PRECISION NUMBERS X AND Y,
573 * RETURNING +1 IF X > Y,
574 * -1 IF X < Y,
575 * AND 0 IF X == Y.
578 mp_compare_mp_to_mp(const MPNumber *x, const MPNumber *y)
580 int i, i2;
582 if (x->sign < y->sign)
583 return -1;
584 if (x->sign > y->sign)
585 return 1;
587 /* SIGN(X) == SIGN(Y), SEE IF ZERO */
588 if (x->sign == 0)
589 return 0; /* X == Y == 0 */
591 /* HAVE TO COMPARE EXPONENTS AND FRACTIONS */
592 i2 = x->exponent - y->exponent;
593 if (i2 < 0) {
594 /* ABS(X) < ABS(Y) */
595 return -x->sign;
597 if (i2 > 0) {
598 /* ABS(X) > ABS(Y) */
599 return x->sign;
601 for (i = 0; i < MP.t; i++) {
602 i2 = x->fraction[i] - y->fraction[i];
603 if (i2 < 0) {
604 /* ABS(X) < ABS(Y) */
605 return -x->sign;
607 if (i2 > 0) {
608 /* ABS(X) > ABS(Y) */
609 return x->sign;
613 /* NUMBERS EQUAL */
614 return 0;
617 /* SETS Z = X/Y, FOR MP X, Y AND Z.
618 * DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 4T+10
619 * (BUT Z(1) MAY BE R(3T+9)).
620 * CHECK LEGALITY OF B, T, M AND MXR
622 void
623 mp_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
625 int i, ie, iz3;
626 MPNumber t;
628 mpchk();
630 /* CHECK FOR DIVISION BY ZERO */
631 if (y->sign == 0) {
632 mperr("*** ATTEMPTED DIVISION BY ZERO IN CALL TO MP_DIVIDE ***");
633 z->sign = 0;
634 return;
637 /* CHECK FOR X = 0 */
638 if (x->sign == 0) {
639 z->sign = 0;
640 return;
643 /* INCREASE M TO AVOID OVERFLOW IN MP_RECIPROCAL */
644 MP.m += 2;
646 /* FORM RECIPROCAL OF Y */
647 mp_reciprocal(y, &t);
649 /* SET EXPONENT OF R(I2) TO ZERO TO AVOID OVERFLOW IN MP_MULTIPLY */
650 ie = t.exponent;
651 t.exponent = 0;
652 i = t.fraction[0];
654 /* MULTIPLY BY X */
655 mp_multiply(x, &t, z);
656 iz3 = z->fraction[0];
657 mpext(i, iz3, z);
659 /* RESTORE M, CORRECT EXPONENT AND RETURN */
660 MP.m += -2;
661 z->exponent += ie;
663 /* Check for overflow or underflow */
664 if (z->exponent < -MP.m)
665 mpunfl(z);
666 else if (z->exponent > MP.m)
667 mpovfl(z, "*** OVERFLOW OCCURRED IN MP_DIVIDE ***");
671 /* DIVIDES MP X BY THE SINGLE-PRECISION INTEGER IY GIVING MP Z.
672 * THIS IS MUCH FASTER THAN DIVISION BY AN MP NUMBER.
674 void
675 mp_divide_integer(const MPNumber *x, int iy, MPNumber *z)
677 int i__1;
678 int c, i, k, b2, c2, i2, j1, j2, r1;
679 int j11, kh, iq, ir, iqj;
681 if (iy == 0) {
682 mperr("*** ATTEMPTED DIVISION BY ZERO IN CALL TO MP_DIVIDE_INTEGER ***");
683 z->sign = 0;
684 return;
687 z->sign = x->sign;
688 if (iy < 0) {
689 iy = -iy;
690 z->sign = -z->sign;
692 if (z->sign == 0)
693 return;
694 z->exponent = x->exponent;
696 /* CHECK FOR DIVISION BY B */
697 if (iy == MP.b) {
698 if (x->exponent <= -MP.m)
700 mpunfl(z);
701 return;
703 mp_set_from_mp(x, z);
704 z->exponent--;
705 return;
708 /* CHECK FOR DIVISION BY 1 OR -1 */
709 if (iy == 1) {
710 int s = z->sign;
711 mp_set_from_mp(x, z);
712 z->sign = s;
713 return;
716 c = 0;
717 i2 = MP.t + 4;
718 i = 0;
720 /* IF IY*B NOT REPRESENTABLE AS AN INTEGER HAVE TO SIMULATE
721 * LONG DIVISION. ASSUME AT LEAST 16-BIT WORD.
724 /* Computing MAX */
725 b2 = max(MP.b << 3, 32767 / MP.b);
726 if (iy < b2) {
727 /* LOOK FOR FIRST NONZERO DIGIT IN QUOTIENT */
728 do {
729 c = MP.b * c;
730 if (i < MP.t)
731 c += x->fraction[i];
732 i++;
733 r1 = c / iy;
734 if (r1 < 0)
735 goto L210;
736 } while(r1 == 0);
738 /* ADJUST EXPONENT AND GET T+4 DIGITS IN QUOTIENT */
739 z->exponent += 1 - i;
740 z->fraction[0] = r1;
741 c = MP.b * (c - iy * r1);
742 kh = 1;
743 if (i < MP.t) {
744 kh = MP.t + 1 - i;
745 for (k = 1; k < kh; k++) {
746 c += x->fraction[i];
747 z->fraction[k] = c / iy;
748 c = MP.b * (c - iy * z->fraction[k]);
749 i++;
751 if (c < 0)
752 goto L210;
755 for (k = kh; k < i2; k++) {
756 z->fraction[k] = c / iy;
757 c = MP.b * (c - iy * z->fraction[k]);
759 if (c < 0)
760 goto L210;
762 /* NORMALIZE AND ROUND RESULT */
763 mp_normalize(z, 0);
765 return;
768 /* HERE NEED SIMULATED DOUBLE-PRECISION DIVISION */
769 j1 = iy / MP.b;
771 /* LOOK FOR FIRST NONZERO DIGIT */
772 c2 = 0;
773 j2 = iy - j1 * MP.b;
774 do {
775 c = MP.b * c + c2;
776 i__1 = c - j1;
777 c2 = i < MP.t ? x->fraction[i] : 0;
778 i++;
779 } while (i__1 < 0 || (i__1 == 0 && c2 < j2));
781 /* COMPUTE T+4 QUOTIENT DIGITS */
782 z->exponent += 1 - i;
783 i--;
784 k = 1;
786 /* MAIN LOOP FOR LARGE ABS(IY) CASE */
787 j11 = j1 + 1;
788 while(1) {
789 /* GET APPROXIMATE QUOTIENT FIRST */
790 ir = c / j11;
792 /* NOW REDUCE SO OVERFLOW DOES NOT OCCUR */
793 iq = c - ir * j1;
794 if (iq >= b2) {
795 /* HERE IQ*B WOULD POSSIBLY OVERFLOW SO INCREASE IR */
796 ++ir;
797 iq -= j1;
800 iq = iq * MP.b - ir * j2;
801 if (iq < 0) {
802 /* HERE IQ NEGATIVE SO IR WAS TOO LARGE */
803 ir--;
804 iq += iy;
807 if (i < MP.t)
808 iq += x->fraction[i];
809 i++;
810 iqj = iq / iy;
812 /* R(K) = QUOTIENT, C = REMAINDER */
813 z->fraction[k - 1] = iqj + ir;
814 c = iq - iy * iqj;
816 if (c < 0)
817 goto L210;
819 ++k;
820 if (k > i2) {
821 mp_normalize(z, 0);
822 return;
826 L210:
827 /* CARRY NEGATIVE SO OVERFLOW MUST HAVE OCCURRED */
828 mpchk();
829 mperr("*** INTEGER OVERFLOW IN MP_DIVIDE_INTEGER, B TOO LARGE ***");
830 z->sign = 0;
835 mp_is_integer(const MPNumber *x)
837 MPNumber MPtt, MP0, MP1;
839 /* Multiplication and division by 10000 is used to get around a
840 * limitation to the "fix" for Sun bugtraq bug #4006391 in the
841 * mp_integer_component() routine in mp.c, when the exponent is less than 1.
843 mp_set_from_integer(10000, &MPtt);
844 mp_multiply(x, &MPtt, &MP0);
845 mp_divide(&MP0, &MPtt, &MP0);
846 mp_integer_component(&MP0, &MP1);
848 return mp_is_equal(&MP0, &MP1);
853 mp_is_natural(const MPNumber *x)
855 return x->sign > 0 && mp_is_integer(x);
859 /* RETURNS LOGICAL VALUE OF (X == Y) FOR MP X AND Y. */
861 mp_is_equal(const MPNumber *x, const MPNumber *y)
863 return mp_compare_mp_to_mp(x, y) == 0;
867 /* THIS ROUTINE IS CALLED WHEN AN ERROR CONDITION IS ENCOUNTERED, AND
868 * AFTER A MESSAGE HAS BEEN WRITTEN TO STDERR.
870 void
871 mperr(const char *format, ...)
873 char text[MAXLINE];
874 va_list args;
876 va_start(args, format);
877 vsnprintf(text, MAXLINE, format, args);
878 va_end(args);
879 doerr(text);
883 /* RETURNS Z = EXP(X) FOR MP X AND Z.
884 * EXP OF INTEGER AND FRACTIONAL PARTS OF X ARE COMPUTED
885 * SEPARATELY. SEE ALSO COMMENTS IN MPEXP1.
886 * TIME IS O(SQRT(T)M(T)).
887 * DIMENSION OF R MUST BE AT LEAST 4T+10 IN CALLING PROGRAM
888 * CHECK LEGALITY OF B, T, M AND MXR
890 void
891 mp_epowy(const MPNumber *x, MPNumber *z)
893 float r__1;
894 int i, ie, ix, ts, xs, tss;
895 float rx, rz, rlb;
896 MPNumber t1, t2;
898 mpchk();
900 /* CHECK FOR X == 0 */
901 if (x->sign == 0) {
902 mp_set_from_integer(1, z);
903 return;
906 /* CHECK IF ABS(X) < 1 */
907 if (x->exponent <= 0) {
908 /* USE MPEXP1 HERE */
909 mpexp1(x, z);
910 mp_add_integer(z, 1, z);
911 return;
914 /* SEE IF ABS(X) SO LARGE THAT EXP(X) WILL CERTAINLY OVERFLOW
915 * OR UNDERFLOW. 1.01 IS TO ALLOW FOR ERRORS IN ALOG.
917 rlb = log((float) MP.b) * (float)1.01;
918 if (mp_compare_mp_to_float(x, -(double)((float) (MP.m + 1)) * rlb) < 0) {
919 /* UNDERFLOW SO CALL MPUNFL AND RETURN */
920 mpunfl(z);
921 return;
924 if (mp_compare_mp_to_float(x, (float) MP.m * rlb) > 0) {
925 /* OVERFLOW HERE */
926 mpovfl(z, "*** OVERFLOW IN SUBROUTINE MP_EPOWY ***");
927 return;
930 /* NOW SAFE TO CONVERT X TO REAL */
931 rx = mp_cast_to_float(x);
933 /* SAVE SIGN AND WORK WITH ABS(X) */
934 xs = x->sign;
935 mp_abs(x, &t2);
937 /* IF ABS(X) > M POSSIBLE THAT INT(X) OVERFLOWS,
938 * SO DIVIDE BY 32.
940 if (fabs(rx) > (float) MP.m) {
941 mp_divide_integer(&t2, 32, &t2);
944 /* GET FRACTIONAL AND INTEGER PARTS OF ABS(X) */
945 ix = mp_cast_to_int(&t2);
946 mp_fractional_component(&t2, &t2);
948 /* ATTACH SIGN TO FRACTIONAL PART AND COMPUTE EXP OF IT */
949 t2.sign *= xs;
950 mpexp1(&t2, z);
951 mp_add_integer(z, 1, z);
953 /* COMPUTE E-2 OR 1/E USING TWO EXTRA DIGITS IN CASE ABS(X) LARGE
954 * (BUT ONLY ONE EXTRA DIGIT IF T < 4)
956 if (MP.t < 4)
957 tss = MP.t + 1;
958 else
959 tss = MP.t + 2;
961 /* LOOP FOR E COMPUTATION. DECREASE T IF POSSIBLE. */
962 /* Computing MIN */
963 ts = MP.t;
964 MP.t = tss;
965 mp_set_from_integer(xs, &t1);
966 MP.t = ts;
968 t2.sign = 0;
969 for (i = 2 ; ; i++) {
970 int t;
972 t = min(tss, tss + 2 + t1.exponent);
973 if (t <= 2)
974 break;
976 ts = MP.t;
977 MP.t = t;
978 mp_divide_integer(&t1, i * xs, &t1);
979 MP.t = ts;
981 ts = MP.t;
982 MP.t = tss;
983 mp_add(&t2, &t1, &t2);
984 MP.t = ts;
985 if (t1.sign == 0)
986 break;
989 /* RAISE E OR 1/E TO POWER IX */
990 ts = MP.t;
991 MP.t = tss;
992 if (xs > 0)
993 mp_add_integer(&t2, 2, &t2);
994 mp_pwr_integer(&t2, ix, &t2);
995 MP.t = ts;
997 /* MULTIPLY EXPS OF INTEGER AND FRACTIONAL PARTS */
998 mp_multiply(z, &t2, z);
1000 /* MUST CORRECT RESULT IF DIVIDED BY 32 ABOVE. */
1001 if (fabs(rx) > (float) MP.m && z->sign != 0) {
1002 for (i = 1; i <= 5; ++i) {
1003 /* SAVE EXPONENT TO AVOID OVERFLOW IN MP_MULTIPLY */
1004 ie = z->exponent;
1005 z->exponent = 0;
1006 mp_multiply(z, z, z);
1007 z->exponent += ie << 1;
1009 /* CHECK FOR UNDERFLOW AND OVERFLOW */
1010 if (z->exponent < -MP.m) {
1011 mpunfl(z);
1012 return;
1014 if (z->exponent > MP.m) {
1015 mpovfl(z, "*** OVERFLOW IN SUBROUTINE MP_EPOWY ***");
1016 return;
1021 /* CHECK THAT RELATIVE ERROR LESS THAN 0.01 UNLESS ABS(X) LARGE
1022 * (WHEN EXP MIGHT OVERFLOW OR UNDERFLOW)
1024 if (fabs(rx) > (float)10.0)
1025 return;
1027 rz = mp_cast_to_float(z);
1028 if ((r__1 = rz - exp(rx), fabs(r__1)) < rz * (float)0.01)
1029 return;
1031 /* THE FOLLOWING MESSAGE MAY INDICATE THAT
1032 * B**(T-1) IS TOO SMALL, OR THAT M IS TOO SMALL SO THE
1033 * RESULT UNDERFLOWED.
1035 mperr("*** ERROR OCCURRED IN MP_EPOWY, RESULT INCORRECT ***");
1039 /* ASSUMES THAT X AND Y ARE MP NUMBERS, -1 < X < 1.
1040 * RETURNS Y = EXP(X) - 1 USING AN O(SQRT(T).M(T)) ALGORITHM
1041 * DESCRIBED IN - R. P. BRENT, THE COMPLEXITY OF MULTIPLE-
1042 * PRECISION ARITHMETIC (IN COMPLEXITY OF COMPUTATIONAL PROBLEM
1043 * SOLVING, UNIV. OF QUEENSLAND PRESS, BRISBANE, 1976, 126-165).
1044 * ASYMPTOTICALLY FASTER METHODS EXIST, BUT ARE NOT USEFUL
1045 * UNLESS T IS VERY LARGE. SEE COMMENTS TO MP_ATAN AND MPPIGL.
1046 * DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 3T+8
1047 * CHECK LEGALITY OF B, T, M AND MXR
1049 void
1050 mpexp1(const MPNumber *x, MPNumber *y)
1052 int i, q, ib, ic;
1053 float rlb;
1054 MPNumber t1, t2;
1056 mpchk();
1058 /* CHECK FOR X = 0 */
1059 if (x->sign == 0) {
1060 y->sign = 0;
1061 return;
1064 /* CHECK THAT ABS(X) < 1 */
1065 if (x->exponent > 0) {
1066 mperr("*** ABS(X) NOT LESS THAN 1 IN CALL TO MPEXP1 ***");
1067 y->sign = 0;
1068 return;
1071 mp_set_from_mp(x, &t1);
1072 rlb = log((float) MP.b);
1074 /* COMPUTE APPROXIMATELY OPTIMAL Q (AND DIVIDE X BY 2**Q) */
1075 q = (int) (sqrt((float) MP.t * (float).48 * rlb) + (float) x->exponent *
1076 (float)1.44 * rlb);
1078 /* HALVE Q TIMES */
1079 if (q > 0) {
1080 ib = MP.b << 2;
1081 ic = 1;
1082 for (i = 1; i <= q; ++i) {
1083 ic <<= 1;
1084 if (ic < ib && ic != MP.b && i < q)
1085 continue;
1086 mp_divide_integer(&t1, ic, &t1);
1087 ic = 1;
1091 if (t1.sign == 0) {
1092 y->sign = 0;
1093 return;
1095 mp_set_from_mp(&t1, y);
1096 mp_set_from_mp(&t1, &t2);
1098 /* SUM SERIES, REDUCING T WHERE POSSIBLE */
1099 for (i = 2; ; i++) {
1100 int t, ts;
1102 t = MP.t + 2 + t2.exponent - y->exponent;
1103 if (t <= 2)
1104 break;
1105 t = min(t, MP.t);
1107 ts = MP.t;
1108 MP.t = t;
1109 mp_multiply(&t1, &t2, &t2);
1110 mp_divide_integer(&t2, i, &t2);
1111 MP.t = ts;
1113 mp_add(&t2, y, y);
1114 if (t2.sign == 0)
1115 break;
1118 if (q <= 0)
1119 return;
1121 /* APPLY (X+1)**2 - 1 = X(2 + X) FOR Q ITERATIONS */
1122 for (i = 1; i <= q; ++i) {
1123 mp_add_integer(y, 2, &t1);
1124 mp_multiply(&t1, y, y);
1129 /* RETURNS K = K/GCD AND L = L/GCD, WHERE GCD IS THE
1130 * GREATEST COMMON DIVISOR OF K AND L.
1131 * SAVE INPUT PARAMETERS IN LOCAL VARIABLES
1133 void
1134 mpgcd(int *k, int *l)
1136 int i, j;
1138 i = abs(*k);
1139 j = abs(*l);
1140 if (j == 0) {
1141 /* IF J = 0 RETURN (1, 0) UNLESS I = 0, THEN (0, 0) */
1142 *k = 1;
1143 *l = 0;
1144 if (i == 0)
1145 *k = 0;
1146 return;
1149 /* EUCLIDEAN ALGORITHM LOOP */
1150 do {
1151 i %= j;
1152 if (i == 0) {
1153 *k = *k / j;
1154 *l = *l / j;
1155 return;
1157 j %= i;
1158 } while (j != 0);
1160 /* HERE J IS THE GCD OF K AND L */
1161 *k = *k / i;
1162 *l = *l / i;
1167 mp_is_zero(const MPNumber *x)
1169 return x->sign == 0;
1173 int
1174 mp_is_negative(const MPNumber *x)
1176 MPNumber zero;
1177 mp_set_from_integer(0, &zero);
1178 return mp_is_less_than(x, &zero);
1183 mp_is_greater_equal(const MPNumber *x, const MPNumber *y)
1185 /* RETURNS LOGICAL VALUE OF (X >= Y) FOR MP X AND Y. */
1186 return (mp_compare_mp_to_mp(x, y) >= 0);
1191 mp_is_greater_than(const MPNumber *x, const MPNumber *y)
1193 /* RETURNS LOGICAL VALUE OF (X > Y) FOR MP X AND Y. */
1194 return (mp_compare_mp_to_mp(x, y) > 0);
1199 mp_is_less_equal(const MPNumber *x, const MPNumber *y)
1201 /* RETURNS LOGICAL VALUE OF (X <= Y) FOR MP X AND Y. */
1202 return (mp_compare_mp_to_mp(x, y) <= 0);
1206 /* RETURNS MP Y = LN(1+X) IF X IS AN MP NUMBER SATISFYING THE
1207 * CONDITION ABS(X) < 1/B, ERROR OTHERWISE.
1208 * USES NEWTONS METHOD TO SOLVE THE EQUATION
1209 * EXP1(-Y) = X, THEN REVERSES SIGN OF Y.
1210 * (HERE EXP1(Y) = EXP(Y) - 1 IS COMPUTED USING MPEXP1).
1211 * TIME IS O(SQRT(T).M(T)) AS FOR MPEXP1, SPACE = 5T+12.
1212 * CHECK LEGALITY OF B, T, M AND MXR
1214 static void
1215 mplns(const MPNumber *x, MPNumber *y)
1217 int t, it0;
1218 MPNumber t1, t2, t3;
1220 mpchk();
1222 /* CHECK FOR X = 0 EXACTLY */
1223 if (x->sign == 0) {
1224 y->sign = 0;
1225 return;
1228 /* CHECK THAT ABS(X) < 1/B */
1229 if (x->exponent + 1 > 0) {
1230 mperr("*** ABS(X) >= 1/B IN CALL TO MPLNS ***");
1231 y->sign = 0;
1232 return;
1235 /* GET STARTING APPROXIMATION TO -LN(1+X) */
1236 mp_set_from_mp(x, &t2);
1237 mp_divide_integer(x, 4, &t1);
1238 mp_add_fraction(&t1, -1, 3, &t1);
1239 mp_multiply(x, &t1, &t1);
1240 mp_add_fraction(&t1, 1, 2, &t1);
1241 mp_multiply(x, &t1, &t1);
1242 mp_add_integer(&t1, -1, &t1);
1243 mp_multiply(x, &t1, y);
1245 /* START NEWTON ITERATION USING SMALL T, LATER INCREASE */
1246 t = max(5, 13 - (MP.b << 1));
1247 if (t <= MP.t)
1249 it0 = (t + 5) / 2;
1251 while(1)
1253 int ts, ts2, ts3;
1255 ts = MP.t;
1256 MP.t = t;
1257 mpexp1(y, &t3);
1258 mp_multiply(&t2, &t3, &t1);
1259 mp_add(&t3, &t1, &t3);
1260 mp_add(&t2, &t3, &t3);
1261 mp_subtract(y, &t3, y);
1262 MP.t = ts;
1263 if (t >= MP.t)
1264 break;
1266 /* FOLLOWING LOOP COMPUTES NEXT VALUE OF T TO USE.
1267 * BECAUSE NEWTONS METHOD HAS 2ND ORDER CONVERGENCE,
1268 * WE CAN ALMOST DOUBLE T EACH TIME.
1270 ts3 = t;
1271 t = MP.t;
1272 do {
1273 ts2 = t;
1274 t = (t + it0) / 2;
1275 } while (t > ts3);
1276 t = ts2;
1279 /* CHECK THAT NEWTON ITERATION WAS CONVERGING AS EXPECTED */
1280 if (t3.sign != 0 && t3.exponent << 1 > it0 - MP.t) {
1281 mperr("*** ERROR OCCURRED IN MPLNS, NEWTON ITERATION NOT CONVERGING PROPERLY ***");
1285 /* REVERSE SIGN OF Y AND RETURN */
1286 y->sign = -y->sign;
1290 /* RETURNS Y = LN(X), FOR MP X AND Y, USING MPLNS.
1291 * RESTRICTION - INTEGER PART OF LN(X) MUST BE REPRESENTABLE
1292 * AS A SINGLE-PRECISION INTEGER. TIME IS O(SQRT(T).M(T)).
1293 * FOR SMALL INTEGER X, MPLNI IS FASTER.
1294 * ASYMPTOTICALLY FASTER METHODS EXIST (EG THE GAUSS-SALAMIN
1295 * METHOD, SEE MPLNGS), BUT ARE NOT USEFUL UNLESS T IS LARGE.
1296 * SEE COMMENTS TO MP_ATAN, MPEXP1 AND MPPIGL.
1297 * DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 6T+14.
1298 * CHECK LEGALITY OF B, T, M AND MXR
1300 void
1301 mp_ln(const MPNumber *x, MPNumber *z)
1303 int e, k;
1304 float rx, rlx;
1305 MPNumber t1, t2;
1307 mpchk();
1309 /* CHECK THAT X IS POSITIVE */
1310 if (x->sign <= 0) {
1311 mperr("*** X NONPOSITIVE IN CALL TO MP_LN ***");
1312 z->sign = 0;
1313 return;
1316 /* MOVE X TO LOCAL STORAGE */
1317 mp_set_from_mp(x, &t1);
1318 z->sign = 0;
1319 k = 0;
1321 /* LOOP TO GET APPROXIMATE LN(X) USING SINGLE-PRECISION */
1322 while(1)
1324 mp_add_integer(&t1, -1, &t2);
1326 /* IF POSSIBLE GO TO CALL MPLNS */
1327 if (t2.sign == 0 || t2.exponent + 1 <= 0) {
1328 /* COMPUTE FINAL CORRECTION ACCURATELY USING MPLNS */
1329 mplns(&t2, &t2);
1330 mp_add(z, &t2, z);
1331 return;
1334 /* REMOVE EXPONENT TO AVOID FLOATING-POINT OVERFLOW */
1335 e = t1.exponent;
1336 t1.exponent = 0;
1337 rx = mp_cast_to_float(&t1);
1339 /* RESTORE EXPONENT AND COMPUTE SINGLE-PRECISION LOG */
1340 t1.exponent = e;
1341 rlx = log(rx) + (float) e * log((float) MP.b);
1342 mp_set_from_float(-(double)rlx, &t2);
1344 /* UPDATE Z AND COMPUTE ACCURATE EXP OF APPROXIMATE LOG */
1345 mp_subtract(z, &t2, z);
1346 mp_epowy(&t2, &t2);
1348 /* COMPUTE RESIDUAL WHOSE LOG IS STILL TO BE FOUND */
1349 mp_multiply(&t1, &t2, &t1);
1351 /* MAKE SURE NOT LOOPING INDEFINITELY */
1352 ++k;
1353 if (k >= 10) {
1354 mperr("*** ERROR IN MP_LN, ITERATION NOT CONVERGING ***");
1355 return;
1361 /* MP precision common log.
1363 * 1. log10(x) = log10(e) * log(x)
1365 void
1366 mp_logarithm(int n, MPNumber *x, MPNumber *z)
1368 MPNumber t1, t2;
1370 mp_set_from_integer(n, &t1);
1371 mp_ln(&t1, &t1);
1372 mp_ln(x, &t2);
1373 mp_divide(&t2, &t1, z);
1377 /* RETURNS LOGICAL VALUE OF (X < Y) FOR MP X AND Y. */
1379 mp_is_less_than(const MPNumber *x, const MPNumber *y)
1381 return (mp_compare_mp_to_mp(x, y) < 0);
1385 /* MULTIPLIES X AND Y, RETURNING RESULT IN Z, FOR MP X, Y AND Z.
1386 * THE SIMPLE O(T**2) ALGORITHM IS USED, WITH
1387 * FOUR GUARD DIGITS AND R*-ROUNDING.
1388 * ADVANTAGE IS TAKEN OF ZERO DIGITS IN X, BUT NOT IN Y.
1389 * ASYMPTOTICALLY FASTER ALGORITHMS ARE KNOWN (SEE KNUTH,
1390 * VOL. 2), BUT ARE DIFFICULT TO IMPLEMENT IN FORTRAN IN AN
1391 * EFFICIENT AND MACHINE-INDEPENDENT MANNER.
1392 * IN COMMENTS TO OTHER MP ROUTINES, M(T) IS THE TIME
1393 * TO PERFORM T-DIGIT MP MULTIPLICATION. THUS
1394 * M(T) = O(T**2) WITH THE PRESENT VERSION OF MP_MULTIPLY,
1395 * BUT M(T) = O(T.LOG(T).LOG(LOG(T))) IS THEORETICALLY POSSIBLE.
1396 * CHECK LEGALITY OF B, T, M AND MXR
1398 void
1399 mp_multiply(const MPNumber *x, const MPNumber *y, MPNumber *z)
1401 int c, i, j, i2, xi;
1402 MPNumber r;
1404 mpchk();
1405 i2 = MP.t + 4;
1407 /* FORM SIGN OF PRODUCT */
1408 z->sign = x->sign * y->sign;
1409 if (z->sign == 0)
1410 return;
1412 /* FORM EXPONENT OF PRODUCT */
1413 z->exponent = x->exponent + y->exponent;
1415 /* CLEAR ACCUMULATOR */
1416 for (i = 0; i < i2; i++)
1417 r.fraction[i] = 0;
1419 /* PERFORM MULTIPLICATION */
1420 c = 8;
1421 for (i = 0; i < MP.t; i++) {
1422 xi = x->fraction[i];
1424 /* FOR SPEED, PUT THE NUMBER WITH MANY ZEROS FIRST */
1425 if (xi == 0)
1426 continue;
1428 /* Computing MIN */
1429 for (j = 0; j < min(MP.t, i2 - i - 1); j++)
1430 r.fraction[i+j+1] += xi * y->fraction[j];
1431 c--;
1432 if (c > 0)
1433 continue;
1435 /* CHECK FOR LEGAL BASE B DIGIT */
1436 if (xi < 0 || xi >= MP.b) {
1437 mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MP_MULTIPLY, POSSIBLE OVERWRITING PROBLEM ***");
1438 z->sign = 0;
1439 return;
1442 /* PROPAGATE CARRIES AT END AND EVERY EIGHTH TIME,
1443 * FASTER THAN DOING IT EVERY TIME.
1445 for (j = i2 - 1; j >= 0; j--) {
1446 int ri = r.fraction[j] + c;
1447 if (ri < 0) {
1448 mperr("*** INTEGER OVERFLOW IN MP_MULTIPLY, B TOO LARGE ***");
1449 z->sign = 0;
1450 return;
1452 c = ri / MP.b;
1453 r.fraction[j] = ri - MP.b * c;
1455 if (c != 0) {
1456 mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MP_MULTIPLY, POSSIBLE OVERWRITING PROBLEM ***");
1457 z->sign = 0;
1458 return;
1460 c = 8;
1463 if (c != 8) {
1464 if (xi < 0 || xi >= MP.b) {
1465 mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MP_MULTIPLY, POSSIBLE OVERWRITING PROBLEM ***");
1466 z->sign = 0;
1467 return;
1470 c = 0;
1471 for (j = i2 - 1; j >= 0; j--) {
1472 int ri = r.fraction[j] + c;
1473 if (ri < 0) {
1474 mperr("*** INTEGER OVERFLOW IN MP_MULTIPLY, B TOO LARGE ***");
1475 z->sign = 0;
1476 return;
1478 c = ri / MP.b;
1479 r.fraction[j] = ri - MP.b * c;
1482 if (c != 0) {
1483 mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MP_MULTIPLY, POSSIBLE OVERWRITING PROBLEM ***");
1484 z->sign = 0;
1485 return;
1489 /* NORMALIZE AND ROUND RESULT */
1490 // FIXME: Use stack variable because of mp_normalize brokeness
1491 for (i = 0; i < i2; i++)
1492 z->fraction[i] = r.fraction[i];
1493 mp_normalize(z, 0);
1497 /* MULTIPLIES MP X BY SINGLE-PRECISION INTEGER IY GIVING MP Z.
1498 * MULTIPLICATION BY 1 MAY BE USED TO NORMALIZE A NUMBER
1499 * EVEN IF SOME DIGITS ARE GREATER THAN B-1.
1500 * RESULT IS ROUNDED IF TRUNC == 0, OTHERWISE TRUNCATED.
1502 void
1503 mpmul2(const MPNumber *x, int iy, MPNumber *z, int trunc)
1505 int c, i, c1, c2, j1, j2;
1506 int t1, t3, t4, ij, ri = 0, is, ix;
1508 z->sign = x->sign;
1509 if (z->sign == 0 || iy == 0) {
1510 z->sign = 0;
1511 return;
1514 if (iy < 0) {
1515 iy = -iy;
1516 z->sign = -z->sign;
1518 /* CHECK FOR MULTIPLICATION BY B */
1519 if (iy == MP.b) {
1520 if (x->exponent < MP.m) {
1521 mp_set_from_mp(x, z);
1522 z->sign = z->sign;
1523 z->exponent = x->exponent + 1;
1525 else {
1526 mpchk();
1527 mpovfl(z, "*** OVERFLOW OCCURRED IN MPMUL2 ***");
1529 return;
1533 /* SET EXPONENT TO EXPONENT(X) + 4 */
1534 z->exponent = x->exponent + 4;
1536 /* FORM PRODUCT IN ACCUMULATOR */
1537 c = 0;
1538 t1 = MP.t + 1;
1539 t3 = MP.t + 3;
1540 t4 = MP.t + 4;
1542 /* IF IY*B NOT REPRESENTABLE AS AN INTEGER WE HAVE TO SIMULATE
1543 * DOUBLE-PRECISION MULTIPLICATION.
1546 /* Computing MAX */
1547 if (iy >= max(MP.b << 3, 32767 / MP.b)) {
1548 /* HERE J IS TOO LARGE FOR SINGLE-PRECISION MULTIPLICATION */
1549 j1 = iy / MP.b;
1550 j2 = iy - j1 * MP.b;
1552 /* FORM PRODUCT */
1553 for (ij = 1; ij <= t4; ++ij) {
1554 c1 = c / MP.b;
1555 c2 = c - MP.b * c1;
1556 i = t1 - ij;
1557 ix = 0;
1558 if (i > 0)
1559 ix = x->fraction[i - 1];
1560 ri = j2 * ix + c2;
1561 is = ri / MP.b;
1562 c = j1 * ix + c1 + is;
1563 z->fraction[i + 3] = ri - MP.b * is;
1566 else
1568 for (ij = 1; ij <= MP.t; ++ij) {
1569 i = t1 - ij;
1570 ri = iy * x->fraction[i - 1] + c;
1571 c = ri / MP.b;
1572 z->fraction[i + 3] = ri - MP.b * c;
1575 /* CHECK FOR INTEGER OVERFLOW */
1576 if (ri < 0) {
1577 mpchk();
1578 mperr("*** INTEGER OVERFLOW IN MPMUL2, B TOO LARGE ***");
1579 z->sign = 0;
1580 return;
1583 /* HAVE TO TREAT FIRST FOUR WORDS OF R SEPARATELY */
1584 for (ij = 1; ij <= 4; ++ij) {
1585 i = 5 - ij;
1586 ri = c;
1587 c = ri / MP.b;
1588 z->fraction[i - 1] = ri - MP.b * c;
1592 /* HAVE TO SHIFT RIGHT HERE AS CARRY OFF END */
1593 while(1) {
1594 /* NORMALIZE AND ROUND OR TRUNCATE RESULT */
1595 if (c == 0)
1597 mp_normalize(z, trunc);
1598 return;
1601 if (c < 0) {
1602 mpchk();
1603 mperr("*** INTEGER OVERFLOW IN MPMUL2, B TOO LARGE ***");
1604 z->sign = 0;
1605 return;
1608 for (ij = 1; ij <= t3; ++ij) {
1609 i = t4 - ij;
1610 z->fraction[i] = z->fraction[i - 1];
1612 ri = c;
1613 c = ri / MP.b;
1614 z->fraction[0] = ri - MP.b * c;
1615 z->exponent++;
1620 /* MULTIPLIES MP X BY SINGLE-PRECISION INTEGER IY GIVING MP Z.
1621 * THIS IS FASTER THAN USING MP_MULTIPLY. RESULT IS ROUNDED.
1622 * MULTIPLICATION BY 1 MAY BE USED TO NORMALIZE A NUMBER
1623 * EVEN IF THE LAST DIGIT IS B.
1625 void
1626 mp_multiply_integer(const MPNumber *x, int iy, MPNumber *z)
1628 mpmul2(x, iy, z, 0);
1632 /* MULTIPLIES MP X BY I/J, GIVING MP Y */
1633 void
1634 mp_multiply_fraction(const MPNumber *x, int numerator, int denominator, MPNumber *z)
1636 int is, js;
1638 if (denominator == 0) {
1639 mpchk();
1640 mperr("*** ATTEMPTED DIVISION BY ZERO IN MP_MULTIPLY_FRACTION ***");
1641 z->sign = 0;
1642 return;
1645 if (numerator == 0) {
1646 z->sign = 0;
1647 return;
1650 /* REDUCE TO LOWEST TERMS */
1651 is = numerator;
1652 js = denominator;
1653 mpgcd(&is, &js);
1654 if (abs(is) == 1) {
1655 /* HERE IS = +-1 */
1656 mp_divide_integer(x, is * js, z);
1657 } else {
1658 mp_divide_integer(x, js, z);
1659 mpmul2(z, is, z, 0);
1664 /* SETS Y = -X FOR MP NUMBERS X AND Y */
1665 void
1666 mp_invert_sign(const MPNumber *x, MPNumber *y)
1668 mp_set_from_mp(x, y);
1669 y->sign = -y->sign;
1672 /* ASSUMES LONG (I.E. (T+4)-DIGIT) FRACTION IN R. NORMALIZES,
1673 * AND RETURNS MP RESULT IN Z. INTEGER ARGUMENTS REG_EXP IS
1674 * NOT PRESERVED. R*-ROUNDING IS USED IF TRUNC == 0
1676 // FIXME: Is r->fraction large enough? It seems to be in practise but it may be MP.t+4 instead of MP.t
1677 // FIXME: There is some sort of stack corruption/use of unitialised variables here. Some functions are
1678 // using stack variables as x otherwise there are corruption errors. e.g. "Cos(45) - 1/Sqrt(2) = -0"
1679 // (try in scientific mode)
1680 void
1681 mp_normalize(MPNumber *x, int trunc)
1683 int i__1, i, j, b2, i2, i2m, round;
1685 /* Normalized zero is zero */
1686 if (x->sign == 0)
1687 return;
1689 /* CHECK THAT SIGN = +-1 */
1690 if (abs(x->sign) > 1) {
1691 mperr("*** SIGN NOT 0, +1 OR -1 IN CALL TO MP_NORMALIZE, POSSIBLE OVERWRITING PROBLEM ***");
1692 x->sign = 0;
1693 return;
1696 i2 = MP.t + 4;
1698 /* Normalize by shifting the fraction to the left */
1699 if (x->fraction[0] == 0) {
1700 /* Find how many places to shift and detect 0 fraction */
1701 for (i = 1; i < i2 && x->fraction[i] == 0; i++);
1702 if (i == i2) {
1703 x->sign = 0;
1704 return;
1707 x->exponent -= i;
1708 i2m = i2 - i;
1709 for (j = 0; j < i2m; j++)
1710 x->fraction[j] = x->fraction[j + i];
1711 for (; j < i2; j++)
1712 x->fraction[j] = 0;
1715 /* CHECK TO SEE IF TRUNCATION IS DESIRED */
1716 if (trunc == 0) {
1717 /* SEE IF ROUNDING NECESSARY
1718 * TREAT EVEN AND ODD BASES DIFFERENTLY
1720 b2 = MP.b / 2;
1721 if (b2 << 1 != MP.b) {
1722 round = 0;
1723 /* ODD BASE, ROUND IF R(T+1)... > 1/2 */
1724 for (i = 0; i < 4; i++) {
1725 i__1 = x->fraction[MP.t + i] - b2;
1726 if (i__1 < 0)
1727 break;
1728 else if (i__1 == 0)
1729 continue;
1730 else {
1731 round = 1;
1732 break;
1736 else {
1737 /* B EVEN. ROUND IF R(T+1) >= B2 UNLESS R(T) ODD AND ALL ZEROS
1738 * AFTER R(T+2).
1740 round = 1;
1741 i__1 = x->fraction[MP.t] - b2;
1742 if (i__1 < 0)
1743 round = 0;
1744 else if (i__1 == 0) {
1745 if (x->fraction[MP.t - 1] % 2 != 0) {
1746 if (x->fraction[MP.t + 1] + x->fraction[MP.t + 2] + x->fraction[MP.t + 3] == 0) {
1747 round = 0;
1753 /* ROUND */
1754 if (round) {
1755 for (j = MP.t - 1; j >= 0; j--) {
1756 ++x->fraction[j];
1757 if (x->fraction[j] < MP.b)
1758 break;
1759 x->fraction[j] = 0;
1762 /* EXCEPTIONAL CASE, ROUNDED UP TO .10000... */
1763 if (j < 0) {
1764 x->exponent++;
1765 x->fraction[0] = 1;
1770 /* Check for over and underflow */
1771 if (x->exponent > MP.m) {
1772 mpovfl(x, "*** OVERFLOW OCCURRED IN MP_NORMALIZE ***");
1773 return;
1775 if (x->exponent < -MP.m) {
1776 mpunfl(x);
1777 return;
1782 /* RETURNS Y = X**N, FOR MP X AND Y, INTEGER N, WITH 0**0 = 1.
1783 * R MUST BE DIMENSIONED AT LEAST 4T+10 IN CALLING PROGRAM
1784 * (2T+6 IS ENOUGH IF N NONNEGATIVE).
1786 void
1787 mp_pwr_integer(const MPNumber *x, int n, MPNumber *y)
1789 int n2, ns;
1790 MPNumber t;
1792 n2 = n;
1793 if (n2 < 0) {
1794 /* N < 0 */
1795 mpchk();
1796 n2 = -n2;
1797 if (x->sign == 0) {
1798 mperr("*** ATTEMPT TO RAISE ZERO TO NEGATIVE POWER IN CALL TO SUBROUTINE MP_PWR_INTEGER ***");
1799 y->sign = 0;
1800 return;
1802 } else if (n2 == 0) {
1803 /* N == 0, RETURN Y = 1. */
1804 mp_set_from_integer(1, y);
1805 return;
1806 } else {
1807 /* N > 0 */
1808 mpchk();
1809 if (x->sign == 0) {
1810 y->sign = 0;
1811 return;
1815 /* MOVE X */
1816 mp_set_from_mp(x, y);
1818 /* IF N < 0 FORM RECIPROCAL */
1819 if (n < 0)
1820 mp_reciprocal(y, y);
1821 mp_set_from_mp(y, &t);
1823 /* SET PRODUCT TERM TO ONE */
1824 mp_set_from_integer(1, y);
1826 /* MAIN LOOP, LOOK AT BITS OF N2 FROM RIGHT */
1827 while(1) {
1828 ns = n2;
1829 n2 /= 2;
1830 if (n2 << 1 != ns)
1831 mp_multiply(y, &t, y);
1832 if (n2 <= 0)
1833 return;
1835 mp_multiply(&t, &t, &t);
1840 /* RETURNS Z = X**Y FOR MP NUMBERS X, Y AND Z, WHERE X IS
1841 * POSITIVE (X == 0 ALLOWED IF Y > 0). SLOWER THAN
1842 * MP_PWR_INTEGER AND MPQPWR, SO USE THEM IF POSSIBLE.
1843 * DIMENSION OF R IN COMMON AT LEAST 7T+16
1844 * CHECK LEGALITY OF B, T, M AND MXR
1846 void
1847 mp_pwr(const MPNumber *x, const MPNumber *y, MPNumber *z)
1849 MPNumber t;
1851 mpchk();
1853 if (x->sign < 0) {
1854 mperr(_("Negative X and non-integer Y not supported"));
1855 z->sign = 0;
1857 else if (x->sign == 0)
1859 /* HERE X IS ZERO, RETURN ZERO IF Y POSITIVE, OTHERWISE ERROR */
1860 if (y->sign <= 0) {
1861 mperr("*** X ZERO AND Y NONPOSITIVE IN CALL TO MP_PWR ***");
1863 z->sign = 0;
1865 else {
1866 /* USUAL CASE HERE, X POSITIVE
1867 * USE MPLN AND MP_EPOWY TO COMPUTE POWER
1869 mp_ln(x, &t);
1870 mp_multiply(y, &t, z);
1872 /* IF X**Y IS TOO LARGE, MP_EPOWY WILL PRINT ERROR MESSAGE */
1873 mp_epowy(z, z);
1878 /* RETURNS Z = 1/X, FOR MP X AND Z.
1879 * MP_ROOT (X, -1, Z) HAS THE SAME EFFECT.
1880 * DIMENSION OF R MUST BE AT LEAST 4*T+10 IN CALLING PROGRAM
1881 * (BUT Z(1) MAY BE R(3T+9)).
1882 * NEWTONS METHOD IS USED, SO FINAL ONE OR TWO DIGITS MAY
1883 * NOT BE CORRECT.
1885 void
1886 mp_reciprocal(const MPNumber *x, MPNumber *z)
1888 /* Initialized data */
1889 static int it[9] = { 0, 8, 6, 5, 4, 4, 4, 4, 4 };
1891 MPNumber tmp_x, t1, t2;
1893 int ex, it0, t;
1894 float rx;
1896 /* CHECK LEGALITY OF B, T, M AND MXR */
1897 mpchk();
1899 /* MP_ADD_INTEGER REQUIRES 2T+6 WORDS. */
1900 if (x->sign == 0) {
1901 mperr("*** ATTEMPTED DIVISION BY ZERO IN CALL TO MP_RECIPROCAL ***");
1902 z->sign = 0;
1903 return;
1906 ex = x->exponent;
1908 /* TEMPORARILY INCREASE M TO AVOID OVERFLOW */
1909 MP.m += 2;
1911 /* SET EXPONENT TO ZERO SO RX NOT TOO LARGE OR SMALL. */
1912 /* work-around to avoid touching X */
1913 mp_set_from_mp(x, &tmp_x);
1914 tmp_x.exponent = 0;
1915 rx = mp_cast_to_float(&tmp_x);
1917 /* USE SINGLE-PRECISION RECIPROCAL AS FIRST APPROXIMATION */
1918 mp_set_from_float((float)1. / rx, &t1);
1920 /* CORRECT EXPONENT OF FIRST APPROXIMATION */
1921 t1.exponent -= ex;
1923 /* START WITH SMALL T TO SAVE TIME. ENSURE THAT B**(T-1) >= 100 */
1924 if (MP.b < 10)
1925 t = it[MP.b - 1];
1926 else
1927 t = 3;
1928 it0 = (t + 4) / 2;
1930 /* MAIN ITERATION LOOP */
1931 if (t <= MP.t) {
1932 while(1) {
1933 int ts, ts2, ts3;
1935 ts = MP.t;
1936 MP.t = t;
1937 mp_multiply(x, &t1, &t2);
1938 mp_add_integer(&t2, -1, &t2);
1939 MP.t = ts;
1941 /* TEMPORARILY REDUCE T */
1942 ts = MP.t;
1943 MP.t = (t + it0) / 2;
1944 mp_multiply(&t1, &t2, &t2);
1945 MP.t = ts;
1947 ts = MP.t;
1948 MP.t = t;
1949 mp_subtract(&t1, &t2, &t1);
1950 MP.t = ts;
1951 if (t >= MP.t)
1952 break;
1954 /* FOLLOWING LOOP ALMOST DOUBLES T (POSSIBLE
1955 * BECAUSE NEWTONS METHOD HAS 2ND ORDER CONVERGENCE).
1957 ts3 = t;
1958 t = MP.t;
1959 do {
1960 ts2 = t;
1961 t = (t + it0) / 2;
1962 } while (t > ts3);
1963 t = min(ts2, MP.t);
1966 /* RETURN IF NEWTON ITERATION WAS CONVERGING */
1967 if (t2.sign != 0 && (t1.exponent - t2.exponent) << 1 < MP.t - it0) {
1968 /* THE FOLLOWING MESSAGE MAY INDICATE THAT B**(T-1) IS TOO SMALL,
1969 * OR THAT THE STARTING APPROXIMATION IS NOT ACCURATE ENOUGH.
1971 mperr("*** ERROR OCCURRED IN MP_RECIPROCAL, NEWTON ITERATION NOT CONVERGING PROPERLY ***");
1975 /* MOVE RESULT TO Y AND RETURN AFTER RESTORING T */
1976 mp_set_from_mp(&t1, z);
1978 /* RESTORE M AND CHECK FOR OVERFLOW (UNDERFLOW IMPOSSIBLE) */
1979 MP.m += -2;
1980 if (z->exponent > MP.m)
1981 mpovfl(z, "*** OVERFLOW OCCURRED IN MP_RECIPROCAL ***");
1985 /* RETURNS Z = X^(1/N) FOR INTEGER N, ABS(N) <= MAX (B, 64).
1986 * AND MP NUMBERS X AND Z,
1987 * USING NEWTONS METHOD WITHOUT DIVISIONS. SPACE = 4T+10
1988 * (BUT Z.EXP MAY BE R(3T+9))
1990 void
1991 mp_root(const MPNumber *x, int n, MPNumber *z)
1993 /* Initialized data */
1994 static const int it[9] = { 0, 8, 6, 5, 4, 4, 4, 4, 4 };
1996 float r__1;
1998 int ex, np, it0, t;
1999 float rx;
2000 MPNumber t1, t2;
2002 /* CHECK LEGALITY OF B, T, M AND MXR */
2003 mpchk();
2005 if (n == 1) {
2006 mp_set_from_mp(x, z);
2007 return;
2010 if (n == 0) {
2011 mperr("*** N == 0 IN CALL TO MP_ROOT ***");
2012 z->sign = 0;
2013 return;
2016 np = abs(n);
2018 /* LOSS OF ACCURACY IF NP LARGE, SO ONLY ALLOW NP <= MAX (B, 64) */
2019 if (np > max(MP.b, 64)) {
2020 mperr("*** ABS(N) TOO LARGE IN CALL TO MP_ROOT ***");
2021 z->sign = 0;
2022 return;
2025 /* LOOK AT SIGN OF X */
2026 if (x->sign == 0) {
2027 /* X == 0 HERE, RETURN 0 IF N POSITIVE, ERROR IF NEGATIVE */
2028 z->sign = 0;
2029 if (n > 0)
2030 return;
2032 mperr("*** X == 0 AND N NEGATIVE IN CALL TO MP_ROOT ***");
2033 z->sign = 0;
2034 return;
2037 if (x->sign < 0 && np % 2 == 0) {
2038 mperr("*** X NEGATIVE AND N EVEN IN CALL TO MP_ROOT ***");
2039 z->sign = 0;
2040 return;
2043 /* DIVIDE EXPONENT BY NP */
2044 ex = x->exponent / np;
2046 /* REDUCE EXPONENT SO RX NOT TOO LARGE OR SMALL. */
2048 MPNumber tmp_x;
2049 mp_set_from_mp(x, &tmp_x);
2050 tmp_x.exponent = 0;
2051 rx = mp_cast_to_float(&tmp_x);
2054 /* USE SINGLE-PRECISION ROOT FOR FIRST APPROXIMATION */
2055 r__1 = exp(((float) (np * ex - x->exponent) * log((float) MP.b) -
2056 log((fabs(rx)))) / (float) np);
2057 mp_set_from_float(r__1, &t1);
2059 /* SIGN OF APPROXIMATION SAME AS THAT OF X */
2060 t1.sign = x->sign;
2062 /* CORRECT EXPONENT OF FIRST APPROXIMATION */
2063 t1.exponent -= ex;
2065 /* START WITH SMALL T TO SAVE TIME */
2066 /* ENSURE THAT B**(T-1) >= 100 */
2067 if (MP.b < 10)
2068 t = it[MP.b - 1];
2069 else
2070 t = 3;
2072 if (t <= MP.t) {
2073 /* IT0 IS A NECESSARY SAFETY FACTOR */
2074 it0 = (t + 4) / 2;
2076 /* MAIN ITERATION LOOP */
2077 while(1) {
2078 int ts, ts2, ts3;
2080 ts = MP.t;
2081 MP.t = t;
2082 mp_pwr_integer(&t1, np, &t2);
2083 mp_multiply(x, &t2, &t2);
2084 mp_add_integer(&t2, -1, &t2);
2085 MP.t = ts;
2087 /* TEMPORARILY REDUCE T */
2088 ts = MP.t;
2089 MP.t = (t + it0) / 2;
2090 mp_multiply(&t1, &t2, &t2);
2091 mp_divide_integer(&t2, np, &t2);
2092 MP.t = ts;
2094 ts = MP.t;
2095 MP.t = t;
2096 mp_subtract(&t1, &t2, &t1);
2097 MP.t = ts;
2099 /* FOLLOWING LOOP ALMOST DOUBLES T (POSSIBLE BECAUSE
2100 * NEWTONS METHOD HAS 2ND ORDER CONVERGENCE).
2102 if (t >= MP.t)
2103 break;
2105 ts3 = t;
2106 t = MP.t;
2107 do {
2108 ts2 = t;
2109 t = (t + it0) / 2;
2110 } while (t > ts3);
2111 t = min(ts2, MP.t);
2114 /* NOW R(I2) IS X**(-1/NP)
2115 * CHECK THAT NEWTON ITERATION WAS CONVERGING
2117 if (t2.sign != 0 && (t1.exponent - t2.exponent) << 1 < MP.t - it0) {
2118 /* THE FOLLOWING MESSAGE MAY INDICATE THAT B**(T-1) IS TOO SMALL,
2119 * OR THAT THE INITIAL APPROXIMATION OBTAINED USING ALOG AND EXP
2120 * IS NOT ACCURATE ENOUGH.
2122 mperr("*** ERROR OCCURRED IN MP_ROOT, NEWTON ITERATION NOT CONVERGING PROPERLY ***");
2126 if (n >= 0) {
2127 mp_pwr_integer(&t1, n - 1, &t1);
2128 mp_multiply(x, &t1, z);
2129 return;
2132 mp_set_from_mp(&t1, z);
2136 /* RETURNS Z = SQRT(X), USING SUBROUTINE MP_ROOT IF X > 0.
2137 * DIMENSION OF R IN CALLING PROGRAM MUST BE AT LEAST 4T+10
2138 * (BUT Z.EXP MAY BE R(3T+9)). X AND Z ARE MP NUMBERS.
2139 * CHECK LEGALITY OF B, T, M AND MXR
2141 void
2142 mp_sqrt(const MPNumber *x, MPNumber *z)
2144 int i, i2, iy3;
2145 MPNumber t;
2147 mpchk();
2149 /* MP_ROOT NEEDS 4T+10 WORDS, BUT CAN OVERLAP SLIGHTLY. */
2150 i2 = MP.t * 3 + 9;
2151 if (x->sign < 0) {
2152 mperr("*** X NEGATIVE IN CALL TO SUBROUTINE MP_SQRT ***");
2153 } else if (x->sign == 0) {
2154 z->sign = 0;
2155 } else {
2156 mp_root(x, -2, &t);
2157 i = t.fraction[0];
2158 mp_multiply(x, &t, z);
2159 iy3 = z->fraction[0];
2160 mpext(i, iy3, z);
2164 /* SUBTRACTS Y FROM X, FORMING RESULT IN Z, FOR MP X, Y AND Z.
2165 * FOUR GUARD DIGITS ARE USED, AND THEN R*-ROUNDING
2167 void
2168 mp_subtract(const MPNumber *x, const MPNumber *y, MPNumber *z)
2170 mp_add2(x, y, -y->sign, z);
2174 void
2175 mp_factorial(const MPNumber *x, MPNumber *z)
2177 int i, value;
2179 /* 0! == 1 */
2180 if (x->sign == 0) {
2181 mp_set_from_integer(1, z);
2182 return;
2184 if (!mp_is_natural(x)) {
2185 mperr("Cannot take factorial of non-natural number");
2188 /* Convert to integer - if couldn't be converted then the factorial would be too big anyway */
2189 value = mp_cast_to_int(x);
2190 mp_set_from_mp(x, z);
2191 for (i = 2; i < value; i++)
2192 mp_multiply_integer(z, i, z);
2196 mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
2198 MPNumber t1, t2;
2200 if (!mp_is_integer(x) || !mp_is_integer(y)) {
2201 return -EINVAL;
2204 mp_divide(x, y, &t1);
2205 mp_integer_component(&t1, &t1);
2206 mp_multiply(&t1, y, &t2);
2207 mp_subtract(x, &t2, z);
2209 mp_set_from_integer(0, &t1);
2210 if ((mp_is_less_than(y, &t1) && mp_is_greater_than(z, &t1)) || mp_is_less_than(z, &t1)) {
2211 mp_add(z, y, z);
2214 return 0;
2217 void
2218 mp_xpowy(const MPNumber *x, const MPNumber *y, MPNumber *z)
2220 if (mp_is_integer(y)) {
2221 mp_pwr_integer(x, mp_cast_to_int(y), z);
2222 } else {
2223 MPNumber reciprocal;
2224 mp_reciprocal(y, &reciprocal);
2225 if (mp_is_integer(&reciprocal))
2226 mp_root(x, mp_cast_to_int(&reciprocal), z);
2227 else
2228 mp_pwr(x, y, z);