[Gmp-commit] /var/hg/gmp: 3 new changesets

mercurial at gmplib.org mercurial at gmplib.org
Sun Sep 8 13:33:34 UTC 2019


details:   /var/hg/gmp/rev/36e148dd1555
changeset: 17876:36e148dd1555
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Sun Sep 08 15:30:43 2019 +0200
description:
mini-gmp: Full mpq support.

details:   /var/hg/gmp/rev/b536800bddb5
changeset: 17877:b536800bddb5
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Sun Sep 08 15:32:58 2019 +0200
description:
mpn/generic/div_qr_2.c: Shorter dependency chain.

details:   /var/hg/gmp/rev/b99e1bf5283a
changeset: 17878:b99e1bf5283a
user:      Seth Troisi <sethtroisi at google.com>
date:      Sun Sep 08 09:04:03 2019 +0200
description:
mpz/nextprime.c: Fixed overalloc

diffstat:

 mini-gmp/mini-mpq.c         |  155 +++++++++++++++++++++++++++++++++++++++++--
 mini-gmp/mini-mpq.h         |   25 +++++++
 mini-gmp/tests/Makefile     |    3 +-
 mini-gmp/tests/hex-random.c |   27 +++++++
 mini-gmp/tests/hex-random.h |    2 +
 mpn/generic/div_qr_2.c      |    2 +-
 mpz/nextprime.c             |    2 +-
 7 files changed, 203 insertions(+), 13 deletions(-)

diffs (truncated from 345 to 300 lines):

diff -r 1e670b6883ce -r b99e1bf5283a mini-gmp/mini-mpq.c
--- a/mini-gmp/mini-mpq.c	Sun Sep 08 15:15:04 2019 +0200
+++ b/mini-gmp/mini-mpq.c	Sun Sep 08 09:04:03 2019 +0200
@@ -37,6 +37,7 @@
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "mini-mpq.h"
 
@@ -67,7 +68,7 @@
 
 /* MPQ helper functions */
 static mpq_srcptr
