diff options
| author | Paul Eggert | 2019-04-28 13:14:49 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-04-28 13:17:30 -0700 |
| commit | 9469d58ebe10b280a89c77ccdc89bd2340766107 (patch) | |
| tree | 4687e58fd03fe490aab623a84da2612ca2b1ba21 /src | |
| parent | 4d97e1a9ea35c3a1d9f03abb7a822d57f384c1a5 (diff) | |
| download | emacs-9469d58ebe10b280a89c77ccdc89bd2340766107.tar.gz emacs-9469d58ebe10b280a89c77ccdc89bd2340766107.zip | |
Update from GMP
* admin/update-copyright (updatable_files):
Don’t update copyright year on files copied from GMP, so that
they’re identical to upstream.
* src/mini-gmp.c, src/mini-gmp.h: Copy from GMP development
versions as of 2019-01-01 20:15:39 UTC.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mini-gmp.c | 559 | ||||
| -rw-r--r-- | src/mini-gmp.h | 2 |
2 files changed, 334 insertions, 227 deletions
diff --git a/src/mini-gmp.c b/src/mini-gmp.c index 90beb6e8327..88b71c3f9a6 100644 --- a/src/mini-gmp.c +++ b/src/mini-gmp.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | Contributed to the GNU project by Niels Möller | 3 | Contributed to the GNU project by Niels Möller |
| 4 | 4 | ||
| 5 | Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc. | 5 | Copyright 1991-1997, 1999-2018 Free Software Foundation, Inc. |
| 6 | 6 | ||
| 7 | This file is part of the GNU MP Library. | 7 | This file is part of the GNU MP Library. |
| 8 | 8 | ||
| @@ -58,7 +58,7 @@ see https://www.gnu.org/licenses/. */ | |||
| 58 | /* Macros */ | 58 | /* Macros */ |
| 59 | #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) | 59 | #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) |
| 60 | 60 | ||
| 61 | #define GMP_LIMB_MAX (~ (mp_limb_t) 0) | 61 | #define GMP_LIMB_MAX ((mp_limb_t) ~ (mp_limb_t) 0) |
| 62 | #define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1)) | 62 | #define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1)) |
| 63 | 63 | ||
| 64 | #define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2)) | 64 | #define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2)) |
| @@ -129,6 +129,20 @@ see https://www.gnu.org/licenses/. */ | |||
| 129 | 129 | ||
| 130 | #define gmp_umul_ppmm(w1, w0, u, v) \ | 130 | #define gmp_umul_ppmm(w1, w0, u, v) \ |
| 131 | do { \ | 131 | do { \ |
| 132 | int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; \ | ||
| 133 | if (sizeof(unsigned int) * CHAR_BIT >= 2 * GMP_LIMB_BITS) \ | ||
| 134 | { \ | ||
| 135 | unsigned int __ww = (unsigned int) (u) * (v); \ | ||
| 136 | w0 = (mp_limb_t) __ww; \ | ||
| 137 | w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ | ||
| 138 | } \ | ||
| 139 | else if (GMP_ULONG_BITS >= 2 * GMP_LIMB_BITS) \ | ||
| 140 | { \ | ||
| 141 | unsigned long int __ww = (unsigned long int) (u) * (v); \ | ||
| 142 | w0 = (mp_limb_t) __ww; \ | ||
| 143 | w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ | ||
| 144 | } \ | ||
| 145 | else { \ | ||
| 132 | mp_limb_t __x0, __x1, __x2, __x3; \ | 146 | mp_limb_t __x0, __x1, __x2, __x3; \ |
| 133 | unsigned __ul, __vl, __uh, __vh; \ | 147 | unsigned __ul, __vl, __uh, __vh; \ |
| 134 | mp_limb_t __u = (u), __v = (v); \ | 148 | mp_limb_t __u = (u), __v = (v); \ |
| @@ -150,6 +164,7 @@ see https://www.gnu.org/licenses/. */ | |||
| 150 | \ | 164 | \ |
| 151 | (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \ | 165 | (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \ |
| 152 | (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \ | 166 | (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \ |
| 167 | } \ | ||
| 153 | } while (0) | 168 | } while (0) |
| 154 | 169 | ||
| 155 | #define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ | 170 | #define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ |
| @@ -753,6 +768,18 @@ mpn_neg (mp_ptr rp, mp_srcptr up, mp_size_t n) | |||
| 753 | mp_limb_t | 768 | mp_limb_t |
| 754 | mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) | 769 | mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) |
| 755 | { | 770 | { |
| 771 | int GMP_LIMB_BITS_MUL_3 = GMP_LIMB_BITS * 3; | ||
| 772 | if (sizeof (unsigned) * CHAR_BIT > GMP_LIMB_BITS * 3) | ||
| 773 | { | ||
| 774 | return (((unsigned) 1 << GMP_LIMB_BITS_MUL_3) - 1) / | ||
| 775 | (((unsigned) u1 << GMP_LIMB_BITS_MUL_3 / 3) + u0); | ||
| 776 | } | ||
| 777 | else if (GMP_ULONG_BITS > GMP_LIMB_BITS * 3) | ||
| 778 | { | ||
| 779 | return (((unsigned long) 1 << GMP_LIMB_BITS_MUL_3) - 1) / | ||
| 780 | (((unsigned long) u1 << GMP_LIMB_BITS_MUL_3 / 3) + u0); | ||
| 781 | } | ||
| 782 | else { | ||
| 756 | mp_limb_t r, p, m, ql; | 783 | mp_limb_t r, p, m, ql; |
| 757 | unsigned ul, uh, qh; | 784 | unsigned ul, uh, qh; |
| 758 | 785 | ||
| @@ -827,7 +854,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) | |||
| 827 | r -= u1; | 854 | r -= u1; |
| 828 | } | 855 | } |
| 829 | 856 | ||
| 830 | /* Now m is the 2/1 invers of u1. If u0 > 0, adjust it to become a | 857 | /* Now m is the 2/1 inverse of u1. If u0 > 0, adjust it to become a |
| 831 | 3/2 inverse. */ | 858 | 3/2 inverse. */ |
| 832 | if (u0 > 0) | 859 | if (u0 > 0) |
| 833 | { | 860 | { |
| @@ -854,6 +881,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) | |||
| 854 | } | 881 | } |
| 855 | 882 | ||
| 856 | return m; | 883 | return m; |
| 884 | } | ||
| 857 | } | 885 | } |
| 858 | 886 | ||
| 859 | struct gmp_div_inverse | 887 | struct gmp_div_inverse |
| @@ -964,36 +992,6 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn, | |||
| 964 | return r >> inv->shift; | 992 | return r >> inv->shift; |
| 965 | } | 993 | } |
| 966 | 994 | ||
| 967 | static mp_limb_t | ||
| 968 | mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d) | ||
| 969 | { | ||
| 970 | assert (d > 0); | ||
| 971 | |||
| 972 | /* Special case for powers of two. */ | ||
| 973 | if ((d & (d-1)) == 0) | ||
| 974 | { | ||
| 975 | mp_limb_t r = np[0] & (d-1); | ||
| 976 | if (qp) | ||
| 977 | { | ||
| 978 | if (d <= 1) | ||
| 979 | mpn_copyi (qp, np, nn); | ||
| 980 | else | ||
| 981 | { | ||
| 982 | unsigned shift; | ||
| 983 | gmp_ctz (shift, d); | ||
| 984 | mpn_rshift (qp, np, nn, shift); | ||
| 985 | } | ||
| 986 | } | ||
| 987 | return r; | ||
| 988 | } | ||
| 989 | else | ||
| 990 | { | ||
| 991 | struct gmp_div_inverse inv; | ||
| 992 | mpn_div_qr_1_invert (&inv, d); | ||
| 993 | return mpn_div_qr_1_preinv (qp, np, nn, &inv); | ||
| 994 | } | ||
| 995 | } | ||
| 996 | |||
| 997 | static void | 995 | static void |
| 998 | mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, | 996 | mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, |
| 999 | const struct gmp_div_inverse *inv) | 997 | const struct gmp_div_inverse *inv) |
| @@ -1029,7 +1027,7 @@ mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, | |||
| 1029 | 1027 | ||
| 1030 | if (shift > 0) | 1028 | if (shift > 0) |
| 1031 | { | 1029 | { |
| 1032 | assert ((r0 << (GMP_LIMB_BITS - shift)) == 0); | 1030 | assert ((r0 & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - shift))) == 0); |
| 1033 | r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift)); | 1031 | r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift)); |
| 1034 | r1 >>= shift; | 1032 | r1 >>= shift; |
| 1035 | } | 1033 | } |
| @@ -1252,7 +1250,7 @@ mpn_limb_get_str (unsigned char *sp, mp_limb_t w, | |||
| 1252 | l = w << binv->shift; | 1250 | l = w << binv->shift; |
| 1253 | 1251 | ||
| 1254 | gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di); | 1252 | gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di); |
| 1255 | assert ( (r << (GMP_LIMB_BITS - binv->shift)) == 0); | 1253 | assert ((r & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - binv->shift))) == 0); |
| 1256 | r >>= binv->shift; | 1254 | r >>= binv->shift; |
| 1257 | 1255 | ||
| 1258 | sp[i] = r; | 1256 | sp[i] = r; |
| @@ -1420,7 +1418,7 @@ mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base) | |||
| 1420 | void | 1418 | void |
| 1421 | mpz_init (mpz_t r) | 1419 | mpz_init (mpz_t r) |
| 1422 | { | 1420 | { |
| 1423 | static const mp_limb_t dummy_limb = 0xc1a0; | 1421 | static const mp_limb_t dummy_limb = GMP_LIMB_MAX & 0xc1a0; |
| 1424 | 1422 | ||
| 1425 | r->_mp_alloc = 0; | 1423 | r->_mp_alloc = 0; |
| 1426 | r->_mp_size = 0; | 1424 | r->_mp_size = 0; |
| @@ -1478,6 +1476,12 @@ mpz_set_si (mpz_t r, signed long int x) | |||
| 1478 | if (x >= 0) | 1476 | if (x >= 0) |
| 1479 | mpz_set_ui (r, x); | 1477 | mpz_set_ui (r, x); |
| 1480 | else /* (x < 0) */ | 1478 | else /* (x < 0) */ |
| 1479 | if (GMP_LIMB_BITS < GMP_ULONG_BITS) | ||
| 1480 | { | ||
| 1481 | mpz_set_ui (r, GMP_NEG_CAST (unsigned long int, x)); | ||
| 1482 | mpz_neg (r, r); | ||
| 1483 | } | ||
| 1484 | else | ||
| 1481 | { | 1485 | { |
| 1482 | r->_mp_size = -1; | 1486 | r->_mp_size = -1; |
| 1483 | MPZ_REALLOC (r, 1)[0] = GMP_NEG_CAST (unsigned long int, x); | 1487 | MPZ_REALLOC (r, 1)[0] = GMP_NEG_CAST (unsigned long int, x); |
| @@ -1491,6 +1495,15 @@ mpz_set_ui (mpz_t r, unsigned long int x) | |||
| 1491 | { | 1495 | { |
| 1492 | r->_mp_size = 1; | 1496 | r->_mp_size = 1; |
| 1493 | MPZ_REALLOC (r, 1)[0] = x; | 1497 | MPZ_REALLOC (r, 1)[0] = x; |
| 1498 | if (GMP_LIMB_BITS < GMP_ULONG_BITS) | ||
| 1499 | { | ||
| 1500 | int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; | ||
| 1501 | while (x >>= LOCAL_GMP_LIMB_BITS) | ||
| 1502 | { | ||
| 1503 | ++ r->_mp_size; | ||
| 1504 | MPZ_REALLOC (r, r->_mp_size)[r->_mp_size - 1] = x; | ||
| 1505 | } | ||
| 1506 | } | ||
| 1494 | } | 1507 | } |
| 1495 | else | 1508 | else |
| 1496 | r->_mp_size = 0; | 1509 | r->_mp_size = 0; |
| @@ -1537,14 +1550,20 @@ mpz_init_set (mpz_t r, const mpz_t x) | |||
| 1537 | int | 1550 | int |
| 1538 | mpz_fits_slong_p (const mpz_t u) | 1551 | mpz_fits_slong_p (const mpz_t u) |
| 1539 | { | 1552 | { |
| 1540 | mp_size_t us = u->_mp_size; | 1553 | return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) && |
| 1554 | mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0; | ||
| 1555 | } | ||
| 1541 | 1556 | ||
| 1542 | if (us == 1) | 1557 | static int |
| 1543 | return u->_mp_d[0] < GMP_LIMB_HIGHBIT; | 1558 | mpn_absfits_ulong_p (mp_srcptr up, mp_size_t un) |
| 1544 | else if (us == -1) | 1559 | { |
| 1545 | return u->_mp_d[0] <= GMP_LIMB_HIGHBIT; | 1560 | int ulongsize = GMP_ULONG_BITS / GMP_LIMB_BITS; |
| 1546 | else | 1561 | mp_limb_t ulongrem = 0; |
| 1547 | return (us == 0); | 1562 | |
| 1563 | if (GMP_ULONG_BITS % GMP_LIMB_BITS != 0) | ||
| 1564 | ulongrem = (mp_limb_t) (ULONG_MAX >> GMP_LIMB_BITS * ulongsize) + 1; | ||
| 1565 | |||
| 1566 | return un <= ulongsize || (up[ulongsize] < ulongrem && un == ulongsize + 1); | ||
| 1548 | } | 1567 | } |
| 1549 | 1568 | ||
| 1550 | int | 1569 | int |
| @@ -1552,22 +1571,36 @@ mpz_fits_ulong_p (const mpz_t u) | |||
| 1552 | { | 1571 | { |
| 1553 | mp_size_t us = u->_mp_size; | 1572 | mp_size_t us = u->_mp_size; |
| 1554 | 1573 | ||
| 1555 | return (us == (us > 0)); | 1574 | return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us); |
| 1556 | } | 1575 | } |
| 1557 | 1576 | ||
| 1558 | long int | 1577 | long int |
| 1559 | mpz_get_si (const mpz_t u) | 1578 | mpz_get_si (const mpz_t u) |
| 1560 | { | 1579 | { |
| 1580 | unsigned long r = mpz_get_ui (u); | ||
| 1581 | unsigned long c = -LONG_MAX - LONG_MIN; | ||
| 1582 | |||
| 1561 | if (u->_mp_size < 0) | 1583 | if (u->_mp_size < 0) |
| 1562 | /* This expression is necessary to properly handle 0x80000000 */ | 1584 | /* This expression is necessary to properly handle -LONG_MIN */ |
| 1563 | return -1 - (long) ((u->_mp_d[0] - 1) & ~GMP_LIMB_HIGHBIT); | 1585 | return -(long) c - (long) ((r - c) & LONG_MAX); |
| 1564 | else | 1586 | else |
| 1565 | return (long) (mpz_get_ui (u) & ~GMP_LIMB_HIGHBIT); | 1587 | return (long) (r & LONG_MAX); |
| 1566 | } | 1588 | } |
| 1567 | 1589 | ||
| 1568 | unsigned long int | 1590 | unsigned long int |
| 1569 | mpz_get_ui (const mpz_t u) | 1591 | mpz_get_ui (const mpz_t u) |
| 1570 | { | 1592 | { |
| 1593 | if (GMP_LIMB_BITS < GMP_ULONG_BITS) | ||
| 1594 | { | ||
| 1595 | int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; | ||
| 1596 | unsigned long r = 0; | ||
| 1597 | mp_size_t n = GMP_ABS (u->_mp_size); | ||
| 1598 | n = GMP_MIN (n, 1 + (GMP_ULONG_BITS - 1) / GMP_LIMB_BITS); | ||
| 1599 | while (--n >= 0) | ||
| 1600 | r = (r << LOCAL_GMP_LIMB_BITS) + u->_mp_d[n]; | ||
| 1601 | return r; | ||
| 1602 | } | ||
| 1603 | |||
| 1571 | return u->_mp_size == 0 ? 0 : u->_mp_d[0]; | 1604 | return u->_mp_size == 0 ? 0 : u->_mp_d[0]; |
| 1572 | } | 1605 | } |
| 1573 | 1606 | ||
| @@ -1665,7 +1698,7 @@ mpz_set_d (mpz_t r, double x) | |||
| 1665 | r->_mp_size = 0; | 1698 | r->_mp_size = 0; |
| 1666 | return; | 1699 | return; |
| 1667 | } | 1700 | } |
| 1668 | B = 2.0 * (double) GMP_LIMB_HIGHBIT; | 1701 | B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); |
| 1669 | Bi = 1.0 / B; | 1702 | Bi = 1.0 / B; |
| 1670 | for (rn = 1; x >= B; rn++) | 1703 | for (rn = 1; x >= B; rn++) |
| 1671 | x *= Bi; | 1704 | x *= Bi; |
| @@ -1703,7 +1736,7 @@ mpz_get_d (const mpz_t u) | |||
| 1703 | mp_limb_t l; | 1736 | mp_limb_t l; |
| 1704 | mp_size_t un; | 1737 | mp_size_t un; |
| 1705 | double x; | 1738 | double x; |
| 1706 | double B = 2.0 * (double) GMP_LIMB_HIGHBIT; | 1739 | double B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); |
| 1707 | 1740 | ||
| 1708 | un = GMP_ABS (u->_mp_size); | 1741 | un = GMP_ABS (u->_mp_size); |
| 1709 | 1742 | ||
| @@ -1748,7 +1781,7 @@ mpz_cmpabs_d (const mpz_t x, double d) | |||
| 1748 | { | 1781 | { |
| 1749 | xn = GMP_ABS (xn); | 1782 | xn = GMP_ABS (xn); |
| 1750 | 1783 | ||
| 1751 | B = 2.0 * (double) GMP_LIMB_HIGHBIT; | 1784 | B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); |
| 1752 | Bi = 1.0 / B; | 1785 | Bi = 1.0 / B; |
| 1753 | 1786 | ||
| 1754 | /* Scale d so it can be compared with the top limb. */ | 1787 | /* Scale d so it can be compared with the top limb. */ |
| @@ -1807,14 +1840,12 @@ mpz_cmp_si (const mpz_t u, long v) | |||
| 1807 | { | 1840 | { |
| 1808 | mp_size_t usize = u->_mp_size; | 1841 | mp_size_t usize = u->_mp_size; |
| 1809 | 1842 | ||
| 1810 | if (usize < -1) | 1843 | if (v >= 0) |
| 1811 | return -1; | ||
| 1812 | else if (v >= 0) | ||
| 1813 | return mpz_cmp_ui (u, v); | 1844 | return mpz_cmp_ui (u, v); |
| 1814 | else if (usize >= 0) | 1845 | else if (usize >= 0) |
| 1815 | return 1; | 1846 | return 1; |
| 1816 | else /* usize == -1 */ | 1847 | else |
| 1817 | return GMP_CMP (GMP_NEG_CAST (mp_limb_t, v), u->_mp_d[0]); | 1848 | return - mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, v)); |
| 1818 | } | 1849 | } |
| 1819 | 1850 | ||
| 1820 | int | 1851 | int |
| @@ -1822,12 +1853,10 @@ mpz_cmp_ui (const mpz_t u, unsigned long v) | |||
| 1822 | { | 1853 | { |
| 1823 | mp_size_t usize = u->_mp_size; | 1854 | mp_size_t usize = u->_mp_size; |
| 1824 | 1855 | ||
| 1825 | if (usize > 1) | 1856 | if (usize < 0) |
| 1826 | return 1; | ||
| 1827 | else if (usize < 0) | ||
| 1828 | return -1; | 1857 | return -1; |
| 1829 | else | 1858 | else |
| 1830 | return GMP_CMP (mpz_get_ui (u), v); | 1859 | return mpz_cmpabs_ui (u, v); |
| 1831 | } | 1860 | } |
| 1832 | 1861 | ||
| 1833 | int | 1862 | int |
| @@ -1847,10 +1876,15 @@ mpz_cmp (const mpz_t a, const mpz_t b) | |||
| 1847 | int | 1876 | int |
| 1848 | mpz_cmpabs_ui (const mpz_t u, unsigned long v) | 1877 | mpz_cmpabs_ui (const mpz_t u, unsigned long v) |
| 1849 | { | 1878 | { |
| 1850 | if (GMP_ABS (u->_mp_size) > 1) | 1879 | mp_size_t un = GMP_ABS (u->_mp_size); |
| 1880 | |||
| 1881 | if (! mpn_absfits_ulong_p (u->_mp_d, un)) | ||
| 1851 | return 1; | 1882 | return 1; |
| 1852 | else | 1883 | else |
| 1853 | return GMP_CMP (mpz_get_ui (u), v); | 1884 | { |
| 1885 | unsigned long uu = mpz_get_ui (u); | ||
| 1886 | return GMP_CMP(uu, v); | ||
| 1887 | } | ||
| 1854 | } | 1888 | } |
| 1855 | 1889 | ||
| 1856 | int | 1890 | int |
| @@ -1885,81 +1919,28 @@ mpz_swap (mpz_t u, mpz_t v) | |||
| 1885 | 1919 | ||
| 1886 | /* MPZ addition and subtraction */ | 1920 | /* MPZ addition and subtraction */ |
| 1887 | 1921 | ||
| 1888 | /* Adds to the absolute value. Returns new size, but doesn't store it. */ | ||
| 1889 | static mp_size_t | ||
| 1890 | mpz_abs_add_ui (mpz_t r, const mpz_t a, unsigned long b) | ||
| 1891 | { | ||
| 1892 | mp_size_t an; | ||
| 1893 | mp_ptr rp; | ||
| 1894 | mp_limb_t cy; | ||
| 1895 | |||
| 1896 | an = GMP_ABS (a->_mp_size); | ||
| 1897 | if (an == 0) | ||
| 1898 | { | ||
| 1899 | MPZ_REALLOC (r, 1)[0] = b; | ||
| 1900 | return b > 0; | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | rp = MPZ_REALLOC (r, an + 1); | ||
| 1904 | |||
| 1905 | cy = mpn_add_1 (rp, a->_mp_d, an, b); | ||
| 1906 | rp[an] = cy; | ||
| 1907 | an += cy; | ||
| 1908 | |||
| 1909 | return an; | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | /* Subtract from the absolute value. Returns new size, (or -1 on underflow), | ||
| 1913 | but doesn't store it. */ | ||
| 1914 | static mp_size_t | ||
| 1915 | mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b) | ||
| 1916 | { | ||
| 1917 | mp_size_t an = GMP_ABS (a->_mp_size); | ||
| 1918 | mp_ptr rp; | ||
| 1919 | |||
| 1920 | if (an == 0) | ||
| 1921 | { | ||
| 1922 | MPZ_REALLOC (r, 1)[0] = b; | ||
| 1923 | return -(b > 0); | ||
| 1924 | } | ||
| 1925 | rp = MPZ_REALLOC (r, an); | ||
| 1926 | if (an == 1 && a->_mp_d[0] < b) | ||
| 1927 | { | ||
| 1928 | rp[0] = b - a->_mp_d[0]; | ||
| 1929 | return -1; | ||
| 1930 | } | ||
| 1931 | else | ||
| 1932 | { | ||
| 1933 | gmp_assert_nocarry (mpn_sub_1 (rp, a->_mp_d, an, b)); | ||
| 1934 | return mpn_normalized_size (rp, an); | ||
| 1935 | } | ||
| 1936 | } | ||
| 1937 | 1922 | ||
| 1938 | void | 1923 | void |
| 1939 | mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b) | 1924 | mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b) |
| 1940 | { | 1925 | { |
| 1941 | if (a->_mp_size >= 0) | 1926 | mpz_t bb; |
| 1942 | r->_mp_size = mpz_abs_add_ui (r, a, b); | 1927 | mpz_init_set_ui (bb, b); |
| 1943 | else | 1928 | mpz_add (r, a, bb); |
| 1944 | r->_mp_size = -mpz_abs_sub_ui (r, a, b); | 1929 | mpz_clear (bb); |
| 1945 | } | 1930 | } |
| 1946 | 1931 | ||
| 1947 | void | 1932 | void |
| 1948 | mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b) | 1933 | mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b) |
| 1949 | { | 1934 | { |
| 1950 | if (a->_mp_size < 0) | 1935 | mpz_ui_sub (r, b, a); |
| 1951 | r->_mp_size = -mpz_abs_add_ui (r, a, b); | 1936 | mpz_neg (r, r); |
| 1952 | else | ||
| 1953 | r->_mp_size = mpz_abs_sub_ui (r, a, b); | ||
| 1954 | } | 1937 | } |
| 1955 | 1938 | ||
| 1956 | void | 1939 | void |
| 1957 | mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b) | 1940 | mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b) |
| 1958 | { | 1941 | { |
| 1959 | if (b->_mp_size < 0) | 1942 | mpz_neg (r, b); |
| 1960 | r->_mp_size = mpz_abs_add_ui (r, b, a); | 1943 | mpz_add_ui (r, r, a); |
| 1961 | else | ||
| 1962 | r->_mp_size = -mpz_abs_sub_ui (r, b, a); | ||
| 1963 | } | 1944 | } |
| 1964 | 1945 | ||
| 1965 | static mp_size_t | 1946 | static mp_size_t |
| @@ -2046,32 +2027,17 @@ mpz_mul_si (mpz_t r, const mpz_t u, long int v) | |||
| 2046 | mpz_neg (r, r); | 2027 | mpz_neg (r, r); |
| 2047 | } | 2028 | } |
| 2048 | else | 2029 | else |
| 2049 | mpz_mul_ui (r, u, (unsigned long int) v); | 2030 | mpz_mul_ui (r, u, v); |
| 2050 | } | 2031 | } |
| 2051 | 2032 | ||
| 2052 | void | 2033 | void |
| 2053 | mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v) | 2034 | mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v) |
| 2054 | { | 2035 | { |
| 2055 | mp_size_t un, us; | 2036 | mpz_t vv; |
| 2056 | mp_ptr tp; | 2037 | mpz_init_set_ui (vv, v); |
| 2057 | mp_limb_t cy; | 2038 | mpz_mul (r, u, vv); |
| 2058 | 2039 | mpz_clear (vv); | |
| 2059 | us = u->_mp_size; | 2040 | return; |
| 2060 | |||
| 2061 | if (us == 0 || v == 0) | ||
| 2062 | { | ||
| 2063 | r->_mp_size = 0; | ||
| 2064 | return; | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | un = GMP_ABS (us); | ||
| 2068 | |||
| 2069 | tp = MPZ_REALLOC (r, un + 1); | ||
| 2070 | cy = mpn_mul_1 (tp, u->_mp_d, un, v); | ||
| 2071 | tp[un] = cy; | ||
| 2072 | |||
| 2073 | un += (cy > 0); | ||
| 2074 | r->_mp_size = (us < 0) ? - un : un; | ||
| 2075 | } | 2041 | } |
| 2076 | 2042 | ||
| 2077 | void | 2043 | void |
| @@ -2150,8 +2116,8 @@ void | |||
| 2150 | mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) | 2116 | mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) |
| 2151 | { | 2117 | { |
| 2152 | mpz_t t; | 2118 | mpz_t t; |
| 2153 | mpz_init (t); | 2119 | mpz_init_set_ui (t, v); |
| 2154 | mpz_mul_ui (t, u, v); | 2120 | mpz_mul (t, u, t); |
| 2155 | mpz_add (r, r, t); | 2121 | mpz_add (r, r, t); |
| 2156 | mpz_clear (t); | 2122 | mpz_clear (t); |
| 2157 | } | 2123 | } |
| @@ -2160,8 +2126,8 @@ void | |||
| 2160 | mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v) | 2126 | mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v) |
| 2161 | { | 2127 | { |
| 2162 | mpz_t t; | 2128 | mpz_t t; |
| 2163 | mpz_init (t); | 2129 | mpz_init_set_ui (t, v); |
| 2164 | mpz_mul_ui (t, u, v); | 2130 | mpz_mul (t, u, t); |
| 2165 | mpz_sub (r, r, t); | 2131 | mpz_sub (r, r, t); |
| 2166 | mpz_clear (t); | 2132 | mpz_clear (t); |
| 2167 | } | 2133 | } |
| @@ -2557,56 +2523,20 @@ static unsigned long | |||
| 2557 | mpz_div_qr_ui (mpz_t q, mpz_t r, | 2523 | mpz_div_qr_ui (mpz_t q, mpz_t r, |
| 2558 | const mpz_t n, unsigned long d, enum mpz_div_round_mode mode) | 2524 | const mpz_t n, unsigned long d, enum mpz_div_round_mode mode) |
| 2559 | { | 2525 | { |
| 2560 | mp_size_t ns, qn; | 2526 | unsigned long ret; |
| 2561 | mp_ptr qp; | 2527 | mpz_t rr, dd; |
| 2562 | mp_limb_t rl; | ||
| 2563 | mp_size_t rs; | ||
| 2564 | |||
| 2565 | ns = n->_mp_size; | ||
| 2566 | if (ns == 0) | ||
| 2567 | { | ||
| 2568 | if (q) | ||
| 2569 | q->_mp_size = 0; | ||
| 2570 | if (r) | ||
| 2571 | r->_mp_size = 0; | ||
| 2572 | return 0; | ||
| 2573 | } | ||
| 2574 | |||
| 2575 | qn = GMP_ABS (ns); | ||
| 2576 | if (q) | ||
| 2577 | qp = MPZ_REALLOC (q, qn); | ||
| 2578 | else | ||
| 2579 | qp = NULL; | ||
| 2580 | 2528 | ||
| 2581 | rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d); | 2529 | mpz_init (rr); |
| 2582 | assert (rl < d); | 2530 | mpz_init_set_ui (dd, d); |
| 2583 | 2531 | mpz_div_qr (q, rr, n, dd, mode); | |
| 2584 | rs = rl > 0; | 2532 | mpz_clear (dd); |
| 2585 | rs = (ns < 0) ? -rs : rs; | 2533 | ret = mpz_get_ui (rr); |
| 2586 | |||
| 2587 | if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0) | ||
| 2588 | || (mode == GMP_DIV_CEIL && ns >= 0))) | ||
| 2589 | { | ||
| 2590 | if (q) | ||
| 2591 | gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1)); | ||
| 2592 | rl = d - rl; | ||
| 2593 | rs = -rs; | ||
| 2594 | } | ||
| 2595 | 2534 | ||
| 2596 | if (r) | 2535 | if (r) |
| 2597 | { | 2536 | mpz_swap (r, rr); |
| 2598 | MPZ_REALLOC (r, 1)[0] = rl; | 2537 | mpz_clear (rr); |
| 2599 | r->_mp_size = rs; | ||
| 2600 | } | ||
| 2601 | if (q) | ||
| 2602 | { | ||
| 2603 | qn -= (qp[qn-1] == 0); | ||
| 2604 | assert (qn == 0 || qp[qn-1] > 0); | ||
| 2605 | |||
| 2606 | q->_mp_size = (ns < 0) ? - qn : qn; | ||
| 2607 | } | ||
| 2608 | 2538 | ||
| 2609 | return rl; | 2539 | return ret; |
| 2610 | } | 2540 | } |
| 2611 | 2541 | ||
| 2612 | unsigned long | 2542 | unsigned long |
| @@ -2745,22 +2675,16 @@ mpn_gcd_11 (mp_limb_t u, mp_limb_t v) | |||
| 2745 | unsigned long | 2675 | unsigned long |
| 2746 | mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) | 2676 | mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) |
| 2747 | { | 2677 | { |
| 2748 | mp_size_t un; | 2678 | mpz_t t; |
| 2679 | mpz_init_set_ui(t, v); | ||
| 2680 | mpz_gcd (t, u, t); | ||
| 2681 | if (v > 0) | ||
| 2682 | v = mpz_get_ui (t); | ||
| 2749 | 2683 | ||
| 2750 | if (v == 0) | 2684 | if (g) |
| 2751 | { | 2685 | mpz_swap (t, g); |
| 2752 | if (g) | ||
| 2753 | mpz_abs (g, u); | ||
| 2754 | } | ||
| 2755 | else | ||
| 2756 | { | ||
| 2757 | un = GMP_ABS (u->_mp_size); | ||
| 2758 | if (un != 0) | ||
| 2759 | v = mpn_gcd_11 (mpn_div_qr_1 (NULL, u->_mp_d, un, v), v); | ||
| 2760 | 2686 | ||
| 2761 | if (g) | 2687 | mpz_clear (t); |
| 2762 | mpz_set_ui (g, v); | ||
| 2763 | } | ||
| 2764 | 2688 | ||
| 2765 | return v; | 2689 | return v; |
| 2766 | } | 2690 | } |
| @@ -2854,7 +2778,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) | |||
| 2854 | signed long sign = mpz_sgn (v); | 2778 | signed long sign = mpz_sgn (v); |
| 2855 | mpz_abs (g, v); | 2779 | mpz_abs (g, v); |
| 2856 | if (s) | 2780 | if (s) |
| 2857 | mpz_set_ui (s, 0); | 2781 | s->_mp_size = 0; |
| 2858 | if (t) | 2782 | if (t) |
| 2859 | mpz_set_si (t, sign); | 2783 | mpz_set_si (t, sign); |
| 2860 | return; | 2784 | return; |
| @@ -2868,7 +2792,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) | |||
| 2868 | if (s) | 2792 | if (s) |
| 2869 | mpz_set_si (s, sign); | 2793 | mpz_set_si (s, sign); |
| 2870 | if (t) | 2794 | if (t) |
| 2871 | mpz_set_ui (t, 0); | 2795 | t->_mp_size = 0; |
| 2872 | return; | 2796 | return; |
| 2873 | } | 2797 | } |
| 2874 | 2798 | ||
| @@ -2993,8 +2917,9 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) | |||
| 2993 | mpz_sub (s0, s0, s1); | 2917 | mpz_sub (s0, s0, s1); |
| 2994 | mpz_add (t0, t0, t1); | 2918 | mpz_add (t0, t0, t1); |
| 2995 | } | 2919 | } |
| 2996 | mpz_divexact_ui (s0, s0, 2); | 2920 | assert (mpz_even_p (t0) && mpz_even_p (s0)); |
| 2997 | mpz_divexact_ui (t0, t0, 2); | 2921 | mpz_tdiv_q_2exp (s0, s0, 1); |
| 2922 | mpz_tdiv_q_2exp (t0, t0, 1); | ||
| 2998 | } | 2923 | } |
| 2999 | 2924 | ||
| 3000 | /* Arrange so that |s| < |u| / 2g */ | 2925 | /* Arrange so that |s| < |u| / 2g */ |
| @@ -3119,7 +3044,10 @@ void | |||
| 3119 | mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e) | 3044 | mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e) |
| 3120 | { | 3045 | { |
| 3121 | mpz_t b; | 3046 | mpz_t b; |
| 3122 | mpz_pow_ui (r, mpz_roinit_normal_n (b, &blimb, blimb != 0), e); | 3047 | |
| 3048 | mpz_init_set_ui (b, blimb); | ||
| 3049 | mpz_pow_ui (r, b, e); | ||
| 3050 | mpz_clear (b); | ||
| 3123 | } | 3051 | } |
| 3124 | 3052 | ||
| 3125 | void | 3053 | void |
| @@ -3231,7 +3159,10 @@ void | |||
| 3231 | mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) | 3159 | mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) |
| 3232 | { | 3160 | { |
| 3233 | mpz_t e; | 3161 | mpz_t e; |
| 3234 | mpz_powm (r, b, mpz_roinit_normal_n (e, &elimb, elimb != 0), m); | 3162 | |
| 3163 | mpz_init_set_ui (e, elimb); | ||
| 3164 | mpz_powm (r, b, e, m); | ||
| 3165 | mpz_clear (e); | ||
| 3235 | } | 3166 | } |
| 3236 | 3167 | ||
| 3237 | /* x=trunc(y^(1/z)), r=y-x^z */ | 3168 | /* x=trunc(y^(1/z)), r=y-x^z */ |
| @@ -3409,6 +3340,177 @@ mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k) | |||
| 3409 | 3340 | ||
| 3410 | 3341 | ||
| 3411 | /* Primality testing */ | 3342 | /* Primality testing */ |
| 3343 | |||
| 3344 | /* Computes Kronecker (a/b) with odd b, a!=0 and GCD(a,b) = 1 */ | ||
| 3345 | /* Adapted from JACOBI_BASE_METHOD==4 in mpn/generic/jacbase.c */ | ||
| 3346 | static int | ||
| 3347 | gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b) | ||
| 3348 | { | ||
| 3349 | int c, bit = 0; | ||
| 3350 | |||
| 3351 | assert (b & 1); | ||
| 3352 | assert (a != 0); | ||
| 3353 | /* assert (mpn_gcd_11 (a, b) == 1); */ | ||
| 3354 | |||
| 3355 | /* Below, we represent a and b shifted right so that the least | ||
| 3356 | significant one bit is implicit. */ | ||
| 3357 | b >>= 1; | ||
| 3358 | |||
| 3359 | gmp_ctz(c, a); | ||
| 3360 | a >>= 1; | ||
| 3361 | |||
| 3362 | do | ||
| 3363 | { | ||
| 3364 | a >>= c; | ||
| 3365 | /* (2/b) = -1 if b = 3 or 5 mod 8 */ | ||
| 3366 | bit ^= c & (b ^ (b >> 1)); | ||
| 3367 | if (a < b) | ||
| 3368 | { | ||
| 3369 | bit ^= a & b; | ||
| 3370 | a = b - a; | ||
| 3371 | b -= a; | ||
| 3372 | } | ||
| 3373 | else | ||
| 3374 | { | ||
| 3375 | a -= b; | ||
| 3376 | assert (a != 0); | ||
| 3377 | } | ||
| 3378 | |||
| 3379 | gmp_ctz(c, a); | ||
| 3380 | ++c; | ||
| 3381 | } | ||
| 3382 | while (b > 0); | ||
| 3383 | |||
| 3384 | return bit & 1 ? -1 : 1; | ||
| 3385 | } | ||
| 3386 | |||
| 3387 | static void | ||
| 3388 | gmp_lucas_step_k_2k (mpz_t V, mpz_t Qk, const mpz_t n) | ||
| 3389 | { | ||
| 3390 | mpz_mod (Qk, Qk, n); | ||
| 3391 | /* V_{2k} <- V_k ^ 2 - 2Q^k */ | ||
| 3392 | mpz_mul (V, V, V); | ||
| 3393 | mpz_submul_ui (V, Qk, 2); | ||
| 3394 | mpz_tdiv_r (V, V, n); | ||
| 3395 | /* Q^{2k} = (Q^k)^2 */ | ||
| 3396 | mpz_mul (Qk, Qk, Qk); | ||
| 3397 | } | ||
| 3398 | |||
| 3399 | /* Computes V_k, Q^k (mod n) for the Lucas' sequence */ | ||
| 3400 | /* with P=1, Q=Q; k = (n>>b0)|1. */ | ||
| 3401 | /* Requires an odd n > 4; b0 > 0; -2*Q must not overflow a long */ | ||
| 3402 | /* Returns (U_k == 0) and sets V=V_k and Qk=Q^k. */ | ||
| 3403 | static int | ||
| 3404 | gmp_lucas_mod (mpz_t V, mpz_t Qk, long Q, | ||
| 3405 | mp_bitcnt_t b0, const mpz_t n) | ||
| 3406 | { | ||
| 3407 | mp_bitcnt_t bs; | ||
| 3408 | mpz_t U; | ||
| 3409 | int res; | ||
| 3410 | |||
| 3411 | assert (b0 > 0); | ||
| 3412 | assert (Q <= - (LONG_MIN / 2)); | ||
| 3413 | assert (Q >= - (LONG_MAX / 2)); | ||
| 3414 | assert (mpz_cmp_ui (n, 4) > 0); | ||
| 3415 | assert (mpz_odd_p (n)); | ||
| 3416 | |||
| 3417 | mpz_init_set_ui (U, 1); /* U1 = 1 */ | ||
| 3418 | mpz_set_ui (V, 1); /* V1 = 1 */ | ||
| 3419 | mpz_set_si (Qk, Q); | ||
| 3420 | |||
| 3421 | for (bs = mpz_sizeinbase (n, 2) - 1; --bs >= b0;) | ||
| 3422 | { | ||
| 3423 | /* U_{2k} <- U_k * V_k */ | ||
| 3424 | mpz_mul (U, U, V); | ||
| 3425 | /* V_{2k} <- V_k ^ 2 - 2Q^k */ | ||
| 3426 | /* Q^{2k} = (Q^k)^2 */ | ||
| 3427 | gmp_lucas_step_k_2k (V, Qk, n); | ||
| 3428 | |||
| 3429 | /* A step k->k+1 is performed if the bit in $n$ is 1 */ | ||
| 3430 | /* mpz_tstbit(n,bs) or the the bit is 0 in $n$ but */ | ||
| 3431 | /* should be 1 in $n+1$ (bs == b0) */ | ||
| 3432 | if (b0 == bs || mpz_tstbit (n, bs)) | ||
| 3433 | { | ||
| 3434 | /* Q^{k+1} <- Q^k * Q */ | ||
| 3435 | mpz_mul_si (Qk, Qk, Q); | ||
| 3436 | /* U_{k+1} <- (U_k + V_k) / 2 */ | ||
| 3437 | mpz_swap (U, V); /* Keep in V the old value of U_k */ | ||
| 3438 | mpz_add (U, U, V); | ||
| 3439 | /* We have to compute U/2, so we need an even value, */ | ||
| 3440 | /* equivalent (mod n) */ | ||
| 3441 | if (mpz_odd_p (U)) | ||
| 3442 | mpz_add (U, U, n); | ||
| 3443 | mpz_tdiv_q_2exp (U, U, 1); | ||
| 3444 | /* V_{k+1} <-(D*U_k + V_k) / 2 = | ||
| 3445 | U_{k+1} + (D-1)/2*U_k = U_{k+1} - 2Q*U_k */ | ||
| 3446 | mpz_mul_si (V, V, -2*Q); | ||
| 3447 | mpz_add (V, U, V); | ||
| 3448 | mpz_tdiv_r (V, V, n); | ||
| 3449 | } | ||
| 3450 | mpz_tdiv_r (U, U, n); | ||
| 3451 | } | ||
| 3452 | |||
| 3453 | res = U->_mp_size == 0; | ||
| 3454 | mpz_clear (U); | ||
| 3455 | return res; | ||
| 3456 | } | ||
| 3457 | |||
| 3458 | /* Performs strong Lucas' test on x, with parameters suggested */ | ||
| 3459 | /* for the BPSW test. Qk is only passed to recycle a variable. */ | ||
| 3460 | /* Requires GCD (x,6) = 1.*/ | ||
| 3461 | static int | ||
| 3462 | gmp_stronglucas (const mpz_t x, mpz_t Qk) | ||
| 3463 | { | ||
| 3464 | mp_bitcnt_t b0; | ||
| 3465 | mpz_t V, n; | ||
| 3466 | mp_limb_t maxD, D; /* The absolute value is stored. */ | ||
| 3467 | long Q; | ||
| 3468 | mp_limb_t tl; | ||
| 3469 | |||
| 3470 | /* Test on the absolute value. */ | ||
| 3471 | mpz_roinit_normal_n (n, x->_mp_d, GMP_ABS (x->_mp_size)); | ||
| 3472 | |||
| 3473 | assert (mpz_odd_p (n)); | ||
| 3474 | /* assert (mpz_gcd_ui (NULL, n, 6) == 1); */ | ||
| 3475 | if (mpz_root (Qk, n, 2)) | ||
| 3476 | return 0; /* A square is composite. */ | ||
| 3477 | |||
| 3478 | /* Check Ds up to square root (in case, n is prime) | ||
| 3479 | or avoid overflows */ | ||
| 3480 | maxD = (Qk->_mp_size == 1) ? Qk->_mp_d [0] - 1 : GMP_LIMB_MAX; | ||
| 3481 | |||
| 3482 | D = 3; | ||
| 3483 | /* Search a D such that (D/n) = -1 in the sequence 5,-7,9,-11,.. */ | ||
| 3484 | /* For those Ds we have (D/n) = (n/|D|) */ | ||
| 3485 | do | ||
| 3486 | { | ||
| 3487 | if (D >= maxD) | ||
| 3488 | return 1 + (D != GMP_LIMB_MAX); /* (1 + ! ~ D) */ | ||
| 3489 | D += 2; | ||
| 3490 | tl = mpz_tdiv_ui (n, D); | ||
| 3491 | if (tl == 0) | ||
| 3492 | return 0; | ||
| 3493 | } | ||
| 3494 | while (gmp_jacobi_coprime (tl, D) == 1); | ||
| 3495 | |||
| 3496 | mpz_init (V); | ||
| 3497 | |||
| 3498 | /* n-(D/n) = n+1 = d*2^{b0}, with d = (n>>b0) | 1 */ | ||
| 3499 | b0 = mpz_scan0 (n, 0); | ||
| 3500 | |||
| 3501 | /* D= P^2 - 4Q; P = 1; Q = (1-D)/4 */ | ||
| 3502 | Q = (D & 2) ? (D >> 2) + 1 : -(long) (D >> 2); | ||
| 3503 | |||
| 3504 | if (! gmp_lucas_mod (V, Qk, Q, b0, n)) /* If Ud != 0 */ | ||
| 3505 | while (V->_mp_size != 0 && --b0 != 0) /* while Vk != 0 */ | ||
| 3506 | /* V <- V ^ 2 - 2Q^k */ | ||
| 3507 | /* Q^{2k} = (Q^k)^2 */ | ||
| 3508 | gmp_lucas_step_k_2k (V, Qk, n); | ||
| 3509 | |||
| 3510 | mpz_clear (V); | ||
| 3511 | return (b0 != 0); | ||
| 3512 | } | ||
| 3513 | |||
| 3412 | static int | 3514 | static int |
| 3413 | gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y, | 3515 | gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y, |
| 3414 | const mpz_t q, mp_bitcnt_t k) | 3516 | const mpz_t q, mp_bitcnt_t k) |
| @@ -3470,21 +3572,26 @@ mpz_probab_prime_p (const mpz_t n, int reps) | |||
| 3470 | if (mpz_cmpabs_ui (n, 31*31) < 0) | 3572 | if (mpz_cmpabs_ui (n, 31*31) < 0) |
| 3471 | return 2; | 3573 | return 2; |
| 3472 | 3574 | ||
| 3473 | /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] = | ||
| 3474 | j^2 + j + 41 using Euler's polynomial. We potentially stop early, | ||
| 3475 | if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps > | ||
| 3476 | 30 (a[30] == 971 > 31*31 == 961). */ | ||
| 3477 | |||
| 3478 | mpz_init (nm1); | 3575 | mpz_init (nm1); |
| 3479 | mpz_init (q); | 3576 | mpz_init (q); |
| 3480 | mpz_init (y); | ||
| 3481 | 3577 | ||
| 3482 | /* Find q and k, where q is odd and n = 1 + 2**k * q. */ | 3578 | /* Find q and k, where q is odd and n = 1 + 2**k * q. */ |
| 3483 | nm1->_mp_size = mpz_abs_sub_ui (nm1, n, 1); | 3579 | mpz_abs (nm1, n); |
| 3580 | nm1->_mp_d[0] -= 1; | ||
| 3484 | k = mpz_scan1 (nm1, 0); | 3581 | k = mpz_scan1 (nm1, 0); |
| 3485 | mpz_tdiv_q_2exp (q, nm1, k); | 3582 | mpz_tdiv_q_2exp (q, nm1, k); |
| 3486 | 3583 | ||
| 3487 | for (j = 0, is_prime = 1; is_prime & (j < reps); j++) | 3584 | /* BPSW test */ |
| 3585 | mpz_init_set_ui (y, 2); | ||
| 3586 | is_prime = gmp_millerrabin (n, nm1, y, q, k) && gmp_stronglucas (n, y); | ||
| 3587 | reps -= 24; /* skip the first 24 repetitions */ | ||
| 3588 | |||
| 3589 | /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] = | ||
| 3590 | j^2 + j + 41 using Euler's polynomial. We potentially stop early, | ||
| 3591 | if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps > | ||
| 3592 | 30 (a[30] == 971 > 31*31 == 961). */ | ||
| 3593 | |||
| 3594 | for (j = 0; is_prime & (j < reps); j++) | ||
| 3488 | { | 3595 | { |
| 3489 | mpz_set_ui (y, (unsigned long) j*j+j+41); | 3596 | mpz_set_ui (y, (unsigned long) j*j+j+41); |
| 3490 | if (mpz_cmp (y, nm1) >= 0) | 3597 | if (mpz_cmp (y, nm1) >= 0) |
| @@ -3552,7 +3659,7 @@ mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index) | |||
| 3552 | { | 3659 | { |
| 3553 | /* d < 0. Check if any of the bits below is set: If so, our bit | 3660 | /* d < 0. Check if any of the bits below is set: If so, our bit |
| 3554 | must be complemented. */ | 3661 | must be complemented. */ |
| 3555 | if (shift > 0 && (w << (GMP_LIMB_BITS - shift)) > 0) | 3662 | if (shift > 0 && (mp_limb_t) (w << (GMP_LIMB_BITS - shift)) > 0) |
| 3556 | return bit ^ 1; | 3663 | return bit ^ 1; |
| 3557 | while (--limb_index >= 0) | 3664 | while (--limb_index >= 0) |
| 3558 | if (d->_mp_d[limb_index] > 0) | 3665 | if (d->_mp_d[limb_index] > 0) |
| @@ -3659,8 +3766,8 @@ mpz_combit (mpz_t d, mp_bitcnt_t bit_index) | |||
| 3659 | void | 3766 | void |
| 3660 | mpz_com (mpz_t r, const mpz_t u) | 3767 | mpz_com (mpz_t r, const mpz_t u) |
| 3661 | { | 3768 | { |
| 3662 | mpz_neg (r, u); | 3769 | mpz_add_ui (r, u, 1); |
| 3663 | mpz_sub_ui (r, r, 1); | 3770 | mpz_neg (r, r); |
| 3664 | } | 3771 | } |
| 3665 | 3772 | ||
| 3666 | void | 3773 | void |
| @@ -4000,7 +4107,7 @@ mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit) | |||
| 4000 | } | 4107 | } |
| 4001 | 4108 | ||
| 4002 | /* Mask to 0 all bits before starting_bit, thus ignoring them. */ | 4109 | /* Mask to 0 all bits before starting_bit, thus ignoring them. */ |
| 4003 | limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS)); | 4110 | limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS); |
| 4004 | } | 4111 | } |
| 4005 | 4112 | ||
| 4006 | return mpn_common_scan (limb, i, up, un, ux); | 4113 | return mpn_common_scan (limb, i, up, un, ux); |
| @@ -4030,7 +4137,7 @@ mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit) | |||
| 4030 | limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */ | 4137 | limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */ |
| 4031 | 4138 | ||
| 4032 | /* Mask all bits before starting_bit, thus ignoring them. */ | 4139 | /* Mask all bits before starting_bit, thus ignoring them. */ |
| 4033 | limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS)); | 4140 | limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS); |
| 4034 | 4141 | ||
| 4035 | return mpn_common_scan (limb, i, up, un, ux); | 4142 | return mpn_common_scan (limb, i, up, un, ux); |
| 4036 | } | 4143 | } |
diff --git a/src/mini-gmp.h b/src/mini-gmp.h index 2586d32db9e..27e0c0671a2 100644 --- a/src/mini-gmp.h +++ b/src/mini-gmp.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* mini-gmp, a minimalistic implementation of a GNU GMP subset. | 1 | /* mini-gmp, a minimalistic implementation of a GNU GMP subset. |
| 2 | 2 | ||
| 3 | Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc. | 3 | Copyright 2011-2015, 2017 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of the GNU MP Library. | 5 | This file is part of the GNU MP Library. |
| 6 | 6 | ||