1
1
/* Reference mpn functions, designed to be simple, portable and independent
2
2
of the normal gmp code. Speed isn't a consideration.
4
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free Software
4
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
5
Software Foundation, Inc.
7
7
This file is part of the GNU MP Library.
19
19
You should have received a copy of the GNU Lesser General Public License
20
20
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
21
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22
MA 02111-1307, USA. */
21
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22
MA 02110-1301, USA. */
25
25
/* Most routines have assertions representing what the mpn routines are
183
207
return (refmpn_msbone (x) << 1) - 1;
210
/* How many digits in the given base will fit in a limb.
211
Notice that the product b is allowed to be equal to the limit
212
2^GMP_NUMB_BITS, this ensures the result for base==2 will be
213
GMP_NUMB_BITS (and similarly other powers of 2). */
215
refmpn_chars_per_limb (int base)
217
mp_limb_t limit[2], b[2];
222
limit[0] = 0; /* limit = 2^GMP_NUMB_BITS */
224
b[0] = 1; /* b = 1 */
230
if (refmpn_mul_1 (b, b, (mp_size_t) 2, (mp_limb_t) base))
232
if (refmpn_cmp (b, limit, (mp_size_t) 2) > 0)
236
return chars_per_limb;
239
/* The biggest value base**n which fits in GMP_NUMB_BITS. */
241
refmpn_big_base (int base)
243
int chars_per_limb = refmpn_chars_per_limb (base);
249
for (i = 0; i < chars_per_limb; i++)
188
256
refmpn_setbit (mp_ptr ptr, unsigned long bit)
323
/* Copy {xp,xsize} to {wp,wsize}. If x is shorter, then pad w with low
324
zeros to wsize. If x is longer, then copy just the high wsize limbs. */
326
refmpn_copy_extend (mp_ptr wp, mp_size_t wsize, mp_srcptr xp, mp_size_t xsize)
331
/* high part of x if x bigger than w */
338
refmpn_copy (wp + wsize-xsize, xp, xsize);
339
refmpn_zero (wp, wsize-xsize);
256
343
refmpn_com_n (mp_ptr rp, mp_srcptr sp, mp_size_t size)
380
467
LOGOPS ((s1p[i] ^ s2p[i]) ^ GMP_NUMB_MASK);
471
/* set *dh,*dl to mh:ml - sh:sl, in full limbs */
473
refmpn_sub_ddmmss (mp_limb_t *dh, mp_limb_t *dl,
474
mp_limb_t mh, mp_limb_t ml, mp_limb_t sh, mp_limb_t sl)
477
*dh = mh - sh - (ml < sl);
383
481
/* set *w to x+y, return 0 or 1 carry */
385
add (mp_limb_t *w, mp_limb_t x, mp_limb_t y)
483
ref_addc_limb (mp_limb_t *w, mp_limb_t x, mp_limb_t y)
387
485
mp_limb_t sum, cy;
514
612
return refmpn_sub_nc (rp, s1p, s2p, size, CNST_LIMB(0));
616
refmpn_addlsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
621
ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
626
tp = refmpn_malloc_limbs (n);
627
cy = refmpn_lshift (tp, vp, n, 1);
628
cy += refmpn_add_n (rp, up, tp, n);
633
refmpn_sublsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
638
ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
643
tp = refmpn_malloc_limbs (n);
644
cy = mpn_lshift (tp, vp, n, 1);
645
cy += mpn_sub_n (rp, up, tp, n);
650
refmpn_rsh1add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
654
ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
659
cya = mpn_add_n (rp, up, vp, n);
660
cys = mpn_rshift (rp, rp, n, 1) >> (GMP_NUMB_BITS - 1);
661
rp[n - 1] |= cya << (GMP_NUMB_BITS - 1);
665
refmpn_rsh1sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
669
ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
674
cya = mpn_sub_n (rp, up, vp, n);
675
cys = mpn_rshift (rp, rp, n, 1) >> (GMP_NUMB_BITS - 1);
676
rp[n - 1] |= cya << (GMP_NUMB_BITS - 1);
518
680
/* Twos complement, return borrow. */
859
refmpn_addmul_N (mp_ptr dst, mp_srcptr src, mp_size_t size,
860
mp_srcptr mult, mp_size_t msize)
866
ASSERT (dst == src || ! refmpn_overlap_p (dst, size+msize-1, src, size));
867
ASSERT (! refmpn_overlap_p (dst, size+msize-1, mult, msize));
868
ASSERT (size >= msize);
869
ASSERT_MPN (mult, msize);
871
/* in case dst==src */
872
src_copy = refmpn_malloc_limbs (size);
873
refmpn_copyi (src_copy, src, size);
876
for (i = 0; i < msize-1; i++)
877
dst[size+i] = refmpn_addmul_1 (dst+i, src, size, mult[i]);
878
ret = refmpn_addmul_1 (dst+i, src, size, mult[i]);
885
refmpn_addmul_2 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
887
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 2);
890
refmpn_addmul_3 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
892
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 3);
895
refmpn_addmul_4 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
897
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 4);
900
refmpn_addmul_5 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
902
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 5);
905
refmpn_addmul_6 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
907
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 6);
910
refmpn_addmul_7 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
912
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 7);
915
refmpn_addmul_8 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
917
return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 8);
697
921
refmpn_addsub_nc (mp_ptr r1p, mp_ptr r2p,
698
922
mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
1047
/* accepting size==0 too */
1049
refmpn_rshift_or_copy_any (mp_ptr rp, mp_srcptr sp, mp_size_t size,
1052
return (size == 0 ? 0 : refmpn_rshift_or_copy (rp, sp, size, shift));
1055
refmpn_lshift_or_copy_any (mp_ptr rp, mp_srcptr sp, mp_size_t size,
1058
return (size == 0 ? 0 : refmpn_lshift_or_copy (rp, sp, size, shift));
824
1061
/* Divide h,l by d, return quotient, store remainder to *rp.
825
1062
Operates on full limbs, not nails.
1046
1284
cs = refmpn_sub_1 (spcopy, sp, size, carry);
1048
1286
for (c = 0; c <= 2; c++)
1049
if (refmpn_divmod_1c (rp, spcopy, size, 3, c) == 0)
1287
if (refmpn_divmod_1c (rp, spcopy, size, CNST_LIMB(3), c) == 0)
1051
1289
ASSERT_FAIL (no value of c satisfies);
1333
1576
if (D[1] & GMP_NUMB_HIGHBIT)
1335
if (refmpn_cmp (r, D, 2) <= 0)
1578
if (refmpn_cmp (r, D, (mp_size_t) 2) <= 0)
1337
refmpn_lshift (D, D, 2, 1);
1580
refmpn_lshift (D, D, (mp_size_t) 2, 1);
1339
1582
ASSERT (n <= GMP_NUMB_BITS);
1344
if (refmpn_cmp (r, D, 2) >= 0)
1345
ASSERT_NOCARRY (refmpn_sub_n (r, r, D, 2));
1346
refmpn_rshift (D, D, 2, 1);
1587
if (refmpn_cmp (r, D, (mp_size_t) 2) >= 0)
1588
ASSERT_NOCARRY (refmpn_sub_n (r, r, D, (mp_size_t) 2));
1589
refmpn_rshift (D, D, (mp_size_t) 2, 1);
1350
ASSERT (refmpn_cmp (r, d, 2) < 0);
1593
ASSERT (refmpn_cmp (r, d, (mp_size_t) 2) < 0);
1354
/* Find n where 0<n<2^GMP_NUMB_BITS and n==c mod m */
1597
/* Return n with 0 < n < 2^GMP_NUMB_BITS such that there exists 0 < |d| <
1598
2^GMP_NUMB_BITS, and n == d * c mod 2^(2*GMP_NUMB_BITS). */
1356
1600
refmpn_gcd_finda (const mp_limb_t c[2])
1475
1722
mp_ptr n2p = refmpn_malloc_limbs (nsize+1);
1476
1723
mp_ptr d2p = refmpn_malloc_limbs (dsize);
1477
int norm = refmpn_count_leading_zeros (dp[dsize-1]);
1724
int norm = refmpn_count_leading_zeros (dp[dsize-1]) - GMP_NAIL_BITS;
1479
1726
n2p[nsize] = refmpn_lshift_or_copy (n2p, np, nsize, norm);
1480
1727
ASSERT_NOCARRY (refmpn_lshift_or_copy (d2p, dp, dsize, norm));
1521
1769
ASSERT (d >= dst);
1522
*d = refmpn_divrem_1 (src, 0, src, size, (mp_limb_t) base);
1770
*d = refmpn_divrem_1 (src, (mp_size_t) 0, src, size, (mp_limb_t) base);
1523
1771
size -= (src[size-1] == 0);
1525
1773
while (size != 0);
1527
/* at most one leading zero */
1528
ASSERT (d == dst || d == dst+1);
1775
/* Move result back and decrement dsize if we didn't generate
1776
the maximum possible digits. */
1781
for (i = 0; i < dsize; i++)
1532
1785
if (POW2_P (base))
1635
1888
bit = GMP_NUMB_HIGHBIT;
1892
/* This is a simple bitwise algorithm working high to low across "s" and
1893
testing each time whether setting the bit would make s^2 exceed n. */
1895
refmpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr np, mp_size_t nsize)
1898
mp_size_t ssize, talloc, tsize, dsize, ret, ilimbs;
1903
ASSERT (nsize >= 0);
1905
/* If n==0, then s=0 and r=0. */
1909
ASSERT (np[nsize - 1] != 0);
1910
ASSERT (rp == NULL || MPN_SAME_OR_SEPARATE_P (np, rp, nsize));
1911
ASSERT (rp == NULL || ! MPN_OVERLAP_P (sp, (nsize + 1) / 2, rp, nsize));
1912
ASSERT (! MPN_OVERLAP_P (sp, (nsize + 1) / 2, np, nsize));
1915
ssize = (nsize+1)/2;
1916
refmpn_zero (sp, ssize);
1918
/* the remainder so far */
1919
dp = refmpn_memdup_limbs (np, nsize);
1923
talloc = 2*ssize + 1;
1924
tp = refmpn_malloc_limbs (talloc);
1926
for (i = GMP_NUMB_BITS * ssize - 1; i >= 0; i--)
1928
/* t = 2*s*2^i + 2^(2*i), being the amount s^2 will increase by if 2^i
1931
ilimbs = (i+1) / GMP_NUMB_BITS;
1932
ibit = (i+1) % GMP_NUMB_BITS;
1933
refmpn_zero (tp, ilimbs);
1934
c = refmpn_lshift_or_copy (tp+ilimbs, sp, ssize, ibit);
1935
tsize = ilimbs + ssize;
1939
ilimbs = (2*i) / GMP_NUMB_BITS;
1940
ibit = (2*i) % GMP_NUMB_BITS;
1941
if (ilimbs + 1 > tsize)
1943
refmpn_zero_extend (tp, tsize, ilimbs + 1);
1946
c = refmpn_add_1 (tp+ilimbs, tp+ilimbs, tsize-ilimbs,
1947
CNST_LIMB(1) << ibit);
1948
ASSERT (tsize < talloc);
1952
if (refmpn_cmp_twosizes (dp, dsize, tp, tsize) >= 0)
1954
/* set this bit in s and subtract from the remainder */
1955
refmpn_setbit (sp, i);
1957
ASSERT_NOCARRY (refmpn_sub_n (dp, dp, tp, dsize));
1958
dsize = refmpn_normalize (dp, dsize);
1964
ret = ! refmpn_zero_p (dp, dsize);
1968
ASSERT (dsize == 0 || dp[dsize-1] != 0);
1969
refmpn_copy (rp, dp, dsize);