-mpq_roinit_normal_n (mpq_t x, mp_srcptr np, mp_size_t ns,
+mpq_roinit_normal_nn (mpq_t x, mp_srcptr np, mp_size_t ns,
 		     mp_srcptr dp, mp_size_t ds)
 {
   mpz_roinit_normal_n (mpq_numref(x), np, ns);
@@ -76,10 +77,10 @@
 }
 
 static mpq_srcptr
-mpq_roinit_z (mpq_t x, mpz_srcptr n, mpz_srcptr d)
+mpq_roinit_zz (mpq_t x, mpz_srcptr n, mpz_srcptr d)
 {
-  return mpq_roinit_normal_n (x, n->_mp_d, n->_mp_size,
-			      d->_mp_d, d->_mp_size);
+  return mpq_roinit_normal_nn (x, n->_mp_d, n->_mp_size,
+			       d->_mp_d, d->_mp_size);
 }
 
 static void
@@ -253,7 +254,7 @@
   mpq_t t;
   assert (d != 0);
   if (sizeof (unsigned long) == sizeof (mp_limb_t))
-    return mpq_cmp (q, mpq_roinit_normal_n (t, (mp_srcptr) &n, n != 0, (mp_srcptr) &d, 1));
+    return mpq_cmp (q, mpq_roinit_normal_nn (t, (mp_srcptr) &n, n != 0, (mp_srcptr) &d, 1));
   else {
     int ret;
 
@@ -279,9 +280,9 @@
       unsigned long l_n = GMP_NEG_CAST (unsigned long, n);
 
       if (sizeof (unsigned long) == sizeof (mp_limb_t))
-	return mpq_cmp (q, mpq_roinit_normal_n (t, (mp_srcptr) &l_n, -1, (mp_srcptr) &d, 1));
+	return mpq_cmp (q, mpq_roinit_normal_nn (t, (mp_srcptr) &l_n, -1, (mp_srcptr) &d, 1));
 
-      mpq_roinit_normal_n (t, mpq_numref (q)->_mp_d, - mpq_numref (q)->_mp_size,
+      mpq_roinit_normal_nn (t, mpq_numref (q)->_mp_d, - mpq_numref (q)->_mp_size,
 		       mpq_denref (q)->_mp_d, mpq_denref (q)->_mp_size);
       return - mpq_cmp_ui (t, l_n, d);
     }
@@ -350,8 +351,8 @@
 {
   mpq_t t;
 
-  mpq_roinit_normal_n (t, mpq_numref (b)->_mp_d, - mpq_numref (b)->_mp_size,
-		       mpq_denref (b)->_mp_d, mpq_denref (b)->_mp_size);
+  mpq_roinit_normal_nn (t, mpq_numref (b)->_mp_d, - mpq_numref (b)->_mp_size,
+			mpq_denref (b)->_mp_d, mpq_denref (b)->_mp_size);
   mpq_add (r, a, t);
 }
 
@@ -359,7 +360,7 @@
 mpq_div (mpq_t r, const mpq_t a, const mpq_t b)
 {
   mpq_t t;
-  mpq_mul (r, a, mpq_roinit_z (t, mpq_denref (b), mpq_numref (b)));
+  mpq_mul (r, a, mpq_roinit_zz (t, mpq_denref (b), mpq_numref (b)));
 }
 
 void
@@ -410,3 +411,137 @@
   mpz_swap (mpq_denref (r), mpq_numref (r));
   mpq_canonical_sign (r);
 }
+
+
+/* MPQ to/from double. */
+void
+mpq_set_d (mpq_t r, double x)
+{
+  mpz_set_ui (mpq_denref (r), 1);
+
+  /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is
+     zero or infinity. */
+  if (x == x * 0.5 || x != x)
+    mpq_numref (r)->_mp_size = 0;
+  else
+    {
+      double B;
+      mp_bitcnt_t e;
+
+      B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1);
+      for (e = 0; x != x + 0.5; e += GMP_LIMB_BITS)
+	x *= B;
+
+      mpz_set_d (mpq_numref (r), x);
+      mpq_div_2exp (r, r, e);
+    }
+}
+
+double
+mpq_get_d (const mpq_t u)
+{
+  mp_bitcnt_t ne, de, ee;
+  mpz_t z;
+  double B, ret;
+
+  ne = mpz_sizeinbase (mpq_numref (u), 2);
+  de = mpz_sizeinbase (mpq_denref (u), 2);
+
+  ee = 8 * sizeof (double);
+  if (de == 1 || ne > de + ee)
+    ee = 0;
+  else
+    ee = (ee + de - ne) / GMP_LIMB_BITS + 1;
+
+  mpz_init (z);
+  mpz_mul_2exp (z, mpq_numref (u), ee * GMP_LIMB_BITS);
+  mpz_tdiv_q (z, z, mpq_denref (u));
+  ret = mpz_get_d (z);
+  mpz_clear (z);
+
+  B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1);
+  for (B = 1 / B; ee != 0; --ee)
+    ret *= B;
+
+  return ret;
+}
+
+
+/* MPQ and strings/streams. */
+char *
+mpq_get_str (char *sp, int base, const mpq_t q)
+{
+  char *res;
+  char *rden;
+  size_t len;
+
+  res = mpz_get_str (sp, base, mpq_numref (q));
+  if (res == NULL || mpz_cmp_ui (mpq_denref (q), 1) == 0)
+    return res;
+
+  len = strlen (res) + 1;
+  rden = sp ? sp + len : NULL;
+  rden = mpz_get_str (rden, base, mpq_denref (q));
+  assert (rden != NULL);
+
+  if (sp == NULL) {
+    void * (*gmp_reallocate_func) (void *, size_t, size_t);
+    void (*gmp_free_func) (void *, size_t);
+    size_t lden;
+
+    mp_get_memory_functions (NULL, &gmp_reallocate_func, &gmp_free_func);
+    lden = strlen (rden) + 1;
+    res = (char *) gmp_reallocate_func (res, 0, (lden + len) * sizeof (char));
+    memcpy (res + len, rden, lden);
+    gmp_free_func (rden, 0);
+  }
+
+  res [len - 1] = '/';
+  return res;
+}
+
+size_t
+mpq_out_str (FILE *stream, int base, const mpq_t x)
+{
+  char * str;
+  size_t len;
+  void (*gmp_free_func) (void *, size_t);
+
+  str = mpq_get_str (NULL, base, x);
+  len = strlen (str);
+  len = fwrite (str, 1, len, stream);
+  mp_get_memory_functions (NULL, NULL, &gmp_free_func);
+  gmp_free_func (str, 0);
+  return len;
+}
+
+int
+mpq_set_str (mpq_t r, const char *sp, int base)
+{
+  const char *slash;
+
+  slash = strchr (sp, '/');
+  if (slash == NULL) {
+    mpz_set_ui (mpq_denref(r), 1);
+    return mpz_set_str (mpq_numref(r), sp, base);
+  } else {
+    char *num;
+    size_t numlen;
+    int ret;
+    void * (*gmp_allocate_func) (size_t);
+    void (*gmp_free_func) (void *, size_t);
+
+    mp_get_memory_functions (&gmp_allocate_func, NULL, &gmp_free_func);
+    numlen = slash - sp;
+    num = (char *) gmp_allocate_func ((numlen + 1) * sizeof (char));
+    memcpy (num, sp, numlen);
+    num[numlen] = '\0';
+    ret = mpz_set_str (mpq_numref(r), num, base);
+    gmp_free_func (num, 0);
+
+    if (ret != 0)
+      return ret;
+
+    return mpz_set_str (mpq_denref(r), slash + 1, base);
+  }
+}
diff -r 1e670b6883ce -r b99e1bf5283a mini-gmp/mini-mpq.h
--- a/mini-gmp/mini-mpq.h	Sun Sep 08 15:15:04 2019 +0200
+++ b/mini-gmp/mini-mpq.h	Sun Sep 08 09:04:03 2019 +0200
@@ -64,23 +64,48 @@
 void mpq_div (mpq_t, const mpq_t, const mpq_t);
 void mpq_div_2exp (mpq_t, const mpq_t, mp_bitcnt_t);
 int mpq_equal (const mpq_t, const mpq_t);
