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 2.1 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; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 /* The code here implements a subset (a very limited subset) of the main GMP
24 functions. It's designed for use in a few build-time calculations and
25 will be slow, but highly portable.
27 None of the normal GMP configure things are used, nor any of the normal
28 gmp.h or gmp-impl.h. To use this file in a program just #include
31 ANSI function definitions can be used here, since ansi2knr is run if
32 necessary. But other ANSI-isms like "const" should be avoided.
34 mp_limb_t here is an unsigned long, since that's a sensible type
35 everywhere we know of, with 8*sizeof(unsigned long) giving the number of
36 bits in the type (that not being true for instance with int or short on
39 Only the low half of each mp_limb_t is used, so as to make carry handling
40 and limb multiplies easy. GMP_LIMB_BITS is the number of bits used. */
47 typedef unsigned long mp_limb_t;
55 #define GMP_LIMB_BITS (sizeof (mp_limb_t) * 8 / 2)
57 #define ABS(x) ((x) >= 0 ? (x) : -(x))
58 #define MIN(l,o) ((l) < (o) ? (l) : (o))
59 #define MAX(h,i) ((h) > (i) ? (h) : (i))
61 #define ALLOC(x) ((x)->_mp_alloc)
62 #define PTR(x) ((x)->_mp_d)
63 #define SIZ(x) ((x)->_mp_size)
64 #define ABSIZ(x) ABS (SIZ (x))
65 #define LOMASK ((1L << GMP_LIMB_BITS) - 1)
66 #define LO(x) ((x) & LOMASK)
67 #define HI(x) ((x) >> GMP_LIMB_BITS)
69 #define ASSERT(cond) \
73 fprintf (stderr, "Assertion failure\n"); \
86 fprintf (stderr, "Out of memory (alloc %d bytes)\n", n);
95 return (mp_limb_t *) xmalloc (n * sizeof (mp_limb_t));
99 mem_copyi (char *dst, char *src, int size)
102 for (i = 0; i < size; i++)
112 for (i = 2; i < n; i++)
130 mpz_realloc (mpz_t r, int n)
136 PTR(r) = (mp_limb_t *) realloc (PTR(r), n * sizeof (mp_limb_t));
139 fprintf (stderr, "Out of memory (realloc to %d)\n", n);
145 mpn_normalize (mp_limb_t *rp, int *rnp)
148 while (rn > 0 && rp[rn-1] == 0)
154 mpn_copyi (mp_limb_t *dst, mp_limb_t *src, int n)
157 for (i = 0; i < n; i++)
162 mpn_zero (mp_limb_t *rp, int rn)
165 for (i = 0; i < rn; i++)
173 PTR(r) = xmalloc_limbs (ALLOC(r));
183 SIZ (r) = 0xbadcafeL;
184 PTR (r) = (mp_limb_t *) 0xdeadbeefL;
190 return (SIZ(a) > 0 ? 1 : SIZ(a) == 0 ? 0 : -1);
199 return (PTR(a)[0] & 1) != 0;
208 return (PTR(a)[0] & 1) == 0;
212 mpz_sizeinbase (mpz_t a, int base)
215 mp_limb_t *ap = PTR (a);
226 for (hi = ap[an - 1]; hi != 0; hi >>= 1)
228 return (an - 1) * GMP_LIMB_BITS + cnt;
232 mpz_set (mpz_t r, mpz_t a)
234 mpz_realloc (r, ABSIZ (a));
236 mpn_copyi (PTR(r), PTR(a), ABSIZ (a));
240 mpz_init_set (mpz_t r, mpz_t a)
247 mpz_set_ui (mpz_t r, unsigned long ui)
254 mpn_normalize (PTR(r), &rn);
259 mpz_init_set_ui (mpz_t r, unsigned long ui)
266 mpz_setbit (mpz_t r, unsigned long bit)
268 int limb, rn, extend;
273 abort (); /* only r>=0 */
275 limb = bit / GMP_LIMB_BITS;
276 bit %= GMP_LIMB_BITS;
278 mpz_realloc (r, limb+1);
280 extend = (limb+1) - rn;
282 mpn_zero (rp + rn, extend);
284 rp[limb] |= (mp_limb_t) 1 << bit;
285 SIZ(r) = MAX (rn, limb+1);
289 mpz_tstbit (mpz_t r, unsigned long bit)
294 abort (); /* only r>=0 */
296 limb = bit / GMP_LIMB_BITS;
300 bit %= GMP_LIMB_BITS;
301 return (PTR(r)[limb] >> bit) & 1;
305 popc_limb (mp_limb_t a)
317 mpz_popcount (mpz_t a)
326 for (i = 0; i < SIZ(a); i++)
327 ret += popc_limb (PTR(a)[i]);
332 mpz_add (mpz_t r, mpz_t a, mpz_t b)
334 int an = ABSIZ (a), bn = ABSIZ (b), rn;
335 mp_limb_t *rp, *ap, *bp;
339 if ((SIZ (a) ^ SIZ (b)) < 0)
340 abort (); /* really subtraction */
344 mpz_realloc (r, MAX (an, bn) + 1);
345 ap = PTR (a); bp = PTR (b); rp = PTR (r);
348 mp_limb_t *tp; int tn;
349 tn = an; an = bn; bn = tn;
350 tp = ap; ap = bp; bp = tp;
354 for (i = 0; i < bn; i++)
356 t = ap[i] + bp[i] + cy;
360 for (i = bn; i < an; i++)
369 mpn_normalize (rp, &rn);
374 mpz_add_ui (mpz_t r, mpz_t a, unsigned long int ui)
385 mpz_sub (mpz_t r, mpz_t a, mpz_t b)
387 int an = ABSIZ (a), bn = ABSIZ (b), rn;
388 mp_limb_t *rp, *ap, *bp;
392 if ((SIZ (a) ^ SIZ (b)) < 0)
393 abort (); /* really addition */
397 mpz_realloc (r, MAX (an, bn) + 1);
398 ap = PTR (a); bp = PTR (b); rp = PTR (r);
401 mp_limb_t *tp; int tn;
402 tn = an; an = bn; bn = tn;
403 tp = ap; ap = bp; bp = tp;
407 for (i = 0; i < bn; i++)
409 t = ap[i] - bp[i] - cy;
413 for (i = bn; i < an; i++)
425 for (i = 0; i < rn; i++)
435 mpn_normalize (rp, &rn);
440 mpz_sub_ui (mpz_t r, mpz_t a, unsigned long int ui)
451 mpz_mul (mpz_t r, mpz_t a, mpz_t b)
453 int an = ABSIZ (a), bn = ABSIZ (b), rn;
454 mp_limb_t *scratch, *tmp, *ap = PTR (a), *bp = PTR (b);
458 scratch = xmalloc_limbs (an + bn);
461 for (bi = 0; bi < bn; bi++)
464 for (ai = 0; ai < an; ai++)
468 for (bi = 0; bi < bn; bi++)
470 t = ap[ai] * bp[bi] + tmp[bi] + cy;
478 mpn_normalize (scratch, &rn);
481 SIZ (r) = (SIZ (a) ^ SIZ (b)) >= 0 ? rn : -rn;
486 mpz_mul_ui (mpz_t r, mpz_t a, unsigned long int ui)
497 mpz_mul_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
508 mpz_ui_pow_ui (mpz_t r, unsigned long b, unsigned long e)
517 for (i = 0; i < e; i++)
524 mpz_tdiv_q_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
529 mp_limb_t high_limb, low_limb;
533 lcnt = bcnt / GMP_LIMB_BITS;
534 rn = ABS (as) - lcnt;
546 cnt = bcnt % GMP_LIMB_BITS;
550 tnc = GMP_LIMB_BITS - cnt;
552 low_limb = high_limb >> cnt;
554 for (i = rn - 1; i != 0; i--)
557 *rp++ = low_limb | LO (high_limb << tnc);
558 low_limb = high_limb >> cnt;
566 mpn_copyi (rp, ap, rn);
569 SIZ (r) = as >= 0 ? rn : -rn;
574 mpz_tdiv_r_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
581 bwhole = bcnt / GMP_LIMB_BITS;
582 bcnt %= GMP_LIMB_BITS;
586 PTR(r)[rn-1] &= ((mp_limb_t) 1 << bcnt) - 1;
587 mpn_normalize (PTR(r), &rn);
588 SIZ(r) = (SIZ(r) >= 0 ? rn : -rn);
593 mpz_cmp (mpz_t a, mpz_t b)
595 mp_limb_t *ap, *bp, al, bl;
596 int as = SIZ (a), bs = SIZ (b);
601 return as > bs ? 1 : -1;
603 sign = as > 0 ? 1 : -1;
607 for (i = ABS (as) - 1; i >= 0; i--)
612 return al > bl ? sign : -sign;
618 mpz_cmp_ui (mpz_t a, unsigned long b)
622 mpz_init_set_ui (bz, b);
623 ret = mpz_cmp (a, bz);
629 mpz_tdiv_qr (mpz_t q, mpz_t r, mpz_t a, mpz_t b)
634 ASSERT (mpz_sgn(a) >= 0);
635 ASSERT (mpz_sgn(b) > 0);
637 mpz_init_set (tmpr, a);
638 mpz_init_set (tmpb, b);
641 if (mpz_cmp (tmpr, tmpb) > 0)
643 cnt = mpz_sizeinbase (tmpr, 2) - mpz_sizeinbase (tmpb, 2) + 1;
644 mpz_mul_2exp (tmpb, tmpb, cnt);
646 for ( ; cnt > 0; cnt--)
648 mpz_mul_2exp (q, q, 1);
649 mpz_tdiv_q_2exp (tmpb, tmpb, 1L);
650 if (mpz_cmp (tmpr, tmpb) >= 0)
652 mpz_sub (tmpr, tmpr, tmpb);
653 mpz_add_ui (q, q, 1L);
654 ASSERT (mpz_cmp (tmpr, tmpb) < 0);
665 mpz_tdiv_qr_ui (mpz_t q, mpz_t r, mpz_t a, unsigned long b)
668 mpz_init_set_ui (bz, b);
669 mpz_tdiv_qr (q, r, a, bz);
674 mpz_tdiv_q (mpz_t q, mpz_t a, mpz_t b)
679 mpz_tdiv_qr (q, r, a, b);
684 mpz_tdiv_q_ui (mpz_t q, mpz_t n, unsigned long d)
687 mpz_init_set_ui (dz, d);
688 mpz_tdiv_q (q, n, dz);
692 /* Set inv to the inverse of d, in the style of invert_limb, ie. for
693 udiv_qrnnd_preinv. */
695 mpz_preinv_invert (mpz_t inv, mpz_t d, int numb_bits)
701 norm = numb_bits - mpz_sizeinbase (d, 2);
703 mpz_init_set_ui (t, 1L);
704 mpz_mul_2exp (t, t, 2*numb_bits - norm);
705 mpz_tdiv_q (inv, t, d);
707 mpz_mul_2exp (t, t, numb_bits);
708 mpz_sub (inv, inv, t);
713 /* Remove leading '0' characters from the start of a string, by copying the
716 strstrip_leading_zeros (char *s)
733 mpz_get_str (char *buf, int base, mpz_t a)
735 static char tohex[] = "0123456789abcdef";
737 mp_limb_t alimb, *ap;
747 buf = xmalloc (ABSIZ (a) * (GMP_LIMB_BITS / 4) + 3);
758 bn = an * (GMP_LIMB_BITS / 4);
761 for (i = 0; i < an; i++)
764 for (j = 0; j < GMP_LIMB_BITS / 4; j++)
767 *bp = tohex [alimb & 0xF];
776 strstrip_leading_zeros (buf);
781 mpz_out_str (FILE *file, int base, mpz_t a)
788 str = mpz_get_str (0, 16, a);
793 /* Calculate r satisfying r*d == 1 mod 2^n. */
795 mpz_invert_2exp (mpz_t r, mpz_t a, unsigned long n)
800 ASSERT (mpz_odd_p (a));
802 mpz_init_set_ui (inv, 1L);
805 for (i = 1; i < n; i++)
807 mpz_mul (prod, inv, a);
808 if (mpz_tstbit (prod, i) != 0)
812 mpz_mul (prod, inv, a);
813 mpz_tdiv_r_2exp (prod, prod, n);
814 ASSERT (mpz_cmp_ui (prod, 1L) == 0);
822 /* Calculate inv satisfying r*a == 1 mod 2^n. */
824 mpz_invert_ui_2exp (mpz_t r, unsigned long a, unsigned long n)
827 mpz_init_set_ui (az, a);
828 mpz_invert_2exp (r, az, n);
834 mpz_pow_ui (mpz_t x, mpz_t y, unsigned long z)
838 mpz_init_set_ui (t, 1);
847 mpz_addmul_ui (mpz_t x, mpz_t y, unsigned long z)
852 mpz_mul_ui (t, y, z);
857 /* x=floor(y^(1/z)) */
859 mpz_root (mpz_t x, mpz_t y, unsigned long z)
865 fprintf (stderr, "mpz_root does not accept negative values\n");
868 if (mpz_cmp_ui (y, 1) <= 0)
877 mpz_pow_ui (t, u, z - 1);
878 mpz_tdiv_q (t, y, t);
879 mpz_addmul_ui (t, u, z - 1);
880 mpz_tdiv_q_ui (t, t, z);
881 if (mpz_cmp (t, u) >= 0)