summaryrefslogtreecommitdiffstats
path: root/contrib/libgmp/mpq
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>1996-10-20 08:49:26 +0000
committermarkm <markm@FreeBSD.org>1996-10-20 08:49:26 +0000
commit6ec01646dc55b6fa688ed5906e0d52556d174da2 (patch)
treeecc4c214d76efa8e1b2fb33ac2f0aab18ea03ebf /contrib/libgmp/mpq
downloadFreeBSD-src-6ec01646dc55b6fa688ed5906e0d52556d174da2.zip
FreeBSD-src-6ec01646dc55b6fa688ed5906e0d52556d174da2.tar.gz
Clean import of libgmp 2.0.2, with only the non-x86 bits removed.
BMakefiles and other bits will follow. Requested by: Andrey Chernov Made world by: Chuck Robey
Diffstat (limited to 'contrib/libgmp/mpq')
-rw-r--r--contrib/libgmp/mpq/Makefile.in81
-rw-r--r--contrib/libgmp/mpq/add.c85
-rw-r--r--contrib/libgmp/mpq/canonicalize.c53
-rw-r--r--contrib/libgmp/mpq/clear.c37
-rw-r--r--contrib/libgmp/mpq/cmp.c120
-rw-r--r--contrib/libgmp/mpq/cmp_ui.c84
-rw-r--r--contrib/libgmp/mpq/configure.in12
-rw-r--r--contrib/libgmp/mpq/div.c93
-rw-r--r--contrib/libgmp/mpq/equal.c43
-rw-r--r--contrib/libgmp/mpq/get_d.c151
-rw-r--r--contrib/libgmp/mpq/get_den.c41
-rw-r--r--contrib/libgmp/mpq/get_num.c42
-rw-r--r--contrib/libgmp/mpq/init.c40
-rw-r--r--contrib/libgmp/mpq/inv.c75
-rw-r--r--contrib/libgmp/mpq/mul.c79
-rw-r--r--contrib/libgmp/mpq/neg.c36
-rw-r--r--contrib/libgmp/mpq/set.c49
-rw-r--r--contrib/libgmp/mpq/set_den.c42
-rw-r--r--contrib/libgmp/mpq/set_num.c42
-rw-r--r--contrib/libgmp/mpq/set_si.c54
-rw-r--r--contrib/libgmp/mpq/set_ui.c50
-rw-r--r--contrib/libgmp/mpq/set_z.c46
-rw-r--r--contrib/libgmp/mpq/sub.c85
-rw-r--r--contrib/libgmp/mpq/tests/Makefile.in48
-rw-r--r--contrib/libgmp/mpq/tests/configure.in11
-rw-r--r--contrib/libgmp/mpq/tests/t-cmp.c109
-rw-r--r--contrib/libgmp/mpq/tests/t-cmp_ui.c102
-rw-r--r--contrib/libgmp/mpq/tests/t-get_d.c88
28 files changed, 1798 insertions, 0 deletions
diff --git a/contrib/libgmp/mpq/Makefile.in b/contrib/libgmp/mpq/Makefile.in
new file mode 100644
index 0000000..f34ffb9
--- /dev/null
+++ b/contrib/libgmp/mpq/Makefile.in
@@ -0,0 +1,81 @@
+# Makefile for GNU MP/mpq functions
+# Copyright (C) 1991, 1993, 1994, 1996 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 the GNU Library General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+
+# 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 Library General Public
+# License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA.
+
+srcdir = .
+
+CC = gcc
+
+CFLAGS = -g -O
+AR = ar
+AR_FLAGS = rc
+SHELL = /bin/sh
+
+#### host and target specific makefile fragments come in here.
+###
+
+MPQ_SRCS = add.c canonicalize.c clear.c cmp.c cmp_ui.c div.c get_d.c \
+ get_den.c get_num.c init.c inv.c mul.c neg.c set.c set_den.c set_num.c \
+ set_si.c set_ui.c sub.c equal.c set_z.c
+MPQ_OBJS = add.o canonicalize.o clear.o cmp.o cmp_ui.o div.o get_d.o \
+ get_den.o get_num.o init.o inv.o mul.o neg.o set.o set_den.o set_num.o \
+ set_si.o set_ui.o sub.o equal.o set_z.o
+
+INCLUDES = -I. -I.. -I../mpn -I$(srcdir)/..
+
+libmpq.a: Makefile $(MPQ_OBJS)
+ rm -f $@
+ $(AR) $(AR_FLAGS) $@ $(MPQ_OBJS)
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+clean mostlyclean:
+ rm -f *.o libmpq.a
+ -cd tests; $(MAKE) $@
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+ -cd tests; $(MAKE) $@
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
+
+H = $(srcdir)/../gmp.h $(srcdir)/../gmp-impl.h ../mpn/gmp-mparam.h
+
+add.o: $(srcdir)/add.c $(H)
+canonicalize.o: $(srcdir)/canonicalize.c $(H)
+clear.o: $(srcdir)/clear.c $(H)
+cmp.o: $(srcdir)/cmp.c $(H) $(srcdir)/../longlong.h
+cmp_ui.o: $(srcdir)/cmp_ui.c $(H)
+div.o: $(srcdir)/div.c $(H)
+equal.o: $(srcdir)/equal.c $(H)
+get_d.o: $(srcdir)/get_d.c $(H) $(srcdir)/../longlong.h
+get_den.o: $(srcdir)/get_den.c $(H)
+get_num.o: $(srcdir)/get_num.c $(H)
+init.o: $(srcdir)/init.c $(H)
+inv.o: $(srcdir)/inv.c $(H)
+mul.o: $(srcdir)/mul.c $(H)
+neg.o: $(srcdir)/neg.c $(H)
+set.o: $(srcdir)/set.c $(H)
+set_den.o: $(srcdir)/set_den.c $(H)
+set_num.o: $(srcdir)/set_num.c $(H)
+set_si.o: $(srcdir)/set_si.c $(H)
+set_ui.o: $(srcdir)/set_ui.c $(H)
+set_z.o: $(srcdir)/set_z.c $(H)
+sub.o: $(srcdir)/sub.c $(H)
diff --git a/contrib/libgmp/mpq/add.c b/contrib/libgmp/mpq/add.c
new file mode 100644
index 0000000..6b98b46
--- /dev/null
+++ b/contrib/libgmp/mpq/add.c
@@ -0,0 +1,85 @@
+/* mpq_add -- add two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_add (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_add (rop, op1, op2)
+ mpq_ptr rop;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd;
+ mpz_t tmp1, tmp2;
+ mp_size_t op1_num_size = ABS (op1->_mp_num._mp_size);
+ mp_size_t op1_den_size = ABS (op1->_mp_den._mp_size);
+ mp_size_t op2_num_size = ABS (op2->_mp_num._mp_size);
+ mp_size_t op2_den_size = ABS (op2->_mp_den._mp_size);
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ MPZ_TMP_INIT (gcd, MIN (op1_den_size, op2_den_size));
+ MPZ_TMP_INIT (tmp1, op1_num_size + op2_den_size);
+ MPZ_TMP_INIT (tmp2, op2_num_size + op1_den_size);
+
+ /* ROP might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of ROP when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd, &(op1->_mp_den), &(op2->_mp_den));
+ if (gcd->_mp_size > 1 || gcd->_mp_d[0] != 1)
+ {
+ mpz_t t;
+
+ mpz_divexact (tmp1, &(op2->_mp_den), gcd);
+ mpz_mul (tmp1, &(op1->_mp_num), tmp1);
+
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd);
+ mpz_mul (tmp2, &(op2->_mp_num), tmp2);
+
+ MPZ_TMP_INIT (t, MAX (ABS (tmp1->_mp_size), ABS (tmp2->_mp_size)) + 1);
+
+ mpz_add (t, tmp1, tmp2);
+ mpz_divexact (tmp1, &(op1->_mp_den), gcd);
+ mpz_gcd (gcd, t, gcd);
+
+ mpz_divexact (&(rop->_mp_num), t, gcd);
+
+ mpz_divexact (tmp2, &(op2->_mp_den), gcd);
+ mpz_mul (&(rop->_mp_den), tmp1, tmp2);
+ }
+ else
+ {
+ /* The common divisor is 1. This is the case (for random input) with
+ probability 6/(pi**2). */
+ mpz_mul (tmp1, &(op1->_mp_num), &(op2->_mp_den));
+ mpz_mul (tmp2, &(op2->_mp_num), &(op1->_mp_den));
+ mpz_add (&(rop->_mp_num), tmp1, tmp2);
+ mpz_mul (&(rop->_mp_den), &(op1->_mp_den), &(op2->_mp_den));
+ }
+ TMP_FREE (marker);
+}
diff --git a/contrib/libgmp/mpq/canonicalize.c b/contrib/libgmp/mpq/canonicalize.c
new file mode 100644
index 0000000..901e6eb
--- /dev/null
+++ b/contrib/libgmp/mpq/canonicalize.c
@@ -0,0 +1,53 @@
+/* mpq_canonicalize(op) -- Remove common factors of the denominator and
+ numerator in OP.
+
+Copyright (C) 1991, 1994, 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_canonicalize (MP_RAT *op)
+#else
+mpq_canonicalize (op)
+ MP_RAT *op;
+#endif
+{
+ mpz_t gcd;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* ??? Dunno if the 1+ is needed. */
+ MPZ_TMP_INIT (gcd, 1 + MAX (ABS (op->_mp_num._mp_size),
+ ABS (op->_mp_den._mp_size)));
+
+ mpz_gcd (gcd, &(op->_mp_num), &(op->_mp_den));
+ mpz_divexact (&(op->_mp_num), &(op->_mp_num), gcd);
+ mpz_divexact (&(op->_mp_den), &(op->_mp_den), gcd);
+
+ if (op->_mp_den._mp_size < 0)
+ {
+ op->_mp_num._mp_size = -op->_mp_num._mp_size;
+ op->_mp_den._mp_size = -op->_mp_den._mp_size;
+ }
+ TMP_FREE (marker);
+}
diff --git a/contrib/libgmp/mpq/clear.c b/contrib/libgmp/mpq/clear.c
new file mode 100644
index 0000000..2837cf2
--- /dev/null
+++ b/contrib/libgmp/mpq/clear.c
@@ -0,0 +1,37 @@
+/* mpq_clear -- free the space occupied by a MP_RAT.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_clear (MP_RAT *m)
+#else
+mpq_clear (m)
+ MP_RAT *m;
+#endif
+{
+ (*_mp_free_func) (m->_mp_num._mp_d,
+ m->_mp_num._mp_alloc * BYTES_PER_MP_LIMB);
+ (*_mp_free_func) (m->_mp_den._mp_d,
+ m->_mp_den._mp_alloc * BYTES_PER_MP_LIMB);
+}
diff --git a/contrib/libgmp/mpq/cmp.c b/contrib/libgmp/mpq/cmp.c
new file mode 100644
index 0000000..fc530e3
--- /dev/null
+++ b/contrib/libgmp/mpq/cmp.c
@@ -0,0 +1,120 @@
+/* mpq_cmp(u,v) -- Compare U, V. Return postive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991, 1994, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+int
+#if __STDC__
+mpq_cmp (const MP_RAT *op1, const MP_RAT *op2)
+#else
+mpq_cmp (op1, op2)
+ const MP_RAT *op1;
+ const MP_RAT *op2;
+#endif
+{
+ mp_size_t num1_size = op1->_mp_num._mp_size;
+ mp_size_t den1_size = op1->_mp_den._mp_size;
+ mp_size_t num2_size = op2->_mp_num._mp_size;
+ mp_size_t den2_size = op2->_mp_den._mp_size;
+ mp_size_t tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_size_t num1_sign;
+ int cc;
+ TMP_DECL (marker);
+
+ if (num1_size == 0)
+ return -num2_size;
+ if (num2_size == 0)
+ return num1_size;
+ if ((num1_size ^ num2_size) < 0) /* I.e. are the signs different? */
+ return num1_size;
+
+ num1_sign = num1_size;
+ num1_size = ABS (num1_size);
+ num2_size = ABS (num2_size);
+
+ tmp1_size = num1_size + den2_size;
+ tmp2_size = num2_size + den1_size;
+
+ /* 1. Check to see if we can tell which operand is larger by just looking at
+ the number of limbs. */
+
+ /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
+ Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
+ if (tmp1_size > tmp2_size + 1)
+ /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
+ return num1_sign;
+ if (tmp2_size > tmp1_size + 1)
+ /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
+ return -num1_sign;
+
+ /* 2. Same, but compare the number of significant bits. */
+ {
+ int cnt1, cnt2;
+ unsigned long int bits1, bits2;
+
+ count_leading_zeros (cnt1, op1->_mp_num._mp_d[num1_size - 1]);
+ count_leading_zeros (cnt2, op2->_mp_den._mp_d[den2_size - 1]);
+ bits1 = tmp1_size * BITS_PER_MP_LIMB - cnt1 - cnt2;
+
+ count_leading_zeros (cnt1, op2->_mp_num._mp_d[num2_size - 1]);
+ count_leading_zeros (cnt2, op1->_mp_den._mp_d[den1_size - 1]);
+ bits2 = tmp2_size * BITS_PER_MP_LIMB - cnt1 - cnt2;
+
+ if (bits1 > bits2 + 1)
+ return num1_sign;
+ if (bits2 > bits1 + 1)
+ return -num1_sign;
+ }
+
+ /* 3. Finally, cross multiply and compare. */
+
+ TMP_MARK (marker);
+ tmp1_ptr = (mp_ptr) TMP_ALLOC (tmp1_size * BYTES_PER_MP_LIMB);
+ tmp2_ptr = (mp_ptr) TMP_ALLOC (tmp2_size * BYTES_PER_MP_LIMB);
+
+ if (num1_size >= den2_size)
+ tmp1_size -= 0 == mpn_mul (tmp1_ptr,
+ op1->_mp_num._mp_d, num1_size,
+ op2->_mp_den._mp_d, den2_size);
+ else
+ tmp1_size -= 0 == mpn_mul (tmp1_ptr,
+ op2->_mp_den._mp_d, den2_size,
+ op1->_mp_num._mp_d, num1_size);
+
+ if (num2_size >= den1_size)
+ tmp2_size -= 0 == mpn_mul (tmp2_ptr,
+ op2->_mp_num._mp_d, num2_size,
+ op1->_mp_den._mp_d, den1_size);
+ else
+ tmp2_size -= 0 == mpn_mul (tmp2_ptr,
+ op1->_mp_den._mp_d, den1_size,
+ op2->_mp_num._mp_d, num2_size);
+
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+ TMP_FREE (marker);
+ return num1_sign < 0 ? -cc : cc;
+}
diff --git a/contrib/libgmp/mpq/cmp_ui.c b/contrib/libgmp/mpq/cmp_ui.c
new file mode 100644
index 0000000..bdecec5
--- /dev/null
+++ b/contrib/libgmp/mpq/cmp_ui.c
@@ -0,0 +1,84 @@
+/* mpq_cmp_ui(u,vn,vd) -- Compare U with Vn/Vd. Return positive, zero, or
+ negative based on if U > V, U == V, or U < V. Vn and Vd may have
+ common factors.
+
+Copyright (C) 1993, 1994, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* gmp.h defines a macro for mpq_cmp_ui. */
+#undef mpq_cmp_ui
+
+int
+#if __STDC__
+mpq_cmp_ui (const MP_RAT *op1, unsigned long int num2, unsigned long int den2)
+#else
+mpq_cmp_ui (op1, num2, den2)
+ const MP_RAT *op1;
+ unsigned long int num2;
+ unsigned long int den2;
+#endif
+{
+ mp_size_t num1_size = op1->_mp_num._mp_size;
+ mp_size_t den1_size = op1->_mp_den._mp_size;
+ mp_size_t tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_size_t num1_sign;
+ mp_limb_t cy_limb;
+ int cc;
+ TMP_DECL (marker);
+
+ if (num1_size == 0)
+ return -(num2 != 0);
+ if (num1_size < 0)
+ return num1_size;
+ if (num2 == 0)
+ return num1_size;
+
+ num1_sign = num1_size;
+ num1_size = ABS (num1_size);
+
+ /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
+ Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
+ if (num1_size > den1_size + 1)
+ /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
+ return num1_sign;
+ if (den1_size > num1_sign + 1)
+ /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
+ return -num1_sign;
+
+ TMP_MARK (marker);
+ tmp1_ptr = (mp_ptr) TMP_ALLOC ((num1_size + 1) * BYTES_PER_MP_LIMB);
+ tmp2_ptr = (mp_ptr) TMP_ALLOC ((den1_size + 1) * BYTES_PER_MP_LIMB);
+
+ cy_limb = mpn_mul_1 (tmp1_ptr, op1->_mp_num._mp_d, num1_size, den2);
+ tmp1_ptr[num1_size] = cy_limb;
+ tmp1_size = num1_size + (cy_limb != 0);
+
+ cy_limb = mpn_mul_1 (tmp2_ptr, op1->_mp_den._mp_d, den1_size, num2);
+ tmp2_ptr[den1_size] = cy_limb;
+ tmp2_size = den1_size + (cy_limb != 0);
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+ TMP_FREE (marker);
+ return (num1_sign < 0) ? -cc : cc;
+}
diff --git a/contrib/libgmp/mpq/configure.in b/contrib/libgmp/mpq/configure.in
new file mode 100644
index 0000000..b5d501c
--- /dev/null
+++ b/contrib/libgmp/mpq/configure.in
@@ -0,0 +1,12 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=tests
+srctrigger=cmp_ui.c
+srcname="GNU Multi-Precision library/mpq"
+
+# per-host:
+
+# per-target:
+
diff --git a/contrib/libgmp/mpq/div.c b/contrib/libgmp/mpq/div.c
new file mode 100644
index 0000000..cd1f3881
--- /dev/null
+++ b/contrib/libgmp/mpq/div.c
@@ -0,0 +1,93 @@
+/* mpq_div -- divide two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_div (mpq_ptr quot, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_div (quot, op1, op2)
+ mpq_ptr quot;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd1, gcd2;
+ mpz_t tmp1, tmp2;
+ mpz_t numtmp;
+
+ mpz_init (gcd1);
+ mpz_init (gcd2);
+ mpz_init (tmp1);
+ mpz_init (tmp2);
+ mpz_init (numtmp);
+
+ /* QUOT might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of QUOT when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd1, &(op1->_mp_num), &(op2->_mp_num));
+ mpz_gcd (gcd2, &(op2->_mp_den), &(op1->_mp_den));
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op1->_mp_num), gcd1);
+ else
+ mpz_set (tmp1, &(op1->_mp_num));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op2->_mp_den), gcd2);
+ else
+ mpz_set (tmp2, &(op2->_mp_den));
+
+ mpz_mul (numtmp, tmp1, tmp2);
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op2->_mp_num), gcd1);
+ else
+ mpz_set (tmp1, &(op2->_mp_num));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd2);
+ else
+ mpz_set (tmp2, &(op1->_mp_den));
+
+ mpz_mul (&(quot->_mp_den), tmp1, tmp2);
+
+ /* We needed to go via NUMTMP to take care of QUOT being the same
+ as either input operands. Now move NUMTMP to QUOT->_mp_num. */
+ mpz_set (&(quot->_mp_num), numtmp);
+
+ /* Keep the denominator positive. */
+ if (quot->_mp_den._mp_size < 0)
+ {
+ quot->_mp_den._mp_size = -quot->_mp_den._mp_size;
+ quot->_mp_num._mp_size = -quot->_mp_num._mp_size;
+ }
+
+ mpz_clear (numtmp);
+ mpz_clear (tmp2);
+ mpz_clear (tmp1);
+ mpz_clear (gcd2);
+ mpz_clear (gcd1);
+}
diff --git a/contrib/libgmp/mpq/equal.c b/contrib/libgmp/mpq/equal.c
new file mode 100644
index 0000000..2b4bb5b
--- /dev/null
+++ b/contrib/libgmp/mpq/equal.c
@@ -0,0 +1,43 @@
+/* mpq_equal(u,v) -- Compare U, V. Return non-zero if they are equal, zero
+ if they are non-equal.
+
+Copyright (C) 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpq_equal (mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_equal (op1, op2)
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mp_size_t num1_size = op1->_mp_num._mp_size;
+ mp_size_t den1_size = op1->_mp_den._mp_size;
+ mp_size_t num2_size = op2->_mp_num._mp_size;
+ mp_size_t den2_size = op2->_mp_den._mp_size;
+
+ return (num1_size == num2_size && den1_size == den2_size
+ && mpn_cmp (op1->_mp_num._mp_d, op2->_mp_num._mp_d, num1_size) == 0
+ && mpn_cmp (op1->_mp_den._mp_d, op2->_mp_den._mp_d, den1_size) == 0);
+}
diff --git a/contrib/libgmp/mpq/get_d.c b/contrib/libgmp/mpq/get_d.c
new file mode 100644
index 0000000..cb4e800
--- /dev/null
+++ b/contrib/libgmp/mpq/get_d.c
@@ -0,0 +1,151 @@
+/* double mpq_get_d (mpq_t src) -- Return the double approximation to SRC.
+
+Copyright (C) 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Algorithm:
+ 1. Develop >= n bits of src.num / src.den, where n is the number of bits
+ in a double. This (partial) division will use all bits from the
+ denominator.
+ 2. Use the remainder to determine how to round the result.
+ 3. Assign the integral result to a temporary double.
+ 4. Scale the temporary double, and return the result.
+
+ An alternative algorithm, that would be faster:
+ 0. Let n be somewhat larger than the number of significant bits in a double.
+ 1. Extract the most significant n bits of the denominator, and an equal
+ number of bits from the numerator.
+ 2. Interpret the extracted numbers as integers, call them a and b
+ respectively, and develop n bits of the fractions ((a + 1) / b) and
+ (a / (b + 1)) using mpn_divrem.
+ 3. If the computed values are identical UP TO THE POSITION WE CARE ABOUT,
+ we are done. If they are different, repeat the algorithm from step 1,
+ but first let n = n * 2.
+ 4. If we end up using all bits from the numerator and denominator, fall
+ back to the first algorithm above.
+ 5. Just to make life harder, The computation of a + 1 and b + 1 above
+ might give carry-out... Needs special handling. It might work to
+ subtract 1 in both cases instead.
+*/
+
+double
+#if __STDC__
+mpq_get_d (const MP_RAT *src)
+#else
+mpq_get_d (src)
+ const MP_RAT *src;
+#endif
+{
+ mp_ptr np, dp;
+ mp_ptr rp;
+ mp_size_t nsize = src->_mp_num._mp_size;
+ mp_size_t dsize = src->_mp_den._mp_size;
+ mp_size_t qsize, rsize;
+ mp_size_t sign_quotient = nsize ^ dsize;
+ unsigned normalization_steps;
+ mp_limb_t qlimb;
+#define N_QLIMBS (1 + (sizeof (double) + BYTES_PER_MP_LIMB-1) / BYTES_PER_MP_LIMB)
+ mp_limb_t qp[N_QLIMBS + 1];
+ TMP_DECL (marker);
+
+ if (nsize == 0)
+ return 0.0;
+
+ TMP_MARK (marker);
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+ np = src->_mp_num._mp_d;
+ dp = src->_mp_den._mp_d;
+
+ rsize = dsize + N_QLIMBS;
+ rp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ numerator the same number of steps (to keep the quotient the same!). */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant limb. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ if (rsize > nsize)
+ {
+ MPN_ZERO (rp, rsize - nsize);
+ nlimb = mpn_lshift (rp + (rsize - nsize),
+ np, nsize, normalization_steps);
+ }
+ else
+ {
+ nlimb = mpn_lshift (rp, np + (nsize - rsize),
+ rsize, normalization_steps);
+ }
+ if (nlimb != 0)
+ {
+ rp[rsize] = nlimb;
+ rsize++;
+ }
+ }
+ else
+ {
+ if (rsize > nsize)
+ {
+ MPN_ZERO (rp, rsize - nsize);
+ MPN_COPY (rp + (rsize - nsize), np, nsize);
+ }
+ else
+ {
+ MPN_COPY (rp, np + (nsize - rsize), rsize);
+ }
+ }
+
+ qlimb = mpn_divmod (qp, rp, rsize, dp, dsize);
+ qsize = rsize - dsize;
+ if (qlimb)
+ {
+ qp[qsize] = qlimb;
+ qsize++;
+ }
+
+ {
+ double res;
+ mp_size_t i;
+
+ res = qp[qsize - 1];
+ for (i = qsize - 2; i >= 0; i--)
+ res = res * MP_BASE_AS_DOUBLE + qp[i];
+
+ res = __gmp_scale2 (res, BITS_PER_MP_LIMB * (nsize - dsize - N_QLIMBS));
+
+ TMP_FREE (marker);
+ return sign_quotient >= 0 ? res : -res;
+ }
+}
diff --git a/contrib/libgmp/mpq/get_den.c b/contrib/libgmp/mpq/get_den.c
new file mode 100644
index 0000000..fc5e387
--- /dev/null
+++ b/contrib/libgmp/mpq/get_den.c
@@ -0,0 +1,41 @@
+/* mpq_get_den(den,rat_src) -- Set DEN to the denominator of RAT_SRC.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_get_den (MP_INT *den, const MP_RAT *src)
+#else
+mpq_get_den (den, src)
+ MP_INT *den;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t size = src->_mp_den._mp_size;
+
+ if (den->_mp_alloc < size)
+ _mpz_realloc (den, size);
+
+ MPN_COPY (den->_mp_d, src->_mp_den._mp_d, size);
+ den->_mp_size = size;
+}
diff --git a/contrib/libgmp/mpq/get_num.c b/contrib/libgmp/mpq/get_num.c
new file mode 100644
index 0000000..61f812f
--- /dev/null
+++ b/contrib/libgmp/mpq/get_num.c
@@ -0,0 +1,42 @@
+ /* mpq_get_num(num,rat_src) -- Set NUM to the numerator of RAT_SRC.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_get_num (MP_INT *num, const MP_RAT *src)
+#else
+mpq_get_num (num, src)
+ MP_INT *num;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t size = src->_mp_num._mp_size;
+ mp_size_t abs_size = ABS (size);
+
+ if (num->_mp_alloc < abs_size)
+ _mpz_realloc (num, abs_size);
+
+ MPN_COPY (num->_mp_d, src->_mp_num._mp_d, abs_size);
+ num->_mp_size = size;
+}
diff --git a/contrib/libgmp/mpq/init.c b/contrib/libgmp/mpq/init.c
new file mode 100644
index 0000000..ae6d8b3
--- /dev/null
+++ b/contrib/libgmp/mpq/init.c
@@ -0,0 +1,40 @@
+/* mpq_init -- Make a new rational number with value 0/1.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_init (MP_RAT *x)
+#else
+mpq_init (x)
+ MP_RAT *x;
+#endif
+{
+ x->_mp_num._mp_alloc = 1;
+ x->_mp_num._mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ x->_mp_num._mp_size = 0;
+ x->_mp_den._mp_alloc = 1;
+ x->_mp_den._mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ x->_mp_den._mp_d[0] = 1;
+ x->_mp_den._mp_size = 1;
+}
diff --git a/contrib/libgmp/mpq/inv.c b/contrib/libgmp/mpq/inv.c
new file mode 100644
index 0000000..745c78d
--- /dev/null
+++ b/contrib/libgmp/mpq/inv.c
@@ -0,0 +1,75 @@
+/* mpq_inv(dest,src) -- invert a rational number, i.e. set DEST to SRC
+ with the numerator and denominator swapped.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_inv (MP_RAT *dest, const MP_RAT *src)
+#else
+mpq_inv (dest, src)
+ MP_RAT *dest;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t num_size = src->_mp_num._mp_size;
+ mp_size_t den_size = src->_mp_den._mp_size;
+
+ if (num_size == 0)
+ num_size = 1 / num_size; /* Divide by zero! */
+
+ if (num_size < 0)
+ {
+ num_size = -num_size;
+ den_size = -den_size;
+ }
+ dest->_mp_den._mp_size = num_size;
+ dest->_mp_num._mp_size = den_size;
+
+ /* If dest == src we may just swap the numerator and denominator, but
+ we have to ensure the new denominator is positive. */
+
+ if (dest == src)
+ {
+ mp_size_t alloc = dest->_mp_num._mp_alloc;
+ mp_ptr limb_ptr = dest->_mp_num._mp_d;
+
+ dest->_mp_num._mp_alloc = dest->_mp_den._mp_alloc;
+ dest->_mp_num._mp_d = dest->_mp_den._mp_d;
+
+ dest->_mp_den._mp_alloc = alloc;
+ dest->_mp_den._mp_d = limb_ptr;
+ }
+ else
+ {
+ den_size = ABS (den_size);
+ if (dest->_mp_num._mp_alloc < den_size)
+ _mpz_realloc (&(dest->_mp_num), den_size);
+
+ if (dest->_mp_den._mp_alloc < num_size)
+ _mpz_realloc (&(dest->_mp_den), num_size);
+
+ MPN_COPY (dest->_mp_num._mp_d, src->_mp_den._mp_d, den_size);
+ MPN_COPY (dest->_mp_den._mp_d, src->_mp_num._mp_d, num_size);
+ }
+}
diff --git a/contrib/libgmp/mpq/mul.c b/contrib/libgmp/mpq/mul.c
new file mode 100644
index 0000000..35f960c
--- /dev/null
+++ b/contrib/libgmp/mpq/mul.c
@@ -0,0 +1,79 @@
+/* mpq_mul -- mutiply two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_mul (mpq_ptr prod, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_mul (prod, op1, op2)
+ mpq_ptr prod;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd1, gcd2;
+ mpz_t tmp1, tmp2;
+
+ mpz_init (gcd1);
+ mpz_init (gcd2);
+ mpz_init (tmp1);
+ mpz_init (tmp2);
+
+ /* PROD might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of PROD when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd1, &(op1->_mp_num), &(op2->_mp_den));
+ mpz_gcd (gcd2, &(op2->_mp_num), &(op1->_mp_den));
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op1->_mp_num), gcd1);
+ else
+ mpz_set (tmp1, &(op1->_mp_num));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op2->_mp_num), gcd2);
+ else
+ mpz_set (tmp2, &(op2->_mp_num));
+
+ mpz_mul (&(prod->_mp_num), tmp1, tmp2);
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op2->_mp_den), gcd1);
+ else
+ mpz_set (tmp1, &(op2->_mp_den));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd2);
+ else
+ mpz_set (tmp2, &(op1->_mp_den));
+
+ mpz_mul (&(prod->_mp_den), tmp1, tmp2);
+
+ mpz_clear (tmp2);
+ mpz_clear (tmp1);
+ mpz_clear (gcd2);
+ mpz_clear (gcd1);
+}
diff --git a/contrib/libgmp/mpq/neg.c b/contrib/libgmp/mpq/neg.c
new file mode 100644
index 0000000..ac54d27
--- /dev/null
+++ b/contrib/libgmp/mpq/neg.c
@@ -0,0 +1,36 @@
+/* mpq_neg(dst, src) -- Assign the negated value of SRC to DST.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_neg (MP_RAT *dst, const MP_RAT *src)
+#else
+mpq_neg (dst, src)
+ MP_RAT *dst;
+ const MP_RAT *src;
+#endif
+{
+ mpz_neg (&dst->_mp_num, &src->_mp_num);
+ mpz_set (&dst->_mp_den, &src->_mp_den);
+}
diff --git a/contrib/libgmp/mpq/set.c b/contrib/libgmp/mpq/set.c
new file mode 100644
index 0000000..ef85639
--- /dev/null
+++ b/contrib/libgmp/mpq/set.c
@@ -0,0 +1,49 @@
+/* mpq_set(dest,src) -- Set DEST to SRC.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set (MP_RAT *dest, const MP_RAT *src)
+#else
+mpq_set (dest, src)
+ MP_RAT *dest;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t num_size, den_size;
+ mp_size_t abs_num_size;
+
+ num_size = src->_mp_num._mp_size;
+ abs_num_size = ABS (num_size);
+ if (dest->_mp_num._mp_alloc < abs_num_size)
+ _mpz_realloc (&(dest->_mp_num), abs_num_size);
+ MPN_COPY (dest->_mp_num._mp_d, src->_mp_num._mp_d, abs_num_size);
+ dest->_mp_num._mp_size = num_size;
+
+ den_size = src->_mp_den._mp_size;
+ if (dest->_mp_den._mp_alloc < den_size)
+ _mpz_realloc (&(dest->_mp_den), den_size);
+ MPN_COPY (dest->_mp_den._mp_d, src->_mp_den._mp_d, den_size);
+ dest->_mp_den._mp_size = den_size;
+}
diff --git a/contrib/libgmp/mpq/set_den.c b/contrib/libgmp/mpq/set_den.c
new file mode 100644
index 0000000..4586c89
--- /dev/null
+++ b/contrib/libgmp/mpq/set_den.c
@@ -0,0 +1,42 @@
+/* mpq_set_den(dest,den) -- Set the denominator of DEST from DEN.
+
+Copyright (C) 1991, 1994, 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_den (MP_RAT *dest, const MP_INT *den)
+#else
+mpq_set_den (dest, den)
+ MP_RAT *dest;
+ const MP_INT *den;
+#endif
+{
+ mp_size_t size = den->_mp_size;
+ mp_size_t abs_size = ABS (size);
+
+ if (dest->_mp_den._mp_alloc < abs_size)
+ _mpz_realloc (&(dest->_mp_den), abs_size);
+
+ MPN_COPY (dest->_mp_den._mp_d, den->_mp_d, abs_size);
+ dest->_mp_den._mp_size = abs_size;
+}
diff --git a/contrib/libgmp/mpq/set_num.c b/contrib/libgmp/mpq/set_num.c
new file mode 100644
index 0000000..ce918ce
--- /dev/null
+++ b/contrib/libgmp/mpq/set_num.c
@@ -0,0 +1,42 @@
+/* mpq_set_num(dest,num) -- Set the numerator of DEST from NUM.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_num (MP_RAT *dest, const MP_INT *num)
+#else
+mpq_set_num (dest, num)
+ MP_RAT *dest;
+ const MP_INT *num;
+#endif
+{
+ mp_size_t size = num->_mp_size;
+ mp_size_t abs_size = ABS (size);
+
+ if (dest->_mp_num._mp_alloc < abs_size)
+ _mpz_realloc (&(dest->_mp_num), abs_size);
+
+ MPN_COPY (dest->_mp_num._mp_d, num->_mp_d, abs_size);
+ dest->_mp_num._mp_size = size;
+}
diff --git a/contrib/libgmp/mpq/set_si.c b/contrib/libgmp/mpq/set_si.c
new file mode 100644
index 0000000..cf1f9f0
--- /dev/null
+++ b/contrib/libgmp/mpq/set_si.c
@@ -0,0 +1,54 @@
+/* mpq_set_si(dest,ulong_num,ulong_den) -- Set DEST to the retional number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_si (MP_RAT *dest, signed long int num, unsigned long int den)
+#else
+mpq_set_si (dest, num, den)
+ MP_RAT *dest;
+ signed long int num;
+ unsigned long int den;
+#endif
+{
+ unsigned long int abs_num;
+
+ abs_num = ABS (num);
+
+ if (num == 0)
+ {
+ /* Canonicalize 0/d to 0/1. */
+ den = 1;
+ dest->_mp_num._mp_size = 0;
+ }
+ else
+ {
+ dest->_mp_num._mp_d[0] = abs_num;
+ dest->_mp_num._mp_size = num > 0 ? 1 : -1;
+ }
+
+ dest->_mp_den._mp_d[0] = den;
+ dest->_mp_den._mp_size = 1;
+}
diff --git a/contrib/libgmp/mpq/set_ui.c b/contrib/libgmp/mpq/set_ui.c
new file mode 100644
index 0000000..aaa9fc2
--- /dev/null
+++ b/contrib/libgmp/mpq/set_ui.c
@@ -0,0 +1,50 @@
+/* mpq_set_ui(dest,ulong_num,ulong_den) -- Set DEST to the retional number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright (C) 1991, 1994, 1995 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_ui (MP_RAT *dest, unsigned long int num, unsigned long int den)
+#else
+mpq_set_ui (dest, num, den)
+ MP_RAT *dest;
+ unsigned long int num;
+ unsigned long int den;
+#endif
+{
+ if (num == 0)
+ {
+ /* Canonicalize 0/n to 0/1. */
+ den = 1;
+ dest->_mp_num._mp_size = 0;
+ }
+ else
+ {
+ dest->_mp_num._mp_d[0] = num;
+ dest->_mp_num._mp_size = 1;
+ }
+
+ dest->_mp_den._mp_d[0] = den;
+ dest->_mp_den._mp_size = 1;
+}
diff --git a/contrib/libgmp/mpq/set_z.c b/contrib/libgmp/mpq/set_z.c
new file mode 100644
index 0000000..ca638f3
--- /dev/null
+++ b/contrib/libgmp/mpq/set_z.c
@@ -0,0 +1,46 @@
+/* mpq_set_z (dest,src) -- Set DEST to SRC.
+
+Copyright (C) 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_z (mpq_ptr dest, mpz_srcptr src)
+#else
+mpq_set_z (dest, src)
+ mpq_ptr dest;
+ mpz_srcptr src;
+#endif
+{
+ mp_size_t num_size;
+ mp_size_t abs_num_size;
+
+ num_size = src->_mp_size;
+ abs_num_size = ABS (num_size);
+ if (dest->_mp_num._mp_alloc < abs_num_size)
+ _mpz_realloc (&(dest->_mp_num), abs_num_size);
+ MPN_COPY (dest->_mp_num._mp_d, src->_mp_d, abs_num_size);
+ dest->_mp_num._mp_size = num_size;
+
+ dest->_mp_den._mp_d[0] = 1;
+ dest->_mp_den._mp_size = 1;
+}
diff --git a/contrib/libgmp/mpq/sub.c b/contrib/libgmp/mpq/sub.c
new file mode 100644
index 0000000..9274ff8
--- /dev/null
+++ b/contrib/libgmp/mpq/sub.c
@@ -0,0 +1,85 @@
+/* mpq_sub -- subtract two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_sub (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_sub (rop, op1, op2)
+ mpq_ptr rop;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd;
+ mpz_t tmp1, tmp2;
+ mp_size_t op1_num_size = ABS (op1->_mp_num._mp_size);
+ mp_size_t op1_den_size = ABS (op1->_mp_den._mp_size);
+ mp_size_t op2_num_size = ABS (op2->_mp_num._mp_size);
+ mp_size_t op2_den_size = ABS (op2->_mp_den._mp_size);
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ MPZ_TMP_INIT (gcd, MIN (op1_den_size, op2_den_size));
+ MPZ_TMP_INIT (tmp1, op1_num_size + op2_den_size);
+ MPZ_TMP_INIT (tmp2, op2_num_size + op1_den_size);
+
+ /* ROP might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of ROP when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd, &(op1->_mp_den), &(op2->_mp_den));
+ if (gcd->_mp_size > 1 || gcd->_mp_d[0] != 1)
+ {
+ mpz_t t;
+
+ mpz_divexact (tmp1, &(op2->_mp_den), gcd);
+ mpz_mul (tmp1, &(op1->_mp_num), tmp1);
+
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd);
+ mpz_mul (tmp2, &(op2->_mp_num), tmp2);
+
+ MPZ_TMP_INIT (t, MAX (ABS (tmp1->_mp_size), ABS (tmp2->_mp_size)) + 1);
+
+ mpz_sub (t, tmp1, tmp2);
+ mpz_divexact (tmp1, &(op1->_mp_den), gcd);
+ mpz_gcd (gcd, t, gcd);
+
+ mpz_divexact (&(rop->_mp_num), t, gcd);
+
+ mpz_divexact (tmp2, &(op2->_mp_den), gcd);
+ mpz_mul (&(rop->_mp_den), tmp1, tmp2);
+ }
+ else
+ {
+ /* The common divisor is 1. This is the case (for random input) with
+ probability 6/(pi**2). */
+ mpz_mul (tmp1, &(op1->_mp_num), &(op2->_mp_den));
+ mpz_mul (tmp2, &(op2->_mp_num), &(op1->_mp_den));
+ mpz_sub (&(rop->_mp_num), tmp1, tmp2);
+ mpz_mul (&(rop->_mp_den), &(op1->_mp_den), &(op2->_mp_den));
+ }
+ TMP_FREE (marker);
+}
diff --git a/contrib/libgmp/mpq/tests/Makefile.in b/contrib/libgmp/mpq/tests/Makefile.in
new file mode 100644
index 0000000..d7921c0
--- /dev/null
+++ b/contrib/libgmp/mpq/tests/Makefile.in
@@ -0,0 +1,48 @@
+# Makefile for mpq/tests for GNU MP
+
+srcdir = .
+
+CC = gcc
+
+TEST_LIBS = ../../libgmp.a
+INCLUDES = -I../../mpn -I$(srcdir)/../..
+CFLAGS = -g -O
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+TEST_SRCS = t-cmp.c t-cmp_ui.c t-get_d.c
+TEST_OBJS = t-cmp.o t-cmp_ui.o t-get_d.o
+TESTS = t-cmp t-cmp_ui t-get_d
+
+check: Makefile st-cmp st-cmp_ui st-get_d
+ @echo "The tests passed."
+
+st-cmp: t-cmp
+ ./t-cmp
+ touch $@
+st-cmp_ui: t-cmp_ui
+ ./t-cmp_ui
+ touch $@
+st-get_d: t-get_d
+ ./t-get_d
+ touch $@
+
+t-cmp: t-cmp.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-cmp_ui: t-cmp_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-get_d: t-get_d.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+
+t-cmp.o: $(srcdir)/t-cmp.c
+t-cmp_ui.o: $(srcdir)/t-cmp_ui.c
+t-get_d.o: $(srcdir)/t-get_d.c
+
+clean mostlyclean:
+ rm -f *.o st-* $(TESTS)
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
diff --git a/contrib/libgmp/mpq/tests/configure.in b/contrib/libgmp/mpq/tests/configure.in
new file mode 100644
index 0000000..5ee2138
--- /dev/null
+++ b/contrib/libgmp/mpq/tests/configure.in
@@ -0,0 +1,11 @@
+# This file is a shell script that supplies the information necessary
+# to tailor a template configure script into the configure script
+# appropriate for this directory. For more information, check any
+# existing configure script.
+
+srctrigger=t-cmp.c
+srcname="gmp/mpq/tests"
+
+# per-host:
+
+# per-target:
diff --git a/contrib/libgmp/mpq/tests/t-cmp.c b/contrib/libgmp/mpq/tests/t-cmp.c
new file mode 100644
index 0000000..77e46f2
--- /dev/null
+++ b/contrib/libgmp/mpq/tests/t-cmp.c
@@ -0,0 +1,109 @@
+/* Test mpq_cmp.
+
+Copyright (C) 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#define NUM(x) (&((x)->_mp_num))
+#define DEN(x) (&((x)->_mp_den))
+
+#define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
+
+ref_mpq_cmp (a, b)
+ mpq_t a, b;
+{
+ mpz_t ai, bi;
+ int cc;
+
+ mpz_init (ai);
+ mpz_init (bi);
+
+ mpz_mul (ai, NUM (a), DEN (b));
+ mpz_mul (bi, NUM (b), DEN (a));
+ cc = mpz_cmp (ai, bi);
+ mpz_clear (ai);
+ mpz_clear (bi);
+ return cc;
+}
+
+#ifndef SIZE
+#define SIZE 8 /* increasing this lowers the probabilty of finding an error */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpq_t a, b;
+ mp_size_t size;
+ int reps = 100000;
+ int i;
+ int cc, ccref;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (a);
+ mpq_init (b);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (a), size);
+ }
+ while (mpz_cmp_ui (DEN (a), 0) == 0);
+
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (b), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (b), size);
+ }
+ while (mpz_cmp_ui (DEN (b), 0) == 0);
+
+ mpq_canonicalize (a);
+ mpq_canonicalize (b);
+
+ ccref = ref_mpq_cmp (a, b);
+ cc = mpq_cmp (a, b);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+ }
+
+ exit (0);
+}
+
+dump (x)
+ mpq_t x;
+{
+ mpz_out_str (stdout, 10, NUM (x));
+ printf ("/");
+ mpz_out_str (stdout, 10, DEN (x));
+ printf ("\n");
+}
diff --git a/contrib/libgmp/mpq/tests/t-cmp_ui.c b/contrib/libgmp/mpq/tests/t-cmp_ui.c
new file mode 100644
index 0000000..f7b92ad
--- /dev/null
+++ b/contrib/libgmp/mpq/tests/t-cmp_ui.c
@@ -0,0 +1,102 @@
+/* Test mpq_cmp_ui.
+
+Copyright (C) 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#define NUM(x) (&((x)->_mp_num))
+#define DEN(x) (&((x)->_mp_den))
+
+#define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
+
+ref_mpq_cmp_ui (a, bn, bd)
+ mpq_t a;
+ unsigned long int bn, bd;
+{
+ mpz_t ai, bi;
+ int cc;
+
+ mpz_init (ai);
+ mpz_init (bi);
+
+ mpz_mul_ui (ai, NUM (a), bd);
+ mpz_mul_ui (bi, DEN (a), bn);
+ cc = mpz_cmp (ai, bi);
+ mpz_clear (ai);
+ mpz_clear (bi);
+ return cc;
+}
+
+#ifndef SIZE
+#define SIZE 8 /* increasing this lowers the probabilty of finding an error */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpq_t a, b;
+ mp_size_t size;
+ int reps = 100000;
+ int i;
+ int cc, ccref;
+ unsigned long int bn, bd;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (a);
+ mpq_init (b);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (a), size);
+ }
+ while (mpz_cmp_ui (DEN (a), 0) == 0);
+
+ mpz_random2 (NUM (b), 1);
+ do
+ {
+ mpz_random2 (DEN (b), 1);
+ }
+ while (mpz_cmp_ui (DEN (b), 0) == 0);
+
+ mpq_canonicalize (a);
+ mpq_canonicalize (b);
+
+ bn = mpz_get_ui (NUM (b));
+ bd = mpz_get_ui (DEN (b));
+
+ ccref = ref_mpq_cmp_ui (a, bn, bd);
+ cc = mpq_cmp_ui (a, bn, bd);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+ }
+
+ exit (0);
+}
diff --git a/contrib/libgmp/mpq/tests/t-get_d.c b/contrib/libgmp/mpq/tests/t-get_d.c
new file mode 100644
index 0000000..db4f926
--- /dev/null
+++ b/contrib/libgmp/mpq/tests/t-get_d.c
@@ -0,0 +1,88 @@
+/* Test mpq_get_d
+
+Copyright (C) 1991, 1993, 1994, 1996 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 the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpq_t a;
+ mp_size_t size;
+ int reps = 10000;
+ int i, j;
+ double last_d, new_d;
+ mpz_t eps;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ /* The idea here is to test the monotonousness of mpq_get_d by adding
+ numbers to the numerator and denominator. */
+
+ mpq_init (a);
+ mpz_init (eps);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (mpq_numref (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (mpq_denref (a), size);
+ }
+ while (mpz_cmp_ui (mpq_denref (a), 0) == 0);
+
+ mpq_canonicalize (a);
+
+ last_d = mpq_get_d (a);
+ for (j = 0; j < 10; j++)
+ {
+ size = urandom () % SIZE;
+ mpz_random2 (eps, size);
+ mpz_add (mpq_numref (a), mpq_numref (a), eps);
+ mpq_canonicalize (a);
+ new_d = mpq_get_d (a);
+ if (last_d > new_d)
+ abort ();
+ last_d = new_d;
+ }
+ }
+
+ exit (0);
+}
+
+dump (x)
+ mpq_t x;
+{
+ mpz_out_str (stdout, 10, mpq_numref (x));
+ printf ("/");
+ mpz_out_str (stdout, 10, mpq_denref (x));
+ printf ("\n");
+}
OpenPOWER on IntegriCloud