|
|
1.1 root 1: #include "mprec.h"
2:
3:
4: /*
5: * Msqrt sets the mint pointed to by "b" to the greatest integer
6: * which is less than or equal to the square root ot the mint
7: * pointed to by "a". It sets the mint pointed to by "r" to the
8: * remainder (ie. r = a - b * b). If "a" is negative, then mperr
9: * is called with the appropriate error message. Note that no
10: * assumption is made as to the distinction of "a", "b" and "r"
11: * except that "b" must not equal "r".
12: */
13:
14: void
15: msqrt(a, b, r)
16: register mint *a, *b, *r;
17: {
18: mint x, xs, tx, rem;
19:
20: if (!ispos(a))
21: mperr("square root of negative number");
22:
23: /* initialize temps */
24: minit(&x);
25: minit(&xs);
26: minit(&rem);
27: minit(&tx);
28:
29:
30: /* get initial guess */
31: mitom(BASE, &x);
32: spow(&x, a->len / 2, &x);
33:
34: /* loop till x * x <= a < (x + 1) * (x + 1) */
35: for (;;) {
36: mult(&x, &x, &xs);
37: msub(a, &xs, &rem);
38: madd(&x, &x, &tx);
39: if (ispos(&rem) && mcmp(&rem, &tx) <= 0)
40: break;
41: madd(a, &xs, &xs);
42: mdiv(&xs, &tx, &x, &xs);
43: }
44:
45: /* throw away garbage and return results */
46: mpfree(b->val);
47: *b = x;
48: mpfree(r->val);
49: *r = rem;
50: mpfree(xs.val);
51: mpfree(tx.val);
52: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.