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

mercurial at gmplib.org mercurial at gmplib.org
Thu Apr 26 21:58:38 UTC 2018


details:   /var/hg/gmp/rev/674f1e68a71b
changeset: 17602:674f1e68a71b
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Thu Apr 26 23:31:31 2018 +0200
description:
mini-mpq and its tests

details:   /var/hg/gmp/rev/e189cc126cc2
changeset: 17603:e189cc126cc2
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Thu Apr 26 23:34:35 2018 +0200
description:
Changelog

details:   /var/hg/gmp/rev/49c5e550ec8e
changeset: 17604:49c5e550ec8e
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Thu Apr 26 23:37:52 2018 +0200
description:
mpq/: Support lazy mpq_t also in the denominator.

diffstat:

 ChangeLog                          |    4 +
 Makefile.am                        |    1 +
 mini-gmp/ChangeLog                 |    8 +
 mini-gmp/mini-mpq.c                |  388 +++++++++++++++++++++++++++++++++++++
 mini-gmp/mini-mpq.h                |   82 +++++++
 mini-gmp/tests/Makefile            |    7 +-
 mini-gmp/tests/t-mpq_addsub.c      |  164 +++++++++++++++
 mini-gmp/tests/t-mpq_muldiv.c      |  160 +++++++++++++++
 mini-gmp/tests/t-mpq_muldiv_2exp.c |  138 +++++++++++++
 mini-gmp/tests/testutils.c         |    1 +
 mpq/clear.c                        |    3 +-
 mpq/clears.c                       |    3 +-
 mpq/div.c                          |    9 +-
 mpq/inp_str.c                      |    2 +-
 mpq/md_2exp.c                      |    2 +-
 mpq/mul.c                          |    2 +-
 mpq/set_d.c                        |    4 +-
 mpq/set_f.c                        |    4 +-
 mpq/set_si.c                       |    2 +-
 mpq/set_str.c                      |    2 +-
 mpq/set_ui.c                       |    2 +-
 mpq/set_z.c                        |    2 +-
 22 files changed, 968 insertions(+), 22 deletions(-)

diffs (truncated from 1200 to 300 lines):

diff -r 765c2c27523b -r 49c5e550ec8e ChangeLog
--- a/ChangeLog	Wed Apr 25 07:38:14 2018 +0200
+++ b/ChangeLog	Thu Apr 26 23:37:52 2018 +0200
@@ -1,3 +1,7 @@
+2018-04-26 Marco Bodrato <bodrato at mail.dm.unipi.it>
+
+	* Makefile.am (EXTRA_DIST): Add mini-gmp/mini-mpq.[ch].
+
 2018-04-23 Marco Bodrato <bodrato at mail.dm.unipi.it>
 
 	* mpn/generic/toom2_sqr.c: Handle the cy=-1 branch slightly faster.
diff -r 765c2c27523b -r 49c5e550ec8e Makefile.am
--- a/Makefile.am	Wed Apr 25 07:38:14 2018 +0200
+++ b/Makefile.am	Thu Apr 26 23:37:52 2018 +0200
@@ -406,6 +406,7 @@
 
 # Distribute mini-gmp. Test sources copied by dist-hook.
 EXTRA_DIST += mini-gmp/README mini-gmp/mini-gmp.c mini-gmp/mini-gmp.h \
+	      mini-gmp/mini-mpq.c mini-gmp/mini-mpq.h \
 	      mini-gmp/tests/Makefile mini-gmp/tests/run-tests
 
 # Avoid: CVS - cvs directories
diff -r 765c2c27523b -r 49c5e550ec8e mini-gmp/ChangeLog
--- a/mini-gmp/ChangeLog	Wed Apr 25 07:38:14 2018 +0200
+++ b/mini-gmp/ChangeLog	Thu Apr 26 23:37:52 2018 +0200
@@ -1,3 +1,11 @@
+2018-04-26 Marco Bodrato <bodrato at mail.dm.unipi.it>
+
+	* mini-gmp/mini-mpq.c: New file, mini-implementation of mpq_t.
+	* mini-gmp/mini-mpq.h: New file, definitions for mpq_t.
+	* mini-gmp/tests/t-mpq_addsub: New tests for mpq_add and sub.
+	* mini-gmp/tests/t-mpq_muldiv: New tests for mpq_mul and div.
+	* mini-gmp/tests/t-mpq_muldiv_2exp: New tests for mpq_*_2exp.
+
 2018-03-11  Niels Möller  <nisse at lysator.liu.se>
 
 	* mini-gmp.c (mpn_div_qr_2_preinv): Drop separate rp argument.
diff -r 765c2c27523b -r 49c5e550ec8e mini-gmp/mini-mpq.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mini-gmp/mini-mpq.c	Thu Apr 26 23:37:52 2018 +0200
@@ -0,0 +1,388 @@
+/* mini-mpq, a minimalistic implementation of a GNU GMP subset.
+
+   Contributed to the GNU project by Marco Bodrato
+
+Copyright 2018 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+  * the GNU Lesser General Public License as published by the Free
+    Software Foundation; either version 3 of the License, or (at your
+    option) any later version.
+
+or
+
+  * the GNU General Public License as published by the Free Software
+    Foundation; either version 2 of the License, or (at your option) any
+    later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library.  If not,
+see https://www.gnu.org/licenses/.  */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mini-mpq.h"
+
+#ifndef GMP_LIMB_HIGHBIT
+/* Define macros and static functions already defined by mini-gmp.c */
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1))
+#define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1))
+#define GMP_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+static mpz_srcptr
+mpz_roinit_normal_n (mpz_t x, mp_srcptr xp, mp_size_t xs)
+{
+  x->_mp_alloc = 0;
+  x->_mp_d = (mp_ptr) xp;
+  x->_mp_size = xs;
+  return x;
+}
+
+static void
+gmp_die (const char *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+  abort();
+}
+#endif
+
+

