diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | bootstrap.c | 1 | ||||
-rw-r--r-- | mini-gmp/ChangeLog | 5 | ||||
-rw-r--r-- | mini-gmp/mini-gmp.c | 32 |
4 files changed, 39 insertions, 3 deletions
@@ -1,3 +1,7 @@ +2018-05-20 Marco Bodrato <bodrato@mail.dm.unipi.it> + + * bootstrap.c: Define DONT_USE_FLOAT_H before including mini-gmp. + 2018-05-14 Marco Bodrato <bodrato@mail.dm.unipi.it> * mpn/generic/dcpi1_bdiv_q.c (mpn_dcpi1_bdiv_q_n): Decl. static. diff --git a/bootstrap.c b/bootstrap.c index 999178e01..5ded7f7f8 100644 --- a/bootstrap.c +++ b/bootstrap.c @@ -29,6 +29,7 @@ GNU Lesser General Public License along with the GNU MP Library. If not, see https://www.gnu.org/licenses/. */ +#define DONT_USE_FLOAT_H 1 #include "mini-gmp/mini-gmp.c" #define MIN(l,o) ((l) < (o) ? (l) : (o)) diff --git a/mini-gmp/ChangeLog b/mini-gmp/ChangeLog index c8a8675fa..58b97426e 100644 --- a/mini-gmp/ChangeLog +++ b/mini-gmp/ChangeLog @@ -1,3 +1,8 @@ +2018-05-20 Marco Bodrato <bodrato@mail.dm.unipi.it> + + * mini-gmp.c (mpz_get_d): Convert a fixed number of + bits (GMP_DBL_MANT_BITS) to avoid rounding. + 2018-04-26 Marco Bodrato <bodrato@mail.dm.unipi.it> * mini-mpq.c: New file, mini-implementation of mpq_t. diff --git a/mini-gmp/mini-gmp.c b/mini-gmp/mini-gmp.c index 360bfa942..86c6fa190 100644 --- a/mini-gmp/mini-gmp.c +++ b/mini-gmp/mini-gmp.c @@ -50,6 +50,10 @@ see https://www.gnu.org/licenses/. */ #include "mini-gmp.h" +#if !defined(DONT_USE_FLOAT_H) +#include <float.h> +#endif + /* Macros */ #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) @@ -71,6 +75,12 @@ see https://www.gnu.org/licenses/. */ #define GMP_CMP(a,b) (((a) > (b)) - ((a) < (b))) +#if defined(DBL_MANT_DIG) && FLT_RADIX == 2 +#define GMP_DBL_MANT_BITS DBL_MANT_DIG +#else +#define GMP_DBL_MANT_BITS (53) +#endif + /* Return non-zero if xp,xsize and yp,ysize overlap. If xp+xsize<=yp there's no overlap, or if yp+ysize<=xp there's no overlap. If both these are false, there's an overlap. */ @@ -1689,6 +1699,8 @@ mpz_init_set_d (mpz_t r, double x) double mpz_get_d (const mpz_t u) { + int m; + mp_limb_t l; mp_size_t un; double x; double B = 2.0 * (double) GMP_LIMB_HIGHBIT; @@ -1698,9 +1710,23 @@ mpz_get_d (const mpz_t u) if (un == 0) return 0.0; - x = u->_mp_d[--un]; - while (un > 0) - x = B*x + u->_mp_d[--un]; + l = u->_mp_d[--un]; + gmp_clz (m, l); + m = m + GMP_DBL_MANT_BITS - GMP_LIMB_BITS; + if (m < 0) + l &= GMP_LIMB_MAX << -m; + + for (x = l; --un >= 0;) + { + x = B*x; + if (m > 0) { + l = u->_mp_d[un]; + m -= GMP_LIMB_BITS; + if (m < 0) + l &= GMP_LIMB_MAX << -m; + x += l; + } + } if (u->_mp_size < 0) x = -x; |