Actually hook powernow.4 into the build.
[dragonfly.git] / contrib / gmp / dumbmp.c
blobcd8c67d369403f6b9a7411d1f39a218bc7d6b3fb
1 /* dumbmp mini GMP compatible library.
3 Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 /* The code here implements a subset (a very limited subset) of the main GMP
22 functions. It's designed for use in a few build-time calculations and
23 will be slow, but highly portable.
25 None of the normal GMP configure things are used, nor any of the normal
26 gmp.h or gmp-impl.h. To use this file in a program just #include
27 "dumbmp.c".
29 ANSI function definitions can be used here, since ansi2knr is run if
30 necessary. But other ANSI-isms like "const" should be avoided.
32 mp_limb_t here is an unsigned long, since that's a sensible type
33 everywhere we know of, with 8*sizeof(unsigned long) giving the number of
34 bits in the type (that not being true for instance with int or short on
35 Cray vector systems.)
37 Only the low half of each mp_limb_t is used, so as to make carry handling
38 and limb multiplies easy. GMP_LIMB_BITS is the number of bits used. */
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
45 typedef unsigned long mp_limb_t;
47 typedef struct {
48 int _mp_alloc;
49 int _mp_size;
50 mp_limb_t *_mp_d;
51 } mpz_t[1];
53 #define GMP_LIMB_BITS (sizeof (mp_limb_t) * 8 / 2)
55 #define ABS(x) ((x) >= 0 ? (x) : -(x))
56 #define MIN(l,o) ((l) < (o) ? (l) : (o))
57 #define MAX(h,i) ((h) > (i) ? (h) : (i))
59 #define ALLOC(x) ((x)->_mp_alloc)
60 #define PTR(x) ((x)->_mp_d)
61 #define SIZ(x) ((x)->_mp_size)
62 #define ABSIZ(x) ABS (SIZ (x))
63 #define LOMASK ((1L << GMP_LIMB_BITS) - 1)
64 #define LO(x) ((x) & LOMASK)
65 #define HI(x) ((x) >> GMP_LIMB_BITS)
67 #define ASSERT(cond) \
68 do { \
69 if (! (cond)) \
70 { \
71 fprintf (stderr, "Assertion failure\n"); \
72 abort (); \
73 } \
74 } while (0)
77 char *
78 xmalloc (int n)
80 char *p;
81 p = malloc (n);
82 if (p == NULL)
84 fprintf (stderr, "Out of memory (alloc %d bytes)\n", n);
85 abort ();
87 return p;
90 mp_limb_t *
91 xmalloc_limbs (int n)
93 return (mp_limb_t *) xmalloc (n * sizeof (mp_limb_t));
96 void
97 mem_copyi (char *dst, char *src, int size)
99 int i;
100 for (i = 0; i < size; i++)
101 dst[i] = src[i];
105 isprime (int n)
107 int i;
108 if (n < 2)
109 return 0;
110 for (i = 2; i < n; i++)
111 if ((n % i) == 0)
112 return 0;
113 return 1;
117 log2_ceil (int n)
119 int e;
120 ASSERT (n >= 1);
121 for (e = 0; ; e++)
122 if ((1 << e) >= n)
123 break;
124 return e;
127 void
128 mpz_realloc (mpz_t r, int n)
130 if (n <= ALLOC(r))
131 return;
133 ALLOC(r) = n;
134 PTR(r) = (mp_limb_t *) realloc (PTR(r), n * sizeof (mp_limb_t));
135 if (PTR(r) == NULL)
137 fprintf (stderr, "Out of memory (realloc to %d)\n", n);
138 abort ();
142 void
143 mpn_normalize (mp_limb_t *rp, int *rnp)
145 int rn = *rnp;
146 while (rn > 0 && rp[rn-1] == 0)
147 rn--;
148 *rnp = rn;
151 void
152 mpn_copyi (mp_limb_t *dst, mp_limb_t *src, int n)
154 int i;
155 for (i = 0; i < n; i++)
156 dst[i] = src[i];
159 void
160 mpn_zero (mp_limb_t *rp, int rn)
162 int i;
163 for (i = 0; i < rn; i++)
164 rp[i] = 0;
167 void
168 mpz_init (mpz_t r)
170 ALLOC(r) = 1;
171 PTR(r) = xmalloc_limbs (ALLOC(r));
172 PTR(r)[0] = 0;
173 SIZ(r) = 0;
176 void
177 mpz_clear (mpz_t r)
179 free (PTR (r));
180 ALLOC(r) = -1;
181 SIZ (r) = 0xbadcafeL;
182 PTR (r) = (mp_limb_t *) 0xdeadbeefL;
186 mpz_sgn (mpz_t a)
188 return (SIZ(a) > 0 ? 1 : SIZ(a) == 0 ? 0 : -1);
192 mpz_odd_p (mpz_t a)
194 if (SIZ(a) == 0)
195 return 0;
196 else
197 return (PTR(a)[0] & 1) != 0;
201 mpz_even_p (mpz_t a)
203 if (SIZ(a) == 0)
204 return 1;
205 else
206 return (PTR(a)[0] & 1) == 0;
209 size_t
210 mpz_sizeinbase (mpz_t a, int base)
212 int an = ABSIZ (a);
213 mp_limb_t *ap = PTR (a);
214 int cnt;
215 mp_limb_t hi;
217 if (base != 2)
218 abort ();
220 if (an == 0)
221 return 1;
223 cnt = 0;
224 for (hi = ap[an - 1]; hi != 0; hi >>= 1)
225 cnt += 1;
226 return (an - 1) * GMP_LIMB_BITS + cnt;
229 void
230 mpz_set (mpz_t r, mpz_t a)
232 mpz_realloc (r, ABSIZ (a));
233 SIZ(r) = SIZ(a);
234 mpn_copyi (PTR(r), PTR(a), ABSIZ (a));
237 void
238 mpz_init_set (mpz_t r, mpz_t a)
240 mpz_init (r);
241 mpz_set (r, a);
244 void
245 mpz_set_ui (mpz_t r, unsigned long ui)
247 int rn;
248 mpz_realloc (r, 2);
249 PTR(r)[0] = LO(ui);
250 PTR(r)[1] = HI(ui);
251 rn = 2;
252 mpn_normalize (PTR(r), &rn);
253 SIZ(r) = rn;
256 void
257 mpz_init_set_ui (mpz_t r, unsigned long ui)
259 mpz_init (r);
260 mpz_set_ui (r, ui);
263 void
264 mpz_setbit (mpz_t r, unsigned long bit)
266 int limb, rn, extend;
267 mp_limb_t *rp;
269 rn = SIZ(r);
270 if (rn < 0)
271 abort (); /* only r>=0 */
273 limb = bit / GMP_LIMB_BITS;
274 bit %= GMP_LIMB_BITS;
276 mpz_realloc (r, limb+1);
277 rp = PTR(r);
278 extend = (limb+1) - rn;
279 if (extend > 0)
280 mpn_zero (rp + rn, extend);
282 rp[limb] |= (mp_limb_t) 1 << bit;
283 SIZ(r) = MAX (rn, limb+1);
287 mpz_tstbit (mpz_t r, unsigned long bit)
289 int limb;
291 if (SIZ(r) < 0)
292 abort (); /* only r>=0 */
294 limb = bit / GMP_LIMB_BITS;
295 if (SIZ(r) <= limb)
296 return 0;
298 bit %= GMP_LIMB_BITS;
299 return (PTR(r)[limb] >> bit) & 1;
303 popc_limb (mp_limb_t a)
305 int ret = 0;
306 while (a != 0)
308 ret += (a & 1);
309 a >>= 1;
311 return ret;
314 unsigned long
315 mpz_popcount (mpz_t a)
317 unsigned long ret;
318 int i;
320 if (SIZ(a) < 0)
321 abort ();
323 ret = 0;
324 for (i = 0; i < SIZ(a); i++)
325 ret += popc_limb (PTR(a)[i]);
326 return ret;
329 void
330 mpz_add (mpz_t r, mpz_t a, mpz_t b)
332 int an = ABSIZ (a), bn = ABSIZ (b), rn;
333 mp_limb_t *rp, *ap, *bp;
334 int i;
335 mp_limb_t t, cy;
337 if ((SIZ (a) ^ SIZ (b)) < 0)
338 abort (); /* really subtraction */
339 if (SIZ (a) < 0)
340 abort ();
342 mpz_realloc (r, MAX (an, bn) + 1);
343 ap = PTR (a); bp = PTR (b); rp = PTR (r);
344 if (an < bn)
346 mp_limb_t *tp; int tn;
347 tn = an; an = bn; bn = tn;
348 tp = ap; ap = bp; bp = tp;
351 cy = 0;
352 for (i = 0; i < bn; i++)
354 t = ap[i] + bp[i] + cy;
355 rp[i] = LO (t);
356 cy = HI (t);
358 for (i = bn; i < an; i++)
360 t = ap[i] + cy;
361 rp[i] = LO (t);
362 cy = HI (t);
364 rp[an] = cy;
365 rn = an + 1;
367 mpn_normalize (rp, &rn);
368 SIZ (r) = rn;
371 void
372 mpz_add_ui (mpz_t r, mpz_t a, unsigned long int ui)
374 mpz_t b;
376 mpz_init (b);
377 mpz_set_ui (b, ui);
378 mpz_add (r, a, b);
379 mpz_clear (b);
382 void
383 mpz_sub (mpz_t r, mpz_t a, mpz_t b)
385 int an = ABSIZ (a), bn = ABSIZ (b), rn;
386 mp_limb_t *rp, *ap, *bp;
387 int i;
388 mp_limb_t t, cy;
390 if ((SIZ (a) ^ SIZ (b)) < 0)
391 abort (); /* really addition */
392 if (SIZ (a) < 0)
393 abort ();
395 mpz_realloc (r, MAX (an, bn) + 1);
396 ap = PTR (a); bp = PTR (b); rp = PTR (r);
397 if (an < bn)
399 mp_limb_t *tp; int tn;
400 tn = an; an = bn; bn = tn;
401 tp = ap; ap = bp; bp = tp;
404 cy = 0;
405 for (i = 0; i < bn; i++)
407 t = ap[i] - bp[i] - cy;
408 rp[i] = LO (t);
409 cy = LO (-HI (t));
411 for (i = bn; i < an; i++)
413 t = ap[i] - cy;
414 rp[i] = LO (t);
415 cy = LO (-HI (t));
417 rp[an] = cy;
418 rn = an + 1;
420 if (cy != 0)
422 cy = 0;
423 for (i = 0; i < rn; i++)
425 t = -rp[i] - cy;
426 rp[i] = LO (t);
427 cy = LO (-HI (t));
429 SIZ (r) = -rn;
430 return;
433 mpn_normalize (rp, &rn);
434 SIZ (r) = rn;
437 void
438 mpz_sub_ui (mpz_t r, mpz_t a, unsigned long int ui)
440 mpz_t b;
442 mpz_init (b);
443 mpz_set_ui (b, ui);
444 mpz_sub (r, a, b);
445 mpz_clear (b);
448 void
449 mpz_mul (mpz_t r, mpz_t a, mpz_t b)
451 int an = ABSIZ (a), bn = ABSIZ (b), rn;
452 mp_limb_t *scratch, *tmp, *ap = PTR (a), *bp = PTR (b);
453 int ai, bi;
454 mp_limb_t t, cy;
456 scratch = xmalloc_limbs (an + bn);
457 tmp = scratch;
459 for (bi = 0; bi < bn; bi++)
460 tmp[bi] = 0;
462 for (ai = 0; ai < an; ai++)
464 tmp = scratch + ai;
465 cy = 0;
466 for (bi = 0; bi < bn; bi++)
468 t = ap[ai] * bp[bi] + tmp[bi] + cy;
469 tmp[bi] = LO (t);
470 cy = HI (t);
472 tmp[bn] = cy;
475 rn = an + bn;
476 mpn_normalize (scratch, &rn);
477 free (PTR (r));
478 PTR (r) = scratch;
479 SIZ (r) = (SIZ (a) ^ SIZ (b)) >= 0 ? rn : -rn;
480 ALLOC (r) = an + bn;
483 void
484 mpz_mul_ui (mpz_t r, mpz_t a, unsigned long int ui)
486 mpz_t b;
488 mpz_init (b);
489 mpz_set_ui (b, ui);
490 mpz_mul (r, a, b);
491 mpz_clear (b);
494 void
495 mpz_mul_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
497 mpz_set (r, a);
498 while (bcnt)
500 mpz_add (r, r, r);
501 bcnt -= 1;
505 void
506 mpz_ui_pow_ui (mpz_t r, unsigned long b, unsigned long e)
508 unsigned long i;
509 mpz_t bz;
511 mpz_init (bz);
512 mpz_set_ui (bz, b);
514 mpz_set_ui (r, 1L);
515 for (i = 0; i < e; i++)
516 mpz_mul (r, r, bz);
518 mpz_clear (bz);
521 void
522 mpz_tdiv_q_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
524 int as, rn;
525 int cnt, tnc;
526 int lcnt;
527 mp_limb_t high_limb, low_limb;
528 int i;
530 as = SIZ (a);
531 lcnt = bcnt / GMP_LIMB_BITS;
532 rn = ABS (as) - lcnt;
533 if (rn <= 0)
534 SIZ (r) = 0;
535 else
537 mp_limb_t *rp, *ap;
539 mpz_realloc (r, rn);
541 rp = PTR (r);
542 ap = PTR (a);
544 cnt = bcnt % GMP_LIMB_BITS;
545 if (cnt != 0)
547 ap += lcnt;
548 tnc = GMP_LIMB_BITS - cnt;
549 high_limb = *ap++;
550 low_limb = high_limb >> cnt;
552 for (i = rn - 1; i != 0; i--)
554 high_limb = *ap++;
555 *rp++ = low_limb | LO (high_limb << tnc);
556 low_limb = high_limb >> cnt;
558 *rp = low_limb;
559 rn -= low_limb == 0;
561 else
563 ap += lcnt;
564 mpn_copyi (rp, ap, rn);
567 SIZ (r) = as >= 0 ? rn : -rn;
571 void
572 mpz_tdiv_r_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
574 int rn, bwhole;
576 mpz_set (r, a);
577 rn = ABSIZ(r);
579 bwhole = bcnt / GMP_LIMB_BITS;
580 bcnt %= GMP_LIMB_BITS;
581 if (rn > bwhole)
583 rn = bwhole+1;
584 PTR(r)[rn-1] &= ((mp_limb_t) 1 << bcnt) - 1;
585 mpn_normalize (PTR(r), &rn);
586 SIZ(r) = (SIZ(r) >= 0 ? rn : -rn);
591 mpz_cmp (mpz_t a, mpz_t b)
593 mp_limb_t *ap, *bp, al, bl;
594 int as = SIZ (a), bs = SIZ (b);
595 int i;
596 int sign;
598 if (as != bs)
599 return as > bs ? 1 : -1;
601 sign = as > 0 ? 1 : -1;
603 ap = PTR (a);
604 bp = PTR (b);
605 for (i = ABS (as) - 1; i >= 0; i--)
607 al = ap[i];
608 bl = bp[i];
609 if (al != bl)
610 return al > bl ? sign : -sign;
612 return 0;
616 mpz_cmp_ui (mpz_t a, unsigned long b)
618 mpz_t bz;
619 int ret;
620 mpz_init_set_ui (bz, b);
621 ret = mpz_cmp (a, bz);
622 mpz_clear (bz);
623 return ret;
626 void
627 mpz_tdiv_qr (mpz_t q, mpz_t r, mpz_t a, mpz_t b)
629 mpz_t tmpr, tmpb;
630 unsigned long cnt;
632 ASSERT (mpz_sgn(a) >= 0);
633 ASSERT (mpz_sgn(b) > 0);
635 mpz_init_set (tmpr, a);
636 mpz_init_set (tmpb, b);
637 mpz_set_ui (q, 0L);
639 if (mpz_cmp (tmpr, tmpb) > 0)
641 cnt = mpz_sizeinbase (tmpr, 2) - mpz_sizeinbase (tmpb, 2) + 1;
642 mpz_mul_2exp (tmpb, tmpb, cnt);
644 for ( ; cnt > 0; cnt--)
646 mpz_mul_2exp (q, q, 1);
647 mpz_tdiv_q_2exp (tmpb, tmpb, 1L);
648 if (mpz_cmp (tmpr, tmpb) >= 0)
650 mpz_sub (tmpr, tmpr, tmpb);
651 mpz_add_ui (q, q, 1L);
652 ASSERT (mpz_cmp (tmpr, tmpb) < 0);
657 mpz_set (r, tmpr);
658 mpz_clear (tmpr);
659 mpz_clear (tmpb);
662 void
663 mpz_tdiv_qr_ui (mpz_t q, mpz_t r, mpz_t a, unsigned long b)
665 mpz_t bz;
666 mpz_init_set_ui (bz, b);
667 mpz_tdiv_qr (q, r, a, bz);
668 mpz_clear (bz);
671 void
672 mpz_tdiv_q (mpz_t q, mpz_t a, mpz_t b)
674 mpz_t r;
676 mpz_init (r);
677 mpz_tdiv_qr (q, r, a, b);
678 mpz_clear (r);
681 void
682 mpz_tdiv_q_ui (mpz_t q, mpz_t n, unsigned long d)
684 mpz_t dz;
685 mpz_init_set_ui (dz, d);
686 mpz_tdiv_q (q, n, dz);
687 mpz_clear (dz);
690 /* Set inv to the inverse of d, in the style of invert_limb, ie. for
691 udiv_qrnnd_preinv. */
692 void
693 mpz_preinv_invert (mpz_t inv, mpz_t d, int numb_bits)
695 mpz_t t;
696 int norm;
697 ASSERT (SIZ(d) > 0);
699 norm = numb_bits - mpz_sizeinbase (d, 2);
700 ASSERT (norm >= 0);
701 mpz_init_set_ui (t, 1L);
702 mpz_mul_2exp (t, t, 2*numb_bits - norm);
703 mpz_tdiv_q (inv, t, d);
704 mpz_set_ui (t, 1L);
705 mpz_mul_2exp (t, t, numb_bits);
706 mpz_sub (inv, inv, t);
708 mpz_clear (t);
711 /* Remove leading '0' characters from the start of a string, by copying the
712 remainder down. */
713 void
714 strstrip_leading_zeros (char *s)
716 char c, *p;
718 p = s;
719 while (*s == '0')
720 s++;
724 c = *s++;
725 *p++ = c;
727 while (c != '\0');
730 char *
731 mpz_get_str (char *buf, int base, mpz_t a)
733 static char tohex[] = "0123456789abcdef";
735 mp_limb_t alimb, *ap;
736 int an, bn, i, j;
737 char *bp;
739 if (base != 16)
740 abort ();
741 if (SIZ (a) < 0)
742 abort ();
744 if (buf == 0)
745 buf = xmalloc (ABSIZ (a) * (GMP_LIMB_BITS / 4) + 3);
747 an = ABSIZ (a);
748 if (an == 0)
750 buf[0] = '0';
751 buf[1] = '\0';
752 return buf;
755 ap = PTR (a);
756 bn = an * (GMP_LIMB_BITS / 4);
757 bp = buf + bn;
759 for (i = 0; i < an; i++)
761 alimb = ap[i];
762 for (j = 0; j < GMP_LIMB_BITS / 4; j++)
764 bp--;
765 *bp = tohex [alimb & 0xF];
766 alimb >>= 4;
768 ASSERT (alimb == 0);
770 ASSERT (bp == buf);
772 buf[bn] = '\0';
774 strstrip_leading_zeros (buf);
775 return buf;
778 void
779 mpz_out_str (FILE *file, int base, mpz_t a)
781 char *str;
783 if (file == 0)
784 file = stdout;
786 str = mpz_get_str (0, 16, a);
787 fputs (str, file);
788 free (str);
791 /* Calculate r satisfying r*d == 1 mod 2^n. */
792 void
793 mpz_invert_2exp (mpz_t r, mpz_t a, unsigned long n)
795 unsigned long i;
796 mpz_t inv, prod;
798 ASSERT (mpz_odd_p (a));
800 mpz_init_set_ui (inv, 1L);
801 mpz_init (prod);
803 for (i = 1; i < n; i++)
805 mpz_mul (prod, inv, a);
806 if (mpz_tstbit (prod, i) != 0)
807 mpz_setbit (inv, i);
810 mpz_mul (prod, inv, a);
811 mpz_tdiv_r_2exp (prod, prod, n);
812 ASSERT (mpz_cmp_ui (prod, 1L) == 0);
814 mpz_set (r, inv);
816 mpz_clear (inv);
817 mpz_clear (prod);
820 /* Calculate inv satisfying r*a == 1 mod 2^n. */
821 void
822 mpz_invert_ui_2exp (mpz_t r, unsigned long a, unsigned long n)
824 mpz_t az;
825 mpz_init_set_ui (az, a);
826 mpz_invert_2exp (r, az, n);
827 mpz_clear (az);
830 /* x=y^z */
831 void
832 mpz_pow_ui (mpz_t x, mpz_t y, unsigned long z)
834 mpz_t t;
836 mpz_init_set_ui (t, 1);
837 for (; z != 0; z--)
838 mpz_mul (t, t, y);
839 mpz_set (x, t);
840 mpz_clear (t);
843 /* x=x+y*z */
844 void
845 mpz_addmul_ui (mpz_t x, mpz_t y, unsigned long z)
847 mpz_t t;
849 mpz_init (t);
850 mpz_mul_ui (t, y, z);
851 mpz_add (x, x, t);
852 mpz_clear (t);
855 /* x=floor(y^(1/z)) */
856 void
857 mpz_root (mpz_t x, mpz_t y, unsigned long z)
859 mpz_t t, u;
861 if (mpz_sgn (y) < 0)
863 fprintf (stderr, "mpz_root does not accept negative values\n");
864 abort ();
866 if (mpz_cmp_ui (y, 1) <= 0)
868 mpz_set (x, y);
869 return;
871 mpz_init (t);
872 mpz_init_set (u, y);
875 mpz_pow_ui (t, u, z - 1);
876 mpz_tdiv_q (t, y, t);
877 mpz_addmul_ui (t, u, z - 1);
878 mpz_tdiv_q_ui (t, t, z);
879 if (mpz_cmp (t, u) >= 0)
880 break;
881 mpz_set (u, t);
883 while (1);
884 mpz_set (x, u);
885 mpz_clear (t);
886 mpz_clear (u);