1 /*
2 * Copyright (c) 1994 David I. Bell
3 * Permission is granted to use, distribute, or modify this source,
4 * provided that this copyright notice remains intact.
5 *
6 * Extended precision integral arithmetic primitives
7 */
8
9 #include <tcl.h>
10 #include "zmath.h"
11
12
13 HALF _twoval_[] = { 2 };
14 HALF _zeroval_[] = { 0 };
15 HALF _oneval_[] = { 1 };
16 HALF _tenval_[] = { 10 };
17
18 ZVALUE _zero_ = { _zeroval_, 1, 0};
19 ZVALUE _one_ = { _oneval_, 1, 0 };
20 ZVALUE _ten_ = { _tenval_, 1, 0 };
21
22
23 /*
24 * mask of given bits, rotated thru all bit positions twice
25 *
26 * bitmask[i] (1 << (i-1)), for -BASEB*4<=i<=BASEB*4
27 */
28 static HALF *bmask; /* actual rotation thru 8 cycles */
29 HALF *bitmask; /* bit rotation, norm 0 */
30
31 static void dadd MATH_PROTO((ZVALUE z1, ZVALUE z2, long y, long n));
32 static BOOL dsub MATH_PROTO((ZVALUE z1, ZVALUE z2, long y, long n));
33 static void dmul MATH_PROTO((ZVALUE z, FULL x, ZVALUE *dest));
34
35
36 #ifdef ALLOCTEST
37 static long nalloc = 0;
38 static long nfree = 0;
39 #endif
40
41
42 HALF *
alloc(len)43 alloc(len)
44 long len;
45 {
46 HALF *hp;
47
48 hp = (HALF *) ckalloc((len+1) * sizeof(HALF));
49 if (hp == 0)
50 math_error("Not enough memory");
51 #ifdef ALLOCTEST
52 ++nalloc;
53 #endif
54 return hp;
55 }
56
57
58 #ifdef ALLOCTEST
59 void
freeh(h)60 freeh(h)
61 HALF *h;
62 {
63 if ((h != _zeroval_) && (h != _oneval_)
64 (h != _twoval_) && (h != _tenval_)) {
65 ckfree(h);
66 ++nfree;
67 }
68 }
69
70
71 void
allocStat()72 allocStat()
73 {
74 fprintf(stderr, "nalloc: %ld nfree: %ld kept: %ld\n",
75 nalloc, nfree, nalloc - nfree);
76 }
77 #endif
78
79
80 /*
81 * Convert a normal integer to a number.
82 */
83 void
itoz(i,res)84 itoz(i, res)
85 long i;
86 ZVALUE *res;
87 {
88 long diddle, len;
89
90 res->len = 1;
91 res->sign = 0;
92 diddle = 0;
93 if (i == 0) {
94 res->v = _zeroval_;
95 return;
96 }
97 if (i < 0) {
98 res->sign = 1;
99 i = -i;
100 if (i < 0) { /* fix most negative number */
101 diddle = 1;
102 i--;
103 }
104 }
105 if (i == 1) {
106 res->v = _oneval_;
107 return;
108 }
109 len = 1 + (((FULL) i) >= BASE);
110 res->len = len;
111 res->v = alloc(len);
112 res->v[0] = (HALF) (i + diddle);
113 if (len == 2)
114 res->v[1] = (HALF) (i / BASE);
115 }
116
117
118 /*
119 * Convert a number to a normal integer, as far as possible.
120 * If the number is out of range, the largest number is returned.
121 */
122 long
ztoi(z)123 ztoi(z)
124 ZVALUE z;
125 {
126 long i;
127
128 if (zisbig(z)) {
129 i = MAXFULL;
130 return (z.sign ? -i : i);
131 }
132 i = (zistiny(z) ? z1tol(z) : z2tol(z));
133 return (z.sign ? -i : i);
134 }
135
136
137 /*
138 * Make a copy of an integer value
139 */
140 void
zcopy(z,res)141 zcopy(z, res)
142 ZVALUE z, *res;
143 {
144 res->sign = z.sign;
145 res->len = z.len;
146 if (zisleone(z)) { /* zero or plus or minus one are easy */
147 res->v = (z.v[0] ? _oneval_ : _zeroval_);
148 return;
149 }
150 res->v = alloc(z.len);
151 zcopyval(z, *res);
152 }
153
154
155 /*
156 * Add together two integers.
157 */
158 void
zadd(z1,z2,res)159 zadd(z1, z2, res)
160 ZVALUE z1, z2, *res;
161 {
162 ZVALUE dest;
163 HALF *p1, *p2, *pd;
164 long len;
165 FULL carry;
166 SIUNION sival;
167
168 if (z1.sign && !z2.sign) {
169 z1.sign = 0;
170 zsub(z2, z1, res);
171 return;
172 }
173 if (z2.sign && !z1.sign) {
174 z2.sign = 0;
175 zsub(z1, z2, res);
176 return;
177 }
178 if (z2.len > z1.len) {
179 pd = z1.v; z1.v = z2.v; z2.v = pd;
180 len = z1.len; z1.len = z2.len; z2.len = len;
181 }
182 dest.len = z1.len + 1;
183 dest.v = alloc(dest.len);
184 dest.sign = z1.sign;
185 carry = 0;
186 pd = dest.v;
187 p1 = z1.v;
188 p2 = z2.v;
189 len = z2.len;
190 while (len--) {
191 sival.ivalue = ((FULL) *p1++) + ((FULL) *p2++) + carry;
192 *pd++ = sival.silow;
193 carry = sival.sihigh;
194 }
195 len = z1.len - z2.len;
196 while (len--) {
197 sival.ivalue = ((FULL) *p1++) + carry;
198 *pd++ = sival.silow;
199 carry = sival.sihigh;
200 }
201 *pd = (HALF)carry;
202 zquicktrim(dest);
203 *res = dest;
204 }
205
206
207 /*
208 * Subtract two integers.
209 */
210 void
zsub(z1,z2,res)211 zsub(z1, z2, res)
212 ZVALUE z1, z2, *res;
213 {
214 register HALF *h1, *h2, *hd;
215 long len1, len2;
216 FULL carry;
217 SIUNION sival;
218 ZVALUE dest;
219
220 if (z1.sign != z2.sign) {
221 z2.sign = z1.sign;
222 zadd(z1, z2, res);
223 return;
224 }
225 len1 = z1.len;
226 len2 = z2.len;
227 if (len1 == len2) {
228 h1 = z1.v + len1 - 1;
229 h2 = z2.v + len2 - 1;
230 while ((len1 > 0) && ((FULL)*h1 == (FULL)*h2)) {
231 len1--;
232 h1--;
233 h2--;
234 }
235 if (len1 == 0) {
236 *res = _zero_;
237 return;
238 }
239 len2 = len1;
240 carry = ((FULL)*h1 < (FULL)*h2);
241 } else {
242 carry = (len1 < len2);
243 }
244 dest.sign = z1.sign;
245 h1 = z1.v;
246 h2 = z2.v;
247 if (carry) {
248 carry = len1;
249 len1 = len2;
250 len2 = carry;
251 h1 = z2.v;
252 h2 = z1.v;
253 dest.sign = !dest.sign;
254 }
255 hd = alloc(len1);
256 dest.v = hd;
257 dest.len = len1;
258 len1 -= len2;
259 carry = 0;
260 while (--len2 >= 0) {
261 sival.ivalue = (BASE1 - ((FULL) *h1++)) + *h2++ + carry;
262 *hd++ = BASE1 - sival.silow;
263 carry = sival.sihigh;
264 }
265 while (--len1 >= 0) {
266 sival.ivalue = (BASE1 - ((FULL) *h1++)) + carry;
267 *hd++ = BASE1 - sival.silow;
268 carry = sival.sihigh;
269 }
270 if (hd[-1] == 0)
271 ztrim(&dest);
272 *res = dest;
273 }
274
275
276 /*
277 * Multiply an integer by a small number.
278 */
279 void
zmuli(z,n,res)280 zmuli(z, n, res)
281 ZVALUE z;
282 long n;
283 ZVALUE *res;
284 {
285 register HALF *h1, *sd;
286 FULL low;
287 FULL high;
288 FULL carry;
289 long len;
290 SIUNION sival;
291 ZVALUE dest;
292
293 if ((n == 0) || ziszero(z)) {
294 *res = _zero_;
295 return;
296 }
297 if (n < 0) {
298 n = -n;
299 z.sign = !z.sign;
300 }
301 if (n == 1) {
302 zcopy(z, res);
303 return;
304 }
305 low = ((FULL) n) & BASE1;
306 high = ((FULL) n) >> BASEB;
307 dest.len = z.len + 2;
308 dest.v = alloc(dest.len);
309 dest.sign = z.sign;
310 /*
311 * Multiply by the low digit.
312 */
313 h1 = z.v;
314 sd = dest.v;
315 len = z.len;
316 carry = 0;
317 while (len--) {
318 sival.ivalue = ((FULL) *h1++) * low + carry;
319 *sd++ = sival.silow;
320 carry = sival.sihigh;
321 }
322 *sd = (HALF)carry;
323 /*
324 * If there was only one digit, then we are all done except
325 * for trimming the number if there was no last carry.
326 */
327 if (high == 0) {
328 dest.len--;
329 if (carry == 0)
330 dest.len--;
331 *res = dest;
332 return;
333 }
334 /*
335 * Need to multiply by the high digit and add it into the
336 * previous value. Clear the final word of rubbish first.
337 */
338 *(++sd) = 0;
339 h1 = z.v;
340 sd = dest.v + 1;
341 len = z.len;
342 carry = 0;
343 while (len--) {
344 sival.ivalue = ((FULL) *h1++) * high + ((FULL) *sd) + carry;
345 *sd++ = sival.silow;
346 carry = sival.sihigh;
347 }
348 *sd = (HALF)carry;
349 zquicktrim(dest);
350 *res = dest;
351 }
352
353
354 /*
355 * Divide two numbers by their greatest common divisor.
356 * This is useful for reducing the numerator and denominator of
357 * a fraction to its lowest terms.
358 */
359 void
zreduce(z1,z2,z1res,z2res)360 zreduce(z1, z2, z1res, z2res)
361 ZVALUE z1, z2, *z1res, *z2res;
362 {
363 ZVALUE tmp;
364
365 if (zisleone(z1) || zisleone(z2))
366 tmp = _one_;
367 else
368 zgcd(z1, z2, &tmp);
369 if (zisunit(tmp)) {
370 zcopy(z1, z1res);
371 zcopy(z2, z2res);
372 } else {
373 zquo(z1, tmp, z1res);
374 zquo(z2, tmp, z2res);
375 }
376 zfree(tmp);
377 }
378
379
380 /*
381 * Divide two numbers to obtain a quotient and remainder.
382 * This algorithm is taken from
383 * Knuth, The Art of Computer Programming, vol 2: Seminumerical Algorithms.
384 * Slight modifications were made to speed this mess up.
385 */
386 void
zdiv(z1,z2,res,rem)387 zdiv(z1, z2, res, rem)
388 ZVALUE z1, z2, *res, *rem;
389 {
390 long i, j, k;
391 register HALF *q, *pp;
392 SIUNION pair; /* pair of halfword values */
393 HALF h2, v2;
394 long y;
395 FULL x;
396 ZVALUE ztmp1, ztmp2, ztmp3, quo;
397
398 if (ziszero(z2))
399 math_error("Division by zero");
400 if (ziszero(z1)) {
401 *res = _zero_;
402 *rem = _zero_;
403 return;
404 }
405 if (zisone(z2)) {
406 zcopy(z1, res);
407 *rem = _zero_;
408 return;
409 }
410 i = BASE / 2;
411 j = 0;
412 k = (long) z2.v[z2.len - 1];
413 while (! (k & i)) {
414 j ++;
415 i >>= 1;
416 }
417 ztmp1.v = alloc(z1.len + 1);
418 ztmp1.len = z1.len + 1;
419 zcopyval(z1, ztmp1);
420 ztmp1.v[z1.len] = 0;
421 ztmp1.sign = 0;
422 ztmp2.v = alloc(z2.len);
423 ztmp2.len = z2.len;
424 ztmp2.sign = 0;
425 zcopyval(z2, ztmp2);
426 if (zrel(ztmp1, ztmp2) < 0) {
427 rem->v = ztmp1.v;
428 rem->sign = z1.sign;
429 rem->len = z1.len;
430 zfree(ztmp2);
431 *res = _zero_;
432 return;
433 }
434 quo.len = z1.len - z2.len + 1;
435 quo.v = alloc(quo.len);
436 quo.sign = z1.sign != z2.sign;
437 zclearval(quo);
438
439 ztmp3.v = zalloctemp(z2.len + 1);
440
441 /*
442 * Normalize z1 and z2
443 */
444 zshiftl(ztmp1, j);
445 zshiftl(ztmp2, j);
446
447 k = ztmp1.len - ztmp2.len;
448 q = quo.v + quo.len;
449 y = ztmp1.len - 1;
450 h2 = ztmp2.v [ztmp2.len - 1];
451 v2 = 0;
452 if (ztmp2.len >= 2)
453 v2 = ztmp2.v [ztmp2.len - 2];
454 for (;k--; --y) {
455 pp = ztmp1.v + y - 1;
456 pair.silow = pp[0];
457 pair.sihigh = pp[1];
458 if (ztmp1.v[y] == h2)
459 x = BASE1;
460 else
461 x = pair.ivalue / h2;
462 if (x) {
463 while (pair.ivalue - x * h2 < BASE && y > 1 &&
464 v2 * x > (pair.ivalue - x * h2) * BASE + ztmp1.v [y-2]) {
465 --x;
466 }
467 dmul(ztmp2, x, &ztmp3);
468 #ifdef divblab
469 printf(" x: %ld\n", x);
470 printf("ztmp1: ");
471 printz(ztmp1);
472 printf("ztmp2: ");
473 printz(ztmp2);
474 printf("ztmp3: ");
475 printz(ztmp3);
476 #endif
477 if (dsub(ztmp1, ztmp3, y, ztmp2.len)) {
478 --x;
479 /*
480 printf("adding back\n");
481 */
482 dadd(ztmp1, ztmp2, y, ztmp2.len);
483 }
484 }
485 ztrim(&ztmp1);
486 *--q = (HALF)x;
487 }
488 zshiftr(ztmp1, j);
489 *rem = ztmp1;
490 ztrim(rem);
491 zfree(ztmp2);
492 ztrim(&quo);
493 *res = quo;
494 }
495
496
497 /*
498 * Return the quotient and remainder of an integer divided by a small
499 * number. A nonzero remainder is only meaningful when both numbers
500 * are positive.
501 */
502 long
zdivi(z,n,res)503 zdivi(z, n, res)
504 ZVALUE z, *res;
505 long n;
506 {
507 register HALF *h1, *sd;
508 FULL val;
509 HALF divval[2];
510 ZVALUE div;
511 ZVALUE dest;
512 long len;
513
514 if (n == 0)
515 math_error("Division by zero");
516 if (ziszero(z)) {
517 *res = _zero_;
518 return 0;
519 }
520 if (n < 0) {
521 n = -n;
522 z.sign = !z.sign;
523 }
524 if (n == 1) {
525 zcopy(z, res);
526 return 0;
527 }
528 /*
529 * If the division is by a large number, then call the normal
530 * divide routine.
531 */
532 if (n & ~BASE1) {
533 div.sign = 0;
534 div.len = 2;
535 div.v = divval;
536 divval[0] = (HALF) n;
537 divval[1] = ((FULL) n) >> BASEB;
538 zdiv(z, div, res, &dest);
539 n = (zistiny(dest) ? z1tol(dest) : z2tol(dest));
540 zfree(dest);
541 return n;
542 }
543 /*
544 * Division is by a small number, so we can be quick about it.
545 */
546 len = z.len;
547 dest.sign = z.sign;
548 dest.len = len;
549 dest.v = alloc(len);
550 h1 = z.v + len - 1;
551 sd = dest.v + len - 1;
552 val = 0;
553 while (len--) {
554 val = ((val << BASEB) + ((FULL) *h1--));
555 *sd-- = val / n;
556 val %= n;
557 }
558 zquicktrim(dest);
559 *res = dest;
560 return val;
561 }
562
563
564 /*
565 * Return the quotient of two numbers.
566 * This works the same as zdiv, except that the remainer is not returned.
567 */
568 void
zquo(z1,z2,res)569 zquo(z1, z2, res)
570 ZVALUE z1, z2, *res;
571 {
572 long i, j, k;
573 register HALF *q, *pp;
574 SIUNION pair; /* pair of halfword values */
575 HALF h2, v2;
576 long y;
577 FULL x;
578 ZVALUE ztmp1, ztmp2, ztmp3, quo;
579
580 if (ziszero(z2))
581 math_error("Division by zero");
582 if (ziszero(z1)) {
583 *res = _zero_;
584 return;
585 }
586 if (zisone(z2)) {
587 zcopy(z1, res);
588 return;
589 }
590 i = BASE / 2;
591 j = 0;
592 k = (long) z2.v[z2.len - 1];
593 while (! (k & i)) {
594 j ++;
595 i >>= 1;
596 }
597 ztmp1.v = alloc(z1.len + 1);
598 ztmp1.len = z1.len + 1;
599 zcopyval(z1, ztmp1);
600 ztmp1.v[z1.len] = 0;
601 ztmp1.sign = 0;
602 ztmp2.v = alloc(z2.len);
603 ztmp2.len = z2.len;
604 ztmp2.sign = 0;
605 zcopyval(z2, ztmp2);
606 if (zrel(ztmp1, ztmp2) < 0) {
607 zfree(ztmp1);
608 zfree(ztmp2);
609 *res = _zero_;
610 return;
611 }
612 quo.len = z1.len - z2.len + 1;
613 quo.v = alloc(quo.len);
614 quo.sign = z1.sign != z2.sign;
615 zclearval(quo);
616
617 ztmp3.v = zalloctemp(z2.len + 1);
618
619 /*
620 * Normalize z1 and z2
621 */
622 zshiftl(ztmp1, j);
623 zshiftl(ztmp2, j);
624
625 k = ztmp1.len - ztmp2.len;
626 q = quo.v + quo.len;
627 y = ztmp1.len - 1;
628 h2 = ztmp2.v [ztmp2.len - 1];
629 v2 = 0;
630 if (ztmp2.len >= 2)
631 v2 = ztmp2.v [ztmp2.len - 2];
632 for (;k--; --y) {
633 pp = ztmp1.v + y - 1;
634 pair.silow = pp[0];
635 pair.sihigh = pp[1];
636 if (ztmp1.v[y] == h2)
637 x = BASE1;
638 else
639 x = pair.ivalue / h2;
640 if (x) {
641 while (pair.ivalue - x * h2 < BASE && y > 1 &&
642 v2 * x > (pair.ivalue - x * h2) * BASE + ztmp1.v [y-2]) {
643 --x;
644 }
645 dmul(ztmp2, x, &ztmp3);
646 if (dsub(ztmp1, ztmp3, y, ztmp2.len)) {
647 --x;
648 dadd(ztmp1, ztmp2, y, ztmp2.len);
649 }
650 }
651 ztrim(&ztmp1);
652 *--q = (HALF)x;
653 }
654 zfree(ztmp1);
655 zfree(ztmp2);
656 ztrim(&quo);
657 *res = quo;
658 }
659
660
661 /*
662 * Compute the remainder after dividing one number by another.
663 * This is only defined for positive z2 values.
664 * The result is normalized to lie in the range 0 to z2-1.
665 */
666 void
zmod(z1,z2,rem)667 zmod(z1, z2, rem)
668 ZVALUE z1, z2, *rem;
669 {
670 long i, j, k, neg;
671 register HALF *pp;
672 SIUNION pair; /* pair of halfword values */
673 HALF h2, v2;
674 long y;
675 FULL x;
676 ZVALUE ztmp1, ztmp2, ztmp3;
677
678 if (ziszero(z2))
679 math_error("Division by zero");
680 if (zisneg(z2))
681 math_error("Non-positive modulus");
682 if (ziszero(z1) || zisunit(z2)) {
683 *rem = _zero_;
684 return;
685 }
686 if (zistwo(z2)) {
687 if (zisodd(z1))
688 *rem = _one_;
689 else
690 *rem = _zero_;
691 return;
692 }
693 neg = z1.sign;
694 z1.sign = 0;
695
696 /*
697 * Do a quick check to see if the absolute value of the number
698 * is less than the modulus. If so, then the result is just a
699 * subtract or a copy.
700 */
701 h2 = z1.v[z1.len - 1];
702 v2 = z2.v[z2.len - 1];
703 if ((z1.len < z2.len) || ((z1.len == z2.len) && (h2 < v2))) {
704 if (neg)
705 zsub(z2, z1, rem);
706 else
707 zcopy(z1, rem);
708 return;
709 }
710
711 /*
712 * Do another quick check to see if the number is positive and
713 * between the size of the modulus and twice the modulus.
714 * If so, then the answer is just another subtract.
715 */
716 if (!neg && (z1.len == z2.len) && (h2 > v2) &&
717 (((FULL) h2) < 2 * ((FULL) v2)))
718 {
719 zsub(z1, z2, rem);
720 return;
721 }
722
723 /*
724 * If the modulus is an exact power of two, then the result
725 * can be obtained by ignoring the high bits of the number.
726 * This truncation assumes that the number of words for the
727 * number is at least as large as the number of words in the
728 * modulus, which is true at this point.
729 */
730 if (((v2 & -v2) == v2) && zisonebit(z2)) { /* ASSUMES 2'S COMP */
731 i = zhighbit(z2);
732 z1.len = (i + BASEB - 1) / BASEB;
733 zcopy(z1, &ztmp1);
734 i %= BASEB;
735 if (i)
736 ztmp1.v[ztmp1.len - 1] &= ((((HALF) 1) << i) - 1);
737 ztmp2.len = 0;
738 goto gotanswer;
739 }
740
741 /*
742 * If the modulus is one less than an exact power of two, then
743 * the result can be simplified similarly to "casting out 9's".
744 * Only do this simplification for large enough modulos.
745 */
746 if ((z2.len > 1) && (z2.v[0] == BASE1) && zisallbits(z2)) {
747 i = -(zhighbit(z2) + 1);
748 zcopy(z1, &ztmp1);
749 z1 = ztmp1;
750 while ((k = zrel(z1, z2)) > 0) {
751 ztmp1 = _zero_;
752 while (!ziszero(z1)) {
753 zand(z1, z2, &ztmp2);
754 zadd(ztmp2, ztmp1, &ztmp3);
755 zfree(ztmp1);
756 zfree(ztmp2);
757 ztmp1 = ztmp3;
758 zshift(z1, i, &ztmp2);
759 zfree(z1);
760 z1 = ztmp2;
761 }
762 zfree(z1);
763 z1 = ztmp1;
764 }
765 if (k == 0) {
766 zfree(ztmp1);
767 *rem = _zero_;
768 return;
769 }
770 ztmp2.len = 0;
771 goto gotanswer;
772 }
773
774 /*
775 * Must actually do the divide.
776 */
777 i = BASE / 2;
778 j = 0;
779 k = (long) z2.v[z2.len - 1];
780 while (! (k & i)) {
781 j ++;
782 i >>= 1;
783 }
784 ztmp1.v = alloc(z1.len + 1);
785 ztmp1.len = z1.len + 1;
786 zcopyval(z1, ztmp1);
787 ztmp1.v[z1.len] = 0;
788 ztmp1.sign = 0;
789 ztmp2.v = alloc(z2.len);
790 ztmp2.len = z2.len;
791 ztmp2.sign = 0;
792 zcopyval(z2, ztmp2);
793 if (zrel(ztmp1, ztmp2) < 0)
794 goto gotanswer;
795
796 ztmp3.v = zalloctemp(z2.len + 1);
797
798 /*
799 * Normalize z1 and z2
800 */
801 zshiftl(ztmp1, j);
802 zshiftl(ztmp2, j);
803
804 k = ztmp1.len - ztmp2.len;
805 y = ztmp1.len - 1;
806 h2 = ztmp2.v [ztmp2.len - 1];
807 v2 = 0;
808 if (ztmp2.len >= 2)
809 v2 = ztmp2.v [ztmp2.len - 2];
810 for (;k--; --y) {
811 pp = ztmp1.v + y - 1;
812 pair.silow = pp[0];
813 pair.sihigh = pp[1];
814 if (ztmp1.v[y] == h2)
815 x = BASE1;
816 else
817 x = pair.ivalue / h2;
818 if (x) {
819 while (pair.ivalue - x * h2 < BASE && y > 1 &&
820 v2 * x > (pair.ivalue - x * h2) * BASE + ztmp1.v [y-2]) {
821 --x;
822 }
823 dmul(ztmp2, x, &ztmp3);
824 if (dsub(ztmp1, ztmp3, y, ztmp2.len))
825 dadd(ztmp1, ztmp2, y, ztmp2.len);
826 }
827 ztrim(&ztmp1);
828 }
829 zshiftr(ztmp1, j);
830
831 gotanswer:
832 ztrim(&ztmp1);
833 if (ztmp2.len)
834 zfree(ztmp2);
835 if (neg && !ziszero(ztmp1)) {
836 zsub(z2, ztmp1, rem);
837 zfree(ztmp1);
838 } else
839 *rem = ztmp1;
840 }
841
842
843 /*
844 * Calculate the mod of an integer by a small number.
845 * This is only defined for positive moduli.
846 */
847 long
zmodi(z,n)848 zmodi(z, n)
849 ZVALUE z;
850 long n;
851 {
852 register HALF *h1;
853 FULL val;
854 HALF divval[2];
855 ZVALUE div;
856 ZVALUE temp;
857 long len;
858
859 if (n == 0)
860 math_error("Division by zero");
861 if (n < 0)
862 math_error("Non-positive modulus");
863 if (ziszero(z) || (n == 1))
864 return 0;
865 if (zisone(z))
866 return 1;
867 /*
868 * If the modulus is by a large number, then call the normal
869 * modulo routine.
870 */
871 if (n & ~BASE1) {
872 div.sign = 0;
873 div.len = 2;
874 div.v = divval;
875 divval[0] = (HALF) n;
876 divval[1] = ((FULL) n) >> BASEB;
877 zmod(z, div, &temp);
878 n = (zistiny(temp) ? z1tol(temp) : z2tol(temp));
879 zfree(temp);
880 return n;
881 }
882 /*
883 * The modulus is by a small number, so we can do this quickly.
884 */
885 len = z.len;
886 h1 = z.v + len - 1;
887 val = 0;
888 while (len--)
889 val = ((val << BASEB) + ((FULL) *h1--)) % n;
890 if (z.sign)
891 val = n - val;
892 return val;
893 }
894
895 /*
896 * Compute the logical OR of two numbers
897 */
898 void
zor(z1,z2,res)899 zor(z1, z2, res)
900 ZVALUE z1, z2, *res;
901 {
902 register HALF *sp, *dp;
903 long len;
904 ZVALUE bz, lz, dest;
905
906 if (z1.len >= z2.len) {
907 bz = z1;
908 lz = z2;
909 } else {
910 bz = z2;
911 lz = z1;
912 }
913 dest.len = bz.len;
914 dest.v = alloc(dest.len);
915 dest.sign = 0;
916 zcopyval(bz, dest);
917 len = lz.len;
918 sp = lz.v;
919 dp = dest.v;
920 while (len--)
921 *dp++ |= *sp++;
922 *res = dest;
923 }
924
925
926 /*
927 * Compute the logical AND of two numbers.
928 */
929 void
zand(z1,z2,res)930 zand(z1, z2, res)
931 ZVALUE z1, z2, *res;
932 {
933 register HALF *h1, *h2, *hd;
934 register long len;
935 ZVALUE dest;
936
937 len = ((z1.len <= z2.len) ? z1.len : z2.len);
938 h1 = &z1.v[len-1];
939 h2 = &z2.v[len-1];
940 while ((len > 1) && ((*h1 & *h2) == 0)) {
941 h1--;
942 h2--;
943 len--;
944 }
945 dest.len = len;
946 dest.v = alloc(len);
947 dest.sign = 0;
948 h1 = z1.v;
949 h2 = z2.v;
950 hd = dest.v;
951 while (len--)
952 *hd++ = (*h1++ & *h2++);
953 *res = dest;
954 }
955
956
957 /*
958 * Compute the logical XOR of two numbers.
959 */
960 void
zxor(z1,z2,res)961 zxor(z1, z2, res)
962 ZVALUE z1, z2, *res;
963 {
964 register HALF *sp, *dp;
965 long len;
966 ZVALUE bz, lz, dest;
967
968 if (z1.len == z2.len) {
969 for (len = z1.len; ((len > 1) && (z1.v[len-1] == z2.v[len-1])); len--) ;
970 z1.len = len;
971 z2.len = len;
972 }
973 if (z1.len >= z2.len) {
974 bz = z1;
975 lz = z2;
976 } else {
977 bz = z2;
978 lz = z1;
979 }
980 dest.len = bz.len;
981 dest.v = alloc(dest.len);
982 dest.sign = 0;
983 zcopyval(bz, dest);
984 len = lz.len;
985 sp = lz.v;
986 dp = dest.v;
987 while (len--)
988 *dp++ ^= *sp++;
989 *res = dest;
990 }
991
992
993 /*
994 * Shift a number left (or right) by the specified number of bits.
995 * Positive shift means to the left. When shifting right, rightmost
996 * bits are lost. The sign of the number is preserved.
997 */
998 void
zshift(z,n,res)999 zshift(z, n, res)
1000 ZVALUE z, *res;
1001 long n;
1002 {
1003 ZVALUE ans;
1004 long hc; /* number of halfwords shift is by */
1005
1006 if (ziszero(z)) {
1007 *res = _zero_;
1008 return;
1009 }
1010 if (n == 0) {
1011 zcopy(z, res);
1012 return;
1013 }
1014 /*
1015 * If shift value is negative, then shift right.
1016 * Check for large shifts, and handle word-sized shifts quickly.
1017 */
1018 if (n < 0) {
1019 n = -n;
1020 if ((n < 0) || (n >= (z.len * BASEB))) {
1021 *res = _zero_;
1022 return;
1023 }
1024 hc = n / BASEB;
1025 n %= BASEB;
1026 z.v += hc;
1027 z.len -= hc;
1028 ans.len = z.len;
1029 ans.v = alloc(ans.len);
1030 ans.sign = z.sign;
1031 zcopyval(z, ans);
1032 if (n > 0) {
1033 zshiftr(ans, n);
1034 ztrim(&ans);
1035 }
1036 if (ziszero(ans)) {
1037 zfree(ans);
1038 ans = _zero_;
1039 }
1040 *res = ans;
1041 return;
1042 }
1043 /*
1044 * Shift value is positive, so shift leftwards.
1045 * Check specially for a shift of the value 1, since this is common.
1046 * Also handle word-sized shifts quickly.
1047 */
1048 if (zisunit(z)) {
1049 zbitvalue(n, res);
1050 res->sign = z.sign;
1051 return;
1052 }
1053 hc = n / BASEB;
1054 n %= BASEB;
1055 ans.len = z.len + hc + 1;
1056 ans.v = alloc(ans.len);
1057 ans.sign = z.sign;
1058 if (hc > 0)
1059 memset((char *) ans.v, 0, hc * sizeof(HALF));
1060 memcpy((char *) (ans.v + hc),
1061 (char *) z.v, z.len * sizeof(HALF));
1062 ans.v[ans.len - 1] = 0;
1063 if (n > 0) {
1064 ans.v += hc;
1065 ans.len -= hc;
1066 zshiftl(ans, n);
1067 ans.v -= hc;
1068 ans.len += hc;
1069 }
1070 ztrim(&ans);
1071 *res = ans;
1072 }
1073
1074
1075 /*
1076 * Return the position of the lowest bit which is set in the binary
1077 * representation of a number (counting from zero). This is the highest
1078 * power of two which evenly divides the number.
1079 */
1080 long
zlowbit(z)1081 zlowbit(z)
1082 ZVALUE z;
1083 {
1084 register HALF *zp;
1085 long n;
1086 HALF dataval;
1087 HALF *bitval;
1088
1089 n = 0;
1090 for (zp = z.v; *zp == 0; zp++)
1091 if (++n >= z.len)
1092 return 0;
1093 dataval = *zp;
1094 bitval = bitmask;
1095 while ((*(bitval++) & dataval) == 0) {
1096 }
1097 return (n*BASEB)+(bitval-bitmask-1);
1098 }
1099
1100
1101 /*
1102 * Return the position of the highest bit which is set in the binary
1103 * representation of a number (counting from zero). This is the highest power
1104 * of two which is less than or equal to the number (which is assumed nonzero).
1105 */
1106 long
zhighbit(z)1107 zhighbit(z)
1108 ZVALUE z;
1109 {
1110 HALF dataval;
1111 HALF *bitval;
1112
1113 dataval = z.v[z.len-1];
1114 bitval = bitmask+BASEB;
1115 if (dataval) {
1116 while ((*(--bitval) & dataval) == 0) {
1117 }
1118 }
1119 return (z.len*BASEB)+(bitval-bitmask-BASEB);
1120 }
1121
1122 /*
1123 * Check whether or not a number has exactly one bit set, and
1124 * thus is an exact power of two. Returns TRUE if so.
1125 */
1126 BOOL
zisonebit(z)1127 zisonebit(z)
1128 ZVALUE z;
1129 {
1130 register HALF *hp;
1131 register LEN len;
1132
1133 if (ziszero(z) || zisneg(z))
1134 return FALSE;
1135 hp = z.v;
1136 len = z.len;
1137 while (len > 4) {
1138 len -= 4;
1139 if (*hp++ || *hp++ || *hp++ || *hp++)
1140 return FALSE;
1141 }
1142 while (--len > 0) {
1143 if (*hp++)
1144 return FALSE;
1145 }
1146 return ((*hp & -*hp) == *hp); /* NEEDS 2'S COMPLEMENT */
1147 }
1148
1149
1150 /*
1151 * Check whether or not a number has all of its bits set below some
1152 * bit position, and thus is one less than an exact power of two.
1153 * Returns TRUE if so.
1154 */
1155 BOOL
zisallbits(z)1156 zisallbits(z)
1157 ZVALUE z;
1158 {
1159 register HALF *hp;
1160 register LEN len;
1161 HALF digit;
1162
1163 if (ziszero(z) || zisneg(z))
1164 return FALSE;
1165 hp = z.v;
1166 len = z.len;
1167 while (len > 4) {
1168 len -= 4;
1169 if ((*hp++ != BASE1) || (*hp++ != BASE1) ||
1170 (*hp++ != BASE1) || (*hp++ != BASE1))
1171 return FALSE;
1172 }
1173 while (--len > 0) {
1174 if (*hp++ != BASE1)
1175 return FALSE;
1176 }
1177 digit = (HALF)(*hp + 1);
1178 return ((digit & -digit) == digit); /* NEEDS 2'S COMPLEMENT */
1179 }
1180
1181
1182 /*
1183 * Return the number whose binary representation contains only one bit which
1184 * is in the specified position (counting from zero). This is equivilant
1185 * to raising two to the given power.
1186 */
1187 void
zbitvalue(n,res)1188 zbitvalue(n, res)
1189 long n;
1190 ZVALUE *res;
1191 {
1192 ZVALUE z;
1193
1194 if (n < 0) n = 0;
1195 z.sign = 0;
1196 z.len = (n / BASEB) + 1;
1197 z.v = alloc(z.len);
1198 zclearval(z);
1199 z.v[z.len-1] = (((HALF) 1) << (n % BASEB));
1200 *res = z;
1201 }
1202
1203
1204 /*
1205 * Compare a number against zero.
1206 * Returns the sgn function of the number (-1, 0, or 1).
1207 */
1208 FLAG
ztest(z)1209 ztest(z)
1210 ZVALUE z;
1211 {
1212 register int sign;
1213 register HALF *h;
1214 register long len;
1215
1216 sign = 1;
1217 if (z.sign)
1218 sign = -sign;
1219 h = z.v;
1220 len = z.len;
1221 while (len--)
1222 if (*h++)
1223 return sign;
1224 return 0;
1225 }
1226
1227
1228 /*
1229 * Compare two numbers to see which is larger.
1230 * Returns -1 if first number is smaller, 0 if they are equal, and 1 if
1231 * first number is larger. This is the same result as ztest(z2-z1).
1232 */
1233 FLAG
zrel(z1,z2)1234 zrel(z1, z2)
1235 ZVALUE z1, z2;
1236 {
1237 register HALF *h1, *h2;
1238 register long len1, len2;
1239 int sign;
1240
1241 sign = 1;
1242 if (z1.sign < z2.sign)
1243 return 1;
1244 if (z2.sign < z1.sign)
1245 return -1;
1246 if (z2.sign)
1247 sign = -1;
1248 len1 = z1.len;
1249 len2 = z2.len;
1250 h1 = z1.v + z1.len - 1;
1251 h2 = z2.v + z2.len - 1;
1252 while (len1 > len2) {
1253 if (*h1--)
1254 return sign;
1255 len1--;
1256 }
1257 while (len2 > len1) {
1258 if (*h2--)
1259 return -sign;
1260 len2--;
1261 }
1262 while (len1--) {
1263 if (*h1-- != *h2--)
1264 break;
1265 }
1266 if ((len1 = *++h1) > (len2 = *++h2))
1267 return sign;
1268 if (len1 < len2)
1269 return -sign;
1270 return 0;
1271 }
1272
1273
1274 /*
1275 * Compare two numbers to see if they are equal or not.
1276 * Returns TRUE if they differ.
1277 */
1278 BOOL
zcmp(z1,z2)1279 zcmp(z1, z2)
1280 ZVALUE z1, z2;
1281 {
1282 register HALF *h1, *h2;
1283 register long len;
1284
1285 if ((z1.sign != z2.sign) || (z1.len != z2.len) || (*z1.v != *z2.v))
1286 return TRUE;
1287 len = z1.len;
1288 h1 = z1.v;
1289 h2 = z2.v;
1290 while (len-- > 0) {
1291 if (*h1++ != *h2++)
1292 return TRUE;
1293 }
1294 return FALSE;
1295 }
1296
1297
1298 /*
1299 * Internal utility subroutines
1300 */
1301 static void
dadd(z1,z2,y,n)1302 dadd(z1, z2, y, n)
1303 ZVALUE z1, z2;
1304 long y, n;
1305 {
1306 HALF *s1, *s2;
1307 short carry;
1308 long sum;
1309
1310 s1 = z1.v + y - n;
1311 s2 = z2.v;
1312 carry = 0;
1313 while (n--) {
1314 sum = (long)*s1 + (long)*s2 + carry;
1315 carry = 0;
1316 if (sum >= BASE) {
1317 sum -= BASE;
1318 carry = 1;
1319 }
1320 *s1 = (HALF)sum;
1321 ++s1;
1322 ++s2;
1323 }
1324 sum = (long)*s1 + carry;
1325 *s1 = (HALF)sum;
1326 }
1327
1328
1329 /*
1330 * Do subtract for divide, returning TRUE if subtraction went negative.
1331 */
1332 static BOOL
dsub(z1,z2,y,n)1333 dsub(z1, z2, y, n)
1334 ZVALUE z1, z2;
1335 long y, n;
1336 {
1337 HALF *s1, *s2, *s3;
1338 FULL i1;
1339 BOOL neg;
1340
1341 neg = FALSE;
1342 s1 = z1.v + y - n;
1343 s2 = z2.v;
1344 if (++n > z2.len)
1345 n = z2.len;
1346 while (n--) {
1347 i1 = (FULL) *s1;
1348 if (i1 < (FULL) *s2) {
1349 s3 = s1 + 1;
1350 while (s3 < z1.v + z1.len && !(*s3)) {
1351 *s3 = BASE1;
1352 ++s3;
1353 }
1354 if (s3 >= z1.v + z1.len)
1355 neg = TRUE;
1356 else
1357 --(*s3);
1358 i1 += BASE;
1359 }
1360 *s1 = i1 - (FULL) *s2;
1361 ++s1;
1362 ++s2;
1363 }
1364 return neg;
1365 }
1366
1367
1368 /*
1369 * Multiply a number by a single 'digit'.
1370 * This is meant to be used only by the divide routine, and so the
1371 * destination area must already be allocated and be large enough.
1372 */
1373 static void
dmul(z,mul,dest)1374 dmul(z, mul, dest)
1375 ZVALUE z;
1376 FULL mul;
1377 ZVALUE *dest;
1378 {
1379 register HALF *zp, *dp;
1380 SIUNION sival;
1381 FULL carry;
1382 long len;
1383
1384 dp = dest->v;
1385 dest->sign = 0;
1386 if (mul == 0) {
1387 dest->len = 1;
1388 *dp = 0;
1389 return;
1390 }
1391 len = z.len;
1392 zp = z.v + len - 1;
1393 while ((*zp == 0) && (len > 1)) {
1394 len--;
1395 zp--;
1396 }
1397 dest->len = len;
1398 zp = z.v;
1399 carry = 0;
1400 while (len >= 4) {
1401 len -= 4;
1402 sival.ivalue = (mul * ((FULL) *zp++)) + carry;
1403 *dp++ = sival.silow;
1404 sival.ivalue = (mul * ((FULL) *zp++)) + ((FULL) sival.sihigh);
1405 *dp++ = sival.silow;
1406 sival.ivalue = (mul * ((FULL) *zp++)) + ((FULL) sival.sihigh);
1407 *dp++ = sival.silow;
1408 sival.ivalue = (mul * ((FULL) *zp++)) + ((FULL) sival.sihigh);
1409 *dp++ = sival.silow;
1410 carry = sival.sihigh;
1411 }
1412 while (--len >= 0) {
1413 sival.ivalue = (mul * ((FULL) *zp++)) + carry;
1414 *dp++ = sival.silow;
1415 carry = sival.sihigh;
1416 }
1417 if (carry) {
1418 *dp = (HALF)carry;
1419 dest->len++;
1420 }
1421 }
1422
1423
1424 /*
1425 * Utility to calculate the gcd of two small integers.
1426 */
1427 long
iigcd(i1,i2)1428 iigcd(i1, i2)
1429 long i1, i2;
1430 {
1431 FULL f1, f2, temp;
1432
1433 f1 = (FULL) ((i1 >= 0) ? i1 : -i1);
1434 f2 = (FULL) ((i2 >= 0) ? i2 : -i2);
1435 while (f1) {
1436 temp = f2 % f1;
1437 f2 = f1;
1438 f1 = temp;
1439 }
1440 return (long) f2;
1441 }
1442
1443
1444 void
ztrim(z)1445 ztrim(z)
1446 ZVALUE *z;
1447 {
1448 register HALF *h;
1449 register long len;
1450
1451 h = z->v + z->len - 1;
1452 len = z->len;
1453 while (*h == 0 && len > 1) {
1454 --h;
1455 --len;
1456 }
1457 z->len = len;
1458 }
1459
1460
1461 /*
1462 * Utility routine to shift right.
1463 */
1464 void
zshiftr(z,n)1465 zshiftr(z, n)
1466 ZVALUE z;
1467 long n;
1468 {
1469 register HALF *h, *lim;
1470 FULL mask, maskt;
1471 long len;
1472
1473 if (n >= BASEB) {
1474 len = n / BASEB;
1475 h = z.v;
1476 lim = z.v + z.len - len;
1477 while (h < lim) {
1478 h[0] = h[len];
1479 ++h;
1480 }
1481 n -= BASEB * len;
1482 lim = z.v + z.len;
1483 while (h < lim)
1484 *h++ = 0;
1485 }
1486 if (n) {
1487 len = z.len;
1488 h = z.v + len - 1;
1489 mask = 0;
1490 while (len--) {
1491 maskt = (((FULL) *h) << (BASEB - n)) & BASE1;
1492 *h = (*h >> n) | mask;
1493 mask = maskt;
1494 --h;
1495 }
1496 }
1497 }
1498
1499
1500 /*
1501 * Utility routine to shift left.
1502 */
1503 void
zshiftl(z,n)1504 zshiftl(z, n)
1505 ZVALUE z;
1506 long n;
1507 {
1508 register HALF *h;
1509 FULL mask, i;
1510 long len;
1511
1512 if (n >= BASEB) {
1513 len = n / BASEB;
1514 h = z.v + z.len - 1;
1515 while (!*h)
1516 --h;
1517 while (h >= z.v) {
1518 h[len] = h[0];
1519 --h;
1520 }
1521 n -= BASEB * len;
1522 while (len)
1523 h[len--] = 0;
1524 }
1525 if (n > 0) {
1526 len = z.len;
1527 h = z.v;
1528 mask = 0;
1529 while (len--) {
1530 i = (((FULL) *h) << n) | mask;
1531 if (i > BASE1) {
1532 mask = i >> BASEB;
1533 i &= BASE1;
1534 } else
1535 mask = 0;
1536 *h = (HALF) i;
1537 ++h;
1538 }
1539 }
1540 }
1541
1542 /*
1543 * initmasks - init the bitmask rotation arrays
1544 *
1545 * bitmask[i] (1 << (i-1)), for -BASEB*4<=i<=BASEB*4
1546 *
1547 * The bmask array contains 8 cycles of rotations of a bit mask.
1548 */
1549 void
initmasks()1550 initmasks()
1551 {
1552 int i;
1553
1554 /*
1555 * setup the bmask array
1556 */
1557 bmask = alloc((long)((8*BASEB)+1));
1558 for (i=0; i < (8*BASEB)+1; ++i) {
1559 bmask[i] = 1 << (i%BASEB);
1560 }
1561
1562 /*
1563 * setup the bitmask array to allow -4*BASEB thru 4*BASEB indexing
1564 */
1565 bitmask = &bmask[4*BASEB];
1566 return;
1567 }
1568
1569 /* END CODE */
1570