summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Boortz <kent@mysql.se>2000-08-02 18:48:06 +0200
committerKent Boortz <kent@mysql.se>2000-08-02 18:48:06 +0200
commitefe82bb8e93212508c8b292754422df81ef8fbc2 (patch)
tree6789e688820ffb0661381f240f10f765a8286025
parenta54783120893faf758d85daee13c0a88c3296553 (diff)
downloadgmp-efe82bb8e93212508c8b292754422df81ef8fbc2.tar.gz
Experimental version of mpfr
-rw-r--r--configure.in12
-rw-r--r--mpfr/Makefile.am42
-rw-r--r--mpfr/Makefile.in423
-rw-r--r--mpfr/README81
-rw-r--r--mpfr/add.c404
-rw-r--r--mpfr/add_ulp.c64
-rw-r--r--mpfr/agm.c172
-rw-r--r--mpfr/clear.c36
-rw-r--r--mpfr/cmp.c219
-rw-r--r--mpfr/cmp_ui.c116
-rw-r--r--mpfr/div.c247
-rw-r--r--mpfr/div_2exp.c43
-rw-r--r--mpfr/div_ui.c135
-rw-r--r--mpfr/exp.c176
-rw-r--r--mpfr/get_str.c207
-rw-r--r--mpfr/init.c49
-rw-r--r--mpfr/karadiv.c137
-rw-r--r--mpfr/karasqrt.c102
-rw-r--r--mpfr/log.c150
-rw-r--r--mpfr/log2.c102
-rw-r--r--mpfr/mpfr-impl.h58
-rw-r--r--mpfr/mpfr.h204
-rw-r--r--mpfr/mpfr.texi1075
-rw-r--r--mpfr/mul.c78
-rw-r--r--mpfr/mul_2exp.c43
-rw-r--r--mpfr/mul_ui.c84
-rw-r--r--mpfr/neg.c40
-rw-r--r--mpfr/out_str.c65
-rw-r--r--mpfr/pi.c131
-rw-r--r--mpfr/pow.c67
-rw-r--r--mpfr/print_raw.c91
-rw-r--r--mpfr/print_rnd_mode.c43
-rw-r--r--mpfr/random.c74
-rw-r--r--mpfr/rnd_mode.c118
-rw-r--r--mpfr/round.c338
-rw-r--r--mpfr/set.c53
-rw-r--r--mpfr/set_d.c329
-rw-r--r--mpfr/set_dfl_prec.c37
-rw-r--r--mpfr/set_dfl_rnd.c37
-rw-r--r--mpfr/set_f.c72
-rw-r--r--mpfr/set_prec.c62
-rw-r--r--mpfr/set_si.c81
-rw-r--r--mpfr/set_str_raw.c112
-rw-r--r--mpfr/set_z.c104
-rw-r--r--mpfr/sqrt.c220
-rw-r--r--mpfr/sub.c483
-rw-r--r--mpfr/tests/Makefile.am37
-rw-r--r--mpfr/tests/Makefile.in525
-rw-r--r--mpfr/tests/dummy.c28
-rw-r--r--mpfr/tests/tadd.c414
-rw-r--r--mpfr/tests/tagm.c185
-rw-r--r--mpfr/tests/tcan_round.c40
-rw-r--r--mpfr/tests/tcmp.c73
-rw-r--r--mpfr/tests/tcmp2.c88
-rw-r--r--mpfr/tests/tcmp_ui.c58
-rw-r--r--mpfr/tests/tdiv.c152
-rw-r--r--mpfr/tests/tdiv_ui.c68
-rw-r--r--mpfr/tests/texp.c239
-rw-r--r--mpfr/tests/tget_str.c67
-rw-r--r--mpfr/tests/tlog.c303
-rw-r--r--mpfr/tests/tlog2.c44
-rw-r--r--mpfr/tests/tmul.c175
-rw-r--r--mpfr/tests/tmul_2exp.c49
-rw-r--r--mpfr/tests/tmul_ui.c66
-rw-r--r--mpfr/tests/tout_str.c85
-rw-r--r--mpfr/tests/tpi.c44
-rw-r--r--mpfr/tests/tround.c45
-rw-r--r--mpfr/tests/tset_d.c90
-rw-r--r--mpfr/tests/tset_f.c74
-rw-r--r--mpfr/tests/tset_si.c65
-rw-r--r--mpfr/tests/tset_str.c87
-rw-r--r--mpfr/tests/tset_z.c66
-rw-r--r--mpfr/tests/tsqrt.c149
-rw-r--r--mpfr/tests/tzeta.c70
-rw-r--r--mpfr/zeta.c116
75 files changed, 10517 insertions, 1 deletions
diff --git a/configure.in b/configure.in
index 108bcbdf9..24abf9c23 100644
--- a/configure.in
+++ b/configure.in
@@ -89,6 +89,16 @@ esac],
AM_CONDITIONAL(WANT_MPBSD, test "$enable_mpbsd" = "yes")
+AC_ARG_ENABLE(mpfr,
+AC_HELP_STRING([--enable-mpfr],[build MPFR [default=no]]),
+[case "${enableval}" in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value ${enableval} for --enable-mpfr, need yes or no]) ;;
+esac],
+[enable_mpfr=no])
+AM_CONDITIONAL(WANT_MPFR, test "$enable_mpfr" = "yes")
+
+
dnl Switch on OS and determine what compiler to use.
dnl
dnl os_64bit Set to "yes" if OS is 64-bit capable.
@@ -928,4 +938,4 @@ dnl FIXME: Upcoming version of autoconf/automake may not like broken lines.
AC_OUTPUT(Makefile mpf/Makefile mpz/Makefile mpn/Makefile mpq/Makefile \
mpf/tests/Makefile mpz/tests/Makefile mpq/tests/Makefile mpn/tests/Makefile \
tests/Makefile tests/rand/Makefile demos/Makefile tune/Makefile \
- mpbsd/Makefile mpbsd/tests/Makefile)
+ mpbsd/Makefile mpbsd/tests/Makefile mpfr/Makefile mpfr/tests/Makefile)
diff --git a/mpfr/Makefile.am b/mpfr/Makefile.am
new file mode 100644
index 000000000..4b617f3df
--- /dev/null
+++ b/mpfr/Makefile.am
@@ -0,0 +1,42 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright (C) 2000 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.
+
+AUTOMAKE_OPTIONS = gnu no-dependencies
+
+SUBDIRS = tests
+
+
+INCLUDES = -I$(top_srcdir)
+
+if WANT_MPFR
+noinst_LTLIBRARIES = libmpfr.la
+endif
+
+# FIXME: Add rnd_mode.c when it's clean.
+libmpfr_la_SOURCES = \
+ add.c div_2exp.c neg.c set_dfl_prec.c set_str_raw.c agm.c get_str.c \
+ print_raw.c set_dfl_rnd.c sqrt.c clear.c init.c set_f.c \
+ sub.c cmp.c mul.c round.c set_prec.c cmp_ui.c mul_2exp.c set.c \
+ set_si.c div.c mul_ui.c set_d.c pow.c out_str.c pi.c set_z.c \
+ add_ulp.c log2.c random.c log.c exp.c div_ui.c zeta.c karadiv.c \
+ karasqrt.c print_rnd_mode.c
+
+EXTRA_DIST = mpfr-impl.h
diff --git a/mpfr/Makefile.in b/mpfr/Makefile.in
new file mode 100644
index 000000000..7f694f873
--- /dev/null
+++ b/mpfr/Makefile.in
@@ -0,0 +1,423 @@
+# Makefile.in generated automatically by automake 1.4a from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_FLAG =
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+
+@SET_MAKE@
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMDEP = @AMDEP@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AWK = @AWK@
+CALLING_CONVENTIONS_OBJS = @CALLING_CONVENTIONS_OBJS@
+CC = @CC@
+CCAS = @CCAS@
+CPP = @CPP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+M4 = @M4@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+SPEED_CYCLECOUNTER_OBJS = @SPEED_CYCLECOUNTER_OBJS@
+STRIP = @STRIP@
+U = @U@
+VERSION = @VERSION@
+gmp_srclinks = @gmp_srclinks@
+install_sh = @install_sh@
+mpn_objects = @mpn_objects@
+mpn_objs_in_libgmp = @mpn_objs_in_libgmp@
+
+# Copyright (C) 2000 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.
+
+
+AUTOMAKE_OPTIONS = gnu no-dependencies
+
+SUBDIRS = tests
+
+INCLUDES = -I$(top_srcdir)
+
+@WANT_MPFR_TRUE@noinst_LTLIBRARIES = @WANT_MPFR_TRUE@libmpfr.la
+
+# FIXME: Add rnd_mode.c when it's clean.
+libmpfr_la_SOURCES = \
+ add.c div_2exp.c neg.c set_dfl_prec.c set_str_raw.c agm.c get_str.c \
+ print_raw.c set_dfl_rnd.c sqrt.c clear.c init.c set_f.c \
+ sub.c cmp.c mul.c round.c set_prec.c cmp_ui.c mul_2exp.c set.c \
+ set_si.c div.c mul_ui.c set_d.c pow.c out_str.c pi.c set_z.c \
+ add_ulp.c log2.c random.c log.c exp.c div_ui.c zeta.c karadiv.c \
+ karasqrt.c print_rnd_mode.c
+
+
+EXTRA_DIST = mpfr-impl.h
+subdir = mpfr
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libmpfr_la_LDFLAGS =
+libmpfr_la_LIBADD =
+am_libmpfr_la_OBJECTS = add.lo div_2exp.lo neg.lo set_dfl_prec.lo \
+set_str_raw.lo agm.lo get_str.lo print_raw.lo set_dfl_rnd.lo sqrt.lo \
+clear.lo init.lo set_f.lo sub.lo cmp.lo mul.lo round.lo set_prec.lo \
+cmp_ui.lo mul_2exp.lo set.lo set_si.lo div.lo mul_ui.lo set_d.lo pow.lo \
+out_str.lo pi.lo set_z.lo add_ulp.lo log2.lo random.lo log.lo exp.lo \
+div_ui.lo zeta.lo karadiv.lo karasqrt.lo print_rnd_mode.lo
+libmpfr_la_OBJECTS = $(am_libmpfr_la_OBJECTS)
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CFLAGS = @CFLAGS@
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libmpfr_la_SOURCES)
+DIST_COMMON = README Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+depcomp =
+SOURCES = $(libmpfr_la_SOURCES)
+OBJECTS = $(am_libmpfr_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu mpfr/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmpfr.la: $(libmpfr_la_OBJECTS) $(libmpfr_la_DEPENDENCIES)
+ $(LINK) $(libmpfr_la_LDFLAGS) $(libmpfr_la_OBJECTS) $(libmpfr_la_LIBADD) $(LIBS)
+.c.o:
+ $(COMPILE) -c $<
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ if test "$$subdir" = "."; then dot_seen=yes; else :; fi; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir); \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -rm -f Makefile.in
+mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-recursive \
+uninstall-recursive install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all install-strip \
+installdirs-am installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/mpfr/README b/mpfr/README
new file mode 100644
index 000000000..2915af66e
--- /dev/null
+++ b/mpfr/README
@@ -0,0 +1,81 @@
+
+ THE MPFR LIBRARY
+
+ ***** EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL *****
+ ***** EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL *****
+ ***** EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL *****
+
+This is a new function class, 'mpfr', for accurate floating-point arithmetic
+with rounding control. Unlike the 'mpf' function class, 'mpfr' is a smooth
+extension to the IEEE P754 arithmetic. In fact, setting the precision to 53,
+'mpfr' functions should work exactly like IEEE doubles.
+
+This code is *experimental* and it is not fully integrated into GMP. It is
+also not as well tested as the other parts of GMP. The original 'mpfr' library
+integrated into GMP was version 0.4.
+
+This code might at some point replace the 'mpf' library.
+
+
+
+ MORE INFORMATION
+
+This code was contributed by the French FIABLE project. Please see the 'mpfr'
+project page for more info, http://www.loria.fr/projets/mpfr/
+
+
+
+ INSTALLATION
+
+To install this package to the libgmp library you add the "--enable-mpfr" to
+configure. This has the unfortune side effect that all programs using GMP
+will also depend on 'libm'.
+
+Two test cases were disabled, 'tcmp' 'tset_d'.
+
+
+
+ REPORTING BUGS
+
+Report bugs to bug-gmp@gnu.org and mpfr@loria.fr. What information is
+needed in a good bug report is described in the manual. The same address
+can be used for suggesting modifications and enhancements.
+
+
+
+ NOTES FROM THE ORIGINAL INSTALL DOCUMENT
+
+We tested the installation with GMP 2.0.2 on the following architectures:
+
+ Pentium II and III/Linux 2.2.10
+ Alpha 21264/OSF1 V4.0
+ SGI R10000/IRIX 6.5 (both using 32- and 64-bit limbs)
+ Sun UltraSparc/Solaris 2.6
+ HP 9000/HP-UX A.09.05
+ Pentium/Windows with Cygnus compiler
+
+Known problems.
+===============
+
+1) On some architectures (for example Alpha/OSF), the default 'make' command
+ crashes in step 3. GNU make is preferred.
+
+2) Under HP-UX and Pentium/Linux, don't use the -pedantic option, otherwise
+ gcc complains with the longlong.h file from GMP.
+
+3) On the Alpha, the test file for the square root (tsqrt) may produce
+ errors as follows:
+
+ libm.a differs from mpfr_sqrt for a=9.89438396044940260000e-134, rnd_mode=2
+ libm.a gives 3.14553397063986620000e-67, mpfr_sqrt gives 3.14553397063986680000e-67 (1 ulp)
+ libm.a differs from mpfr_sqrt for a=7.86528588050363750000e+31, rnd_mode=1
+ libm.a gives 8.86864469944739500000e+15, mpfr_sqrt gives 8.86864469944739400000e+15 (-1 ulp)
+
+ Also, Linux on Alpha is known to have problems with IEEE conformance. See
+ http://www.linux.org.uk/VERSION/relnotes.2211.html.
+
+ In most cases, as above, the error comes from the libm.a. On Alpha/Linux,
+ which is known to have a bad libm.a, you may even find errors in the
+ addition or multiplication.
+
+
diff --git a/mpfr/add.c b/mpfr/add.c
new file mode 100644
index 000000000..c9bebe443
--- /dev/null
+++ b/mpfr/add.c
@@ -0,0 +1,404 @@
+/* mpfr_add -- add two floating-point numbers
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+extern void mpfr_sub1 _PROTO((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ unsigned char, int));
+
+#define ONE ((mp_limb_t) 1)
+
+/* signs of b and c are supposed equal,
+ diff_exp is the difference between the exponents of b and c,
+ which is supposed >= 0 */
+
+void
+#if __STDC__
+mpfr_add1(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
+ unsigned char rnd_mode, int diff_exp)
+#else
+mpfr_add1(a, b, c, rnd_mode, diff_exp)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+ unsigned char rnd_mode;
+ int diff_exp;
+#endif
+{
+ mp_limb_t *ap, *bp, *cp, cc, c2, c3=0; unsigned int an,bn,cn; int sh,dif,k;
+ TMP_DECL(marker);
+
+ TMP_MARK(marker);
+ ap = MANT(a);
+ bp = MANT(b);
+ cp = MANT(c);
+ if (ap == bp) {
+ bp = (mp_ptr) TMP_ALLOC(ABSSIZE(b) * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, ap, ABSSIZE(b));
+ if (ap == cp) { cp = bp; }
+ }
+ else if (ap == cp)
+ {
+ cp = (mp_ptr) TMP_ALLOC (ABSSIZE(c) * BYTES_PER_MP_LIMB);
+ MPN_COPY(cp, ap, ABSSIZE(c));
+ }
+
+ an = (PREC(a)-1)/mp_bits_per_limb+1; /* number of significant limbs of a */
+
+ sh = an*mp_bits_per_limb-PREC(a); /* non-significant bits in low limb */
+ bn = (PREC(b)-1)/mp_bits_per_limb+1; /* number of significant limbs of b */
+ EXP(a) = EXP(b);
+
+ if (SIGN(a)!=SIGN(b)) CHANGE_SIGN(a);
+
+ /* case 1: diff_exp>=prec(a), i.e. c only affects the last bit
+ through rounding */
+ dif = PREC(a)-diff_exp;
+
+ if (dif<=0) {
+
+ /* diff_exp>=PREC(a): c does not overlap with a */
+ /* either PREC(b)<=PREC(a), and we can copy the mantissa of b directly
+ into that of a, or PREC(b)>PREC(a) and we have to round b+c */
+
+ if (PREC(b)<=PREC(a)) {
+
+ MPN_COPY(ap+(an-bn), bp, bn);
+ /* fill low significant limbs with zero */
+
+ for (bp=ap;bn<an;bn++) *bp++=0;
+
+ /* now take c into account */
+ if (rnd_mode==GMP_RNDN) {
+
+ /* to nearest */
+ /* if diff_exp > PREC(a), no change */
+
+ if (diff_exp==PREC(a)) {
+
+ /* if c is not zero, then as it is normalized, we have to add
+ one to the lsb of a if c>1/2, or c=1/2 and lsb(a)=1 (round to
+ even) */
+
+ if (NOTZERO(c)) {
+
+ /* c is not zero */
+ /* check whether mant(c)=1/2 or not */
+
+ cc = *cp - (ONE<<(mp_bits_per_limb-1));
+ if (cc==0) {
+ bp = cp+(PREC(c)-1)/mp_bits_per_limb;
+ while (cp<bp && cc==0) cc = *++cp;
+ }
+
+ if (cc || (ap[an-1] & (ONE<<sh))) goto add_one_ulp;
+ /* mant(c) != 1/2 or mant(c) = 1/2: add 1 iff lsb(a)=1 */
+ }
+ }
+ }
+ else if ((ISNONNEG(b) && rnd_mode==GMP_RNDU) ||
+ (ISNEG(b) && rnd_mode==GMP_RNDD)) {
+
+ /* round up */
+ if (NOTZERO(c)) goto add_one_ulp;
+ }
+ /* in the other cases (round to zero, or up/down with sign -/+),
+ nothing to do */
+ }
+ else {
+
+ /* PREC(b)>PREC(a) : we have to round b+c */
+ k=bn-an;
+
+ /* first copy the 'an' most significant limbs of b to a */
+ MPN_COPY(ap, bp+k, an);
+ if (rnd_mode==GMP_RNDN) {
+
+ /* to nearest */
+ /* first check whether the truncated bits from b are 1/2*lsb(a) */
+
+ if (sh) {
+ cc = *ap & ((ONE<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ cc -= ONE<<(sh-1);
+ }
+ else /* no bit to truncate */
+ cc = bp[--k] - (ONE<<(mp_bits_per_limb-1));
+
+ if ((long)cc>0) goto add_one_ulp; /* trunc(b)>1/2*lsb(a) -> round up */
+ else if (cc==0) {
+
+ while (k>1 && cc==0) cc=bp[--k];
+
+ /* now if the truncated part of b = 1/2*lsb(a), check whether c=0 */
+ if (NOTZERO(c) || (*ap & (ONE<<sh))) goto add_one_ulp;
+ /* if trunc(b)+c is exactly 1/2*lsb(a) : round to even lsb */
+ }
+
+ /* if cc<0 : trunc(b) < 1/2*lsb(a) -> round down, i.e. do nothing */
+ }
+ else if ((ISNONNEG(b) && rnd_mode==GMP_RNDU) ||
+ (ISNEG(b) && rnd_mode==GMP_RNDD)) {
+
+ /* first check whether trunc(b)+c is zero or not */
+ if (sh) {
+ cc = *ap & ((ONE<<sh)-1); *ap &= ~cc; /* truncate last bits */
+ }
+ else cc = bp[--k] - (ONE<<(mp_bits_per_limb-1));
+ while (cc==0 && k>1) cc=bp[--k];
+ if (cc || NOTZERO(c)) goto add_one_ulp;
+ }
+
+ /* in the other cases (round to zero, or up/down with sign -/+),
+ nothing to do, since b and c don't overlap, there can't be any
+ carry */
+
+ }
+ }
+ else {
+ /* diff_exp < PREC(a) : c overlaps with a by dif bits */
+ /* first copy upper part of c into a (after shift) */
+ unsigned char overlap;
+
+ k = (dif-1)/mp_bits_per_limb + 1; /* only the highest k limbs from c
+ have to be considered */
+ cn = (PREC(c)-1)/mp_bits_per_limb + 1;
+ MPN_ZERO(ap+k, an-k); /* do it now otherwise ap[k] may be destroyed
+ in case dif<0 */
+
+ if (dif<=PREC(c)) {
+ /* c has to be truncated */
+ dif = dif % mp_bits_per_limb;
+ dif = (dif) ? mp_bits_per_limb-dif-sh : -sh;
+
+ /* we have to shift by dif bits to the right */
+
+ if (dif>0) mpn_rshift(ap, cp+(cn-k), k, dif);
+ else if (dif<0) {
+ ap[k] = mpn_lshift(ap, cp+(cn-k), k, -dif);
+
+ /* put the non-significant bits in low limb for further rounding */
+
+ if (cn >= k+1)
+ ap[0] += cp[cn-k-1]>>(mp_bits_per_limb+dif);
+ }
+ else MPN_COPY(ap, cp+(cn-k), k);
+ overlap=1;
+ }
+ else {
+
+ /* c is not truncated, but we have to fill low limbs with 0 */
+
+ k = diff_exp/mp_bits_per_limb;
+ overlap = diff_exp%mp_bits_per_limb;
+
+ /* warning: a shift of zero bit is not allowed */
+ MPN_ZERO(ap, an-k-cn);
+ if (overlap) {
+ cc=mpn_rshift(ap+(an-k-cn), cp, cn, overlap);
+ if (an-k-cn>0) ap[an-k-cn-1]=cc;
+ }
+ else MPN_COPY(ap+(an-k-cn), cp, cn);
+ overlap=0;
+ }
+
+ /* here overlap=1 iff ulp(c)<ulp(a) */
+ /* then put high limbs to zero */
+ /* now add 'an' upper limbs of b in place */
+
+ if (PREC(b)<=PREC(a)) {
+ overlap += 2;
+ cc = mpn_add_n(ap+(an-bn), ap+(an-bn), bp, bn);
+ }
+ else
+ /* PREC(b) > PREC(a): we have to truncate b */
+ cc = mpn_add_n(ap, ap, bp+(bn-an), an);
+
+ if (cc) {
+
+ /* shift one bit to the right */
+
+ c3 = (ap[0]&1) && (PREC(a)%mp_bits_per_limb==0);
+ mpn_rshift(ap, ap, an, 1);
+ ap[an-1] += ONE<<(mp_bits_per_limb-1);
+ EXP(a)++;
+ }
+
+ /* remains to do the rounding */
+
+ if (rnd_mode==GMP_RNDN) {
+
+ /* to nearest */
+
+ int kc;
+
+ /* four cases: overlap =
+ (0) PREC(b) > PREC(a) and diff_exp+PREC(c) <= PREC(a)
+ (1) PREC(b) > PREC(a) and diff_exp+PREC(c) > PREC(a)
+ (2) PREC(b) <= PREC(a) and diff_exp+PREC(c) <= PREC(a)
+ (3) PREC(b) <= PREC(a) and diff_exp+PREC(c) > PREC(a) */
+
+ switch (overlap)
+ {
+ case 1: /* both b and c to round */
+ kc = cn-k; /* remains kc limbs from c */
+ k = bn-an; /* remains k limbs from b */
+
+ /* truncate last bits and store the difference with 1/2*ulp in cc */
+
+ cc = *ap & ((ONE<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ cc -= ONE<<(sh-1);
+ while ((cc==0 || cc==-1) && k!=0 && kc!=0) {
+ kc--;
+ cc += mpn_add_1(&c2, bp+(--k), 1,(cp[kc+1]<<(mp_bits_per_limb-dif))
+ +(cp[kc]>>dif));
+ if (cc==0 || cc==-1) cc=c2;
+ }
+ if ((long)cc>0) goto add_one_ulp;
+ else if ((long)cc<-1)
+ { TMP_FREE(marker); return; /* the carry can be at most 1 */ }
+ else if (kc==0) goto round_b;
+
+ /* else round c: go through */
+
+ case 3: /* only c to round */
+ bp=cp; k=cn-k; goto to_nearest;
+
+ case 0: /* only b to round */
+ round_b:
+ k=bn-an; dif=0; goto to_nearest;
+
+ /* otherwise the result is exact: nothing to do */
+ }
+ }
+ else if ((ISNONNEG(b) && rnd_mode==GMP_RNDU) ||
+ (ISNEG(b) && rnd_mode==GMP_RNDD)) {
+ cc = *ap & ((ONE<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ if (cc || c3) goto add_one_ulp; /* will happen most of the time */
+ else {
+
+ /* same four cases too */
+
+ int kc = cn-k; /* remains kc limbs from c */
+ switch (overlap)
+ {
+ case 1: /* both b and c to round */
+ k = bn-an; /* remains k limbs from b */
+ while (cc==0 && k!=0 && kc!=0) {
+ kc--;
+ cc = mpn_add_1(&c2, bp+(--k), 1,(cp[kc+1]<<(mp_bits_per_limb-dif))
+ + (cp[kc]>>dif));
+ }
+ if (cc) goto add_one_ulp;
+ else if (kc==0) goto round_b2;
+ /* else round c: go through */
+ case 3: /* only c to round */
+ while (kc) if (cp[--kc]) goto add_one_ulp;
+ /* if dif>0 : remains to check last dif bits from c */
+ if (dif>0 && (cp[0]<<(mp_bits_per_limb-dif))) goto add_one_ulp;
+ break;
+ case 0: /* only b to round */
+ round_b2:
+ k=bn-an;
+ while (k) if (bp[--k]) goto add_one_ulp;
+ /* otherwise the result is exact: nothing to do */
+ }
+ }
+ }
+ /* else nothing to do: round towards zero, i.e. truncate last sh bits */
+ else
+ *ap &= ~((ONE<<sh)-1);
+ }
+ goto end_of_add;
+
+ to_nearest: /* 0 <= sh < mp_bits_per_limb : number of bits of a to truncate
+ bp[k] : last significant limb from b */
+ if (sh) {
+ cc = *ap & ((ONE<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ c2 = ONE<<(sh-1);
+ }
+ else /* no bit to truncate */
+ { if (k) cc = bp[--k]; else cc = 0; c2 = ONE<<(mp_bits_per_limb-1); }
+ if (cc>c2) goto add_one_ulp; /* trunc(b)>1/2*lsb(a) -> round up */
+ else if (cc==c2) {
+ cc=0; while (k && cc==0) cc=bp[--k];
+ /* special case of rouding c shifted to the right */
+ if (cc==0 && dif>0) cc=cp[0]<<(mp_bits_per_limb-dif);
+ /* now if the truncated part of b = 1/2*lsb(a), check whether c=0 */
+ if (cc || (*ap & (ONE<<sh))) goto add_one_ulp;
+ }
+ goto end_of_add;
+
+ add_one_ulp: /* add one unit in last place to a */
+ cc = mpn_add_1(ap, ap, an, ONE<<sh);
+ if (cc) { fprintf(stderr, "carry(3) in mpfr_add\n"); exit(1); }
+
+ end_of_add:
+ TMP_FREE(marker);
+ return;
+}
+
+void
+#if __STDC__
+mpfr_add(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
+ unsigned char rnd_mode)
+#else
+mpfr_add(a, b, c, rnd_mode)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+ unsigned char rnd_mode;
+#endif
+{
+ int diff_exp;
+
+ if (FLAG_NAN(b) || FLAG_NAN(c)) {
+ SET_NAN(a); return;
+ }
+
+ if (!NOTZERO(b)) { mpfr_set(a, c, rnd_mode); return; }
+ if (!NOTZERO(c)) { mpfr_set(a, b, rnd_mode); return; }
+
+ diff_exp = EXP(b)-EXP(c);
+ if (SIGN(b) != SIGN(c)) { /* signs differ, it's a subtraction */
+ if (diff_exp<0) {
+ mpfr_sub1(a, c, b, rnd_mode, -diff_exp);
+ }
+ else if (diff_exp>0) mpfr_sub1(a, b, c, rnd_mode, diff_exp);
+ else { /* diff_exp=0 */
+ diff_exp = mpfr_cmp3(b,c,-1);
+ /* if b>0 and diff_exp>0 or b<0 and diff_exp<0: abs(b) > abs(c) */
+ if (diff_exp==0) SET_ZERO(a);
+ else if (diff_exp*SIGN(b)>0) mpfr_sub1(a, b, c, rnd_mode, 0);
+ else mpfr_sub1(a, c, b, rnd_mode, 0);
+ }
+ }
+ else /* signs are equal, it's an addition */
+ if (diff_exp<0) mpfr_add1(a, c, b, rnd_mode, -diff_exp);
+ else mpfr_add1(a, b, c, rnd_mode, diff_exp);
+}
+
diff --git a/mpfr/add_ulp.c b/mpfr/add_ulp.c
new file mode 100644
index 000000000..7a8fa6150
--- /dev/null
+++ b/mpfr/add_ulp.c
@@ -0,0 +1,64 @@
+/* mpfr_add_one_ulp, mpfr_sub_one_ulp -- add/subtract one unit in last place
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+/* sets x to x+sign(x)*2^(EXP(x)-PREC(x)) */
+int
+#if __STDC__
+mpfr_add_one_ulp(mpfr_ptr x)
+#else
+mpfr_add_one_ulp(x)
+ mpfr_ptr x;
+#endif
+{
+ int xn, sh; mp_limb_t *xp;
+
+ xn = 1 + (PREC(x)-1)/BITS_PER_MP_LIMB;
+ sh = xn*BITS_PER_MP_LIMB - PREC(x);
+ xp = MANT(x);
+ if (mpn_add_1(xp, xp, xn, (mp_limb_t)1<<sh)) {
+ EXP(x)++;
+ mpn_rshift(xp, xp, xn, 1);
+ xp[xn-1] += (mp_limb_t)1<<(BITS_PER_MP_LIMB-1);
+ }
+ return 0;
+}
+
+/* sets x to x-sign(x)*ulp(x) */
+int mpfr_sub_one_ulp(mpfr_ptr x)
+{
+ int xn, sh; mp_limb_t *xp;
+
+ xn = 1 + (PREC(x)-1)/BITS_PER_MP_LIMB;
+ sh = xn*BITS_PER_MP_LIMB-PREC(x);
+ xp = MANT(x);
+ mpn_sub_1(xp, xp, xn, (mp_limb_t)1<<sh);
+ if (xp[xn-1] >> (BITS_PER_MP_LIMB-1) == 0) {
+ /* was an exact power of two: not normalized any more */
+ EXP(x)--;
+ mpn_lshift(xp, xp, xn, 1);
+ *xp |= ((mp_limb_t)1 << sh);
+ }
+ return 0;
+}
diff --git a/mpfr/agm.c b/mpfr/agm.c
new file mode 100644
index 000000000..e4c700961
--- /dev/null
+++ b/mpfr/agm.c
@@ -0,0 +1,172 @@
+/* mpfr_agm -- arithmetic-geometric mean of two floating-point numbers
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+
+/*Memory gestion */
+#define MON_INIT(xp, x, p, s) xp = (mp_ptr) TMP_ALLOC(s*BYTES_PER_MP_LIMB); x -> _mp_prec = p; x -> _mp_d = xp; x -> _mp_size = s; x -> _mp_exp = 0;
+
+
+
+
+void
+#ifdef __STDC__
+mpfr_agm(mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, unsigned char rnd_mode)
+#else
+mpfr_agm(r, a, b, rnd_mode)
+ mpfr_ptr r;
+ mpfr_srcptr a;
+ mpfr_srcptr b;
+ unsigned char rnd_mode;
+#endif
+{
+ int s, p, q, go_on;
+ double uo, vo;
+ mp_limb_t *up, *vp, *tmpp, *tmpup, *tmpvp, *ap, *bp;
+ mpfr_t u, v, tmp, tmpu, tmpv, a, b;
+ TMP_DECL(marker1);
+ TMP_DECL(marker2);
+
+
+ /* If a or b is NaN, the result is NaN */
+ if (FLAG_NAN(op1) || FLAG_NAN(op2))
+ { SET_NAN(r); return; }
+
+
+ /* If a or b is negative, the result is NaN */
+ if ((SIGN(op1)<0)||(SIGN(op2)<0))
+ { SET_NAN(r); return; }
+
+
+
+ /* If a or b is 0, the result is 0 */
+ if ((SIGN(op1)==0)||(SIGN(op2)==0))
+ { SET_ZERO(r);
+ return;
+ }
+
+ /* precision of the following calculus */
+ q = PREC(r);
+ p = q + 15;
+
+
+ /* Initialisations */
+ go_on=1;
+
+ TMP_MARK(marker1);
+ s=(p-1)/BITS_PER_MP_LIMB+1;
+ MON_INIT(ap, a, p, s);
+ MON_INIT(bp, b, p, s);
+ TMP_MARK(marker2);
+ MON_INIT(up, u, p, s);
+ MON_INIT(vp, v, p, s);
+ MON_INIT(tmpup, tmpu, p, s);
+ MON_INIT(tmpvp, tmpv, p, s);
+ MON_INIT(tmpp, tmp, p, s);
+
+
+
+ /* b and a will be the 2 operands but I want b>= a */
+ if (mpfr_cmp(op1,op2) > 0) {
+ mpfr_set(b,op1,GMP_RNDN); mpfr_set(a,op2,GMP_RNDN);
+ }
+ else {
+ mpfr_set(b,op2,GMP_RNDN); mpfr_set(a,op1,GMP_RNDN);
+ }
+
+ vo=mpfr_get_d(b);
+ uo=mpfr_get_d(a);
+
+ mpfr_set(u,a,GMP_RNDN);
+ mpfr_set(v,b,GMP_RNDN);
+
+
+ /* Main loop */
+
+ while (go_on) {
+ int err, eq, can_round;
+
+ eq=0;
+
+ err=ceil((3.0/2.0*log((double)p)/log(2.0)+1.0)*exp(-(double)p*log(2.0))+3.0*exp(-2.0*(double)p*uo*log(2.0)/(vo-uo)));
+ if(p-err-3<=q) {
+ p=q+err+4;
+ err=ceil((3.0/2.0*log((double)p)/log(2.0)+1.0)*exp(-(double)p*log(2.0))+3.0*exp(-2.0*(double)p*uo*log(2.0)/(vo-uo)));
+ }
+
+ /* Calculus of un and vn */
+ while (eq<=p-2) {
+ mpfr_mul(tmp,u,v,GMP_RNDN);
+ mpfr_sqrt(tmpu,tmp,GMP_RNDN);
+ mpfr_add(tmp,u,v,GMP_RNDN);
+ mpfr_div_2exp(tmpv,tmp,1,GMP_RNDN);
+ mpfr_set(u,tmpu,GMP_RNDN);
+ mpfr_set(v,tmpv,GMP_RNDN);
+ if (mpfr_cmp(v,u)>=0)
+ eq=mpfr_cmp2(v,u);
+ else
+ eq=mpfr_cmp2(u,v);
+ }
+
+ /* printf("avant can_round %i bits faux\n v : ",err+3);
+ mpfr_print_raw(v); printf("\n u : ");
+ mpfr_print_raw(u);printf("\n");*/
+
+
+ /* Roundability of the result */
+ can_round=mpfr_can_round(v,p-err-3,GMP_RNDN,rnd_mode,q);
+
+ if (can_round)
+ go_on=0;
+
+ else {
+ go_on=1;
+ p+=5;
+ TMP_FREE(marker2);
+ TMP_MARK(marker2);
+ s=(p-1)/BITS_PER_MP_LIMB+1;
+ MON_INIT(up, u, p, s);
+ MON_INIT(vp, v, p, s);
+ MON_INIT(tmpup, tmpu, p, s);
+ MON_INIT(tmpvp, tmpv, p, s);
+ MON_INIT(tmpp, tmp, p, s);
+ mpfr_set(u,a,GMP_RNDN);
+ mpfr_set(v,b,GMP_RNDN);
+ }
+ }
+ /* End of while */
+
+ /* Setting of the result */
+
+ mpfr_set(r,v,rnd_mode);
+
+
+ /* Let's clean */
+ TMP_FREE(marker1);
+
+ return ;
+}
+
diff --git a/mpfr/clear.c b/mpfr/clear.c
new file mode 100644
index 000000000..371c1a766
--- /dev/null
+++ b/mpfr/clear.c
@@ -0,0 +1,36 @@
+/* mpfr_clear -- free the memory space allocated for a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_clear (mpfr_ptr m)
+#else
+mpfr_clear (m)
+ mpfr_ptr m;
+#endif
+{
+ (*_mp_free_func) (m->_mp_d, ((m->_mp_prec>>3) + 1));
+}
diff --git a/mpfr/cmp.c b/mpfr/cmp.c
new file mode 100644
index 000000000..b64506b03
--- /dev/null
+++ b/mpfr/cmp.c
@@ -0,0 +1,219 @@
+/* mpfr_cmp -- compare two floating-point numbers
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+/* returns 0 iff b = c
+ a positive value iff b > c
+ a negative value iff b < c
+
+More precisely, in case b and c are of same sign, the absolute value
+of the result is one plus the absolute difference between the exponents
+of b and c, i.e. one plus the number of bits shifts to align b and c
+(this value is useful in mpfr_sub).
+
+*/
+
+/* #define DEBUG */
+
+/* compares b and sign(s)*c */
+int
+#if __STDC__
+mpfr_cmp3 ( mpfr_srcptr b, mpfr_srcptr c, long int s)
+#else
+mpfr_cmp3(b, c, s)
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+ long int s;
+#endif
+{
+ long int diff_exp;
+ unsigned long bn, cn;
+ mp_limb_t *bp, *cp;
+
+ if (!NOTZERO(b) && !NOTZERO(c)) { return 0; }
+ s = s*SIGN(b)*SIGN(c);
+ if (s<0) return(SIGN(b));
+
+ /* now signs are equal */
+
+ diff_exp = EXP(b)-EXP(c);
+ s = (SIGN(b)>0) ? 1 : -1;
+
+ if (diff_exp>0) return(s*(1+diff_exp));
+ else if (diff_exp<0) return(s*(-1+diff_exp));
+ /* both signs and exponents are equal */
+
+ bn = (PREC(b)-1)/mp_bits_per_limb+1;
+ cn = (PREC(c)-1)/mp_bits_per_limb+1;
+ bp = MANT(b); cp = MANT(c);
+
+ while (bn && cn) {
+ if (bp[--bn] != cp[--cn])
+ return((bp[bn]>cp[cn]) ? s : -s);
+ }
+
+ if (bn) { while (bn) if (bp[--bn]) return(s); }
+ else if (cn) while (cn) if (cp[--cn]) return(-s);
+
+ return 0;
+}
+
+/* returns the number of cancelled bits when one subtracts abs(c) from abs(b).
+ Assumes b>=c, which implies EXP(b)>=EXP(c).
+ if b=c, returns prec(b).
+*/
+int
+#if __STDC__
+mpfr_cmp2 ( mpfr_srcptr b, mpfr_srcptr c )
+#else
+mpfr_cmp2(b, c)
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+#endif
+{
+ long int d, bn, cn, k, z;
+ mp_limb_t *bp, *cp, t, u=0, cc=0;
+
+#ifdef DEBUG
+ printf("b="); mpfr_print_raw(b); putchar('\n');
+ printf("c="); mpfr_print_raw(c); putchar('\n');
+#endif
+ if (NOTZERO(c)==0) return (NOTZERO(b)) ? 0 : PREC(b);
+ d = EXP(b)-EXP(c);
+ k = 0; /* result can be d or d+1 if d>1, or >= d otherwise */
+ /* k is the number of identical bits in the high part,
+ then z is the number of possibly cancelled bits */
+#ifdef DEBUG
+ if (d<0) { printf("assumption EXP(b)<EXP(c) violated\n"); exit(1); }
+#endif
+ bn = (PREC(b)-1)/mp_bits_per_limb;
+ cn = (PREC(c)-1)/mp_bits_per_limb;
+ bp = MANT(b); cp = MANT(c);
+ /* subtract c from b from most significant to less significant limbs,
+ and first determines first non zero limb difference */
+ if (d)
+ {
+ cc = bp[bn--];
+ if (d<mp_bits_per_limb)
+ cc -= cp[cn]>>d;
+ }
+ else { /* d=0 */
+ while (bn>=0 && cn>=0 && (cc=(bp[bn--]-cp[cn--]))==0) {
+ k+=mp_bits_per_limb;
+ }
+
+ if (cc==0) { /* either bn<0 or cn<0 */
+ while (bn>=0 && (cc=bp[bn--])==0) k+=mp_bits_per_limb;
+ }
+ /* now bn<0 or cc<>0 */
+ if (cc==0 && bn<0) return(PREC(b));
+ }
+
+ /* the first non-zero limb difference is cc, and the number
+ of cancelled bits in the upper limbs is k */
+
+ count_leading_zeros(u, cc);
+ k += u;
+
+ if (cc != (1<<(mp_bits_per_limb-u-1))) return k;
+
+ /* now cc is an exact power of two */
+ if (cc != 1)
+ /* We just need to compare the following limbs */
+ /* until two of them differ. The result is either k or k+1. */
+ {
+ /* First flush all the unmatched limbs of b ; they all have to
+ be 0 in order for the process to go on */
+ while (bn >= 0)
+ {
+ if (cn < 0) { return k; }
+ t = bp[bn--];
+ if (d < mp_bits_per_limb)
+ {
+ if (d)
+ {
+ u = cp[cn--] << (mp_bits_per_limb - d);
+ if (cn >= 0) u+=(cp[cn]>>d);
+ }
+ else u = cp[cn--];
+
+ if (t > u || (t == u && cn < 0)) return k;
+ if (t < u) return k+1;
+ }
+ else
+ if (t) return k; else d -= mp_bits_per_limb;
+ }
+
+ /* bn < 0; if some limb of c is nonzero, return k+1, otherwise return k*/
+
+ if (cn>=0 && (cp[cn--] << (mp_bits_per_limb - d))) { return k+1; }
+
+ while (cn >= 0)
+ if (cp[cn--]) return k+1;
+ return k;
+ }
+
+ /* cc = 1. Too bad. */
+ z = 0; /* number of possibly cancelled bits - 1 */
+ /* thus result is either k if low(b) >= low(c)
+ or k+z+1 if low(b) < low(c) */
+ if (d > mp_bits_per_limb) { return k; }
+
+ while (bn >= 0)
+ {
+ if (cn < 0) { return k; }
+
+ if (d)
+ {
+ u = cp[cn--] << (mp_bits_per_limb - d);
+ if (cn >= 0) u+=(cp[cn]>>d);
+ }
+ else u = cp[cn--];
+
+ /* bp[bn--] > cp[cn--] : no borrow possible, k unchanged
+ bp[bn--] = cp[cn--] : need to consider next limbs
+ bp[bn--] < cp[cn--] : borrow
+ */
+ if ((cc = bp[bn--]) != u) {
+ if (cc>u) return k;
+ else { count_leading_zeros(u, cc-u); return k + 1 + z + u; }
+ }
+ else z += mp_bits_per_limb;
+ }
+
+ if (cn >= 0)
+ count_leading_zeros(cc, ~(cp[cn--] << (mp_bits_per_limb - d)));
+ else { cc = 0; }
+
+ k += cc;
+ if (cc < d) return k;
+
+ while (cn >= 0 && !~cp[cn--]) { z += mp_bits_per_limb; }
+ if (cn >= 0) { count_leading_zeros(cc, ~cp[cn--]); return (k + z + cc); }
+
+ return k; /* We **need** that the nonsignificant limbs of c are set
+ to zero there */
+}
diff --git a/mpfr/cmp_ui.c b/mpfr/cmp_ui.c
new file mode 100644
index 000000000..48217a520
--- /dev/null
+++ b/mpfr/cmp_ui.c
@@ -0,0 +1,116 @@
+/* mpfr_cmp_ui -- compare a floating-point number with a machine integer
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+/* returns a positive value if b>i*2^f,
+ a negative value if b<i*2^f,
+ zero if b=i*2^f
+*/
+
+int
+#if __STDC__
+mpfr_cmp_ui_2exp ( mpfr_srcptr b, unsigned long int i, int f )
+#else
+mpfr_cmp_ui_2exp (b, i, f)
+ mpfr_srcptr b;
+ unsigned long int i;
+ int f;
+#endif
+{
+ int e, k, bn; mp_limb_t c, *bp;
+
+ if (SIGN(b)<0) return -1;
+ else if (!NOTZERO(b)) return((i) ? -1 : 0);
+ else { /* b>0 */
+ e = EXP(b); /* 2^(e-1) <= b < 2^e */
+ if (e>f+mp_bits_per_limb) return 1;
+
+ c = (mp_limb_t) i;
+ count_leading_zeros(k, c);
+ k = f+mp_bits_per_limb - k; /* 2^(k-1) <= i*2^f < 2^k */
+ if (k!=e) return (e-k);
+
+ /* now k=e */
+ c <<= (f+mp_bits_per_limb-k);
+ bn = (PREC(b)-1)/mp_bits_per_limb;
+ bp = MANT(b) + bn;
+ if (*bp>c) return 1;
+ else if (*bp<c) return -1;
+
+ /* most significant limbs agree, check remaining limbs from b */
+ while (--bn>=0)
+ if (*--bp) return 1;
+ return 0;
+ }
+}
+
+/* returns a positive value if b>i*2^f,
+ a negative value if b<i*2^f,
+ zero if b=i*2^f
+*/
+
+int
+#if __STDC__
+mpfr_cmp_si_2exp ( mpfr_srcptr b, long int i, int f )
+#else
+mpfr_cmp_si_2exp(b, i, f)
+ mpfr_srcptr b;
+ long int i;
+ int f;
+#endif
+{
+ int e, k, bn, si; mp_limb_t c, *bp;
+
+ si = (i<0) ? -1 : 1; /* sign of i */
+ if (SIGN(b)*i<0) return SIGN(b); /* both signs differ */
+ else if (!NOTZERO(b) || (i==0)) { /* one is zero */
+ if (i==0) return ((NOTZERO(b)) ? SIGN(b) : 0);
+ else return si; /* b is zero */
+
+ }
+ else { /* b and i are of same sign */
+ e = EXP(b); /* 2^(e-1) <= b < 2^e */
+ if (e>f+mp_bits_per_limb) return si;
+
+ c = (mp_limb_t) ((i<0) ? -i : i);
+ count_leading_zeros(k, c);
+ k = f+mp_bits_per_limb - k; /* 2^(k-1) <= i*2^f < 2^k */
+ if (k!=e) return (si*(e-k));
+
+ /* now k=e */
+ c <<= (f+mp_bits_per_limb-k);
+ bn = (PREC(b)-1)/mp_bits_per_limb;
+ bp = MANT(b) + bn;
+ if (*bp>c) return si;
+ else if (*bp<c) return -si;
+
+ /* most significant limbs agree, check remaining limbs from b */
+ while (--bn>=0)
+ if (*--bp) return si;
+ return 0;
+ }
+}
+
diff --git a/mpfr/div.c b/mpfr/div.c
new file mode 100644
index 000000000..ee1475694
--- /dev/null
+++ b/mpfr/div.c
@@ -0,0 +1,247 @@
+/* mpfr_div -- divide two floating-point numbers
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "longlong.h"
+
+/* #define DEBUG */
+
+void
+mpfr_div (mpfr_ptr r, mpfr_srcptr u, mpfr_srcptr v, unsigned char rnd_mode)
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp, tp0, tmp;
+ mp_size_t usize, vsize, rrsize;
+ mp_size_t rsize;
+ mp_size_t sign_quotient;
+ mp_size_t prec, err;
+ mp_limb_t q_limb;
+ mp_exp_t rexp;
+ long k, mult, vn;
+ unsigned long cc = 0, rw, nw;
+ char can_round = 0;
+ TMP_DECL (marker);
+
+ if (FLAG_NAN(u) || FLAG_NAN(v)) { SET_NAN(r); return; }
+
+ usize = (PREC(u) - 1)/BITS_PER_MP_LIMB + 1;
+ vsize = (PREC(v) - 1)/BITS_PER_MP_LIMB + 1;
+ sign_quotient = (SIGN(u) == SIGN(v) ? 1 : -1);
+ prec = PREC(r);
+
+ if (!NOTZERO(u)) { SET_ZERO(r); return; }
+
+ if (!NOTZERO(v))
+ vsize = 1 / v->_mp_d[vsize - 1]; /* Gestion des infinis ? */
+
+ if (!NOTZERO(v))
+ {
+ r->_mp_exp = 0;
+ MPN_ZERO(r->_mp_d, r->_mp_size);
+ return;
+ }
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+#ifdef DEBUG
+ printf("Entering division : ");
+ for(k = usize - 1; k >= 0; k--) { printf("%lu ", up[k]); }
+ printf(" by ");
+ for(k = vsize - 1; k >= 0; k--) { printf("%lu ", vp[k]); }
+ printf(".\n");
+#endif
+
+ /* Compare the mantissas */
+ mult = mpn_cmp(up, vp, (usize > vsize ? vsize : usize));
+ if (mult == 0 && vsize > usize)
+ {
+ vn = vsize - usize;
+ while (vn >= 0) if (vp[vn--]) { mult = 1; break; }
+ /* On peut diagnostiquer ici pour pas cher le cas u = v */
+ }
+ else { mult = (mult < 0 ? 1 : 0); }
+
+ rsize = (PREC(r) + 3)/BITS_PER_MP_LIMB + 1;
+ rrsize = PREC(r)/BITS_PER_MP_LIMB + 1;
+ /* Three extra bits are needed in order to get the quotient with enough
+ precision ; take one extra bit for rrsize in order to solve more
+ easily the problem of rounding to nearest. */
+
+ /* ATTENTION, USIZE DOIT RESTER > A VSIZE !!!!!!!! */
+
+ do
+ {
+ TMP_MARK (marker);
+
+ rexp = u->_mp_exp - v->_mp_exp;
+
+ err = rsize*BITS_PER_MP_LIMB;
+ if (rsize < vsize) { err-=2; }
+ if (rsize < usize) { err--; }
+ if (err > rrsize * BITS_PER_MP_LIMB)
+ { err = rrsize * BITS_PER_MP_LIMB; }
+
+ tp0 = (mp_ptr) TMP_ALLOC ((rsize+rrsize) * BYTES_PER_MP_LIMB);
+ /* fill by zero rrsize low limbs of t */
+ MPN_ZERO(tp0, rrsize); tp = tp0 + rrsize;
+ tmp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ rp = (mp_ptr) TMP_ALLOC (rrsize * BYTES_PER_MP_LIMB);
+
+ if (vsize >= rsize) {
+ MPN_COPY (tmp, vp + vsize - rsize, rsize);
+ }
+ else {
+ MPN_COPY (tmp + rsize - vsize, vp, vsize);
+ MPN_ZERO (tmp, rsize - vsize);
+ }
+
+ if (usize >= rsize) {
+ MPN_COPY (tp, up + usize - rsize, rsize);
+ }
+ else {
+ MPN_COPY (tp + rsize - usize, up, usize);
+ MPN_ZERO (tp, rsize - usize);
+ }
+
+ /* Do the real job */
+
+#ifdef DEBUG
+ printf("Dividing : ");
+ for(k = rsize - 1; k >= 0; k--) { printf("%lu ", tp[k]); }
+ printf(" by ");
+ for(k = rsize - 1; k >= 0; k--) { printf("%lu ", tmp[k]); }
+ printf(".\n");
+#endif
+
+ q_limb = (rsize==rrsize) /* use Burnikel-Ziegler algorithm */
+ ? mpn_divrem_n (rp, tp0, tmp, rsize)
+ : mpn_divrem (rp, 0, tp0, rsize+rrsize, tmp, rsize);
+ tp = tp0; /* location of remainder */
+
+#ifdef DEBUG
+ printf("The result is : \n");
+ printf("Quotient : ");
+ for(k = rrsize - 1; k >= 0; k--) { printf("%lu ", rp[k]); }
+ printf("Remainder : ");
+ for(k = rsize - 1; k >= 0; k--) { printf("%lu ", tp[k]); }
+ printf("(q_limb = %lu)\n", q_limb);
+#endif
+
+ /* msb-normalize the result */
+
+ if (q_limb)
+ {
+ count_leading_zeros(k, q_limb);
+ mpn_rshift(rp, rp, rrsize, BITS_PER_MP_LIMB - k);
+ rp[rrsize - 1] |= (q_limb << k);
+ rexp += BITS_PER_MP_LIMB - k;
+ }
+ else
+ {
+ count_leading_zeros(k, rp[rrsize - 1]);
+ if (k) { mpn_lshift(rp, rp, rrsize, k); }
+ rexp -= k;
+ }
+
+ can_round = (mpfr_can_round_raw(rp, rrsize, sign_quotient, err,
+ GMP_RNDN, rnd_mode, PREC(r))
+ || (usize == rsize && vsize == rsize &&
+ mpfr_can_round_raw(rp, rrsize, sign_quotient, err,
+ GMP_RNDZ, rnd_mode, PREC(r))));
+
+ /* If we used all the limbs of both the dividend and the divisor,
+ then we have the correct RNDZ rounding */
+
+ if (!can_round && (rsize < usize || rsize < vsize))
+ {
+#ifdef DEBUG
+ printf("Increasing the precision.\n");
+#endif
+ printf("#");
+ TMP_FREE(marker);
+ }
+ }
+ while (!can_round && (rsize < usize || rsize < vsize)
+ && (rsize++) && (rrsize++));
+
+ /* ON PEUT PROBABLEMENT SE DEBROUILLER DES QUE rsize >= vsize */
+ /* MAIS IL FAUT AJOUTER LE BOUT QUI MANQUE DE usize A rsize */
+
+ if (can_round)
+ {
+ cc = mpfr_round_raw(rp, rp, err, (sign_quotient == -1 ? 1 : 0),
+ PREC(r), rnd_mode);
+ rrsize = (PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
+ }
+ else
+ /* Use the remainder to find out the correct rounding */
+ /* Note that at this point the division has been done */
+ /* EXACTLY. */
+ if ((rnd_mode == GMP_RNDD && sign_quotient == -1)
+ || (rnd_mode == GMP_RNDU && sign_quotient == 1)
+ || (rnd_mode == GMP_RNDN))
+ {
+ /* We cannot round, so that the last bits of the quotient
+ have to be zero; just look if the remainder is nonzero */
+ k = rsize - 1;
+ while (k >= 0) { if (tp[k]) break; k--; }
+ if (k >= 0)
+ cc = mpn_add_1(rp, rp, rrsize, (mp_limb_t)1 << (BITS_PER_MP_LIMB -
+ (PREC(r) &
+ (BITS_PER_MP_LIMB - 1))));
+ else
+ if (rnd_mode == GMP_RNDN) /* even rounding */
+ {
+ rw = (PREC(r) + 1) & (BITS_PER_MP_LIMB - 1);
+ if (rw) { rw = BITS_PER_MP_LIMB - rw; nw = 0; } else nw = 1;
+ if ((rw ? (rp[nw] >> (rw + 1)) & 1 :
+ (rp[nw] >> (BITS_PER_MP_LIMB - 1)) & 1))
+ {
+ cc = mpn_add_1(rp + nw, rp + nw, rrsize,
+ ((mp_limb_t)1) << rw);
+ }
+ }
+ /* cas 0111111 */
+ }
+
+ if (sign_quotient != SIGN(r)) { CHANGE_SIGN(r); }
+ r->_mp_exp = rexp;
+
+ if (cc) {
+ mpn_rshift(rp, rp, rrsize, 1);
+ rp[rrsize-1] |= (mp_limb_t) 1 << (BITS_PER_MP_LIMB-1);
+ r->_mp_exp++;
+ }
+
+ rsize = rrsize;
+ rrsize = (PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
+ MPN_COPY(r->_mp_d, rp + rsize - rrsize, rrsize);
+ MANT(r) [0] &= ~(((mp_limb_t)1 << (BITS_PER_MP_LIMB -
+ (PREC(r) & (BITS_PER_MP_LIMB - 1)))) - 1) ;
+
+ TMP_FREE (marker);
+}
diff --git a/mpfr/div_2exp.c b/mpfr/div_2exp.c
new file mode 100644
index 000000000..e7602db44
--- /dev/null
+++ b/mpfr/div_2exp.c
@@ -0,0 +1,43 @@
+/* mpfr_div_2exp -- divide a floating-point number by a power of two
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_div_2exp(mpfr_ptr y, mpfr_srcptr x, unsigned long int n, unsigned char rnd_mode)
+#else
+mpfr_div_2exp(y, x, n, rnd_mode)
+ mpfr_ptr y;
+ mpfr_srcptr x;
+ unsigned long int n;
+ unsigned char rnd_mode;
+#endif
+{
+ /* Important particular case */
+ if (y != x) mpfr_set(y, x, rnd_mode);
+ EXP(y) -= n;
+ return;
+}
+
diff --git a/mpfr/div_ui.c b/mpfr/div_ui.c
new file mode 100644
index 000000000..7cd124142
--- /dev/null
+++ b/mpfr/div_ui.c
@@ -0,0 +1,135 @@
+/* mpfr_div_ui -- divide a floating-point number by a machine integer
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+/* #define DEBUG */
+
+/* returns 0 if result exact, non-zero otherwise */
+int
+#ifdef __STDC__
+mpfr_div_ui(mpfr_ptr y, mpfr_srcptr x, unsigned long u, unsigned char rnd_mode)
+#else
+mpfr_div_ui(y, x, u, rnd_mode)
+ mpfr_ptr y;
+ mpfr_srcptr x;
+ unsigned long u;
+ unsigned char rnd_mode;
+#endif
+{
+ int xn, yn, dif, sh, i; mp_limb_t *xp, *yp, *tmp, c, d;
+ TMP_DECL(marker);
+
+ if (FLAG_NAN(x)) { SET_NAN(y); return 1; }
+ if (u==0) { printf("infinity\n"); return 1; }
+
+ TMP_MARK(marker);
+ xn = (PREC(x)-1)/BITS_PER_MP_LIMB + 1;
+ yn = (PREC(y)-1)/BITS_PER_MP_LIMB + 1;
+
+ xp = MANT(x);
+ yp = MANT(y);
+ EXP(y) = EXP(x);
+ if (SIGN(x)!=SIGN(y)) CHANGE_SIGN(y);
+
+ dif = yn+1-xn;
+#ifdef DEBUG
+ printf("dif=%d u=%lu xn=%d\n",dif,u,xn);
+ printf("x="); mpfr_print_raw(x); putchar('\n');
+#endif
+
+ /* we need to store yn+1 = xn + dif limbs of the quotient */
+ if (ABSSIZE(y)>=yn+1) tmp=yp;
+ else tmp=TMP_ALLOC((yn+1)*BYTES_PER_MP_LIMB);
+
+ c = (mp_limb_t) u;
+ if (dif>=0) {
+ /* patch for bug in mpn_divrem_1 */
+#if (UDIV_NEEDS_NORMALIZATION==1)
+ count_leading_zeros(sh, c);
+ c <<= sh;
+ EXP(y) += sh;
+#endif
+ c = mpn_divrem_1(tmp, dif, xp, xn, c);
+ }
+ else /* dif < 0 i.e. xn > yn */
+ c = mpn_divrem_1(tmp, 0, xp-dif, yn, c);
+
+ if (tmp[yn]==0) { tmp--; sh=0; EXP(y) -= mp_bits_per_limb; }
+ /* shift left to normalize */
+ count_leading_zeros(sh, tmp[yn]);
+ if (sh) {
+ mpn_lshift(yp, tmp+1, yn, sh);
+ yp[0] += tmp[0] >> (BITS_PER_MP_LIMB-sh);
+ EXP(y) -= sh;
+ }
+ else MPN_COPY(yp, tmp+1, yn);
+#ifdef DEBUG
+printf("y="); mpfr_print_raw(y); putchar('\n');
+#endif
+
+ sh = yn*BITS_PER_MP_LIMB - PREC(y);
+ /* it remains sh bits in less significant limb of y */
+
+ d = *yp & (((mp_limb_t)1 << sh) - 1);
+ *yp ^= d; /* set to zero lowest sh bits */
+
+ TMP_FREE(marker);
+ if ((c | d)==0) {
+ for (i=0; i<-dif && xp[i]==0; i++);
+ if (i>=-dif) return 0; /* result is exact */
+ }
+
+ switch (rnd_mode) {
+ case GMP_RNDZ:
+ return 1; /* result is inexact */
+ case GMP_RNDU:
+ if (SIGN(y)>0) mpfr_add_one_ulp(y);
+ return 1; /* result is inexact */
+ case GMP_RNDD:
+ if (SIGN(y)<0) mpfr_add_one_ulp(y);
+ return 1; /* result is inexact */
+ case GMP_RNDN:
+ if (d < ((mp_limb_t)1 << (sh-1))) return 1;
+ else if (d > ((mp_limb_t)1 << (sh-1))) {
+ mpfr_add_one_ulp(y);
+ }
+ else { /* d = (mp_limb_t)1 << (sh-1) */
+ if (c) mpfr_add_one_ulp(y);
+ else {
+ for (i=0; i<-dif && xp[i]==0; i++);
+ if (i<-dif) mpfr_add_one_ulp(y);
+ else { /* exactly in the middle */
+ if (*yp & ((mp_limb_t)1 << sh)) mpfr_add_one_ulp(y);
+ }
+ }
+ }
+ return 1;
+ }
+ return 0; /* to prevent warning from gcc */
+}
+
+
+
diff --git a/mpfr/exp.c b/mpfr/exp.c
new file mode 100644
index 000000000..c3ec218a0
--- /dev/null
+++ b/mpfr/exp.c
@@ -0,0 +1,176 @@
+/* mpfr_exp -- exponential of a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+/* #define DEBUG */
+
+#define LOG2 0.69314718055994528622 /* log(2) rounded to zero on 53 bits */
+
+/* use Brent's formula exp(x) = (1+r+r^2/2!+r^3/3!+...)^(2^K)*2^n
+ where x = n*log(2)+(2^K)*r
+ number of operations = O(K+prec(r)/K)
+*/
+int
+#if __STDC__
+mpfr_exp(mpfr_ptr y, mpfr_srcptr x, unsigned char rnd_mode)
+#else
+mpfr_exp(y, x, rnd_mode)
+ mpfr_ptr y;
+ mpfr_srcptr x;
+ unsigned char rnd_mode;
+#endif
+{
+ int n, expx, K, precy, q, k, l, expr, err;
+ mpfr_t r, s, t;
+
+ if (FLAG_NAN(x)) { SET_NAN(y); return 1; }
+ if (!NOTZERO(x)) { mpfr_set_ui(y, 1, GMP_RNDN); return 0; }
+
+ expx = EXP(x);
+ precy = PREC(y);
+#ifdef DEBUG
+ printf("EXP(x)=%d\n",expx);
+#endif
+
+ /* if x > (2^31-1)*ln(2), then exp(x) > 2^(2^31-1) i.e. gives +infinity */
+ if (expx > 30) {
+ if (SIGN(x)>0) { printf("+infinity"); return 1; }
+ else { SET_ZERO(y); return 1; }
+ }
+
+ /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */
+ if (expx < -precy) { int signx = SIGN(x);
+ mpfr_set_ui(y, 1, rnd_mode);
+ if (signx>0 && rnd_mode==GMP_RNDU) mpfr_add_one_ulp(y);
+ else if (signx<0 && (rnd_mode==GMP_RNDD || rnd_mode==GMP_RNDZ))
+ mpfr_sub_one_ulp(y);
+ return 1; }
+
+ n = (int) floor(mpfr_get_d(x)/LOG2);
+
+ K = (int) sqrt( (double) precy );
+ l = (precy-1)/K + 1;
+ err = K + (int) ceil(log(2.0*(double)l+18.0)/LOG2);
+ /* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */
+ q = precy + err + K + 3;
+ mpfr_init2(r, q); mpfr_init2(s, q); mpfr_init2(t, q);
+ /* the algorithm consists in computing an upper bound of exp(x) using
+ a precision of q bits, and see if we can round to PREC(y) taking
+ into account the maximal error. Otherwise we increase q. */
+ do {
+#ifdef DEBUG
+ printf("n=%d K=%d l=%d q=%d\n",n,K,l,q);
+#endif
+
+ /* if n<0, we have to get an upper bound of log(2)
+ in order to get an upper bound of r = x-n*log(2) */
+ mpfr_log2(s, (n>=0) ? GMP_RNDZ : GMP_RNDU);
+#ifdef DEBUG
+ printf("n=%d log(2)=",n); mpfr_print_raw(s); putchar('\n');
+#endif
+ mpfr_mul_ui(r, s, (n<0) ? -n : n, (n>=0) ? GMP_RNDZ : GMP_RNDU);
+ if (n<0) mpfr_neg(r, r, GMP_RNDD);
+ /* r = floor(n*log(2)) */
+
+#ifdef DEBUG
+ printf("x=%1.20e\n",mpfr_get_d(x));
+ printf(" ="); mpfr_print_raw(x); putchar('\n');
+ printf("r=%1.20e\n",mpfr_get_d(r));
+ printf(" ="); mpfr_print_raw(r); putchar('\n');
+#endif
+ mpfr_sub(r, x, r, GMP_RNDU);
+ if (SIGN(r)<0) { /* initial approximation n was too large */
+ n--;
+ mpfr_mul_ui(r, s, (n<0) ? -n : n, GMP_RNDZ);
+ if (n<0) mpfr_neg(r, r, GMP_RNDD);
+ mpfr_sub(r, x, r, GMP_RNDU);
+ }
+#ifdef DEBUG
+ printf("x-r=%1.20e\n",mpfr_get_d(r));
+ printf(" ="); mpfr_print_raw(r); putchar('\n');
+ if (SIGN(r)<0) { fprintf(stderr,"Error in mpfr_exp: r<0\n"); exit(1); }
+#endif
+ mpfr_div_2exp(r, r, K, GMP_RNDU); /* r = (x-n*log(2))/2^K */
+ mpfr_set_ui(s, 1, GMP_RNDU);
+ mpfr_set_ui(t, 1, GMP_RNDU);
+
+ l = 1; expr = EXP(r);
+ do {
+ mpfr_mul(t, t, r, GMP_RNDU);
+ mpfr_div_ui(t, t, l, GMP_RNDU);
+ mpfr_add(s, s, t, GMP_RNDU);
+#ifdef DEBUG
+ printf("l=%d t=%1.20e\n",l,mpfr_get_d(t));
+ printf("s=%1.20e\n",mpfr_get_d(s));
+#endif
+ l++;
+ } while (EXP(t)+expr > -q);
+#ifdef DEBUG
+ printf("l=%d q=%d (K+l)*q^2=%1.3e\n", l, q, (K+l)*(double)q*q);
+#endif
+
+ /* add 2 ulp to take into account rest of summation */
+ mpfr_add_one_ulp(s);
+ mpfr_add_one_ulp(s);
+
+ for (k=0;k<K;k++) {
+ mpfr_mul(s, s, s, GMP_RNDU);
+#ifdef DEBUG
+ printf("k=%d s=%1.20e\n",k,mpfr_get_d(s));
+#endif
+ }
+
+ if (n>0) mpfr_mul_2exp(s, s, n, GMP_RNDU);
+ else mpfr_div_2exp(s, s, -n, GMP_RNDU);
+
+ /* error is at most 2^K*(2l+18) ulp */
+ l = 2*l+17; k=0; while (l) { k++; l >>= 1; }
+ /* now k = ceil(log(2l+18)/log(2)) */
+ K += k;
+#ifdef DEBUG
+ printf("after mult. by 2^n:\n");
+ if (EXP(s)>-1024) printf("s=%1.20e\n",mpfr_get_d(s));
+ printf(" ="); mpfr_print_raw(s); putchar('\n');
+ printf("err=%d bits\n", K);
+#endif
+
+ l = mpfr_can_round(s, q-K, GMP_RNDU, rnd_mode, precy);
+ if (l==0) {
+#ifdef DEBUG
+ printf("not enough precision, use %d\n", q+BITS_PER_MP_LIMB);
+ printf("q=%d q-K=%d precy=%d\n",q,q-K,precy);
+#endif
+ q += BITS_PER_MP_LIMB;
+ mpfr_set_prec(r, q); mpfr_set_prec(s, q); mpfr_set_prec(t, q);
+ }
+ } while (l==0);
+
+ mpfr_set(y, s, rnd_mode);
+
+ mpfr_clear(r); mpfr_clear(s); mpfr_clear(t);
+ return 1;
+}
+
diff --git a/mpfr/get_str.c b/mpfr/get_str.c
new file mode 100644
index 000000000..e100b300e
--- /dev/null
+++ b/mpfr/get_str.c
@@ -0,0 +1,207 @@
+/* mpfr_get_str -- output a floating-point number to a string
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+/*
+ Convert op to a string in base 'base' with 'n' digits and writes the
+ mantissa in 'str', the exponent in 'expptr'.
+ The result is rounded wrt 'rnd_mode'.
+
+ For op = 3.1416 we get str = "31416" and expptr=1.
+ */
+#if __STDC__
+char *mpfr_get_str(char *str, mp_exp_t *expptr, int base, size_t n,
+ mpfr_srcptr op, unsigned char rnd_mode)
+#else
+char *mpfr_get_str(str, expptr, base, n, op, rnd_mode)
+ char *str;
+ mp_exp_t *expptr;
+ int base;
+ size_t n;
+ mpfr_srcptr op;
+ unsigned char rnd_mode;
+#endif
+{
+ double d; long e, q, div, p, err, prec, sh; mpfr_t a, b; mpz_t bz;
+ char *str0; unsigned char rnd1; int f, pow2, ok=0, neg;
+
+ if (base<2 || 36<base) {
+ fprintf(stderr, "Error: too small or too large base in mpfr_get_str: %d\n",
+ base);
+ exit(1);
+ }
+
+ neg = (SIGN(op)<0) ? 1 : 0;
+
+ if (!NOTZERO(op)) {
+ if (str==NULL) str0=str=(*_mp_allocate_func)(neg + n + 2);
+ if (SIGN(op)<0) *str++ = '-';
+ for (f=0;f<n;f++) *str++ = '0';
+ *expptr = 1;
+ return str0;
+ }
+
+ count_leading_zeros(pow2, (mp_limb_t)base);
+ pow2 = BITS_PER_MP_LIMB - pow2 - 1;
+ if (base != (1<<pow2)) pow2=0;
+ /* if pow2 <> 0, then base = 2^pow2 */
+
+ /* first determines the exponent */
+ e = EXP(op);
+ d = fabs(mpfr_get_d2(op, 0));
+ /* the absolute value of op is between 1/2*2^e and 2^e */
+ /* the output exponent f is such that base^(f-1) <= |op| < base^f
+ i.e. f = 1 + floor(log(|op|)/log(base))
+ = 1 + floor((log(|m|)+e*log(2))/log(base)) */
+ f = 1 + (int) floor((log(d)+(double)e*log(2.0))/log((double)base));
+ if (n==0) {
+ /* performs exact rounding, i.e. returns y such that for rnd_mode=RNDN
+ for example, we have:
+ y*base^(f-n) <= x*2^(e-p) < (x+1)*2^(e-p) <= (y+1)*base^(f-n)
+ which implies 2^(EXP(op)-PREC(op)) <= base^(f-n)
+ */
+ n = f + (int) ceil(((double)PREC(op)-e)*log(2.0)/log((double)base));
+ }
+ /* now the first n digits of the mantissa are obtained from
+ rnd(op*base^(n-f)) */
+ prec = (long) ceil((double)n*log((double)base)/log(2.0));
+ err = 5;
+ q = prec+err;
+ /* one has to use at least q bits */
+ q = (((q-1)/BITS_PER_MP_LIMB)+1)*BITS_PER_MP_LIMB;
+ mpfr_init2(a,q); mpfr_init2(b,q);
+
+ do {
+ p = n-f; if ((div=(p<0))) p=-p;
+ rnd1 = rnd_mode;
+ if (div) {
+ /* if div we divide by base^p so we have to invert the rounding mode */
+ switch (rnd1) {
+ case GMP_RNDN: rnd1=GMP_RNDN; break;
+ case GMP_RNDZ: rnd1=GMP_RNDU; break;
+ case GMP_RNDU: rnd1=GMP_RNDZ; break;
+ case GMP_RNDD: rnd1=GMP_RNDZ; break;
+ }
+ }
+
+ if (pow2) {
+ if (div) mpfr_div_2exp(b, op, pow2*p, rnd_mode);
+ else mpfr_mul_2exp(b, op, pow2*p, rnd_mode);
+ }
+ else {
+ /* compute base^p with q bits and rounding towards zero */
+ mpfr_set_prec(b, q);
+ if (p==0) { mpfr_set(b, op, rnd_mode); mpfr_set_ui(a, 1, rnd_mode); }
+ else {
+ mpfr_set_prec(a, q);
+ mpfr_ui_pow_ui(a, base, p, rnd1);
+ if (div) {
+ mpfr_set_ui(b, 1, rnd_mode);
+ mpfr_div(a, b, a, rnd_mode);
+ }
+ /* now a is an approximation by default of 1/base^(f-n) */
+ mpfr_mul(b, op, a, rnd_mode);
+ }
+ }
+ if (neg) CHANGE_SIGN(b); /* put b positive */
+
+ if (q>2*prec+BITS_PER_MP_LIMB) {
+ /* happens when just in the middle between two digits */
+ n--; q-=BITS_PER_MP_LIMB;
+ if (n==0) {
+ fprintf(stderr, "cannot determine leading digit\n"); exit(1);
+ }
+ }
+ ok = pow2 || mpfr_can_round(b, q-err, rnd_mode, rnd_mode, prec);
+
+ if (ok) {
+ if (pow2) {
+ sh = e-PREC(op) + pow2*(n-f); /* error at most 2^e */
+ ok = mpfr_can_round(b, EXP(b)-sh-1, rnd_mode, rnd_mode, n*pow2);
+ }
+ else {
+ /* check that value is the same at distance 2^(e-PREC(op))/base^(f-n)
+ in opposite from rounding direction */
+ if (e>=PREC(op)) mpfr_mul_2exp(a, a, e-PREC(op), rnd_mode);
+ else mpfr_div_2exp(a, a, PREC(op)-e, rnd_mode);
+ if (rnd_mode==GMP_RNDN) {
+ mpfr_div_2exp(a, a, 2, rnd_mode);
+ mpfr_sub(b, b, a, rnd_mode); /* b - a/2 */
+ mpfr_mul_2exp(a, a, 2, rnd_mode);
+ mpfr_add(a, b, a, rnd_mode); /* b + a/2 */
+ }
+ else if ((rnd_mode==GMP_RNDU && neg==0) || (rnd_mode==GMP_RNDD && neg))
+ mpfr_sub(a, b, a, rnd_mode);
+ else mpfr_add(a, b, a, rnd_mode);
+ /* check that a and b are rounded similarly */
+ prec=EXP(b);
+ if (EXP(a) != prec) ok=0;
+ else {
+ mpfr_round(b, rnd_mode, prec);
+ mpfr_round(a, rnd_mode, prec);
+ if (mpfr_cmp(a, b)) ok=0;
+ }
+ }
+ if (ok==0) { /* n is too large */
+ n--;
+ if (n==0) {
+ fprintf(stderr, "cannot determine leading digit\n"); exit(1);
+ }
+ q -= BITS_PER_MP_LIMB;
+ }
+ }
+ } while (ok==0 && (q+=BITS_PER_MP_LIMB) );
+ if (neg)
+ switch (rnd_mode) {
+ case GMP_RNDU: rnd_mode=GMP_RNDZ; break;
+ case GMP_RNDD: rnd_mode=GMP_RNDU; break;
+ }
+
+ prec=EXP(b); /* may have changed due to rounding */
+
+ /* now the mantissa is the integer part of b */
+ mpz_init(bz); q=1+(prec-1)/BITS_PER_MP_LIMB;
+ _mpz_realloc(bz, q);
+ sh = prec%BITS_PER_MP_LIMB;
+ e = 1 + (PREC(b)-1)/BITS_PER_MP_LIMB-q;
+ if (sh) mpn_rshift(PTR(bz), MANT(b)+e, q, BITS_PER_MP_LIMB-sh);
+ else MPN_COPY(PTR(bz), MANT(b)+e, q);
+ bz->_mp_size=q;
+
+ /* computes the number of characters needed */
+ q = neg + n + 2; /* n+1 may not be enough for 100000... */
+ if (str==NULL) str0=str=(*_mp_allocate_func)(q);
+ if (neg) *str++='-';
+ mpz_get_str(str, base, bz); /* n digits of mantissa */
+ if (strlen(str)==n+1) f++; /* possible due to rounding */
+ *expptr = f;
+ mpfr_clear(a); mpfr_clear(b); mpz_clear(bz);
+ return str0;
+}
+
diff --git a/mpfr/init.c b/mpfr/init.c
new file mode 100644
index 000000000..e416511c7
--- /dev/null
+++ b/mpfr/init.c
@@ -0,0 +1,49 @@
+/* mpfr_init -- initialize a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_init2 (mpfr_t x, unsigned long int p)
+#else
+mpfr_init2 (x, p)
+ mpfr_t x;
+ unsigned long int p;
+#endif
+{
+ unsigned long xsize;
+
+ if (p==0) {
+ printf("*** cannot initialize mpfr with precision 0\n"); exit(1);
+ }
+
+ xsize = (p - 1)/BITS_PER_MP_LIMB + 1;
+
+ x -> _mp_prec = p;
+ x -> _mp_d = (mp_ptr) (*_mp_allocate_func)
+ (xsize * BYTES_PER_MP_LIMB);
+ x -> _mp_size = xsize;
+ x -> _mp_exp = 0; /* avoids uninitialized memory reads for zero */
+}
diff --git a/mpfr/karadiv.c b/mpfr/karadiv.c
new file mode 100644
index 000000000..94db05353
--- /dev/null
+++ b/mpfr/karadiv.c
@@ -0,0 +1,137 @@
+/* mpn_divrem_n -- Karatsuba division in 2*K(n) limb operations
+
+Copyright (C) 1999-2000 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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. */
+
+/*
+[1] Fast Recursive Division, by Christoph Burnikel and Joachim Ziegler,
+ Technical report MPI-I-98-1-022, october 1998,
+ cf http://www.mpi-sb.mpg.de/~ziegler/TechRep.ps.gz.
+ Implemented by Paul Zimmermann, 1999.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+extern void mpn_divrem_n2 (mp_limb_t *, mp_limb_t *, mp_limb_t *, mp_size_t, mp_limb_t *);
+extern void mpn_divrem_3by2 (mp_limb_t *, mp_limb_t *, mp_limb_t *, mp_size_t, mp_limb_t *);
+
+/* mpn_divrem_n(n) calls 2*mul(n/2)+2*div(n/2), thus to be faster then
+ div(n)=4*div(n/2), we need mul(n/2) to be faster than the classic way,
+ i.e. n/2 >= KARATSUBA_MUL_THRESHOLD */
+
+#define DIV_LIMIT (7*KARATSUBA_MUL_THRESHOLD)
+
+static void mpn_decr(mp_limb_t *Q)
+{
+ while ((*Q++)-- == 0);
+}
+
+/* implements algorithm of page 8 in [1]: divides (A,2n) by (B,n) and puts the
+ quotient in (Q,n), the remainder in (A,n).
+ Returns most significant limb of the quotient, which is 0 or 1.
+*/
+mp_limb_t
+mpn_divrem_n(mp_limb_t *Q, mp_limb_t *A, mp_limb_t *B, mp_size_t n)
+{
+ if (n<DIV_LIMIT) return mpn_divrem(Q, 0, A, 2*n, B, n);
+ else {
+ mp_limb_t cc=0;
+ if (mpn_cmp(A+n, B, n)>=0) {
+ cc=1;
+ mpn_sub_n(A+n, A+n, B, n);
+ }
+ if (n%2) {
+ /* divide (2n-2) most significant limbs from A by those (n-1) from B */
+ mpn_divrem_n(Q+1, A+2, B+1, n-1);
+ /* now (Q+1, n-1) contains the quotient of (A+2,2n-2) by (B+1,n-1)
+ and (A+2, n-1) contains the remainder */
+ if (mpn_sub_1(A+n, A+n, 1, mpn_submul_1(A+1, Q+1, n-1, B[0]))) {
+ /* quotient two large */
+ mpn_decr(Q+1);
+ if (mpn_add_n(A+1, A+1, B, n)==0) {
+ mpn_decr(Q+1); mpn_add_n(A+1, A+1, B, n);
+ }
+ }
+ /* now divide (A,n+1) by (B,n) */
+ mpn_divrem(Q, 0, A, n+1, B, n);
+ }
+ else {
+ mp_limb_t *tmp; int n2=n/2;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ tmp = (mp_limb_t*) TMP_ALLOC(n*sizeof(mp_limb_t));
+ mpn_divrem_3by2(Q+n2, A+n2, B, n2, tmp);
+ mpn_divrem_3by2(Q, A, B, n2, tmp);
+ TMP_FREE (marker);
+ }
+ return cc;
+ }
+}
+
+/* inner procedure, with no memory allocation
+ assumes mpn_cmp(A+n, B, n) < 0
+*/
+void mpn_divrem_n2(mp_limb_t *Q, mp_limb_t *A, mp_limb_t *B, mp_size_t n,
+ mp_limb_t *tmp)
+{
+ if (n%2) {
+ /* divide (2n-2) most significant limbs from A by those (n-1) from B */
+ mpn_divrem_n2(Q+1, A+2, B+1, n-1, tmp);
+ /* now (Q+1, n-1) contains the quotient of (A+2,2n-2) by (B+1,n-1)
+ and (A+2, n-1) contains the remainder */
+ if (mpn_sub_1(A+n, A+n, 1, mpn_submul_1(A+1, Q+1, n-1, B[0]))) {
+ /* quotient two large */
+ mpn_decr(Q+1);
+ if (mpn_add_n(A+1, A+1, B, n)==0) { /* still too large */
+ mpn_decr(Q+1); mpn_add_n(A+1, A+1, B, n);
+ }
+ }
+ /* now divide (A,n+1) by (B,n) */
+ mpn_divrem(Q, 0, A, n+1, B, n);
+ }
+ else {
+ int n2=n/2;
+ mpn_divrem_3by2(Q+n2, A+n2, B, n2, tmp);
+ mpn_divrem_3by2(Q, A, B, n2, tmp);
+ }
+}
+
+/* divides (A,3n) by (B,2n) and puts the quotient in (Q,n),
+ the remainder in (A,2n) */
+void
+mpn_divrem_3by2(mp_limb_t *Q, mp_limb_t *A, mp_limb_t *B,
+ mp_size_t n, mp_limb_t *tmp)
+{
+ int twon = n+n;
+
+ if (n<DIV_LIMIT) mpn_divrem(Q, 0, A+n, twon, B+n, n);
+ else mpn_divrem_n2(Q, A+n, B+n, n, tmp);
+ /* q=(Q,n), c=(A+n,n) with the notations of [1] */
+ mpn_mul_n(tmp, Q, B, n);
+ if (mpn_sub_n(A, A, tmp, twon)) /* R=(A,2n) */ {
+ mpn_decr(Q);
+ if (mpn_add_n(A, A, B, twon)==0) { /* Q still too large */
+ mpn_decr(Q); mpn_add_n(A, A, B, twon);
+ }
+ }
+ return;
+}
diff --git a/mpfr/karasqrt.c b/mpfr/karasqrt.c
new file mode 100644
index 000000000..74a4bf805
--- /dev/null
+++ b/mpfr/karasqrt.c
@@ -0,0 +1,102 @@
+/* kara_sqrtrem -- Karatsuba square root
+
+Copyright (C) 1999-2000 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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. */
+
+/* Reference: Karatsuba Square Root, Paul Zimmermann, Research Report 3805,
+ INRIA, November 1999. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+#define SQRT_LIMIT KARATSUBA_MUL_THRESHOLD /* must be at least 3, should be
+ near from optimal */
+
+/* n must be even */
+mp_size_t kara_sqrtrem(mp_limb_t *s, mp_limb_t *r, mp_limb_t *op, mp_size_t n)
+{
+ if (n<SQRT_LIMIT) return mpn_sqrtrem(s, r, op, n);
+ else {
+ mp_size_t nn, rn, rrn, sn, qn; mp_limb_t *q, tmp;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ nn = n/4; /* block size 'b' corresponds to nn limbs */
+ rn = kara_sqrtrem(s+nn, r+nn, op+2*nn, n-2*nn);
+ /* rn <= ceil(n-2*nn, 2) + 1 <= ceil(2*nn+3, 2) + 1 <= nn+3 */
+ /* to divide by 2*s', first divide by 2, to ensure the dividend is
+ less than b^2 */
+ sn=(n-2*nn+1)/2; /* sn >= nn */
+ MPN_COPY(r, op+nn, nn); /* copy a_1 */
+ tmp = mpn_rshift(r, r, nn+rn, 1);
+ if (r[nn+rn-1]==0) rn--;
+ q = (mp_limb_t*) TMP_ALLOC(2*(sn+1)*sizeof(mp_limb_t));
+ if (nn+rn < 2*sn) MPN_ZERO(r+nn+rn, 2*sn-nn-rn);
+ qn = sn; if (mpn_cmp(r+sn, s+nn, sn)>=0) {
+ q[qn++]=1; mpn_sub_n(r+sn, r+sn, s+nn, sn);
+ }
+#if 0
+ mpn_divrem(q, 0, r, 2*sn, s+nn, sn);
+#else
+ mpn_divrem_n(q, r, s+nn, sn);
+#endif
+ while (qn>nn && q[qn-1]==0) qn--;
+ MPN_COPY(s, q, nn);
+ if (nn+rn > 2*sn) {
+ tmp=mpn_add_n(s+sn, s+sn, q+sn, nn+rn-2*sn);
+ if (tmp) mpn_add_1(s+nn+rn-sn, s+nn+rn-sn, (n+1)/2-nn-rn+sn, tmp);
+ }
+ /* multiply remainder by two and add low bit of a_1 */
+ rrn = nn+sn; /* size of output remainder */
+ rrn += mpn_lshift(r+nn, r, sn, 1);
+ r[nn] |= (op[nn] & 1);
+ sn += nn;
+ if (qn>nn) {
+ MPN_COPY(r, s+nn, qn-nn); /* save the qn-nn limbs from s */
+ MPN_COPY(s+nn, q+nn, qn-nn); /* replace by those of q */
+ }
+ mpn_mul_n(q, s, s, qn);
+ if (qn>nn) { /* restore the limbs from s, adding them to those of q */
+ mp_limb_t cy;
+
+ cy = mpn_add_n(s+nn, s+nn, r, qn-nn);
+ if (qn<sn) cy = mpn_add_1(s+qn, s+qn, sn-qn, cy);
+ if (cy) s[sn++]=1;
+ }
+ MPN_COPY(r, op, nn); /* copy a_0 */
+ qn = 2*qn;
+ if (qn<sn) MPN_ZERO(q+qn, sn-qn);
+ if (rrn<sn) MPN_ZERO(r+rrn, sn-rrn);
+ if (mpn_sub_n(r, r, q, sn) || (qn>sn)) {
+ if (rrn>sn) rrn=sn;
+ else {
+ /* one shift and one add is faster than two add's */
+ r[sn] = mpn_lshift(q, s, sn, 1) + mpn_add_n(r, r, q, sn)
+ - mpn_sub_1(r, r, sn, 1) - 1;
+ rrn = sn + r[sn];
+ mpn_sub_1(s, s, sn, 1);
+ }
+ }
+ else if (rrn>sn) r[sn]=1;
+ TMP_FREE (marker);
+ MPN_NORMALIZE(r, rrn);
+ return rrn;
+ }
+}
diff --git a/mpfr/log.c b/mpfr/log.c
new file mode 100644
index 000000000..ad8e9856d
--- /dev/null
+++ b/mpfr/log.c
@@ -0,0 +1,150 @@
+/* mpfr_log -- natural logarithm of a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+
+ /* The computation of log(a) is done using the formula :
+ if we want p bits of the result,
+ pi
+ log(a) ~ ------------ - m log 2
+ 2 AG(1,4/s)
+
+ where s = x 2^m > 2^(p/2)
+
+ More precisely, if F(x) = int(1/sqrt(1-(1-x^2)*sin(t)^2), t=0..PI/2),
+ then for s>=1.26 we have log(s) < F(4/s) < log(s)*(1+4/s^2)
+ from which we deduce pi/2/AG(1,4/s)*(1-4/s^2) < log(s) < pi/2/AG(1,4/s)
+ so the relative error 4/s^2 is < 4/2^p i.e. 4 ulps.
+ */
+
+
+#define MON_INIT(xp, x, p, s) xp = (mp_ptr) TMP_ALLOC(s*BYTES_PER_MP_LIMB); x -> _mp_prec = p; x -> _mp_d = xp; x -> _mp_size = s; x -> _mp_exp = 0;
+
+/* #define DEBUG */
+
+int
+#if __STDC__
+mpfr_log(mpfr_ptr r, mpfr_srcptr a, unsigned char rnd_mode)
+#else
+mpfr_log()
+ mpfr_ptr r;
+ mpfr_srcptr a;
+ unsigned char rnd_mode;
+#endif
+{
+ int p, m, q, bool, size, cancel;
+ mpfr_t cst, rapport, agm, tmp1, tmp2, s, mm;
+ mp_limb_t *cstp, *rapportp, *agmp, *tmp1p, *tmp2p, *sp, *mmp;
+ double ref;
+ TMP_DECL(marker);
+
+ /* If a is NaN or a is negative or null, the result is NaN */
+ if (FLAG_NAN(a) || (SIGN(a)<=0))
+ { SET_NAN(r); return 1; }
+
+ /* If a is 1, the result is 0 */
+ if (mpfr_cmp_ui_2exp(a,1,0)==0){
+ SET_ZERO(r);
+ return 0; /* only case where the result is exact */
+ }
+
+ q=PREC(r);
+
+ ref=mpfr_get_d(a)-1.0;
+ if (ref<0)
+ ref=-ref;
+
+ p=q+4;
+ /* adjust to entire limb */
+ if (p%BITS_PER_MP_LIMB) p += BITS_PER_MP_LIMB - (p%BITS_PER_MP_LIMB);
+
+ bool=1;
+
+ while (bool==1) {
+#ifdef DEBUG
+ printf("a="); mpfr_print_raw(a); putchar('\n');
+ printf("p=%d\n", p);
+#endif
+ /* Calculus of m (depends on p) */
+ m=(int) ceil(((double) p)/2.0) -EXP(a)+1;
+
+ /* All the mpfr_t needed have a precision of p */
+ TMP_MARK(marker);
+ size=(p-1)/BITS_PER_MP_LIMB+1;
+ MON_INIT(cstp, cst, p, size);
+ MON_INIT(rapportp, rapport, p, size);
+ MON_INIT(agmp, agm, p, size);
+ MON_INIT(tmp1p, tmp1, p, size);
+ MON_INIT(tmp2p, tmp2, p, size);
+ MON_INIT(sp, s, p, size);
+ MON_INIT(mmp, mm, p, size);
+
+ mpfr_set_si(mm,m,GMP_RNDN); /* I have m, supposed exact */
+ mpfr_set_si(tmp1,1,GMP_RNDN); /* I have 1, exact */
+ mpfr_set_si(tmp2,4,GMP_RNDN); /* I have 4, exact */
+ mpfr_mul_2exp(s,a,m,GMP_RNDN); /* I compute s=a*2^m, err <= 1 ulp */
+ mpfr_div(rapport,tmp2,s,GMP_RNDN); /* I compute 4/s, err <= 2 ulps */
+ mpfr_agm(agm,tmp1,rapport,GMP_RNDN); /* AG(1,4/s), err<=3 ulps */
+ mpfr_mul_2exp(tmp1,agm,1,GMP_RNDN); /* 2*AG(1,4/s), still err<=3 ulps */
+ mpfr_pi(cst, GMP_RNDN); /* I compute pi, err<=1ulp */
+ mpfr_div(tmp2,cst,tmp1,GMP_RNDN); /* pi/2*AG(1,4/s), err<=5ulps */
+ mpfr_log2(cst,GMP_RNDN); /* I compute log(2), err<=1ulp */
+ mpfr_mul(tmp1,cst,mm,GMP_RNDN); /* I compute m*log(2), err<=2ulps */
+ cancel = EXP(tmp2);
+ mpfr_sub(cst,tmp2,tmp1,GMP_RNDN); /* log(a), err<=7ulps+cancel */
+ cancel -= EXP(cst);
+#ifdef DEBUG
+ printf("cancelled bits=%d\n", cancel);
+ printf("approx="); mpfr_print_raw(cst); putchar('\n');
+#endif
+ if (cancel<0) cancel=0;
+
+ /* If we can round the result, we set it and go out of the loop */
+
+ /* we have 7 ulps of error from the above roundings,
+ 4 ulps from the 4/s^2 second order term,
+ plus the cancelled bits */
+ if (mpfr_can_round(cst,p-cancel-4,GMP_RNDN,rnd_mode,q)==1) {
+ mpfr_set(r,cst,rnd_mode);
+#ifdef DEBUG
+ printf("result="); mpfr_print_raw(r); putchar('\n');
+#endif
+ bool=0;
+ }
+ /* else we increase the precision */
+ else {
+ p += BITS_PER_MP_LIMB+cancel;
+ TMP_FREE(marker);
+ }
+
+ /* We clean */
+ TMP_FREE(marker);
+
+ }
+ return 1; /* result is inexact */
+}
+
+
diff --git a/mpfr/log2.c b/mpfr/log2.c
new file mode 100644
index 000000000..151e0e8cb
--- /dev/null
+++ b/mpfr/log2.c
@@ -0,0 +1,102 @@
+/* mpfr_log2 -- compute natural logarithm of 2
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+mpfr_t __mpfr_log2; /* stored value of log(2) with rnd_mode=GMP_RNDZ */
+int __mpfr_log2_prec=0; /* precision of stored value */
+
+/* set x to log(2) rounded to precision PREC(x) with direction rnd_mode
+
+ use formula log(2) = sum(1/k/2^k, k=1..infinity)
+
+ whence 2^N*log(2) = S(N) + R(N)
+
+ where S(N) = sum(2^(N-k)/k, k=1..N-1)
+ and R(N) = sum(1/k/2^(k-N), k=N..infinity) < 2/N
+
+ Let S'(N) = sum(floor(2^(N-k)/k), k=1..N-1)
+
+ Then 2^N*log(2)-S'(N) <= N-1+2/N <= N for N>=2.
+*/
+void
+#if __STDC__
+mpfr_log2(mpfr_ptr x, unsigned char rnd_mode)
+#else
+mpfr_log2(x, rnd_mode) mpfr_ptr x; unsigned char rnd_mode;
+#endif
+{
+ int N, oldN, k, precx; mpz_t s, t, u;
+
+ precx = PREC(x);
+
+ /* has stored value enough precision ? */
+ if (precx <= __mpfr_log2_prec) {
+ if (rnd_mode==GMP_RNDZ || rnd_mode==GMP_RNDD ||
+ mpfr_can_round(__mpfr_log2, __mpfr_log2_prec, GMP_RNDZ, rnd_mode, precx))
+ {
+ mpfr_set(x, __mpfr_log2, rnd_mode); return;
+ }
+ }
+
+ /* need to recompute */
+ N=2;
+ do {
+ oldN = N;
+ N = precx + (int)ceil(log((double)N)/log(2.0));
+ } while (N != oldN);
+ mpz_init_set_ui(s,0);
+ mpz_init(u);
+ mpz_init_set_ui(t,1);
+#if 0
+ /* use log(2) = sum(1/k/2^k, k=1..infinity) */
+ mpz_mul_2exp(t, t, N);
+ for (k=1;k<N;k++) {
+ mpz_div_2exp(t, t, 1);
+ mpz_fdiv_q_ui(u, t, k);
+ mpz_add(s, s, u);
+ }
+#else
+ /* use log(2) = sum((6*k-1)/(2*k^2-k)/2^(2*k+1), k=1..infinity) */
+ mpz_mul_2exp(t, t, N-1);
+ for (k=1;k<N/2;k++) {
+ mpz_div_2exp(t, t, 2);
+ mpz_mul_ui(u, t, 6*k-1);
+ mpz_fdiv_q_ui(u, u, k*(2*k-1));
+ mpz_add(s, s, u);
+ }
+#endif
+ mpfr_set_z(x, s, rnd_mode);
+ EXP(x) -= N;
+
+ /* stored computed value */
+ if (__mpfr_log2_prec==0) mpfr_init2(__mpfr_log2, precx);
+ else mpfr_set_prec(__mpfr_log2, precx);
+ mpfr_set(__mpfr_log2, x, GMP_RNDZ);
+ __mpfr_log2_prec=precx;
+
+ mpz_clear(s); mpz_clear(t); mpz_clear(u);
+}
diff --git a/mpfr/mpfr-impl.h b/mpfr/mpfr-impl.h
new file mode 100644
index 000000000..3464febb1
--- /dev/null
+++ b/mpfr/mpfr-impl.h
@@ -0,0 +1,58 @@
+/* Utilities for MPFR developers, not exported.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+
+/* generate a random double using the whole range of possible values,
+ including denormalized numbers, NaN, infinities, ... */
+double drand()
+{
+ volatile double d; int *i;
+
+ i = (int*) &d;
+ i[0] = mrand48();
+ i[1] = mrand48();
+ return d;
+}
+
+/* returns the number of ulp's between a and b */
+int ulp(a,b) double a,b;
+{
+ double eps=1.1102230246251565404e-16; /* 2^(-53) */
+ if (a==0.0) {
+ if (b==0.0) return 0;
+ else if (b<0.0) return 2147483647;
+ else return -2147483647;
+ }
+ b = (a-b)/a;
+ if (b>0)
+ return (int) floor(b/eps);
+ else
+ return (int) ceil(b/eps);
+}
+
+/* return double m*2^e */
+double dbl(m,e) double m; int e;
+{
+ if (e>=0) while (e-->0) m *= 2.0;
+ else while (e++<0) m /= 2.0;
+ return m;
+}
diff --git a/mpfr/mpfr.h b/mpfr/mpfr.h
new file mode 100644
index 000000000..9f25eba2f
--- /dev/null
+++ b/mpfr/mpfr.h
@@ -0,0 +1,204 @@
+/* mpfr.h -- Include file for mpfr.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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>
+
+/* Cygnus does not know about *rand48 functions */
+#ifdef __CYGWIN32__
+#define mrand48 rand
+#define drand48 rand
+#define lrand48 rand
+#define srand48 srand
+#endif
+
+/* Definition of rounding modes */
+
+#define GMP_RNDN 0
+#define GMP_RNDZ 1
+#define GMP_RNDU 2
+#define GMP_RNDD 3
+
+/* Definitions of types and their semantics */
+
+typedef struct {
+ unsigned long int _mp_prec; /* WARNING : for the mpfr type, the precision */
+ /* should be understood as the number of BITS,*/
+ /* not the number of mp_limb_t's. This means */
+ /* that the corresponding number of allocated
+ limbs is >= ceil(_mp_prec/BITS_PER_MP_LIMB) */
+ mp_size_t _mp_size; /* abs(_mp_size) is the number of allocated
+ limbs the field _mp_d points to.
+ The sign is that of _mp_size.
+ The number 0 is such that _mp_d[k-1]=0
+ where k = ceil(_mp_prec/BITS_PER_MP_LIMB) */
+ mp_exp_t _mp_exp;
+ mp_limb_t *_mp_d;
+}
+__mpfr_struct;
+
+/*
+ The number represented is
+
+ sign(_mp_size)*(_mp_d[k-1]/B+_mp_d[k-2]/B^2+...+_mp_d[0]/B^k)*2^_mp_exp
+
+ where k=ceil(_mp_prec/BITS_PER_MP_LIMB) and B=2^BITS_PER_MP_LIMB.
+
+ For the msb (most significant bit) normalized representation, we must have
+ _mp_d[k-1]>=B/2, unless the number is zero (in that case its sign is still
+ given by sign(_mp_size)).
+
+ We must also have the last k*BITS_PER_MP_LIMB-_mp_prec bits set to zero.
+*/
+
+typedef __mpfr_struct mpfr_t[1];
+typedef __mpfr_struct *mpfr_ptr;
+typedef __gmp_const __mpfr_struct *mpfr_srcptr;
+
+
+/* Prototypes */
+
+#ifndef _PROTO
+#if defined (__STDC__) || defined (__cplusplus)
+#define _PROTO(x) x
+#else
+#define _PROTO(x) ()
+#endif
+#endif
+
+/* bit 31 of _mp_size is used for sign,
+ bit 30 of _mp_size is used for Nan flag,
+ remaining bits are used to store the number of allocated limbs */
+#define FLAG_NAN(x) (((x)->_mp_size >> 30)&1)
+#define SET_NAN(x) ((x)->_mp_size |= (1<<30))
+#define ABSSIZE(x) ((x)->_mp_size & ((1<<30)-1))
+#define SIZE(x) ((x)->_mp_size)
+#define EXP(x) ((x)->_mp_exp)
+#define MANT(x) ((x)->_mp_d)
+#define SIGN(x) (((x)->_mp_size >> 31) ? -1 : 1)
+#define ISNONNEG(x) (SIGN(x)>=0)
+#define ISNEG(x) (SIGN(x)==-1)
+#define CHANGE_SIGN(x) (SIZE(x) = SIZE(x) ^ (1<<31))
+#define PREC(x) ((x)->_mp_prec)
+#define NOTZERO(x) (MANT(x)[(PREC(x)-1)/BITS_PER_MP_LIMB])
+#define SET_ZERO(x) (MANT(x)[(PREC(x)-1)/BITS_PER_MP_LIMB] = 0)
+
+/* reallocates the mantissa of x to q bits and sets the precision to q */
+#define _mpfr_realloc(x, q) { \
+ (x)->_mp_d = (mp_ptr) (*_mp_reallocate_func) \
+ ((x)->_mp_d, (x)->_mp_prec>>3 + 1, (q)>>3 + 1); \
+ (x)->_mp_prec = q; }
+
+void mpfr_init2 _PROTO ((mpfr_ptr, unsigned long int));
+int mpfr_round_raw _PROTO ((mp_limb_t *, mp_limb_t *, unsigned long, char,
+ unsigned long, char));
+int mpfr_round_raw2 _PROTO ((mp_limb_t *, unsigned long, char, char,
+ unsigned long));
+void mpfr_round _PROTO ((mpfr_ptr, char, unsigned long));
+int mpfr_can_round _PROTO ((mpfr_ptr, unsigned long, unsigned char,
+ unsigned char, unsigned long));
+int mpfr_can_round_raw _PROTO ((mp_limb_t *, unsigned long, int,
+ unsigned long,
+ unsigned char, unsigned char, unsigned long));
+void mpfr_set_d _PROTO ((mpfr_ptr, double, unsigned char));
+int mpfr_set_z _PROTO ((mpfr_ptr, mpz_srcptr, unsigned char));
+double mpfr_get_d _PROTO ((mpfr_srcptr));
+double mpfr_get_d2 _PROTO ((mpfr_srcptr, long));
+void mpfr_set_f _PROTO ((mpfr_ptr, mpf_srcptr, char));
+void mpfr_set_si _PROTO ((mpfr_ptr, long, unsigned char));
+void mpfr_set_ui _PROTO ((mpfr_ptr, unsigned long, unsigned char));
+void mpfr_print_raw _PROTO ((mpfr_srcptr));
+void mpfr_random _PROTO ((mpfr_ptr));
+void mpfr_clear _PROTO ((mpfr_ptr));
+void mpfr_set_str_raw _PROTO ((mpfr_ptr, char *));
+void mpfr_get_str_raw _PROTO ((char *, mpfr_srcptr));
+char* mpfr_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpfr_srcptr, unsigned char));
+size_t mpfr_out_str _PROTO ((FILE *, int, size_t, mpfr_srcptr, unsigned char));
+void mpfr_mul _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, unsigned char));
+void mpfr_pow_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned int, unsigned char));
+void mpfr_ui_pow_ui _PROTO ((mpfr_ptr, unsigned int, unsigned int, unsigned char));
+mp_limb_t mpn_divrem_n _PROTO ((mp_limb_t *, mp_limb_t *, mp_limb_t *, mp_size_t));
+mp_size_t kara_sqrtrem _PROTO ((mp_limb_t *, mp_limb_t *, mp_limb_t *, mp_size_t));
+void mpfr_div _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, unsigned char));
+void mpfr_agm _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, unsigned char));
+int mpfr_sqrt _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned char));
+void mpfr_add _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, unsigned char));
+int mpfr_add_one_ulp _PROTO ((mpfr_ptr));
+void mpfr_sub _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, unsigned char));
+void mpfr_set4 _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned char, int));
+void mpfr_pi _PROTO ((mpfr_ptr, unsigned char));
+void mpfr_log2 _PROTO ((mpfr_ptr, unsigned char));
+int mpfr_log _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned char));
+int mpfr_exp _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned char));
+int mpfr_zeta _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned char));
+void mpfr_mul_ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long, unsigned char));
+void mpfr_set_machine_rnd_mode _PROTO ((unsigned char));
+int mpfr_cmp3 _PROTO ((mpfr_srcptr, mpfr_srcptr, long int));
+int mpfr_cmp_ui_2exp _PROTO ((mpfr_srcptr, unsigned long int, int));
+int mpfr_cmp_si_2exp _PROTO ((mpfr_srcptr, long int, int));
+int mpfr_cmp2 _PROTO ((mpfr_srcptr, mpfr_srcptr));
+void mpfr_mul_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int,unsigned char));
+void mpfr_div_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int,unsigned char));
+void mpfr_set_prec _PROTO((mpfr_ptr, unsigned long int));
+void mpfr_set_default_prec _PROTO((unsigned long int));
+extern mp_size_t __gmp_default_fp_bit_precision;
+extern char __gmp_default_rounding_mode;
+char * mpfr_print_rnd_mode _PROTO((unsigned char));
+void mpfr_neg _PROTO((mpfr_ptr, mpfr_srcptr, unsigned char));
+int mpfr_sub_one_ulp _PROTO((mpfr_ptr x));
+int mpfr_div_ui _PROTO((mpfr_ptr y, mpfr_srcptr x, unsigned long u, unsigned char rnd_mode));
+unsigned long int mpfr_get_prec _PROTO((mpfr_t x));
+
+#define mpfr_init(x) mpfr_init2(x, __gmp_default_fp_bit_precision)
+#define mpfr_cmp_ui(b,i) mpfr_cmp_ui_2exp(b,i,0)
+#define mpfr_cmp_si(b,i) mpfr_cmp_si_2exp(b,i,0)
+#define mpfr_set(a,b,r) mpfr_set4(a,b,r,SIGN(b))
+#define mpfr_cmp(b,c) mpfr_cmp3(b,c,1)
+
+#if (BITS_PER_MP_LIMB==32)
+#define MPFR_LIMBS_PER_DOUBLE 2
+#elif (BITS_PER_MP_LIMB==64)
+#define MPFR_LIMBS_PER_DOUBLE 1
+#endif
+
+/* gmp-2.0.2 had only one threshold for both multiplication and squaring */
+#ifndef KARATSUBA_MUL_THRESHOLD
+#ifdef KARATSUBA_THRESHOLD
+#define KARATSUBA_MUL_THRESHOLD KARATSUBA_THRESHOLD
+#else
+#define KARATSUBA_MUL_THRESHOLD 16
+#endif
+#endif
+
+#define mpfr_init_set_si(x, i, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set_si((x), (i), (rnd));
+#define mpfr_init_set_ui(x, i, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set_ui((x), (i), (rnd));
+#define mpfr_init_set_d(x, d, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set_d((x), (d), (rnd));
+#define mpfr_init_set(x, y, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set((x), (y), (rnd));
+#define mpfr_init_set_f(x, y, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set_f((x), (y), (rnd));
+#define mpfr_init_set_str(x, y, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set_str((x), (y), (rnd));
+#define mpfr_init_set_str_raw(x, y, p, rnd) \
+ mpfr_init2((x), (p)); mpfr_set_str_raw((x), (y), (rnd));
+
diff --git a/mpfr/mpfr.texi b/mpfr/mpfr.texi
new file mode 100644
index 000000000..e74f74a70
--- /dev/null
+++ b/mpfr/mpfr.texi
@@ -0,0 +1,1075 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gmp.info
+@settitle MPFR 1.0
+@synindex tp fn
+@iftex
+@afourpaper
+@end iftex
+@comment %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* mpfr: (mpfr.info). Multiple Precision Floating-Point Reliable Library.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@c smallbook
+
+@iftex
+@finalout
+@end iftex
+
+@c Note: the edition number is listed in *three* places; please update
+@c all three. Also, update the month and year where appropriate.
+
+@c ==> Update edition number for settitle and subtitle, and in the
+@c ==> following paragraph; update date, too.
+
+
+@ifinfo
+This file documents MPFR, a library for reliable multiple precision floating-point arithmetic
+
+Copyright (C) 1999, PolKA team, INRIA Lorraine and LORIA, France
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@setchapternewpage on
+@titlepage
+@c use the new format for titles
+
+@title MPFR
+@subtitle The Multiple Precision Floating-Point Reliable Library
+@subtitle Edition 1.0
+@subtitle June 1999
+
+@author the PolKA project, INRIA Lorraine and LORIA
+
+@c Include the Distribution inside the titlepage so
+@c that headings are turned off.
+
+@tex
+\global\parindent=0pt
+\global\parskip=8pt
+\global\baselineskip=13pt
+@end tex
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1999 The PolKA project
+
+@sp 2
+
+Published by the Free Software Foundation @*
+59 Temple Place - Suite 330 @*
+Boston, MA 02111-1307, USA @*
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end titlepage
+@headings double
+
+@ifinfo
+@node Top, Copying, (dir), (dir)
+
+@top MPFR
+
+This manual documents how to install and use the Multiple Precision
+Floating-Point Reliable Library, version 1.0
+
+@end ifinfo
+
+@menu
+* Copying:: GMP Copying Conditions (LGPL).
+* Introduction to MPFR:: Brief introduction to MPFR.
+* Installing MPFR:: How to configure and compile the MPFR library.
+* MPFR Basics:: What every MPFR user should now.
+* Reporting Bugs:: How to usefully report bugs.
+* Floating-point Functions:: Functions for arithmetic on floats.
+
+* Contributors::
+* References::
+* Concept Index::
+* Function Index::
+@end menu
+
+@node Copying, Introduction to MPFR, Top, Top
+@comment node-name, next, previous, up
+@unnumbered MPFR Copying Conditions
+@cindex Copying conditions
+@cindex Conditions for copying MPFR
+
+This library is @dfn{free}; this means that everyone is free to use it and
+free to redistribute it on a free basis. The library is not in the public
+domain; it is copyrighted and there are restrictions on its distribution, but
+these restrictions are designed to permit everything that a good cooperating
+citizen would want to do. What is not allowed is to try to prevent others
+from further sharing any version of this library that they might get from
+you.@refill
+
+Specifically, we want to make sure that you have the right to give away copies
+of the library, that you receive source code or else can get it if you want
+it, that you can change this library or use pieces of it in new free programs,
+and that you know you can do these things.@refill
+
+To make sure that everyone has such rights, we have to forbid you to deprive
+anyone else of these rights. For example, if you distribute copies of the
+MPFR library, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And you
+must tell them their rights.@refill
+
+Also, for our own protection, we must make certain that everyone finds out
+that there is no warranty for the MPFR library. If it is modified by
+someone else and passed on, we want their recipients to know that what they
+have is not what we distributed, so that any problems introduced by others
+will not reflect on our reputation.@refill
+
+The precise conditions of the license for the MPFR library are found in the
+Library General Public License that accompany the source code.
+See the file COPYING.LIB.@refill
+
+@node Introduction to MPFR, Installing MPFR, Copying, Top
+@comment node-name, next, previous, up
+@chapter Introduction to MPFR
+
+
+MPFR is a portable library written in C for arbitrary precision arithmetic
+on reliable floating-point numbers. It is based on the GNU MP library.
+It aims to extend the class of floating-point numbers provided by the
+GNU MP library by @dfn{reliable} floating-point numbers. It may replace
+the GNU MP floating-point numbers in a future release. The main differences
+with the @code{mpf} class are:
+@itemize @bullet
+@item the @code{mpfr} code is portable, i.e. the result of any operation
+does not depend (or should not) on the machine word size
+@code{mp_bits_per_limb} (32 or 64 on most machines);
+@item the precision in bits can be set exactly to any positive value
+ for each variable (including one bit of precision);
+@item @code{mpfr} provides the four rounding modes from the IEEE 754
+ standard.
+@end itemize
+In particular, with a precision of 53 bits, @code{mpfr} should be able
+to exactly reproduce all computations with double-precision machine
+floating-point
+numbers (@code{double} type in C), except the range of values is much wider
+(the exponent has at least 32 bits instead of 11).
+
+This version of MPFR is released under the GNU Library General Public
+License.
+It is permitted to link MPFR to non-free programs, as long as MPFR
+source code is provided when distributing the non-free program.
+
+
+@section How to use this Manual
+
+Everyone should read @ref{MPFR Basics}. If you need to install the library
+yourself, you need to read @ref{Installing MPFR}, too.
+
+The rest of the manual can be used for later reference, although it is
+probably a good idea to glance through it.
+
+
+@node Installing MPFR, MPFR Basics, Introduction to MPFR, Top
+@comment node-name, next, previous, up
+@chapter Installing MPFR
+@cindex Installation
+
+To build MPFR, you first have to install GNU MP
+(version 2.0.2 or higher) on your computer.
+You need a C compiler, preferably GCC, but any reasonable compiler should
+work. And you need a standard Unix @samp{make} program, plus some other
+standard Unix utility programs.
+
+Here are the steps needed to install the library on Unix systems:
+
+@enumerate
+@item
+In most cases, @samp{./Configure} should work.
+If you get error messages, your machine might
+not be supported.
+
+If you want to compile in a separate object directory, cd to that directory,
+and prefix the configure command with the path to the MPFR source directory.
+Not all @samp{make} programs have the necessary features to support this. In
+particular, SunOS and Slowaris @samp{make} have bugs that make them unable to
+build from a separate object directory. Use GNU @samp{make} instead.
+Also, the generated makefiles use some pattern matching rules that are not
+supported by all @samp{make} programs. Again, use GNU @samp{make} instead.
+
+@item
+@samp{make}
+
+This will compile MPFR, and create a library archive file @file{libmpfr.a}
+in the working directory.
+
+@item
+@samp{make check}
+
+This will make sure MPFR was built correctly.
+If you get error messages, please
+report this to @samp{mpfr@@loria.fr}. (@xref{Reporting Bugs}, for
+information on what to include in useful bug reports.)
+
+@item
+@samp{make install}
+
+This will copy the files @file{mpfr.h} and @file{libmpfr.a},
+as well as the info
+files, to @file{/usr/local} (or if you passed the @samp{--prefix} option to
+@file{configure}, to the directory given as argument to @samp{--prefix}).
+@end enumerate
+
+There are some other useful make targets:
+
+@itemize @bullet
+@item
+@samp{doc}
+
+Create a DVI version of the manual, in @file{mpfr.dvi} and a set of info files,
+in @file{mpfr.info}, @file{mpfr.info-1}, @file{mpfr.info-2}, etc.
+
+@item
+@samp{ps}
+
+Create a Postscript version of the manual, in @file{mpfr.ps}.
+
+@item
+@samp{html}
+
+Create a HTML version of the manual, in @file{mpfr.html}.
+
+@item
+@samp{clean}
+
+Delete all object files and archive files, but not the configuration files.
+
+@item
+@samp{distclean}
+
+Delete all files not included in the distribution.
+
+@item
+@samp{uninstall}
+
+Delete all files copied by @samp{make install}.
+@end itemize
+
+
+@section Known Build Problems
+
+MPFR suffers from all bugs from the GNU MP library, plus many many more.
+
+Please report other problems to @samp{mpfr@@loria.fr}.
+@xref{Reporting Bugs}.
+
+
+@node MPFR Basics, Reporting Bugs, Installing MPFR, Top
+@comment node-name, next, previous, up
+@chapter MPFR Basics
+
+
+@cindex @file{mpfr.h}
+All declarations needed to use MPFR are collected in the include file
+@file{mpfr.h}. It is designed to work with both C and C++ compilers.
+
+
+@section Nomenclature and Types
+
+@cindex Floating-point number
+@tindex @code{mpfr_t}
+@noindent
+@dfn{Floating point number} or @dfn{Float} for short, is an arbitrary precision
+mantissa with a limited precision exponent. The C data type for such objects
+is @code{mpfr_t}.
+
+@cindex Limb
+@c @tindex @code{mp_limb_t}
+@noindent
+A @dfn{limb} means the part of a multi-precision number that fits in a single
+word. (We chose this word because a limb of the human body is analogous to a
+digit, only larger, and containing several digits.) Normally a limb contains
+32 or 64 bits. The C data type for a limb is @code{mp_limb_t}.
+
+@section Function Classes
+
+There is only one class of functions in the MPFR library:
+
+@enumerate
+@item
+Functions for floating-point arithmetic, with names beginning with
+@code{mpfr_}. The associated type is @code{mpfr_t}. There are about 50
+functions is this class.
+@end enumerate
+
+
+@section MPFR Variable Conventions
+
+As a general rule, all MPFR functions expect output arguments before input
+arguments. This notation is based on an analogy with the assignment operator.
+
+MPFR allows you to use the same variable for both input and output in the same
+expression. For example, the main function for floating-point multiplication,
+@code{mpfr_mul}, can be used like this: @code{mpfr_mul (x, x, x, rnd_mode)}.
+This
+computes the square of @var{x} with rounding mode @code{rnd_mode}
+and puts the result back in @var{x}.
+
+Before you can assign to an MPFR variable, you need to initialize it by calling
+one of the special initialization functions. When you're done with a
+variable, you need to clear it out, using one of the functions for that
+purpose.
+
+A variable should only be initialized once, or at least cleared out between
+each initialization. After a variable has been initialized, it may be
+assigned to any number of times.
+
+For efficiency reasons, avoid to initialize and clear out a variable in loops.
+Instead, initialize it before entering the loop, and clear it out after the
+loop has exited.
+
+You don't need to be concerned about allocating additional space for MPFR
+variables, since any variable has a mantissa of fixed size.
+Hence unless you change its precision, or clear and reinitialize it,
+a floating-point variable will have the same allocated space during all its
+life.
+
+@section Getting the Latest Version of MP
+
+The latest version of the MPFR library is available from the web page
+of the PolKA team at
+@samp{http://www.loria.fr/equipes/polka}.
+
+@node Reporting Bugs, MPFR Basics, Top
+@comment node-name, next, previous, up
+@chapter Reporting Bugs
+@cindex Reporting bugs
+
+If you think you have found a bug in the MPFR library, please investigate it
+and report it. We have made this library available to you, and it is not to ask
+too much from you, to ask you to report the bugs that you find.
+
+There are a few things you should think about when you put your bug report
+together.
+
+You have to send us a test case that makes it possible for us to reproduce the
+bug. Include instructions on how to run the test case.
+
+You also have to explain what is wrong; if you get a crash, or if the results
+printed are incorrect and in that case, in what way.
+
+Please include compiler version information
+in your bug report. This can be extracted using @samp{what `which cc`}, or,
+if you're using gcc, @samp{gcc -v}. Also, include the output from @samp{uname
+-a}.
+
+If your bug report is good, we will do our best to help you to get a corrected
+version of the library; if the bug report is poor, we won't do anything about
+it (aside of chiding you to send better bug reports).
+
+Send your bug report to: @samp{mpfr@@loria.fr}.
+
+If you think something in this manual is unclear, or downright incorrect, or if
+the language needs to be improved, please send a note to the same address.
+
+@node Floating-point Functions, Low-level Functions, Reporting bugs, Top
+@comment node-name, next, previous, up
+@chapter Floating-point Functions
+@cindex Floating-point functions
+@cindex Float functions
+
+The floating-point functions expect arguments of type @code{mpfr_t}.
+
+The MPFR floating-point functions have an interface that is similar to the
+GNU MP
+integer functions. The function prefix for floating-point operations is
+@code{mpfr_}.
+
+There is one significant characteristic of floating-point numbers that has
+motivated a difference between this function class and other MPFR function
+classes: the inherent inexactness of floating point arithmetic. The user has
+to specify the precision of each variable. A computation that assigns a
+variable will take place with the precision of the assigned variable; the
+cost of that computation should not depend from the
+precision of variables used as input on average.
+
+@cindex User-defined precision
+The precision of a calculation is defined as follows: Compute the requested
+operation exactly (with ``infinite precision''), and round the result to
+the destination variable precision with the given rounding mode.
+Even if the user has asked for a very
+high precision, MP will not calculate with superfluous digits. For example,
+if two low-precision numbers of nearly equal magnitude are added, the
+precision of the result will be limited to what is required to represent the
+result accurately.
+
+The MPFR floating-point functions are intended to be a smooth extension
+of the IEEE P754 arithmetic. The results obtained on one
+computer should not differ from the results obtained on a computer with a
+different word size.
+
+@menu
+* Rounding Modes
+* Initializing Floats::
+* Assigning Floats::
+* Converting Floats::
+* Float Arithmetic::
+* Float Comparison::
+* I/O of Floats::
+* Miscellaneous Float Functions::
+@end menu
+
+@cindex Rouding modes
+@section Global Variables and Rounding Modes
+
+@deftypevr {Global Variable} {mp_size_t} __gmp_default_fp_bit_precision
+The default precision in bits (53 initially).
+@end deftypevr
+
+@deftypevr {Global Variable} {char} __gmp_default_rounding_mode
+The default rounding mode (to nearest initially).
+@end deftypevr
+
+The following four rounding modes are supported:
+@itemize @bullet
+@item @code{GMP_RNDN}: round to nearest
+@item @code{GMP_RNDZ}: round towards zero
+@item @code{GMP_RNDU}: round towards plus infinity
+@item @code{GMP_RNDD}: round towards minus infinity
+@end itemize
+The @samp{round to nearest} mode works as in the IEEE P754 standard: in case
+the number to be rounded lies exactly in the middle of two reprensentable
+numbers, it is rounded to the one with the least significant bit set to zero.
+For example, the number 5, which is represented by (101) in binary, is rounded
+to (100)=4 with a precision of two bits, and not to (110)=6.
+This rule avoids the @dfn{drift} phenomena mentioned by Knuth in volume 2
+of The Art of Computer Programming (section 4.2.2, pages 221-222).
+
+@deftypefun void mpfr_set_default_rounding_mode (char @var{rnd})
+Sets the default rounding mode to @var{rnd}.
+The default rounding mode is to nearest initially.
+@end deftypefun
+
+@deftypefun void mpfr_round (mpfr_t @var{x}, char @var{rnd}, unsigned long @var{prec})
+Round @var{x} according to @var{rnd} with precision @var{prec}, which
+may be different from that of @var{x}.
+If @var{prec} is greater or equal to the precision of @var{x}, then new
+space is allocated for the mantissa, and it is filled with zeroes.
+Otherwise, the mantissa is rounded to precision @var{prec} with the given
+direction. In both cases, the precision of @var{x} is changed to @var{prec}.
+@end deftypefun
+
+@deftypefun void mpfr_set_machine_rnd_mode (char @var{rnd})
+Set the machine rounding mode to @var{rnd}.
+This function is useful for debugging purpose, but
+also as a common interface to all different ways of setting the
+rounding mode, which unfortunately differ from one operating system to
+another one.
+@end deftypefun
+
+@deftypefun {char *} mpfr_print_rnd_mode (unsigned char @var{rnd})
+Returns the input string (GMP_RNDD, GMP_RNDU, GMP_RNDN, GMP_RNDZ)
+corresponding to the rounding mode @var{rnd}.
+@end deftypefun
+
+@node Initializing Floats, Assigning Floats, , Floating-point Functions
+@comment node-name, next, previous, up
+@section Initialization and Assignment Functions
+
+@deftypefun void mpfr_set_default_prec (unsigned long int @var{prec})
+Set the default precision to be @strong{exactly} @var{prec} bits. The
+precision of a variable means the number of bits used to store its mantissa.
+All
+subsequent calls to @code{mpf_init} will use this precision, but previously
+initialized variables are unaffected.
+This default precision is set to 53 bits initially.
+The precision can be any positive integer, even a precision of 1 is possible.
+@end deftypefun
+
+An @code{mpfr_t} object must be initialized before storing the first value in
+it. The functions @code{mpfr_init} and @code{mpfr_init2} are used for that
+purpose.
+
+@deftypefun void mpfr_init (mpfr_t @var{x})
+Initialize @var{x}. No special value is set.
+Normally, a variable should be initialized once only
+or at least be cleared, using @code{mpfr_clear}, between initializations. The
+precision of @var{x} is the default precision, which can be changed
+by a call to @code{mpfr_set_default_prec}.
+@end deftypefun
+
+@deftypefun void mpfr_init2 (mpfr_t @var{x}, unsigned long int @var{prec})
+Initialize @var{x} and set its precision to be @strong{exactly}
+@var{prec} bits. Normally, a variable should be initialized once only or at
+least be cleared, using @code{mpfr_clear}, between initializations.
+To change the precision of a variable which has already been initialized,
+use @code{mpfr_set_prec} instead.
+@end deftypefun
+
+@deftypefun void mpfr_clear (mpfr_t @var{x})
+Free the space occupied by @var{x}. Make sure to call this function for all
+@code{mpfr_t} variables when you are done with them.
+@end deftypefun
+
+@need 2000
+Here is an example on how to initialize floating-point variables:
+@example
+@{
+ mpfr_t x, y;
+ mpfr_init (x); /* use default precision */
+ mpfr_init2 (y, 256); /* precision @emph{exactly} 256 bits */
+ @dots{}
+ /* Unless the program is about to exit, do ... */
+ mpfr_clear (x);
+ mpfr_clear (y);
+@}
+@end example
+
+The following two functions are useful for changing the precision during a
+calculation. A typical use would be for adjusting the precision gradually in
+iterative algorithms like Newton-Raphson, making the computation precision
+closely match the actual accurate part of the numbers.
+
+@deftypefun void mpfr_set_prec (mpfr_t @var{x}, unsigned long int @var{prec})
+Reset the precision of @var{x} to be @strong{exactly} @var{prec} bits.
+The previous value stored in @var{x} is lost. It is equivalent to
+a call to @code{mpfr_clear(x)} followed by a call to
+@code{mpfr_init2(x, prec)}, but more efficient as no allocation is done in
+case the current allocated space for the mantissa of @var{x} is enough.
+
+In case you want to keep the previous value stored in @var{x},
+use @code{mpfr_round} instead.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpfr_get_prec (mpf_t @var{x})
+Return the precision actually used for assignments of @var{x}, i.e.
+the number of bits used to store its mantissa.
+@end deftypefun
+
+@node Assigning Floats, Simultaneous Float Init & Assign, Initializing Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@subsection Assignment Functions
+@cindex Float assignment functions
+
+These functions assign new values to already initialized floats
+(@pxref{Initializing Floats}).
+
+@deftypefun void mpfr_set (mpfr_t @var{rop}, mpfr_t @var{op}, char @var{rnd})
+@deftypefunx void mpfr_set_ui (mpfr_t @var{rop}, unsigned long int @var{op}, char @var{rnd})
+@deftypefunx void mpfr_set_si (mpfr_t @var{rop}, long int @var{op}, char @var{rnd}
+@deftypefunx void mpfr_set_d (mpfr_t @var{rop}, double @var{op}, char @var{rnd})
+@deftypefunx void mpfr_set_z (mpfr_t @var{rop}, mpz_t @var{op}, char @var{rnd})
+Set the value of @var{rop} from @var{op}, rounded to the precision of @var{rop}
+towards the given direction @var{rnd}.
+Please note that even a @code{long int} may have to be rounded,
+if the destination precision is less than the machine word width.
+@end deftypefun
+
+@deftypefun void mpfr_set_str_raw (mpfr_t @var{x}, char *@var{s})
+Set @var{x} to the value of the binary number in string @var{s}, which has to
+be of the
+form +/-xxxx.xxxxxxEyy. The exponent is read in decimal, but is interpreted
+as the power of two to be multiplied by the mantissa.
+@end deftypefun
+
+@deftypefun void mpfr_set_f (mpfr_t @var{x}, mpf_t @var{y}, char @var{rnd})
+Set @var{x} to the GNU MP floating-point number
+@var{y}, rounded with the @var{rnd} mode and the precision
+of @var{x}.
+@end deftypefun
+
+@node Converting Floats, Float Arithmetic, Simultaneous Float Init & Assign, Floating-point Functions
+@comment node-name, next, previous, up
+@section Conversion Functions
+@cindex Conversion functions
+
+@deftypefun double mpfr_get_d (mpfr_t @var{op})
+Convert @var{op} to a double, using the current @emph{machine} rounding mode.
+@end deftypefun
+
+@deftypefun {char *} mpfr_get_str (char *@var{str}, mp_exp_t *@var{expptr}, int @var{base}, size_t @var{n_digits}, mpfr_t @var{op}, char @var{rnd})
+Convert @var{op} to a string of digits in base @var{base}, with rounding in
+direction @var{rnd}. The base may vary
+from 2 to 36. Generate exactly @var{n_digits} significant digits.
+
+If @var{n_digits} is 0, it prints the maximum possible number of digits
+giving an exact rounding in the given base @var{base} with the direction
+@var{rnd}. In other words, if @var{op} was the exact rounding
+of a real number in direction @var{rnd}, then the printed value is also
+an exact rounding in base @var{base} of that real number with the same
+precision. An error occurs when one is unable to determine the leading
+digit, which can happen especially if the precision of @var{op} is small.
+
+If @var{str} is NULL, space for the mantissa is allocated using the default
+allocation function, and a pointer to the string is returned.
+
+If @var{str} is not NULL, it should point to a block of storage enough large
+for the mantissa, i.e., @var{n_digits} + 2. The two extra bytes are for a
+possible minus sign, and for the terminating null character.
+
+The exponent is written through the pointer @var{expptr}.
+
+If @var{n_digits} is 0, note that the space
+requirements for @var{str} in this case will be impossible for the user to
+predetermine. Therefore, you need to pass NULL for the string argument
+whenever @var{n_digits} is 0.
+
+The generated string is a fraction, with an implicit radix point immediately
+to the left of the first digit. For example, the number 3.1416 would be
+returned as "31416" in the string and 1 written at @var{expptr}.
+@end deftypefun
+
+
+@node Float Arithmetic, Float Comparison, Converting Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Basic Arithmetic Functions
+@cindex Float arithmetic functions
+@cindex Arithmetic functions
+
+@deftypefun void mpfr_add (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, char @var{rnd})
+@ifinfo
+Set @var{rop} to @var{op1} + @var{op2} rounded in the direction @var{rnd}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} + @var{op2}$ rounded in the direction @var{rnd}.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpfr_sub (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, char @var{rnd})
+Set @var{rop} to @var{op1} @minus{} @var{op2} rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun void mpfr_mul (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, char @var{rnd})
+@deftypefunx void mpfr_mul_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, char @var{rnd})
+@ifinfo
+Set @var{rop} to @var{op1} times @var{op2} rounded in the direction @var{rnd}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} \times @var{op2}$ rounded in the direction @var{rnd}.
+@end tex
+@end iftex
+@end deftypefun
+
+Division is undefined if the divisor is zero, and passing a zero divisor to
+the divide functions will make these functions intentionally divide by zero.
+This gives the user the possibility to handle arithmetic exceptions in these
+functions in the same manner as other arithmetic exceptions.
+
+@deftypefun void mpfr_div (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, char @var{rnd})
+@deftypefunx int mpfr_div_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, char @var{rnd})
+Set @var{rop} to @var{op1}/@var{op2} rounded in the direction @var{rnd}.
+@c Return 0 if the division is exact, a non-zero value otherwise.
+@end deftypefun
+
+@deftypefun int mpfr_sqrt (mpfr_t @var{rop}, mpfr_t @var{op}, char @var{rnd})
+@ifinfo
+Set @var{rop} to the square root of @var{op} rounded in the direction @var{rnd}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $\sqrt{@var{op}}$ rounded in the direction @var{rnd}.
+@end tex
+@end iftex
+Set @var{rop} to NaN if @var{op} is negative.
+Return 0 if the operation is exact, a non-zero value otherwise.
+@end deftypefun
+
+@deftypefun void mpfr_pow_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, char @var{rnd})
+@deftypefunx void mpfr_ui_pow_ui (mpfr_t @var{rop}, unsigned long int @var{op1}, unsigned long int @var{op2}, char @var{rnd})
+Set @var{rop} to @var{op1} raised to @var{op2}. The computation is done by
+binary exponentiation, each multiplication being rounded to direction
+@var{rnd}. Hence the relative error with respect to the exact result may be
+larger than one unit in last place (ulp). In other words, this function does
+not provide an exact rounding.
+@end deftypefun
+
+@deftypefun void mpfr_neg (mpfr_t @var{rop}, mpfr_t @var{op}, char @var{rnd})
+Set @var{rop} to @minus{}@var{op} rounded in the direction @var{rnd}.
+Just changes the sign
+if @var{rop} and @var{op} are the same variable.
+@end deftypefun
+
+@c @deftypefun void mpfr_abs (mpfr_t @var{rop}, mpfr_t @var{op})
+@c Set @var{rop} to the absolute value of @var{op}.
+@c @end deftypefun
+
+@deftypefun void mpfr_mul_2exp (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, char @var{rnd})
+@ifinfo
+Set @var{rop} to @var{op1} times 2 raised to @var{op2}
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} \times 2^{op2}$
+@end tex
+@end iftex
+rounded to the direction @var{rnd}. Just increases the exponent by @var{op2}
+when @var{rop} and @var{op1} are identical.
+@end deftypefun
+
+@deftypefun void mpfr_div_2exp (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} divided by 2 raised to @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1}/2^{op2}$.
+@end tex
+@end iftex
+rounded to the direction @var{rnd}. Just decreases the exponent by @var{op2}
+when @var{rop} and @var{op1} are identical.
+@end deftypefun
+
+@node Float Comparison, I/O of Floats, Float Arithmetic, Floating-point Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+@cindex Float comparisons functions
+@cindex Comparison functions
+
+@deftypefun int mpfr_cmp (mpfr_t @var{op1}, mpfr_t @var{op2})
+@deftypefunx int mpfr_cmp_ui (mpfr_t @var{op1}, unsigned long int @var{op2})
+@deftypefunx int mpfr_cmp_si (mpfr_t @var{op1}, signed long int @var{op2})
+@ifinfo
+Compare @var{op1} and @var{op2}. Return a positive value if @var{op1} >
+@var{op2}, zero if @var{op1} = @var{op2}, and a negative value if @var{op1} <
+@var{op2}.
+@end ifinfo
+@iftex
+@tex
+Compare @var{op1} and @var{op2}. Return a positive value if $@var{op1} >
+@var{op2}$, zero if $@var{op1} = @var{op2}$, and a negative value if $@var{op1}
+< @var{op2}$.
+@end tex
+@end iftex
+Both @var{op1} and @var{op2} are considered to their full own precision,
+which may differ. In case @var{op1} and @var{op2} are of same sign but
+different, the absolute value returned is
+one plus the absolute difference of their exponents.
+@end deftypefun
+
+@deftypefun int mpfr_cmp_ui_2exp (mpfr_t @var{op1}, unsigned long int @var{op2}, int @var{e})
+@deftypefunx int mpfr_cmp_si_2exp (mpfr_t @var{op1}, unsigned long int @var{op2}, int @var{e})
+Compare @var{op1} and @var{op2} multiplied by two to the power @var{e}.
+@end deftypefun
+
+@c @deftypefun int mpfr_eq (mpfr_t @var{op1}, mpfr_t @var{op2}, unsigned long int op3)
+@c Return non-zero if the first @var{op3} bits of @var{op1} and @var{op2} are
+@c equal, zero otherwise. I.e., test of @var{op1} and @var{op2} are
+@c approximately equal.
+@c @end deftypefun
+
+@c @deftypefun void mpfr_reldiff (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2})
+@c Compute the relative difference between @var{op1} and @var{op2} and store the
+@c result in @var{rop}.
+@c @end deftypefun
+
+@deftypefn Macro int SIGN (mpfr_t @var{op})
+@ifinfo
+Return +1 if @var{op} > 0, and @minus{}1 if @var{op} < 0.
+@end ifinfo
+@iftex
+@tex
+Return $+1$ if $@var{op} > 0$, and $-1$ if $@var{op} < 0$.
+@end tex
+@end iftex
+This function is actually implemented as a macro. It evaluates its
+arguments multiple times.
+As in the IEEE 754 standard, there is a positive zero and a negative one,
+therefore the @var{SIGN} macro does not distinguish zero from non-zero
+numbers.
+@end deftypefn
+
+@deftypefn Macro int NOTZERO (mpfr_t @var{op})
+Returns zero when its argument is zero, and a non-zero value otherwise.
+@end deftypefn
+
+@section Special Functions
+@cindex Special functions
+
+@deftypefun int mpfr_log (mpfr_t @var{rop}, mpfr_t @var{op}, char @var{rnd})
+Set @var{rop} to the natural logarithm of @var{op},
+rounded to the direction @var{rnd} with the precision of @var{rop}.
+Return 0 iff the result is exact (this occurs in fact only when @var{op} is 1
+i.e. the result is 0).
+@end deftypefun
+
+@deftypefun int mpfr_exp (mpfr_t @var{rop}, mpfr_t @var{op}, char @var{rnd})
+Set @var{rop} to the exponential of @var{op},
+rounded to the direction @var{rnd} with the precision of @var{rop}.
+Return 0 iff the result is exact (this occurs in fact only when @var{op} is 0
+i.e. the result is 1).
+@end deftypefun
+
+@deftypefun void mpfr_agm (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, char @var{rnd})
+Set @var{rop} to the arithmetic-geometric mean of @var{op1} and @var{op2},
+rounded to the direction @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun void mpfr_log2 (mpfr_t @var{rop}, unsigned char @var{rnd})
+Set @var{rop} to the logarithm of 2 rounded to the direction @var{rnd}
+with the precision of @var{rop}. This function stores the computed
+value to avoid another calculation if a lower or equal precision is
+requested.
+@end deftypefun
+
+@deftypefun void mpfr_pi (mpfr_t @var{rop}, unsigned char @var{rnd})
+Set @var{rop} to the value of Pi rounded to the direction @var{rnd}
+with the precision of @var{rop}. This function uses the Borwein, Borwein,
+Plouffe formula which directly gives the expansion of Pi in base 16.
+@end deftypefun
+
+@node I/O of Floats, Miscellaneous Float Functions, Float Comparison, Floating-point Functions
+@comment node-name, next, previous, up
+@section Input and Output Functions
+@cindex Float input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+
+Functions that perform input from a stdio stream, and functions that output to
+a stdio stream. Passing a NULL pointer for a @var{stream} argument to any of
+these functions will make them read from @code{stdin} and write to
+@code{stdout}, respectively.
+
+When using any of these functions, it is a good idea to include @file{stdio.h}
+before @file{mpfr.h}, since that will allow @file{mpfr.h} to define prototypes
+for these functions.
+
+@deftypefun size_t mpfr_out_str (FILE *@var{stream}, int @var{base}, size_t @var{n_digits}, mpfr_t @var{op}, char @var{rnd})
+Output @var{op} on stdio stream @var{stream}, as a string of digits in
+base @var{base}, rounded to direction @var{rnd}.
+The base may vary from 2 to 36. Print at most
+@var{n_digits} significant digits, or if @var{n_digits} is 0, the maximum
+number of digits accurately representable by @var{op}.
+
+In addition to the significant digits, a decimal point at the right of the
+first digit and a
+trailing exponent, in the form @samp{eNNN}, are printed. If @var{base}
+is greater than 10, @samp{@@} will be used instead of @samp{e} as
+exponent delimiter.
+
+Return the number of bytes written, or if an error occurred, return 0.
+@end deftypefun
+
+@c @deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base})
+@c Input a string in base @var{base} from stdio stream @var{stream}, and put the
+@c read float in @var{rop}. The string is of the form @samp{M@@N} or, if the
+@c base is 10 or less, alternatively @samp{MeN}. @samp{M} is the mantissa and
+@c @samp{N} is the exponent. The mantissa is always in the specified base. The
+@c exponent is either in the specified base or, if @var{base} is negative, in
+@c decimal.
+
+@c The argument @var{base} may be in the ranges 2 to 36, or @minus{}36 to
+@c @minus{}2. Negative values are used to specify that the exponent is in
+@c decimal.
+
+@c Unlike the corresponding @code{mpz} function, the base will not be determined
+@c from the leading characters of the string if @var{base} is 0. This is so that
+@c numbers like @samp{0.23} are not interpreted as octal.
+
+@c Return the number of bytes read, or if an error occurred, return 0.
+@c @end deftypefun
+
+@deftypefun void mpfr_print_raw (mpfr_t @var{float})
+Output @var{float} on stdout (should be changed to allow any io stream),
+in raw binary format (the exponent is in decimal, yet).
+The last bits from the least significant limb which do not belong to
+the mantissa are printed between square brackets;
+they should always be zero.
+@end deftypefun
+
+@c @deftypefun void mpfr_inp_raw (mpfr_t @var{float}, FILE *@var{stream})
+@c Input from stdio stream @var{stream} in the format written by
+@c @code{mpfr_out_raw}, and put the result in @var{float}.
+@c @end deftypefun
+
+
+@node Miscellaneous Float Functions, , I/O of Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Miscellaneous Functions
+@cindex Miscellaneous float functions
+
+@deftypefun void mpfr_random (mpfr_t @var{rop})
+Put in @var{rop} a random float in the interval [0,1[.
+Random limbs are generated using the
+@code{random} system function.
+zeros and ones in the binary representation. The exponent of the number is in
+the interval @minus{}@var{exp} to @var{exp}. This function is useful for
+testing functions and algorithms, since this kind of random numbers have
+proven to be more likely to trigger corner-case bugs. Negative random numbers
+are generated when @var{max_size} is negative.
+@end deftypefun
+
+@deftypefun void mpfr_srandom (unsigned long @var{seed})
+Set the random seed used by @code{mpfr_random} to @var{seed}.
+@end deftypefun
+
+@c @deftypefun size_t mpfr_size (mpfr_t @var{op})
+@c Return the size of @var{op} measured in number of limbs. If @var{op} is
+@c zero, the returned value will be zero. (@xref{Nomenclature}, for an
+@c explanation of the concept @dfn{limb}.)
+@c
+@c @strong{This function is obsolete. It will disappear from future MP
+@c releases.}
+@c @end deftypefun
+
+@section Internal Functions
+
+These functions were mainly designed for the implementation of @code{mpfr},
+but may be useful for users too.
+
+@deftypefun Macro int FLAG_NAN (mpfr_t x)
+Returns a non-zero value iff its argument is @samp{Not a Number}.
+@end deftypefun
+
+@deftypefun Macro int SET_NAN (mpfr_t x)
+Sets its argument to @samp{Not a Number}.
+@end deftypefun
+
+@deftypefun Macro int ABSSIZE (mpfr_t x)
+Returns the number of limb the mantissa of @var{x} points to.
+@end deftypefun
+
+@deftypefun Macro int EXP (mpfr_t x)
+Returns the exponent of @var{x}.
+@end deftypefun
+
+@deftypefun Macro mp_limb_t* MANT (mpfr_t x)
+Returns a pointer to the mantissa of @var{x}.
+@end deftypefun
+
+@deftypefun Macro unsigned int PREC (mpfr_t x)
+Returns the precision of @var{x}.
+@end deftypefun
+
+@deftypefun Macro int CHANGE_SIGN (mpfr_t x)
+Changes the sign of @var{x}.
+@end deftypefun
+
+@deftypefun int mpfr_add_one_ulp (mpfr_t @var{x})
+Add one unit in last place (ulp) to the mantissa of @var{x}
+if it is positive or zero, and subtracts one ulp otherwise.
+Always return 0 (result is exact).
+@end deftypefun
+
+@deftypefun int mpfr_sub_one_ulp (mpfr_t @var{x})
+Subtract one ulp to @var{x} if it is positive or zero,
+and adds one ulp otherwise.
+Always return 0 (result is exact).
+@end deftypefun
+
+@deftypefun int mpfr_cmp2 (mpfr_t @var{a}, mpfr_t @var{b})
+Assuming @var{a} is greater or equal to @var{b}, returns the number of
+cancelled bits when one subtracts @var{b} from @var{a}.
+Returns the precision of @var{a} when both operands are equal.
+Mainly used in @code{mpfr_sub}.
+@end deftypefun
+
+@deftypefun int mpfr_round_raw (mp_limb_t* @var{y}, mp_limb_t* @var{x}, long @var{xprec}, char @var{neg}, long @var{yprec}, char @var{rnd})
+Puts in mantissa beginning at @var{y} the value of that
+beginning at @var{x} (with precision @var{xprec} bits and negative iff
+@var{neg} is not zero)
+rounded with mode @var{rnd} to precision @var{yprec}.
+@end deftypefun
+
+@deftypefun int mpfr_round_raw2 (mp_limb_t* @var{x}, long @var{xn}, char @var{neg}, char @var{rnd}, unsigned long @var{prec})
+Returns 0 if the multiple precision number stored in the @var{xn} limbs
+starting at @var{xp} (least significant limbs first) with sign @var{neg}
+(positive iff @var{neg} equals zero)
+is rounded similarly with direction @var{rnd} and precision @var{prec}
+than towards zero, and 1 otherwise.
+In other words, the bit returned is what has to be added to bit @var{prec}
+to round to mode @var{rnd}. This function @strong{does not modify} the
+mantissa stored in @var{xp}.
+@end deftypefun
+
+@deftypefun int mpfr_can_round (mpfr_t @var{b}, unsigned long @var{err}, char @var{rnd1}, char @var{rnd2}, unsigned long @var{prec})
+Assuming @var{b} is an approximation of an unknown number
+@var{x} in direction @var{rnd1} with error at most two to the power
+E(b)-@var{err} where E(b) is the exponent of
+@var{b}, returns 1 if one is able to round exactly @var{x} to precision
+@var{prec} with direction @var{rnd2},
+ and 0 otherwise. This function @strong{does not modify} its arguments.
+@end deftypefun
+
+@node Contributors, References, Custom Allocation, Top
+@comment node-name, next, previous, up
+@unnumbered Contributors
+
+We would like to thank Jean-Michel Muller and Joris van der Hoeven for very
+fruitful discussions at the beginning of that project, Torbjorn Granlund
+for his help about design issues
+and his suggestions for a easy integration into GNU MP.
+
+Sylvie Boldo from ENS-Lyon, France,
+contributed the function @code{mpfr_agm} during her stage in the PolKA team
+in June and July 1999.
+
+@node References, , Contributors, Top
+@comment node-name, next, previous, up
+@unnumbered References
+
+@itemize @bullet
+
+@item
+Torbjorn Granlund, "GNU MP: The GNU Multiple Precision Arithmetic Library",
+ version 2.0.2, 1996.
+
+@item
+IEEE standard for binary floating-point arithmetic, Technical Report
+ANSI-IEEE Standard 754-1985, New York, 1985.
+Approved March 21, 1985: IEEE Standards Board; approved July 26,
+ 1985: American National Standards Institute, 18 pages.
+
+@item
+Donald E. Knuth, "The Art of Computer Programming", vol 2,
+"Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+@end itemize
+
+@node Concept Index, , , Top
+@comment node-name, next, previous, up
+@unnumbered Concept Index
+@printindex cp
+
+@node Function Index, , , Top
+@comment node-name, next, previous, up
+@unnumbered Function and Type Index
+@printindex fn
+
+@contents
+@bye
diff --git a/mpfr/mul.c b/mpfr/mul.c
new file mode 100644
index 000000000..c7c3cd3f5
--- /dev/null
+++ b/mpfr/mul.c
@@ -0,0 +1,78 @@
+/* mpfr_mul -- multiply two floating-point numbers
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+/* Remains to do:
+- do not use all bits of b and c when PREC(b)>PREC(a) or PREC(c)>PREC(a)
+ [current complexity is O(PREC(b)*PREC(c))]
+*/
+
+void
+#if __STDC__
+mpfr_mul(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, unsigned char rnd_mode)
+#else
+mpfr_mul(a, b, c, rnd_mode)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+ unsigned char rnd_mode;
+#endif
+{
+ unsigned int bn, cn, an, tn, k; int cc;
+ mp_limb_t *ap=MANT(a), *bp=MANT(b), *cp=MANT(c), *tmp, b1;
+ long int sign_product;
+ TMP_DECL(marker);
+
+ /* deal with NaN and zero */
+ if (FLAG_NAN(b) || FLAG_NAN(c)) { SET_NAN(a); return; }
+ if (!NOTZERO(b) || !NOTZERO(c)) { SET_ZERO(a); return; }
+
+ sign_product = SIGN(b) * SIGN(c);
+ bn = (PREC(b)-1)/mp_bits_per_limb+1; /* number of significant limbs of b */
+ cn = (PREC(c)-1)/mp_bits_per_limb+1; /* number of significant limbs of c */
+ tn = (PREC(c)+PREC(b)-1)/mp_bits_per_limb+1;
+ k = bn+cn; /* effective nb of limbs used by b*c */
+ TMP_MARK(marker);
+ tmp = (mp_limb_t*) TMP_ALLOC(k*BYTES_PER_MP_LIMB);
+
+ /* multiplies two mantissa in temporary allocated space */
+ b1 = (bn>=cn) ? mpn_mul(tmp, bp, bn, cp, cn) : mpn_mul(tmp, cp, cn, bp, bn);
+
+ /* now tmp[0]..tmp[k-1] contains the product of both mantissa,
+ with tmp[k-1]>=2^(mp_bits_per_limb-2) */
+ an = (PREC(a)-1)/mp_bits_per_limb+1; /* number of significant limbs of a */
+ b1 >>= mp_bits_per_limb-1; /* msb from the product */
+
+ if (b1==0) mpn_lshift(tmp, tmp, k, 1);
+ cc = mpfr_round_raw(ap, tmp+bn+cn-tn,
+ PREC(b)+PREC(c), (sign_product<0), PREC(a), rnd_mode);
+ if (cc) { /* cc = 1 ==> result is a power of two */
+ ap[an-1] = (mp_limb_t) 1 << (BITS_PER_MP_LIMB-1);
+ }
+ EXP(a) = EXP(b) + EXP(c) + b1 - 1 + cc;
+ if (sign_product * SIGN(a)<0) CHANGE_SIGN(a);
+ TMP_FREE(marker);
+ return;
+}
diff --git a/mpfr/mul_2exp.c b/mpfr/mul_2exp.c
new file mode 100644
index 000000000..31dab2ac6
--- /dev/null
+++ b/mpfr/mul_2exp.c
@@ -0,0 +1,43 @@
+/* mpfr_mul_2exp -- multiply a floating-point number by a power of two
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_mul_2exp(mpfr_ptr y, mpfr_srcptr x, unsigned long int n, unsigned char rnd_mode)
+#else
+mpfr_mul_2exp(y, x, n, rnd_mode)
+ mpfr_ptr y;
+ mpfr_srcptr x;
+ unsigned long int n;
+ unsigned char rnd_mode;
+#endif
+{
+ /* Important particular case */
+ if (y != x) mpfr_set(y, x, rnd_mode);
+ EXP(y) += n;
+ return;
+}
+
diff --git a/mpfr/mul_ui.c b/mpfr/mul_ui.c
new file mode 100644
index 000000000..db4c39a90
--- /dev/null
+++ b/mpfr/mul_ui.c
@@ -0,0 +1,84 @@
+/* mpfr_mul_ui -- multiply a floating-point number by a machine integer
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+void
+#if __STDC__
+mpfr_mul_ui(mpfr_ptr y, mpfr_srcptr x, unsigned long u, unsigned char RND_MODE)
+#else
+mpfr_mul_ui()
+ mpfr_ptr y;
+ mpfr_srcptr x;
+ unsigned long u;
+ unsigned char RND_MODE;
+#endif
+{
+ mp_limb_t carry, *my, *old_my; unsigned long c;
+ unsigned long xsize, ysize, cnt, dif;
+ TMP_DECL(marker);
+
+ TMP_MARK(marker);
+ my = MANT(y);
+ ysize = (PREC(y)-1)/BITS_PER_MP_LIMB + 1;
+ xsize = (PREC(x)-1)/BITS_PER_MP_LIMB + 1;
+
+ if (ysize < xsize) {
+ old_my = my;
+ my = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB);
+ dif=0;
+ }
+ else dif=ysize-xsize;
+
+ carry = mpn_mul_1(my+dif, MANT(x), xsize, u);
+ MPN_ZERO(my, dif);
+
+ /* WARNING: count_leading_zeros is undefined for carry=0 */
+ if (carry) count_leading_zeros(cnt, carry);
+ else cnt=BITS_PER_MP_LIMB;
+
+ c = mpfr_round_raw(my, my, PREC(x), (SIGN(x)<0),
+ PREC(y)-BITS_PER_MP_LIMB+cnt, RND_MODE);
+
+ /* If cnt = 1111111111111 and c = 1 we shall get depressed */
+ if (c && (carry == (((mp_limb_t)1) << (BITS_PER_MP_LIMB - cnt)) - 1))
+ {
+ cnt--;
+ mpn_rshift(my, my, ysize, BITS_PER_MP_LIMB - cnt);
+ my[ysize - 1] |= ((mp_limb_t) 1) << (BITS_PER_MP_LIMB - 1);
+ }
+ else
+ {
+ /* Warning: mpn_rshift is undefined for shift=0 */
+ if (cnt!=BITS_PER_MP_LIMB)
+ mpn_rshift(my, my, ysize, BITS_PER_MP_LIMB - cnt);
+ my[ysize - 1] |= (carry << cnt);
+ }
+ EXP(y) = EXP(x) + BITS_PER_MP_LIMB - cnt;
+ if (ysize < xsize) MPN_COPY(old_my, my, ysize);
+ /* set sign */
+ if (SIGN(y) != SIGN(x)) CHANGE_SIGN(y);
+ TMP_FREE(marker);
+}
diff --git a/mpfr/neg.c b/mpfr/neg.c
new file mode 100644
index 000000000..fff73a65a
--- /dev/null
+++ b/mpfr/neg.c
@@ -0,0 +1,40 @@
+/* mpfr_neg -- change the sign of a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_neg(mpfr_ptr a, mpfr_srcptr b, unsigned char rnd_mode)
+#else
+mpfr_neg(a, b, rnd_mode)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ unsigned char rnd_mode;
+#endif
+{
+ if (a != b) mpfr_set4(a, b, rnd_mode, -SIGN(b));
+ else CHANGE_SIGN(a);
+ return;
+}
diff --git a/mpfr/out_str.c b/mpfr/out_str.c
new file mode 100644
index 000000000..aeaf64bd2
--- /dev/null
+++ b/mpfr/out_str.c
@@ -0,0 +1,65 @@
+/* mpfr_out_str -- output a floating-point number to a stream
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+size_t
+#if __STDC__
+mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
+ unsigned char rnd_mode)
+#else
+mpfr_out_str (stream, base, n_digits, op, rnd_mode)
+ FILE *stream;
+ int base;
+ size_t n_digits;
+ mpfr_srcptr op;
+ unsigned char rnd_mode;
+#endif
+{
+ char *s,*s0; size_t l; mp_exp_t e;
+
+ if (FLAG_NAN(op)) { fprintf(stream, "NaN"); return 3; }
+ if (!NOTZERO(op)) { fprintf(stream, "0"); return 1; }
+
+ s = mpfr_get_str(NULL, &e, base, n_digits, op, rnd_mode);
+ s0 = s;
+ /* for op=3.1416 we have s = "31416" and e = 1 */
+
+ l = strlen(s)+1;
+ if (*s == '-') fputc(*s++, stream);
+
+ fputc(*s++, stream); e--; /* writes leading digit */
+ fputc('.', stream); /* decimal point */
+ fputs(s, stream); /* rest of mantissa */
+ if (e) {
+ fputc((base>10) ? '@' : 'e', stream); l++;
+ sprintf(s, "%ld", e);
+ l += strlen(s);
+ fprintf(stream, "%s", s);
+ }
+
+ (*_mp_free_func)(s0, l);
+ return l;
+}
diff --git a/mpfr/pi.c b/mpfr/pi.c
new file mode 100644
index 000000000..322a2ab1c
--- /dev/null
+++ b/mpfr/pi.c
@@ -0,0 +1,131 @@
+/* mpfr_pi -- compute Pi
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+/*
+Set x to the value of Pi to precision PREC(x) rounded to direction rnd_mode.
+Use the formula giving the binary representation of Pi found by Simon Plouffe
+and the Borwein's brothers:
+
+ infinity 4 2 1 1
+ ----- ------- - ------- - ------- - -------
+ \ 8 n + 1 8 n + 4 8 n + 5 8 n + 6
+ Pi = ) -------------------------------------
+ / n
+ ----- 16
+ n = 0
+
+i.e. Pi*16^N = S(N) + R(N) where
+S(N) = sum(16^(N-n)*(4/(8*n+1)-2/(8*n+4)-1/(8*n+5)-1/(8*n+6)), n=0..N-1)
+R(N) = sum((4/(8*n+1)-2/(8*n+4)-1/(8*n+5)-1/(8*n+6))/16^(n-N), n=N..infinity)
+
+Let f(n) = 4/(8*n+1)-2/(8*n+4)-1/(8*n+5)-1/(8*n+6), we can show easily that
+f(n) < 15/(64*n^2), so R(N) < sum(15/(64*n^2)/16^(n-N), n=N..infinity)
+ < 15/64/N^2*sum(1/16^(n-N), n=N..infinity)
+ = 1/4/N^2
+
+Now let S'(N) = sum(floor(16^(N-n)*(120*n^2+151*n+47),
+ (512*n^4+1024*n^3+712*n^2+194*n+15)), n=0..N-1)
+
+S(N)-S'(N) <= sum(1, n=0..N-1) = N
+
+so Pi*16^N-S'(N) <= N+1 (as 1/4/N^2 < 1)
+*/
+
+mpfr_t __mpfr_pi; /* stored value of Pi */
+int __mpfr_pi_prec=0; /* precision of stored value */
+char __mpfr_pi_rnd; /* rounding mode of stored value */
+
+void
+#if __STDC__
+mpfr_pi(mpfr_ptr x, unsigned char rnd_mode)
+#else
+mpfr_pi(x, rnd_mode)
+ mpfr_ptr x;
+ unsigned char rnd_mode;
+#endif
+{
+ int N, oldN, n, prec; mpz_t pi, num, den, d3, d2, tmp; mpfr_t y;
+
+ prec=PREC(x);
+
+ /* has stored value enough precision ? */
+ if ((prec==__mpfr_pi_prec && rnd_mode==__mpfr_pi_rnd) ||
+ (prec<=__mpfr_pi_prec &&
+ mpfr_can_round(__mpfr_pi, __mpfr_pi_prec, __mpfr_pi_rnd, rnd_mode, prec)))
+ {
+ mpfr_set(x, __mpfr_pi, rnd_mode); return;
+ }
+
+ /* need to recompute */
+ N=1;
+ do {
+ oldN = N;
+ N = (prec+3)/4 + (int)ceil(log((double)N+1.0)/log(2.0));
+ } while (N != oldN);
+ mpz_init(pi); mpz_init(num); mpz_init(den); mpz_init(d3); mpz_init(d2);
+ mpz_init(tmp);
+ mpz_set_ui(pi, 0);
+ mpz_set_ui(num, 16); /* num(-1) */
+ mpz_set_ui(den, 21); /* den(-1) */
+ mpz_set_si(d3, -2454);
+ mpz_set_ui(d2, 14736);
+ /* invariants: num=120*n^2+151*n+47, den=512*n^4+1024*n^3+712*n^2+194*n+15
+ d3 = 2048*n^3+400*n-6, d2 = 6144*n^2-6144*n+2448
+ */
+ for (n=0; n<N; n++) {
+ /* num(n)-num(n-1) = 240*n+31 */
+ mpz_add_ui(num, num, 240*n+31); /* no overflow up to PREC=71M */
+ /* d2(n) - d2(n-1) = 12288*(n-1) */
+ if (n>0) mpz_add_ui(d2, d2, 12288*(n-1));
+ else mpz_sub_ui(d2, d2, 12288);
+ /* d3(n) - d3(n-1) = d2 */
+ mpz_add(d3, d3, d2);
+ /* den(n)-den(n-1) = 2048*n^3 + 400n - 6 = d3 */
+ mpz_add(den, den, d3);
+ mpz_mul_2exp(tmp, num, 4*(N-n));
+ mpz_fdiv_q(tmp, tmp, den);
+ mpz_add(pi, pi, tmp);
+ }
+ mpfr_set_z(x, pi, rnd_mode);
+ mpfr_init2(y, mpfr_get_prec(x));
+ mpz_add_ui(pi, pi, N+1);
+ mpfr_set_z(y, pi, rnd_mode);
+ if (mpfr_cmp(x, y) != 0) {
+ fprintf(stderr, "does not converge\n"); exit(1);
+ }
+ EXP(x) -= 4*N;
+ mpz_clear(pi); mpz_clear(num); mpz_clear(den); mpz_clear(d3); mpz_clear(d2);
+ mpz_clear(tmp); mpfr_clear(y);
+
+ /* store computed value */
+ if (__mpfr_pi_prec==0) mpfr_init2(__mpfr_pi, prec);
+ else mpfr_set_prec(__mpfr_pi, prec);
+ mpfr_set(__mpfr_pi, x, rnd_mode);
+ __mpfr_pi_prec=prec;
+ __mpfr_pi_rnd=rnd_mode;
+}
diff --git a/mpfr/pow.c b/mpfr/pow.c
new file mode 100644
index 000000000..c53819ec2
--- /dev/null
+++ b/mpfr/pow.c
@@ -0,0 +1,67 @@
+/* mpfr_pow_ui, mpfr_ui_pow_ui -- compute the power of a floating-point
+ number or machine integer
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+/* sets x to y^n */
+void
+#if __STDC__
+mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned int n, unsigned char rnd)
+#else
+mpfr_pow_ui (x, y, n, rnd)
+ mpfr_ptr x;
+ mpfr_srcptr y;
+ unsigned int n;
+ unsigned char rnd;
+#endif
+{
+ int i;
+
+ if (n==0) { mpfr_set_ui(x, 1, rnd); return; }
+ mpfr_set(x, y, rnd);
+ for (i=0;(1<<i)<=n;i++);
+ /* now 2^(i-1) <= n < 2^i */
+ for (i-=2; i>=0; i--) {
+ mpfr_mul(x, x, x, rnd);
+ if (n & (1<<i)) mpfr_mul(x, x, y, rnd);
+ }
+ return;
+}
+
+/* sets x to y^n */
+void mpfr_ui_pow_ui (mpfr_ptr x, unsigned int y, unsigned int n,
+ unsigned char rnd)
+{
+ int i;
+
+ if (n==0) { mpfr_set_ui(x, 1, rnd); return; }
+ mpfr_set_ui(x, y, rnd);
+ for (i=0;(1<<i)<=n;i++);
+ /* now 2^(i-1) <= n < 2^i */
+ for (i-=2; i>=0; i--) {
+ mpfr_mul(x, x, x, rnd);
+ if (n & (1<<i)) mpfr_mul_ui(x, x, y, rnd);
+ }
+ return;
+}
diff --git a/mpfr/print_raw.c b/mpfr/print_raw.c
new file mode 100644
index 000000000..4ff68bcaf
--- /dev/null
+++ b/mpfr/print_raw.c
@@ -0,0 +1,91 @@
+/* mpfr_print_raw -- print the internal binary representation of a
+ floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_get_str_raw(char *digit_ptr, mpfr_srcptr x)
+#else
+mpfr_get_str_raw(digit_ptr, x)
+ char *digit_ptr;
+ mpfr_srcptr x;
+#endif
+{
+ mp_limb_t *mx, wd, t; long ex, sx, k, l, p;
+
+ mx = MANT(x);
+ ex = EXP(x);
+ p = PREC(x);
+
+ if (SIGN(x) < 0) { *digit_ptr = '-'; digit_ptr++; }
+ sprintf(digit_ptr, "0."); digit_ptr += 2;
+
+ sx = 1+(p-1)/mp_bits_per_limb; /* number of significant limbs */
+ for (k = sx - 1; k >= 0 ; k--)
+ {
+ wd = mx[k];
+ t = ((mp_limb_t)1) << (BITS_PER_MP_LIMB - 1);
+ for (l = BITS_PER_MP_LIMB - 1; l>=0; l--)
+ {
+ if (wd & t)
+ { *digit_ptr = '1'; digit_ptr++; }
+ else
+ { *digit_ptr = '0'; digit_ptr++; }
+ t >>= 1;
+ if (--p==0) { *digit_ptr = '['; digit_ptr++; }
+ }
+ }
+ sprintf(digit_ptr, "]E%ld", ex);
+}
+
+void
+#if __STDC__
+mpfr_print_raw(mpfr_srcptr x)
+#else
+mpfr_print_raw(x)
+ mpfr_srcptr x;
+#endif
+{
+ char *str;
+
+ if (FLAG_NAN(x)) printf("NaN");
+ else if (!NOTZERO(x)) printf("0");
+ else {
+ /* 3 char for sign + 0 + binary point
+ + ABSSIZE(x) * BITS_PER_MP_LIMB for mantissa
+ + 2 for brackets in mantissa
+ + 1 for 'E'
+ + 11 for exponent (including sign)
+ = 17 + ABSSIZE(x) * BITS_PER_MP_LIMB
+ */
+ str = (char *) malloc((17 + ABSSIZE(x) * BITS_PER_MP_LIMB)*sizeof(char));
+ mpfr_get_str_raw(str, x);
+
+ printf("%s", str);
+ free(str);
+ }
+}
+
diff --git a/mpfr/print_rnd_mode.c b/mpfr/print_rnd_mode.c
new file mode 100644
index 000000000..a7bc1d06d
--- /dev/null
+++ b/mpfr/print_rnd_mode.c
@@ -0,0 +1,43 @@
+/* mpfr_print_rnd_mode -- convert a given rounding mode to a string
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+char *
+#if __STDC__
+mpfr_print_rnd_mode(unsigned char rnd_mode)
+#else
+mpfr_print_rnd_mode(rnd_mode)
+ unsigned char rnd_mode;
+#endif
+{
+ switch (rnd_mode)
+ {
+ case GMP_RNDD: return("GMP_RNDD");
+ case GMP_RNDU: return("GMP_RNDU");
+ case GMP_RNDN: return("GMP_RNDN");
+ case GMP_RNDZ: return("GMP_RNDZ");
+ default: return("unknown rounding mode");
+ }
+}
diff --git a/mpfr/random.c b/mpfr/random.c
new file mode 100644
index 000000000..e61ddc0b7
--- /dev/null
+++ b/mpfr/random.c
@@ -0,0 +1,74 @@
+/* mpfr_random -- generate a random floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+/* Computes a random mpfr in [0, 1[ with precision PREC */
+
+extern long random _PROTO((void));
+extern int srandom _PROTO((unsigned int));
+
+/* extracted from GNU mpf */
+#if defined (__hpux) || defined (__alpha)
+/* HPUX lacks random(). DEC OSF/1 1.2 random() returns a double. */
+#define random mrand48
+#define srandom srand48
+#endif
+
+void
+#if __STDC__
+mpfr_random(mpfr_ptr x)
+#else
+mpfr_random(x)
+ mpfr_ptr x;
+#endif
+{
+ mp_limb_t *xp; unsigned long xn, i, cnt, prec=PREC(x);
+
+ xp = MANT(x);
+ xn = (prec-1)/BITS_PER_MP_LIMB + 1;
+
+ for (i = 0; i < xn; i++)
+ {
+ /* random() c/sh/ould be replaced by a homemade random number generator.
+ Indeed, if on Linux random is a good RNG, this is definitely not
+ the case in most Un*xes. */
+ xp[i] = random();
+ }
+
+ count_leading_zeros(cnt, xp[xn - 1]);
+ if (cnt) mpn_lshift(xp, xp, xn, cnt);
+ EXP(x) = -cnt;
+
+ cnt = xn*BITS_PER_MP_LIMB - prec;
+ /* cnt is the number of non significant bits in the low limb */
+ xp[0] &= ~((((mp_limb_t)1)<<cnt) - 1);
+}
+
+void
+mpfr_srandom(unsigned long seed)
+{
+ srandom(seed);
+}
diff --git a/mpfr/rnd_mode.c b/mpfr/rnd_mode.c
new file mode 100644
index 000000000..9c37fb4c1
--- /dev/null
+++ b/mpfr/rnd_mode.c
@@ -0,0 +1,118 @@
+/* mpfr_set_machine_rnd_mode -- set the rounding mode for machine floats
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+/* functions to set/get the machine rounding mode */
+#ifdef _ISOC9X_SOURCE
+#include <fenv.h>
+#define TONEAREST fesetround(FE_TONEAREST)
+#define TOZERO fesetround(FE_TOWARDZERO)
+#define TOINFP fesetround(FE_UPWARD)
+#define TOINFM fesetround(FE_DOWNWARD)
+#elif IRIX64
+#include <sys/fpu.h>
+extern int swapRM();
+#define TOZERO swapRM(ROUND_TO_ZERO)
+#define TOINFP swapRM(ROUND_TO_PLUS_INFINITY)
+#define TONEAREST swapRM(ROUND_TO_NEAREST)
+#define TOINFM swapRM(ROUND_TO_MINUS_INFINITY)
+#elif (defined (solaris) || defined (sun4) || defined(hpux))
+#ifdef hpux
+#include <math.h>
+#else
+#include <ieeefp.h>
+#endif
+#define TOZERO fpsetround(FP_RZ)
+#define TOINFP fpsetround(FP_RP)
+#define TONEAREST fpsetround(FP_RN)
+#define TOINFM fpsetround(FP_RM)
+#elif alpha
+#ifdef __GNUC__
+/* GCC patched include files forget to define those... */
+#define FP_RND_RZ 0
+#define FP_RND_RN 1
+#define FP_RND_RP 2
+#define FP_RND_RM 3
+#endif
+#include <float.h>
+#define TOZERO write_rnd(FP_RND_RZ)
+#define TOINFP write_rnd(FP_RND_RP)
+#define TONEAREST write_rnd(FP_RND_RN)
+#define TOINFM write_rnd(FP_RND_RM)
+#elif AIX
+#include <float.h>
+#define TOZERO fp_swap_rnd(FP_RND_RZ)
+#define TOINFP fp_swap_rnd(FP_RND_RP)
+#define TONEAREST fp_swap_rnd(FP_RND_RN)
+#define TOINFM fp_swap_rnd(FP_RND_RM)
+#elif sunos
+#include <floatingpoint.h>
+char *out;
+#define TOZERO ieee_flags("set","direction","tozero",&out)
+#define TOINFP ieee_flags("set","direction","positive",&out)
+#define TONEAREST ieee_flags("set","direction","nearest",&out)
+#define TOINFM ieee_flags("set","direction","negative",&out)
+#elif (defined (__i386__) || defined (__i486__) || defined (linux))
+#ifdef __CYGWIN32__ /* no fpu_control.h under Cygnus */
+#define _FPU_EXTENDED 0x300
+#define _FPU_DOUBLE 0x200
+#define _FPU_DEFAULT 0x137f
+#define _FPU_RC_NEAREST 0x0
+#define _FPU_RC_DOWN 0x400
+#define _FPU_RC_UP 0x800
+#define _FPU_RC_ZERO 0xC00
+#else
+#include <fpu_control.h>
+#endif
+#if defined(LIBC211) || defined(__CYGWIN32__)
+#define __setfpucw(cw) __asm__ ("fldcw %0" : : "m" (cw))
+#endif
+/* be careful to put Precision control bits
+ to round to double precision instead of the
+ default (round to extended precision) */
+#define _fpu_ieee ((_FPU_DEFAULT & (~_FPU_EXTENDED)) | _FPU_DOUBLE)
+#define TOZERO __setfpucw(_fpu_ieee | _FPU_RC_ZERO)
+#define TOINFP __setfpucw(_fpu_ieee | _FPU_RC_UP)
+#define TOINFM __setfpucw(_fpu_ieee | _FPU_RC_DOWN)
+#define TONEAREST __setfpucw(_fpu_ieee)
+#endif
+
+/* sets the machine rounding mode to the value rnd_mode */
+void
+#if __STDC__
+mpfr_set_machine_rnd_mode(unsigned char rnd_mode)
+#else
+mpfr_set_machine_rnd_mode(rnd_mode)
+ unsigned char rnd_mode;
+#endif
+{
+ switch (rnd_mode) {
+ case GMP_RNDN: TONEAREST; break;
+ case GMP_RNDZ: TOZERO; break;
+ case GMP_RNDU: TOINFP; break;
+ case GMP_RNDD: TOINFM; break;
+ default: fprintf(stderr,"invalid rounding mode\n"); exit(1);
+ }
+}
+
diff --git a/mpfr/round.c b/mpfr/round.c
new file mode 100644
index 000000000..9fad4c47e
--- /dev/null
+++ b/mpfr/round.c
@@ -0,0 +1,338 @@
+/* mpfr_round_raw2, mpfr_round_raw, mpfr_round, mpfr_can_round,
+ mpfr_can_round_raw -- various rounding functions
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+#ifdef Exp
+#include "longlong.h"
+#endif
+
+/* returns 0 if round(sign*xp[0..xn-1], prec, rnd) =
+ round(sign*xp[0..xn-1], prec, GMP_RNDZ), 1 otherwise,
+ where sign=1 if neg=0, sign=-1 otherwise.
+
+ Does *not* modify anything.
+*/
+int
+#if __STDC__
+mpfr_round_raw2(mp_limb_t *xp, unsigned long xn,
+ char neg, char rnd, unsigned long prec)
+#else
+mpfr_round_raw2(xp, xn, neg, rnd, prec)
+ mp_limb_t *xp;
+ unsigned long xn;
+ char neg;
+ char rnd;
+ unsigned long prec;
+#endif
+{
+ unsigned long nw; long wd; char rw; short l; mp_limb_t mask;
+
+ nw = prec / BITS_PER_MP_LIMB; rw = prec & (BITS_PER_MP_LIMB - 1);
+ if (rw) nw++;
+ if (rnd==GMP_RNDZ || xn<nw || (rnd==GMP_RNDU && neg)
+ || (rnd==GMP_RNDD && neg==0)) return 0;
+
+ mask = ~((((mp_limb_t)1)<<(BITS_PER_MP_LIMB - rw)) - 1);
+ switch (rnd)
+ {
+ case GMP_RNDU:
+ case GMP_RNDD:
+ if (xp[xn - nw] & ~mask) return 1;
+ for (l = nw + 1;l <= xn; l++)
+ if (xp[xn - l]) break;
+ return (l <= xn);
+
+ case GMP_RNDN:
+ /* First check if we are just halfway between two representable numbers */
+ wd = xn - nw;
+ if (!rw)
+ {
+ if (!wd) /* all bits are significative */ return 0;
+ wd--;
+ if (xp[wd] == ((mp_limb_t)1 << (BITS_PER_MP_LIMB - 1)))
+ {
+ do wd--; while (wd > 0 && !xp[wd]);
+ if (!wd) { return 1; } else return xp[xn - nw] & 1;
+ }
+
+ return xp[wd]>>(BITS_PER_MP_LIMB - 1);
+ }
+ else
+ if (rw + 1 < BITS_PER_MP_LIMB)
+ {
+ if ((xp[wd] & (~mask)) == (((mp_limb_t)1) << (BITS_PER_MP_LIMB - rw - 1)))
+ do { wd--; } while (wd >= 0 && !xp[wd]);
+ else return ((xp[wd]>>(BITS_PER_MP_LIMB - rw - 1)) & 1);
+
+ /* first limb was in the middle, and others down to wd+1 were 0 */
+ if (wd>=0) return 1;
+ else
+ return ((xp[xn - nw] & mask) >> (BITS_PER_MP_LIMB - rw)) & 1;
+ }
+ else
+ /* Modified PZ, 27 May 1999:
+ rw, i.e. the number of bits stored in xp[xn-nw], is
+ BITS_PER_MP_LIMB-1, i.e. there is exactly one non significant bit.
+ We are just halfway iff xp[wd] has its low significant bit
+ set and all limbs xp[0]...xp[wd-1] are zero */
+ {
+ if (xp[wd] & 1)
+ do wd--; while (wd >= 0 && !xp[wd]);
+ return ((wd<0) ? xp[xn-nw]>>1 : xp[xn-nw]) & 1;
+ }
+ default: return 0;
+ }
+}
+
+/* puts in y the value of xp (with precision xprec and sign 1 if negative=0,
+ -1 otherwise) rounded to precision yprec and direction RND_MODE
+ Supposes x is not zero nor NaN nor +/- Infinity (i.e. *xp != 0).
+*/
+int
+#if __STDC__
+mpfr_round_raw(mp_limb_t *y, mp_limb_t *xp, unsigned long xprec, char negative,
+ unsigned long yprec, char RND_MODE)
+#else
+mpfr_round_raw(y, xp, xprec, negative, yprec, RND_MODE)
+ mp_limb_t *y;
+ mp_limb_t *xp;
+ unsigned long xprec;
+ cher negative;
+ unsigned long yprec;
+ char RND_MODE;
+#endif
+{
+ unsigned long nw, xsize; mp_limb_t mask;
+ char rw, xrw, carry = 0;
+
+ xsize = (xprec-1)/BITS_PER_MP_LIMB + 1;
+ xrw = xprec % BITS_PER_MP_LIMB; if (xrw == 0) { xrw = BITS_PER_MP_LIMB; }
+
+#ifdef Exp
+ count_leading_zeros(flag, xp[xsize-1]);
+ yprec += flag;
+#endif
+
+ nw = yprec / BITS_PER_MP_LIMB; rw = yprec & (BITS_PER_MP_LIMB - 1);
+ if (rw) nw++;
+ /* number of words needed to represent x */
+
+ mask = ~((((mp_limb_t)1)<<(BITS_PER_MP_LIMB - rw)) - (mp_limb_t)1);
+
+ /* precision is larger than the size of x. No rounding is necessary.
+ Just add zeroes at the end */
+ if (xsize < nw) {
+ MPN_COPY(y + nw - xsize, xp, xsize);
+ MPN_ZERO(y, nw - xsize); /* PZ 27 May 99 */
+ y[0] &= mask;
+ return 0;
+ }
+
+ if (mpfr_round_raw2(xp, xsize, negative, RND_MODE, yprec))
+ carry = mpn_add_1(y, xp + xsize - nw, nw,
+ ((mp_limb_t)1) << (BITS_PER_MP_LIMB - rw));
+ else MPN_COPY(y, xp + xsize - nw, nw);
+
+ y[0] &= mask;
+ return carry;
+}
+
+void
+#if __STDC__
+mpfr_round(mpfr_t x, char RND_MODE, unsigned long prec)
+#else
+mpfr_round(x, RND_MODE, prec)
+ mpfr_t x;
+ char RND_MODE;
+ unsigned long prec;
+#endif
+{
+ mp_limb_t *tmp; int carry; unsigned long nw;
+ TMP_DECL(marker);
+
+ nw = prec / BITS_PER_MP_LIMB;
+ if (prec & (BITS_PER_MP_LIMB - 1)) nw++;
+ TMP_MARK(marker);
+ tmp = TMP_ALLOC (nw * BYTES_PER_MP_LIMB);
+ carry = mpfr_round_raw(tmp, MANT(x), PREC(x), (SIGN(x)<0), prec, RND_MODE);
+
+ if (carry)
+ {
+ mpn_rshift(tmp, tmp, nw, 1);
+ tmp [nw-1] |= (((mp_limb_t)1) << (BITS_PER_MP_LIMB - 1));
+ EXP(x)++;
+ }
+
+ if (SIGN(x)<0) { SIZE(x)=nw; CHANGE_SIGN(x); } else SIZE(x)=nw;
+ PREC(x) = prec;
+ MPN_COPY(MANT(x), tmp, nw);
+ TMP_FREE(marker);
+}
+
+/* hypotheses : BITS_PER_MP_LIMB est une puissance de 2
+ dans un test, la premiere partie du && est evaluee d'abord */
+
+
+/* assuming b is an approximation of x in direction rnd1
+ with error at most 2^(EXP(b)-err), returns 1 if one is
+ able to round exactly x to precision prec with direction rnd2,
+ and 0 otherwise.
+
+ Side effects: none.
+*/
+
+int
+#if __STDC__
+mpfr_can_round(mpfr_t b, unsigned long err, unsigned char rnd1,
+ unsigned char rnd2, unsigned long prec)
+#else
+mpfr_can_round(b, err, rnd1, rnd2, prec)
+ mpfr_t b;
+ unsigned long err;
+ unsigned char rnd1;
+ unsigned char rnd2;
+ unsigned long prec;
+#endif
+{
+ return mpfr_can_round_raw(MANT(b), (PREC(b) - 1)/BITS_PER_MP_LIMB + 1,
+ SIGN(b), err, rnd1, rnd2, prec);
+}
+
+int
+#if __STDC__
+mpfr_can_round_raw(mp_limb_t *bp, unsigned long bn, int neg,
+ unsigned long err, unsigned char rnd1, unsigned char rnd2,
+ unsigned long prec)
+#else
+mpfr_can_round_raw(bp, bn, neg, err, rnd1, rnd2, prec)
+ mp_limb_t *bp;
+ unsigned long bn;
+ int neg;
+ unsigned long err;
+ unsigned char rnd1;
+ unsigned char rnd2;
+ unsigned long prec;
+#endif
+{
+ int k, k1, l, l1, tn; mp_limb_t cc, cc2, *tmp;
+ TMP_DECL(marker);
+
+ if (err<=prec) return 0;
+ neg = (neg > 0 ? 0 : 1);
+
+ /* warning: if k = m*BITS_PER_MP_LIMB, consider limb m-1 and not m */
+ k = (err-1)/BITS_PER_MP_LIMB;
+ l = err % BITS_PER_MP_LIMB; if (l) l = BITS_PER_MP_LIMB-l;
+ /* the error corresponds to bit l in limb k */
+ k1 = (prec-1)/BITS_PER_MP_LIMB;
+ l1 = prec%BITS_PER_MP_LIMB; if (l1) l1 = BITS_PER_MP_LIMB-l1;
+
+ /* the last significant bit is bit l1 in limb k1 */
+
+ /* don't need to consider the k1 most significant limbs */
+ k -= k1; bn -= k1; prec -= k1*BITS_PER_MP_LIMB; k1=0;
+
+ if (rnd1==GMP_RNDU) { if (neg) rnd1=GMP_RNDZ; }
+ if (rnd1==GMP_RNDD) { if (neg) rnd1=GMP_RNDU; else rnd1=GMP_RNDZ; }
+
+ /* in the sequel, RNDU = towards infinity, RNDZ = towards zero */
+
+ TMP_MARK(marker);
+ tn = bn;
+ k++; /* since we work with k+1 everywhere */
+
+ switch (rnd1) {
+
+ case GMP_RNDZ: /* b <= x <= b+2^(EXP(b)-err) */
+ tmp = TMP_ALLOC(tn*BYTES_PER_MP_LIMB);
+ cc = (bp[bn-1]>>l1) & 1;
+ cc ^= mpfr_round_raw2(bp, bn, neg, rnd2, prec);
+
+ /* now round b+2^(EXP(b)-err) */
+ cc2 = mpn_add_1(tmp+bn-k, bp+bn-k, k, (mp_limb_t)1<<l);
+ /* if carry, then all bits up to err were to 1, and we can round only
+ if cc==0 and mpfr_round_raw2 returns 0 below */
+ if (cc2 && cc) { TMP_FREE(marker); return 0; }
+ cc2 = (tmp[bn-1]>>l1) & 1; /* gives 0 when carry */
+ cc2 ^= mpfr_round_raw2(tmp, bn, neg, rnd2, prec);
+
+ TMP_FREE(marker);
+ return (cc == cc2);
+
+ case GMP_RNDU: /* b-2^(EXP(b)-err) <= x <= b */
+ tmp = TMP_ALLOC(tn*BYTES_PER_MP_LIMB);
+ /* first round b */
+ cc = (bp[bn-1]>>l1) & 1;
+ cc ^= mpfr_round_raw2(bp, bn, neg, rnd2, prec);
+
+ /* now round b-2^(EXP(b)-err) */
+ cc2 = mpn_sub_1(tmp+bn-k, bp+bn-k, k, (mp_limb_t)1<<l);
+ /* if borrow, then all bits up to err were to 0, and we can round only
+ if cc==0 and mpfr_round_raw2 returns 1 below */
+ if (cc2 && cc) { TMP_FREE(marker); return 0; }
+ cc2 = (tmp[bn-1]>>l1) & 1; /* gives 1 when carry */
+ cc2 ^= mpfr_round_raw2(tmp, bn, neg, rnd2, prec);
+
+ TMP_FREE(marker);
+ return (cc == cc2);
+
+ case GMP_RNDN: /* b-2^(EXP(b)-err-1) <= x <= b+2^(EXP(b)-err-1) */
+ if (l==0) tn++;
+ tmp = TMP_ALLOC(tn*BYTES_PER_MP_LIMB);
+
+ /* this case is the same than GMP_RNDZ, except we first have to
+ subtract 2^(EXP(b)-err-1) from b */
+
+ if (l) {
+ l--; /* tn=bn */
+ mpn_sub_1(tmp+tn-k, bp+bn-k, k, (mp_limb_t)1<<l);
+ }
+ else {
+ MPN_COPY(tmp+1, bp, bn); *tmp=0; /* extra limb to add or subtract 1 */
+ k++; l=BITS_PER_MP_LIMB-1;
+ mpn_sub_1(tmp+tn-k, tmp+tn-k, k, (mp_limb_t)1<<l);
+ }
+
+ /* round b-2^(EXP(b)-err-1) */
+ /* we can disregard borrow, since we start from tmp in 2nd case too */
+ cc = (tmp[tn-1]>>l1) & 1;
+ cc ^= mpfr_round_raw2(tmp, tn, neg, rnd2, prec);
+
+ if (l==BITS_PER_MP_LIMB-1) { l=0; k--; } else l++;
+
+ /* round b+2^(EXP(b)-err-1) = b-2^(EXP(b)-err-1) + 2^(EXP(b)-err) */
+ cc2 = mpn_add_1(tmp+tn-k, tmp+tn-k, k, (mp_limb_t)1<<l);
+ /* if carry, then all bits up to err were to 1, and we can round only
+ if cc==0 and mpfr_round_raw2 returns 0 below */
+ if (cc2 && cc) { TMP_FREE(marker); return 0; }
+ cc2 = (tmp[tn-1]>>l1) & 1; /* gives 0 when carry */
+ cc2 ^= mpfr_round_raw2(tmp, tn, neg, rnd2, prec);
+
+ TMP_FREE(marker);
+ return (cc == cc2);
+ }
+ return 0;
+}
diff --git a/mpfr/set.c b/mpfr/set.c
new file mode 100644
index 000000000..b4a151dc5
--- /dev/null
+++ b/mpfr/set.c
@@ -0,0 +1,53 @@
+/* mpfr_set -- copy of a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_set4(mpfr_ptr a, mpfr_srcptr b, unsigned char rnd_mode, int signb)
+#else
+mpfr_set4(a, b, rnd_mode)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ unsigned char rnd_mode;
+ int signb;
+#endif
+{
+ int carry, an, preca = PREC(a), sh; mp_limb_t *ap = MANT(a);
+
+ carry = mpfr_round_raw(ap, MANT(b), PREC(b), (signb<0), preca, rnd_mode);
+ EXP(a) = EXP(b);
+ if (carry) {
+ an = (preca-1)/BITS_PER_MP_LIMB + 1;
+ sh = an * BITS_PER_MP_LIMB - preca;
+ if ((*ap >> sh) & 1) {
+ fprintf(stderr, "unable to round in mpfr_set\n"); exit(1);
+ }
+ mpn_rshift(ap, ap, an, 1);
+ ap[an-1] |= (mp_limb_t) 1 << (BITS_PER_MP_LIMB-1);
+ EXP(a)++;
+ }
+ if (SIGN(a) != signb) CHANGE_SIGN(a);
+}
diff --git a/mpfr/set_d.c b/mpfr/set_d.c
new file mode 100644
index 000000000..4863aca76
--- /dev/null
+++ b/mpfr/set_d.c
@@ -0,0 +1,329 @@
+/* mpfr_set_d, mpfr_get_d -- convert a multiple precision floating-point number
+ from/to a machine double precision float
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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. */
+
+#if __GNUC__ /* gcc "patched" headers seem to omit isnan... */
+extern int isnan(double);
+#endif
+#include <math.h> /* for isnan and NaN */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+#define NaN sqrt(-1) /* ensures a machine-independent NaN */
+
+/* Included from gmp-2.0.2, patched to support denorms */
+
+#ifdef XDEBUG
+#undef _GMP_IEEE_FLOATS
+#endif
+
+#ifndef _GMP_IEEE_FLOATS
+#define _GMP_IEEE_FLOATS 0
+#endif
+
+int
+#if __STDC__
+__mpfr_extract_double (mp_ptr rp, double d, int e)
+#else
+__mpfr_extract_double (rp, d)
+ mp_ptr rp;
+ double d;
+ int e;
+#endif
+ /* e=0 iff BITS_PER_MP_LIMB=32 and rp has only one limb */
+{
+ long exp;
+ mp_limb_t manl;
+#if BITS_PER_MP_LIMB == 32
+ mp_limb_t manh;
+#endif
+
+ /* BUGS
+
+ 1. Should handle Inf and NaN in IEEE specific code.
+ 2. Handle Inf and NaN also in default code, to avoid hangs.
+ 3. Generalize to handle all BITS_PER_MP_LIMB >= 32.
+ 4. This lits is incomplete and misspelled.
+ */
+
+ if (d == 0.0)
+ {
+ rp[0] = 0;
+#if BITS_PER_MP_LIMB == 32
+ if (e) rp[1] = 0;
+#endif
+ return 0;
+ }
+
+#if _GMP_IEEE_FLOATS
+ {
+ union ieee_double_extract x;
+ x.d = d;
+
+ exp = x.s.exp;
+ if (exp)
+ {
+#if BITS_PER_MP_LIMB == 64
+ manl = (((mp_limb_t) 1 << 63)
+ | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
+#else
+ manh = ((mp_limb_t) 1 << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
+ manl = x.s.manl << 11;
+#endif
+ }
+ else
+ {
+#if BITS_PER_MP_LIMB == 64
+ manl = ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11);
+#else
+ manh = (x.s.manh << 11) | (x.s.manl >> 21);
+ manl = x.s.manl << 11;
+#endif
+ }
+ }
+#else
+ {
+ /* Unknown (or known to be non-IEEE) double format. */
+ exp = 0;
+ if (d >= 1.0)
+ {
+ if (d * 0.5 == d)
+ abort ();
+
+ while (d >= 32768.0)
+ {
+ d *= (1.0 / 65536.0);
+ exp += 16;
+ }
+ while (d >= 1.0)
+ {
+ d *= 0.5;
+ exp += 1;
+ }
+ }
+ else if (d < 0.5)
+ {
+ while (d < (1.0 / 65536.0))
+ {
+ d *= 65536.0;
+ exp -= 16;
+ }
+ while (d < 0.5)
+ {
+ d *= 2.0;
+ exp -= 1;
+ }
+ }
+
+ d *= MP_BASE_AS_DOUBLE;
+#if BITS_PER_MP_LIMB == 64
+ manl = d;
+#else
+ manh = d;
+ manl = (d - manh) * MP_BASE_AS_DOUBLE;
+#endif
+
+ exp += 1022;
+ }
+#endif
+
+ if (exp) exp = (unsigned) exp - 1022; else exp = -1021;
+
+#if BITS_PER_MP_LIMB == 64
+ rp[0] = manl;
+#else
+ if (e) {
+ rp[1] = manh;
+ rp[0] = manl;
+ }
+ else {
+ rp[0] = manh;
+ }
+#endif
+
+ return exp;
+}
+
+/* End of part included from gmp-2.0.2 */
+/* Part included from gmp temporary releases */
+double
+#if __STDC__
+__mpfr_scale2 (double d, int exp)
+#else
+__mpfr_scale2 (d, exp)
+ double d;
+ int exp;
+#endif
+{
+#if _GMP_IEEE_FLOATS
+ {
+ union ieee_double_extract x;
+ x.d = d;
+ exp += x.s.exp;
+ x.s.exp = exp;
+ if (exp >= 2047)
+ {
+ /* Return +-infinity */
+ x.s.exp = 2047;
+ x.s.manl = x.s.manh = 0;
+ }
+ else if (exp < 1)
+ {
+ x.s.exp = 1; /* smallest exponent (biased) */
+ /* Divide result by 2 until we have scaled it to the right IEEE
+ denormalized number, but stop if it becomes zero. */
+ while (exp < 1 && x.d != 0)
+ {
+ x.d *= 0.5;
+ exp++;
+ }
+ }
+ return x.d;
+ }
+#else
+ {
+ double factor, r;
+
+ factor = 2.0;
+ if (exp < 0)
+ {
+ factor = 0.5;
+ exp = -exp;
+ }
+ r = d;
+ if (exp != 0)
+ {
+ if ((exp & 1) != 0)
+ r *= factor;
+ exp >>= 1;
+ while (exp != 0)
+ {
+ factor *= factor;
+ if ((exp & 1) != 0)
+ r *= factor;
+ exp >>= 1;
+ }
+ }
+ return r;
+ }
+#endif
+}
+
+
+/* End of part included from gmp */
+
+void
+#if __STDC__
+mpfr_set_d(mpfr_t r, double d, unsigned char rnd_mode)
+#else
+mpfr_set_d(r, d, rnd_mode)
+ mpfr_t r;
+ double d;
+ unsigned char rnd_mode;
+#endif
+{
+ int signd, sizer; unsigned int cnt;
+
+ if (d == 0) { SET_ZERO(r); return; }
+ else if (isnan(d)) { SET_NAN(r); return; }
+
+ signd = (d < 0) ? -1 : 1;
+ d = ABS (d);
+ sizer = (PREC(r)-1)/BITS_PER_MP_LIMB + 1;
+
+ /* warning: __mpfr_extract_double requires at least two limbs */
+ if (sizer < MPFR_LIMBS_PER_DOUBLE)
+ EXP(r) = __mpfr_extract_double (MANT(r), d, 0);
+ else
+ EXP(r) = __mpfr_extract_double (MANT(r) + sizer - MPFR_LIMBS_PER_DOUBLE, d, 1);
+
+ if (sizer > MPFR_LIMBS_PER_DOUBLE)
+ MPN_ZERO(MANT(r), sizer - MPFR_LIMBS_PER_DOUBLE);
+
+ count_leading_zeros(cnt, MANT(r)[sizer-1]);
+ if (cnt) mpn_lshift(MANT(r), MANT(r), sizer, cnt);
+
+ EXP(r) -= cnt;
+ if (SIZE(r)*signd<0) CHANGE_SIGN(r);
+
+ mpfr_round(r, rnd_mode, PREC(r));
+ return;
+}
+
+double
+#if __STDC__
+mpfr_get_d2(mpfr_srcptr src, long e)
+#else
+mpfr_get_d2(src, e)
+ mpfr_srcptr(src);
+ long e;
+#endif
+{
+ double res;
+ mp_size_t size, i, n_limbs_to_use;
+ mp_ptr qp;
+ int negative;
+
+ if (FLAG_NAN(src)) {
+#ifdef DEBUG
+ printf("recognized NaN\n");
+#endif
+ return NaN; }
+ if (NOTZERO(src)==0) return 0.0;
+ size = 1+(PREC(src)-1)/BITS_PER_MP_LIMB;
+ qp = MANT(src);
+ negative = (SIGN(src)==-1);
+
+ /* Warning: don't compute the abs(res) and set the sign afterwards,
+ otherwise the current machine rounding mode will not be taken
+ correctly into account. */
+ /* res = (negative) ? -(double)qp[size - 1] : qp[size - 1]; */
+ res = 0.0;
+ /* Warning: an arbitrary number of limbs may be required for an exact
+ rounding. The following code is correct but not optimal since one
+ may be able to decide without considering all limbs. */
+ /* n_limbs_to_use = MIN (MPFR_LIMBS_PER_DOUBLE, size); */
+ n_limbs_to_use = size;
+ /* Accumulate the limbs from less significant to most significant
+ otherwise due to rounding we may accumulate several ulps,
+ especially in rounding towards -/+infinity. */
+ for (i = n_limbs_to_use; i>=1; i--)
+ res = res / MP_BASE_AS_DOUBLE +
+ ((negative) ? -(double)qp[size - i] : qp[size - i]);
+ res = __mpfr_scale2 (res, e - BITS_PER_MP_LIMB);
+
+ return res;
+}
+
+double
+#if __STDC__
+mpfr_get_d(mpfr_srcptr src)
+#else
+mpfr_get_d(src)
+ mpfr_srcptr src;
+#endif
+{
+ return mpfr_get_d2(src, EXP(src));
+}
+
diff --git a/mpfr/set_dfl_prec.c b/mpfr/set_dfl_prec.c
new file mode 100644
index 000000000..aa341be8a
--- /dev/null
+++ b/mpfr/set_dfl_prec.c
@@ -0,0 +1,37 @@
+/* mpfr_set_default_prec -- set the default precision
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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"
+
+/* default is 53 bits */
+mp_size_t __gmp_default_fp_bit_precision = 53;
+
+void
+#if __STDC__
+mpfr_set_default_prec (unsigned long int prec_in_bits)
+#else
+mpfr_set_default_prec (prec_in_bits)
+ unsigned long int prec_in_bits;
+#endif
+{
+ __gmp_default_fp_bit_precision = prec_in_bits;
+}
diff --git a/mpfr/set_dfl_rnd.c b/mpfr/set_dfl_rnd.c
new file mode 100644
index 000000000..cf8fd0175
--- /dev/null
+++ b/mpfr/set_dfl_rnd.c
@@ -0,0 +1,37 @@
+/* mpfr_set_default_rounding_mode -- set the default rounding mode
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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"
+
+char __gmp_default_rounding_mode = 0;
+
+void
+#if __STDC__
+mpfr_set_default_rounding_mode (char rnd_mode)
+#else
+mpfr_set_default_rounding_mode (rnd_mode)
+ char rnd_mode;
+#endif
+{
+ __gmp_default_rounding_mode = rnd_mode;
+}
+
diff --git a/mpfr/set_f.c b/mpfr/set_f.c
new file mode 100644
index 000000000..d3bb98dbf
--- /dev/null
+++ b/mpfr/set_f.c
@@ -0,0 +1,72 @@
+/* mpfr_set_f -- set a MPFR number from a GNU MPF number
+
+Copyright (C) 1999-2000 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+void
+#if __STDC__
+mpfr_set_f(mpfr_ptr y, mpf_srcptr x, char rnd_mode)
+#else
+mpfr_set_f(y, x, rnd_mode)
+ mpfr_ptr y;
+ mpf_srcptr x;
+ char rnd_mode;
+#endif
+{
+ mp_limb_t *my, *mx, *tmp; unsigned long cnt, sx, sy;
+ TMP_DECL(marker);
+
+ sx = ABS(SIZ(x)); sy = ABSSIZE(y);
+ my = MANT(y); mx = MANT(x);
+
+ if (sx==0) { /* x is zero */
+ SET_ZERO(y); return;
+ }
+
+ count_leading_zeros(cnt, mx[sx - 1]);
+
+ if (SIZ(x)*SIGN(y)<0) CHANGE_SIGN(y);
+
+ if (sy < sx)
+ {
+ unsigned long xprec = sx * BITS_PER_MP_LIMB;
+
+ tmp = (mp_limb_t*) TMP_ALLOC(xprec);
+ if (cnt) mpn_lshift(tmp, mx, sx, cnt);
+ else MPN_COPY(tmp, mx, sx);
+ mpfr_round_raw(my, tmp, xprec, (SIZ(x)<0), PREC(y), rnd_mode);
+ }
+ else
+ {
+ if (cnt) mpn_lshift(my + sy - sx, mx, sx, cnt);
+ else MPN_COPY(my + sy - sx, mx, sy);
+ MPN_ZERO(my, sy - sx);
+ /* no rounding necessary, since y has a larger mantissa */
+ }
+
+ EXP(y) = EXP(x) * BITS_PER_MP_LIMB - cnt;
+
+ TMP_FREE(marker);
+}
diff --git a/mpfr/set_prec.c b/mpfr/set_prec.c
new file mode 100644
index 000000000..d85eac3c3
--- /dev/null
+++ b/mpfr/set_prec.c
@@ -0,0 +1,62 @@
+/* mpfr_set_prec -- reset the precision of a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+void
+#if __STDC__
+mpfr_set_prec (mpfr_t x, unsigned long int p)
+#else
+mpfr_set_prec (x, p)
+ mpfr_t x;
+ unsigned long int p;
+#endif
+{
+ unsigned long xsize;
+
+ if (p==0) {
+ printf("*** cannot set precision to 0 bits\n"); exit(1);
+ }
+
+ xsize = (p - 1)/BITS_PER_MP_LIMB + 1; /* new limb size */
+
+ if (xsize > ABSSIZE(x)) {
+ x -> _mp_d = (mp_ptr) (*_mp_reallocate_func)
+ (x -> _mp_d, ABSSIZE(x)*BYTES_PER_MP_LIMB, xsize * BYTES_PER_MP_LIMB);
+ SIZE(x) = xsize; /* new number of allocated limbs */
+ }
+
+ x -> _mp_prec = p;
+}
+
+unsigned long int
+#if __STDC__
+mpfr_get_prec (mpfr_t x)
+#else
+mpfr_get_prec (x)
+ mpfr_t x;
+#endif
+{
+ return x -> _mp_prec;
+}
diff --git a/mpfr/set_si.c b/mpfr/set_si.c
new file mode 100644
index 000000000..b2d916cd1
--- /dev/null
+++ b/mpfr/set_si.c
@@ -0,0 +1,81 @@
+/* mpfr_set_si, mpfr_set_ui -- set a MPFR number from a machine integer
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "longlong.h"
+#include "mpfr.h"
+
+void
+#if __STDC__
+mpfr_set_si(mpfr_ptr x, long i, unsigned char rnd_mode)
+#else
+mpfr_set_si(x, i, rnd_mode)
+ mpfr_ptr x;
+ long i;
+ unsigned char rnd_mode;
+#endif
+{
+ unsigned long xn, cnt; mp_limb_t ai;
+
+ if (i==0) { SET_ZERO(x); return; }
+ xn = (PREC(x)-1)/BITS_PER_MP_LIMB;
+ ai = ABS(i);
+
+ count_leading_zeros(cnt, ai);
+
+ x -> _mp_d[xn] = ai << cnt;
+ /* don't forget to put zero in lower limbs */
+ MPN_ZERO(MANT(x), xn);
+ x -> _mp_exp = BITS_PER_MP_LIMB - cnt;
+ /* warning: don't change the precision of x! */
+ if (i*SIGN(x) < 0) CHANGE_SIGN(x);
+
+ return;
+}
+
+void
+#if __STDC__
+mpfr_set_ui(mpfr_ptr x, unsigned long i, unsigned char rnd_mode)
+#else
+mpfr_set_ui(x, i, rnd_mode)
+ mpfr_ptr x;
+ long i;
+ unsigned char rnd_mode;
+#endif
+{
+ unsigned int xn, cnt;
+
+ if (i==0) { SET_ZERO(x); return; }
+ xn = (PREC(x)-1)/BITS_PER_MP_LIMB;
+ count_leading_zeros(cnt, (mp_limb_t) i);
+
+ x -> _mp_d[xn] = ((mp_limb_t) i) << cnt;
+ /* don't forget to put zero in lower limbs */
+ MPN_ZERO(MANT(x), xn);
+ x -> _mp_exp = BITS_PER_MP_LIMB - cnt;
+ /* warning: don't change the precision of x! */
+ if (SIGN(x) < 0) CHANGE_SIGN(x);
+
+ return;
+}
+
diff --git a/mpfr/set_str_raw.c b/mpfr/set_str_raw.c
new file mode 100644
index 000000000..d0945c4bc
--- /dev/null
+++ b/mpfr/set_str_raw.c
@@ -0,0 +1,112 @@
+/* mpfr_set_str_raw -- set a floating-point number from a binary string
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#ifdef HAS_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+/* Currently the number should be of the form +/- xxxx.xxxxxxEyy, with
+ decimal exponent. The mantissa of x is supposed to be large enough
+ to hold all the bits of str. */
+
+void
+#if __STDC__
+mpfr_set_str_raw(mpfr_ptr x, char *str)
+#else
+mpfr_set_str_raw(x, str)
+ mpfr_ptr x;
+ char *str;
+#endif
+{
+ char *str2, *str0, negative = 0;
+ unsigned long j, l, k = 0, xsize, cnt; mp_limb_t *xp;
+ long expn = 0, e; char *endstr2;
+
+ xp = x -> _mp_d;
+ xsize = 1 + (PREC(x)-1)/BITS_PER_MP_LIMB;
+ str0 = str2 = (char *) malloc((strlen(str)+1)*sizeof(char));
+
+ if (*str == '-') { negative = 1; str++; }
+ else if (*str == '+') str++;
+
+ while (*str == '0') { str++; }
+
+ while (*str == '0' || *str == '1')
+ { *(str2++) = *(str++); k++; }
+
+ if (*str == '.')
+ {
+ str++;
+ while (*str == '0' || *str == '1')
+ { *(str2++) = *(str++); }
+
+ if (*str == '[') { while (*str != ']') str++; }
+ }
+
+ if (*str == '[') { while (*str != ']') str++; }
+
+ if (*str == 'e' || *str == 'E')
+ {
+ e = atol(++str); /* signed exponent after 'e' or 'E' */
+ expn = k + e;
+ if (expn < e)
+ fprintf(stderr, "Warning: overflow in exponent in Str -> mpfr\n");
+ }
+ else expn=k;
+
+ endstr2 = str2;
+ *str2 = (char) 0; /* end of string */
+ l = (strlen(str0) - 1) / BITS_PER_MP_LIMB + 1; str2 = str0;
+
+ /* str2[0]..endstr2[-1] contains the mantissa */
+ for (k = 1; k <= l; k++)
+ {
+ j = 0;
+ xp[xsize - k] = 0;
+ while (str2<endstr2 && j < BITS_PER_MP_LIMB)
+ {
+ xp[xsize - k] = (xp[xsize - k] << 1) + (*str2 - '0');
+ str2++; j++;
+ }
+ xp[xsize - k] <<= (BITS_PER_MP_LIMB - j);
+ }
+
+ for (; k <= xsize; k++) { xp[xsize - k] = 0; }
+
+ count_leading_zeros(cnt, xp[xsize - 1]);
+ if (cnt) mpn_lshift(xp, xp, xsize, cnt);
+
+ x -> _mp_exp = expn - cnt;
+ x -> _mp_size = xsize; if (negative) CHANGE_SIGN(x);
+
+ free(str0);
+
+ /* May change to take into account : syntax errors, overflow in exponent,
+ string truncated because of size of x */
+}
diff --git a/mpfr/set_z.c b/mpfr/set_z.c
new file mode 100644
index 000000000..de9132033
--- /dev/null
+++ b/mpfr/set_z.c
@@ -0,0 +1,104 @@
+/* mpfr_set_z -- set a floating-point number from a multiple-precision integer
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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"
+#include "mpfr.h"
+
+/* set f to the integer z */
+int
+#if __STDC__
+mpfr_set_z (mpfr_ptr f, mpz_srcptr z, unsigned char rnd)
+#else
+mpfr_set_z (f, z, rnd)
+ mpfr_ptr f;
+ mpz_srcptr z;
+ unsigned char rnd;
+#endif
+{
+ int fn, zn, k, dif, sign_z, sh; mp_limb_t *fp = MANT(f), *zp, cc, c2;
+
+ sign_z = mpz_cmp_ui(z,0);
+ if (sign_z==0) return (SIZE(f)=0);
+ fn = 1 + (PREC(f)-1)/BITS_PER_MP_LIMB;
+ zn = ABS(SIZ(z));
+ dif = zn-fn;
+ zp = PTR(z);
+ count_leading_zeros(k, zp[zn-1]);
+ EXP(f) = zn*BITS_PER_MP_LIMB-k;
+ if (SIGN(f)*sign_z<0) CHANGE_SIGN(f);
+ if (dif>=0) { /* number has to be truncated */
+ if (k) {
+ mpn_lshift(fp, zp + dif, fn, k);
+ if (dif) *fp += zp[dif-1] >> (BITS_PER_MP_LIMB-k);
+ }
+ else MPN_COPY(fp, zp + dif, fn);
+ sh = fn*BITS_PER_MP_LIMB-PREC(f);
+ cc = *fp & (((mp_limb_t)1 << sh) - 1);
+ *fp = *fp & ~cc;
+ if (rnd==GMP_RNDN) {
+ if (sh) c2 = (mp_limb_t)1 << (sh-1);
+ else { /* sh=0 */
+ c2 = ((mp_limb_t)1) << (BITS_PER_MP_LIMB-1);
+ dif--;
+ cc = (dif>=0) ? ((zp[dif])<<k) : 0;
+ if (dif>0 && k) cc += zp[dif-1] >> (BITS_PER_MP_LIMB-k);
+ }
+ /* now compares cc to c2 */
+ if (cc>c2) { mpfr_add_one_ulp(f); return cc; }
+ else if (cc<c2) goto towards_zero;
+ else {
+ cc=0;
+ while (dif>0 && (cc=zp[dif-1])==0) dif--;
+ if (cc) { mpfr_add_one_ulp(f); return cc; }
+ else /* exactly in middle: inexact in both cases */
+ if (*fp & ((mp_limb_t)1<<sh)) { mpfr_add_one_ulp(f); return 1; }
+ else return 1;
+ }
+ }
+ else if ((sign_z>0 && rnd==GMP_RNDU) || (sign_z<0 && rnd==GMP_RNDD)) {
+ /* round towards infinity */
+ /* result is exact iff all remaining bits are zero */
+ if (dif>0 && cc==0) cc=zp[--dif]<<k;
+ while (cc==0 && dif>0) cc=zp[--dif];
+ if (cc) { mpfr_add_one_ulp(f); return 1; }
+ else return 0;
+ }
+ else { /* round towards zero */
+ /* result is exact iff all remaining bits are zero */
+ towards_zero:
+ if (cc==0 && dif>0) cc=zp[--dif]<<k;
+ while (cc==0 && dif>0) cc=zp[--dif];
+ return cc;
+ }
+ }
+ else {
+ if (k) mpn_lshift(fp-dif, zp, zn, k);
+ else MPN_COPY(fp-dif, zp, zn);
+ /* fill with zeroes */
+ MPN_ZERO(fp, -dif);
+ return 0; /* result is exact */
+ }
+}
+
+
+
diff --git a/mpfr/sqrt.c b/mpfr/sqrt.c
new file mode 100644
index 000000000..a34ff6dae
--- /dev/null
+++ b/mpfr/sqrt.c
@@ -0,0 +1,220 @@
+/* mpfr_sqrt -- square root of a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "longlong.h"
+
+/* #define DEBUG */
+
+int
+mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, unsigned char rnd_mode)
+{
+ mp_ptr up, rp, tmp, remp;
+ mp_size_t usize, rrsize;
+ mp_size_t rsize;
+ mp_size_t prec, err;
+ mp_limb_t q_limb;
+ long rw, nw, k;
+ int exact = 0;
+ unsigned long cc = 0;
+ char can_round = 0;
+ TMP_DECL (marker); TMP_DECL(marker0);
+
+ if (FLAG_NAN(u) || SIGN(u) == -1) { SET_NAN(r); return 0; }
+
+ prec = PREC(r);
+
+ if (!NOTZERO(u))
+ {
+ EXP(r) = 0;
+ MPN_ZERO(MANT(r), ABSSIZE(r));
+ return 1;
+ }
+
+ up = MANT(u);
+
+#ifdef DEBUG
+ printf("Entering square root : ");
+ for(k = usize - 1; k >= 0; k--) { printf("%lu ", up[k]); }
+ printf(".\n");
+#endif
+
+ /* Compare the mantissas */
+
+ usize = (PREC(u) - 1)/BITS_PER_MP_LIMB + 1;
+ rsize = ((PREC(r) + 2 + (EXP(u) & 1))/BITS_PER_MP_LIMB + 1) << 1;
+ rrsize = (PREC(r) + 2 + (EXP(u) & 1))/BITS_PER_MP_LIMB + 1;
+ /* One extra bit is needed in order to get the square root with enough
+ precision ; take one extra bit for rrsize in order to solve more
+ easily the problem of rounding to nearest.
+ Need to have 2*rrsize = rsize...
+ Take one extra bit if the exponent of u is odd since we shall have
+ to shift then.
+ */
+
+ TMP_MARK(marker0);
+ if (EXP(u) & 1) /* Shift u one bit to the right */
+ {
+ if (PREC(u) & (BITS_PER_MP_LIMB - 1))
+ {
+ up = TMP_ALLOC(usize*BYTES_PER_MP_LIMB);
+ mpn_rshift(up, u->_mp_d, usize, 1);
+ }
+ else
+ {
+ up = TMP_ALLOC((usize + 1)*BYTES_PER_MP_LIMB);
+ if (mpn_rshift(up + 1, u->_mp_d, ABSSIZE(u), 1))
+ up [0] = ((mp_limb_t) 1) << (BITS_PER_MP_LIMB - 1);
+ else up[0] = 0;
+ usize++;
+ }
+ }
+
+ EXP(r) = ((EXP(u) + (EXP(u) & 1)) / 2) ;
+
+ do
+ {
+ TMP_MARK (marker);
+
+ err = rsize*BITS_PER_MP_LIMB;
+ if (rsize < usize) { err--; }
+ if (err > rrsize * BITS_PER_MP_LIMB)
+ { err = rrsize * BITS_PER_MP_LIMB; }
+
+ tmp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ rp = (mp_ptr) TMP_ALLOC (rrsize * BYTES_PER_MP_LIMB);
+ remp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ if (usize >= rsize) {
+ MPN_COPY (tmp, up + usize - rsize, rsize);
+ }
+ else {
+ MPN_COPY (tmp + rsize - usize, up, usize);
+ MPN_ZERO (tmp, rsize - usize);
+ }
+
+ /* Do the real job */
+
+#ifdef DEBUG
+ printf("Taking the sqrt of : ");
+ for(k = rsize - 1; k >= 0; k--) {
+ printf("+%lu*2^%lu",tmp[k],k*mp_bits_per_limb); }
+ printf(".\n");
+#endif
+
+ q_limb = kara_sqrtrem (rp, remp, tmp, rsize);
+
+#ifdef DEBUG
+ printf("The result is : \n");
+ printf("sqrt : ");
+ for(k = rrsize - 1; k >= 0; k--) { printf("%lu ", rp[k]); }
+ printf("(q_limb = %lu)\n", q_limb);
+#endif
+
+ can_round = (mpfr_can_round_raw(rp, rrsize, 1, err,
+ GMP_RNDZ, rnd_mode, PREC(r)));
+
+ /* If we used all the limbs of both the dividend and the divisor,
+ then we have the correct RNDZ rounding */
+
+ if (!can_round && (rsize < 2*usize))
+ {
+#ifdef DEBUG
+ printf("Increasing the precision.\n");
+#endif
+ TMP_FREE(marker);
+ }
+ }
+ while (!can_round && (rsize < 2*usize)
+ && (rsize += 2) && (rrsize ++));
+
+
+ /* This part may be deplaced upper to avoid a few mpfr_can_round_raw */
+ /* when the square root is exact. It is however very unprobable that */
+ /* it would improve the behaviour of the present code on average. */
+
+ if (!q_limb) /* possibly exact */
+ {
+ /* if we have taken into account the whole of up */
+ for (k = usize - rsize - 1; k >= 0; k ++)
+ if (up[k]) break;
+
+ if (k < 0) { exact = 1; goto fin; }
+ }
+
+ if (can_round)
+ {
+ cc = mpfr_round_raw(rp, rp, err, 0, PREC(r), rnd_mode);
+ rrsize = (PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
+ }
+ else
+ /* Use the return value of sqrtrem to decide of the rounding */
+ /* Note that at this point the sqrt has been computed */
+ /* EXACTLY. If rounding = GMP_RNDZ, do nothing [comes from */
+ /* the fact that the exact square root can end with a bunch of ones, */
+ /* and in that case we indeed cannot round if we do not know that */
+ /* the computation was exact. */
+ switch (rnd_mode)
+ {
+ case GMP_RNDZ :
+ case GMP_RNDD : break;
+
+ case GMP_RNDN :
+ /* Not in the situation ...0 111111 */
+ rw = (PREC(r) + 1) & (BITS_PER_MP_LIMB - 1);
+ if (rw) { rw = BITS_PER_MP_LIMB - rw; nw = 0; } else nw = 1;
+ if ((rp[nw] >> rw) & 1 && /* Not 0111111111 */
+ (q_limb || /* Nonzero remainder */
+ (rw ? (rp[nw] >> (rw + 1)) & 1 :
+ (rp[nw] >> (BITS_PER_MP_LIMB - 1)) & 1))) /* or even rounding */
+ cc = mpn_add_1(rp + nw, rp + nw, rrsize, ((mp_limb_t)1) << rw);
+ break;
+
+ case GMP_RNDU :
+ if (q_limb)
+ cc = mpn_add_1(rp, rp, rrsize, 1 << (BITS_PER_MP_LIMB -
+ (PREC(r) &
+ (BITS_PER_MP_LIMB - 1))));
+ }
+
+ if (cc) {
+ mpn_rshift(rp, rp, rrsize, 1);
+ rp[rrsize-1] |= (mp_limb_t) 1 << (BITS_PER_MP_LIMB-1);
+ r->_mp_exp++;
+ }
+
+ fin:
+ rsize = rrsize;
+ rrsize = (PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
+ MPN_COPY(r->_mp_d, rp + rsize - rrsize, rrsize);
+
+ if (PREC(r) & (BITS_PER_MP_LIMB - 1))
+ MANT(r) [0] &= ~(((mp_limb_t)1 << (BITS_PER_MP_LIMB -
+ (PREC(r) & (BITS_PER_MP_LIMB - 1)))) - 1) ;
+
+ TMP_FREE(marker0); TMP_FREE (marker);
+ return exact;
+}
diff --git a/mpfr/sub.c b/mpfr/sub.c
new file mode 100644
index 000000000..dfe755b73
--- /dev/null
+++ b/mpfr/sub.c
@@ -0,0 +1,483 @@
+/* mpfr_sub -- subtract two floating-point numbers
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 "mpfr.h"
+
+/* #define DEBUG */
+
+extern void mpfr_add1 _PROTO((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ unsigned char, int));
+
+/* put in ap[0]..ap[an-1] the value of bp[0]..bp[n-1] shifted by sh bits
+ to the left minus ap[0]..ap[n-1], with 0 <= sh < mp_bits_per_limb, and
+ returns the borrow.
+*/
+mp_limb_t
+#if __STDC__
+mpn_sub_lshift_n (mp_limb_t *ap, mp_limb_t *bp, int n, int sh, int an)
+#else
+mpn_sub_lshift_n (ap, bp, n, sh, an) mp_limb_t *ap, *bp; int n,sh,an;
+#endif
+{
+ mp_limb_t c, bh;
+
+ /* shift b to the left */
+ if (sh) bh = mpn_lshift(bp, bp, n, sh);
+ c = (n<an) ? mpn_sub_n(ap, bp, ap, n) : mpn_sub_n(ap, bp+(n-an), ap, an);
+ /* shift back b to the right */
+ if (sh) {
+ mpn_rshift(bp, bp, n, sh);
+ bp[n-1] += bh<<(mp_bits_per_limb-sh);
+ }
+ return c;
+}
+
+/* signs of b and c differ, abs(b)>=abs(c), diff_exp>=0 */
+void
+#if __STDC__
+mpfr_sub1(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, unsigned char rnd_mode, int diff_exp)
+#else
+mpfr_sub1(a, b, c, rnd_mode, diff_exp)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+ unsigned char rnd_mode;
+ int diff_exp;
+#endif
+{
+ mp_limb_t *ap, *bp, *cp, cc, c2; unsigned int an,bn,cn;
+ int sh,dif,k,cancel,cancel1,cancel2;
+ TMP_DECL(marker);
+
+#ifdef DEBUG
+ printf("b= "); if (SIGN(b)>=0) putchar(' ');
+ mpfr_print_raw(b); putchar('\n');
+ printf("c= "); if (SIGN(c)>=0) putchar(' ');
+ for (k=0;k<diff_exp;k++) putchar(' '); mpfr_print_raw(c);
+ putchar('\n');
+ printf("b=%1.20e c=%1.20e\n",mpfr_get_d(b),mpfr_get_d(c));
+#endif
+ cancel = mpfr_cmp2(b, c);
+ /* we have to take into account the first (PREC(a)+cancel) bits from b */
+ cancel1 = cancel/mp_bits_per_limb; cancel2 = cancel%mp_bits_per_limb;
+ TMP_MARK(marker);
+ ap = MANT(a);
+ bp = MANT(b);
+ cp = MANT(c);
+ if (ap == bp) {
+ bp = (mp_ptr) TMP_ALLOC(ABSSIZE(b) * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, ap, ABSSIZE(b));
+ if (ap == cp) { cp = bp; }
+ }
+ else if (ap == cp)
+ {
+ cp = (mp_ptr) TMP_ALLOC (ABSSIZE(c) * BYTES_PER_MP_LIMB);
+ MPN_COPY(cp, ap, ABSSIZE(c));
+ }
+ an = (PREC(a)-1)/mp_bits_per_limb+1; /* number of significant limbs of a */
+ sh = an*mp_bits_per_limb-PREC(a); /* non-significant bits in low limb */
+ bn = (PREC(b)-1)/mp_bits_per_limb+1; /* number of significant limbs of b */
+ cn = (PREC(c)-1)/mp_bits_per_limb + 1;
+ EXP(a) = EXP(b)-cancel;
+ /* adjust sign to that of b */
+ if (SIGN(a)*SIGN(b)<0) CHANGE_SIGN(a);
+ /* case 1: diff_exp>=prec(a), i.e. c only affects the last bit
+ through rounding */
+ dif = PREC(a)-diff_exp;
+#ifdef DEBUG
+ printf("PREC(a)=%d an=%u PREC(b)=%d bn=%u PREC(c)=%d diff_exp=%u dif=%d cancel=%d\n",
+ PREC(a),an,PREC(b),bn,PREC(c),diff_exp,dif,cancel);
+#endif
+ if (dif<=0) { /* diff_exp>=PREC(a): c does not overlap with a */
+ /* either PREC(b)<=PREC(a), and we can copy the mantissa of b directly
+ into that of a, or PREC(b)>PREC(a) and we have to round b-c */
+ if (PREC(b)<=PREC(a)+cancel) {
+ if (cancel2) mpn_lshift(ap+(an-bn+cancel1), bp, bn-cancel1, cancel2);
+ else MPN_COPY(ap+(an-bn+cancel1), bp, bn-cancel1);
+ /* fill low significant limbs with zero */
+ MPN_ZERO(ap, an-bn+cancel1);
+ /* now take c into account */
+ if (rnd_mode==GMP_RNDN) { /* to nearest */
+ /* if diff_exp > PREC(a), no change */
+ if (diff_exp==PREC(a)) {
+ /* if c is not zero, then as it is normalized, we have to subtract
+ one to the lsb of a if c>1/2, or c=1/2 and lsb(a)=1 (round to
+ even) */
+ if (NOTZERO(c)) { /* c is not zero */
+ /* check whether mant(c)=1/2 or not */
+ cc = *cp - ((mp_limb_t)1<<(mp_bits_per_limb-1));
+ if (cc==0) {
+ bp = cp+(PREC(c)-1)/mp_bits_per_limb;
+ while (cp<bp && cc==0) cc = *++cp;
+ }
+ if (cc || (ap[an-1] & (mp_limb_t)1<<sh)) goto sub_one_ulp;
+ /* mant(c) > 1/2 or mant(c) = 1/2: subtract 1 iff lsb(a)=1 */
+ }
+ }
+ else if (ap[an-1]==0) { /* case b=2^n */
+ ap[an-1] = (mp_limb_t) 1 << (BITS_PER_MP_LIMB-1);
+ EXP(a)++;
+ }
+ }
+ else if ((ISNONNEG(b) && rnd_mode==GMP_RNDU) ||
+ (ISNEG(b) && rnd_mode==GMP_RNDD)) {
+ /* round up: nothing to do */
+ if (ap[an-1]==0) { /* case b=2^n */
+ ap[an-1] = (mp_limb_t) 1 << (BITS_PER_MP_LIMB-1);
+ EXP(a)++;
+ }
+ }
+ else {
+ /* round down: subtract 1 ulp iff c<>0 */
+ if (NOTZERO(c)) goto sub_one_ulp;
+ }
+ }
+ else { /* PREC(b)>PREC(a) : we have to round b-c */
+ k=bn-an;
+ /* first copy the 'an' most significant limbs of b to a */
+ MPN_COPY(ap, bp+k, an);
+ if (rnd_mode==GMP_RNDN) { /* to nearest */
+ /* first check whether the truncated bits from b are 1/2*lsb(a) */
+ if (sh) {
+ cc = *ap & (((mp_limb_t)1<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ cc -= (mp_limb_t)1<<(sh-1);
+ }
+ else /* no bit to truncate */
+ cc = bp[--k] - ((mp_limb_t)1<<(mp_bits_per_limb-1));
+ if ((long)cc>0) { /* suppose sizeof(long)=sizeof(mp_limb_t) */
+ goto add_one_ulp; /* trunc(b)>1/2*lsb(a) -> round up */
+ }
+ else if (cc==0) {
+ while (k>1 && cc==0) cc=bp[--k];
+ /* now if the truncated part of b = 1/2*lsb(a), check whether c=0 */
+ if (NOTZERO(c) || (*ap & ((mp_limb_t)1<<sh))) goto sub_one_ulp;
+ /* if trunc(b)-c is exactly 1/2*lsb(a) : round to even lsb */
+ }
+ /* if cc<0 : trunc(b) < 1/2*lsb(a) -> round down, i.e. do nothing */
+ }
+ else { /* round towards infinity or zero */
+ if (sh) {
+ cc = *ap & (((mp_limb_t)1<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ }
+ else cc=0;
+ cn--;
+ c2 = (dif>-sh) ? cp[cn]>>(mp_bits_per_limb-dif-sh) : 0;
+ while (cc==c2 && (k || cn)) {
+ if (k) cc = bp[--k];
+ if (cn) {
+ c2 = cp[cn]<<(dif+sh);
+ if (--cn) c2 += cp[cn]>>(mp_bits_per_limb-dif-sh);
+ }
+ }
+ dif = ((ISNONNEG(b) && rnd_mode==GMP_RNDU) ||
+ (ISNEG(b) && rnd_mode==GMP_RNDD));
+ /* round towards infinity if dif=1, towards zero otherwise */
+ if (dif && cc>c2) goto add_one_ulp;
+ else if (dif==0 && cc<c2) goto sub_one_ulp;
+ }
+ }
+ }
+ else { /* case 2: diff_exp < PREC(a) : c overlaps with a by dif bits */
+ /* first copy upper part of c into a (after shift) */
+ int overlap;
+ dif += cancel;
+ k = (dif-1)/mp_bits_per_limb + 1; /* only the highest k limbs from c
+ have to be considered */
+ if (k<an) {
+ MPN_ZERO(ap+k, an-k); /* do it now otherwise ap[k] may be
+ destroyed in case dif<0 */
+ }
+#ifdef DEBUG
+ printf("cancel=%d dif=%d k=%d cn=%d sh=%d\n",cancel,dif,k,cn,sh);
+#endif
+ if (dif<=PREC(c)) { /* c has to be truncated */
+ dif = dif % mp_bits_per_limb;
+ dif = (dif) ? mp_bits_per_limb-dif-sh : -sh;
+ /* we have to shift by dif bits to the right */
+ if (dif>0) {
+ mpn_rshift(ap, cp+(cn-k), (k<=an) ? k : an, dif);
+ if (k>an) ap[an-1] += cp[cn-k+an]<<(mp_bits_per_limb-dif);
+ }
+ else if (dif<0) {
+ cc = mpn_lshift(ap, cp+(cn-k), k, -dif);
+ if (k<an) ap[k]=cc;
+ /* put the non-significant bits in low limb for further rounding */
+ if (cn >= k+1)
+ ap[0] += cp[cn-k-1]>>(mp_bits_per_limb+dif);
+ }
+ else MPN_COPY(ap, cp+(cn-k), k);
+ overlap=1;
+ }
+ else { /* c is not truncated, but we have to fill low limbs with 0 */
+ MPN_ZERO(ap, k-cn);
+ overlap = cancel-diff_exp;
+#ifdef DEBUG
+ printf("0:a="); mpfr_print_raw(a); putchar('\n');
+ printf("overlap=%d\n",overlap);
+#endif
+ if (overlap>=0) {
+ cn -= overlap/mp_bits_per_limb;
+ overlap %= mp_bits_per_limb;
+ /* warning: a shift of zero with mpn_lshift is not allowed */
+ if (overlap) {
+ if (an<cn) {
+ mpn_lshift(ap, cp+(cn-an), an, overlap);
+ ap[0] += cp[cn-an-1]>>(mp_bits_per_limb-overlap);
+ }
+ else mpn_lshift(ap+(an-cn), cp, cn, overlap);
+ }
+ else MPN_COPY(ap+(an-cn), cp, cn);
+ }
+ else { /* shift to the right by -overlap bits */
+ overlap = -overlap;
+ k = overlap/mp_bits_per_limb;
+ overlap = overlap % mp_bits_per_limb;
+ if (overlap) cc = mpn_rshift(ap+(an-k-cn), cp, cn, overlap);
+ else {
+ MPN_COPY(ap+(an-k-cn), cp, cn);
+ cc = 0;
+ }
+ if (an>k+cn) ap[an-k-cn-1]=cc;
+ }
+ overlap=0;
+ }
+#ifdef DEBUG
+ printf("1:a="); mpfr_print_raw(a); putchar('\n');
+#endif
+ /* here overlap=1 iff ulp(c)<ulp(a) */
+ /* then put high limbs to zero */
+ /* now add 'an' upper limbs of b in place */
+ if (PREC(b)<=PREC(a)+cancel) { int i, imax;
+ overlap += 2;
+ /* invert low limbs */
+ imax = (int)an-(int)bn+cancel1;
+ for (i=0;i<imax;i++) ap[i] = ~ap[i];
+ cc = (i) ? mpn_add_1(ap, ap, i, 1) : 1;
+ mpn_sub_lshift_n(ap+i, bp, bn-cancel1, cancel2, an);
+ mpn_sub_1(ap+i, ap+i, an-i, (mp_limb_t)1-cc);
+ }
+ else /* PREC(b) > PREC(a): we have to truncate b */
+ mpn_sub_lshift_n(ap, bp+(bn-an-cancel1), an, cancel2, an);
+ /* remains to do the rounding */
+#ifdef DEBUG
+ printf("2:a="); mpfr_print_raw(a); putchar('\n');
+ printf("overlap=%d\n",overlap);
+#endif
+ if (rnd_mode==GMP_RNDN) { /* to nearest */
+ int kc;
+ /* four cases: overlap =
+ (0) PREC(b) > PREC(a) and diff_exp+PREC(c) <= PREC(a)
+ (1) PREC(b) > PREC(a) and diff_exp+PREC(c) > PREC(a)
+ (2) PREC(b) <= PREC(a) and diff_exp+PREC(c) <= PREC(a)
+ (3) PREC(b) <= PREC(a) and diff_exp+PREC(c) > PREC(a) */
+ switch (overlap)
+ {
+ case 1: /* both b and c to round */
+ kc = cn-k; /* remains kc limbs from c */
+ k = bn-an; /* remains k limbs from b */
+ /* truncate last bits and store the difference with 1/2*ulp in cc */
+ cc = *ap & (((mp_limb_t)1<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ cc -= (mp_limb_t)1<<(sh-1);
+ while ((cc==0 || cc==-1) && k!=0 && kc!=0) {
+ kc--;
+ cc -= mpn_sub_1(&c2, bp+(--k), 1, (cp[kc]>>dif) +
+ (cp[kc+1]<<(mp_bits_per_limb-dif)));
+ if (cc==0 || cc==-1) cc=c2;
+ }
+ if ((long)cc>0) goto add_one_ulp;
+ else if ((long)cc<-1) goto end_of_sub; /* the carry can be at most 1 */
+ else if (kc==0) goto round_b;
+ /* else round c: go through */
+ case 3: /* only c to round */
+ bp=cp; k=cn-k; goto to_nearest;
+ case 0: /* only b to round */
+ round_b:
+ k=bn-an; dif=0; goto to_nearest;
+ /* otherwise the result is exact: nothing to do */
+ }
+ }
+ else if ((ISNONNEG(b) && rnd_mode==GMP_RNDU) ||
+ (ISNEG(b) && rnd_mode==GMP_RNDD)) {
+ cc = *ap & (((mp_limb_t)1<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ if (cc) goto add_one_ulp; /* will happen most of the time */
+ else { /* same four cases too */
+ int kc = cn-k; /* remains kc limbs from c */
+ switch (overlap)
+ {
+ case 1: /* both b and c to round */
+ k = bn-an; /* remains k limbs from b */
+ dif = diff_exp % mp_bits_per_limb;
+ while (cc==0 && k!=0 && kc!=0) {
+ kc--;
+ cc = bp[--k] - (cp[kc]>>dif);
+ if (dif) cc -= (cp[kc+1]<<(mp_bits_per_limb-dif));
+ }
+ if (cc) goto add_one_ulp;
+ else if (kc==0) goto round_b2;
+ /* else round c: go through */
+ case 3: /* only c to round: nothing to do */
+ /* while (kc) if (cp[--kc]) goto add_one_ulp; */
+ /* if dif>0 : remains to check last dif bits from c */
+ /* if (dif>0 && (cp[0]<<(mp_bits_per_limb-dif))) goto add_one_ulp; */
+ break;
+ case 0: /* only b to round */
+ round_b2:
+ k=bn-an;
+ while (k) if (bp[--k]) goto add_one_ulp;
+ /* otherwise the result is exact: nothing to do */
+ }
+ }
+ }
+ /* else round to zero: remove 1 ulp if neglected bits from b-c are < 0 */
+ else {
+ cc = *ap & (((mp_limb_t)1<<sh)-1);
+ *ap &= ~cc;
+ if (cc==0) { /* otherwise neglected difference cannot be < 0 */
+ /* take into account bp[0]..bp[bn-cancel1-1] shifted by cancel2 to left
+ and cp[0]..cp[cn-k-1] shifted by dif bits to right */
+ switch (overlap) {
+ case 0:
+ case 2:
+ break; /* c is not truncated ==> no borrow */
+ case 1: /* both b and c are truncated */
+ break;
+ case 3: /* only c is truncated */
+ cn -= k; /* take into account cp[0]..cp[cn-1] shifted by dif bits
+ to the right */
+ cc = (dif>0) ? cp[cn]<<(mp_bits_per_limb-dif) : 0;
+ while (cc==0 && cn>0) cc = cp[--cn];
+ if (cc) goto sub_one_ulp;
+ break;
+ }
+ }
+ }
+ }
+ goto end_of_sub;
+
+ to_nearest: /* 0 <= sh < mp_bits_per_limb : number of bits of a to truncate
+ bp[k] : last significant limb from b */
+#ifdef DEBUG
+mpfr_print_raw(a); putchar('\n');
+#endif
+ if (sh) {
+ cc = *ap & (((mp_limb_t)1<<sh)-1);
+ *ap &= ~cc; /* truncate last bits */
+ c2 = (mp_limb_t)1<<(sh-1);
+ }
+ else /* no bit to truncate */
+ { if (k) cc = bp[--k]; else cc = 0; c2 = (mp_limb_t)1<<(mp_bits_per_limb-1); }
+#ifdef DEBUG
+ printf("cc=%lu c2=%lu k=%u\n",cc,c2,k);
+#endif
+ if (cc>c2) goto add_one_ulp; /* trunc(b)>1/2*lsb(a) -> round up */
+ else if (cc==c2) {
+ cc=0; while (k && cc==0) cc=bp[--k];
+#ifdef DEBUG
+ printf("cc=%lu\n",cc);
+#endif
+ /* special case of rouding c shifted to the right */
+ if (cc==0 && dif>0) cc=bp[0]<<(mp_bits_per_limb-dif);
+ /* now if the truncated part of b = 1/2*lsb(a), check whether c=0 */
+ if (bp!=cp) {
+ if (cc || (*ap & ((mp_limb_t)1<<sh))) goto add_one_ulp;
+ }
+ else {
+ /* subtract: if cc>0, do nothing */
+ if (cc==0 && (*ap & ((mp_limb_t)1<<sh))) goto add_one_ulp;
+ }
+ }
+ goto end_of_sub;
+
+ sub_one_ulp:
+ cc = mpn_sub_1(ap, ap, an, (mp_limb_t)1<<sh);
+ goto end_of_sub;
+
+ add_one_ulp: /* add one unit in last place to a */
+ cc = mpn_add_1(ap, ap, an, (mp_limb_t)1<<sh);
+
+ end_of_sub:
+#ifdef DEBUG
+printf("b-c="); if (SIGN(a)>0) putchar(' '); mpfr_print_raw(a); putchar('\n');
+#endif
+ TMP_FREE(marker);
+ return;
+}
+
+void
+#if __STDC__
+mpfr_sub(mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, unsigned char rnd_mode)
+#else
+mpfr_sub(a, b, c, rnd_mode)
+ mpfr_ptr a;
+ mpfr_srcptr b;
+ mpfr_srcptr c;
+ unsigned char rnd_mode;
+#endif
+{
+ int diff_exp;
+
+ if (FLAG_NAN(b) || FLAG_NAN(c)) { SET_NAN(a); return; }
+
+ if (!NOTZERO(b)) { mpfr_neg(a, c, rnd_mode); return; }
+ if (!NOTZERO(c)) { mpfr_set(a, b, rnd_mode); return; }
+
+ diff_exp = EXP(b)-EXP(c);
+ if (SIGN(b) == SIGN(c)) { /* signs are equal, it's a real subtraction */
+ if (diff_exp<0) {
+ /* exchange rounding modes towards +/- infinity */
+ if (rnd_mode==GMP_RNDU) rnd_mode=GMP_RNDD;
+ else if (rnd_mode==GMP_RNDD) rnd_mode=GMP_RNDU;
+ mpfr_sub1(a, c, b, rnd_mode, -diff_exp);
+ CHANGE_SIGN(a);
+ }
+ else if (diff_exp>0) mpfr_sub1(a, b, c, rnd_mode, diff_exp);
+ else { /* diff_exp=0 */
+ diff_exp = mpfr_cmp3(b,c,1);
+ /* if b>0 and diff_exp>0 or b<0 and diff_exp<0: abs(b) > abs(c) */
+ if (diff_exp==0) SET_ZERO(a);
+ else if (diff_exp*SIGN(b)>0) mpfr_sub1(a, b, c, rnd_mode, 0);
+ else {
+ /* exchange rounding modes towards +/- infinity */
+ if (rnd_mode==GMP_RNDU) rnd_mode=GMP_RNDD;
+ else if (rnd_mode==GMP_RNDD) rnd_mode=GMP_RNDU;
+ mpfr_sub1(a, c, b, rnd_mode, 0);
+ CHANGE_SIGN(a);
+ }
+ }
+ }
+ else /* signs differ, it's an addition */
+ if (diff_exp<0) {
+ /* exchange rounding modes towards +/- infinity */
+ if (rnd_mode==GMP_RNDU) rnd_mode=GMP_RNDD;
+ else if (rnd_mode==GMP_RNDD) rnd_mode=GMP_RNDU;
+ mpfr_add1(a, c, b, rnd_mode, -diff_exp);
+ CHANGE_SIGN(a);
+ }
+ else mpfr_add1(a, b, c, rnd_mode, diff_exp);
+}
+
diff --git a/mpfr/tests/Makefile.am b/mpfr/tests/Makefile.am
new file mode 100644
index 000000000..c86cbf314
--- /dev/null
+++ b/mpfr/tests/Makefile.am
@@ -0,0 +1,37 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright (C) 2000 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.
+
+AUTOMAKE_OPTIONS = gnu no-dependencies
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mpfr
+LDADD = $(top_builddir)/libgmp.la
+dummy_LDADD =
+
+if WANT_MPFR
+# FIXME: The following tests need mpfr_set_machine_rnd_mode() which is not
+# built right now:
+# tadd tget_str tset_f tsqrt tagm tmul tdiv tlog texp tdiv_ui tout_str
+MPBSD_check_OPTION = tcmp2 tmul_ui tcmp_ui tround tset_si tcmp tmul_2exp \
+ tset_d tset_str tpi tset_z tlog2 tcan_round tzeta
+endif
+
+check_PROGRAMS = dummy $(MPBSD_check_OPTION)
+TESTS = $(check_PROGRAMS)
diff --git a/mpfr/tests/Makefile.in b/mpfr/tests/Makefile.in
new file mode 100644
index 000000000..e1e655895
--- /dev/null
+++ b/mpfr/tests/Makefile.in
@@ -0,0 +1,525 @@
+# Makefile.in generated automatically by automake 1.4a from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_FLAG =
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+
+@SET_MAKE@
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMDEP = @AMDEP@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AWK = @AWK@
+CALLING_CONVENTIONS_OBJS = @CALLING_CONVENTIONS_OBJS@
+CC = @CC@
+CCAS = @CCAS@
+CPP = @CPP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+M4 = @M4@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+SPEED_CYCLECOUNTER_OBJS = @SPEED_CYCLECOUNTER_OBJS@
+STRIP = @STRIP@
+U = @U@
+VERSION = @VERSION@
+gmp_srclinks = @gmp_srclinks@
+install_sh = @install_sh@
+mpn_objects = @mpn_objects@
+mpn_objs_in_libgmp = @mpn_objs_in_libgmp@
+
+# Copyright (C) 2000 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.
+
+
+AUTOMAKE_OPTIONS = gnu no-dependencies
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mpfr
+LDADD = $(top_builddir)/libgmp.la
+dummy_LDADD =
+
+# FIXME: The following tests need mpfr_set_machine_rnd_mode() which is not
+# built right now:
+# tadd tget_str tset_f tsqrt tagm tmul tdiv tlog texp tdiv_ui tout_str
+@WANT_MPFR_TRUE@MPBSD_check_OPTION = @WANT_MPFR_TRUE@tcmp2 tmul_ui tcmp_ui tround tset_si tcmp tmul_2exp \
+@WANT_MPFR_TRUE@ tset_d tset_str tpi tset_z tlog2 tcan_round tzeta
+
+check_PROGRAMS = dummy $(MPBSD_check_OPTION)
+TESTS = $(check_PROGRAMS)
+subdir = mpfr/tests
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES =
+@WANT_MPFR_FALSE@check_PROGRAMS = dummy$(EXEEXT)
+@WANT_MPFR_TRUE@check_PROGRAMS = dummy$(EXEEXT) tcmp2$(EXEEXT) \
+@WANT_MPFR_TRUE@tmul_ui$(EXEEXT) tcmp_ui$(EXEEXT) tround$(EXEEXT) \
+@WANT_MPFR_TRUE@tset_si$(EXEEXT) tcmp$(EXEEXT) tmul_2exp$(EXEEXT) \
+@WANT_MPFR_TRUE@tset_d$(EXEEXT) tset_str$(EXEEXT) tpi$(EXEEXT) \
+@WANT_MPFR_TRUE@tset_z$(EXEEXT) tlog2$(EXEEXT) tcan_round$(EXEEXT) \
+@WANT_MPFR_TRUE@tzeta$(EXEEXT)
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+dummy_SOURCES = dummy.c
+dummy_OBJECTS = dummy.$(OBJEXT)
+dummy_DEPENDENCIES =
+dummy_LDFLAGS =
+tcan_round_SOURCES = tcan_round.c
+tcan_round_OBJECTS = tcan_round.$(OBJEXT)
+tcan_round_LDADD = $(LDADD)
+tcan_round_DEPENDENCIES = $(top_builddir)/libgmp.la
+tcan_round_LDFLAGS =
+tcmp_SOURCES = tcmp.c
+tcmp_OBJECTS = tcmp.$(OBJEXT)
+tcmp_LDADD = $(LDADD)
+tcmp_DEPENDENCIES = $(top_builddir)/libgmp.la
+tcmp_LDFLAGS =
+tcmp2_SOURCES = tcmp2.c
+tcmp2_OBJECTS = tcmp2.$(OBJEXT)
+tcmp2_LDADD = $(LDADD)
+tcmp2_DEPENDENCIES = $(top_builddir)/libgmp.la
+tcmp2_LDFLAGS =
+tcmp_ui_SOURCES = tcmp_ui.c
+tcmp_ui_OBJECTS = tcmp_ui.$(OBJEXT)
+tcmp_ui_LDADD = $(LDADD)
+tcmp_ui_DEPENDENCIES = $(top_builddir)/libgmp.la
+tcmp_ui_LDFLAGS =
+tlog2_SOURCES = tlog2.c
+tlog2_OBJECTS = tlog2.$(OBJEXT)
+tlog2_LDADD = $(LDADD)
+tlog2_DEPENDENCIES = $(top_builddir)/libgmp.la
+tlog2_LDFLAGS =
+tmul_2exp_SOURCES = tmul_2exp.c
+tmul_2exp_OBJECTS = tmul_2exp.$(OBJEXT)
+tmul_2exp_LDADD = $(LDADD)
+tmul_2exp_DEPENDENCIES = $(top_builddir)/libgmp.la
+tmul_2exp_LDFLAGS =
+tmul_ui_SOURCES = tmul_ui.c
+tmul_ui_OBJECTS = tmul_ui.$(OBJEXT)
+tmul_ui_LDADD = $(LDADD)
+tmul_ui_DEPENDENCIES = $(top_builddir)/libgmp.la
+tmul_ui_LDFLAGS =
+tpi_SOURCES = tpi.c
+tpi_OBJECTS = tpi.$(OBJEXT)
+tpi_LDADD = $(LDADD)
+tpi_DEPENDENCIES = $(top_builddir)/libgmp.la
+tpi_LDFLAGS =
+tround_SOURCES = tround.c
+tround_OBJECTS = tround.$(OBJEXT)
+tround_LDADD = $(LDADD)
+tround_DEPENDENCIES = $(top_builddir)/libgmp.la
+tround_LDFLAGS =
+tset_d_SOURCES = tset_d.c
+tset_d_OBJECTS = tset_d.$(OBJEXT)
+tset_d_LDADD = $(LDADD)
+tset_d_DEPENDENCIES = $(top_builddir)/libgmp.la
+tset_d_LDFLAGS =
+tset_si_SOURCES = tset_si.c
+tset_si_OBJECTS = tset_si.$(OBJEXT)
+tset_si_LDADD = $(LDADD)
+tset_si_DEPENDENCIES = $(top_builddir)/libgmp.la
+tset_si_LDFLAGS =
+tset_str_SOURCES = tset_str.c
+tset_str_OBJECTS = tset_str.$(OBJEXT)
+tset_str_LDADD = $(LDADD)
+tset_str_DEPENDENCIES = $(top_builddir)/libgmp.la
+tset_str_LDFLAGS =
+tset_z_SOURCES = tset_z.c
+tset_z_OBJECTS = tset_z.$(OBJEXT)
+tset_z_LDADD = $(LDADD)
+tset_z_DEPENDENCIES = $(top_builddir)/libgmp.la
+tset_z_LDFLAGS =
+tzeta_SOURCES = tzeta.c
+tzeta_OBJECTS = tzeta.$(OBJEXT)
+tzeta_LDADD = $(LDADD)
+tzeta_DEPENDENCIES = $(top_builddir)/libgmp.la
+tzeta_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CFLAGS = @CFLAGS@
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = dummy.c tcan_round.c tcmp.c tcmp2.c tcmp_ui.c tlog2.c \
+tmul_2exp.c tmul_ui.c tpi.c tround.c tset_d.c tset_si.c tset_str.c \
+tset_z.c tzeta.c
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+depcomp =
+SOURCES = dummy.c tcan_round.c tcmp.c tcmp2.c tcmp_ui.c tlog2.c tmul_2exp.c tmul_ui.c tpi.c tround.c tset_d.c tset_si.c tset_str.c tset_z.c tzeta.c
+OBJECTS = dummy.$(OBJEXT) tcan_round.$(OBJEXT) tcmp.$(OBJEXT) tcmp2.$(OBJEXT) tcmp_ui.$(OBJEXT) tlog2.$(OBJEXT) tmul_2exp.$(OBJEXT) tmul_ui.$(OBJEXT) tpi.$(OBJEXT) tround.$(OBJEXT) tset_d.$(OBJEXT) tset_si.$(OBJEXT) tset_str.$(OBJEXT) tset_z.$(OBJEXT) tzeta.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu mpfr/tests/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+dummy$(EXEEXT): $(dummy_OBJECTS) $(dummy_DEPENDENCIES)
+ @rm -f dummy$(EXEEXT)
+ $(LINK) $(dummy_LDFLAGS) $(dummy_OBJECTS) $(dummy_LDADD) $(LIBS)
+
+tcan_round$(EXEEXT): $(tcan_round_OBJECTS) $(tcan_round_DEPENDENCIES)
+ @rm -f tcan_round$(EXEEXT)
+ $(LINK) $(tcan_round_LDFLAGS) $(tcan_round_OBJECTS) $(tcan_round_LDADD) $(LIBS)
+
+tcmp$(EXEEXT): $(tcmp_OBJECTS) $(tcmp_DEPENDENCIES)
+ @rm -f tcmp$(EXEEXT)
+ $(LINK) $(tcmp_LDFLAGS) $(tcmp_OBJECTS) $(tcmp_LDADD) $(LIBS)
+
+tcmp2$(EXEEXT): $(tcmp2_OBJECTS) $(tcmp2_DEPENDENCIES)
+ @rm -f tcmp2$(EXEEXT)
+ $(LINK) $(tcmp2_LDFLAGS) $(tcmp2_OBJECTS) $(tcmp2_LDADD) $(LIBS)
+
+tcmp_ui$(EXEEXT): $(tcmp_ui_OBJECTS) $(tcmp_ui_DEPENDENCIES)
+ @rm -f tcmp_ui$(EXEEXT)
+ $(LINK) $(tcmp_ui_LDFLAGS) $(tcmp_ui_OBJECTS) $(tcmp_ui_LDADD) $(LIBS)
+
+tlog2$(EXEEXT): $(tlog2_OBJECTS) $(tlog2_DEPENDENCIES)
+ @rm -f tlog2$(EXEEXT)
+ $(LINK) $(tlog2_LDFLAGS) $(tlog2_OBJECTS) $(tlog2_LDADD) $(LIBS)
+
+tmul_2exp$(EXEEXT): $(tmul_2exp_OBJECTS) $(tmul_2exp_DEPENDENCIES)
+ @rm -f tmul_2exp$(EXEEXT)
+ $(LINK) $(tmul_2exp_LDFLAGS) $(tmul_2exp_OBJECTS) $(tmul_2exp_LDADD) $(LIBS)
+
+tmul_ui$(EXEEXT): $(tmul_ui_OBJECTS) $(tmul_ui_DEPENDENCIES)
+ @rm -f tmul_ui$(EXEEXT)
+ $(LINK) $(tmul_ui_LDFLAGS) $(tmul_ui_OBJECTS) $(tmul_ui_LDADD) $(LIBS)
+
+tpi$(EXEEXT): $(tpi_OBJECTS) $(tpi_DEPENDENCIES)
+ @rm -f tpi$(EXEEXT)
+ $(LINK) $(tpi_LDFLAGS) $(tpi_OBJECTS) $(tpi_LDADD) $(LIBS)
+
+tround$(EXEEXT): $(tround_OBJECTS) $(tround_DEPENDENCIES)
+ @rm -f tround$(EXEEXT)
+ $(LINK) $(tround_LDFLAGS) $(tround_OBJECTS) $(tround_LDADD) $(LIBS)
+
+tset_d$(EXEEXT): $(tset_d_OBJECTS) $(tset_d_DEPENDENCIES)
+ @rm -f tset_d$(EXEEXT)
+ $(LINK) $(tset_d_LDFLAGS) $(tset_d_OBJECTS) $(tset_d_LDADD) $(LIBS)
+
+tset_si$(EXEEXT): $(tset_si_OBJECTS) $(tset_si_DEPENDENCIES)
+ @rm -f tset_si$(EXEEXT)
+ $(LINK) $(tset_si_LDFLAGS) $(tset_si_OBJECTS) $(tset_si_LDADD) $(LIBS)
+
+tset_str$(EXEEXT): $(tset_str_OBJECTS) $(tset_str_DEPENDENCIES)
+ @rm -f tset_str$(EXEEXT)
+ $(LINK) $(tset_str_LDFLAGS) $(tset_str_OBJECTS) $(tset_str_LDADD) $(LIBS)
+
+tset_z$(EXEEXT): $(tset_z_OBJECTS) $(tset_z_DEPENDENCIES)
+ @rm -f tset_z$(EXEEXT)
+ $(LINK) $(tset_z_LDFLAGS) $(tset_z_OBJECTS) $(tset_z_LDADD) $(LIBS)
+
+tzeta$(EXEEXT): $(tzeta_OBJECTS) $(tzeta_DEPENDENCIES)
+ @rm -f tzeta$(EXEEXT)
+ $(LINK) $(tzeta_LDFLAGS) $(tzeta_OBJECTS) $(tzeta_LDADD) $(LIBS)
+.c.o:
+ $(COMPILE) -c $<
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir); \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; \
+ srcdir=$(srcdir); export srcdir; \
+ for tst in $(TESTS); do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *" $$tst "*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *" $$tst "*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ fi; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -rm -f Makefile.in
+mostlyclean-am: mostlyclean-checkPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-checkPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-checkPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-checkPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-checkPROGRAMS distclean-checkPROGRAMS \
+clean-checkPROGRAMS maintainer-clean-checkPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir check-TESTS info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all install-strip \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/mpfr/tests/dummy.c b/mpfr/tests/dummy.c
new file mode 100644
index 000000000..fd8c4d3c5
--- /dev/null
+++ b/mpfr/tests/dummy.c
@@ -0,0 +1,28 @@
+/* A dummy do-nothing test program, which always passes. */
+
+/*
+Copyright (C) 2000 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.
+*/
+
+int
+main ()
+{
+ exit (0);
+}
diff --git a/mpfr/tests/tadd.c b/mpfr/tests/tadd.c
new file mode 100644
index 000000000..517edb9e4
--- /dev/null
+++ b/mpfr/tests/tadd.c
@@ -0,0 +1,414 @@
+/* Test file for mpfr_add and mpfr_sub.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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. */
+
+/* #define DEBUG */
+/* #define VERBOSE */
+
+#define N 100000
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#ifdef IRIX64
+#include <sys/fpu.h>
+#endif
+
+extern int isnan();
+extern int getpid();
+
+#define ABS(x) (((x)>0) ? (x) : (-x))
+
+/* checks that x+y gives the same results in double
+ and with mpfr with 53 bits of precision */
+void check(double x, double y, unsigned int rnd_mode, unsigned int px,
+unsigned int py, unsigned int pz, double res)
+{
+ double z1,z2; mpfr_t xx,yy,zz;
+
+ mpfr_init2(xx, px);
+ mpfr_init2(yy, py);
+ mpfr_init2(zz, pz);
+ mpfr_set_d(xx, x, rnd_mode);
+ mpfr_set_d(yy, y, rnd_mode);
+ mpfr_add(zz, xx, yy, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z1 = (res==0.0) ? x+y : res;
+ z2 = mpfr_get_d(zz);
+ if (px==53 && py==53 && pz==53) res=1.0;
+ if (res!=0.0 && z1!=z2 && !(isnan(z1) && isnan(z2))) {
+ printf("expected sum is %1.20e, got %1.20e\n",z1,z2);
+ printf("mpfr_add failed for x=%1.20e y=%1.20e with rnd_mode=%u\n",x,y,rnd_mode);
+ exit(1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
+}
+
+/* idem than check for mpfr_add(x, x, y) */
+void check3(double x, double y, unsigned int rnd_mode)
+{
+ double z1,z2; mpfr_t xx,yy; int neg;
+
+ neg = rand() % 2;
+ mpfr_init2(xx, 53);
+ mpfr_init2(yy, 53);
+ mpfr_set_d(xx, x, rnd_mode);
+ mpfr_set_d(yy, y, rnd_mode);
+ if (neg) mpfr_sub(xx, xx, yy, rnd_mode);
+ else mpfr_add(xx, xx, yy, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z1 = (neg) ? x-y : x+y;
+ z2 = mpfr_get_d(xx);
+ if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
+ printf("expected result is %1.20e, got %1.20e\n",z1,z2);
+ printf("mpfr_%s(x,x,y) failed for x=%1.20e y=%1.20e with rnd_mode=%u\n",
+ (neg) ? "sub" : "add",x,y,rnd_mode);
+ exit(1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy);
+}
+
+/* idem than check for mpfr_add(x, y, x) */
+void check4(double x, double y, unsigned int rnd_mode)
+{
+ double z1,z2; mpfr_t xx,yy; int neg;
+
+ neg = rand() % 2;
+ mpfr_init2(xx, 53);
+ mpfr_init2(yy, 53);
+ mpfr_set_d(xx, x, rnd_mode);
+ mpfr_set_d(yy, y, rnd_mode);
+ if (neg) mpfr_sub(xx, yy, xx, rnd_mode);
+ else mpfr_add(xx, yy, xx, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z1 = (neg) ? y-x : x+y;
+ z2 = mpfr_get_d(xx);
+ if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
+ printf("expected result is %1.20e, got %1.20e\n",z1,z2);
+ printf("mpfr_%s(x,y,x) failed for x=%1.20e y=%1.20e with rnd_mode=%u\n",
+ (neg) ? "sub" : "add",x,y,rnd_mode);
+ exit(1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy);
+}
+
+/* idem than check for mpfr_add(x, x, x) */
+void check5(double x, unsigned int rnd_mode)
+{
+ double z1,z2; mpfr_t xx; int neg;
+
+ mpfr_init2(xx, 53); neg = rand() % 2;
+ mpfr_set_d(xx, x, rnd_mode);
+ if (neg) mpfr_sub(xx, xx, xx, rnd_mode);
+ else mpfr_add(xx, xx, xx, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z1 = (neg) ? x-x : x+x;
+ z2 = mpfr_get_d(xx);
+ if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
+ printf("expected result is %1.20e, got %1.20e\n",z1,z2);
+ printf("mpfr_%s(x,x,x) failed for x=%1.20e with rnd_mode=%u\n",
+ (neg) ? "sub" : "add",x,rnd_mode);
+ exit(1);
+ }
+ mpfr_clear(xx);
+}
+
+void check2(x,px,y,py,pz,rnd_mode) double x,y; int px,py,pz,rnd_mode;
+{
+ mpfr_t xx, yy, zz; double z,z2; int u;
+
+#ifdef DEBUG
+printf("x=%1.20e,%d y=%1.20e,%d pz=%d,rnd=%d\n",x,px,y,py,pz,rnd_mode);
+#endif
+ mpfr_init2(xx,px); mpfr_init2(yy,py); mpfr_init2(zz,pz);
+ mpfr_set_d(xx, x, rnd_mode);
+ mpfr_set_d(yy, y, rnd_mode);
+ mpfr_add(zz, xx, yy, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z = x+y; z2=mpfr_get_d(zz); u=ulp(z,z2);
+#ifdef DEBUG
+ printf("x+y=%1.20e,%d (%d ulp) rnd_mode=%d\n",z2,pz,u,rnd_mode);
+ mpfr_set_d(zz, z2, rnd_mode);
+ printf("i.e."); mpfr_print_raw(zz); putchar('\n');
+#endif
+ /* one ulp difference is possible due to composed rounding */
+ if (px>=53 && py>=53 && pz>=53 && ABS(u)>1) {
+ printf("x=%1.20e,%d y=%1.20e,%d pz=%d,rnd=%d\n",x,px,y,py,pz,rnd_mode);
+ printf("got %1.20e\n",z2);
+ printf("result should be %1.20e (diff=%d ulp)\n",z,u);
+ mpfr_set_d(zz, z, rnd_mode);
+ printf("i.e."); mpfr_print_raw(zz); putchar('\n');
+ exit(1); }
+ mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
+}
+
+void check64()
+{
+ mpfr_t x, t, u;
+
+ mpfr_init(x); mpfr_init(t); mpfr_init(u);
+ mpfr_set_prec(x, 53); mpfr_set_prec(t, 76); mpfr_set_prec(u, 76);
+ mpfr_set_str_raw(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
+ mpfr_set_str_raw(t, "-0.1011000101110010000101111111011111010001110011110111100110101011110010011111");
+ mpfr_sub(u, x, t, GMP_RNDU);
+ mpfr_set_str_raw(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100");
+ if (mpfr_cmp(u,t)) {
+ printf("expect "); mpfr_print_raw(t); putchar('\n');
+ fprintf(stderr, "mpfr_add failed for precisions 53-76\n"); exit(1);
+ }
+ mpfr_set_prec(x, 53); mpfr_set_prec(t, 108); mpfr_set_prec(u, 108);
+ mpfr_set_str_raw(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
+ mpfr_set_str_raw(t, "-0.101100010111001000010111111101111101000111001111011110011010101111001001111000111011001110011000000000111111");
+ mpfr_sub(u, x, t, GMP_RNDU);
+ mpfr_set_str_raw(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111");
+ if (mpfr_cmp(u,t)) {
+ printf("expect "); mpfr_print_raw(t); putchar('\n');
+ fprintf(stderr, "mpfr_add failed for precisions 53-108\n"); exit(1);
+ }
+ mpfr_set_prec(x, 97); mpfr_set_prec(t, 97); mpfr_set_prec(u, 97);
+ mpfr_set_str_raw(x, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010000000000000000E-39");
+ mpfr_set_ui(t, 1, GMP_RNDN);
+ mpfr_add(u, x, t, GMP_RNDN);
+ mpfr_set_str_raw(x, "0.1000000000000000000000000000000000000000111110110000100000000101100011011110100000101111100010001E1");
+ if (mpfr_cmp(u,x)) {
+ fprintf(stderr, "mpfr_add failed for precision 97\n"); exit(1);
+ }
+ mpfr_set_prec(x, 128); mpfr_set_prec(t, 128); mpfr_set_prec(u, 128);
+ mpfr_set_str_raw(x, "0.10101011111001001010111011001000101100111101000000111111111011010100001100011101010001010111111101111010100110111111100101100010E-4");
+ mpfr_set(t, x, GMP_RNDN);
+ mpfr_sub(u, x, t, GMP_RNDN);
+ mpfr_set_prec(x, 96); mpfr_set_prec(t, 96); mpfr_set_prec(u, 96);
+ mpfr_set_str_raw(x, "0.111000000001110100111100110101101001001010010011010011100111100011010100011001010011011011000010E-4");
+ mpfr_set(t, x, GMP_RNDN);
+ mpfr_sub(u, x, t, GMP_RNDN);
+ mpfr_set_prec(x, 85); mpfr_set_prec(t, 85); mpfr_set_prec(u, 85);
+ mpfr_set_str_raw(x, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
+ mpfr_set_str_raw(t, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
+ mpfr_sub(u, x, t, GMP_RNDU);
+ mpfr_sub(x, x, t, GMP_RNDU);
+ if (mpfr_cmp(x, u) != 0) {
+ printf("Error in mpfr_sub: u=x-t and x=x-t give different results\n");
+ exit(1);
+ }
+ if ((MANT(u)[(PREC(u)-1)/mp_bits_per_limb] &
+ ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) {
+ printf("Error in mpfr_sub: result is not msb-normalized\n"); exit(1);
+ }
+ mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65);
+ mpfr_set_str_raw(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
+ mpfr_set_str_raw(t, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
+ mpfr_sub(u, x, t, GMP_RNDU);
+ if (mpfr_get_d(u) != 9.4349060620538533806e167) { /* 2^558 */
+ printf("Error (1) in mpfr_sub\n"); exit(1);
+ }
+ mpfr_set_prec(x, 64); mpfr_set_prec(t, 64); mpfr_set_prec(u, 64);
+ mpfr_set_str_raw(x, "0.1000011110101111011110111111000011101011101111101101101100000100E-220");
+ mpfr_set_str_raw(t, "0.1000011110101111011110111111000011101011101111101101010011111101E-220");
+ mpfr_add(u, x, t, GMP_RNDU);
+ if ((MANT(u)[0] & 1) != 1) {
+ printf("error in mpfr_add with rnd_mode=GMP_RNDU\n");
+ printf("b= "); mpfr_print_raw(x); putchar('\n');
+ printf("c= "); mpfr_print_raw(t); putchar('\n');
+ printf("b+c="); mpfr_print_raw(u); putchar('\n');
+ exit(1);
+ }
+ mpfr_clear(x); mpfr_clear(t); mpfr_clear(u);
+}
+
+/* checks when source and destination are equal */
+void check_same()
+{
+ mpfr_t x;
+
+ mpfr_init(x); mpfr_set_d(x, 1.0, GMP_RNDZ);
+ mpfr_add(x, x, x, GMP_RNDZ);
+ if (mpfr_get_d(x) != 2.0) {
+ printf("Error when all 3 operands are equal\n"); exit(1);
+ }
+ mpfr_clear(x);
+}
+
+int main(argc,argv) int argc; char *argv[];
+{
+ double x,y; int i,prec,rnd_mode,px,py,pz,rnd;
+#ifdef IRIX64
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+
+ check64();
+ check_same();
+ check(6.14384195492641560499e-02, -6.14384195401037683237e-02,
+ GMP_RNDU, 53, 53, 53, 0.0);
+ check(1.16809465359248765399e+196, 7.92883212101990665259e+196,
+ GMP_RNDU, 53, 53, 53, 0.0);
+ check(3.14553393112021279444e-67, 3.14553401015952024126e-67,
+ GMP_RNDU, 53, 53, 53, 0.0);
+#ifdef VERBOSE
+ printf("Checking random precisions\n");
+#endif
+ srand(getpid());
+ check2(5.43885304644369509058e+185,53,-1.87427265794105342763e-57,53,53,0);
+ check2(5.43885304644369509058e+185,53,-1.87427265794105342763e-57,53,53,1);
+ check2(5.43885304644369509058e+185,53,-1.87427265794105342763e-57,53,53,2);
+ check2(5.43885304644369509058e+185,53,-1.87427265794105342763e-57,53,53,3);
+ check2(2.26531902208967707071e+168,99,-2.67795218510613988524e+168,67,94,2);
+ check2(-1.21510626304662318398e+145,70,1.21367733647758957118e+145,65,61,3);
+ check2(2.73028857032080744543e+155,83,-1.16446121423113355603e+163,59,125,1);
+ check2(-4.38589520019641698848e+78,155,-1.09923643769309483415e+72,15,159,3);
+ check2(-1.49963910666191123860e+265,76,-2.30915090591874527520e-191,8,75,1);
+ check2(5.17945380930936917508e+112,119,1.11369077158813567738e+108,15,150,1);
+ check2(-2.66910493504493276454e-52,117,1.61188644159592323415e-52,61,68,1);
+ check2(-1.87427265794105342764e-57,175,1.76570844587489516446e+190,2,115,1);
+ check2(6.85523243386777784171e+107,187,-2.78148588123699111146e+48,87,178,3);
+ check2(-1.15706375390780417299e-135,94,-1.07455137477117851576e-129,66,111,2);
+ check2(-1.15706375390780417299e-135,94,-1.07455137477117851576e-129,66,111,3);
+ check2(-3.31624349995221499866e-22,107,-8.20150212714204839621e+156,79,99,3);
+ check2(-1.15706375390780417299e-135,94,-1.07455137477117851576e-129,66,111,3);
+ check2(-1.08007920352320089721e+150,63,1.77607317509426332389e+73,64,64,0);
+ check2(4.49465557237618783128e+53,108,-2.45103927353799477871e+48,60,105,0);
+ check2(3.25471707846623300604e-160,81,-7.93846654265839958715e-274,58,54,0);
+ check2(-8.88471912490080158206e+253,79,-7.84488427404526918825e+124,95,53,3);
+ check2(-2.18548638152863831959e-125,61,-1.22788940592412363564e+226,71,54,0);
+ check2(-7.94156823309993162569e+77,74,-5.26820160805275124882e+80,99,101,3);
+ check2(-3.85170653452493859064e+189,62,2.18827389706660314090e+158,94,106,3);
+ check2(1.07966151149311101950e+46,88,1.13198076934147457400e+46,67,53,0);
+ check2(3.36768223223409657622e+209,55,-9.61624007357265441884e+219,113,53,0);
+ check2(-6.47376909368979326475e+159,111,5.11127211034490340501e+159,99,62,3);
+ check2(-4.95229483271607845549e+220,110,-6.06992115033276044773e+213,109,55,0);
+ check2(-6.47376909368979326475e+159,74,5.11127211034490340501e+159,111,75,2);
+ check2(2.26531902208967707070e+168,99,-2.67795218510613988525e+168,67,94,2);
+ check2(-2.28886326552077479586e-188,67,3.41419438647157839320e-177,60,110,2);
+ check2(-2.66910493504493276454e-52,117,1.61188644159592323415e-52,61,68,1);
+ check2(2.90983392714730768886e+50,101,2.31299792168440591870e+50,74,105,1);
+ check2(2.72046257722708717791e+243,97,-1.62158447436486437113e+243,83,96,0);
+ for (i=0;i<N;i++) {
+#ifdef DEBUG
+printf("\nTest i=%d\n",i);
+#endif
+ px = 53 + (rand() % 64);
+ py = 53 + (rand() % 64);
+ pz = 53 + (rand() % 64);
+ rnd_mode = rand() % 4;
+ do { x = drand(); } while (isnan(x));
+ do { y = drand(); } while (isnan(y));
+ check2(x,px,y,py,pz,rnd_mode);
+ }
+#ifdef VERBOSE
+ printf("Checking double precision (53 bits)\n");
+#endif
+ prec = (argc<2) ? 53 : atoi(argv[1]);
+ rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
+ check(-8.22183238641455905806e-19, 7.42227178769761587878e-19,
+ GMP_RNDD, 53, 53, 53, 0.0);
+ check(5.82106394662028628236e+234, -5.21514064202368477230e+89,
+ GMP_RNDD, 53, 53, 53, 0.0);
+ check(5.72931679569871602371e+122, -5.72886070363264321230e+122,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(-5.09937369394650450820e+238, 2.70203299854862982387e+250,
+ GMP_RNDD, 53, 53, 53, 0.0);
+ check(-2.96695924472363684394e+27, 1.22842938251111500000e+16,
+ GMP_RNDD, 53, 53, 53, 0.0);
+ check(1.74693641655743793422e-227, -7.71776956366861843469e-229,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(-1.03432206392780011159e-125, 1.30127034799251347548e-133,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(1.05824655795525779205e+71, -1.06022698059744327881e+71,
+ GMP_RNDZ, 53, 53, 53, 0.0);
+ check(-5.84204911040921732219e+240, 7.26658169050749590763e+240,
+ GMP_RNDD, 53, 53, 53, 0.0);
+ /* the following check double overflow */
+ /* check(6.27557402141211962228e+307, 1.32141396570101687757e+308,
+ GMP_RNDZ, 53, 53, 53, 0.0); */
+ check(1.00944884131046636376e+221, 2.33809162651471520268e+215,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(4.29232078932667367325e-278, 1.07735250473897938332e-281,
+ GMP_RNDU, 53, 53, 53, 0.0);
+ check(5.27584773801377058681e-80, 8.91207657803547196421e-91,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(2.99280481918991653800e+272, 5.34637717585790933424e+271,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(4.67302514390488041733e-184, 2.18321376145645689945e-190,
+ GMP_RNDN, 53, 53, 53, 0.0);
+ check(5.57294120336300389254e+71, 2.60596167942024924040e+65,
+ GMP_RNDZ, 53, 53, 53, 0.0);
+ x=6151626677899716.0; for (i=0;i<30;i++) x = 2.0*x;
+ check(x, 4938448004894539.0, GMP_RNDU, 53, 53, 53, 0.0);
+ check(1.23056185051606761523e-190, 1.64589756643433857138e-181,
+ GMP_RNDU, 53, 53, 53, 0.0);
+ check(2.93231171510175981584e-280, 3.26266919161341483877e-273,
+ GMP_RNDU, 53, 53, 53, 0.0);
+ check(5.76707395945001907217e-58, 4.74752971449827687074e-51,
+ GMP_RNDD, 53, 53, 53, 0.0);
+ check(277363943109.0, 11.0, GMP_RNDN, 53, 53, 53, 0.0);
+ /* test denormalized numbers too */
+ check(8.06294740693074521573e-310, 6.95250701071929654575e-310,
+ GMP_RNDU, 53, 53, 53, 0.0);
+#ifdef VERBOSE
+ printf("Comparing to double precision using machine arithmetic\n");
+#endif
+ for (i=0;i<N;i++) {
+ x = drand();
+ y = drand();
+ if (ABS(x)>2.2e-307 && ABS(y)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308)
+ /* avoid denormalized numbers and overflows */
+ rnd = (rnd_mode==-1) ? lrand48()%4 : rnd_mode;
+ check(x, y, rnd, prec, prec, prec, 0.0);
+ }
+#ifdef VERBOSE
+ printf("Checking mpfr_add(x, x, y) with prec=53\n");
+#endif
+ for (i=0;i<N;i++) {
+ x = drand();
+ y = drand();
+ if (ABS(x)>2.2e-307 && ABS(y)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308)
+ /* avoid denormalized numbers and overflows */
+ rnd = (rnd_mode==-1) ? lrand48()%4 : rnd_mode;
+ check3(x, y, rnd);
+ }
+#ifdef VERBOSE
+ printf("Checking mpfr_add(x, y, x) with prec=53\n");
+#endif
+ for (i=0;i<N;i++) {
+ x = drand();
+ y = drand();
+ if (ABS(x)>2.2e-307 && ABS(y)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308)
+ /* avoid denormalized numbers and overflows */
+ rnd = (rnd_mode==-1) ? lrand48()%4 : rnd_mode;
+ check4(x, y, rnd);
+ }
+#ifdef VERBOSE
+ printf("Checking mpfr_add(x, x, x) with prec=53\n");
+#endif
+ for (i=0;i<N;i++) {
+ do { x = drand(); } while ((ABS(x)<2.2e-307) || (ABS(x)>0.8e308));
+ /* avoid denormalized numbers and overflows */
+ rnd = (rnd_mode==-1) ? lrand48()%4 : rnd_mode;
+ check5(x, rnd);
+ }
+ exit (0);
+}
+
diff --git a/mpfr/tests/tagm.c b/mpfr/tests/tagm.c
new file mode 100644
index 000000000..1782911f2
--- /dev/null
+++ b/mpfr/tests/tagm.c
@@ -0,0 +1,185 @@
+/* Test file for mpfr_agm.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+extern int isnan();
+
+double drand_agm()
+{
+ double d; long int *i;
+
+ i = (long int*) &d;
+ do {
+ i[0] = lrand48();
+ i[1] = lrand48();
+ /*if (lrand48()%2) d=-d; */ /* generates negative numbers */
+ /* useless here */
+ } while ((d<1e-153)||(d>1e153)); /* to avoid underflow or overflow
+ in double calculus in sqrt(u*v) */
+
+ return d;
+}
+
+
+double max(double a,double b) {
+ if (a>=b)
+ return a;
+ return b;
+}
+
+double min(double a,double b) {
+ if (b>=a)
+ return a;
+ return b;
+}
+
+double dagm(double a, double b) {
+ double u,v,tmpu,tmpv;
+
+ if ((isnan(a))||(isnan(b)))
+ return a+b;
+
+ tmpv=max(a,b);
+ tmpu=min(a,b);
+
+ do
+ {
+ u=tmpu;
+ v=tmpv;
+ tmpu=sqrt(u*v);
+ tmpv=(u+v)/2.0;
+ }
+ while (!(((tmpu==u)&&(tmpv==v))||(ulp(u,v)==0)));
+
+ /* printf("difference : %i ulp\n",ulp(u,v)); */
+ return u;
+}
+
+#define check(a,b,r) check4(a,b,r,0.0)
+
+void check4(double a, double b, unsigned char rnd_mode, double res1)
+{
+ mpfr_t ta, tb, tres;
+ double res2;
+ int ck=0;
+
+ mpfr_init2(ta, 53);
+ mpfr_init2(tb, 53);
+ mpfr_init2(tres, 53);
+
+ mpfr_set_d(ta, a, rnd_mode);
+ mpfr_set_d(tb, b, rnd_mode);
+
+ mpfr_agm(tres, ta, tb, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+
+ if (res1==0.0) res1=dagm(a,b); else ck=1;
+ res2 = mpfr_get_d(tres);
+
+ if (ck && res1!=res2 && (!isnan(res1) || !isnan(res2))) {
+ printf("mpfr_agm failed for a=%1.20e, b=%1.20e, rnd_mode=%d\n",a,b,rnd_mode);
+ printf("expected result is %1.20e, got %1.20e (%d ulp)\n",res1,res2,
+ ulp(res2,res1));
+ /*exit(1);*/
+ }
+ mpfr_clear(ta); mpfr_clear(tb); mpfr_clear(tres);
+}
+
+void check_large()
+{
+ mpfr_t a, b, agm;
+
+ mpfr_init2(a, 82); mpfr_init2(b, 82); mpfr_init2(agm, 82);
+ mpfr_set_ui(a, 1, GMP_RNDN);
+ mpfr_set_str_raw(b, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010E-39");
+ mpfr_agm(agm, a, b, GMP_RNDN);
+ mpfr_set_str_raw(a, "0.1110001000111101101010101010101101001010001001001011100101111011110101111001111100E-4");
+ if (mpfr_cmp(agm, a)) {
+ fprintf(stderr, "mpfr_agm failed for precision 82\n"); exit(1);
+ }
+ mpfr_clear(a); mpfr_clear(b); mpfr_clear(agm);
+}
+
+void slave(int N, int p) {
+ int i;
+ double a,b;
+ mpfr_t ta, tb, tres;
+
+ srand48(getpid());
+ mpfr_init2(ta, 53);
+ mpfr_init2(tb, 53);
+ mpfr_init2(tres, p);
+ for(i=0;i<N;i++) {
+ a=drand_agm();
+ b=drand_agm();
+ mpfr_set_d(ta, a, GMP_RNDN);
+ mpfr_set_d(tb, b, GMP_RNDN);
+ mpfr_agm(tres, ta, tb, rand() % 4 );
+ }
+ mpfr_clear(ta); mpfr_clear(ta); mpfr_clear(tres);
+ printf("fin\n");
+}
+
+
+int main(int argc, char* argv[]) {
+ int N;
+
+ if (argc==3) { /* tagm N p : N calculus with precision p*/
+ printf("Doing %d random tests in %d precision\n",atoi(argv[1]),atoi(argv[2]));
+ slave(atoi(argv[1]),atoi(argv[2]));
+ exit (0);
+ }
+
+ if (argc==2) { /* tagm N: N tests with random double's */
+ int i;
+ double a,b;
+
+ srand48(getpid());
+ N = atoi(argv[1]);
+ for (i=0;i<N;i++) {
+ a = drand();
+ b = drand();
+ check(a, b, rand() % 4);
+ }
+ exit (0);
+ }
+ else {
+ check_large();
+ check(2,1,GMP_RNDN);
+ check(6,4,GMP_RNDN);
+ check(62,61,GMP_RNDN);
+ check(0.5,1,GMP_RNDN);
+ check(1,2,GMP_RNDN);
+ check4(234375765,234375000,GMP_RNDN,2.34375382499843955040e+08);
+ check(8,1,GMP_RNDU);
+ check(1,44,GMP_RNDU);
+ check(1,3.725290298461914062500000e-9,GMP_RNDU);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/tcan_round.c b/mpfr/tests/tcan_round.c
new file mode 100644
index 000000000..7e452ab80
--- /dev/null
+++ b/mpfr/tests/tcan_round.c
@@ -0,0 +1,40 @@
+/* Test file for mpfr_can_round.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+int main()
+{
+ mpfr_t x;
+
+ /* checks that rounds to nearest sets the last
+ bit to zero in case of equal distance */
+ mpfr_init2(x, 59);
+ mpfr_set_str_raw(x, "-0.10010001010111000011110010111010111110000000111101100111111E663");
+ if (mpfr_can_round(x, 54, GMP_RNDZ, GMP_RNDZ, 53) != 0) {
+ fprintf(stderr, "Error in mpfr_can_round\n"); exit(1);
+ }
+ mpfr_clear(x);
+ exit (0);
+}
diff --git a/mpfr/tests/tcmp.c b/mpfr/tests/tcmp.c
new file mode 100644
index 000000000..0f063c235
--- /dev/null
+++ b/mpfr/tests/tcmp.c
@@ -0,0 +1,73 @@
+/* Test file for mpfr_cmp.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <math.h>
+#include "gmp.h"
+#include "longlong.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+int
+main()
+{
+ double x,y; mpfr_t xx,yy; int i,c;
+
+ fprintf(stderr, "Test case 'tcmp' disabled\n");
+ exit(0); /* THIS TEST CASE IS NOT WORKING */
+
+ mpfr_init2(xx, 65); mpfr_init2(yy, 65);
+ mpfr_set_str_raw(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
+ mpfr_set_str_raw(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
+ if (mpfr_cmp2(xx,yy)!=64) { printf("Error (1) in mpfr_cmp\n"); exit(1); }
+ mpfr_set_str_raw(xx, "0.10100010001110110111000010001000010011111101000100011101000011100");
+ mpfr_set_str_raw(yy, "0.10100010001110110111000010001000010011111101000100011101000011011");
+ if (mpfr_cmp2(xx,yy)!=64) { printf("Error (1) in mpfr_cmp\n"); exit(1); }
+ mpfr_set_prec(xx,53); mpfr_set_prec(yy,200);
+ mpfr_set_d(xx, 1.0, 0);
+ mpfr_set_d(yy, 1.0, 0);
+ if (mpfr_cmp(xx,yy)!=0) {
+ printf("Error in mpfr_cmp: 1.0 != 1.0\n"); exit(1);
+ }
+ mpfr_set_prec(yy, 31);
+ mpfr_set_d(xx, 1.0000000002, 0);
+ mpfr_set_d(yy, 1.0, 0);
+ if (!(mpfr_cmp(xx,yy)>0)) {
+ printf("Error in mpfr_cmp: not 1.0000000002 > 1.0\n"); exit(1);
+ }
+ mpfr_set_prec(yy, 53);
+ for (i=0;i<1000000;) {
+ x=drand(); y=drand();
+ if (!isnan(x) && !isnan(y)) {
+ i++;
+ mpfr_set_d(xx, x, 0);
+ mpfr_set_d(yy, y, 0);
+ c = mpfr_cmp(xx,yy);
+ if ((c>0 && x<=y) || (c==0 && x!=y) || (c<0 && x>=y)) {
+ printf("Error in mpfr_cmp with x=%1.20e, y=%1.20e mpfr_cmp(x,y)=%d\n",
+ x,y,c); exit(1);
+ }
+ }
+ }
+ mpfr_clear(xx); mpfr_clear(yy);
+ exit (0);
+}
diff --git a/mpfr/tests/tcmp2.c b/mpfr/tests/tcmp2.c
new file mode 100644
index 000000000..f7e3f3599
--- /dev/null
+++ b/mpfr/tests/tcmp2.c
@@ -0,0 +1,88 @@
+/* Test file for mpfr_cmp2.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <math.h>
+#include "gmp.h"
+#include "longlong.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#ifdef IRIX64
+#include <sys/fpu.h>
+#endif
+
+extern int isnan();
+
+void tcmp2(x, y, i) double x, y; int i;
+{
+ mpfr_t xx,yy; int j;
+
+ if (i==-1) {
+ if (x==y) i=53;
+ else i = (int) floor(log(x)/log(2.0)) - (int) floor(log(x-y)/log(2.0));
+ }
+ mpfr_init2(xx, 53); mpfr_init2(yy, 53);
+ mpfr_set_d(xx, x, 0);
+ mpfr_set_d(yy, y, 0);
+ if ((j=mpfr_cmp2(xx, yy)) != i) {
+ printf("Error in mpfr_cmp2: x=%1.20e y=%1.20e mpfr_cmp2(x,y)=%d instead of %d\n",x,y,j,i);
+ exit(1);
+ }
+ mpfr_set_prec(xx, 127); mpfr_set_prec(yy, 127);
+ mpfr_set_str_raw(xx, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6");
+ mpfr_set_str_raw(yy, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6");
+ if ((j=mpfr_cmp2(xx, yy)) != 32) {
+ printf("Error in mpfr_cmp2:\n");
+ printf("x="); mpfr_print_raw(xx); putchar('\n');
+ printf("y="); mpfr_print_raw(yy); putchar('\n');
+ printf("got %d, expected 32\n", j);
+ exit(1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy);
+}
+
+int main()
+{
+ int i,j; double x=1.0, y, z;
+#ifdef IRIX64
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+
+ tcmp2(1.06022698059744327881e+71, 1.05824655795525779205e+71, -1);
+ tcmp2(1.0, 1.0, 53);
+ for (i=0;i<54;i++) {
+ tcmp2(1.0, 1.0-x, i);
+ x /= 2.0;
+ }
+ for (j=0;j<1000000;j++) {
+ x = drand48();
+ y = drand48();
+ if (x<y) { z=x; x=y; y=z; }
+ if (y != 0.0 && y != -0.0) tcmp2(x, y, -1);
+ }
+ exit (0);
+}
+
diff --git a/mpfr/tests/tcmp_ui.c b/mpfr/tests/tcmp_ui.c
new file mode 100644
index 000000000..61410edd0
--- /dev/null
+++ b/mpfr/tests/tcmp_ui.c
@@ -0,0 +1,58 @@
+/* Test file for mpfr_cmp_ui.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <math.h>
+#include "gmp.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+int
+main()
+{
+ mpfr_t x; unsigned long i; long s;
+
+ mpfr_init(x);
+
+ mpfr_set_ui(x, 3, GMP_RNDZ);
+ if (mpfr_cmp_ui(x, i=3)!=0) {
+ printf("Error in mpfr_cmp_ui(%1.20f,%d)\n",mpfr_get_d(x), i); exit(1);
+ }
+ if (mpfr_cmp_ui(x, i=2)<=0) {
+ printf("Error in mpfr_cmp_ui(%1.20f,%d)\n",mpfr_get_d(x), i); exit(1);
+ }
+ if (mpfr_cmp_ui(x, i=4)>=0) {
+ printf("Error in mpfr_cmp_ui(%1.20f,%d)\n",mpfr_get_d(x), i); exit(1);
+ }
+
+ mpfr_set_si(x, -3, GMP_RNDZ);
+ if (mpfr_cmp_si(x, s=-3)!=0) {
+ printf("Error in mpfr_cmp_si(%1.20f,%d)\n",mpfr_get_d(x), s); exit(1);
+ }
+ if (mpfr_cmp_si(x, s=-4)<=0) {
+ printf("Error in mpfr_cmp_si(%1.20f,%d)\n",mpfr_get_d(x), s); exit(1);
+ }
+ if (mpfr_cmp_si(x, s=1)>=0) {
+ printf("Error in mpfr_cmp_si(%1.20f,%d)\n",mpfr_get_d(x), s); exit(1);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/tdiv.c b/mpfr/tests/tdiv.c
new file mode 100644
index 000000000..a7de5dde9
--- /dev/null
+++ b/mpfr/tests/tdiv.c
@@ -0,0 +1,152 @@
+/* Test file for mpfr_div.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#ifdef IRIX64
+#include <sys/fpu.h>
+#endif
+
+extern int isnan();
+
+/* #define DEBUG */
+
+#define check(n,d,r) check4(n,d,r,53)
+
+void check4(N, D, rnd_mode, p) double N, D; unsigned char rnd_mode; int p;
+{
+ mpfr_t q, n, d; double Q,Q2;
+
+#ifdef DEBUG
+ printf("N=%1.20e D=%1.20e rnd_mode=%d\n",N,D,rnd_mode);
+#endif
+ mpfr_init2(q, p); mpfr_init2(n, p); mpfr_init2(d, p);
+ mpfr_set_d(n, N, rnd_mode);
+ mpfr_set_d(d, D, rnd_mode);
+ mpfr_div(q, n, d, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ Q = N/D;
+ Q2 = mpfr_get_d(q);
+#ifdef DEBUG
+ printf("expected quotient is %1.20e, got %1.20e (%d ulp)\n",Q,Q2,
+ ulp(Q2,Q));
+ mpfr_print_raw(q); putchar('\n');
+#endif
+ if (Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
+ printf("mpfr_div failed for n=%1.20e, d=%1.20e, rnd_mode=%d\n",N,D,rnd_mode);
+ printf("expected quotient is %1.20e, got %1.20e (%d ulp)\n",Q,Q2,
+ ulp(Q2,Q));
+ exit(1);
+ }
+ mpfr_clear(q); mpfr_clear(n); mpfr_clear(d);
+}
+
+void check24(float N, float D, unsigned char rnd_mode)
+{
+ mpfr_t q, n, d; float Q,Q2;
+
+ mpfr_init2(q, 24); mpfr_init2(n, 24); mpfr_init2(d, 24);
+ mpfr_set_d(n, N, rnd_mode);
+ mpfr_set_d(d, D, rnd_mode);
+ mpfr_div(q, n, d, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ Q = N/D;
+ Q2 = mpfr_get_d(q);
+ if (Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
+ printf("mpfr_div failed for n=%1.10e, d=%1.10e, prec=24, rnd_mode=%d\n",N,D,rnd_mode);
+ printf("expected quotient is %1.10e, got %1.10e\n",Q,Q2);
+ exit(1);
+ }
+ mpfr_clear(q); mpfr_clear(n); mpfr_clear(d);
+}
+
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 2 */
+void check_float()
+{
+ int i; float b=8388608.0; /* 2^23 */
+
+ for (i=0;i<4;i++) {
+ check24(b*8388610.0, 8388609.0, i);
+ check24(b*16777215.0, 16777213.0, i);
+ check24(b*8388612.0, 8388611.0, i);
+ check24(b*12582914.0, 12582911.0, i);
+ check24(12582913.0, 12582910.0, i);
+ check24(b*16777215.0, 8388609.0, i);
+ check24(b*8388612.0, 8388609.0, i);
+ check24(b*12582914.0, 8388610.0, i);
+ check24(b*12582913.0, 8388610.0, i);
+ }
+}
+
+void check_convergence()
+{
+ mpfr_t x, y;
+
+ mpfr_init2(x, 130);
+ mpfr_set_str_raw(x, "0.1011111101011010101000001010011111101000011100011101010011111011000011001010000000111100100111110011001010110100100001001000111001E6944");
+ mpfr_init_set_ui(y, 5, 130, GMP_RNDN);
+ mpfr_div(x, x, y, GMP_RNDD); /* exact division */
+ mpfr_clear(x); mpfr_clear(y);
+}
+
+int main(int argc, char *argv[])
+{
+ int i, N; double n, d, e;
+#ifdef IRIX64
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+
+ N = (argc>1) ? atoi(argv[1]) : 100000;
+ check_float(); /* checks single precision */
+ check_convergence();
+ check(0.0, 1.0, 1);
+ check(-7.49889692246885910000e+63, 4.88168664502887320000e+306, GMP_RNDD);
+ check(-1.33225773037748601769e+199, 3.63449540676937123913e+79, GMP_RNDZ);
+ d = 1.0; for (i=0;i<52;i++) d *= 2.0;
+ check4(4.0, d, GMP_RNDZ, 62);
+ check4(1.0, 2.10263340267725788209e+187, 2, 65);
+ check4(2.44394909079968374564e-150, 2.10263340267725788209e+187, 2, 65);
+ /* the following tests when d is an exact power of two */
+ check(9.89438396044940256501e-134, 5.93472984109987421717e-67, 2);
+ check(9.89438396044940256501e-134, -5.93472984109987421717e-67, 2);
+ check(-4.53063926135729747564e-308, 7.02293374921793516813e-84, 3);
+ check(6.25089225176473806123e-01, -2.35527154824420243364e-230, 3);
+ check(6.52308934689126000000e+15, -1.62063546601505417497e+273, 0);
+ check(1.04636807108079349236e-189, 3.72295730823253012954e-292, 1);
+ srand48(getpid());
+ for (i=0;i<N;i++) {
+ do { n = drand(); d = drand(); e = fabs(n)/fabs(d); }
+ /* smallest normalized is 2^(-1022), largest is 2^(1023)*(2-2^(-52)) */
+ while (e>=1.7976931348623157081e308 || e<2.225073858507201383e-308);
+ check(n, d, rand() % 4);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/tdiv_ui.c b/mpfr/tests/tdiv_ui.c
new file mode 100644
index 000000000..bb45287af
--- /dev/null
+++ b/mpfr/tests/tdiv_ui.c
@@ -0,0 +1,68 @@
+/* Test file for mpfr_div_ui.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#include "time.h"
+
+extern int isnan(), getpid();
+
+void check(double d, unsigned long u, unsigned char rnd)
+{
+ mpfr_t x, y; double e, f;
+
+ mpfr_init2(x, 53); mpfr_init2(y, 53);
+ mpfr_set_machine_rnd_mode(rnd);
+ e = d / u;
+ mpfr_set_d(x, d, rnd);
+ mpfr_div_ui(y, x, u, rnd);
+ f = mpfr_get_d(y);
+ if (f != e && (!isnan(f) || !isnan(e))) {
+ printf("mpfr_div_ui failed for x=%1.20e, u=%lu, rnd=%d\n",d,u,rnd);
+ printf("expected result is %1.20e, got %1.20e, dif=%d ulp\n",e,f,
+ ulp(e,f));
+ exit(1);
+ }
+ mpfr_clear(x);
+}
+
+int
+main(int argc, char **argv)
+{
+ int i; unsigned long u; double d;
+
+ srand(getpid());
+ check(1.0, 3, 0);
+ check(1.0, 3, 1);
+ check(1.0, 3, 2);
+ check(1.0, 3, 3);
+ check(1.0, 2116118, 0);
+ for (i=0;i<1000000;i++) {
+ do { u = lrand48(); } while (u==0);
+ do { d = drand(); } while (fabs(d/u)<2.2e-307);
+ check(d, u, rand() % 4);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/texp.c b/mpfr/tests/texp.c
new file mode 100644
index 000000000..b23d28431
--- /dev/null
+++ b/mpfr/tests/texp.c
@@ -0,0 +1,239 @@
+/* Test file for mpfr_exp.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+
+/* #define DEBUG */
+
+extern int isnan();
+extern int getpid();
+
+int maxu=0;
+
+/* returns the number of ulp's between a and b */
+int ulp(a,b) double a,b;
+{
+ double eps=1.1102230246251565404e-16; /* 2^(-53) */
+ b = (a-b)/a; if (b<0) b = -b;
+ return (int) floor(b/eps);
+}
+
+#define check(d, r) check3(d, r, 0.0)
+
+/* returns the number of ulp of error */
+int check3(double d, unsigned char rnd, double e)
+{
+ mpfr_t x, y; double f; int u=0, ck=0;
+
+#ifdef DEBUG
+ printf("d=%1.20e rnd=%d\n",d,rnd);
+#endif
+ mpfr_init2(x, 53); mpfr_init2(y, 53);
+ mpfr_set_machine_rnd_mode(rnd);
+ if (e==0.0) e = exp(d); else ck=1; /* really check */
+ mpfr_set_d(x, d, rnd);
+ mpfr_exp(y, x, rnd);
+ f = mpfr_get_d(y);
+ if (f != e && (!isnan(f) || !isnan(e))) {
+ u = ulp(e,f);
+ if (u<0) {
+ if (u == (mp_limb_t)1<<(BITS_PER_MP_LIMB-1)) u += 1;
+ u=-u;
+ }
+ if (u!=0) {
+ if (ck) {
+ printf("mpfr_exp failed for x=%1.20e, rnd=%s\n", d,
+ mpfr_print_rnd_mode(rnd));
+ printf("expected result is %1.20e, got %1.20e, dif=%d ulp\n",e,f,u);
+ exit(1);
+ }
+ else if (u>maxu) {
+ maxu=u;
+ printf("mpfr_exp differs from libm.a for x=%1.20e, rnd=%d\n",d,rnd);
+ printf("libm.a gave %1.20e, mpfr_exp got %1.20e, dif=%d ulp\n",e,f,u);
+ }
+ }
+ }
+ mpfr_clear(x); mpfr_clear(y);
+ return u;
+}
+
+/* computes n bits of exp(d) */
+int check_large (double d, int n, char rnd)
+{
+ mpfr_t x; mpfr_t y;
+
+ mpfr_init2(x, n); mpfr_init2(y, n);
+ if (d==0.0) { /* try exp(Pi*sqrt(163)/3)-640320 */
+ mpfr_set_d(x, 163.0, rnd);
+ mpfr_sqrt(x, x, rnd);
+ mpfr_pi(y, rnd);
+ mpfr_mul(x, x, y, rnd);
+ mpfr_div_ui(x, x, 3, rnd);
+ }
+ else mpfr_set_d(x, d, rnd);
+ mpfr_exp(y, x, rnd);
+ if (d==0.0) {
+ mpfr_set_d(x, 640320.0, rnd);
+ mpfr_sub(y, y, x, rnd);
+ printf("exp(Pi*sqrt(163)/3)-640320=");
+ }
+ else printf("exp(%1.20e)=",d);
+ mpfr_out_str(stdout, 10, 0, y, rnd);
+ putchar('\n');
+ printf(" ="); mpfr_print_raw(y); putchar('\n');
+ if (n==53) printf(" =%1.20e\n", mpfr_get_d(y));
+ mpfr_clear(x); mpfr_clear(y);
+ return 0;
+}
+
+/* expx is the value of exp(X) rounded towards -infinity */
+int check_worst_case(double X, double expx)
+{
+ mpfr_t x, y;
+
+ mpfr_init2(x, 53); mpfr_init2(y, 53);
+ mpfr_set_d(x, X, GMP_RNDN);
+#ifdef DEBUG
+ printf("x="); mpfr_print_raw(x); putchar('\n');
+#endif
+ mpfr_exp(y, x, GMP_RNDD);
+#ifdef DEBUG
+ printf("D(exp(x))="); mpfr_print_raw(y); putchar('\n');
+#endif
+ if (mpfr_get_d(y) != expx) {
+ fprintf(stderr, "exp(x) rounded towards -infinity is wrong\n"); exit(1);
+ }
+ mpfr_exp(x, x, GMP_RNDN);
+#ifdef DEBUG
+ printf("N(exp(x))="); mpfr_print_raw(x); putchar('\n');
+#endif
+ mpfr_set_d(x, X, GMP_RNDN);
+ mpfr_exp(x, x, GMP_RNDU);
+#ifdef DEBUG
+ printf("U(exp(x))="); mpfr_print_raw(x); putchar('\n');
+#endif
+ mpfr_add_one_ulp(y);
+ if (mpfr_cmp(x,y)) {
+ fprintf(stderr, "exp(x) rounded towards +infinity is wrong\n"); exit(1);
+ }
+ mpfr_clear(x); mpfr_clear(y);
+ return 0;
+}
+
+/* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */
+int check_worst_cases()
+{
+ mpfr_t x;
+
+ mpfr_init2(x, 53);
+ check_worst_case(4.44089209850062517562e-16, 1.00000000000000022204);
+ check_worst_case(6.39488462184069720009e-14, 1.00000000000006372680);
+ check_worst_case(1.84741111297455401935e-12, 1.00000000000184718907);
+ check_worst_case(1.76177628026265550074e-10, 1.00000000017617751702);
+ check3(1.76177628026265550074e-10, GMP_RNDN, 1.00000000017617773906);
+ check_worst_case(7.54175277499595900852e-10, 1.00000000075417516676);
+ check3(7.54175277499595900852e-10, GMP_RNDN, 1.00000000075417538881);
+ /* bug found by Vincent Lefe`vre on December 8, 1999 */
+ check3(-5.42410311287441459172e+02, GMP_RNDN, 2.7176584868845723e-236);
+ /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */
+ check3(-1.32920285897904911589e-10, GMP_RNDN, 0.999999999867079769622);
+ check3(-1.44037948245738330735e-10, GMP_RNDN, 0.9999999998559621072757);
+ check3(-1.66795910430705305937e-10, GMP_RNDZ, 0.9999999998332040895832);
+ check3(-1.64310953745426656203e-10, GMP_RNDN, 0.9999999998356891017792);
+ check3(-1.38323574826034659172e-10, GMP_RNDZ, 0.9999999998616764251835);
+ check3(-1.23621668465115401498e-10, GMP_RNDZ, 0.9999999998763783315425);
+ mpfr_clear(x);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int i, N, s=0, e, maxe=0; double d, lo, hi;
+
+ if (argc==4) { check_large(atof(argv[1]), atoi(argv[2]), atoi(argv[3]));
+ exit(1); }
+ check_worst_cases();
+ check3(0.0, GMP_RNDU, 1.0);
+ check3(-8.88024741073346941839e-17, GMP_RNDU, 1.0);
+ check3(8.70772839244701057915e-01, GMP_RNDN, 2.38875626491680437269);
+ check3(1.0, GMP_RNDN, 2.71828182845904509080);
+ check3(-3.42135637628104173534e-07, GMP_RNDZ, 0.999999657864420798958);
+ /* worst case for argument reduction, very near from 5*log(2),
+ thanks to Jean-Michel Muller
+ */
+ check3(3.4657359027997265421, GMP_RNDN, 32.0);
+ check3(3.4657359027997265421, GMP_RNDU, 32.0);
+ check3(3.4657359027997265421, GMP_RNDD, 31.999999999999996447);
+ srand48(getpid());
+ N = (argc==1) ? 0 : atoi(argv[1]);
+ lo = (argc>=3) ? atof(argv[2]) : -7.083964185e2;
+ hi = (argc>=4) ? atof(argv[3]) : 7.097827129e2;
+ for (i=0;i<N;i++) {
+ /* select d such that exp(d) can be represented as a normalized
+ machine double-precision number,
+ i.e. 2^(-1022) <= exp(d) <= 2^(1023)*(2-2^(-52)) */
+ d = lo + (hi-lo)*drand48();
+ e = check(d, rand() % 4);
+ s += e;
+ if (e>maxe) maxe=e;
+ }
+ if (N) printf("mean error=%1.2e max error=%d\n", (double)s/(double)N,maxe);
+ check3(2.26523754332090625496e+01, 3, 6.8833785261699581146e9);
+ /* errors found in libm.a on PC under Linux */
+ check3(1.31478962104089092122e+01, GMP_RNDZ, 5.12930793917860137299e+05);
+ check3(4.25637507920002378103e-01, GMP_RNDU, 1.53056585656161181497e+00);
+ check3(6.26551618962329307459e-16, GMP_RNDU, 1.00000000000000066613e+00);
+ check3(-3.35589513871216568383e-03, GMP_RNDD, 9.96649729583626853291e-01);
+ check3(1.95151388850007272424e+01, GMP_RNDU, 2.98756340674767792225e+08);
+ check3(2.45045953503350730784e+01, GMP_RNDN, 4.38743344916128387451e+10);
+ check3(2.58165606081678085104e+01, GMP_RNDD, 1.62925781879432281494e+11);
+ check3(-2.36539020084338638128e+01, GMP_RNDZ, 5.33630792749924762447e-11);
+ check3(2.39211946135858077866e+01, GMP_RNDU, 2.44817704330214385986e+10);
+ check3(-2.78190533055889162029e+01, 1, 8.2858803483596879512e-13);
+ /* +45 ulp, wrong side */
+ check3(2.64028186174889789584e+01, 3, 2.9281844652878973388e11); /* -45 ulp*/
+ check3(2.92086338843268329413e+01, 1, 4.8433797301907177734e12); /* -45 ulp*/
+ check3(-2.46355324071459982349e+01, 1, 1.9995129297760994791e-11);
+ /* +45 ulp, wrong side */
+ check3(-2.23509444608605427618e+01, 1, 1.9638492867489702307e-10);
+ /* +45 ulp, wrong side */
+ check3(-2.41175390197331687148e+01, 3, 3.3564940885530624592e-11);/*-45 ulp*/
+ check3(2.46363885231578088053e+01, 2, 5.0055014282693267822e10); /* +45 ulp*/
+ check3(1.111263531080090984914932e2, GMP_RNDN, 1.8262572323517295459e48);
+ check3(-3.56196340354684821250e+02, 0, 2.0225297096141478156e-155); /*+352 */
+ check3(6.59678273772710895173e+02, 2, 3.1234469273830195529e286); /* +459 */
+ check3(5.13772529701934331570e+02, 3, 1.3445427121297197752e223); /* -469 */
+ check3(3.57430211008718345056e+02, 3, 1.6981197246857298443e155); /* -610 */
+ check3(3.82001814471465536371e+02, 2, 7.9667300591087367805e165); /* +705 */
+ check3(5.92396038219384422518e+02, 3, 1.880747529554661989e257); /* -707 */
+ check3(-5.02678550462488090034e+02, 2, 4.8919201895446217839e-219); /* +708*/
+ check3(5.30015757134837031117e+02, 3, 1.5237672861171573939e230); /* -709 */
+ check3(5.16239362447650933063e+02, 1, 1.5845518406744492105e224); /* -710 */
+ /* between 1/2 and 1 */
+ check3(6.00812634798592370977e-01, 0, 1.823600119339019443); /* +1 ulp */
+ exit (0);
+}
diff --git a/mpfr/tests/tget_str.c b/mpfr/tests/tget_str.c
new file mode 100644
index 000000000..ef70086a0
--- /dev/null
+++ b/mpfr/tests/tget_str.c
@@ -0,0 +1,67 @@
+/* Test file for mpfr_get_str.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#include <time.h>
+
+void check(d, rnd) double d; unsigned char rnd;
+{
+ mpfr_t x; char *str, str2[30]; mp_exp_t e;
+
+ mpfr_init2(x, 53);
+ mpfr_set_d(x, d, rnd);
+ str = mpfr_get_str(NULL, &e, 10, 5, x, rnd);
+ mpfr_set_machine_rnd_mode(rnd);
+ sprintf(str2, "%1.4e", d);
+ mpfr_clear(x);
+ free(str);
+}
+
+int
+main(int argc, char **argv)
+{
+ int i; double d;
+
+ srand(getpid());
+ /* printf seems to round towards nearest in all cases, at least with gcc */
+ check(4.059650008e-83, 0);
+ check(-6.606499965302424244461355e233, 0);
+ check(-7.4, 0);
+ check(0.997, 0);
+ check(-4.53063926135729747564e-308, 0);
+ check(2.14478198760196000000e+16, 0);
+ check(7.02293374921793516813e-84, 0);
+ check(-6.7274500420134077e-87,0);
+ for (i=0;i<100000;i++) {
+ do { d = drand(); } while (isnan(d));
+ check(d, 0);
+ }
+ exit (0);
+}
+
+
+
diff --git a/mpfr/tests/tlog.c b/mpfr/tests/tlog.c
new file mode 100644
index 000000000..899c13135
--- /dev/null
+++ b/mpfr/tests/tlog.c
@@ -0,0 +1,303 @@
+/* Test file for mpfr_log.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+double drand_log()
+{
+ double d; long int *i;
+
+ i = (long int*) &d;
+ do {
+ i[0] = lrand48();
+ i[1] = lrand48();
+ } while ((d<1e-153)||(d>1e153)); /* to avoid underflow or overflow
+ in double calculus in sqrt(u*v) */
+ return d;
+}
+
+#define check(a,r) check2(a,r,0.0)
+
+
+int check1(double a, unsigned char rnd_mode, double res1, int ck)
+{
+ mpfr_t ta, tres;
+ double res2;
+ /* ck=1 iff res1 is certified correct */
+
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ if (ck==0 && res1==0.0) res1=log(a);
+ /* printf("mpfr_log working on a=%1.20e, rnd_mode=%d\n",a,rnd_mode);*/
+ mpfr_init2(ta, 53);
+ mpfr_init2(tres, 53);
+ mpfr_set_d(ta, a, GMP_RNDN);
+ mpfr_log(tres, ta, rnd_mode);
+ res2=mpfr_get_d(tres);
+ mpfr_clear(ta); mpfr_clear(tres);
+
+ if (res1!=res2 && (!isnan(res1) || !isnan(res2))) {
+ if (ck) {
+ printf("mpfr_log failed for a=%1.20e, rnd_mode=%d\n",a,rnd_mode);
+ printf("correct result is %1.20e\n mpfr_log gives %1.20e (%d ulp)\n",res1,res2,ulp(res1,res2));
+ exit(1);
+ }
+ else {
+ printf("mpfr_log differs from libm.a for a=%1.20e, rnd_mode=%d\n",a,rnd_mode);
+ printf(" double calculus gives %1.20e\n mpfr_log gives %1.20e (%d ulp)\n",res1,res2,ulp(res1,res2));
+ }
+ }
+ if (!isnan(res1) || !isnan(res2))
+ return ulp(res1,res2);
+ else
+ return 0;
+}
+
+
+void check2(double a, unsigned char rnd_mode, double res1) {
+ check1(a,rnd_mode, res1,1);
+ return;
+}
+
+void check3(double d, unsigned long prec, unsigned char rnd)
+{
+ mpfr_t x, y;
+
+ mpfr_init2(x, prec); mpfr_init2(y, prec);
+ mpfr_set_d(x, d, rnd);
+ mpfr_log(y, x, rnd);
+ mpfr_out_str(stdout, 10, 0, y, rnd); putchar('\n');
+ mpfr_print_raw(y); putchar('\n');
+ mpfr_clear(x); mpfr_clear(y);
+}
+
+void check4(int N) {
+ int i, max=-1, sum=0, cur;
+ double d;
+
+ for(i=0;i<N;i++) {
+ d=drand_log();
+ cur=check1(d,rand() % 4,0.0,0);
+ if (cur<0)
+ cur = -cur;
+ if (cur > max)
+ max=cur;
+ sum+=cur;
+ }
+ d=(double)sum / (double)N;
+ printf("max error : %i \t mean error : %f (in ulps)\n",max,d);
+}
+
+void slave(int N, int p) {
+ int i;
+ double d;
+ mpfr_t ta, tres;
+
+ mpfr_init2(ta, 53);
+ mpfr_init2(tres, p);
+ for(i=0;i<N;i++) {
+ d=drand_log();
+ mpfr_set_d(ta, d, GMP_RNDN);
+ mpfr_log(tres, ta,rand() % 4 );
+ }
+ mpfr_clear(ta); mpfr_clear(tres);
+ printf("fin\n");
+}
+
+
+
+/* examples from Jean-Michel Muller and Vincent Lefevre
+ Cf http://www.ens-lyon.fr/~jmmuller/Intro-to-TMD.htm
+*/
+
+void check_worst_cases()
+{
+ check2(1.00089971802309629645, GMP_RNDD, 8.99313519443722736088e-04);
+ check2(1.00089971802309629645, GMP_RNDN, 8.99313519443722844508e-04);
+ check2(1.00089971802309629645, GMP_RNDU, 8.99313519443722844508e-04);
+
+ check2(1.01979300812244555452, GMP_RNDD, 1.95996734891603630047e-02);
+ check2(1.01979300812244555452, GMP_RNDN, 1.95996734891603664741e-02);
+ check2(1.01979300812244555452, GMP_RNDU, 1.95996734891603664741e-02);
+
+ check2(1.02900871924604464525, GMP_RNDD, 2.85959303301472726744e-02);
+ check2(1.02900871924604464525, GMP_RNDN, 2.85959303301472761438e-02);
+ check2(1.02900871924604464525, GMP_RNDU, 2.85959303301472761438e-02);
+
+ check2(1.27832870030418943585, GMP_RNDD, 2.45553521871417795852e-01);
+ check2(1.27832870030418943585, GMP_RNDN, 2.45553521871417823608e-01);
+ check2(1.27832870030418943585, GMP_RNDU, 2.45553521871417823608e-01);
+
+ check2(1.31706530746788241792, GMP_RNDD, 2.75406009586277422674e-01);
+ check2(1.31706530746788241792, GMP_RNDN, 2.75406009586277478185e-01);
+ check2(1.31706530746788241792, GMP_RNDU, 2.75406009586277478185e-01);
+
+ check2(1.47116981099449883885, GMP_RNDD, 3.86057874110010412760e-01);
+ check2(1.47116981099449883885, GMP_RNDN, 3.86057874110010412760e-01);
+ check2(1.47116981099449883885, GMP_RNDU, 3.86057874110010468272e-01);
+
+ check2(1.58405446812987782401, GMP_RNDD, 4.59987679246663727639e-01);
+ check2(1.58405446812987782401, GMP_RNDN, 4.59987679246663783150e-01);
+ check2(1.58405446812987782401, GMP_RNDU, 4.59987679246663783150e-01);
+
+ check2(1.67192331263391547047, GMP_RNDD, 5.13974647961076613889e-01);
+ check2(1.67192331263391547047, GMP_RNDN, 5.13974647961076724911e-01);
+ check2(1.67192331263391547047, GMP_RNDU, 5.13974647961076724911e-01);
+
+ check2(1.71101198068990645318, GMP_RNDD, 5.37084997042120315669e-01);
+ check2(1.71101198068990645318, GMP_RNDN, 5.37084997042120315669e-01);
+ check2(1.71101198068990645318, GMP_RNDU, 5.37084997042120426691e-01);
+
+ check2(1.72634853551388700588, GMP_RNDD, 5.46008504786553605648e-01);
+ check2(1.72634853551388700588, GMP_RNDN, 5.46008504786553716670e-01);
+ check2(1.72634853551388700588, GMP_RNDU, 5.46008504786553716670e-01);
+
+ check2(2.00028876593004323325, GMP_RNDD, 6.93291553102749702475e-01);
+ check2(2.00028876593004323325, GMP_RNDN, 6.93291553102749813497e-01);
+ check2(2.00028876593004323325, GMP_RNDU, 6.93291553102749813497e-01);
+
+ check2(6.27593230200363105808, GMP_RNDD, 1.83672204800630312072);
+ check2(6.27593230200363105808, GMP_RNDN, 1.83672204800630334276);
+ check2(6.27593230200363105808, GMP_RNDU, 1.83672204800630334276);
+
+ check2(7.47216682321367997588, GMP_RNDD, 2.01118502712453661729);
+ check2(7.47216682321367997588, GMP_RNDN, 2.01118502712453706138);
+ check2(7.47216682321367997588, GMP_RNDU, 2.01118502712453706138);
+
+ check2(9.34589857718275318632, GMP_RNDD, 2.23493759221664944903);
+ check2(9.34589857718275318632, GMP_RNDN, 2.23493759221664989312);
+ check2(9.34589857718275318632, GMP_RNDU, 2.23493759221664989312);
+
+ check2(10.6856587560831854944, GMP_RNDD, 2.36890253928838445674);
+ check2(10.6856587560831854944, GMP_RNDN, 2.36890253928838445674);
+ check2(10.6856587560831854944, GMP_RNDU, 2.36890253928838490083);
+
+ check2(12.4646345033981766903, GMP_RNDD, 2.52289539471636015122);
+ check2(12.4646345033981766903, GMP_RNDN, 2.52289539471636015122);
+ check2(12.4646345033981766903, GMP_RNDU, 2.52289539471636059531);
+
+ check2(17.0953275851761752335, GMP_RNDD, 2.83880518553861849185);
+ check2(17.0953275851761752335, GMP_RNDN, 2.83880518553861893594);
+ check2(17.0953275851761752335, GMP_RNDU, 2.83880518553861893594);
+
+ check2(19.8509496207496916043, GMP_RNDD, 2.98825184582516722998);
+ check2(19.8509496207496916043, GMP_RNDN, 2.98825184582516722998);
+ check2(19.8509496207496916043, GMP_RNDU, 2.98825184582516767406);
+
+ check2(23.9512076062771335216, GMP_RNDD, 3.17601874455977206679);
+ check2(23.9512076062771335216, GMP_RNDN, 3.17601874455977206679);
+ check2(23.9512076062771335216, GMP_RNDU, 3.17601874455977251088);
+
+ check2(428.315247165198229595, GMP_RNDD, 6.05985948325268264369);
+ check2(428.315247165198229595, GMP_RNDN, 6.05985948325268353187);
+ check2(428.315247165198229595, GMP_RNDU, 6.05985948325268353187);
+}
+
+int main(int argc, char *argv[]) {
+ int N=0;
+
+ srand48(getpid());
+ if (argc==4) { /* tlog x prec rnd */
+ check3(atof(argv[1]), atoi(argv[2]), atoi(argv[3]));
+ exit (0);
+ }
+
+ if (argc==3) { /* tlog N p : N calculus with precision p*/
+ printf("Doing %d random tests in %d precision\n",atoi(argv[1]),atoi(argv[2]));
+ slave(atoi(argv[1]),atoi(argv[2]));
+ exit (0);
+ }
+
+ if (argc==2) { /* tlog N: N tests with random double's */
+ N=atoi(argv[1]);
+ printf("Doing %d random tests in double precision\n", N);
+ /*printf("GMP_RNDN : %i, GMP_RNDZ : %i,GMP_RNDU : %i,GMP_RNDD : %i\n",GMP_RNDN, GMP_RNDZ,GMP_RNDU, GMP_RNDD); */
+ check4(N);
+ }
+ else {
+ check_worst_cases();
+
+ check2(1.01979300812244555452, GMP_RNDN, 1.95996734891603664741e-02);
+ check2(10.0,GMP_RNDU,2.30258509299404590110e+00);
+ check2(6.0,GMP_RNDU,1.79175946922805517936);
+ check2(1.0,GMP_RNDZ,0.0);
+ check2(62.0,GMP_RNDU,4.12713438504509166905);
+ check2(0.5,GMP_RNDZ,-6.93147180559945286226e-01);
+ check2(3.0,GMP_RNDZ,1.09861228866810956006e+00);
+ check2(234375765.0,GMP_RNDU,1.92724362186836231104e+01);
+ check2(8.0,GMP_RNDZ,2.07944154167983574765e+00);
+ check2(44.0,GMP_RNDU,3.78418963391826146392e+00);
+ check2(1.01979300812244555452, GMP_RNDN, 1.95996734891603664741e-02);
+ /* bugs found by Vincent Lefe`vre */
+ check2(0.99999599881598921769, GMP_RNDN, -4.0011920155404068690e-6);
+ check2(9.99995576063808955247e-01, GMP_RNDZ, -4.42394597667932383816e-06);
+ check2(9.99993687357856209097e-01, GMP_RNDN, -6.31266206860017342601e-06);
+ check2(9.99995223520736886691e-01, GMP_RNDN, -4.77649067052670982220e-06);
+ check2(9.99993025794720935551e-01, GMP_RNDN, -6.97422959894716163837e-06);
+ check2(9.99987549017837484833e-01, GMP_RNDN, -1.24510596766369924330e-05);
+ check2(9.99985901426543311032e-01, GMP_RNDN, -1.40986728425098585229e-05);
+ check2(9.99986053947420794330e-01, GMP_RNDN, -1.39461498263010849386e-05);
+ check2(9.99971938247442126979e-01, GMP_RNDN, -2.80621462962173414790e-05);
+ /* other bugs found by Vincent Lefe`vre */
+ check2(1.18615436389927785905e+77, GMP_RNDN, 1.77469768607706015473e+02);
+ check2(9.48868723578399476187e+77, GMP_RNDZ, 1.79549152432275803903e+02);
+ check2(2.31822210096938820854e+89, GMP_RNDN, 2.05770873832573869322e+02);
+ /* further bugs found by Vincent Lefe`vre */
+ check2(9.99999989485669482647e-01, GMP_RNDZ, -1.05143305726283042331e-08);
+ check2(9.99999989237970177136e-01, GMP_RNDZ, -1.07620298807745377934e-08);
+ check2(9.99999989239339082125e-01, GMP_RNDN, -1.07606609757704445430e-08);
+
+ check2(7.3890560989306504,GMP_RNDU,2.0000000000000004); /* exp(2.0) */
+ check2(7.3890560989306495,GMP_RNDU,2.0); /* exp(2.0) */
+ check2(7.53428236571286402512e+34,GMP_RNDZ,8.03073567492226345621e+01);
+ check2(6.18784121531737948160e+19,GMP_RNDZ,4.55717030391710693493e+01);
+ check2(1.02560267603047283735e+00,GMP_RNDD,2.52804164149448735987e-02);
+ check2(7.53428236571286402512e+34,GMP_RNDZ,8.03073567492226345621e+01);
+ check2(1.42470900831881198052e+49,GMP_RNDZ,1.13180637144887668910e+02);
+
+ check2(1.08013816255293777466e+11,GMP_RNDN,2.54055249841782604392e+01);
+ check2(6.72783635300509015581e-37,GMP_RNDU,-8.32893948416799503320e+01);
+ check2(2.25904918906057891180e-52,GMP_RNDU,-1.18919480823735682406e+02);
+ check2(1.48901209246462951085e+00,GMP_RNDD,3.98112874867437460668e-01);
+ check2(1.70322470467612341327e-01,GMP_RNDN,-1.77006175364294615626);
+ check2(1.94572026316065240791e+01,GMP_RNDD,2.96821731676437838842);
+ check2(4.01419512207026418764e+04,GMP_RNDD,1.06001772315501128218e+01);
+ check2(9.47077365236487591672e-04,GMP_RNDZ,-6.96212977303956748187e+00);
+ check2(3.95906157687589643802e-109,GMP_RNDD,-2.49605768114704119399e+02);
+ check2(2.73874914516503004113e-02,GMP_RNDD,-3.59766888618655977794e+00);
+ check2(9.18989072589566467669e-17,GMP_RNDZ,-3.69258425351464083519e+01);
+ check2(dbl(2830750724514701.0,131),GMP_RNDZ,dbl(1111664301085491.0,-43));
+ check2(1.74827399630587801934e-23,GMP_RNDZ,-5.24008281254547156891e+01);
+ check2(4.35302958401482307665e+22,GMP_RNDD,5.21277441046519527390e+01);
+ check2(9.70791868689332915209e+00,GMP_RNDD,2.27294191194272210410e+00);
+ check2(2.22183639799464011100e-01,GMP_RNDN,-1.50425103275253957413e+00);
+ check2(2.27313466156682375540e+00,GMP_RNDD,8.21159787095675608448e-01);
+ check2(6.58057413965851156767e-01,GMP_RNDZ,-4.18463096196088235600e-01);
+ check2(7.34302197248998461006e+43,GMP_RNDZ,1.01004909469513179942e+02);
+ check2(6.09969788341579732815e+00,GMP_RNDD,1.80823924264386204363e+00);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/tlog2.c b/mpfr/tests/tlog2.c
new file mode 100644
index 000000000..0ba296a83
--- /dev/null
+++ b/mpfr/tests/tlog2.c
@@ -0,0 +1,44 @@
+/* Test file for mpfr_log2.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+/* tlog2 [prec] [rnd] [0 = no print] */
+
+int main(argc, argv) int argc; char *argv[];
+{
+ mpfr_t x; int p; unsigned char rnd;
+
+ p = (argc>1) ? atoi(argv[1]) : 53;
+ rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ;
+ mpfr_init2(x, p);
+ mpfr_log2(x, rnd);
+ if (argc>=2) {
+ printf("log(2)="); mpfr_out_str(stdout, 10, 0, x, rnd); putchar('\n');
+ }
+ else if (mpfr_get_d(x) != 6.9314718055994530941e-1) {
+ fprintf(stderr, "mpfr_log2 failed for prec=53\n"); exit(1);
+ }
+ mpfr_clear(x);
+ exit (0);
+}
diff --git a/mpfr/tests/tmul.c b/mpfr/tests/tmul.c
new file mode 100644
index 000000000..881d0eb64
--- /dev/null
+++ b/mpfr/tests/tmul.c
@@ -0,0 +1,175 @@
+/* Test file for mpfr_mul.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+#define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
+
+/* checks that x*y gives the same results in double
+ and with mpfr with 53 bits of precision */
+void check(double x, double y, unsigned int rnd_mode, unsigned int px,
+unsigned int py, unsigned int pz, double res)
+{
+ double z1,z2; mpfr_t xx,yy,zz;
+
+ mpfr_init2(xx, px);
+ mpfr_init2(yy, py);
+ mpfr_init2(zz, pz);
+ mpfr_set_d(xx, x, rnd_mode);
+ mpfr_set_d(yy, y, rnd_mode);
+ mpfr_mul(zz, xx, yy, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z1 = (res==0.0) ? x*y : res;
+ z2 = mpfr_get_d(zz);
+ if (z1!=z2 && (z1>=MINNORM || z1<=-MINNORM)) {
+ printf("mpfr_mul ");
+ if (res==0.0) printf("differs from libm.a"); else printf("failed");
+ printf(" for x=%1.20e y=%1.20e with rnd_mode=%u\n",x,y,rnd_mode);
+ mpfr_print_raw(zz); putchar('\n');
+ printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n",z1,z2);
+ exit(1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
+}
+
+/* checks that x*y gives the same results in double
+ and with mpfr with 24 bits of precision */
+void check24(float x, float y, unsigned int rnd_mode, float res)
+{
+ float z1,z2; mpfr_t xx,yy,zz;
+
+ mpfr_init2(xx, 24);
+ mpfr_init2(yy, 24);
+ mpfr_init2(zz, 24);
+ mpfr_set_d(xx, x, rnd_mode);
+ mpfr_set_d(yy, y, rnd_mode);
+ mpfr_mul(zz, xx, yy, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ z1 = (res==0.0) ? x*y : res;
+ z2 = (float) mpfr_get_d(zz);
+ if (z1!=z2) {
+ printf("mpfr_mul ");
+ if (res==0.0) printf("differs from libm.a"); else printf("failed");
+ printf(" for x=%1.10e y=%1.10e with prec=24 and rnd_mode=%u\n",x,y,rnd_mode);
+ printf("libm.a gives %1.10e, mpfr_mul gives %1.10e\n",z1,z2);
+ if (res!=0.0) exit(1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
+}
+
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 1 */
+void check_float()
+{
+ int i;
+ for (i=0;i<4;i++) {
+ if (i!=2) {
+ check24(8388609.0, 8388609.0, i, 0.0);
+ check24(16777213.0, 8388609.0, i, 0.0);
+ check24(8388611.0, 8388609.0, i, 0.0);
+ check24(12582911.0, 8388610.0, i, 0.0);
+ check24(12582914.0, 8388610.0, i, 0.0);
+ check24(13981013.0, 8388611.0, i, 0.0);
+ check24(11184811.0, 8388611.0, i, 0.0);
+ check24(11184810.0, 8388611.0, i, 0.0);
+ check24(13981014.0, 8388611.0, i, 0.0);
+ }
+ }
+ i=GMP_RNDU;
+ check24(8388609.0, 8388609.0, GMP_RNDU, 70368769343488.0);
+ check24(16777213.0, 8388609.0, GMP_RNDU, 140737479966720.0);
+ check24(8388611.0, 8388609.0, GMP_RNDU, 70368786120704.0);
+ check24(12582911.0, 8388610.0, GMP_RNDU, 105553133043712.0);
+ check24(12582914.0, 8388610.0, GMP_RNDU, 105553166598144.0);
+ check24(13981013.0, 8388611.0, GMP_RNDU, 117281279442944.0);
+ check24(11184811.0, 8388611.0, GMP_RNDU, 93825036976128.0);
+ check24(11184810.0, 8388611.0, GMP_RNDU, 93825020198912.0);
+ check24(13981014.0, 8388611.0, GMP_RNDU, 117281296220160.0);
+}
+
+/* check sign of result */
+void check_sign()
+{
+ mpfr_t a, b;
+
+ mpfr_init2(a, 53); mpfr_init2(b, 53);
+ mpfr_set_d(a, -1.0, GMP_RNDN);
+ mpfr_set_d(b, 2.0, GMP_RNDN);
+ mpfr_mul(a, b, b, GMP_RNDN);
+ if (mpfr_get_d(a) != 4.0) {
+ fprintf(stderr,"2.0*2.0 gives %1.20e\n", mpfr_get_d(a)); exit(1);
+ }
+ mpfr_clear(a); mpfr_clear(b);
+}
+
+int main(argc,argv) int argc; char *argv[];
+{
+ double x,y,z; int i,prec,rnd_mode;
+
+ check_float();
+ check(6.9314718055994530941514e-1, 0.0, GMP_RNDZ, 53, 53, 53, 0.0);
+ check(0.0, 6.9314718055994530941514e-1, GMP_RNDZ, 53, 53, 53, 0.0);
+ prec = (argc<2) ? 53 : atoi(argv[1]);
+ rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
+ check_sign();
+ check(-4.165000000e4, -0.00004801920768307322868063274915, GMP_RNDN,
+ 53, 53, 53, 2.0);
+ check(2.71331408349172961467e-08, -6.72658901114033715233e-165,
+ GMP_RNDZ, 53, 53, 53, 0.0);
+ x=0.31869277231188065; y=0.88642843322303122;
+ check(x, y, GMP_RNDZ, 53, 53, 53, 0.0);
+ x=8.47622108205396074254e-01; y=3.24039313247872939883e-01;
+ check(x, y, GMP_RNDU, 28, 45, 1, 0.5);
+ x=2.63978122803639081440e-01;
+ y=5736014.0/8388608.0; /* 6.83786096444222835089e-01; */
+ check(x, y, GMP_RNDN, 34, 23, 31, 0.180504585267044603);
+ x=9.84891017624509146344e-01; /* rounded to 1.0 with prec=6 */
+ x=1.0;
+ y=1.18351709358762491320e-01;
+ check(x, y, GMP_RNDU, 6, 41, 36, 0.1183517093595583);
+ /* the following checks that rounding to nearest sets the last
+ bit to zero in case of equal distance */
+ check(67108865.0, 134217729.0, GMP_RNDN, 53, 53, 53, 0.0);
+ x=1.37399642157394197284e-01; y=2.28877275604219221350e-01;
+ check(x, y, GMP_RNDN, 49, 15, 32, 0.0314472340833162888);
+ x=4.03160720978664954828e-01; y=5.85483042917246621073e-01;
+ check(x, y, GMP_RNDZ, 51, 22, 32, 0.2360436821472831);
+ x=3.90798504668055102229e-14; y=9.85394674650308388664e-04;
+ check(x, y, GMP_RNDN, 46, 22, 12, 0.385027296503914762e-16);
+ x=4.58687081072827851358e-01; y=2.20543551472118792844e-01;
+ check(x, y, GMP_RNDN, 49, 3, 1, 0.125);
+ for (i=0;i<1000000;) {
+ x = drand();
+ y = drand();
+ z = x*y; if (z<0) z=-z;
+ if (z<1e+308 && z>1e-308) /* don't test overflow/underflow for now */
+ { i++;
+ check(x, y, (rnd_mode==-1) ? lrand48()%4 : rnd_mode,
+ prec, prec, prec, 0.0);
+ }
+ }
+ exit (0);
+}
+
diff --git a/mpfr/tests/tmul_2exp.c b/mpfr/tests/tmul_2exp.c
new file mode 100644
index 000000000..c47031313
--- /dev/null
+++ b/mpfr/tests/tmul_2exp.c
@@ -0,0 +1,49 @@
+/* Test file for mpfr_mul_2exp.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <time.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+/* checks that x*y gives the same results in double
+ and with mpfr with 53 bits of precision */
+
+int
+main(argc,argv) int argc; char *argv[];
+{
+ double x, z; mpfr_t w;
+
+ mpfr_init2(w, 53);
+
+ srand48(time(NULL));
+ x = drand48();
+ mpfr_set_d(w, x, 0);
+ mpfr_mul_2exp(w, w, 10, GMP_RNDZ);
+ if (x != (z = mpfr_get_d(w)/1024))
+ {
+ fprintf(stderr, "%f != %f\n", x, z);
+ exit (1);
+ }
+ exit (0);
+}
+
diff --git a/mpfr/tests/tmul_ui.c b/mpfr/tests/tmul_ui.c
new file mode 100644
index 000000000..fab7d50fd
--- /dev/null
+++ b/mpfr/tests/tmul_ui.c
@@ -0,0 +1,66 @@
+/* Test file for mpfr_mul_ui.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "time.h"
+
+int
+main(int argc, char **argv)
+{
+ mpfr_t x, y;
+
+ mpfr_init2(x, 53); mpfr_init2(y, 53);
+
+ /* checks that result is normalized */
+ mpfr_set_d(y, 6.93147180559945286227e-01, GMP_RNDZ);
+ mpfr_mul_ui(x, y, 1, GMP_RNDZ);
+ if (MANT(x)[PREC(x)/BITS_PER_MP_LIMB] >> (BITS_PER_MP_LIMB-1) == 0) {
+ fprintf(stderr, "Error in mpfr_mul_ui: result not normalized\n");
+ exit(1);
+ }
+ if (mpfr_cmp(x,y)) {
+ fprintf(stderr, "Error in mpfr_mul_ui: 1*y != y\n");
+ printf("y= "); mpfr_print_raw(y); putchar('\n');
+ printf("1*y="); mpfr_print_raw(x); putchar('\n');
+ exit(1);
+ }
+
+ mpfr_set_d(x, 1.0/3.0, GMP_RNDZ);
+ mpfr_mul_ui(x, x, 3, GMP_RNDU);
+ if (mpfr_get_d(x) != 1.0) {
+ fprintf(stderr, "Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n"); exit(1);
+ }
+
+ /* checks sign is correct */
+ mpfr_set_d(x, -2.0, GMP_RNDZ);
+ mpfr_set_d(y, 3.0, GMP_RNDZ);
+ mpfr_mul_ui(x, y, 4, GMP_RNDZ);
+ if (SIGN(x) != 1) {
+ fprintf(stderr, "Error in mpfr_mul_ui: 4*3.0 does not give a positive result\n"); exit(1);
+ }
+
+ mpfr_clear(x); mpfr_clear(y);
+ exit (0);
+}
diff --git a/mpfr/tests/tout_str.c b/mpfr/tests/tout_str.c
new file mode 100644
index 000000000..cfb8a822e
--- /dev/null
+++ b/mpfr/tests/tout_str.c
@@ -0,0 +1,85 @@
+/* Test file for mpfr_out_str.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+FILE *fout;
+
+#define check(d,r,b) check4(d,r,b,53)
+
+void check4(d, rnd, base, prec) double d; unsigned char rnd; int base, prec;
+{
+ mpfr_t x;
+
+ mpfr_init2(x, prec);
+ mpfr_set_d(x, d, rnd);
+ mpfr_set_machine_rnd_mode(rnd);
+ fprintf(fout, "%1.19e base %d rnd %d:\n ", d, base, rnd);
+ mpfr_out_str(fout, base, (base==2) ? prec : 0, x, rnd);
+ fputc('\n', fout);
+ mpfr_clear(x);
+}
+
+int
+main(int argc, char **argv)
+{
+ int i,N=100,r,p; double d;
+
+ /* with no argument: prints to /dev/null,
+ tout_str N: prints N tests to stdout */
+ if (argc==1) fout=fopen("/dev/null", "w");
+ else { fout=stdout; N=atoi(argv[1]); }
+ check(-1.5674376729569697500e+15, GMP_RNDN, 19);
+ check(-5.71262771772792640000e-79, GMP_RNDU, 16);
+ check(-0.0, GMP_RNDU, 7);
+ check(-4.5306392613572974756e-308, GMP_RNDN, 8);
+ check(-6.7265890111403371523e-165, GMP_RNDN, 4);
+ check(-1.3242553591261807653e+156, GMP_RNDN, 16);
+ check(-6.606499965302424244461355e233, GMP_RNDN, 10);
+ check4(1.0, GMP_RNDN, 10, 120);
+ check(1.0, GMP_RNDU, 10);
+ check(4.059650008e-83, GMP_RNDN, 10);
+ check(-7.4, GMP_RNDN, 10);
+ check(0.997, GMP_RNDN, 10);
+ check(-4.53063926135729747564e-308, GMP_RNDN, 10);
+ check(2.14478198760196000000e+16, GMP_RNDN, 10);
+ check(7.02293374921793516813e-84, GMP_RNDN, 10);
+
+ /* random tests */
+ srand(getpid());
+ for (i=0;i<N;i++) {
+ do { d = drand(); } while (isnan(d));
+ r = rand()%4;
+ p = 2 + rand()%35;
+ check(d, r, p);
+ }
+ exit (0);
+}
+
+
+
diff --git a/mpfr/tests/tpi.c b/mpfr/tests/tpi.c
new file mode 100644
index 000000000..487983c5f
--- /dev/null
+++ b/mpfr/tests/tpi.c
@@ -0,0 +1,44 @@
+/* Test file for mpfr_pi.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+/* tpi [prec] [rnd] [0 = no print] */
+
+int main(argc, argv) int argc; char *argv[];
+{
+ mpfr_t x; int p; unsigned char rnd;
+
+ p = (argc>1) ? atoi(argv[1]) : 53;
+ rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ;
+ mpfr_init2(x, p);
+ mpfr_pi(x, rnd);
+ if (argc>=2) {
+ printf("Pi="); mpfr_out_str(stdout, 10, 0, x, rnd); putchar('\n');
+ }
+ else if (mpfr_get_d(x) != 3.141592653589793116) {
+ fprintf(stderr, "mpfr_pi failed for prec=53\n"); exit(1);
+ }
+ mpfr_clear(x);
+ exit (0);
+}
diff --git a/mpfr/tests/tround.c b/mpfr/tests/tround.c
new file mode 100644
index 000000000..3ccd6ff7f
--- /dev/null
+++ b/mpfr/tests/tround.c
@@ -0,0 +1,45 @@
+/* Test file for mpfr_round.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+int
+main()
+{
+ mpfr_t x;
+
+ /* checks that rounds to nearest sets the last
+ bit to zero in case of equal distance */
+ mpfr_init2(x, 2);
+ mpfr_set_d(x, 5.0, 0);
+ if (mpfr_get_d(x) != 4.0) { printf("Error in tround: got %1.1f instead of 4.0\n",mpfr_get_d(x)); }
+
+ mpfr_set_d(x, 0.00098539467465030839, 0);
+
+ mpfr_set_d(x, 9.84891017624509146344e-01, GMP_RNDU);
+ if (mpfr_get_d(x) != 1.0) { printf("Error in tround: got %f instead of 1.0\n",mpfr_get_d(x)); exit(1); }
+
+ mpfr_clear(x);
+ exit (0);
+}
diff --git a/mpfr/tests/tset_d.c b/mpfr/tests/tset_d.c
new file mode 100644
index 000000000..c542dc1e2
--- /dev/null
+++ b/mpfr/tests/tset_d.c
@@ -0,0 +1,90 @@
+/* Test file for mpfr_set_d and mpfr_get_d.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <time.h>
+#ifdef IRIX64
+#include <sys/fpu.h>
+#endif
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+extern int isnan();
+
+int
+main(int argc, char **argv)
+{
+ fprintf(stderr, "Test case tset_d disabled\n");
+ exit(0); /* THIS TEST CASE IS NOT WORKING */
+
+#if 0
+ mpfr_t x,y,z; unsigned long k,n; double d, dd;
+#ifdef IRIX64
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+
+ mpfr_init2(z, 32);
+ mpfr_set_d(z, 1.0, 0);
+ if (mpfr_get_d(z) != 1.0) {
+ mpfr_print_raw(z); putchar('\n');
+ printf("Error: 1.0 != 1.0\n"); exit(1);
+ }
+ mpfr_init2(x, 53); mpfr_init2(y, 53);
+ mpfr_set_d(x, d=-1.08007920352320089721e+150, 0);
+ if (mpfr_get_d(x) != d) {
+ mpfr_print_raw(x); putchar('\n');
+ printf("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",d,
+ mpfr_get_d(x)); exit(1);
+ }
+ srand48(time(NULL));
+ mpfr_set_d(x, 8.06294740693074521573e-310, 0);
+ d = -6.72658901114033715233e-165;
+ mpfr_set_d(x, d, 0);
+ if (d != mpfr_get_d(x)) {
+ mpfr_print_raw(x); putchar('\n');
+ printf("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",d,
+ mpfr_get_d(x)); exit(1);
+ }
+ n = (argc==1) ? 1000000 : atoi(argv[1]);
+ for (k = 1; k <= n; k++)
+ {
+ d = drand();
+ mpfr_set_d(x, d, 0);
+ dd = mpfr_get_d(x);
+ if (d != dd && (!isnan(d) || !isnan(dd)))
+ {
+ fprintf(stderr,
+ "Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d(x));
+ mpfr_print_raw(x); putchar('\n');
+ }
+ }
+
+ mpfr_clear(x); mpfr_clear(y); mpfr_clear(z);
+ exit (0);
+#endif /* 0 */
+}
+
diff --git a/mpfr/tests/tset_f.c b/mpfr/tests/tset_f.c
new file mode 100644
index 000000000..4a82f0a40
--- /dev/null
+++ b/mpfr/tests/tset_f.c
@@ -0,0 +1,74 @@
+/* Test file for mpfr_set_f.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "time.h"
+
+#if defined(hpux)
+#define srandom srand48
+#endif
+
+int
+main()
+{
+ mpfr_t x; mpf_t y; mpf_t z; unsigned long k, pr; double f;
+
+ mpfr_init2(x, 100);
+ mpf_init(y);
+
+ mpf_set_d(y, 0.0);
+ mpfr_set_f(x, y, GMP_RNDN);
+
+ srandom(time(NULL));
+ mpf_random2(y, 10, 0);
+ mpfr_set_f(x, y, rand() & 3);
+
+ /* bug found by Jean-Pierre Merlet on February 3, 2000 */
+ mpfr_set_prec(x, 256); mpf_init2(y, 256);
+ mpfr_set_machine_rnd_mode(GMP_RNDD);
+ mpf_set_str(y, "2033.033", 10);
+ mpfr_set_f(x, y, GMP_RNDN);
+ f = mpfr_get_d(x);
+ if (f != 2033.0329999999999017745722085) {
+ fprintf(stderr, "mpfr_set_f failed for y=2033.033\n"); exit(1);
+ }
+ mpf_set_str(y, "-2033.033", 10);
+ mpfr_set_f(x, y, GMP_RNDN);
+ f = mpfr_get_d(x);
+ if (f != -2033.0330000000001291482476518) {
+ fprintf(stderr, "mpfr_set_f failed for y=-2033.033\n"); exit(1);
+ }
+
+ mpf_clear(y); mpfr_clear(x);
+
+ for (k = 1; k <= 100000; k++)
+ {
+ pr = 1 + (rand()&255);
+ mpf_init2(z, pr);
+ mpf_random2(z, z->_mp_prec, 0);
+ mpfr_init2(x, pr);
+ mpfr_set_f(x, z, 0);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/tset_si.c b/mpfr/tests/tset_si.c
new file mode 100644
index 000000000..db4e73ac7
--- /dev/null
+++ b/mpfr/tests/tset_si.c
@@ -0,0 +1,65 @@
+/* Test file for mpfr_set_si and mpfr_set_ui.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "time.h"
+
+int
+main(int argc, char **argv)
+{
+ mpfr_t x; long k, z, d; unsigned long zl, dl, N;
+
+ mpfr_init2(x, 100);
+
+ srandom(time(NULL));
+
+ N = (argc==1) ? 1000000 : atoi(argv[1]);
+
+ for (k = 1; k <= N; k++)
+ {
+ z = random() - (1 << 30);
+ mpfr_set_si(x, z, GMP_RNDZ);
+ d = (int)mpfr_get_d(x);
+ if (d != z)
+ {
+ fprintf(stderr, "Expected %ld got %ld\n", z, d);
+ exit(1);
+ }
+ }
+
+ for (k = 1; k <= N; k++)
+ {
+ zl = random();
+ mpfr_set_ui(x, zl, GMP_RNDZ);
+ dl = (unsigned int) mpfr_get_d(x);
+ if (dl != zl)
+ {
+ fprintf(stderr, "Expected %lu got %lu\n", zl, dl);
+ exit(1);
+ }
+ }
+
+ mpfr_clear(x);
+ exit (0);
+}
diff --git a/mpfr/tests/tset_str.c b/mpfr/tests/tset_str.c
new file mode 100644
index 000000000..a1cd3000d
--- /dev/null
+++ b/mpfr/tests/tset_str.c
@@ -0,0 +1,87 @@
+/* Test file for mpfr_set_str.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include <time.h>
+
+#if defined (hpux)
+#define srandom srand48
+#define random mrand48
+#endif
+
+int
+main(int argc, char **argv)
+{
+ mpfr_t x; unsigned long k, bd, nc; char *str, *str2;
+
+ if (argc==2) { /* tset_str <string> */
+ mpfr_init2(x, 53);
+ mpfr_set_str_raw(x, argv[1]);
+ printf("%1.20e\n", mpfr_get_d(x));
+ mpfr_clear(x);
+ exit (0);
+ }
+
+ srandom(time(NULL));
+
+ if (argc > 1) { nc = atoi(argv[1]); } else { nc = 53; }
+ if (nc < 24) { nc = 24; }
+
+ bd = random()&8;
+
+ str2 = str = (char *) malloc (nc*sizeof(char));
+
+ if (bd)
+ {
+ for(k = 1; k <= bd; k++)
+ { *(str2++) = (random() & 1) + '0'; }
+ }
+ else { *(str2++) = '0'; }
+
+ *(str2++) = '.';
+
+ for(k = 1; k < nc - 17 - bd; k++)
+ {
+ *(str2++) = '0' + (random() & 1);
+ }
+
+ *(str2++) = 'e';
+ sprintf(str2, "%d", random() - (1 << 30));
+
+ /* printf("%s\n", str); */
+ mpfr_init2(x, nc + 10);
+ mpfr_set_str_raw(x, str);
+ /* mpfr_print_raw(x); printf("\n"); */
+
+ mpfr_set_prec(x, 53);
+ mpfr_set_str_raw(x, "+110101100.01010000101101000000100111001000101011101110E00");
+
+ mpfr_set_str_raw(x, "1.0");
+ if (mpfr_get_d(x) != 1.0) {
+ fprintf(stderr, "Error in mpfr_set_str_raw for s=1.0\n"); exit(1);
+ }
+
+ mpfr_clear(x); free(str);
+ exit (0);
+}
diff --git a/mpfr/tests/tset_z.c b/mpfr/tests/tset_z.c
new file mode 100644
index 000000000..61fe654f3
--- /dev/null
+++ b/mpfr/tests/tset_z.c
@@ -0,0 +1,66 @@
+/* Test file for mpfr_set_z.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <stdlib.h>
+#include <unistd.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+/* tset_z z rnd prec */
+
+void check(long i, unsigned char rnd) {
+ mpfr_t f; mpz_t z;
+
+ mpfr_init2(f, 53); mpz_init(z);
+ mpz_set_ui(z, i);
+ mpfr_set_z(f, z, rnd);
+ if ((long)mpfr_get_d(f) != i) {
+ printf("Error in mpfr_set_z for i=%ld rnd_mode=%d\n",i,rnd);
+ exit(1);
+ }
+ mpfr_clear(f); mpz_clear(z);
+}
+
+void check_large()
+{
+ mpz_t z; mpfr_t x,y;
+
+ mpz_init(z); mpfr_init2(x, 160); mpfr_init2(y, 160);
+ mpz_set_str(z, "77031627725494291259359895954016675357279104942148788042", 10);
+ mpfr_set_z(x, z, GMP_RNDN);
+ mpfr_set_str_raw(y, "0.1100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001001E186");
+ if (mpfr_cmp(x,y)) {
+ fprintf(stderr, "Error in mpfr_set_z on large input\n"); exit(1);
+ }
+ mpz_clear(z); mpfr_clear(x); mpfr_clear(y);
+}
+
+int main(argc,argv) int argc; char *argv[];
+{
+ long j;
+
+ check_large();
+ srand(getpid());
+ for (j=0; j<1000000; j++)
+ check(lrand48(), rand()%4);
+ exit (0);
+}
+
diff --git a/mpfr/tests/tsqrt.c b/mpfr/tests/tsqrt.c
new file mode 100644
index 000000000..ccffad0c5
--- /dev/null
+++ b/mpfr/tests/tsqrt.c
@@ -0,0 +1,149 @@
+/* Test file for mpfr_sqrt.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#ifdef IRIX64
+#include <sys/fpu.h>
+#endif
+
+extern int isnan(), getpid();
+
+#define check(a,r) check3(a,r,-1.0)
+
+int maxulp=0;
+
+void check3(a, rnd_mode, Q) double a; unsigned char rnd_mode; double Q;
+{
+ mpfr_t q; double Q2; int ck,u;
+
+ ck = (Q!=-1.0); /* if ck=1, then Q is certified correct */
+ mpfr_init2(q, 53);
+ mpfr_set_d(q, a, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ mpfr_sqrt(q, q, rnd_mode);
+ if (ck==0) Q = sqrt(a);
+ Q2 = mpfr_get_d(q);
+ if (Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
+ u = ulp(Q2,Q);
+ if (ck) {
+ printf("mpfr_sqrt failed for a=%1.20e, rnd_mode=%d\n",a,rnd_mode);
+ printf("expected sqrt is %1.20e, got %1.20e (%d ulp)\n",Q,Q2,u);
+ exit(1);
+ }
+ else if (u>maxulp || u<-maxulp) {
+ maxulp = (u>maxulp) ? u : -u;
+ printf("libm.a differs from mpfr_sqrt for a=%1.20e, rnd_mode=%d\n",a,rnd_mode);
+ printf("libm.a gives %1.20e, mpfr_sqrt gives %1.20e (%d ulp)\n",Q,Q2,u);
+ }
+ }
+ mpfr_clear(q);
+}
+
+void check24(a, rnd_mode) float a; unsigned char rnd_mode;
+{
+ mpfr_t q; float Q,Q2;
+
+ mpfr_init2(q, 24);
+ mpfr_set_d(q, a, rnd_mode);
+ mpfr_set_machine_rnd_mode(rnd_mode);
+ mpfr_sqrt(q, q, rnd_mode);
+ Q = sqrt(a);
+ Q2 = mpfr_get_d(q);
+ if (Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
+ printf("mpfr_sqrt failed for a=%1.10e, rnd_mode=%d\n",a,rnd_mode);
+ printf("expected sqrt is %1.10e, got %1.10e\n",Q,Q2);
+ exit(1);
+ }
+ mpfr_clear(q);
+}
+
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 3 */
+void check_float()
+{
+ int i; float b = 8388608.0; /* 2^23 */
+
+ for (i=0;i<4;i++) {
+ check24(b*8388610.0, i);
+ check24(b*2.0*16777214.0, i);
+ check24(b*8388612.0, i);
+ check24(b*2.0*16777212.0, i);
+ check24(b*11946704.0, i);
+ check24(b*14321479.0, i);
+ check24(b*2.0*13689673.0, i);
+ check24(b*8388614.0, i);
+ check24(b*2.0*16777210.0, i);
+ check24(b*10873622.0, i);
+ }
+}
+
+int main()
+{
+ int i; double a;
+#ifdef IRIX64
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+
+ check_float();
+ srand(getpid());
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 4 */
+ a = 4503599627370496.0; /* 2^52 */
+ for (i=0;i<4;i++) {
+ check(a*2.0*8732221479794286.0, i);
+ check(a*8550954388695124.0, i);
+ check(a*7842344481681754.0, i);
+ check(a*5935035262218600.0, i);
+ check(a*5039650445085418.0, i);
+ check(a*5039721545366078.0, i);
+ check(a*8005963117781324.0, i);
+ check(a*6703494707970582.0, i);
+ check(a*8010323124937260.0, i);
+ check(a*2.0*8010776873384260.0, i);
+ }
+ check(6.37983013646045901440e+32, GMP_RNDN);
+ check(1.0, GMP_RNDN);
+ check(1.0, GMP_RNDZ);
+ check(3.725290298461914062500000e-9, GMP_RNDN);
+ check(3.725290298461914062500000e-9, GMP_RNDZ);
+ a=1190456976439861.0;
+ check3(a, GMP_RNDZ, dbl(4630914205854029.0,-27));
+ check3(1024.0*a, GMP_RNDZ, dbl(4630914205854029.0,-22));
+ /* the following examples are bugs in Cygnus compiler/system, found by
+ Fabrice Rouillier while porting mpfr to Windows */
+ check3(9.89438396044940256501e-134, GMP_RNDU, 3.14553397063986684729e-67);
+ check3(7.86528588050363751914e+31, GMP_RNDZ, 8.86864469944739400000e+15);
+ for (i=0;i<100000;i++) {
+ a = drand();
+ check(a, rand() % 4);
+ }
+ exit (0);
+}
diff --git a/mpfr/tests/tzeta.c b/mpfr/tests/tzeta.c
new file mode 100644
index 000000000..d9495e57b
--- /dev/null
+++ b/mpfr/tests/tzeta.c
@@ -0,0 +1,70 @@
+/* Test file for mpfr_zeta.
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+/* #define DEBUG */
+
+int main()
+{mpfr_t p,result,res_p; int succes; size_t t;
+mpfr_init2(result, 53);
+mpfr_init2(res_p, 53);
+mpfr_init2(p, 53); mpfr_set_d(p, 2.0, GMP_RNDN);
+
+mpfr_zeta(result,p,GMP_RNDN);
+/*printf("%d\n",succes);*/
+#ifdef DEBUG
+printf("Valeur de zeta(2) avec prec=53 et arrondi au plus pres:\n");
+mpfr_print_raw(result);printf("\n");
+t=mpfr_out_str(stdout,10,0,result,GMP_RNDN);printf("\n");
+#endif
+ if (mpfr_get_d(result) != 1.64493406684822640607e+00) {
+ fprintf(stderr, "mpfr_zeta fails for s=2 and rnd_mode=GMP_RNDN\n");
+ exit(1);
+ }
+
+/*Test de comparaison avec pi^2/6*/
+mpfr_set_prec(p, 67);
+mpfr_pi(p,GMP_RNDN);
+mpfr_mul(p,p,p,GMP_RNDN);
+mpfr_set_ui(res_p,6,GMP_RNDN);
+mpfr_div(p,p,res_p,GMP_RNDN);
+/*mpfr_print_raw(p);printf("\n");
+t=mpfr_out_str(stdout,10,0,p,GMP_RNDN);printf("\n");*/
+succes=mpfr_can_round(p,63,GMP_RNDN,GMP_RNDN,53);
+mpfr_set(res_p,p,GMP_RNDN);
+/*printf("%d\n",succes);*/
+#ifdef DEBUG
+printf("Valeur de pi^2/6 avec prec=53 et arrondi au plus pres:\n");
+mpfr_print_raw(res_p);printf("\n");
+t=mpfr_out_str(stdout,10,0,res_p,GMP_RNDN);printf("\n");
+#endif
+
+mpfr_clear(p);
+mpfr_clear(result);
+mpfr_clear(res_p);
+exit (0);
+}
diff --git a/mpfr/zeta.c b/mpfr/zeta.c
new file mode 100644
index 000000000..5250a9dd7
--- /dev/null
+++ b/mpfr/zeta.c
@@ -0,0 +1,116 @@
+/* mpfr_zeta -- Riemann Zeta function at a floating-point number
+
+Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
+
+This file is part of the MPFR Library.
+
+The MPFR 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 MPFR 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 MPFR 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "mpfr.h"
+
+int
+#if __STDC__
+mpfr_zeta(mpfr_ptr result, mpfr_srcptr op, unsigned char rnd_mode)
+#else
+mpfr_zeta(result, op, rnd_mode)
+ mpfr_ptr result;
+ mpfr_srcptr op;
+ unsigned char rnd_mode;
+#endif
+{
+ mpfr_t s,s2,x,y,u,b,v,nn,z,z2;
+ int i,n,succes;
+
+ /* first version */
+ if (mpfr_get_d(op) != 2.0 || rnd_mode != GMP_RNDN
+ || PREC(result) != 53) {
+ fprintf(stderr, "not yet implemented\n"); exit(1);
+ }
+
+mpfr_set_default_prec(67);
+mpfr_init(x);
+mpfr_init(y);
+mpfr_init(s);
+mpfr_init(s2);
+mpfr_init(u);
+mpfr_init(b);
+mpfr_init(v);
+mpfr_init(nn);
+mpfr_init(z);
+mpfr_init(z2);
+mpfr_set_ui(u,1,GMP_RNDN);
+mpfr_set_ui(s,0,GMP_RNDN);
+/*s=Somme des 1/i^2 (i=100...2)*/
+n=100;
+for (i=n; i>1; i--)
+{
+mpfr_set_ui(x,i*i,GMP_RNDN);
+mpfr_div(y,u,x,GMP_RNDN);
+mpfr_add(s,s,y,GMP_RNDN);
+};
+/*mpfr_print_raw(s);printf("\n");
+t=mpfr_out_str(stdout,10,0,s,GMP_RNDN);printf("\n");*/
+/*Application d'Euler-Maclaurin, jusqu'au terme 1/n^7 - n=100)*/
+mpfr_set_ui(nn,n,GMP_RNDN);
+mpfr_div(z,u,nn,GMP_RNDN);
+mpfr_set(s2,z,GMP_RNDN);
+mpfr_mul(z2,z,z,GMP_RNDN);
+mpfr_div_2exp(v,z2,1,GMP_RNDN);
+mpfr_sub(s2,s2,v,GMP_RNDN);
+mpfr_set_ui(b,6,GMP_RNDN);
+mpfr_mul(z,z,z2,GMP_RNDN);
+mpfr_div(v,z,b,GMP_RNDN);
+mpfr_add(s2,s2,v,GMP_RNDN);
+mpfr_set_si(b,-30,GMP_RNDN);
+mpfr_mul(z,z,z2,GMP_RNDN);
+mpfr_div(v,z,b,GMP_RNDN);
+mpfr_add(s2,s2,v,GMP_RNDN);
+mpfr_set_si(b,42,GMP_RNDN);
+mpfr_mul(z,z,z2,GMP_RNDN);
+mpfr_div(v,z,b,GMP_RNDN);
+mpfr_add(s2,s2,v,GMP_RNDN);
+/*mpfr_print_raw(s2);printf("\n");
+t=mpfr_out_str(stdout,10,0,s2,GMP_RNDN);printf("\n");*/
+mpfr_add(s,s,s2,GMP_RNDN);
+/*mpfr_print_raw(s);printf("\n");
+t=mpfr_out_str(stdout,10,0,s,GMP_RNDN);printf("\n");*/
+mpfr_add(s,s,u,GMP_RNDN);
+/*mpfr_print_raw(s);printf("\n");
+t=mpfr_out_str(stdout,10,0,s,GMP_RNDN);printf("\n");*/
+/*Peut-on arrondir ? La reponse est oui*/
+succes=mpfr_can_round(s,57,GMP_RNDN,GMP_RNDN,53);
+if (succes) mpfr_set(result,s,GMP_RNDN);
+else {
+ fprintf(stderr, "can't round in mpfr_zeta\n"); exit(1);
+}
+
+mpfr_clear(x);
+mpfr_clear(y);
+mpfr_clear(s);
+mpfr_clear(s2);
+mpfr_clear(u);
+mpfr_clear(b);
+mpfr_clear(v);
+mpfr_clear(nn);
+mpfr_clear(z);
+mpfr_clear(z2);
+return 1; /* result is inexact */
+}