+double mpq_get_d (const mpq_t);
 void mpq_get_den (mpz_t, const mpq_t);
 void mpq_get_num (mpz_t, const mpq_t);
+char * mpq_get_str (char *, int, const mpq_t q);
 void mpq_init (mpq_t);
 void mpq_inv (mpq_t, const mpq_t);
 void mpq_mul (mpq_t, const mpq_t, const mpq_t);
 void mpq_mul_2exp (mpq_t, const mpq_t, mp_bitcnt_t);
 void mpq_neg (mpq_t, const mpq_t);
 void mpq_set (mpq_t, const mpq_t);
+void mpq_set_d (mpq_t, double);
 void mpq_set_den (mpq_t, const mpz_t);
 void mpq_set_num (mpq_t, const mpz_t);
 void mpq_set_si (mpq_t, signed long, unsigned long);
+int mpq_set_str (mpq_t, const char *, int);
 void mpq_set_ui (mpq_t, unsigned long, unsigned long);
 void mpq_set_z (mpq_t, const mpz_t);
 int mpq_sgn (const mpq_t);
 void mpq_sub (mpq_t, const mpq_t, const mpq_t);
 void mpq_swap (mpq_t, mpq_t);
 
+/* This long list taken from gmp.h. */
+/* For reference, "defined(EOF)" cannot be used here.  In g++ 2.95.4,
+   <iostream> defines EOF but not FILE.  */
+#if defined (FILE)                                              \
+  || defined (H_STDIO)                                          \
+  || defined (_H_STDIO)               /* AIX */                 \
+  || defined (_STDIO_H)               /* glibc, Sun, SCO */     \
+  || defined (_STDIO_H_)              /* BSD, OSF */            \
+  || defined (__STDIO_H)              /* Borland */             \
+  || defined (__STDIO_H__)            /* IRIX */                \
+  || defined (_STDIO_INCLUDED)        /* HPUX */                \
+  || defined (__dj_include_stdio_h_)  /* DJGPP */               \
+  || defined (_FILE_DEFINED)          /* Microsoft */           \
+  || defined (__STDIO__)              /* Apple MPW MrC */       \
+  || defined (_MSL_STDIO_H)           /* Metrowerks */          \
+  || defined (_STDIO_H_INCLUDED)      /* QNX4 */                \
+  || defined (_ISO_STDIO_ISO_H)       /* Sun C++ */             \
+  || defined (__STDIO_LOADED)         /* VMS */
+size_t mpq_out_str (FILE *, int, const mpq_t);
+#endif
+
 void mpz_set_q (mpz_t, const mpq_t);
 
 #if defined (__cplusplus)
diff -r 1e670b6883ce -r b99e1bf5283a mini-gmp/tests/Makefile
--- a/mini-gmp/tests/Makefile	Sun Sep 08 15:15:04 2019 +0200
+++ b/mini-gmp/tests/Makefile	Sun Sep 08 09:04:03 2019 +0200
@@ -31,7 +31,8 @@
 	t-double t-cmp_d t-gcd t-lcm t-import t-comb t-signed \
 	t-sqrt t-root t-powm t-logops t-bitops t-scan t-str \
 	t-reuse t-aorsmul t-limbs t-cong t-pprime_p t-lucm \
-	t-mpq_addsub t-mpq_muldiv t-mpq_muldiv_2exp
+	t-mpq_addsub t-mpq_muldiv t-mpq_muldiv_2exp t-mpq_str \
+	t-mpq_double
 # Default TESTS to all tests, allowing overriding TESTS for building tests
 # without running them.
 TESTS = $(CHECK_PROGRAMS)
diff -r 1e670b6883ce -r b99e1bf5283a mini-gmp/tests/hex-random.c
--- a/mini-gmp/tests/hex-random.c	Sun Sep 08 15:15:04 2019 +0200
+++ b/mini-gmp/tests/hex-random.c	Sun Sep 08 09:04:03 2019 +0200
@@ -544,3 +544,30 @@
   mpz_clear (t1);
   mpz_clear (t2);
 }
+
+void
+hex_mpq_random_str_op (unsigned long maxbits,
+		       int base, char **ap, char **rp)
+{
+  mpq_t a;
+  unsigned long abits;
+  unsigned signs;
+
+  mpq_init (a);
+
+  abits = gmp_urandomb_ui (state, 32) % maxbits;
+
+  mpz_rrandomb (mpq_numref (a), state, abits);
+  mpz_rrandomb (mpq_denref (a), state, abits);


More information about the gmp-commit mailing list