+/* MPQ helper functions */
+static mpq_srcptr
+mpq_roinit_normal_n (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);
+  mpz_roinit_normal_n (mpq_denref(x), dp, ds);
+  return x;
+}
+
+static mpq_srcptr
+mpq_roinit_z (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);
+}
+
+void
+mpq_init (mpq_t x)
+{
+  mpz_init (mpq_numref (x));
+  mpz_init_set_ui (mpq_denref (x), 1);
+}
+
+void
+mpq_clear (mpq_t x)
+{
+  mpz_clear (mpq_numref (x));
+  mpz_clear (mpq_denref (x));
+}
+
+static void
+mpq_canonical_sign (mpq_t r)
+{
+  int cmp = mpq_denref (r)->_mp_size;
+  if (cmp <= 0)
+    {
+      if (cmp == 0)
+	gmp_die("mpq: Fraction with zero denominator.");
+      mpz_neg (mpq_denref (r), mpq_denref (r));
+      mpz_neg (mpq_numref (r), mpq_numref (r));
+    }
+}
+
+static void
+mpq_helper_canonicalize (mpq_t r, const mpq_t c, mpz_t g)
+{
+  if (mpq_numref (c)->_mp_size == 0)
+    mpq_set_ui (r, 0, 1);
+  else
+    {
+      mpz_gcd (g, mpq_numref (c), mpq_denref (c));
+      mpz_tdiv_q (mpq_numref (r), mpq_numref (c), g);
+      mpz_tdiv_q (mpq_denref (r), mpq_denref (c), g);
+      mpq_canonical_sign (r);
+    }
+}
+
+void
+mpq_canonicalize (mpq_t r)
+{
+  mpz_t t;
+
+  mpz_init (t);
+  mpq_helper_canonicalize (r, r, t);
+  mpz_clear (t);
+}
+
+void
+mpq_swap (mpq_t a, mpq_t b)
+{
+  mpz_swap (mpq_numref (a), mpq_numref (b));
+  mpz_swap (mpq_denref (a), mpq_denref (b));
+}
+
+

+/* MPQ assignment and conversions. */
+void
+mpz_set_q (mpz_t r, const mpq_t q)
+{
+  mpz_tdiv_q (r, mpq_numref (q), mpq_denref (q));
+}
+
+void
+mpq_set (mpq_t r, const mpq_t q)
+{
+  mpz_set (mpq_numref (r), mpq_numref (q));
+  mpz_set (mpq_denref (r), mpq_denref (q));
+}
+
+void
+mpq_set_ui (mpq_t r, unsigned long n, unsigned long d)
+{
+  assert (d != 0);
+
+  mpz_set_ui (mpq_numref (r), n);
+  mpz_set_ui (mpq_denref (r), d);
+}
+
+void
+mpq_set_si (mpq_t r, signed long n, unsigned long d)
+{
+  assert (d != 0);
+
+  mpz_set_si (mpq_numref (r), n);
+  mpz_set_ui (mpq_denref (r), d);
+}
+
+void
+mpq_set_z (mpq_t r, const mpz_t n)
+{
+  mpz_set_ui (mpq_denref (r), 1);
+  mpz_set (mpq_numref (r), n);
+}
+
+void
+mpq_set_num (mpq_t r, const mpz_t z)
+{
+  mpz_set (mpq_numref (r), z);
+}
+
+void
+mpq_set_den (mpq_t r, const mpz_t z)
+{
+  assert (z->_mp_size != 0);
+  mpz_set (mpq_denref (r), z);
+}
+
+void
+mpq_get_num (mpz_t r, const mpq_t q)
+{
+  mpz_set (r, mpq_numref (q));
+}
+
+void
+mpq_get_den (mpz_t r, const mpq_t q)
+{
+  mpz_set (r, mpq_denref (q));
+}
+
+

+/* MPQ comparisons and the like. */
+int
+mpq_cmp (const mpq_t a, const mpq_t b)
+{
+  mpz_t t1, t2;
+  int res;
+
+  mpz_init (t1);
+  mpz_init (t2);
+  mpz_mul (t1, mpq_numref (a), mpq_denref (b));
+  mpz_mul (t2, mpq_numref (b), mpq_denref (a));
+  res = mpz_cmp (t1, t2);
+  mpz_clear (t1);
+  mpz_clear (t2);
+
+  return res;
+}
+
+int
+mpq_cmp_z (const mpq_t a, const mpz_t b)
+{
+  mpz_t t;
+  int res;
+
+  mpz_init (t);
+  mpz_mul (t, b, mpq_denref (a));
+  res = mpz_cmp (mpq_numref (a), t);
+  mpz_clear (t);
+
+  return res;
+}
+
+int
+mpq_equal (const mpq_t a, const mpq_t b)
+{
+  return (mpz_cmp (mpq_numref (a), mpq_numref (b)) == 0) &&
+    (mpz_cmp (mpq_denref (a), mpq_denref (b)) == 0);
+}
+
+int
+mpq_cmp_ui (const mpq_t q, unsigned long n, unsigned long d)
+{
+  mpq_t t;
+  assert (d != 0);
+  return mpq_cmp (q, mpq_roinit_normal_n (t, &n, n != 0, &d, 1));
+}
+
+int
+mpq_cmp_si (const mpq_t q, signed long n, unsigned long d)
+{
+  assert (d != 0);
+
+  if (n >= 0)
+    return mpq_cmp_ui (q, n, d);


More information about the gmp-commit mailing list