kernel - Use GDF_VIRTUSER to help measure user% in the vkernel host
[dragonfly.git] / contrib / gmp / dumbmp.c
blobc87aae451cd3bdd005847efbfa4538480b3c7bf5
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];
104 static int
105 isprime (unsigned long int t)
107 unsigned long int q, r, d;
109 if (t < 32)
110 return (0xa08a28acUL >> t) & 1;
111 if ((t & 1) == 0)
112 return 0;
114 if (t % 3 == 0)
115 return 0;
116 if (t % 5 == 0)
117 return 0;
118 if (t % 7 == 0)
119 return 0;
121 for (d = 11;;)
123 q = t / d;
124 r = t - q * d;
125 if (q < d)
126 return 1;
127 if (r == 0)
128 break;
129 d += 2;
130 q = t / d;
131 r = t - q * d;
132 if (q < d)
133 return 1;
134 if (r == 0)
135 break;
136 d += 4;
138 return 0;
142 log2_ceil (int n)
144 int e;
145 ASSERT (n >= 1);
146 for (e = 0; ; e++)
147 if ((1 << e) >= n)
148 break;
149 return e;
152 void
153 mpz_realloc (mpz_t r, int n)
155 if (n <= ALLOC(r))
156 return;
158 ALLOC(r) = n;
159 PTR(r) = (mp_limb_t *) realloc (PTR(r), n * sizeof (mp_limb_t));
160 if (PTR(r) == NULL)
162 fprintf (stderr, "Out of memory (realloc to %d)\n", n);
163 abort ();
167 void
168 mpn_normalize (mp_limb_t *rp, int *rnp)
170 int rn = *rnp;
171 while (rn > 0 && rp[rn-1] == 0)
172 rn--;
173 *rnp = rn;
176 void
177 mpn_copyi (mp_limb_t *dst, mp_limb_t *src, int n)
179 int i;
180 for (i = 0; i < n; i++)
181 dst[i] = src[i];
184 void
185 mpn_zero (mp_limb_t *rp, int rn)
187 int i;
188 for (i = 0; i < rn; i++)
189 rp[i] = 0;
192 void
193 mpz_init (mpz_t r)
195 ALLOC(r) = 1;
196 PTR(r) = xmalloc_limbs (ALLOC(r));
197 PTR(r)[0] = 0;
198 SIZ(r) = 0;
201 void
202 mpz_clear (mpz_t r)
204 free (PTR (r));
205 ALLOC(r) = -1;
206 SIZ (r) = 0xbadcafeL;
207 PTR (r) = (mp_limb_t *) 0xdeadbeefL;
211 mpz_sgn (mpz_t a)
213 return (SIZ(a) > 0 ? 1 : SIZ(a) == 0 ? 0 : -1);
217 mpz_odd_p (mpz_t a)
219 if (SIZ(a) == 0)
220 return 0;
221 else
222 return (PTR(a)[0] & 1) != 0;
226 mpz_even_p (mpz_t a)
228 if (SIZ(a) == 0)
229 return 1;
230 else
231 return (PTR(a)[0] & 1) == 0;
234 size_t
235 mpz_sizeinbase (mpz_t a, int base)
237 int an = ABSIZ (a);
238 mp_limb_t *ap = PTR (a);
239 int cnt;
240 mp_limb_t hi;
242 if (base != 2)
243 abort ();
245 if (an == 0)
246 return 1;
248 cnt = 0;
249 for (hi = ap[an - 1]; hi != 0; hi >>= 1)
250 cnt += 1;
251 return (an - 1) * GMP_LIMB_BITS + cnt;
254 void
255 mpz_set (mpz_t r, mpz_t a)
257 mpz_realloc (r, ABSIZ (a));
258 SIZ(r) = SIZ(a);
259 mpn_copyi (PTR(r), PTR(a), ABSIZ (a));
262 void
263 mpz_init_set (mpz_t r, mpz_t a)
265 mpz_init (r);
266 mpz_set (r, a);
269 void
270 mpz_set_ui (mpz_t r, unsigned long ui)
272 int rn;
273 mpz_realloc (r, 2);
274 PTR(r)[0] = LO(ui);
275 PTR(r)[1] = HI(ui);
276 rn = 2;
277 mpn_normalize (PTR(r), &rn);
278 SIZ(r) = rn;
281 void
282 mpz_init_set_ui (mpz_t r, unsigned long ui)
284 mpz_init (r);
285 mpz_set_ui (r, ui);
288 void
289 mpz_setbit (mpz_t r, unsigned long bit)
291 int limb, rn, extend;
292 mp_limb_t *rp;
294 rn = SIZ(r);
295 if (rn < 0)
296 abort (); /* only r>=0 */
298 limb = bit / GMP_LIMB_BITS;
299 bit %= GMP_LIMB_BITS;
301 mpz_realloc (r, limb+1);
302 rp = PTR(r);
303 extend = (limb+1) - rn;
304 if (extend > 0)
305 mpn_zero (rp + rn, extend);
307 rp[limb] |= (mp_limb_t) 1 << bit;
308 SIZ(r) = MAX (rn, limb+1);
312 mpz_tstbit (mpz_t r, unsigned long bit)
314 int limb;
316 if (SIZ(r) < 0)
317 abort (); /* only r>=0 */
319 limb = bit / GMP_LIMB_BITS;
320 if (SIZ(r) <= limb)
321 return 0;
323 bit %= GMP_LIMB_BITS;
324 return (PTR(r)[limb] >> bit) & 1;
328 popc_limb (mp_limb_t a)
330 int ret = 0;
331 while (a != 0)
333 ret += (a & 1);
334 a >>= 1;
336 return ret;
339 unsigned long
340 mpz_popcount (mpz_t a)
342 unsigned long ret;
343 int i;
345 if (SIZ(a) < 0)
346 abort ();
348 ret = 0;
349 for (i = 0; i < SIZ(a); i++)
350 ret += popc_limb (PTR(a)[i]);
351 return ret;
354 void
355 mpz_add (mpz_t r, mpz_t a, mpz_t b)
357 int an = ABSIZ (a), bn = ABSIZ (b), rn;
358 mp_limb_t *rp, *ap, *bp;
359 int i;
360 mp_limb_t t, cy;
362 if ((SIZ (a) ^ SIZ (b)) < 0)
363 abort (); /* really subtraction */
364 if (SIZ (a) < 0)
365 abort ();
367 mpz_realloc (r, MAX (an, bn) + 1);
368 ap = PTR (a); bp = PTR (b); rp = PTR (r);
369 if (an < bn)
371 mp_limb_t *tp; int tn;
372 tn = an; an = bn; bn = tn;
373 tp = ap; ap = bp; bp = tp;
376 cy = 0;
377 for (i = 0; i < bn; i++)
379 t = ap[i] + bp[i] + cy;
380 rp[i] = LO (t);
381 cy = HI (t);
383 for (i = bn; i < an; i++)
385 t = ap[i] + cy;
386 rp[i] = LO (t);
387 cy = HI (t);
389 rp[an] = cy;
390 rn = an + 1;
392 mpn_normalize (rp, &rn);
393 SIZ (r) = rn;
396 void
397 mpz_add_ui (mpz_t r, mpz_t a, unsigned long int ui)
399 mpz_t b;
401 mpz_init (b);
402 mpz_set_ui (b, ui);
403 mpz_add (r, a, b);
404 mpz_clear (b);
407 void
408 mpz_sub (mpz_t r, mpz_t a, mpz_t b)
410 int an = ABSIZ (a), bn = ABSIZ (b), rn;
411 mp_limb_t *rp, *ap, *bp;
412 int i;
413 mp_limb_t t, cy;
415 if ((SIZ (a) ^ SIZ (b)) < 0)
416 abort (); /* really addition */
417 if (SIZ (a) < 0)
418 abort ();
420 mpz_realloc (r, MAX (an, bn) + 1);
421 ap = PTR (a); bp = PTR (b); rp = PTR (r);
422 if (an < bn)
424 mp_limb_t *tp; int tn;
425 tn = an; an = bn; bn = tn;
426 tp = ap; ap = bp; bp = tp;
429 cy = 0;
430 for (i = 0; i < bn; i++)
432 t = ap[i] - bp[i] - cy;
433 rp[i] = LO (t);
434 cy = LO (-HI (t));
436 for (i = bn; i < an; i++)
438 t = ap[i] - cy;
439 rp[i] = LO (t);
440 cy = LO (-HI (t));
442 rp[an] = cy;
443 rn = an + 1;
445 if (cy != 0)
447 cy = 0;
448 for (i = 0; i < rn; i++)
450 t = -rp[i] - cy;
451 rp[i] = LO (t);
452 cy = LO (-HI (t));
454 SIZ (r) = -rn;
455 return;
458 mpn_normalize (rp, &rn);
459 SIZ (r) = rn;
462 void
463 mpz_sub_ui (mpz_t r, mpz_t a, unsigned long int ui)
465 mpz_t b;
467 mpz_init (b);
468 mpz_set_ui (b, ui);
469 mpz_sub (r, a, b);
470 mpz_clear (b);
473 void
474 mpz_mul (mpz_t r, mpz_t a, mpz_t b)
476 int an = ABSIZ (a), bn = ABSIZ (b), rn;
477 mp_limb_t *scratch, *tmp, *ap = PTR (a), *bp = PTR (b);
478 int ai, bi;
479 mp_limb_t t, cy;
481 scratch = xmalloc_limbs (an + bn);
482 tmp = scratch;
484 for (bi = 0; bi < bn; bi++)
485 tmp[bi] = 0;
487 for (ai = 0; ai < an; ai++)
489 tmp = scratch + ai;
490 cy = 0;
491 for (bi = 0; bi < bn; bi++)
493 t = ap[ai] * bp[bi] + tmp[bi] + cy;
494 tmp[bi] = LO (t);
495 cy = HI (t);
497 tmp[bn] = cy;
500 rn = an + bn;
501 mpn_normalize (scratch, &rn);
502 free (PTR (r));
503 PTR (r) = scratch;
504 SIZ (r) = (SIZ (a) ^ SIZ (b)) >= 0 ? rn : -rn;
505 ALLOC (r) = an + bn;
508 void
509 mpz_mul_ui (mpz_t r, mpz_t a, unsigned long int ui)
511 mpz_t b;
513 mpz_init (b);
514 mpz_set_ui (b, ui);
515 mpz_mul (r, a, b);
516 mpz_clear (b);
519 void
520 mpz_mul_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
522 mpz_set (r, a);
523 while (bcnt)
525 mpz_add (r, r, r);
526 bcnt -= 1;
530 void
531 mpz_ui_pow_ui (mpz_t r, unsigned long b, unsigned long e)
533 unsigned long i;
534 mpz_t bz;
536 mpz_init (bz);
537 mpz_set_ui (bz, b);
539 mpz_set_ui (r, 1L);
540 for (i = 0; i < e; i++)
541 mpz_mul (r, r, bz);
543 mpz_clear (bz);
546 void
547 mpz_tdiv_q_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
549 int as, rn;
550 int cnt, tnc;
551 int lcnt;
552 mp_limb_t high_limb, low_limb;
553 int i;
555 as = SIZ (a);
556 lcnt = bcnt / GMP_LIMB_BITS;
557 rn = ABS (as) - lcnt;
558 if (rn <= 0)
559 SIZ (r) = 0;
560 else
562 mp_limb_t *rp, *ap;
564 mpz_realloc (r, rn);
566 rp = PTR (r);
567 ap = PTR (a);
569 cnt = bcnt % GMP_LIMB_BITS;
570 if (cnt != 0)
572 ap += lcnt;
573 tnc = GMP_LIMB_BITS - cnt;
574 high_limb = *ap++;
575 low_limb = high_limb >> cnt;
577 for (i = rn - 1; i != 0; i--)
579 high_limb = *ap++;
580 *rp++ = low_limb | LO (high_limb << tnc);
581 low_limb = high_limb >> cnt;
583 *rp = low_limb;
584 rn -= low_limb == 0;
586 else
588 ap += lcnt;
589 mpn_copyi (rp, ap, rn);
592 SIZ (r) = as >= 0 ? rn : -rn;
596 void
597 mpz_tdiv_r_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
599 int rn, bwhole;
601 mpz_set (r, a);
602 rn = ABSIZ(r);
604 bwhole = bcnt / GMP_LIMB_BITS;
605 bcnt %= GMP_LIMB_BITS;
606 if (rn > bwhole)
608 rn = bwhole+1;
609 PTR(r)[rn-1] &= ((mp_limb_t) 1 << bcnt) - 1;
610 mpn_normalize (PTR(r), &rn);
611 SIZ(r) = (SIZ(r) >= 0 ? rn : -rn);
616 mpz_cmp (mpz_t a, mpz_t b)
618 mp_limb_t *ap, *bp, al, bl;
619 int as = SIZ (a), bs = SIZ (b);
620 int i;
621 int sign;
623 if (as != bs)
624 return as > bs ? 1 : -1;
626 sign = as > 0 ? 1 : -1;
628 ap = PTR (a);
629 bp = PTR (b);
630 for (i = ABS (as) - 1; i >= 0; i--)
632 al = ap[i];
633 bl = bp[i];
634 if (al != bl)
635 return al > bl ? sign : -sign;
637 return 0;
641 mpz_cmp_ui (mpz_t a, unsigned long b)
643 mpz_t bz;
644 int ret;
645 mpz_init_set_ui (bz, b);
646 ret = mpz_cmp (a, bz);
647 mpz_clear (bz);
648 return ret;
651 void
652 mpz_tdiv_qr (mpz_t q, mpz_t r, mpz_t a, mpz_t b)
654 mpz_t tmpr, tmpb;
655 unsigned long cnt;
657 ASSERT (mpz_sgn(a) >= 0);
658 ASSERT (mpz_sgn(b) > 0);
660 mpz_init_set (tmpr, a);
661 mpz_init_set (tmpb, b);
662 mpz_set_ui (q, 0L);
664 if (mpz_cmp (tmpr, tmpb) > 0)
666 cnt = mpz_sizeinbase (tmpr, 2) - mpz_sizeinbase (tmpb, 2) + 1;
667 mpz_mul_2exp (tmpb, tmpb, cnt);
669 for ( ; cnt > 0; cnt--)
671 mpz_mul_2exp (q, q, 1);
672 mpz_tdiv_q_2exp (tmpb, tmpb, 1L);
673 if (mpz_cmp (tmpr, tmpb) >= 0)
675 mpz_sub (tmpr, tmpr, tmpb);
676 mpz_add_ui (q, q, 1L);
677 ASSERT (mpz_cmp (tmpr, tmpb) < 0);
682 mpz_set (r, tmpr);
683 mpz_clear (tmpr);
684 mpz_clear (tmpb);
687 void
688 mpz_tdiv_qr_ui (mpz_t q, mpz_t r, mpz_t a, unsigned long b)
690 mpz_t bz;
691 mpz_init_set_ui (bz, b);
692 mpz_tdiv_qr (q, r, a, bz);
693 mpz_clear (bz);
696 void
697 mpz_tdiv_q (mpz_t q, mpz_t a, mpz_t b)
699 mpz_t r;
701 mpz_init (r);
702 mpz_tdiv_qr (q, r, a, b);
703 mpz_clear (r);
706 void
707 mpz_tdiv_r (mpz_t r, mpz_t a, mpz_t b)
709 mpz_t q;
711 mpz_init (q);
712 mpz_tdiv_qr (q, r, a, b);
713 mpz_clear (q);
716 void
717 mpz_tdiv_q_ui (mpz_t q, mpz_t n, unsigned long d)
719 mpz_t dz;
720 mpz_init_set_ui (dz, d);
721 mpz_tdiv_q (q, n, dz);
722 mpz_clear (dz);
725 /* Set inv to the inverse of d, in the style of invert_limb, ie. for
726 udiv_qrnnd_preinv. */
727 void
728 mpz_preinv_invert (mpz_t inv, mpz_t d, int numb_bits)
730 mpz_t t;
731 int norm;
732 ASSERT (SIZ(d) > 0);
734 norm = numb_bits - mpz_sizeinbase (d, 2);
735 ASSERT (norm >= 0);
736 mpz_init_set_ui (t, 1L);
737 mpz_mul_2exp (t, t, 2*numb_bits - norm);
738 mpz_tdiv_q (inv, t, d);
739 mpz_set_ui (t, 1L);
740 mpz_mul_2exp (t, t, numb_bits);
741 mpz_sub (inv, inv, t);
743 mpz_clear (t);
746 /* Remove leading '0' characters from the start of a string, by copying the
747 remainder down. */
748 void
749 strstrip_leading_zeros (char *s)
751 char c, *p;
753 p = s;
754 while (*s == '0')
755 s++;
759 c = *s++;
760 *p++ = c;
762 while (c != '\0');
765 char *
766 mpz_get_str (char *buf, int base, mpz_t a)
768 static char tohex[] = "0123456789abcdef";
770 mp_limb_t alimb, *ap;
771 int an, bn, i, j;
772 char *bp;
774 if (base != 16)
775 abort ();
776 if (SIZ (a) < 0)
777 abort ();
779 if (buf == 0)
780 buf = xmalloc (ABSIZ (a) * (GMP_LIMB_BITS / 4) + 3);
782 an = ABSIZ (a);
783 if (an == 0)
785 buf[0] = '0';
786 buf[1] = '\0';
787 return buf;
790 ap = PTR (a);
791 bn = an * (GMP_LIMB_BITS / 4);
792 bp = buf + bn;
794 for (i = 0; i < an; i++)
796 alimb = ap[i];
797 for (j = 0; j < GMP_LIMB_BITS / 4; j++)
799 bp--;
800 *bp = tohex [alimb & 0xF];
801 alimb >>= 4;
803 ASSERT (alimb == 0);
805 ASSERT (bp == buf);
807 buf[bn] = '\0';
809 strstrip_leading_zeros (buf);
810 return buf;
813 void
814 mpz_out_str (FILE *file, int base, mpz_t a)
816 char *str;
818 if (file == 0)
819 file = stdout;
821 str = mpz_get_str (0, 16, a);
822 fputs (str, file);
823 free (str);
826 /* Calculate r satisfying r*d == 1 mod 2^n. */
827 void
828 mpz_invert_2exp (mpz_t r, mpz_t a, unsigned long n)
830 unsigned long i;
831 mpz_t inv, prod;
833 ASSERT (mpz_odd_p (a));
835 mpz_init_set_ui (inv, 1L);
836 mpz_init (prod);
838 for (i = 1; i < n; i++)
840 mpz_mul (prod, inv, a);
841 if (mpz_tstbit (prod, i) != 0)
842 mpz_setbit (inv, i);
845 mpz_mul (prod, inv, a);
846 mpz_tdiv_r_2exp (prod, prod, n);
847 ASSERT (mpz_cmp_ui (prod, 1L) == 0);
849 mpz_set (r, inv);
851 mpz_clear (inv);
852 mpz_clear (prod);
855 /* Calculate inv satisfying r*a == 1 mod 2^n. */
856 void
857 mpz_invert_ui_2exp (mpz_t r, unsigned long a, unsigned long n)
859 mpz_t az;
860 mpz_init_set_ui (az, a);
861 mpz_invert_2exp (r, az, n);
862 mpz_clear (az);
865 /* x=y^z */
866 void
867 mpz_pow_ui (mpz_t x, mpz_t y, unsigned long z)
869 mpz_t t;
871 mpz_init_set_ui (t, 1);
872 for (; z != 0; z--)
873 mpz_mul (t, t, y);
874 mpz_set (x, t);
875 mpz_clear (t);
878 /* x=x+y*z */
879 void
880 mpz_addmul_ui (mpz_t x, mpz_t y, unsigned long z)
882 mpz_t t;
884 mpz_init (t);
885 mpz_mul_ui (t, y, z);
886 mpz_add (x, x, t);
887 mpz_clear (t);
890 /* x=floor(y^(1/z)) */
891 void
892 mpz_root (mpz_t x, mpz_t y, unsigned long z)
894 mpz_t t, u;
896 if (mpz_sgn (y) < 0)
898 fprintf (stderr, "mpz_root does not accept negative values\n");
899 abort ();
901 if (mpz_cmp_ui (y, 1) <= 0)
903 mpz_set (x, y);
904 return;
906 mpz_init (t);
907 mpz_init_set (u, y);
910 mpz_pow_ui (t, u, z - 1);
911 mpz_tdiv_q (t, y, t);
912 mpz_addmul_ui (t, u, z - 1);
913 mpz_tdiv_q_ui (t, t, z);
914 if (mpz_cmp (t, u) >= 0)
915 break;
916 mpz_set (u, t);
918 while (1);
919 mpz_set (x, u);
920 mpz_clear (t);
921 mpz_clear (u);