diff options
Diffstat (limited to 'mpfr/tests')
173 files changed, 56069 insertions, 0 deletions
diff --git a/mpfr/tests/Makefile.am b/mpfr/tests/Makefile.am new file mode 100644 index 0000000000..465aebd713 --- /dev/null +++ b/mpfr/tests/Makefile.am @@ -0,0 +1,95 @@ +# Copyright 2000-2016 Free Software Foundation, Inc. +# This Makefile.am 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. + + +AUTOMAKE_OPTIONS = 1.6 gnu + +check_PROGRAMS = tversion tinternals tinits tisqrt tsgn tcheck \ + tisnan texceptions tset_exp tset mpf_compat mpfr_compat \ + reuse tabs tacos tacosh tadd tadd1sp tadd_d tadd_ui tagm \ + tai tasin tasinh tatan tatanh taway tbuildopt tcan_round \ + tcbrt tcmp tcmp2 tcmp_d tcmp_ld tcmp_ui tcmpabs \ + tcomparisons tconst_catalan tconst_euler tconst_log2 \ + tconst_pi tcopysign tcos tcosh tcot tcoth tcsc tcsch \ + td_div td_sub tdigamma tdim tdiv tdiv_d tdiv_ui teint teq \ + terf texp texp10 texp2 texpm1 tfactorial tfits tfma tfmod \ + tfms tfprintf tfrac tfrexp tgamma tget_flt tget_d tget_d_2exp \ + tget_f tget_ld_2exp tget_set_d64 tget_sj tget_str tget_z \ + tgmpop tgrandom thyperbolic thypot tinp_str tj0 tj1 tjn tl2b \ + tlgamma tli2 tlngamma tlog tlog10 tlog1p tlog2 tmin_prec \ + tminmax tmodf tmul tmul_2exp tmul_d tmul_ui tnext \ + tout_str toutimpl tpow tpow3 tpow_all tpow_z tprintf \ + trandom trec_sqrt tremquo trint troot tround_prec tsec \ + tsech tset_d tset_f tset_ld tset_q tset_si tset_sj \ + tset_str tset_z tset_z_exp tsi_op tsin tsin_cos tsinh \ + tsinh_cosh tsprintf tsqr tsqrt tsqrt_ui tstckintc tstdint tstrtofr \ + tsub tsub1sp tsub_d tsub_ui tsubnormal tsum tswap ttan \ + ttanh ttrunc tui_div tui_pow tui_sub turandom \ + tvalist ty0 ty1 tyn tzeta tzeta_ui + +# Before Automake 1.13, we ran tversion at the beginning and at the end +# of the tests, and output from tversion appeared at the same place as +# the tests results (make output). With Automake 1.13+, the tests are +# parallelized by default and their output is sent to log files instead +# of the make output, so that the user could no longer see information +# from tversion. To mimic the old behavior, we now output the contents +# of the tversion log file if this file exists (i.e. if the Makefile +# has been generated with Automake 1.13+). +check: + cat tversion.log 2> /dev/null || true + +AM_CPPFLAGS = -DSRCDIR='"$(srcdir)"' + +EXTRA_DIST = tgeneric.c tgeneric_ui.c mpf_compat.h inp_str.data tmul.dat + +LDADD = libfrtests.la $(MPFR_LIBM) $(top_builddir)/src/libmpfr.la +AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src + +# LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS) +# enables to compile a program foo.c in the test directory by simply doing +# "make foo". +# Warning! This is not guaranteed to work, as libtool is not used. In +# particular, this may not work as expected under GNU/Linux if --with-gmp +# has been used, unless the directory is in your $LD_LIBRARY_PATH. +# Moreover, dependencies are not tracked. Thus you may want to run +# "make tversion" (for instance) just before, to make sure that every +# dependency has been rebuilt. +LOADLIBES=$(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(top_builddir)/tests/.libs/libfrtests.a $(top_builddir)/src/.libs/libmpfr.a $(LIBS) $(MPFR_LIBM) + +check_LTLIBRARIES = libfrtests.la +libfrtests_la_SOURCES = mpfr-test.h memory.c rnd_mode.c tests.c cmp_str.c random2.c + +$(top_builddir)/src/libmpfr.la: + cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.la + +TESTS = $(check_PROGRAMS) +TESTS_ENVIRONMENT = MPFR_QUIET=1 $(VALGRIND) + +# The -no-install option prevents libtool from generating wrapper scripts +# for the tests. +# This is useful to easily run the test scripts under valgrind or gdb. +# See discussion http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28033 +# http://article.gmane.org/gmane.comp.lib.gnulib.bugs/28140 in particular. +# +# The -L$(top_builddir)/src/.libs option is necessary for some platforms, +# such as HP-UX, when --with-gmp or --with-gmp-lib is used and an old MPFR +# library is already installed in the corresponding lib directory: its +# purpose is to make sure that the local .libs comes first in the library +# search path (otherwise the tests are linked against the old MPFR library +# by the LINK command -- see the generated Makefile). See: +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00042.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00043.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00044.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00066.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00065.html +# and +# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9728 +# +AM_LDFLAGS = -no-install -L$(top_builddir)/src/.libs diff --git a/mpfr/tests/Makefile.in b/mpfr/tests/Makefile.in new file mode 100644 index 0000000000..d035438698 --- /dev/null +++ b/mpfr/tests/Makefile.in @@ -0,0 +1,3856 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 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. + +@SET_MAKE@ + +# Copyright 2000-2016 Free Software Foundation, Inc. +# This Makefile.am 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. +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = tversion$(EXEEXT) tinternals$(EXEEXT) tinits$(EXEEXT) \ + tisqrt$(EXEEXT) tsgn$(EXEEXT) tcheck$(EXEEXT) tisnan$(EXEEXT) \ + texceptions$(EXEEXT) tset_exp$(EXEEXT) tset$(EXEEXT) \ + mpf_compat$(EXEEXT) mpfr_compat$(EXEEXT) reuse$(EXEEXT) \ + tabs$(EXEEXT) tacos$(EXEEXT) tacosh$(EXEEXT) tadd$(EXEEXT) \ + tadd1sp$(EXEEXT) tadd_d$(EXEEXT) tadd_ui$(EXEEXT) \ + tagm$(EXEEXT) tai$(EXEEXT) tasin$(EXEEXT) tasinh$(EXEEXT) \ + tatan$(EXEEXT) tatanh$(EXEEXT) taway$(EXEEXT) \ + tbuildopt$(EXEEXT) tcan_round$(EXEEXT) tcbrt$(EXEEXT) \ + tcmp$(EXEEXT) tcmp2$(EXEEXT) tcmp_d$(EXEEXT) tcmp_ld$(EXEEXT) \ + tcmp_ui$(EXEEXT) tcmpabs$(EXEEXT) tcomparisons$(EXEEXT) \ + tconst_catalan$(EXEEXT) tconst_euler$(EXEEXT) \ + tconst_log2$(EXEEXT) tconst_pi$(EXEEXT) tcopysign$(EXEEXT) \ + tcos$(EXEEXT) tcosh$(EXEEXT) tcot$(EXEEXT) tcoth$(EXEEXT) \ + tcsc$(EXEEXT) tcsch$(EXEEXT) td_div$(EXEEXT) td_sub$(EXEEXT) \ + tdigamma$(EXEEXT) tdim$(EXEEXT) tdiv$(EXEEXT) tdiv_d$(EXEEXT) \ + tdiv_ui$(EXEEXT) teint$(EXEEXT) teq$(EXEEXT) terf$(EXEEXT) \ + texp$(EXEEXT) texp10$(EXEEXT) texp2$(EXEEXT) texpm1$(EXEEXT) \ + tfactorial$(EXEEXT) tfits$(EXEEXT) tfma$(EXEEXT) \ + tfmod$(EXEEXT) tfms$(EXEEXT) tfprintf$(EXEEXT) tfrac$(EXEEXT) \ + tfrexp$(EXEEXT) tgamma$(EXEEXT) tget_flt$(EXEEXT) \ + tget_d$(EXEEXT) tget_d_2exp$(EXEEXT) tget_f$(EXEEXT) \ + tget_ld_2exp$(EXEEXT) tget_set_d64$(EXEEXT) tget_sj$(EXEEXT) \ + tget_str$(EXEEXT) tget_z$(EXEEXT) tgmpop$(EXEEXT) \ + tgrandom$(EXEEXT) thyperbolic$(EXEEXT) thypot$(EXEEXT) \ + tinp_str$(EXEEXT) tj0$(EXEEXT) tj1$(EXEEXT) tjn$(EXEEXT) \ + tl2b$(EXEEXT) tlgamma$(EXEEXT) tli2$(EXEEXT) tlngamma$(EXEEXT) \ + tlog$(EXEEXT) tlog10$(EXEEXT) tlog1p$(EXEEXT) tlog2$(EXEEXT) \ + tmin_prec$(EXEEXT) tminmax$(EXEEXT) tmodf$(EXEEXT) \ + tmul$(EXEEXT) tmul_2exp$(EXEEXT) tmul_d$(EXEEXT) \ + tmul_ui$(EXEEXT) tnext$(EXEEXT) tout_str$(EXEEXT) \ + toutimpl$(EXEEXT) tpow$(EXEEXT) tpow3$(EXEEXT) \ + tpow_all$(EXEEXT) tpow_z$(EXEEXT) tprintf$(EXEEXT) \ + trandom$(EXEEXT) trec_sqrt$(EXEEXT) tremquo$(EXEEXT) \ + trint$(EXEEXT) troot$(EXEEXT) tround_prec$(EXEEXT) \ + tsec$(EXEEXT) tsech$(EXEEXT) tset_d$(EXEEXT) tset_f$(EXEEXT) \ + tset_ld$(EXEEXT) tset_q$(EXEEXT) tset_si$(EXEEXT) \ + tset_sj$(EXEEXT) tset_str$(EXEEXT) tset_z$(EXEEXT) \ + tset_z_exp$(EXEEXT) tsi_op$(EXEEXT) tsin$(EXEEXT) \ + tsin_cos$(EXEEXT) tsinh$(EXEEXT) tsinh_cosh$(EXEEXT) \ + tsprintf$(EXEEXT) tsqr$(EXEEXT) tsqrt$(EXEEXT) \ + tsqrt_ui$(EXEEXT) tstckintc$(EXEEXT) tstdint$(EXEEXT) \ + tstrtofr$(EXEEXT) tsub$(EXEEXT) tsub1sp$(EXEEXT) \ + tsub_d$(EXEEXT) tsub_ui$(EXEEXT) tsubnormal$(EXEEXT) \ + tsum$(EXEEXT) tswap$(EXEEXT) ttan$(EXEEXT) ttanh$(EXEEXT) \ + ttrunc$(EXEEXT) tui_div$(EXEEXT) tui_pow$(EXEEXT) \ + tui_sub$(EXEEXT) turandom$(EXEEXT) tvalist$(EXEEXT) \ + ty0$(EXEEXT) ty1$(EXEEXT) tyn$(EXEEXT) tzeta$(EXEEXT) \ + tzeta_ui$(EXEEXT) +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +libfrtests_la_LIBADD = +am_libfrtests_la_OBJECTS = memory.lo rnd_mode.lo tests.lo cmp_str.lo \ + random2.lo +libfrtests_la_OBJECTS = $(am_libfrtests_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mpf_compat_SOURCES = mpf_compat.c +mpf_compat_OBJECTS = mpf_compat.$(OBJEXT) +mpf_compat_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +mpf_compat_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +mpfr_compat_SOURCES = mpfr_compat.c +mpfr_compat_OBJECTS = mpfr_compat.$(OBJEXT) +mpfr_compat_LDADD = $(LDADD) +mpfr_compat_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +reuse_SOURCES = reuse.c +reuse_OBJECTS = reuse.$(OBJEXT) +reuse_LDADD = $(LDADD) +reuse_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tabs_SOURCES = tabs.c +tabs_OBJECTS = tabs.$(OBJEXT) +tabs_LDADD = $(LDADD) +tabs_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tacos_SOURCES = tacos.c +tacos_OBJECTS = tacos.$(OBJEXT) +tacos_LDADD = $(LDADD) +tacos_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tacosh_SOURCES = tacosh.c +tacosh_OBJECTS = tacosh.$(OBJEXT) +tacosh_LDADD = $(LDADD) +tacosh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tadd_SOURCES = tadd.c +tadd_OBJECTS = tadd.$(OBJEXT) +tadd_LDADD = $(LDADD) +tadd_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tadd1sp_SOURCES = tadd1sp.c +tadd1sp_OBJECTS = tadd1sp.$(OBJEXT) +tadd1sp_LDADD = $(LDADD) +tadd1sp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tadd_d_SOURCES = tadd_d.c +tadd_d_OBJECTS = tadd_d.$(OBJEXT) +tadd_d_LDADD = $(LDADD) +tadd_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tadd_ui_SOURCES = tadd_ui.c +tadd_ui_OBJECTS = tadd_ui.$(OBJEXT) +tadd_ui_LDADD = $(LDADD) +tadd_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tagm_SOURCES = tagm.c +tagm_OBJECTS = tagm.$(OBJEXT) +tagm_LDADD = $(LDADD) +tagm_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tai_SOURCES = tai.c +tai_OBJECTS = tai.$(OBJEXT) +tai_LDADD = $(LDADD) +tai_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tasin_SOURCES = tasin.c +tasin_OBJECTS = tasin.$(OBJEXT) +tasin_LDADD = $(LDADD) +tasin_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tasinh_SOURCES = tasinh.c +tasinh_OBJECTS = tasinh.$(OBJEXT) +tasinh_LDADD = $(LDADD) +tasinh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tatan_SOURCES = tatan.c +tatan_OBJECTS = tatan.$(OBJEXT) +tatan_LDADD = $(LDADD) +tatan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tatanh_SOURCES = tatanh.c +tatanh_OBJECTS = tatanh.$(OBJEXT) +tatanh_LDADD = $(LDADD) +tatanh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +taway_SOURCES = taway.c +taway_OBJECTS = taway.$(OBJEXT) +taway_LDADD = $(LDADD) +taway_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tbuildopt_SOURCES = tbuildopt.c +tbuildopt_OBJECTS = tbuildopt.$(OBJEXT) +tbuildopt_LDADD = $(LDADD) +tbuildopt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcan_round_SOURCES = tcan_round.c +tcan_round_OBJECTS = tcan_round.$(OBJEXT) +tcan_round_LDADD = $(LDADD) +tcan_round_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcbrt_SOURCES = tcbrt.c +tcbrt_OBJECTS = tcbrt.$(OBJEXT) +tcbrt_LDADD = $(LDADD) +tcbrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcheck_SOURCES = tcheck.c +tcheck_OBJECTS = tcheck.$(OBJEXT) +tcheck_LDADD = $(LDADD) +tcheck_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcmp_SOURCES = tcmp.c +tcmp_OBJECTS = tcmp.$(OBJEXT) +tcmp_LDADD = $(LDADD) +tcmp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcmp2_SOURCES = tcmp2.c +tcmp2_OBJECTS = tcmp2.$(OBJEXT) +tcmp2_LDADD = $(LDADD) +tcmp2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcmp_d_SOURCES = tcmp_d.c +tcmp_d_OBJECTS = tcmp_d.$(OBJEXT) +tcmp_d_LDADD = $(LDADD) +tcmp_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcmp_ld_SOURCES = tcmp_ld.c +tcmp_ld_OBJECTS = tcmp_ld.$(OBJEXT) +tcmp_ld_LDADD = $(LDADD) +tcmp_ld_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcmp_ui_SOURCES = tcmp_ui.c +tcmp_ui_OBJECTS = tcmp_ui.$(OBJEXT) +tcmp_ui_LDADD = $(LDADD) +tcmp_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcmpabs_SOURCES = tcmpabs.c +tcmpabs_OBJECTS = tcmpabs.$(OBJEXT) +tcmpabs_LDADD = $(LDADD) +tcmpabs_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcomparisons_SOURCES = tcomparisons.c +tcomparisons_OBJECTS = tcomparisons.$(OBJEXT) +tcomparisons_LDADD = $(LDADD) +tcomparisons_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tconst_catalan_SOURCES = tconst_catalan.c +tconst_catalan_OBJECTS = tconst_catalan.$(OBJEXT) +tconst_catalan_LDADD = $(LDADD) +tconst_catalan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tconst_euler_SOURCES = tconst_euler.c +tconst_euler_OBJECTS = tconst_euler.$(OBJEXT) +tconst_euler_LDADD = $(LDADD) +tconst_euler_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tconst_log2_SOURCES = tconst_log2.c +tconst_log2_OBJECTS = tconst_log2.$(OBJEXT) +tconst_log2_LDADD = $(LDADD) +tconst_log2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tconst_pi_SOURCES = tconst_pi.c +tconst_pi_OBJECTS = tconst_pi.$(OBJEXT) +tconst_pi_LDADD = $(LDADD) +tconst_pi_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcopysign_SOURCES = tcopysign.c +tcopysign_OBJECTS = tcopysign.$(OBJEXT) +tcopysign_LDADD = $(LDADD) +tcopysign_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcos_SOURCES = tcos.c +tcos_OBJECTS = tcos.$(OBJEXT) +tcos_LDADD = $(LDADD) +tcos_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcosh_SOURCES = tcosh.c +tcosh_OBJECTS = tcosh.$(OBJEXT) +tcosh_LDADD = $(LDADD) +tcosh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcot_SOURCES = tcot.c +tcot_OBJECTS = tcot.$(OBJEXT) +tcot_LDADD = $(LDADD) +tcot_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcoth_SOURCES = tcoth.c +tcoth_OBJECTS = tcoth.$(OBJEXT) +tcoth_LDADD = $(LDADD) +tcoth_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcsc_SOURCES = tcsc.c +tcsc_OBJECTS = tcsc.$(OBJEXT) +tcsc_LDADD = $(LDADD) +tcsc_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tcsch_SOURCES = tcsch.c +tcsch_OBJECTS = tcsch.$(OBJEXT) +tcsch_LDADD = $(LDADD) +tcsch_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +td_div_SOURCES = td_div.c +td_div_OBJECTS = td_div.$(OBJEXT) +td_div_LDADD = $(LDADD) +td_div_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +td_sub_SOURCES = td_sub.c +td_sub_OBJECTS = td_sub.$(OBJEXT) +td_sub_LDADD = $(LDADD) +td_sub_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tdigamma_SOURCES = tdigamma.c +tdigamma_OBJECTS = tdigamma.$(OBJEXT) +tdigamma_LDADD = $(LDADD) +tdigamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tdim_SOURCES = tdim.c +tdim_OBJECTS = tdim.$(OBJEXT) +tdim_LDADD = $(LDADD) +tdim_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tdiv_SOURCES = tdiv.c +tdiv_OBJECTS = tdiv.$(OBJEXT) +tdiv_LDADD = $(LDADD) +tdiv_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tdiv_d_SOURCES = tdiv_d.c +tdiv_d_OBJECTS = tdiv_d.$(OBJEXT) +tdiv_d_LDADD = $(LDADD) +tdiv_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tdiv_ui_SOURCES = tdiv_ui.c +tdiv_ui_OBJECTS = tdiv_ui.$(OBJEXT) +tdiv_ui_LDADD = $(LDADD) +tdiv_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +teint_SOURCES = teint.c +teint_OBJECTS = teint.$(OBJEXT) +teint_LDADD = $(LDADD) +teint_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +teq_SOURCES = teq.c +teq_OBJECTS = teq.$(OBJEXT) +teq_LDADD = $(LDADD) +teq_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +terf_SOURCES = terf.c +terf_OBJECTS = terf.$(OBJEXT) +terf_LDADD = $(LDADD) +terf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +texceptions_SOURCES = texceptions.c +texceptions_OBJECTS = texceptions.$(OBJEXT) +texceptions_LDADD = $(LDADD) +texceptions_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +texp_SOURCES = texp.c +texp_OBJECTS = texp.$(OBJEXT) +texp_LDADD = $(LDADD) +texp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +texp10_SOURCES = texp10.c +texp10_OBJECTS = texp10.$(OBJEXT) +texp10_LDADD = $(LDADD) +texp10_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +texp2_SOURCES = texp2.c +texp2_OBJECTS = texp2.$(OBJEXT) +texp2_LDADD = $(LDADD) +texp2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +texpm1_SOURCES = texpm1.c +texpm1_OBJECTS = texpm1.$(OBJEXT) +texpm1_LDADD = $(LDADD) +texpm1_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfactorial_SOURCES = tfactorial.c +tfactorial_OBJECTS = tfactorial.$(OBJEXT) +tfactorial_LDADD = $(LDADD) +tfactorial_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfits_SOURCES = tfits.c +tfits_OBJECTS = tfits.$(OBJEXT) +tfits_LDADD = $(LDADD) +tfits_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfma_SOURCES = tfma.c +tfma_OBJECTS = tfma.$(OBJEXT) +tfma_LDADD = $(LDADD) +tfma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfmod_SOURCES = tfmod.c +tfmod_OBJECTS = tfmod.$(OBJEXT) +tfmod_LDADD = $(LDADD) +tfmod_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfms_SOURCES = tfms.c +tfms_OBJECTS = tfms.$(OBJEXT) +tfms_LDADD = $(LDADD) +tfms_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfprintf_SOURCES = tfprintf.c +tfprintf_OBJECTS = tfprintf.$(OBJEXT) +tfprintf_LDADD = $(LDADD) +tfprintf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfrac_SOURCES = tfrac.c +tfrac_OBJECTS = tfrac.$(OBJEXT) +tfrac_LDADD = $(LDADD) +tfrac_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tfrexp_SOURCES = tfrexp.c +tfrexp_OBJECTS = tfrexp.$(OBJEXT) +tfrexp_LDADD = $(LDADD) +tfrexp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tgamma_SOURCES = tgamma.c +tgamma_OBJECTS = tgamma.$(OBJEXT) +tgamma_LDADD = $(LDADD) +tgamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_d_SOURCES = tget_d.c +tget_d_OBJECTS = tget_d.$(OBJEXT) +tget_d_LDADD = $(LDADD) +tget_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_d_2exp_SOURCES = tget_d_2exp.c +tget_d_2exp_OBJECTS = tget_d_2exp.$(OBJEXT) +tget_d_2exp_LDADD = $(LDADD) +tget_d_2exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_f_SOURCES = tget_f.c +tget_f_OBJECTS = tget_f.$(OBJEXT) +tget_f_LDADD = $(LDADD) +tget_f_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_flt_SOURCES = tget_flt.c +tget_flt_OBJECTS = tget_flt.$(OBJEXT) +tget_flt_LDADD = $(LDADD) +tget_flt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_ld_2exp_SOURCES = tget_ld_2exp.c +tget_ld_2exp_OBJECTS = tget_ld_2exp.$(OBJEXT) +tget_ld_2exp_LDADD = $(LDADD) +tget_ld_2exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_set_d64_SOURCES = tget_set_d64.c +tget_set_d64_OBJECTS = tget_set_d64.$(OBJEXT) +tget_set_d64_LDADD = $(LDADD) +tget_set_d64_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_sj_SOURCES = tget_sj.c +tget_sj_OBJECTS = tget_sj.$(OBJEXT) +tget_sj_LDADD = $(LDADD) +tget_sj_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_str_SOURCES = tget_str.c +tget_str_OBJECTS = tget_str.$(OBJEXT) +tget_str_LDADD = $(LDADD) +tget_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tget_z_SOURCES = tget_z.c +tget_z_OBJECTS = tget_z.$(OBJEXT) +tget_z_LDADD = $(LDADD) +tget_z_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tgmpop_SOURCES = tgmpop.c +tgmpop_OBJECTS = tgmpop.$(OBJEXT) +tgmpop_LDADD = $(LDADD) +tgmpop_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tgrandom_SOURCES = tgrandom.c +tgrandom_OBJECTS = tgrandom.$(OBJEXT) +tgrandom_LDADD = $(LDADD) +tgrandom_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +thyperbolic_SOURCES = thyperbolic.c +thyperbolic_OBJECTS = thyperbolic.$(OBJEXT) +thyperbolic_LDADD = $(LDADD) +thyperbolic_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +thypot_SOURCES = thypot.c +thypot_OBJECTS = thypot.$(OBJEXT) +thypot_LDADD = $(LDADD) +thypot_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tinits_SOURCES = tinits.c +tinits_OBJECTS = tinits.$(OBJEXT) +tinits_LDADD = $(LDADD) +tinits_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tinp_str_SOURCES = tinp_str.c +tinp_str_OBJECTS = tinp_str.$(OBJEXT) +tinp_str_LDADD = $(LDADD) +tinp_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tinternals_SOURCES = tinternals.c +tinternals_OBJECTS = tinternals.$(OBJEXT) +tinternals_LDADD = $(LDADD) +tinternals_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tisnan_SOURCES = tisnan.c +tisnan_OBJECTS = tisnan.$(OBJEXT) +tisnan_LDADD = $(LDADD) +tisnan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tisqrt_SOURCES = tisqrt.c +tisqrt_OBJECTS = tisqrt.$(OBJEXT) +tisqrt_LDADD = $(LDADD) +tisqrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tj0_SOURCES = tj0.c +tj0_OBJECTS = tj0.$(OBJEXT) +tj0_LDADD = $(LDADD) +tj0_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tj1_SOURCES = tj1.c +tj1_OBJECTS = tj1.$(OBJEXT) +tj1_LDADD = $(LDADD) +tj1_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tjn_SOURCES = tjn.c +tjn_OBJECTS = tjn.$(OBJEXT) +tjn_LDADD = $(LDADD) +tjn_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tl2b_SOURCES = tl2b.c +tl2b_OBJECTS = tl2b.$(OBJEXT) +tl2b_LDADD = $(LDADD) +tl2b_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tlgamma_SOURCES = tlgamma.c +tlgamma_OBJECTS = tlgamma.$(OBJEXT) +tlgamma_LDADD = $(LDADD) +tlgamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tli2_SOURCES = tli2.c +tli2_OBJECTS = tli2.$(OBJEXT) +tli2_LDADD = $(LDADD) +tli2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tlngamma_SOURCES = tlngamma.c +tlngamma_OBJECTS = tlngamma.$(OBJEXT) +tlngamma_LDADD = $(LDADD) +tlngamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tlog_SOURCES = tlog.c +tlog_OBJECTS = tlog.$(OBJEXT) +tlog_LDADD = $(LDADD) +tlog_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tlog10_SOURCES = tlog10.c +tlog10_OBJECTS = tlog10.$(OBJEXT) +tlog10_LDADD = $(LDADD) +tlog10_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tlog1p_SOURCES = tlog1p.c +tlog1p_OBJECTS = tlog1p.$(OBJEXT) +tlog1p_LDADD = $(LDADD) +tlog1p_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tlog2_SOURCES = tlog2.c +tlog2_OBJECTS = tlog2.$(OBJEXT) +tlog2_LDADD = $(LDADD) +tlog2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tmin_prec_SOURCES = tmin_prec.c +tmin_prec_OBJECTS = tmin_prec.$(OBJEXT) +tmin_prec_LDADD = $(LDADD) +tmin_prec_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tminmax_SOURCES = tminmax.c +tminmax_OBJECTS = tminmax.$(OBJEXT) +tminmax_LDADD = $(LDADD) +tminmax_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tmodf_SOURCES = tmodf.c +tmodf_OBJECTS = tmodf.$(OBJEXT) +tmodf_LDADD = $(LDADD) +tmodf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tmul_SOURCES = tmul.c +tmul_OBJECTS = tmul.$(OBJEXT) +tmul_LDADD = $(LDADD) +tmul_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tmul_2exp_SOURCES = tmul_2exp.c +tmul_2exp_OBJECTS = tmul_2exp.$(OBJEXT) +tmul_2exp_LDADD = $(LDADD) +tmul_2exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tmul_d_SOURCES = tmul_d.c +tmul_d_OBJECTS = tmul_d.$(OBJEXT) +tmul_d_LDADD = $(LDADD) +tmul_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tmul_ui_SOURCES = tmul_ui.c +tmul_ui_OBJECTS = tmul_ui.$(OBJEXT) +tmul_ui_LDADD = $(LDADD) +tmul_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tnext_SOURCES = tnext.c +tnext_OBJECTS = tnext.$(OBJEXT) +tnext_LDADD = $(LDADD) +tnext_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tout_str_SOURCES = tout_str.c +tout_str_OBJECTS = tout_str.$(OBJEXT) +tout_str_LDADD = $(LDADD) +tout_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +toutimpl_SOURCES = toutimpl.c +toutimpl_OBJECTS = toutimpl.$(OBJEXT) +toutimpl_LDADD = $(LDADD) +toutimpl_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tpow_SOURCES = tpow.c +tpow_OBJECTS = tpow.$(OBJEXT) +tpow_LDADD = $(LDADD) +tpow_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tpow3_SOURCES = tpow3.c +tpow3_OBJECTS = tpow3.$(OBJEXT) +tpow3_LDADD = $(LDADD) +tpow3_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tpow_all_SOURCES = tpow_all.c +tpow_all_OBJECTS = tpow_all.$(OBJEXT) +tpow_all_LDADD = $(LDADD) +tpow_all_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tpow_z_SOURCES = tpow_z.c +tpow_z_OBJECTS = tpow_z.$(OBJEXT) +tpow_z_LDADD = $(LDADD) +tpow_z_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tprintf_SOURCES = tprintf.c +tprintf_OBJECTS = tprintf.$(OBJEXT) +tprintf_LDADD = $(LDADD) +tprintf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +trandom_SOURCES = trandom.c +trandom_OBJECTS = trandom.$(OBJEXT) +trandom_LDADD = $(LDADD) +trandom_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +trec_sqrt_SOURCES = trec_sqrt.c +trec_sqrt_OBJECTS = trec_sqrt.$(OBJEXT) +trec_sqrt_LDADD = $(LDADD) +trec_sqrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tremquo_SOURCES = tremquo.c +tremquo_OBJECTS = tremquo.$(OBJEXT) +tremquo_LDADD = $(LDADD) +tremquo_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +trint_SOURCES = trint.c +trint_OBJECTS = trint.$(OBJEXT) +trint_LDADD = $(LDADD) +trint_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +troot_SOURCES = troot.c +troot_OBJECTS = troot.$(OBJEXT) +troot_LDADD = $(LDADD) +troot_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tround_prec_SOURCES = tround_prec.c +tround_prec_OBJECTS = tround_prec.$(OBJEXT) +tround_prec_LDADD = $(LDADD) +tround_prec_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsec_SOURCES = tsec.c +tsec_OBJECTS = tsec.$(OBJEXT) +tsec_LDADD = $(LDADD) +tsec_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsech_SOURCES = tsech.c +tsech_OBJECTS = tsech.$(OBJEXT) +tsech_LDADD = $(LDADD) +tsech_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_SOURCES = tset.c +tset_OBJECTS = tset.$(OBJEXT) +tset_LDADD = $(LDADD) +tset_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_d_SOURCES = tset_d.c +tset_d_OBJECTS = tset_d.$(OBJEXT) +tset_d_LDADD = $(LDADD) +tset_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_exp_SOURCES = tset_exp.c +tset_exp_OBJECTS = tset_exp.$(OBJEXT) +tset_exp_LDADD = $(LDADD) +tset_exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_f_SOURCES = tset_f.c +tset_f_OBJECTS = tset_f.$(OBJEXT) +tset_f_LDADD = $(LDADD) +tset_f_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_ld_SOURCES = tset_ld.c +tset_ld_OBJECTS = tset_ld.$(OBJEXT) +tset_ld_LDADD = $(LDADD) +tset_ld_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_q_SOURCES = tset_q.c +tset_q_OBJECTS = tset_q.$(OBJEXT) +tset_q_LDADD = $(LDADD) +tset_q_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_si_SOURCES = tset_si.c +tset_si_OBJECTS = tset_si.$(OBJEXT) +tset_si_LDADD = $(LDADD) +tset_si_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_sj_SOURCES = tset_sj.c +tset_sj_OBJECTS = tset_sj.$(OBJEXT) +tset_sj_LDADD = $(LDADD) +tset_sj_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_str_SOURCES = tset_str.c +tset_str_OBJECTS = tset_str.$(OBJEXT) +tset_str_LDADD = $(LDADD) +tset_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_z_SOURCES = tset_z.c +tset_z_OBJECTS = tset_z.$(OBJEXT) +tset_z_LDADD = $(LDADD) +tset_z_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tset_z_exp_SOURCES = tset_z_exp.c +tset_z_exp_OBJECTS = tset_z_exp.$(OBJEXT) +tset_z_exp_LDADD = $(LDADD) +tset_z_exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsgn_SOURCES = tsgn.c +tsgn_OBJECTS = tsgn.$(OBJEXT) +tsgn_LDADD = $(LDADD) +tsgn_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsi_op_SOURCES = tsi_op.c +tsi_op_OBJECTS = tsi_op.$(OBJEXT) +tsi_op_LDADD = $(LDADD) +tsi_op_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsin_SOURCES = tsin.c +tsin_OBJECTS = tsin.$(OBJEXT) +tsin_LDADD = $(LDADD) +tsin_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsin_cos_SOURCES = tsin_cos.c +tsin_cos_OBJECTS = tsin_cos.$(OBJEXT) +tsin_cos_LDADD = $(LDADD) +tsin_cos_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsinh_SOURCES = tsinh.c +tsinh_OBJECTS = tsinh.$(OBJEXT) +tsinh_LDADD = $(LDADD) +tsinh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsinh_cosh_SOURCES = tsinh_cosh.c +tsinh_cosh_OBJECTS = tsinh_cosh.$(OBJEXT) +tsinh_cosh_LDADD = $(LDADD) +tsinh_cosh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsprintf_SOURCES = tsprintf.c +tsprintf_OBJECTS = tsprintf.$(OBJEXT) +tsprintf_LDADD = $(LDADD) +tsprintf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsqr_SOURCES = tsqr.c +tsqr_OBJECTS = tsqr.$(OBJEXT) +tsqr_LDADD = $(LDADD) +tsqr_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsqrt_SOURCES = tsqrt.c +tsqrt_OBJECTS = tsqrt.$(OBJEXT) +tsqrt_LDADD = $(LDADD) +tsqrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsqrt_ui_SOURCES = tsqrt_ui.c +tsqrt_ui_OBJECTS = tsqrt_ui.$(OBJEXT) +tsqrt_ui_LDADD = $(LDADD) +tsqrt_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tstckintc_SOURCES = tstckintc.c +tstckintc_OBJECTS = tstckintc.$(OBJEXT) +tstckintc_LDADD = $(LDADD) +tstckintc_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tstdint_SOURCES = tstdint.c +tstdint_OBJECTS = tstdint.$(OBJEXT) +tstdint_LDADD = $(LDADD) +tstdint_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tstrtofr_SOURCES = tstrtofr.c +tstrtofr_OBJECTS = tstrtofr.$(OBJEXT) +tstrtofr_LDADD = $(LDADD) +tstrtofr_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsub_SOURCES = tsub.c +tsub_OBJECTS = tsub.$(OBJEXT) +tsub_LDADD = $(LDADD) +tsub_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsub1sp_SOURCES = tsub1sp.c +tsub1sp_OBJECTS = tsub1sp.$(OBJEXT) +tsub1sp_LDADD = $(LDADD) +tsub1sp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsub_d_SOURCES = tsub_d.c +tsub_d_OBJECTS = tsub_d.$(OBJEXT) +tsub_d_LDADD = $(LDADD) +tsub_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsub_ui_SOURCES = tsub_ui.c +tsub_ui_OBJECTS = tsub_ui.$(OBJEXT) +tsub_ui_LDADD = $(LDADD) +tsub_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsubnormal_SOURCES = tsubnormal.c +tsubnormal_OBJECTS = tsubnormal.$(OBJEXT) +tsubnormal_LDADD = $(LDADD) +tsubnormal_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tsum_SOURCES = tsum.c +tsum_OBJECTS = tsum.$(OBJEXT) +tsum_LDADD = $(LDADD) +tsum_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tswap_SOURCES = tswap.c +tswap_OBJECTS = tswap.$(OBJEXT) +tswap_LDADD = $(LDADD) +tswap_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +ttan_SOURCES = ttan.c +ttan_OBJECTS = ttan.$(OBJEXT) +ttan_LDADD = $(LDADD) +ttan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +ttanh_SOURCES = ttanh.c +ttanh_OBJECTS = ttanh.$(OBJEXT) +ttanh_LDADD = $(LDADD) +ttanh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +ttrunc_SOURCES = ttrunc.c +ttrunc_OBJECTS = ttrunc.$(OBJEXT) +ttrunc_LDADD = $(LDADD) +ttrunc_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tui_div_SOURCES = tui_div.c +tui_div_OBJECTS = tui_div.$(OBJEXT) +tui_div_LDADD = $(LDADD) +tui_div_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tui_pow_SOURCES = tui_pow.c +tui_pow_OBJECTS = tui_pow.$(OBJEXT) +tui_pow_LDADD = $(LDADD) +tui_pow_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tui_sub_SOURCES = tui_sub.c +tui_sub_OBJECTS = tui_sub.$(OBJEXT) +tui_sub_LDADD = $(LDADD) +tui_sub_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +turandom_SOURCES = turandom.c +turandom_OBJECTS = turandom.$(OBJEXT) +turandom_LDADD = $(LDADD) +turandom_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tvalist_SOURCES = tvalist.c +tvalist_OBJECTS = tvalist.$(OBJEXT) +tvalist_LDADD = $(LDADD) +tvalist_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tversion_SOURCES = tversion.c +tversion_OBJECTS = tversion.$(OBJEXT) +tversion_LDADD = $(LDADD) +tversion_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +ty0_SOURCES = ty0.c +ty0_OBJECTS = ty0.$(OBJEXT) +ty0_LDADD = $(LDADD) +ty0_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +ty1_SOURCES = ty1.c +ty1_OBJECTS = ty1.$(OBJEXT) +ty1_LDADD = $(LDADD) +ty1_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tyn_SOURCES = tyn.c +tyn_OBJECTS = tyn.$(OBJEXT) +tyn_LDADD = $(LDADD) +tyn_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tzeta_SOURCES = tzeta.c +tzeta_OBJECTS = tzeta.$(OBJEXT) +tzeta_LDADD = $(LDADD) +tzeta_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +tzeta_ui_SOURCES = tzeta_ui.c +tzeta_ui_OBJECTS = tzeta_ui.$(OBJEXT) +tzeta_ui_LDADD = $(LDADD) +tzeta_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/libmpfr.la +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libfrtests_la_SOURCES) mpf_compat.c mpfr_compat.c reuse.c \ + tabs.c tacos.c tacosh.c tadd.c tadd1sp.c tadd_d.c tadd_ui.c \ + tagm.c tai.c tasin.c tasinh.c tatan.c tatanh.c taway.c \ + tbuildopt.c tcan_round.c tcbrt.c tcheck.c tcmp.c tcmp2.c \ + tcmp_d.c tcmp_ld.c tcmp_ui.c tcmpabs.c tcomparisons.c \ + tconst_catalan.c tconst_euler.c tconst_log2.c tconst_pi.c \ + tcopysign.c tcos.c tcosh.c tcot.c tcoth.c tcsc.c tcsch.c \ + td_div.c td_sub.c tdigamma.c tdim.c tdiv.c tdiv_d.c tdiv_ui.c \ + teint.c teq.c terf.c texceptions.c texp.c texp10.c texp2.c \ + texpm1.c tfactorial.c tfits.c tfma.c tfmod.c tfms.c tfprintf.c \ + tfrac.c tfrexp.c tgamma.c tget_d.c tget_d_2exp.c tget_f.c \ + tget_flt.c tget_ld_2exp.c tget_set_d64.c tget_sj.c tget_str.c \ + tget_z.c tgmpop.c tgrandom.c thyperbolic.c thypot.c tinits.c \ + tinp_str.c tinternals.c tisnan.c tisqrt.c tj0.c tj1.c tjn.c \ + tl2b.c tlgamma.c tli2.c tlngamma.c tlog.c tlog10.c tlog1p.c \ + tlog2.c tmin_prec.c tminmax.c tmodf.c tmul.c tmul_2exp.c \ + tmul_d.c tmul_ui.c tnext.c tout_str.c toutimpl.c tpow.c \ + tpow3.c tpow_all.c tpow_z.c tprintf.c trandom.c trec_sqrt.c \ + tremquo.c trint.c troot.c tround_prec.c tsec.c tsech.c tset.c \ + tset_d.c tset_exp.c tset_f.c tset_ld.c tset_q.c tset_si.c \ + tset_sj.c tset_str.c tset_z.c tset_z_exp.c tsgn.c tsi_op.c \ + tsin.c tsin_cos.c tsinh.c tsinh_cosh.c tsprintf.c tsqr.c \ + tsqrt.c tsqrt_ui.c tstckintc.c tstdint.c tstrtofr.c tsub.c \ + tsub1sp.c tsub_d.c tsub_ui.c tsubnormal.c tsum.c tswap.c \ + ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c \ + turandom.c tvalist.c tversion.c ty0.c ty1.c tyn.c tzeta.c \ + tzeta_ui.c +DIST_SOURCES = $(libfrtests_la_SOURCES) mpf_compat.c mpfr_compat.c \ + reuse.c tabs.c tacos.c tacosh.c tadd.c tadd1sp.c tadd_d.c \ + tadd_ui.c tagm.c tai.c tasin.c tasinh.c tatan.c tatanh.c \ + taway.c tbuildopt.c tcan_round.c tcbrt.c tcheck.c tcmp.c \ + tcmp2.c tcmp_d.c tcmp_ld.c tcmp_ui.c tcmpabs.c tcomparisons.c \ + tconst_catalan.c tconst_euler.c tconst_log2.c tconst_pi.c \ + tcopysign.c tcos.c tcosh.c tcot.c tcoth.c tcsc.c tcsch.c \ + td_div.c td_sub.c tdigamma.c tdim.c tdiv.c tdiv_d.c tdiv_ui.c \ + teint.c teq.c terf.c texceptions.c texp.c texp10.c texp2.c \ + texpm1.c tfactorial.c tfits.c tfma.c tfmod.c tfms.c tfprintf.c \ + tfrac.c tfrexp.c tgamma.c tget_d.c tget_d_2exp.c tget_f.c \ + tget_flt.c tget_ld_2exp.c tget_set_d64.c tget_sj.c tget_str.c \ + tget_z.c tgmpop.c tgrandom.c thyperbolic.c thypot.c tinits.c \ + tinp_str.c tinternals.c tisnan.c tisqrt.c tj0.c tj1.c tjn.c \ + tl2b.c tlgamma.c tli2.c tlngamma.c tlog.c tlog10.c tlog1p.c \ + tlog2.c tmin_prec.c tminmax.c tmodf.c tmul.c tmul_2exp.c \ + tmul_d.c tmul_ui.c tnext.c tout_str.c toutimpl.c tpow.c \ + tpow3.c tpow_all.c tpow_z.c tprintf.c trandom.c trec_sqrt.c \ + tremquo.c trint.c troot.c tround_prec.c tsec.c tsech.c tset.c \ + tset_d.c tset_exp.c tset_f.c tset_ld.c tset_q.c tset_si.c \ + tset_sj.c tset_str.c tset_z.c tset_z_exp.c tsgn.c tsi_op.c \ + tsin.c tsin_cos.c tsinh.c tsinh_cosh.c tsprintf.c tsqr.c \ + tsqrt.c tsqrt_ui.c tstckintc.c tstdint.c tstrtofr.c tsub.c \ + tsub1sp.c tsub_d.c tsub_ui.c tsubnormal.c tsum.c tswap.c \ + ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c \ + turandom.c tvalist.c tversion.c ty0.c ty1.c tyn.c tzeta.c \ + tzeta_ui.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATAFILES = @DATAFILES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBMPFR_LDFLAGS = @LIBMPFR_LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPFR_LDFLAGS = @MPFR_LDFLAGS@ +MPFR_LIBM = @MPFR_LIBM@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TUNE_LIBS = @TUNE_LIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = 1.6 gnu +AM_CPPFLAGS = -DSRCDIR='"$(srcdir)"' -I$(top_srcdir)/src \ + -I$(top_builddir)/src +EXTRA_DIST = tgeneric.c tgeneric_ui.c mpf_compat.h inp_str.data tmul.dat +LDADD = libfrtests.la $(MPFR_LIBM) $(top_builddir)/src/libmpfr.la + +# LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS) +# enables to compile a program foo.c in the test directory by simply doing +# "make foo". +# Warning! This is not guaranteed to work, as libtool is not used. In +# particular, this may not work as expected under GNU/Linux if --with-gmp +# has been used, unless the directory is in your $LD_LIBRARY_PATH. +# Moreover, dependencies are not tracked. Thus you may want to run +# "make tversion" (for instance) just before, to make sure that every +# dependency has been rebuilt. +LOADLIBES = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(top_builddir)/tests/.libs/libfrtests.a $(top_builddir)/src/.libs/libmpfr.a $(LIBS) $(MPFR_LIBM) +check_LTLIBRARIES = libfrtests.la +libfrtests_la_SOURCES = mpfr-test.h memory.c rnd_mode.c tests.c cmp_str.c random2.c +TESTS = $(check_PROGRAMS) +TESTS_ENVIRONMENT = MPFR_QUIET=1 $(VALGRIND) + +# The -no-install option prevents libtool from generating wrapper scripts +# for the tests. +# This is useful to easily run the test scripts under valgrind or gdb. +# See discussion http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28033 +# http://article.gmane.org/gmane.comp.lib.gnulib.bugs/28140 in particular. +# +# The -L$(top_builddir)/src/.libs option is necessary for some platforms, +# such as HP-UX, when --with-gmp or --with-gmp-lib is used and an old MPFR +# library is already installed in the corresponding lib directory: its +# purpose is to make sure that the local .libs comes first in the library +# search path (otherwise the tests are linked against the old MPFR library +# by the LINK command -- see the generated Makefile). See: +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00042.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00043.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00044.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00066.html +# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00065.html +# and +# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9728 +# +AM_LDFLAGS = -no-install -L$(top_builddir)/src/.libs +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libfrtests.la: $(libfrtests_la_OBJECTS) $(libfrtests_la_DEPENDENCIES) $(EXTRA_libfrtests_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libfrtests_la_OBJECTS) $(libfrtests_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +mpf_compat$(EXEEXT): $(mpf_compat_OBJECTS) $(mpf_compat_DEPENDENCIES) $(EXTRA_mpf_compat_DEPENDENCIES) + @rm -f mpf_compat$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(mpf_compat_OBJECTS) $(mpf_compat_LDADD) $(LIBS) + +mpfr_compat$(EXEEXT): $(mpfr_compat_OBJECTS) $(mpfr_compat_DEPENDENCIES) $(EXTRA_mpfr_compat_DEPENDENCIES) + @rm -f mpfr_compat$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(mpfr_compat_OBJECTS) $(mpfr_compat_LDADD) $(LIBS) + +reuse$(EXEEXT): $(reuse_OBJECTS) $(reuse_DEPENDENCIES) $(EXTRA_reuse_DEPENDENCIES) + @rm -f reuse$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(reuse_OBJECTS) $(reuse_LDADD) $(LIBS) + +tabs$(EXEEXT): $(tabs_OBJECTS) $(tabs_DEPENDENCIES) $(EXTRA_tabs_DEPENDENCIES) + @rm -f tabs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tabs_OBJECTS) $(tabs_LDADD) $(LIBS) + +tacos$(EXEEXT): $(tacos_OBJECTS) $(tacos_DEPENDENCIES) $(EXTRA_tacos_DEPENDENCIES) + @rm -f tacos$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tacos_OBJECTS) $(tacos_LDADD) $(LIBS) + +tacosh$(EXEEXT): $(tacosh_OBJECTS) $(tacosh_DEPENDENCIES) $(EXTRA_tacosh_DEPENDENCIES) + @rm -f tacosh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tacosh_OBJECTS) $(tacosh_LDADD) $(LIBS) + +tadd$(EXEEXT): $(tadd_OBJECTS) $(tadd_DEPENDENCIES) $(EXTRA_tadd_DEPENDENCIES) + @rm -f tadd$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tadd_OBJECTS) $(tadd_LDADD) $(LIBS) + +tadd1sp$(EXEEXT): $(tadd1sp_OBJECTS) $(tadd1sp_DEPENDENCIES) $(EXTRA_tadd1sp_DEPENDENCIES) + @rm -f tadd1sp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tadd1sp_OBJECTS) $(tadd1sp_LDADD) $(LIBS) + +tadd_d$(EXEEXT): $(tadd_d_OBJECTS) $(tadd_d_DEPENDENCIES) $(EXTRA_tadd_d_DEPENDENCIES) + @rm -f tadd_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tadd_d_OBJECTS) $(tadd_d_LDADD) $(LIBS) + +tadd_ui$(EXEEXT): $(tadd_ui_OBJECTS) $(tadd_ui_DEPENDENCIES) $(EXTRA_tadd_ui_DEPENDENCIES) + @rm -f tadd_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tadd_ui_OBJECTS) $(tadd_ui_LDADD) $(LIBS) + +tagm$(EXEEXT): $(tagm_OBJECTS) $(tagm_DEPENDENCIES) $(EXTRA_tagm_DEPENDENCIES) + @rm -f tagm$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tagm_OBJECTS) $(tagm_LDADD) $(LIBS) + +tai$(EXEEXT): $(tai_OBJECTS) $(tai_DEPENDENCIES) $(EXTRA_tai_DEPENDENCIES) + @rm -f tai$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tai_OBJECTS) $(tai_LDADD) $(LIBS) + +tasin$(EXEEXT): $(tasin_OBJECTS) $(tasin_DEPENDENCIES) $(EXTRA_tasin_DEPENDENCIES) + @rm -f tasin$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tasin_OBJECTS) $(tasin_LDADD) $(LIBS) + +tasinh$(EXEEXT): $(tasinh_OBJECTS) $(tasinh_DEPENDENCIES) $(EXTRA_tasinh_DEPENDENCIES) + @rm -f tasinh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tasinh_OBJECTS) $(tasinh_LDADD) $(LIBS) + +tatan$(EXEEXT): $(tatan_OBJECTS) $(tatan_DEPENDENCIES) $(EXTRA_tatan_DEPENDENCIES) + @rm -f tatan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tatan_OBJECTS) $(tatan_LDADD) $(LIBS) + +tatanh$(EXEEXT): $(tatanh_OBJECTS) $(tatanh_DEPENDENCIES) $(EXTRA_tatanh_DEPENDENCIES) + @rm -f tatanh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tatanh_OBJECTS) $(tatanh_LDADD) $(LIBS) + +taway$(EXEEXT): $(taway_OBJECTS) $(taway_DEPENDENCIES) $(EXTRA_taway_DEPENDENCIES) + @rm -f taway$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(taway_OBJECTS) $(taway_LDADD) $(LIBS) + +tbuildopt$(EXEEXT): $(tbuildopt_OBJECTS) $(tbuildopt_DEPENDENCIES) $(EXTRA_tbuildopt_DEPENDENCIES) + @rm -f tbuildopt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tbuildopt_OBJECTS) $(tbuildopt_LDADD) $(LIBS) + +tcan_round$(EXEEXT): $(tcan_round_OBJECTS) $(tcan_round_DEPENDENCIES) $(EXTRA_tcan_round_DEPENDENCIES) + @rm -f tcan_round$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcan_round_OBJECTS) $(tcan_round_LDADD) $(LIBS) + +tcbrt$(EXEEXT): $(tcbrt_OBJECTS) $(tcbrt_DEPENDENCIES) $(EXTRA_tcbrt_DEPENDENCIES) + @rm -f tcbrt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcbrt_OBJECTS) $(tcbrt_LDADD) $(LIBS) + +tcheck$(EXEEXT): $(tcheck_OBJECTS) $(tcheck_DEPENDENCIES) $(EXTRA_tcheck_DEPENDENCIES) + @rm -f tcheck$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcheck_OBJECTS) $(tcheck_LDADD) $(LIBS) + +tcmp$(EXEEXT): $(tcmp_OBJECTS) $(tcmp_DEPENDENCIES) $(EXTRA_tcmp_DEPENDENCIES) + @rm -f tcmp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcmp_OBJECTS) $(tcmp_LDADD) $(LIBS) + +tcmp2$(EXEEXT): $(tcmp2_OBJECTS) $(tcmp2_DEPENDENCIES) $(EXTRA_tcmp2_DEPENDENCIES) + @rm -f tcmp2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcmp2_OBJECTS) $(tcmp2_LDADD) $(LIBS) + +tcmp_d$(EXEEXT): $(tcmp_d_OBJECTS) $(tcmp_d_DEPENDENCIES) $(EXTRA_tcmp_d_DEPENDENCIES) + @rm -f tcmp_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcmp_d_OBJECTS) $(tcmp_d_LDADD) $(LIBS) + +tcmp_ld$(EXEEXT): $(tcmp_ld_OBJECTS) $(tcmp_ld_DEPENDENCIES) $(EXTRA_tcmp_ld_DEPENDENCIES) + @rm -f tcmp_ld$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcmp_ld_OBJECTS) $(tcmp_ld_LDADD) $(LIBS) + +tcmp_ui$(EXEEXT): $(tcmp_ui_OBJECTS) $(tcmp_ui_DEPENDENCIES) $(EXTRA_tcmp_ui_DEPENDENCIES) + @rm -f tcmp_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcmp_ui_OBJECTS) $(tcmp_ui_LDADD) $(LIBS) + +tcmpabs$(EXEEXT): $(tcmpabs_OBJECTS) $(tcmpabs_DEPENDENCIES) $(EXTRA_tcmpabs_DEPENDENCIES) + @rm -f tcmpabs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcmpabs_OBJECTS) $(tcmpabs_LDADD) $(LIBS) + +tcomparisons$(EXEEXT): $(tcomparisons_OBJECTS) $(tcomparisons_DEPENDENCIES) $(EXTRA_tcomparisons_DEPENDENCIES) + @rm -f tcomparisons$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcomparisons_OBJECTS) $(tcomparisons_LDADD) $(LIBS) + +tconst_catalan$(EXEEXT): $(tconst_catalan_OBJECTS) $(tconst_catalan_DEPENDENCIES) $(EXTRA_tconst_catalan_DEPENDENCIES) + @rm -f tconst_catalan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tconst_catalan_OBJECTS) $(tconst_catalan_LDADD) $(LIBS) + +tconst_euler$(EXEEXT): $(tconst_euler_OBJECTS) $(tconst_euler_DEPENDENCIES) $(EXTRA_tconst_euler_DEPENDENCIES) + @rm -f tconst_euler$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tconst_euler_OBJECTS) $(tconst_euler_LDADD) $(LIBS) + +tconst_log2$(EXEEXT): $(tconst_log2_OBJECTS) $(tconst_log2_DEPENDENCIES) $(EXTRA_tconst_log2_DEPENDENCIES) + @rm -f tconst_log2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tconst_log2_OBJECTS) $(tconst_log2_LDADD) $(LIBS) + +tconst_pi$(EXEEXT): $(tconst_pi_OBJECTS) $(tconst_pi_DEPENDENCIES) $(EXTRA_tconst_pi_DEPENDENCIES) + @rm -f tconst_pi$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tconst_pi_OBJECTS) $(tconst_pi_LDADD) $(LIBS) + +tcopysign$(EXEEXT): $(tcopysign_OBJECTS) $(tcopysign_DEPENDENCIES) $(EXTRA_tcopysign_DEPENDENCIES) + @rm -f tcopysign$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcopysign_OBJECTS) $(tcopysign_LDADD) $(LIBS) + +tcos$(EXEEXT): $(tcos_OBJECTS) $(tcos_DEPENDENCIES) $(EXTRA_tcos_DEPENDENCIES) + @rm -f tcos$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcos_OBJECTS) $(tcos_LDADD) $(LIBS) + +tcosh$(EXEEXT): $(tcosh_OBJECTS) $(tcosh_DEPENDENCIES) $(EXTRA_tcosh_DEPENDENCIES) + @rm -f tcosh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcosh_OBJECTS) $(tcosh_LDADD) $(LIBS) + +tcot$(EXEEXT): $(tcot_OBJECTS) $(tcot_DEPENDENCIES) $(EXTRA_tcot_DEPENDENCIES) + @rm -f tcot$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcot_OBJECTS) $(tcot_LDADD) $(LIBS) + +tcoth$(EXEEXT): $(tcoth_OBJECTS) $(tcoth_DEPENDENCIES) $(EXTRA_tcoth_DEPENDENCIES) + @rm -f tcoth$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcoth_OBJECTS) $(tcoth_LDADD) $(LIBS) + +tcsc$(EXEEXT): $(tcsc_OBJECTS) $(tcsc_DEPENDENCIES) $(EXTRA_tcsc_DEPENDENCIES) + @rm -f tcsc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcsc_OBJECTS) $(tcsc_LDADD) $(LIBS) + +tcsch$(EXEEXT): $(tcsch_OBJECTS) $(tcsch_DEPENDENCIES) $(EXTRA_tcsch_DEPENDENCIES) + @rm -f tcsch$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tcsch_OBJECTS) $(tcsch_LDADD) $(LIBS) + +td_div$(EXEEXT): $(td_div_OBJECTS) $(td_div_DEPENDENCIES) $(EXTRA_td_div_DEPENDENCIES) + @rm -f td_div$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(td_div_OBJECTS) $(td_div_LDADD) $(LIBS) + +td_sub$(EXEEXT): $(td_sub_OBJECTS) $(td_sub_DEPENDENCIES) $(EXTRA_td_sub_DEPENDENCIES) + @rm -f td_sub$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(td_sub_OBJECTS) $(td_sub_LDADD) $(LIBS) + +tdigamma$(EXEEXT): $(tdigamma_OBJECTS) $(tdigamma_DEPENDENCIES) $(EXTRA_tdigamma_DEPENDENCIES) + @rm -f tdigamma$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tdigamma_OBJECTS) $(tdigamma_LDADD) $(LIBS) + +tdim$(EXEEXT): $(tdim_OBJECTS) $(tdim_DEPENDENCIES) $(EXTRA_tdim_DEPENDENCIES) + @rm -f tdim$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tdim_OBJECTS) $(tdim_LDADD) $(LIBS) + +tdiv$(EXEEXT): $(tdiv_OBJECTS) $(tdiv_DEPENDENCIES) $(EXTRA_tdiv_DEPENDENCIES) + @rm -f tdiv$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tdiv_OBJECTS) $(tdiv_LDADD) $(LIBS) + +tdiv_d$(EXEEXT): $(tdiv_d_OBJECTS) $(tdiv_d_DEPENDENCIES) $(EXTRA_tdiv_d_DEPENDENCIES) + @rm -f tdiv_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tdiv_d_OBJECTS) $(tdiv_d_LDADD) $(LIBS) + +tdiv_ui$(EXEEXT): $(tdiv_ui_OBJECTS) $(tdiv_ui_DEPENDENCIES) $(EXTRA_tdiv_ui_DEPENDENCIES) + @rm -f tdiv_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tdiv_ui_OBJECTS) $(tdiv_ui_LDADD) $(LIBS) + +teint$(EXEEXT): $(teint_OBJECTS) $(teint_DEPENDENCIES) $(EXTRA_teint_DEPENDENCIES) + @rm -f teint$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(teint_OBJECTS) $(teint_LDADD) $(LIBS) + +teq$(EXEEXT): $(teq_OBJECTS) $(teq_DEPENDENCIES) $(EXTRA_teq_DEPENDENCIES) + @rm -f teq$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(teq_OBJECTS) $(teq_LDADD) $(LIBS) + +terf$(EXEEXT): $(terf_OBJECTS) $(terf_DEPENDENCIES) $(EXTRA_terf_DEPENDENCIES) + @rm -f terf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(terf_OBJECTS) $(terf_LDADD) $(LIBS) + +texceptions$(EXEEXT): $(texceptions_OBJECTS) $(texceptions_DEPENDENCIES) $(EXTRA_texceptions_DEPENDENCIES) + @rm -f texceptions$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(texceptions_OBJECTS) $(texceptions_LDADD) $(LIBS) + +texp$(EXEEXT): $(texp_OBJECTS) $(texp_DEPENDENCIES) $(EXTRA_texp_DEPENDENCIES) + @rm -f texp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(texp_OBJECTS) $(texp_LDADD) $(LIBS) + +texp10$(EXEEXT): $(texp10_OBJECTS) $(texp10_DEPENDENCIES) $(EXTRA_texp10_DEPENDENCIES) + @rm -f texp10$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(texp10_OBJECTS) $(texp10_LDADD) $(LIBS) + +texp2$(EXEEXT): $(texp2_OBJECTS) $(texp2_DEPENDENCIES) $(EXTRA_texp2_DEPENDENCIES) + @rm -f texp2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(texp2_OBJECTS) $(texp2_LDADD) $(LIBS) + +texpm1$(EXEEXT): $(texpm1_OBJECTS) $(texpm1_DEPENDENCIES) $(EXTRA_texpm1_DEPENDENCIES) + @rm -f texpm1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(texpm1_OBJECTS) $(texpm1_LDADD) $(LIBS) + +tfactorial$(EXEEXT): $(tfactorial_OBJECTS) $(tfactorial_DEPENDENCIES) $(EXTRA_tfactorial_DEPENDENCIES) + @rm -f tfactorial$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfactorial_OBJECTS) $(tfactorial_LDADD) $(LIBS) + +tfits$(EXEEXT): $(tfits_OBJECTS) $(tfits_DEPENDENCIES) $(EXTRA_tfits_DEPENDENCIES) + @rm -f tfits$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfits_OBJECTS) $(tfits_LDADD) $(LIBS) + +tfma$(EXEEXT): $(tfma_OBJECTS) $(tfma_DEPENDENCIES) $(EXTRA_tfma_DEPENDENCIES) + @rm -f tfma$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfma_OBJECTS) $(tfma_LDADD) $(LIBS) + +tfmod$(EXEEXT): $(tfmod_OBJECTS) $(tfmod_DEPENDENCIES) $(EXTRA_tfmod_DEPENDENCIES) + @rm -f tfmod$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfmod_OBJECTS) $(tfmod_LDADD) $(LIBS) + +tfms$(EXEEXT): $(tfms_OBJECTS) $(tfms_DEPENDENCIES) $(EXTRA_tfms_DEPENDENCIES) + @rm -f tfms$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfms_OBJECTS) $(tfms_LDADD) $(LIBS) + +tfprintf$(EXEEXT): $(tfprintf_OBJECTS) $(tfprintf_DEPENDENCIES) $(EXTRA_tfprintf_DEPENDENCIES) + @rm -f tfprintf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfprintf_OBJECTS) $(tfprintf_LDADD) $(LIBS) + +tfrac$(EXEEXT): $(tfrac_OBJECTS) $(tfrac_DEPENDENCIES) $(EXTRA_tfrac_DEPENDENCIES) + @rm -f tfrac$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfrac_OBJECTS) $(tfrac_LDADD) $(LIBS) + +tfrexp$(EXEEXT): $(tfrexp_OBJECTS) $(tfrexp_DEPENDENCIES) $(EXTRA_tfrexp_DEPENDENCIES) + @rm -f tfrexp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tfrexp_OBJECTS) $(tfrexp_LDADD) $(LIBS) + +tgamma$(EXEEXT): $(tgamma_OBJECTS) $(tgamma_DEPENDENCIES) $(EXTRA_tgamma_DEPENDENCIES) + @rm -f tgamma$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tgamma_OBJECTS) $(tgamma_LDADD) $(LIBS) + +tget_d$(EXEEXT): $(tget_d_OBJECTS) $(tget_d_DEPENDENCIES) $(EXTRA_tget_d_DEPENDENCIES) + @rm -f tget_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_d_OBJECTS) $(tget_d_LDADD) $(LIBS) + +tget_d_2exp$(EXEEXT): $(tget_d_2exp_OBJECTS) $(tget_d_2exp_DEPENDENCIES) $(EXTRA_tget_d_2exp_DEPENDENCIES) + @rm -f tget_d_2exp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_d_2exp_OBJECTS) $(tget_d_2exp_LDADD) $(LIBS) + +tget_f$(EXEEXT): $(tget_f_OBJECTS) $(tget_f_DEPENDENCIES) $(EXTRA_tget_f_DEPENDENCIES) + @rm -f tget_f$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_f_OBJECTS) $(tget_f_LDADD) $(LIBS) + +tget_flt$(EXEEXT): $(tget_flt_OBJECTS) $(tget_flt_DEPENDENCIES) $(EXTRA_tget_flt_DEPENDENCIES) + @rm -f tget_flt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_flt_OBJECTS) $(tget_flt_LDADD) $(LIBS) + +tget_ld_2exp$(EXEEXT): $(tget_ld_2exp_OBJECTS) $(tget_ld_2exp_DEPENDENCIES) $(EXTRA_tget_ld_2exp_DEPENDENCIES) + @rm -f tget_ld_2exp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_ld_2exp_OBJECTS) $(tget_ld_2exp_LDADD) $(LIBS) + +tget_set_d64$(EXEEXT): $(tget_set_d64_OBJECTS) $(tget_set_d64_DEPENDENCIES) $(EXTRA_tget_set_d64_DEPENDENCIES) + @rm -f tget_set_d64$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_set_d64_OBJECTS) $(tget_set_d64_LDADD) $(LIBS) + +tget_sj$(EXEEXT): $(tget_sj_OBJECTS) $(tget_sj_DEPENDENCIES) $(EXTRA_tget_sj_DEPENDENCIES) + @rm -f tget_sj$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_sj_OBJECTS) $(tget_sj_LDADD) $(LIBS) + +tget_str$(EXEEXT): $(tget_str_OBJECTS) $(tget_str_DEPENDENCIES) $(EXTRA_tget_str_DEPENDENCIES) + @rm -f tget_str$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_str_OBJECTS) $(tget_str_LDADD) $(LIBS) + +tget_z$(EXEEXT): $(tget_z_OBJECTS) $(tget_z_DEPENDENCIES) $(EXTRA_tget_z_DEPENDENCIES) + @rm -f tget_z$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tget_z_OBJECTS) $(tget_z_LDADD) $(LIBS) + +tgmpop$(EXEEXT): $(tgmpop_OBJECTS) $(tgmpop_DEPENDENCIES) $(EXTRA_tgmpop_DEPENDENCIES) + @rm -f tgmpop$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tgmpop_OBJECTS) $(tgmpop_LDADD) $(LIBS) + +tgrandom$(EXEEXT): $(tgrandom_OBJECTS) $(tgrandom_DEPENDENCIES) $(EXTRA_tgrandom_DEPENDENCIES) + @rm -f tgrandom$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tgrandom_OBJECTS) $(tgrandom_LDADD) $(LIBS) + +thyperbolic$(EXEEXT): $(thyperbolic_OBJECTS) $(thyperbolic_DEPENDENCIES) $(EXTRA_thyperbolic_DEPENDENCIES) + @rm -f thyperbolic$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(thyperbolic_OBJECTS) $(thyperbolic_LDADD) $(LIBS) + +thypot$(EXEEXT): $(thypot_OBJECTS) $(thypot_DEPENDENCIES) $(EXTRA_thypot_DEPENDENCIES) + @rm -f thypot$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(thypot_OBJECTS) $(thypot_LDADD) $(LIBS) + +tinits$(EXEEXT): $(tinits_OBJECTS) $(tinits_DEPENDENCIES) $(EXTRA_tinits_DEPENDENCIES) + @rm -f tinits$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tinits_OBJECTS) $(tinits_LDADD) $(LIBS) + +tinp_str$(EXEEXT): $(tinp_str_OBJECTS) $(tinp_str_DEPENDENCIES) $(EXTRA_tinp_str_DEPENDENCIES) + @rm -f tinp_str$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tinp_str_OBJECTS) $(tinp_str_LDADD) $(LIBS) + +tinternals$(EXEEXT): $(tinternals_OBJECTS) $(tinternals_DEPENDENCIES) $(EXTRA_tinternals_DEPENDENCIES) + @rm -f tinternals$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tinternals_OBJECTS) $(tinternals_LDADD) $(LIBS) + +tisnan$(EXEEXT): $(tisnan_OBJECTS) $(tisnan_DEPENDENCIES) $(EXTRA_tisnan_DEPENDENCIES) + @rm -f tisnan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tisnan_OBJECTS) $(tisnan_LDADD) $(LIBS) + +tisqrt$(EXEEXT): $(tisqrt_OBJECTS) $(tisqrt_DEPENDENCIES) $(EXTRA_tisqrt_DEPENDENCIES) + @rm -f tisqrt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tisqrt_OBJECTS) $(tisqrt_LDADD) $(LIBS) + +tj0$(EXEEXT): $(tj0_OBJECTS) $(tj0_DEPENDENCIES) $(EXTRA_tj0_DEPENDENCIES) + @rm -f tj0$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tj0_OBJECTS) $(tj0_LDADD) $(LIBS) + +tj1$(EXEEXT): $(tj1_OBJECTS) $(tj1_DEPENDENCIES) $(EXTRA_tj1_DEPENDENCIES) + @rm -f tj1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tj1_OBJECTS) $(tj1_LDADD) $(LIBS) + +tjn$(EXEEXT): $(tjn_OBJECTS) $(tjn_DEPENDENCIES) $(EXTRA_tjn_DEPENDENCIES) + @rm -f tjn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tjn_OBJECTS) $(tjn_LDADD) $(LIBS) + +tl2b$(EXEEXT): $(tl2b_OBJECTS) $(tl2b_DEPENDENCIES) $(EXTRA_tl2b_DEPENDENCIES) + @rm -f tl2b$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tl2b_OBJECTS) $(tl2b_LDADD) $(LIBS) + +tlgamma$(EXEEXT): $(tlgamma_OBJECTS) $(tlgamma_DEPENDENCIES) $(EXTRA_tlgamma_DEPENDENCIES) + @rm -f tlgamma$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlgamma_OBJECTS) $(tlgamma_LDADD) $(LIBS) + +tli2$(EXEEXT): $(tli2_OBJECTS) $(tli2_DEPENDENCIES) $(EXTRA_tli2_DEPENDENCIES) + @rm -f tli2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tli2_OBJECTS) $(tli2_LDADD) $(LIBS) + +tlngamma$(EXEEXT): $(tlngamma_OBJECTS) $(tlngamma_DEPENDENCIES) $(EXTRA_tlngamma_DEPENDENCIES) + @rm -f tlngamma$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlngamma_OBJECTS) $(tlngamma_LDADD) $(LIBS) + +tlog$(EXEEXT): $(tlog_OBJECTS) $(tlog_DEPENDENCIES) $(EXTRA_tlog_DEPENDENCIES) + @rm -f tlog$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlog_OBJECTS) $(tlog_LDADD) $(LIBS) + +tlog10$(EXEEXT): $(tlog10_OBJECTS) $(tlog10_DEPENDENCIES) $(EXTRA_tlog10_DEPENDENCIES) + @rm -f tlog10$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlog10_OBJECTS) $(tlog10_LDADD) $(LIBS) + +tlog1p$(EXEEXT): $(tlog1p_OBJECTS) $(tlog1p_DEPENDENCIES) $(EXTRA_tlog1p_DEPENDENCIES) + @rm -f tlog1p$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlog1p_OBJECTS) $(tlog1p_LDADD) $(LIBS) + +tlog2$(EXEEXT): $(tlog2_OBJECTS) $(tlog2_DEPENDENCIES) $(EXTRA_tlog2_DEPENDENCIES) + @rm -f tlog2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tlog2_OBJECTS) $(tlog2_LDADD) $(LIBS) + +tmin_prec$(EXEEXT): $(tmin_prec_OBJECTS) $(tmin_prec_DEPENDENCIES) $(EXTRA_tmin_prec_DEPENDENCIES) + @rm -f tmin_prec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tmin_prec_OBJECTS) $(tmin_prec_LDADD) $(LIBS) + +tminmax$(EXEEXT): $(tminmax_OBJECTS) $(tminmax_DEPENDENCIES) $(EXTRA_tminmax_DEPENDENCIES) + @rm -f tminmax$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tminmax_OBJECTS) $(tminmax_LDADD) $(LIBS) + +tmodf$(EXEEXT): $(tmodf_OBJECTS) $(tmodf_DEPENDENCIES) $(EXTRA_tmodf_DEPENDENCIES) + @rm -f tmodf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tmodf_OBJECTS) $(tmodf_LDADD) $(LIBS) + +tmul$(EXEEXT): $(tmul_OBJECTS) $(tmul_DEPENDENCIES) $(EXTRA_tmul_DEPENDENCIES) + @rm -f tmul$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tmul_OBJECTS) $(tmul_LDADD) $(LIBS) + +tmul_2exp$(EXEEXT): $(tmul_2exp_OBJECTS) $(tmul_2exp_DEPENDENCIES) $(EXTRA_tmul_2exp_DEPENDENCIES) + @rm -f tmul_2exp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tmul_2exp_OBJECTS) $(tmul_2exp_LDADD) $(LIBS) + +tmul_d$(EXEEXT): $(tmul_d_OBJECTS) $(tmul_d_DEPENDENCIES) $(EXTRA_tmul_d_DEPENDENCIES) + @rm -f tmul_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tmul_d_OBJECTS) $(tmul_d_LDADD) $(LIBS) + +tmul_ui$(EXEEXT): $(tmul_ui_OBJECTS) $(tmul_ui_DEPENDENCIES) $(EXTRA_tmul_ui_DEPENDENCIES) + @rm -f tmul_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tmul_ui_OBJECTS) $(tmul_ui_LDADD) $(LIBS) + +tnext$(EXEEXT): $(tnext_OBJECTS) $(tnext_DEPENDENCIES) $(EXTRA_tnext_DEPENDENCIES) + @rm -f tnext$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tnext_OBJECTS) $(tnext_LDADD) $(LIBS) + +tout_str$(EXEEXT): $(tout_str_OBJECTS) $(tout_str_DEPENDENCIES) $(EXTRA_tout_str_DEPENDENCIES) + @rm -f tout_str$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tout_str_OBJECTS) $(tout_str_LDADD) $(LIBS) + +toutimpl$(EXEEXT): $(toutimpl_OBJECTS) $(toutimpl_DEPENDENCIES) $(EXTRA_toutimpl_DEPENDENCIES) + @rm -f toutimpl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(toutimpl_OBJECTS) $(toutimpl_LDADD) $(LIBS) + +tpow$(EXEEXT): $(tpow_OBJECTS) $(tpow_DEPENDENCIES) $(EXTRA_tpow_DEPENDENCIES) + @rm -f tpow$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tpow_OBJECTS) $(tpow_LDADD) $(LIBS) + +tpow3$(EXEEXT): $(tpow3_OBJECTS) $(tpow3_DEPENDENCIES) $(EXTRA_tpow3_DEPENDENCIES) + @rm -f tpow3$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tpow3_OBJECTS) $(tpow3_LDADD) $(LIBS) + +tpow_all$(EXEEXT): $(tpow_all_OBJECTS) $(tpow_all_DEPENDENCIES) $(EXTRA_tpow_all_DEPENDENCIES) + @rm -f tpow_all$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tpow_all_OBJECTS) $(tpow_all_LDADD) $(LIBS) + +tpow_z$(EXEEXT): $(tpow_z_OBJECTS) $(tpow_z_DEPENDENCIES) $(EXTRA_tpow_z_DEPENDENCIES) + @rm -f tpow_z$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tpow_z_OBJECTS) $(tpow_z_LDADD) $(LIBS) + +tprintf$(EXEEXT): $(tprintf_OBJECTS) $(tprintf_DEPENDENCIES) $(EXTRA_tprintf_DEPENDENCIES) + @rm -f tprintf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tprintf_OBJECTS) $(tprintf_LDADD) $(LIBS) + +trandom$(EXEEXT): $(trandom_OBJECTS) $(trandom_DEPENDENCIES) $(EXTRA_trandom_DEPENDENCIES) + @rm -f trandom$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(trandom_OBJECTS) $(trandom_LDADD) $(LIBS) + +trec_sqrt$(EXEEXT): $(trec_sqrt_OBJECTS) $(trec_sqrt_DEPENDENCIES) $(EXTRA_trec_sqrt_DEPENDENCIES) + @rm -f trec_sqrt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(trec_sqrt_OBJECTS) $(trec_sqrt_LDADD) $(LIBS) + +tremquo$(EXEEXT): $(tremquo_OBJECTS) $(tremquo_DEPENDENCIES) $(EXTRA_tremquo_DEPENDENCIES) + @rm -f tremquo$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tremquo_OBJECTS) $(tremquo_LDADD) $(LIBS) + +trint$(EXEEXT): $(trint_OBJECTS) $(trint_DEPENDENCIES) $(EXTRA_trint_DEPENDENCIES) + @rm -f trint$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(trint_OBJECTS) $(trint_LDADD) $(LIBS) + +troot$(EXEEXT): $(troot_OBJECTS) $(troot_DEPENDENCIES) $(EXTRA_troot_DEPENDENCIES) + @rm -f troot$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(troot_OBJECTS) $(troot_LDADD) $(LIBS) + +tround_prec$(EXEEXT): $(tround_prec_OBJECTS) $(tround_prec_DEPENDENCIES) $(EXTRA_tround_prec_DEPENDENCIES) + @rm -f tround_prec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tround_prec_OBJECTS) $(tround_prec_LDADD) $(LIBS) + +tsec$(EXEEXT): $(tsec_OBJECTS) $(tsec_DEPENDENCIES) $(EXTRA_tsec_DEPENDENCIES) + @rm -f tsec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsec_OBJECTS) $(tsec_LDADD) $(LIBS) + +tsech$(EXEEXT): $(tsech_OBJECTS) $(tsech_DEPENDENCIES) $(EXTRA_tsech_DEPENDENCIES) + @rm -f tsech$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsech_OBJECTS) $(tsech_LDADD) $(LIBS) + +tset$(EXEEXT): $(tset_OBJECTS) $(tset_DEPENDENCIES) $(EXTRA_tset_DEPENDENCIES) + @rm -f tset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_OBJECTS) $(tset_LDADD) $(LIBS) + +tset_d$(EXEEXT): $(tset_d_OBJECTS) $(tset_d_DEPENDENCIES) $(EXTRA_tset_d_DEPENDENCIES) + @rm -f tset_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_d_OBJECTS) $(tset_d_LDADD) $(LIBS) + +tset_exp$(EXEEXT): $(tset_exp_OBJECTS) $(tset_exp_DEPENDENCIES) $(EXTRA_tset_exp_DEPENDENCIES) + @rm -f tset_exp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_exp_OBJECTS) $(tset_exp_LDADD) $(LIBS) + +tset_f$(EXEEXT): $(tset_f_OBJECTS) $(tset_f_DEPENDENCIES) $(EXTRA_tset_f_DEPENDENCIES) + @rm -f tset_f$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_f_OBJECTS) $(tset_f_LDADD) $(LIBS) + +tset_ld$(EXEEXT): $(tset_ld_OBJECTS) $(tset_ld_DEPENDENCIES) $(EXTRA_tset_ld_DEPENDENCIES) + @rm -f tset_ld$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_ld_OBJECTS) $(tset_ld_LDADD) $(LIBS) + +tset_q$(EXEEXT): $(tset_q_OBJECTS) $(tset_q_DEPENDENCIES) $(EXTRA_tset_q_DEPENDENCIES) + @rm -f tset_q$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_q_OBJECTS) $(tset_q_LDADD) $(LIBS) + +tset_si$(EXEEXT): $(tset_si_OBJECTS) $(tset_si_DEPENDENCIES) $(EXTRA_tset_si_DEPENDENCIES) + @rm -f tset_si$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_si_OBJECTS) $(tset_si_LDADD) $(LIBS) + +tset_sj$(EXEEXT): $(tset_sj_OBJECTS) $(tset_sj_DEPENDENCIES) $(EXTRA_tset_sj_DEPENDENCIES) + @rm -f tset_sj$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_sj_OBJECTS) $(tset_sj_LDADD) $(LIBS) + +tset_str$(EXEEXT): $(tset_str_OBJECTS) $(tset_str_DEPENDENCIES) $(EXTRA_tset_str_DEPENDENCIES) + @rm -f tset_str$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_str_OBJECTS) $(tset_str_LDADD) $(LIBS) + +tset_z$(EXEEXT): $(tset_z_OBJECTS) $(tset_z_DEPENDENCIES) $(EXTRA_tset_z_DEPENDENCIES) + @rm -f tset_z$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_z_OBJECTS) $(tset_z_LDADD) $(LIBS) + +tset_z_exp$(EXEEXT): $(tset_z_exp_OBJECTS) $(tset_z_exp_DEPENDENCIES) $(EXTRA_tset_z_exp_DEPENDENCIES) + @rm -f tset_z_exp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tset_z_exp_OBJECTS) $(tset_z_exp_LDADD) $(LIBS) + +tsgn$(EXEEXT): $(tsgn_OBJECTS) $(tsgn_DEPENDENCIES) $(EXTRA_tsgn_DEPENDENCIES) + @rm -f tsgn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsgn_OBJECTS) $(tsgn_LDADD) $(LIBS) + +tsi_op$(EXEEXT): $(tsi_op_OBJECTS) $(tsi_op_DEPENDENCIES) $(EXTRA_tsi_op_DEPENDENCIES) + @rm -f tsi_op$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsi_op_OBJECTS) $(tsi_op_LDADD) $(LIBS) + +tsin$(EXEEXT): $(tsin_OBJECTS) $(tsin_DEPENDENCIES) $(EXTRA_tsin_DEPENDENCIES) + @rm -f tsin$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsin_OBJECTS) $(tsin_LDADD) $(LIBS) + +tsin_cos$(EXEEXT): $(tsin_cos_OBJECTS) $(tsin_cos_DEPENDENCIES) $(EXTRA_tsin_cos_DEPENDENCIES) + @rm -f tsin_cos$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsin_cos_OBJECTS) $(tsin_cos_LDADD) $(LIBS) + +tsinh$(EXEEXT): $(tsinh_OBJECTS) $(tsinh_DEPENDENCIES) $(EXTRA_tsinh_DEPENDENCIES) + @rm -f tsinh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsinh_OBJECTS) $(tsinh_LDADD) $(LIBS) + +tsinh_cosh$(EXEEXT): $(tsinh_cosh_OBJECTS) $(tsinh_cosh_DEPENDENCIES) $(EXTRA_tsinh_cosh_DEPENDENCIES) + @rm -f tsinh_cosh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsinh_cosh_OBJECTS) $(tsinh_cosh_LDADD) $(LIBS) + +tsprintf$(EXEEXT): $(tsprintf_OBJECTS) $(tsprintf_DEPENDENCIES) $(EXTRA_tsprintf_DEPENDENCIES) + @rm -f tsprintf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsprintf_OBJECTS) $(tsprintf_LDADD) $(LIBS) + +tsqr$(EXEEXT): $(tsqr_OBJECTS) $(tsqr_DEPENDENCIES) $(EXTRA_tsqr_DEPENDENCIES) + @rm -f tsqr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsqr_OBJECTS) $(tsqr_LDADD) $(LIBS) + +tsqrt$(EXEEXT): $(tsqrt_OBJECTS) $(tsqrt_DEPENDENCIES) $(EXTRA_tsqrt_DEPENDENCIES) + @rm -f tsqrt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsqrt_OBJECTS) $(tsqrt_LDADD) $(LIBS) + +tsqrt_ui$(EXEEXT): $(tsqrt_ui_OBJECTS) $(tsqrt_ui_DEPENDENCIES) $(EXTRA_tsqrt_ui_DEPENDENCIES) + @rm -f tsqrt_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsqrt_ui_OBJECTS) $(tsqrt_ui_LDADD) $(LIBS) + +tstckintc$(EXEEXT): $(tstckintc_OBJECTS) $(tstckintc_DEPENDENCIES) $(EXTRA_tstckintc_DEPENDENCIES) + @rm -f tstckintc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tstckintc_OBJECTS) $(tstckintc_LDADD) $(LIBS) + +tstdint$(EXEEXT): $(tstdint_OBJECTS) $(tstdint_DEPENDENCIES) $(EXTRA_tstdint_DEPENDENCIES) + @rm -f tstdint$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tstdint_OBJECTS) $(tstdint_LDADD) $(LIBS) + +tstrtofr$(EXEEXT): $(tstrtofr_OBJECTS) $(tstrtofr_DEPENDENCIES) $(EXTRA_tstrtofr_DEPENDENCIES) + @rm -f tstrtofr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tstrtofr_OBJECTS) $(tstrtofr_LDADD) $(LIBS) + +tsub$(EXEEXT): $(tsub_OBJECTS) $(tsub_DEPENDENCIES) $(EXTRA_tsub_DEPENDENCIES) + @rm -f tsub$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsub_OBJECTS) $(tsub_LDADD) $(LIBS) + +tsub1sp$(EXEEXT): $(tsub1sp_OBJECTS) $(tsub1sp_DEPENDENCIES) $(EXTRA_tsub1sp_DEPENDENCIES) + @rm -f tsub1sp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsub1sp_OBJECTS) $(tsub1sp_LDADD) $(LIBS) + +tsub_d$(EXEEXT): $(tsub_d_OBJECTS) $(tsub_d_DEPENDENCIES) $(EXTRA_tsub_d_DEPENDENCIES) + @rm -f tsub_d$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsub_d_OBJECTS) $(tsub_d_LDADD) $(LIBS) + +tsub_ui$(EXEEXT): $(tsub_ui_OBJECTS) $(tsub_ui_DEPENDENCIES) $(EXTRA_tsub_ui_DEPENDENCIES) + @rm -f tsub_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsub_ui_OBJECTS) $(tsub_ui_LDADD) $(LIBS) + +tsubnormal$(EXEEXT): $(tsubnormal_OBJECTS) $(tsubnormal_DEPENDENCIES) $(EXTRA_tsubnormal_DEPENDENCIES) + @rm -f tsubnormal$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsubnormal_OBJECTS) $(tsubnormal_LDADD) $(LIBS) + +tsum$(EXEEXT): $(tsum_OBJECTS) $(tsum_DEPENDENCIES) $(EXTRA_tsum_DEPENDENCIES) + @rm -f tsum$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tsum_OBJECTS) $(tsum_LDADD) $(LIBS) + +tswap$(EXEEXT): $(tswap_OBJECTS) $(tswap_DEPENDENCIES) $(EXTRA_tswap_DEPENDENCIES) + @rm -f tswap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tswap_OBJECTS) $(tswap_LDADD) $(LIBS) + +ttan$(EXEEXT): $(ttan_OBJECTS) $(ttan_DEPENDENCIES) $(EXTRA_ttan_DEPENDENCIES) + @rm -f ttan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ttan_OBJECTS) $(ttan_LDADD) $(LIBS) + +ttanh$(EXEEXT): $(ttanh_OBJECTS) $(ttanh_DEPENDENCIES) $(EXTRA_ttanh_DEPENDENCIES) + @rm -f ttanh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ttanh_OBJECTS) $(ttanh_LDADD) $(LIBS) + +ttrunc$(EXEEXT): $(ttrunc_OBJECTS) $(ttrunc_DEPENDENCIES) $(EXTRA_ttrunc_DEPENDENCIES) + @rm -f ttrunc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ttrunc_OBJECTS) $(ttrunc_LDADD) $(LIBS) + +tui_div$(EXEEXT): $(tui_div_OBJECTS) $(tui_div_DEPENDENCIES) $(EXTRA_tui_div_DEPENDENCIES) + @rm -f tui_div$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tui_div_OBJECTS) $(tui_div_LDADD) $(LIBS) + +tui_pow$(EXEEXT): $(tui_pow_OBJECTS) $(tui_pow_DEPENDENCIES) $(EXTRA_tui_pow_DEPENDENCIES) + @rm -f tui_pow$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tui_pow_OBJECTS) $(tui_pow_LDADD) $(LIBS) + +tui_sub$(EXEEXT): $(tui_sub_OBJECTS) $(tui_sub_DEPENDENCIES) $(EXTRA_tui_sub_DEPENDENCIES) + @rm -f tui_sub$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tui_sub_OBJECTS) $(tui_sub_LDADD) $(LIBS) + +turandom$(EXEEXT): $(turandom_OBJECTS) $(turandom_DEPENDENCIES) $(EXTRA_turandom_DEPENDENCIES) + @rm -f turandom$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(turandom_OBJECTS) $(turandom_LDADD) $(LIBS) + +tvalist$(EXEEXT): $(tvalist_OBJECTS) $(tvalist_DEPENDENCIES) $(EXTRA_tvalist_DEPENDENCIES) + @rm -f tvalist$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tvalist_OBJECTS) $(tvalist_LDADD) $(LIBS) + +tversion$(EXEEXT): $(tversion_OBJECTS) $(tversion_DEPENDENCIES) $(EXTRA_tversion_DEPENDENCIES) + @rm -f tversion$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tversion_OBJECTS) $(tversion_LDADD) $(LIBS) + +ty0$(EXEEXT): $(ty0_OBJECTS) $(ty0_DEPENDENCIES) $(EXTRA_ty0_DEPENDENCIES) + @rm -f ty0$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ty0_OBJECTS) $(ty0_LDADD) $(LIBS) + +ty1$(EXEEXT): $(ty1_OBJECTS) $(ty1_DEPENDENCIES) $(EXTRA_ty1_DEPENDENCIES) + @rm -f ty1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ty1_OBJECTS) $(ty1_LDADD) $(LIBS) + +tyn$(EXEEXT): $(tyn_OBJECTS) $(tyn_DEPENDENCIES) $(EXTRA_tyn_DEPENDENCIES) + @rm -f tyn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tyn_OBJECTS) $(tyn_LDADD) $(LIBS) + +tzeta$(EXEEXT): $(tzeta_OBJECTS) $(tzeta_DEPENDENCIES) $(EXTRA_tzeta_DEPENDENCIES) + @rm -f tzeta$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tzeta_OBJECTS) $(tzeta_LDADD) $(LIBS) + +tzeta_ui$(EXEEXT): $(tzeta_ui_OBJECTS) $(tzeta_ui_DEPENDENCIES) $(EXTRA_tzeta_ui_DEPENDENCIES) + @rm -f tzeta_ui$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tzeta_ui_OBJECTS) $(tzeta_ui_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_str.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpf_compat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpfr_compat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reuse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rnd_mode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tabs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacos.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacosh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd1sp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tagm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tai.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tasin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tasinh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tatan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tatanh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/taway.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tbuildopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcan_round.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcbrt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcheck.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp_ld.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp_ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmpabs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcomparisons.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_catalan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_euler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_log2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_pi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcopysign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcos.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcosh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcoth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/td_div.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/td_sub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdigamma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdim.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/teint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/teq.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texceptions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp10.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texpm1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfactorial.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfits.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfmod.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfms.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfrac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfrexp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgamma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_d_2exp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_f.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_flt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_ld_2exp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_set_d64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_sj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_str.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_z.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgmpop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgrandom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thyperbolic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thypot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinits.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinp_str.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinternals.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tisnan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tisqrt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tj0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tj1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tl2b.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlgamma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tli2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlngamma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog10.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog1p.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmin_prec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tminmax.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmodf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_2exp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnext.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tout_str.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/toutimpl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_all.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_z.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trandom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trec_sqrt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tremquo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/troot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tround_prec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsech.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_exp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_f.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_ld.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_q.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_si.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_sj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_str.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_z.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_z_exp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsgn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsi_op.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsin_cos.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsinh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsinh_cosh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqrt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqrt_ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstckintc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstdint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstrtofr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub1sp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub_d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub_ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsubnormal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tswap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttanh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttrunc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_div.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_pow.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_sub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/turandom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvalist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tversion.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ty0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ty1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tyn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tzeta.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tzeta_ui.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_LTLIBRARIES) $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +tversion.log: tversion$(EXEEXT) + @p='tversion$(EXEEXT)'; \ + b='tversion'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tinternals.log: tinternals$(EXEEXT) + @p='tinternals$(EXEEXT)'; \ + b='tinternals'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tinits.log: tinits$(EXEEXT) + @p='tinits$(EXEEXT)'; \ + b='tinits'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tisqrt.log: tisqrt$(EXEEXT) + @p='tisqrt$(EXEEXT)'; \ + b='tisqrt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsgn.log: tsgn$(EXEEXT) + @p='tsgn$(EXEEXT)'; \ + b='tsgn'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcheck.log: tcheck$(EXEEXT) + @p='tcheck$(EXEEXT)'; \ + b='tcheck'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tisnan.log: tisnan$(EXEEXT) + @p='tisnan$(EXEEXT)'; \ + b='tisnan'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +texceptions.log: texceptions$(EXEEXT) + @p='texceptions$(EXEEXT)'; \ + b='texceptions'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_exp.log: tset_exp$(EXEEXT) + @p='tset_exp$(EXEEXT)'; \ + b='tset_exp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset.log: tset$(EXEEXT) + @p='tset$(EXEEXT)'; \ + b='tset'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +mpf_compat.log: mpf_compat$(EXEEXT) + @p='mpf_compat$(EXEEXT)'; \ + b='mpf_compat'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +mpfr_compat.log: mpfr_compat$(EXEEXT) + @p='mpfr_compat$(EXEEXT)'; \ + b='mpfr_compat'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +reuse.log: reuse$(EXEEXT) + @p='reuse$(EXEEXT)'; \ + b='reuse'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tabs.log: tabs$(EXEEXT) + @p='tabs$(EXEEXT)'; \ + b='tabs'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tacos.log: tacos$(EXEEXT) + @p='tacos$(EXEEXT)'; \ + b='tacos'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tacosh.log: tacosh$(EXEEXT) + @p='tacosh$(EXEEXT)'; \ + b='tacosh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tadd.log: tadd$(EXEEXT) + @p='tadd$(EXEEXT)'; \ + b='tadd'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tadd1sp.log: tadd1sp$(EXEEXT) + @p='tadd1sp$(EXEEXT)'; \ + b='tadd1sp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tadd_d.log: tadd_d$(EXEEXT) + @p='tadd_d$(EXEEXT)'; \ + b='tadd_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tadd_ui.log: tadd_ui$(EXEEXT) + @p='tadd_ui$(EXEEXT)'; \ + b='tadd_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tagm.log: tagm$(EXEEXT) + @p='tagm$(EXEEXT)'; \ + b='tagm'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tai.log: tai$(EXEEXT) + @p='tai$(EXEEXT)'; \ + b='tai'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tasin.log: tasin$(EXEEXT) + @p='tasin$(EXEEXT)'; \ + b='tasin'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tasinh.log: tasinh$(EXEEXT) + @p='tasinh$(EXEEXT)'; \ + b='tasinh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tatan.log: tatan$(EXEEXT) + @p='tatan$(EXEEXT)'; \ + b='tatan'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tatanh.log: tatanh$(EXEEXT) + @p='tatanh$(EXEEXT)'; \ + b='tatanh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +taway.log: taway$(EXEEXT) + @p='taway$(EXEEXT)'; \ + b='taway'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tbuildopt.log: tbuildopt$(EXEEXT) + @p='tbuildopt$(EXEEXT)'; \ + b='tbuildopt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcan_round.log: tcan_round$(EXEEXT) + @p='tcan_round$(EXEEXT)'; \ + b='tcan_round'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcbrt.log: tcbrt$(EXEEXT) + @p='tcbrt$(EXEEXT)'; \ + b='tcbrt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcmp.log: tcmp$(EXEEXT) + @p='tcmp$(EXEEXT)'; \ + b='tcmp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcmp2.log: tcmp2$(EXEEXT) + @p='tcmp2$(EXEEXT)'; \ + b='tcmp2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcmp_d.log: tcmp_d$(EXEEXT) + @p='tcmp_d$(EXEEXT)'; \ + b='tcmp_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcmp_ld.log: tcmp_ld$(EXEEXT) + @p='tcmp_ld$(EXEEXT)'; \ + b='tcmp_ld'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcmp_ui.log: tcmp_ui$(EXEEXT) + @p='tcmp_ui$(EXEEXT)'; \ + b='tcmp_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcmpabs.log: tcmpabs$(EXEEXT) + @p='tcmpabs$(EXEEXT)'; \ + b='tcmpabs'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcomparisons.log: tcomparisons$(EXEEXT) + @p='tcomparisons$(EXEEXT)'; \ + b='tcomparisons'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tconst_catalan.log: tconst_catalan$(EXEEXT) + @p='tconst_catalan$(EXEEXT)'; \ + b='tconst_catalan'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tconst_euler.log: tconst_euler$(EXEEXT) + @p='tconst_euler$(EXEEXT)'; \ + b='tconst_euler'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tconst_log2.log: tconst_log2$(EXEEXT) + @p='tconst_log2$(EXEEXT)'; \ + b='tconst_log2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tconst_pi.log: tconst_pi$(EXEEXT) + @p='tconst_pi$(EXEEXT)'; \ + b='tconst_pi'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcopysign.log: tcopysign$(EXEEXT) + @p='tcopysign$(EXEEXT)'; \ + b='tcopysign'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcos.log: tcos$(EXEEXT) + @p='tcos$(EXEEXT)'; \ + b='tcos'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcosh.log: tcosh$(EXEEXT) + @p='tcosh$(EXEEXT)'; \ + b='tcosh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcot.log: tcot$(EXEEXT) + @p='tcot$(EXEEXT)'; \ + b='tcot'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcoth.log: tcoth$(EXEEXT) + @p='tcoth$(EXEEXT)'; \ + b='tcoth'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcsc.log: tcsc$(EXEEXT) + @p='tcsc$(EXEEXT)'; \ + b='tcsc'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tcsch.log: tcsch$(EXEEXT) + @p='tcsch$(EXEEXT)'; \ + b='tcsch'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +td_div.log: td_div$(EXEEXT) + @p='td_div$(EXEEXT)'; \ + b='td_div'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +td_sub.log: td_sub$(EXEEXT) + @p='td_sub$(EXEEXT)'; \ + b='td_sub'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tdigamma.log: tdigamma$(EXEEXT) + @p='tdigamma$(EXEEXT)'; \ + b='tdigamma'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tdim.log: tdim$(EXEEXT) + @p='tdim$(EXEEXT)'; \ + b='tdim'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tdiv.log: tdiv$(EXEEXT) + @p='tdiv$(EXEEXT)'; \ + b='tdiv'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tdiv_d.log: tdiv_d$(EXEEXT) + @p='tdiv_d$(EXEEXT)'; \ + b='tdiv_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tdiv_ui.log: tdiv_ui$(EXEEXT) + @p='tdiv_ui$(EXEEXT)'; \ + b='tdiv_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +teint.log: teint$(EXEEXT) + @p='teint$(EXEEXT)'; \ + b='teint'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +teq.log: teq$(EXEEXT) + @p='teq$(EXEEXT)'; \ + b='teq'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +terf.log: terf$(EXEEXT) + @p='terf$(EXEEXT)'; \ + b='terf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +texp.log: texp$(EXEEXT) + @p='texp$(EXEEXT)'; \ + b='texp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +texp10.log: texp10$(EXEEXT) + @p='texp10$(EXEEXT)'; \ + b='texp10'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +texp2.log: texp2$(EXEEXT) + @p='texp2$(EXEEXT)'; \ + b='texp2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +texpm1.log: texpm1$(EXEEXT) + @p='texpm1$(EXEEXT)'; \ + b='texpm1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfactorial.log: tfactorial$(EXEEXT) + @p='tfactorial$(EXEEXT)'; \ + b='tfactorial'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfits.log: tfits$(EXEEXT) + @p='tfits$(EXEEXT)'; \ + b='tfits'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfma.log: tfma$(EXEEXT) + @p='tfma$(EXEEXT)'; \ + b='tfma'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfmod.log: tfmod$(EXEEXT) + @p='tfmod$(EXEEXT)'; \ + b='tfmod'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfms.log: tfms$(EXEEXT) + @p='tfms$(EXEEXT)'; \ + b='tfms'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfprintf.log: tfprintf$(EXEEXT) + @p='tfprintf$(EXEEXT)'; \ + b='tfprintf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfrac.log: tfrac$(EXEEXT) + @p='tfrac$(EXEEXT)'; \ + b='tfrac'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tfrexp.log: tfrexp$(EXEEXT) + @p='tfrexp$(EXEEXT)'; \ + b='tfrexp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tgamma.log: tgamma$(EXEEXT) + @p='tgamma$(EXEEXT)'; \ + b='tgamma'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_flt.log: tget_flt$(EXEEXT) + @p='tget_flt$(EXEEXT)'; \ + b='tget_flt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_d.log: tget_d$(EXEEXT) + @p='tget_d$(EXEEXT)'; \ + b='tget_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_d_2exp.log: tget_d_2exp$(EXEEXT) + @p='tget_d_2exp$(EXEEXT)'; \ + b='tget_d_2exp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_f.log: tget_f$(EXEEXT) + @p='tget_f$(EXEEXT)'; \ + b='tget_f'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_ld_2exp.log: tget_ld_2exp$(EXEEXT) + @p='tget_ld_2exp$(EXEEXT)'; \ + b='tget_ld_2exp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_set_d64.log: tget_set_d64$(EXEEXT) + @p='tget_set_d64$(EXEEXT)'; \ + b='tget_set_d64'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_sj.log: tget_sj$(EXEEXT) + @p='tget_sj$(EXEEXT)'; \ + b='tget_sj'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_str.log: tget_str$(EXEEXT) + @p='tget_str$(EXEEXT)'; \ + b='tget_str'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tget_z.log: tget_z$(EXEEXT) + @p='tget_z$(EXEEXT)'; \ + b='tget_z'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tgmpop.log: tgmpop$(EXEEXT) + @p='tgmpop$(EXEEXT)'; \ + b='tgmpop'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tgrandom.log: tgrandom$(EXEEXT) + @p='tgrandom$(EXEEXT)'; \ + b='tgrandom'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +thyperbolic.log: thyperbolic$(EXEEXT) + @p='thyperbolic$(EXEEXT)'; \ + b='thyperbolic'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +thypot.log: thypot$(EXEEXT) + @p='thypot$(EXEEXT)'; \ + b='thypot'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tinp_str.log: tinp_str$(EXEEXT) + @p='tinp_str$(EXEEXT)'; \ + b='tinp_str'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tj0.log: tj0$(EXEEXT) + @p='tj0$(EXEEXT)'; \ + b='tj0'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tj1.log: tj1$(EXEEXT) + @p='tj1$(EXEEXT)'; \ + b='tj1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tjn.log: tjn$(EXEEXT) + @p='tjn$(EXEEXT)'; \ + b='tjn'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tl2b.log: tl2b$(EXEEXT) + @p='tl2b$(EXEEXT)'; \ + b='tl2b'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlgamma.log: tlgamma$(EXEEXT) + @p='tlgamma$(EXEEXT)'; \ + b='tlgamma'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tli2.log: tli2$(EXEEXT) + @p='tli2$(EXEEXT)'; \ + b='tli2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlngamma.log: tlngamma$(EXEEXT) + @p='tlngamma$(EXEEXT)'; \ + b='tlngamma'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlog.log: tlog$(EXEEXT) + @p='tlog$(EXEEXT)'; \ + b='tlog'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlog10.log: tlog10$(EXEEXT) + @p='tlog10$(EXEEXT)'; \ + b='tlog10'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlog1p.log: tlog1p$(EXEEXT) + @p='tlog1p$(EXEEXT)'; \ + b='tlog1p'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tlog2.log: tlog2$(EXEEXT) + @p='tlog2$(EXEEXT)'; \ + b='tlog2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tmin_prec.log: tmin_prec$(EXEEXT) + @p='tmin_prec$(EXEEXT)'; \ + b='tmin_prec'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tminmax.log: tminmax$(EXEEXT) + @p='tminmax$(EXEEXT)'; \ + b='tminmax'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tmodf.log: tmodf$(EXEEXT) + @p='tmodf$(EXEEXT)'; \ + b='tmodf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tmul.log: tmul$(EXEEXT) + @p='tmul$(EXEEXT)'; \ + b='tmul'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tmul_2exp.log: tmul_2exp$(EXEEXT) + @p='tmul_2exp$(EXEEXT)'; \ + b='tmul_2exp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tmul_d.log: tmul_d$(EXEEXT) + @p='tmul_d$(EXEEXT)'; \ + b='tmul_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tmul_ui.log: tmul_ui$(EXEEXT) + @p='tmul_ui$(EXEEXT)'; \ + b='tmul_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tnext.log: tnext$(EXEEXT) + @p='tnext$(EXEEXT)'; \ + b='tnext'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tout_str.log: tout_str$(EXEEXT) + @p='tout_str$(EXEEXT)'; \ + b='tout_str'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +toutimpl.log: toutimpl$(EXEEXT) + @p='toutimpl$(EXEEXT)'; \ + b='toutimpl'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tpow.log: tpow$(EXEEXT) + @p='tpow$(EXEEXT)'; \ + b='tpow'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tpow3.log: tpow3$(EXEEXT) + @p='tpow3$(EXEEXT)'; \ + b='tpow3'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tpow_all.log: tpow_all$(EXEEXT) + @p='tpow_all$(EXEEXT)'; \ + b='tpow_all'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tpow_z.log: tpow_z$(EXEEXT) + @p='tpow_z$(EXEEXT)'; \ + b='tpow_z'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tprintf.log: tprintf$(EXEEXT) + @p='tprintf$(EXEEXT)'; \ + b='tprintf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +trandom.log: trandom$(EXEEXT) + @p='trandom$(EXEEXT)'; \ + b='trandom'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +trec_sqrt.log: trec_sqrt$(EXEEXT) + @p='trec_sqrt$(EXEEXT)'; \ + b='trec_sqrt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tremquo.log: tremquo$(EXEEXT) + @p='tremquo$(EXEEXT)'; \ + b='tremquo'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +trint.log: trint$(EXEEXT) + @p='trint$(EXEEXT)'; \ + b='trint'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +troot.log: troot$(EXEEXT) + @p='troot$(EXEEXT)'; \ + b='troot'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tround_prec.log: tround_prec$(EXEEXT) + @p='tround_prec$(EXEEXT)'; \ + b='tround_prec'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsec.log: tsec$(EXEEXT) + @p='tsec$(EXEEXT)'; \ + b='tsec'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsech.log: tsech$(EXEEXT) + @p='tsech$(EXEEXT)'; \ + b='tsech'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_d.log: tset_d$(EXEEXT) + @p='tset_d$(EXEEXT)'; \ + b='tset_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_f.log: tset_f$(EXEEXT) + @p='tset_f$(EXEEXT)'; \ + b='tset_f'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_ld.log: tset_ld$(EXEEXT) + @p='tset_ld$(EXEEXT)'; \ + b='tset_ld'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_q.log: tset_q$(EXEEXT) + @p='tset_q$(EXEEXT)'; \ + b='tset_q'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_si.log: tset_si$(EXEEXT) + @p='tset_si$(EXEEXT)'; \ + b='tset_si'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_sj.log: tset_sj$(EXEEXT) + @p='tset_sj$(EXEEXT)'; \ + b='tset_sj'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_str.log: tset_str$(EXEEXT) + @p='tset_str$(EXEEXT)'; \ + b='tset_str'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_z.log: tset_z$(EXEEXT) + @p='tset_z$(EXEEXT)'; \ + b='tset_z'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tset_z_exp.log: tset_z_exp$(EXEEXT) + @p='tset_z_exp$(EXEEXT)'; \ + b='tset_z_exp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsi_op.log: tsi_op$(EXEEXT) + @p='tsi_op$(EXEEXT)'; \ + b='tsi_op'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsin.log: tsin$(EXEEXT) + @p='tsin$(EXEEXT)'; \ + b='tsin'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsin_cos.log: tsin_cos$(EXEEXT) + @p='tsin_cos$(EXEEXT)'; \ + b='tsin_cos'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsinh.log: tsinh$(EXEEXT) + @p='tsinh$(EXEEXT)'; \ + b='tsinh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsinh_cosh.log: tsinh_cosh$(EXEEXT) + @p='tsinh_cosh$(EXEEXT)'; \ + b='tsinh_cosh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsprintf.log: tsprintf$(EXEEXT) + @p='tsprintf$(EXEEXT)'; \ + b='tsprintf'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsqr.log: tsqr$(EXEEXT) + @p='tsqr$(EXEEXT)'; \ + b='tsqr'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsqrt.log: tsqrt$(EXEEXT) + @p='tsqrt$(EXEEXT)'; \ + b='tsqrt'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsqrt_ui.log: tsqrt_ui$(EXEEXT) + @p='tsqrt_ui$(EXEEXT)'; \ + b='tsqrt_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tstckintc.log: tstckintc$(EXEEXT) + @p='tstckintc$(EXEEXT)'; \ + b='tstckintc'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tstdint.log: tstdint$(EXEEXT) + @p='tstdint$(EXEEXT)'; \ + b='tstdint'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tstrtofr.log: tstrtofr$(EXEEXT) + @p='tstrtofr$(EXEEXT)'; \ + b='tstrtofr'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsub.log: tsub$(EXEEXT) + @p='tsub$(EXEEXT)'; \ + b='tsub'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsub1sp.log: tsub1sp$(EXEEXT) + @p='tsub1sp$(EXEEXT)'; \ + b='tsub1sp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsub_d.log: tsub_d$(EXEEXT) + @p='tsub_d$(EXEEXT)'; \ + b='tsub_d'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsub_ui.log: tsub_ui$(EXEEXT) + @p='tsub_ui$(EXEEXT)'; \ + b='tsub_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsubnormal.log: tsubnormal$(EXEEXT) + @p='tsubnormal$(EXEEXT)'; \ + b='tsubnormal'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tsum.log: tsum$(EXEEXT) + @p='tsum$(EXEEXT)'; \ + b='tsum'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tswap.log: tswap$(EXEEXT) + @p='tswap$(EXEEXT)'; \ + b='tswap'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ttan.log: ttan$(EXEEXT) + @p='ttan$(EXEEXT)'; \ + b='ttan'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ttanh.log: ttanh$(EXEEXT) + @p='ttanh$(EXEEXT)'; \ + b='ttanh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ttrunc.log: ttrunc$(EXEEXT) + @p='ttrunc$(EXEEXT)'; \ + b='ttrunc'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tui_div.log: tui_div$(EXEEXT) + @p='tui_div$(EXEEXT)'; \ + b='tui_div'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tui_pow.log: tui_pow$(EXEEXT) + @p='tui_pow$(EXEEXT)'; \ + b='tui_pow'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tui_sub.log: tui_sub$(EXEEXT) + @p='tui_sub$(EXEEXT)'; \ + b='tui_sub'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +turandom.log: turandom$(EXEEXT) + @p='turandom$(EXEEXT)'; \ + b='turandom'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tvalist.log: tvalist$(EXEEXT) + @p='tvalist$(EXEEXT)'; \ + b='tvalist'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ty0.log: ty0$(EXEEXT) + @p='ty0$(EXEEXT)'; \ + b='ty0'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +ty1.log: ty1$(EXEEXT) + @p='ty1$(EXEEXT)'; \ + b='ty1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tyn.log: tyn$(EXEEXT) + @p='tyn$(EXEEXT)'; \ + b='tyn'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tzeta.log: tzeta$(EXEEXT) + @p='tzeta$(EXEEXT)'; \ + b='tzeta'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tzeta_ui.log: tzeta_ui$(EXEEXT) + @p='tzeta_ui$(EXEEXT)'; \ + b='tzeta_ui'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Before Automake 1.13, we ran tversion at the beginning and at the end +# of the tests, and output from tversion appeared at the same place as +# the tests results (make output). With Automake 1.13+, the tests are +# parallelized by default and their output is sent to log files instead +# of the make output, so that the user could no longer see information +# from tversion. To mimic the old behavior, we now output the contents +# of the tversion log file if this file exists (i.e. if the Makefile +# has been generated with Automake 1.13+). +check: + cat tversion.log 2> /dev/null || true + +$(top_builddir)/src/libmpfr.la: + cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.la + +# 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/cmp_str.c b/mpfr/tests/cmp_str.c new file mode 100644 index 0000000000..83eaf6b98d --- /dev/null +++ b/mpfr/tests/cmp_str.c @@ -0,0 +1,37 @@ +/* mpfr_cmp_str -- compare a floating-point number with a string. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mpfr-test.h" + +int +mpfr_cmp_str (mpfr_srcptr x, const char *s, int base, mpfr_rnd_t rnd) +{ + mpfr_t y; + int res; + + MPFR_ASSERTN (!MPFR_IS_NAN (x)); + mpfr_init2 (y, MPFR_PREC(x)); + mpfr_set_str (y, s, base, rnd); + res = mpfr_cmp (x,y); + mpfr_clear (y); + return res; +} diff --git a/mpfr/tests/inp_str.data b/mpfr/tests/inp_str.data new file mode 100644 index 0000000000..31e81c5cc5 --- /dev/null +++ b/mpfr/tests/inp_str.data @@ -0,0 +1,64 @@ +3.1415E4 +3.14160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +this_is_an_invalid_float +1.0010010100001110100101001110011010111011100001110010e226 +2.0120022122100022221001012120111010e142 +1.02110032211032122323201302e113 +1.43422433221034224112212e97 +2.245023334051130112541e87 +3.0214031231425640423e80 +2.224164516327341620e75 +2.16278308831176433e71 +1.2344999999999999e68 +2.5768519130417743@65 +1.326a50b3b9b311a@63 +1.4ca424800281ca0@61 +2.d44d2c475c1617@59 +b.4e8eae45eec494@57 +4.943a539aee1c8@56 +2.a69b19309ce43@55 +2.08b6320agf513@54 +2.18igbef497b79@53 +2.eg92a193d6jib@52 +4.bcj53i4dg133i@51 +9.7aee6ife1hgc@50 +1.065g326jbmm6@50 +2.l9dfn9kk1l6k@49 +9.jcnhb3me6c6m@48 +1.ci74dmge82kb@48 +6.f8h98p15fd2p@47 +1.57pn1af15bcb@47 +6.i3h3gqn3sp0@46 +1.bnhlsj9haq1@46 +9.h60jmhep7e9@45 +2.98eijjbn1p0@45 +i.u9r3j72f706@44 +5.2vxma61rnia@44 +1.epbr7wcjrks@44 +e.t2lm57i7hol@43 +4.KOJ1KXDLOD4@43 +1.H11SSC49aK9@43 +I.IWc1P7E0LQ8@42 +6.FBLVIEPHDc@42 +2.AV3VN4CK5A@42 +Y.MLABZPIMQ8@41 +D.6dIaKL16KV@41 +5.5RIZ3BGFbB@41 +2.1bIDPOihRN@41 +c.5SPGTF1gcJ@40 +G.60Khc9JPg1@40 +6.jNOlekhHB9@40 +3.2B39MUfSUI@40 +1.HhIJK7WJnh@40 +V.HkOThmcRf8@39 +E.aOdo3XbWH0@39 +6.qaNNZOE7Dd@39 +3.KAITW0C2kr@39 +1.ZdacKp9sIh@39 +j.ff6t2aeHht@38 +N.Jl6DgUeeZA@38 +C.3GakhvVNYH@38 +6.HTqomOD3Rh@38 +3.JSeUbAAtE@38 +1.lD6kuqhV0@38 +x.I7kYxn4IR@37 diff --git a/mpfr/tests/memory.c b/mpfr/tests/memory.c new file mode 100644 index 0000000000..1bb88b8c7b --- /dev/null +++ b/mpfr/tests/memory.c @@ -0,0 +1,193 @@ +/* Memory allocation used during tests. + +Copyright 2001-2003, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Note: this file comes from GMP's tests/memory.c */ + +#include <stdio.h> +#include <stdlib.h> /* for abort */ +#include <limits.h> + +#include "mpfr-test.h" + +/* Each block allocated is a separate malloc, for the benefit of a redzoning + malloc debugger during development or when bug hunting. + + Sizes passed when reallocating or freeing are checked (the default + routines don't care about these). + + Memory leaks are checked by requiring that all blocks have been freed + when tests_memory_end() is called. Test programs must be sure to have + "clear"s for all temporary variables used. */ + +struct header { + void *ptr; + size_t size; + struct header *next; +}; + +static struct header *tests_memory_list; + +/* Return a pointer to a pointer to the found block (so it can be updated + when unlinking). */ +static struct header ** +tests_memory_find (void *ptr) +{ + struct header **hp; + + for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next)) + if ((*hp)->ptr == ptr) + return hp; + + return NULL; +} + +/* +static int +tests_memory_valid (void *ptr) +{ + return (tests_memory_find (ptr) != NULL); +} +*/ + +void * +tests_allocate (size_t size) +{ + struct header *h; + + if (size == 0) + { + printf ("tests_allocate(): attempt to allocate 0 bytes\n"); + abort (); + } + + h = (struct header *) __gmp_default_allocate (sizeof (*h)); + h->next = tests_memory_list; + tests_memory_list = h; + + h->size = size; + h->ptr = __gmp_default_allocate (size); + return h->ptr; +} + +void * +tests_reallocate (void *ptr, size_t old_size, size_t new_size) +{ + struct header **hp, *h; + + if (new_size == 0) + { + printf ("tests_reallocate(): attempt to reallocate 0x%lX to 0 bytes\n", + (unsigned long) ptr); + abort (); + } + + hp = tests_memory_find (ptr); + if (hp == NULL) + { + printf ("tests_reallocate(): attempt to reallocate bad pointer 0x%lX\n", + (unsigned long) ptr); + abort (); + } + h = *hp; + + if (h->size != old_size) + { + /* Note: we should use the standard %zu to print sizes, but + this is not supported by old C implementations. */ + printf ("tests_reallocate(): bad old size %lu, should be %lu\n", + (unsigned long) old_size, (unsigned long) h->size); + abort (); + } + + h->size = new_size; + h->ptr = __gmp_default_reallocate (ptr, old_size, new_size); + return h->ptr; +} + +static struct header ** +tests_free_find (void *ptr) +{ + struct header **hp = tests_memory_find (ptr); + if (hp == NULL) + { + printf ("tests_free(): attempt to free bad pointer 0x%lX\n", + (unsigned long) ptr); + abort (); + } + return hp; +} + +static void +tests_free_nosize (void *ptr) +{ + struct header **hp = tests_free_find (ptr); + struct header *h = *hp; + + *hp = h->next; /* unlink */ + + __gmp_default_free (ptr, h->size); + __gmp_default_free (h, sizeof (*h)); +} + +void +tests_free (void *ptr, size_t size) +{ + struct header **hp = tests_free_find (ptr); + struct header *h = *hp; + + if (h->size != size) + { + /* Note: we should use the standard %zu to print sizes, but + this is not supported by old C implementations. */ + printf ("tests_free(): bad size %lu, should be %lu\n", + (unsigned long) size, (unsigned long) h->size); + abort (); + } + + tests_free_nosize (ptr); +} + +void +tests_memory_start (void) +{ + tests_memory_list = NULL; + mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free); +} + +void +tests_memory_end (void) +{ + if (tests_memory_list != NULL) + { + struct header *h; + unsigned count; + + printf ("tests_memory_end(): not all memory freed\n"); + + count = 0; + for (h = tests_memory_list; h != NULL; h = h->next) + count++; + + printf (" %u blocks remaining\n", count); + abort (); + } +} diff --git a/mpfr/tests/mpf_compat.c b/mpfr/tests/mpf_compat.c new file mode 100644 index 0000000000..5562ed8606 --- /dev/null +++ b/mpfr/tests/mpf_compat.c @@ -0,0 +1,25 @@ +/* Test compatibility mpf-mpfr. + +Copyright 2003, 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#define MPF +#define mpf_free_str mpfr_free_str +#include "mpf_compat.h" diff --git a/mpfr/tests/mpf_compat.h b/mpfr/tests/mpf_compat.h new file mode 100644 index 0000000000..81861c2c54 --- /dev/null +++ b/mpfr/tests/mpf_compat.h @@ -0,0 +1,236 @@ +/* Test compatibility mpf-mpfr. + +Copyright 2003-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if defined (__cplusplus) +#include <cstdio> +#else +#include <stdio.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "gmp.h" +#include "mpfr.h" +#ifdef MPFR +#include "mpf2mpfr.h" +#endif + +int +main (void) +{ + unsigned long int prec; + unsigned long int prec2; + mpf_t x, y; + mpz_t z; + mpq_t q; + double d; + signed long int exp; + long l; + unsigned long u; + char *s; + int i; + FILE *f; + gmp_randstate_t state; + + /* Initialization Functions */ + prec = 53; + mpf_set_default_prec (prec); + prec2 = mpf_get_default_prec (); + if (prec2 < prec) + { + printf ("Error in get_default_prec: %lu < %lu\n", prec2, prec); + exit (1); + } + + mpf_init (y); + + mpf_init2 (x, prec); + prec2 = mpf_get_prec (x); + if (prec2 < prec) + { + printf ("Error in get_prec: %lu < %lu\n", prec2, prec); + mpf_clear (y); + mpf_clear (x); + exit (1); + } + + mpf_set_prec (x, 2 * prec); + prec2 = mpf_get_prec (x); + if (prec2 < 2 * prec) + { + printf ("Error in set_prec: %lu < %lu\n", prec2, 2 * prec); + mpf_clear (y); + mpf_clear (x); + exit (1); + } + + mpf_set_prec_raw (x, prec); + prec2 = mpf_get_prec (x); + if (prec2 < prec) + { + printf ("Error in set_prec_raw: %lu < %lu\n", prec2, prec); + mpf_clear (y); + mpf_clear (x); + exit (1); + } + + /* Assignment Functions */ + + mpf_set (y, x); + mpf_set_ui (x, 1); + mpf_set_si (x, -1); + mpf_set_d (x, 1.0); + + mpz_init_set_ui (z, 17); + mpf_set_z (x, z); + mpz_clear (z); + + mpq_init (q); + mpq_set_ui (q, 2, 3); + mpf_set_q (x, q); + mpq_clear (q); + + mpf_set_str (x, "3.1415e1", 10); + mpf_swap (x, y); + + /* Combined Initialization and Assignment Functions */ + + mpf_clear (x); + mpf_init_set (x, y); + mpf_clear (x); + mpf_init_set_ui (x, 17); + mpf_clear (x); + mpf_init_set_si (x, -17); + mpf_clear (x); + mpf_init_set_d (x, 17.0); + mpf_clear (x); + mpf_init_set_str (x, "3.1415e1", 10); + + /* Conversion Functions */ + + d = mpf_get_d (x); + d = mpf_get_d_2exp (&exp, x); + l = mpf_get_si (x); + u = mpf_get_ui (x); + s = mpf_get_str (NULL, &exp, 10, 10, x); + /* MPF doen't have mpf_free_str */ + mpfr_free_str (s); + + /* Use d, l and u to avoid a warning with -Wunused-but-set-variable + from GCC 4.6. The variables above were mainly used for prototype + checking. */ + (void) d; (void) l; (void) u; + + /* Arithmetic Functions */ + + mpf_add (y, x, x); + mpf_add_ui (y, x, 1); + mpf_sub (y, x, x); + mpf_ui_sub (y, 1, x); + mpf_sub_ui (y, x, 1); + mpf_mul (y, x, x); + mpf_mul_ui (y, x, 17); + mpf_div (y, x, x); + mpf_ui_div (y, 17, x); + mpf_div_ui (y, x, 17); + mpf_sqrt (y, x); + mpf_sqrt_ui (y, 17); + mpf_pow_ui (y, x, 2); + mpf_neg (y, x); + mpf_abs (y, x); + mpf_mul_2exp (y, x, 17); + mpf_div_2exp (y, x, 17); + + /* Comparison Functions */ + + i = mpf_cmp (y, x); + i = mpf_cmp_d (y, 1.7); + i = mpf_cmp_ui (y, 17); + i = mpf_cmp_si (y, -17); + i = mpf_eq (y, x, 17); + mpf_reldiff (y, y, x); + i = mpf_sgn (x); + + /* Input and Output Functions */ + + f = fopen ("/dev/null", "w"); + if (f != NULL) + { + mpf_out_str (f, 10, 10, x); + fclose (f); + } + + mpf_set_prec (x, 15); + mpf_set_prec (y, 15); + /* We may use src_fopen instead of fopen, but it is defined + in mpfr-test, and not in mpfr.h and gmp.h, and we want + to test theses includes files. */ + f = fopen ("inp_str.data", "r"); + if (f != NULL) + { + i = mpf_inp_str (x, f, 10); + if ((i == 0) || mpf_cmp_ui (x, 31415)) + { + printf ("Error in reading 1st line from file inp_str.data\n"); + exit (1); + } + fclose (f); + } + + /* Miscellaneous Functions */ + + mpf_ceil (y, x); + mpf_floor (y, x); + mpf_trunc (y, x); + + i = mpf_integer_p (x); + + i = mpf_fits_ulong_p (x); + i = mpf_fits_slong_p (x); + i = mpf_fits_uint_p (x); + i = mpf_fits_sint_p (x); + i = mpf_fits_ushort_p (x); + i = mpf_fits_sshort_p (x); + + gmp_randinit_lc_2exp_size (state, 128); + mpf_urandomb (x, state, 10); + gmp_randclear (state); + + /* Conversion to mpz */ + mpz_init (z); + mpf_set_ui (x, 17); + mpz_set_f (z, x); + mpf_set_z (x, z); + mpz_clear (z); + if (mpf_cmp_ui (x, 17) != 0) + { + fprintf (stderr, "Error in conversion to/from mpz\n"); + fprintf (stderr, "expected 17, got %1.16e\n", mpf_get_d (x)); + exit (1); + } + + /* clear all variables */ + mpf_clear (y); + mpf_clear (x); + + return 0; +} diff --git a/mpfr/tests/mpfr-test.h b/mpfr/tests/mpfr-test.h new file mode 100644 index 0000000000..96e77b3100 --- /dev/null +++ b/mpfr/tests/mpfr-test.h @@ -0,0 +1,179 @@ +/* auxiliary functions for MPFR tests. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef __MPFR_TEST_H__ +#define __MPFR_TEST_H__ + +#include <stdio.h> + +#include "mpfr-impl.h" + +/* generates a random long int, a random double, + and corresponding seed initializing */ +#define DBL_RAND() ((double) randlimb() / (double) MP_LIMB_T_MAX) + +#define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */ +#define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */ + +/* Generates a random rounding mode */ +#define RND_RAND() ((mpfr_rnd_t) (randlimb() % MPFR_RND_MAX)) + +/* Generates a random sign */ +#define SIGN_RAND() ( (randlimb()%2) ? MPFR_SIGN_POS : MPFR_SIGN_NEG) + +/* Loop for all rounding modes */ +#define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++) + +/* Test whether two floating-point data have the same value, + seen as an element of the set of the floating-point data + (Level 2 in the IEEE 754-2008 standard). */ +#define SAME_VAL(X,Y) \ + ((MPFR_IS_NAN (X) && MPFR_IS_NAN (Y)) || \ + (mpfr_equal_p ((X), (Y)) && MPFR_INT_SIGN (X) == MPFR_INT_SIGN (Y))) + +/* The MAX, MIN and ABS macros may already be defined if gmp-impl.h has + been included. They have the same semantics as in gmp-impl.h, but the + expressions may be slightly different. So, it's better to undefine + them first, as required by the ISO C standard. */ +#undef MAX +#undef MIN +#undef ABS +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define ABS(x) (((x)>0) ? (x) : -(x)) + +#define FLIST mpfr_ptr, mpfr_srcptr, mpfr_rnd_t + +#if defined (__cplusplus) +extern "C" { +#endif + +int test_version _MPFR_PROTO ((void)); + +void tests_memory_start _MPFR_PROTO ((void)); +void tests_memory_end _MPFR_PROTO ((void)); + +void tests_start_mpfr _MPFR_PROTO ((void)); +void tests_end_mpfr _MPFR_PROTO ((void)); + +int mpfr_set_machine_rnd_mode _MPFR_PROTO ((mpfr_rnd_t)); +void mpfr_test_init _MPFR_PROTO ((void)); +mp_limb_t randlimb _MPFR_PROTO ((void)); +void randseed _MPFR_PROTO ((unsigned int)); +void mpfr_random2 _MPFR_PROTO ((mpfr_ptr, mp_size_t, mpfr_exp_t, gmp_randstate_t)); +int ulp _MPFR_PROTO ((double, double)); +double dbl _MPFR_PROTO ((double, int)); +double Ulp _MPFR_PROTO ((double)); +int Isnan _MPFR_PROTO ((double)); +void d_trace _MPFR_PROTO ((const char *, double)); +void ld_trace _MPFR_PROTO ((const char *, long double)); + +FILE *src_fopen _MPFR_PROTO ((const char *, const char *)); +void set_emin _MPFR_PROTO ((mpfr_exp_t)); +void set_emax _MPFR_PROTO ((mpfr_exp_t)); +void tests_default_random _MPFR_PROTO ((mpfr_ptr, int, mpfr_exp_t, mpfr_exp_t, + int)); +void data_check _MPFR_PROTO ((const char *, int (*) (FLIST), const char *)); +void bad_cases _MPFR_PROTO ((int (*)(FLIST), int (*)(FLIST), + const char *, int, mpfr_exp_t, mpfr_exp_t, + mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, int)); +void flags_out _MPFR_PROTO ((unsigned int)); + +int mpfr_cmp_str _MPFR_PROTO ((mpfr_srcptr x, const char *, int, mpfr_rnd_t)); +#define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,MPFR_RNDN) +#define mpfr_set_str1(x,s) mpfr_set_str(x,s,10,MPFR_RNDN) + +#define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y)) +#define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i)) + +/* Allocation */ +void *tests_allocate _MPFR_PROTO ((size_t)); +void *tests_reallocate _MPFR_PROTO ((void *, size_t, size_t)); +void tests_free _MPFR_PROTO ((void *, size_t)); + +#if defined (__cplusplus) +} +#endif + +/* define CHECK_EXTERNAL if you want to check mpfr against another library + with correct rounding. You'll probably have to modify mpfr_print_raw() + and/or test_add() below: + * mpfr_print_raw() prints each number as "p m e" where p is the precision, + m the mantissa (as a binary integer with sign), and e the exponent. + The corresponding number is m*2^e. Example: "2 10 -6" represents + 2*2^(-6) with a precision of 2 bits. + * test_add() outputs "b c a" on one line, for each addition a <- b + c. + Currently it only prints such a line for rounding to nearest, when + the inputs b and c are not NaN and/or Inf. +*/ +#ifdef CHECK_EXTERNAL +static void +mpfr_print_raw (mpfr_srcptr x) +{ + printf ("%lu ", MPFR_PREC (x)); + if (MPFR_IS_NAN (x)) + { + printf ("@NaN@"); + return; + } + + if (MPFR_SIGN (x) < 0) + printf ("-"); + + if (MPFR_IS_INF (x)) + printf ("@Inf@"); + else if (MPFR_IS_ZERO (x)) + printf ("0 0"); + else + { + mp_limb_t *mx; + mpfr_prec_t px; + mp_size_t n; + + mx = MPFR_MANT (x); + px = MPFR_PREC (x); + + for (n = (px - 1) / GMP_NUMB_BITS; ; n--) + { + mp_limb_t wd, t; + + MPFR_ASSERTN (n >= 0); + wd = mx[n]; + for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1) + { + printf ((wd & t) == 0 ? "0" : "1"); + if (--px == 0) + { + mpfr_exp_t ex; + + ex = MPFR_GET_EXP (x); + MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX); + printf (" %ld", (long) ex - (long) MPFR_PREC (x)); + return; + } + } + } + } +} +#endif + +#endif diff --git a/mpfr/tests/mpfr_compat.c b/mpfr/tests/mpfr_compat.c new file mode 100644 index 0000000000..5a05e8af0f --- /dev/null +++ b/mpfr/tests/mpfr_compat.c @@ -0,0 +1,25 @@ +/* Test compatibility mpf-mpfr. + +Copyright 2003, 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#define MPFR +#define mpf_free_str mpfr_free_str +#include "mpf_compat.h" diff --git a/mpfr/tests/random2.c b/mpfr/tests/random2.c new file mode 100644 index 0000000000..9d5720ea90 --- /dev/null +++ b/mpfr/tests/random2.c @@ -0,0 +1,144 @@ +/* mpfr_random2 -- Generate a positive random mpfr_t of specified size, with + long runs of consecutive ones and zeros in the binary representation. + +Copyright 1999, 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mpfr-test.h" + +#define LOGBITS_PER_BLOCK 4 +#if GMP_NUMB_BITS < 32 +#define BITS_PER_RANDCALL GMP_NUMB_BITS +#else +#define BITS_PER_RANDCALL 32 +#endif + +void +mpfr_random2 (mpfr_ptr x, mp_size_t size, mpfr_exp_t exp, + gmp_randstate_t rstate) +{ + mp_size_t xn, k, ri; + unsigned long sh; + mp_limb_t *xp; + mp_limb_t elimb, ran, acc; + int ran_nbits, bit_pos, nb; + + if (MPFR_UNLIKELY(size == 0)) + { + MPFR_SET_ZERO (x); + MPFR_SET_POS (x); + return ; + } + else if (size > 0) + { + MPFR_SET_POS (x); + } + else + { + MPFR_SET_NEG (x); + size = -size; + } + + xn = MPFR_LIMB_SIZE (x); + xp = MPFR_MANT (x); + if (size > xn) + size = xn; + k = xn - size; + + /* Code extracted from GMP, function mpn_random2, to avoid the use + of GMP's internal random state in MPFR */ + + mpfr_rand_raw (&elimb, rstate, BITS_PER_RANDCALL); + ran = elimb; + + /* Start off at a random bit position in the most significant limb. */ + bit_pos = GMP_NUMB_BITS - 1; + ran >>= 6; /* Ideally log2(GMP_NUMB_BITS) */ + ran_nbits = BITS_PER_RANDCALL - 6; /* Ideally - log2(GMP_NUMB_BITS) */ + + /* Bit 0 of ran chooses string of ones/string of zeroes. + Make most significant limb be non-zero by setting bit 0 of RAN. */ + ran |= 1; + ri = xn - 1; + + acc = 0; + while (ri >= k) + { + if (ran_nbits < LOGBITS_PER_BLOCK + 1) + { + mpfr_rand_raw (&elimb, rstate, BITS_PER_RANDCALL); + ran = elimb; + ran_nbits = BITS_PER_RANDCALL; + } + + nb = (ran >> 1) % (1 << LOGBITS_PER_BLOCK) + 1; + if ((ran & 1) != 0) + { + /* Generate a string of nb ones. */ + if (nb > bit_pos) + { + xp[ri--] = acc | (((mp_limb_t) 2 << bit_pos) - 1); + bit_pos += GMP_NUMB_BITS; + bit_pos -= nb; + acc = ((~(mp_limb_t) 1) << bit_pos) & GMP_NUMB_MASK; + } + else + { + bit_pos -= nb; + acc |= (((mp_limb_t) 2 << nb) - 2) << bit_pos; + } + } + else + { + /* Generate a string of nb zeroes. */ + if (nb > bit_pos) + { + xp[ri--] = acc; + acc = 0; + bit_pos += GMP_NUMB_BITS; + } + bit_pos -= nb; + } + ran_nbits -= LOGBITS_PER_BLOCK + 1; + ran >>= LOGBITS_PER_BLOCK + 1; + } + + /* Set mandatory most significant bit. */ + /* xp[xn - 1] |= MPFR_LIMB_HIGHBIT; */ + + if (k != 0) + { + /* Clear last limbs */ + MPN_ZERO (xp, k); + } + else + { + /* Mask off non significant bits in the low limb. */ + MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (x)); + xp[0] &= ~MPFR_LIMB_MASK (sh); + } + + /* Generate random exponent. */ + mpfr_rand_raw (&elimb, RANDS, GMP_NUMB_BITS); + exp = ABS (exp); + MPFR_SET_EXP (x, elimb % (2 * exp + 1) - exp); + + return ; +} diff --git a/mpfr/tests/reuse.c b/mpfr/tests/reuse.c new file mode 100644 index 0000000000..5c03eea1df --- /dev/null +++ b/mpfr/tests/reuse.c @@ -0,0 +1,685 @@ +/* Test file for in-place operations. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define DISP(s, t) {printf(s); mpfr_out_str(stdout, 2, 0, t, MPFR_RNDN); } +#define DISP2(s,t) {DISP(s,t); putchar('\n');} + +#define SPECIAL_MAX 12 + +static void +set_special (mpfr_ptr x, unsigned int select) +{ + MPFR_ASSERTN (select < SPECIAL_MAX); + switch (select) + { + case 0: + MPFR_SET_NAN (x); + break; + case 1: + MPFR_SET_INF (x); + MPFR_SET_POS (x); + break; + case 2: + MPFR_SET_INF (x); + MPFR_SET_NEG (x); + break; + case 3: + MPFR_SET_ZERO (x); + MPFR_SET_POS (x); + break; + case 4: + MPFR_SET_ZERO (x); + MPFR_SET_NEG (x); + break; + case 5: + mpfr_set_str_binary (x, "1"); + break; + case 6: + mpfr_set_str_binary (x, "-1"); + break; + case 7: + mpfr_set_str_binary (x, "1e-1"); + break; + case 8: + mpfr_set_str_binary (x, "1e+1"); + break; + case 9: + mpfr_const_pi (x, MPFR_RNDN); + break; + case 10: + mpfr_const_pi (x, MPFR_RNDN); + MPFR_SET_EXP (x, MPFR_GET_EXP (x)-1); + break; + default: + mpfr_urandomb (x, RANDS); + if (randlimb () & 1) + mpfr_neg (x, x, MPFR_RNDN); + break; + } +} +/* same than mpfr_cmp, but returns 0 for both NaN's */ +static int +mpfr_compare (mpfr_srcptr a, mpfr_srcptr b) +{ + return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) : + (MPFR_IS_NAN(b) || mpfr_cmp(a, b)); +} + +static void +test3 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t), + const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t ref1, ref2, ref3; + mpfr_t res1; + int i; + +#ifdef DEBUG + printf("checking %s\n", foo); +#endif + mpfr_init2 (ref1, prec); + mpfr_init2 (ref2, prec); + mpfr_init2 (ref3, prec); + mpfr_init2 (res1, prec); + + /* for each variable, consider each of the following 6 possibilities: + NaN, +Infinity, -Infinity, +0, -0 or a random number */ + for (i=0; i < SPECIAL_MAX*SPECIAL_MAX ; i++) + { + set_special (ref2, i%SPECIAL_MAX); + set_special (ref3, i/SPECIAL_MAX); + + /* reference call: foo(a, b, c) */ + testfunc (ref1, ref2, ref3, rnd); + + /* foo(a, a, c) */ + mpfr_set (res1, ref2, rnd); /* exact operation */ + testfunc (res1, res1, ref3, rnd); + + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, a, c) for ", foo); + DISP("a=",ref2); DISP2(", c=",ref3); + printf ("expected "); mpfr_print_binary (ref1); puts (""); + printf ("got "); mpfr_print_binary (res1); puts (""); + exit (1); + } + + /* foo(a, b, a) */ + mpfr_set (res1, ref3, rnd); + testfunc (res1, ref2, res1, rnd); + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, b, a) for ", foo); + DISP("b=",ref2); DISP2(", a=", ref3); + DISP("expected ", ref1); DISP2(", got ",res1); + exit (1); + } + + /* foo(a, a, a) */ + mpfr_set (ref3, ref2, rnd); + testfunc (ref1, ref2, ref3, rnd); + mpfr_set (res1, ref2, rnd); + testfunc (res1, res1, res1, rnd); + + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, a, a) for ", foo); + DISP2("a=",ref2); + DISP("expected ", ref1); DISP2(", got", res1); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (ref3); + mpfr_clear (res1); +} + +static void +test4 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, + mpfr_rnd_t), + const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t ref, op1, op2, op3; + mpfr_t res; + int i, j, k; + +#ifdef DEBUG + printf("checking %s\n", foo); +#endif + mpfr_init2 (ref, prec); + mpfr_init2 (op1, prec); + mpfr_init2 (op2, prec); + mpfr_init2 (op3, prec); + mpfr_init2 (res, prec); + + /* for each variable, consider each of the following 6 possibilities: + NaN, +Infinity, -Infinity, +0, -0 or a random number */ + + for (i=0; i<SPECIAL_MAX; i++) + { + set_special (op1, i); + for (j=0; j<SPECIAL_MAX; j++) + { + set_special (op2, j); + for (k=0; k<SPECIAL_MAX; k++) + { + set_special (op3, k); + + /* reference call: foo(s, a, b, c) */ + testfunc (ref, op1, op2, op3, rnd); + + /* foo(a, a, b, c) */ + mpfr_set (res, op1, rnd); /* exact operation */ + testfunc (res, res, op2, op3, rnd); + + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, b, c) for ", foo); + DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + + /* foo(b, a, b, c) */ + mpfr_set (res, op2, rnd); + testfunc (res, op1, res, op3, rnd); + + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, b, c) for ", foo); + DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + + /* foo(c, a, b, c) */ + mpfr_set (res, op3, rnd); + testfunc (res, op1, op2, res, rnd); + + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, b, c) for ", foo); + DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + + /* foo(a, a, a,c) */ + testfunc (ref, op1, op1, op3, rnd); + mpfr_set (res, op1, rnd); + testfunc (res, res, res, op3, rnd); + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, b, c) for ", foo); + DISP("a=", op1); DISP(", a=", op2); DISP2(", c=", op3); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + + /* foo(a, a, b,a) */ + testfunc (ref, op1, op2, op1, rnd); + mpfr_set (res, op1, rnd); + testfunc (res, res, op2, res, rnd); + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, b, c) for ", foo); + DISP("a=", op1); DISP(", a=", op2); DISP2(", c=", op3); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + + /* foo(b, a, b, b) */ + testfunc (ref, op1, op2, op2, rnd); + mpfr_set (res, op2, rnd); + testfunc (res, op1, res, res, rnd); + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, b, c) for ", foo); + DISP("a=", op1); DISP(", a=", op2); DISP2(", c=", op3); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + + /* foo (a, a, a, a) */ + testfunc (ref, op1, op1, op1 ,rnd); + mpfr_set (res, op1, rnd); + testfunc (res, res, res, res, rnd); + if (mpfr_compare (res, ref)) + { + printf ("Error for %s(a, a, a, a) for ", foo); + DISP2("a=", op1); + DISP("expected ", ref); DISP2(", got", res); + exit (1); + } + } + } + } + + mpfr_clear (ref); + mpfr_clear (op1); + mpfr_clear (op2); + mpfr_clear (op3); + mpfr_clear (res); + +} + +static void +test2ui (int (*testfunc)(mpfr_ptr, mpfr_srcptr, unsigned long int, mpfr_rnd_t), + const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t ref1, ref2; + unsigned int ref3; + mpfr_t res1; + int i; + +#ifdef DEBUG + printf("checking %s\n", foo); +#endif + mpfr_init2 (ref1, prec); + mpfr_init2 (ref2, prec); + mpfr_init2 (res1, prec); + + /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number + ref3 can be 0 or any number */ + for (i=0; i<SPECIAL_MAX*2; i++) + { + set_special (ref2, i%SPECIAL_MAX); + ref3 = i/SPECIAL_MAX == 0 ? 0 : randlimb (); + + /* reference call: foo(a, b, c) */ + testfunc (ref1, ref2, ref3, rnd); + + /* foo(a, a, c) */ + mpfr_set (res1, ref2, rnd); /* exact operation */ + testfunc (res1, res1, ref3, rnd); + + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, a, c) for c=%u\n", foo, ref3); + DISP2("a=",ref2); + printf ("expected "); mpfr_print_binary (ref1); puts (""); + printf ("got "); mpfr_print_binary (res1); puts (""); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (res1); +} + +static void +testui2 (int (*testfunc)(mpfr_ptr, unsigned long int, mpfr_srcptr, mpfr_rnd_t), + const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t ref1, ref3; + unsigned int ref2; + mpfr_t res1; + int i; + +#ifdef DEBUG + printf("checking %s\n", foo); +#endif + mpfr_init2 (ref1, prec); + mpfr_init2 (ref3, prec); + mpfr_init2 (res1, prec); + + for (i=0; i<SPECIAL_MAX*2; i++) + { + set_special (ref3, i%SPECIAL_MAX); + ref2 = i/SPECIAL_MAX==0 ? 0 : randlimb (); + + /* reference call: foo(a, b, c) */ + testfunc (ref1, ref2, ref3, rnd); + + /* foo(a, b, a) */ + mpfr_set (res1, ref3, rnd); /* exact operation */ + testfunc (res1, ref2, res1, rnd); + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, b, a) for b=%u \n", foo, ref2); + DISP2("a=", ref3); + DISP("expected", ref1); DISP2(", got ", res1); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref3); + mpfr_clear (res1); +} + +/* foo(mpfr_ptr, mpfr_srcptr, mp_rndt) */ +static void +test2 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), + const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t ref1, ref2; + mpfr_t res1; + int i; + +#ifdef DEBUG + printf("checking %s\n", foo); +#endif + mpfr_init2 (ref1, prec); + mpfr_init2 (ref2, prec); + mpfr_init2 (res1, prec); + + for (i=0; i<SPECIAL_MAX; i++) + { + set_special (ref2, i); + + /* reference call: foo(a, b) */ + testfunc (ref1, ref2, rnd); + + /* foo(a, a) */ + mpfr_set (res1, ref2, rnd); /* exact operation */ + testfunc (res1, res1, rnd); + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, a) for ", foo); + DISP2("a=", ref2); + DISP("expected", ref1); DISP2(", got ", res1); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (res1); +} + +/* foo(mpfr_ptr, mpfr_srcptr) */ +static void +test2a (int (*testfunc)(mpfr_ptr, mpfr_srcptr), + const char *foo, mpfr_prec_t prec) +{ + mpfr_t ref1, ref2; + mpfr_t res1; + int i; + +#ifdef DEBUG + printf ("checking %s\n", foo); +#endif + mpfr_init2 (ref1, prec); + mpfr_init2 (ref2, prec); + mpfr_init2 (res1, prec); + + for (i=0; i<SPECIAL_MAX; i++) + { + set_special (ref2, i); + + /* reference call: foo(a, b) */ + testfunc (ref1, ref2); + + /* foo(a, a) */ + mpfr_set (res1, ref2, MPFR_RNDN); /* exact operation */ + testfunc (res1, res1); + if (mpfr_compare (res1, ref1)) + { + printf ("Error for %s(a, a) for ", foo); + DISP2("a=",ref2); + DISP("expected", ref1); DISP2(", got ", res1); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (res1); +} + +/* one operand, two results */ +static void +test3a (int (*testfunc)(mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), + const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t ref1, ref2, ref3; + mpfr_t res1, res2; + int i; + +#ifdef DEBUG + printf ("checking %s\n", foo); +#endif + mpfr_init2 (ref1, prec); + mpfr_init2 (ref2, prec); + mpfr_init2 (ref3, prec); + mpfr_init2 (res1, prec); + mpfr_init2 (res2, prec); + + for (i=0; i<SPECIAL_MAX; i++) + { + set_special (ref3, i); + + /* reference call: foo(a, b, c) */ + testfunc (ref1, ref2, ref3, rnd); + + /* foo(a, b, a) */ + mpfr_set (res1, ref3, rnd); /* exact operation */ + testfunc (res1, res2, res1, rnd); + if (mpfr_compare (res1, ref1) || mpfr_compare (res2, ref2)) + { + printf ("Error for %s(a, b, a) for rnd=%s, ", foo, + mpfr_print_rnd_mode (rnd)); + DISP2("a=",ref3); + DISP("expected (", ref1); DISP(",",ref2); + DISP("), got (", res1); DISP(",", res2); printf(")\n"); + exit (1); + } + + /* foo(a, b, b) */ + mpfr_set (res2, ref3, rnd); /* exact operation */ + testfunc (res1, res2, res2, rnd); + if (mpfr_compare (res1, ref1) || mpfr_compare (res2, ref2)) + { + printf ("Error for %s(a, b, b) for ", foo); + DISP2("b=",ref3); + DISP("expected (", ref1); DISP(",",ref2); + DISP("), got (", res1); DISP(",", res2); printf(")\n"); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (ref3); + mpfr_clear (res1); + mpfr_clear (res2); +} + +static int +reldiff_wrapper (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + mpfr_reldiff (a, b, c, rnd_mode); + return 0; +} + +static void +pow_int (mpfr_rnd_t rnd) +{ + mpfr_t ref1, ref2, ref3; + mpfr_t res1; + int i; + +#ifdef DEBUG + printf("pow_int\n"); +#endif + mpfr_inits2 ((randlimb () % 200) + MPFR_PREC_MIN, + ref1, ref2, res1, (mpfr_ptr) 0); + mpfr_init2 (ref3, 1005); + + for (i = 0; i <= 15; i++) + { + mpfr_urandomb (ref2, RANDS); + if (i & 1) + mpfr_neg (ref2, ref2, MPFR_RNDN); + mpfr_set_ui (ref3, 20, MPFR_RNDN); + /* We need to test huge integers because different algorithms/codes + are used for not-too-large integers (mpfr_pow_z) and for general + cases, in particular huge integers (mpfr_pow_general). [r7606] */ + if (i & 2) + mpfr_mul_2ui (ref3, ref3, 1000, MPFR_RNDN); + if (i & 4) + mpfr_add_ui (ref3, ref3, 1, MPFR_RNDN); /* odd integer */ + + /* reference call: pow(a, b, c) */ + mpfr_pow (ref1, ref2, ref3, rnd); + + /* pow(a, a, c) */ + mpfr_set (res1, ref2, rnd); /* exact operation */ + mpfr_pow (res1, res1, ref3, rnd); + + if (mpfr_compare (res1, ref1)) + { + printf ("Error for pow_int(a, a, c) for "); + DISP("a=",ref2); DISP2(", c=",ref3); + printf ("expected "); mpfr_print_binary (ref1); puts (""); + printf ("got "); mpfr_print_binary (res1); puts (""); + exit (1); + } + } + + mpfr_clears (ref1, ref2, ref3, res1, (mpfr_ptr) 0); +} + +int +main (void) +{ + int rnd; + mpfr_prec_t p; + tests_start_mpfr (); + + p = (randlimb () % 200) + MPFR_PREC_MIN; + RND_LOOP (rnd) + { + test2a (mpfr_round, "mpfr_round", p); + test2a (mpfr_ceil, "mpfr_ceil", p); + test2a (mpfr_floor, "mpfr_floor", p); + test2a (mpfr_trunc, "mpfr_trunc", p); + + test2ui (mpfr_add_ui, "mpfr_add_ui", p, (mpfr_rnd_t) rnd); + test2ui (mpfr_div_2exp, "mpfr_div_2exp", p, (mpfr_rnd_t) rnd); + test2ui (mpfr_div_ui, "mpfr_div_ui", p, (mpfr_rnd_t) rnd); + test2ui (mpfr_mul_2exp, "mpfr_mul_2exp", p, (mpfr_rnd_t) rnd); + test2ui (mpfr_mul_ui, "mpfr_mul_ui", p, (mpfr_rnd_t) rnd); + test2ui (mpfr_pow_ui, "mpfr_pow_ui", p, (mpfr_rnd_t) rnd); + test2ui (mpfr_sub_ui, "mpfr_sub_ui", p, (mpfr_rnd_t) rnd); + + testui2 (mpfr_ui_div, "mpfr_ui_div", p, (mpfr_rnd_t) rnd); + testui2 (mpfr_ui_sub, "mpfr_ui_sub", p, (mpfr_rnd_t) rnd); + testui2 (mpfr_ui_pow, "mpfr_ui_pow", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_sqr, "mpfr_sqr", p, (mpfr_rnd_t) rnd); + test2 (mpfr_sqrt, "mpfr_sqrt", p, (mpfr_rnd_t) rnd); + test2 (mpfr_abs, "mpfr_abs", p, (mpfr_rnd_t) rnd); + test2 (mpfr_neg, "mpfr_neg", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_log, "mpfr_log", p, (mpfr_rnd_t) rnd); + test2 (mpfr_log2, "mpfr_log2", p, (mpfr_rnd_t) rnd); + test2 (mpfr_log10, "mpfr_log10", p, (mpfr_rnd_t) rnd); + test2 (mpfr_log1p, "mpfr_log1p", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_exp, "mpfr_exp", p, (mpfr_rnd_t) rnd); + test2 (mpfr_exp2, "mpfr_exp2", p, (mpfr_rnd_t) rnd); + test2 (mpfr_exp10, "mpfr_exp10", p, (mpfr_rnd_t) rnd); + test2 (mpfr_expm1, "mpfr_expm1", p, (mpfr_rnd_t) rnd); + test2 (mpfr_eint, "mpfr_eint", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_sinh, "mpfr_sinh", p, (mpfr_rnd_t) rnd); + test2 (mpfr_cosh, "mpfr_cosh", p, (mpfr_rnd_t) rnd); + test2 (mpfr_tanh, "mpfr_tanh", p, (mpfr_rnd_t) rnd); + test2 (mpfr_asinh, "mpfr_asinh", p, (mpfr_rnd_t) rnd); + test2 (mpfr_acosh, "mpfr_acosh", p, (mpfr_rnd_t) rnd); + test2 (mpfr_atanh, "mpfr_atanh", p, (mpfr_rnd_t) rnd); + test2 (mpfr_sech, "mpfr_sech", p, (mpfr_rnd_t) rnd); + test2 (mpfr_csch, "mpfr_csch", p, (mpfr_rnd_t) rnd); + test2 (mpfr_coth, "mpfr_coth", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_asin, "mpfr_asin", p, (mpfr_rnd_t) rnd); + test2 (mpfr_acos, "mpfr_acos", p, (mpfr_rnd_t) rnd); + test2 (mpfr_atan, "mpfr_atan", p, (mpfr_rnd_t) rnd); + test2 (mpfr_cos, "mpfr_cos", p, (mpfr_rnd_t) rnd); + test2 (mpfr_sin, "mpfr_sin", p, (mpfr_rnd_t) rnd); + test2 (mpfr_tan, "mpfr_tan", p, (mpfr_rnd_t) rnd); + test2 (mpfr_sec, "mpfr_sec", p, (mpfr_rnd_t) rnd); + test2 (mpfr_csc, "mpfr_csc", p, (mpfr_rnd_t) rnd); + test2 (mpfr_cot, "mpfr_cot", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_erf, "mpfr_erf", p, (mpfr_rnd_t) rnd); + test2 (mpfr_erfc, "mpfr_erfc", p, (mpfr_rnd_t) rnd); + test2 (mpfr_j0, "mpfr_j0", p, (mpfr_rnd_t) rnd); + test2 (mpfr_j1, "mpfr_j1", p, (mpfr_rnd_t) rnd); + test2 (mpfr_y0, "mpfr_y0", p, (mpfr_rnd_t) rnd); + test2 (mpfr_y1, "mpfr_y1", p, (mpfr_rnd_t) rnd); + test2 (mpfr_zeta, "mpfr_zeta", p, (mpfr_rnd_t) rnd); + test2 (mpfr_gamma, "mpfr_gamma", p, (mpfr_rnd_t) rnd); + test2 (mpfr_lngamma, "mpfr_lngamma", p, (mpfr_rnd_t) rnd); + + test2 (mpfr_rint, "mpfr_rint", p, (mpfr_rnd_t) rnd); + test2 (mpfr_rint_ceil, "mpfr_rint_ceil", p, (mpfr_rnd_t) rnd); + test2 (mpfr_rint_floor, "mpfr_rint_floor", p, (mpfr_rnd_t) rnd); + test2 (mpfr_rint_round, "mpfr_rint_round", p, (mpfr_rnd_t) rnd); + test2 (mpfr_rint_trunc, "mpfr_rint_trunc", p, (mpfr_rnd_t) rnd); + test2 (mpfr_frac, "mpfr_frac", p, (mpfr_rnd_t) rnd); + + test3 (mpfr_add, "mpfr_add", p, (mpfr_rnd_t) rnd); + test3 (mpfr_sub, "mpfr_sub", p, (mpfr_rnd_t) rnd); + test3 (mpfr_mul, "mpfr_mul", p, (mpfr_rnd_t) rnd); + test3 (mpfr_div, "mpfr_div", p, (mpfr_rnd_t) rnd); + + test3 (mpfr_agm, "mpfr_agm", p, (mpfr_rnd_t) rnd); + test3 (mpfr_min, "mpfr_min", p, (mpfr_rnd_t) rnd); + test3 (mpfr_max, "mpfr_max", p, (mpfr_rnd_t) rnd); + + test3 (reldiff_wrapper, "mpfr_reldiff", p, (mpfr_rnd_t) rnd); + test3 (mpfr_dim, "mpfr_dim", p, (mpfr_rnd_t) rnd); + + test3 (mpfr_remainder, "mpfr_remainder", p, (mpfr_rnd_t) rnd); + test3 (mpfr_pow, "mpfr_pow", p, (mpfr_rnd_t) rnd); + pow_int ((mpfr_rnd_t) rnd); + test3 (mpfr_atan2, "mpfr_atan2", p, (mpfr_rnd_t) rnd); + test3 (mpfr_hypot, "mpfr_hypot", p, (mpfr_rnd_t) rnd); + + test3a (mpfr_sin_cos, "mpfr_sin_cos", p, (mpfr_rnd_t) rnd); + + test4 (mpfr_fma, "mpfr_fma", p, (mpfr_rnd_t) rnd); + test4 (mpfr_fms, "mpfr_fms", p, (mpfr_rnd_t) rnd); + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + test2 (mpfr_li2, "mpfr_li2", p, (mpfr_rnd_t) rnd); + test2 (mpfr_rec_sqrt, "mpfr_rec_sqrt", p, (mpfr_rnd_t) rnd); + test3 (mpfr_fmod, "mpfr_fmod", p, (mpfr_rnd_t) rnd); + test3a (mpfr_modf, "mpfr_modf", p, (mpfr_rnd_t) rnd); + test3a (mpfr_sinh_cosh, "mpfr_sinh_cosh", p, (mpfr_rnd_t) rnd); +#endif + } + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/rnd_mode.c b/mpfr/tests/rnd_mode.c new file mode 100644 index 0000000000..1cbe6f6730 --- /dev/null +++ b/mpfr/tests/rnd_mode.c @@ -0,0 +1,70 @@ +/* mpfr_set_machine_rnd_mode -- set the rounding mode for machine floats + +Copyright 1999, 2001-2002, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "mpfr-test.h" + +/* It is important to test each FE_* macro -- see the ISO C99 standard. + For instance, with some ARM implementations, only FE_TONEAREST may + be defined. */ + +/* sets the machine rounding mode to the value rnd_mode */ +int +mpfr_set_machine_rnd_mode (mpfr_rnd_t rnd_mode) +{ + switch (rnd_mode) + { + case MPFR_RNDN: + return +#if defined (MPFR_HAVE_FESETROUND) && defined (FE_TONEAREST) + fesetround(FE_TONEAREST) +#else + -1 +#endif + ; + case MPFR_RNDZ: + return +#if defined (MPFR_HAVE_FESETROUND) && defined (FE_TOWARDZERO) + fesetround(FE_TOWARDZERO) +#else + -1 +#endif + ; + case MPFR_RNDU: + return +#if defined (MPFR_HAVE_FESETROUND) && defined (FE_UPWARD) + fesetround(FE_UPWARD) +#else + -1 +#endif + ; + case MPFR_RNDD: + return +#if defined (MPFR_HAVE_FESETROUND) && defined (FE_DOWNWARD) + fesetround(FE_DOWNWARD) +#else + -1 +#endif + ; + default: + return -1; + } +} diff --git a/mpfr/tests/tabs.c b/mpfr/tests/tabs.c new file mode 100644 index 0000000000..9448ec442c --- /dev/null +++ b/mpfr/tests/tabs.c @@ -0,0 +1,176 @@ +/* Test file for mpfr_abs. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +static void +check_inexact (void) +{ + mpfr_prec_t p, q; + mpfr_t x, y, absx; + int rnd; + int inexact, cmp; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (absx); + + for (p=2; p<500; p++) + { + mpfr_set_prec (x, p); + mpfr_set_prec (absx, p); + mpfr_urandomb (x, RANDS); + if (randlimb () % 2) + { + mpfr_set (absx, x, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + } + else + mpfr_set (absx, x, MPFR_RNDN); + for (q=2; q<2*p; q++) + { + mpfr_set_prec (y, q); + RND_LOOP (rnd) + { + inexact = mpfr_abs (y, x, (mpfr_rnd_t) rnd); + cmp = mpfr_cmp (y, absx); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong inexact flag: expected %d, got %d\n", + cmp, inexact); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("absx="); mpfr_print_binary (absx); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (absx); +} + +static void +check_cmp (int argc, char *argv[]) +{ + mpfr_t x, y; + int n, k; + + mpfr_inits2 (53, x, y, (mpfr_ptr) 0); + + mpfr_set_ui(x, 1, MPFR_RNDN); + (mpfr_abs) (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_abs(1.0)\n"); + exit (1); + } + + mpfr_set_si(x, -1, MPFR_RNDN); + mpfr_abs(x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_abs(1.0)\n"); + exit (1); + } + + mpfr_set_si(x, -1, MPFR_RNDN); + mpfr_abs(x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_abs(-1.0)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_abs (x, x, MPFR_RNDN); + if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0)) + { + printf ("Error in mpfr_abs(Inf).\n"); + exit (1); + } + mpfr_set_inf (x, -1); + mpfr_abs (x, x, MPFR_RNDN); + if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0)) + { + printf ("Error in mpfr_abs(-Inf).\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_abs (x, x, MPFR_RNDN); + if (!MPFR_IS_NAN(x)) + { + printf ("Error in mpfr_abs(NAN).\n"); + exit (1); + } + + n = (argc==1) ? 25000 : atoi(argv[1]); + for (k = 1; k <= n; k++) + { + mpfr_rnd_t rnd; + int sign = SIGN_RAND (); + + mpfr_urandomb (x, RANDS); + MPFR_SET_SIGN (x, sign); + rnd = RND_RAND (); + mpfr_abs (y, x, rnd); + MPFR_SET_POS (x); + if (mpfr_cmp (x, y)) + { + printf ("Mismatch for sign=%d and x=", sign); + mpfr_print_binary (x); + printf ("\nResults="); + mpfr_print_binary (y); + putchar ('\n'); + exit (1); + } + } + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION mpfr_abs +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_test_init (); + tests_start_mpfr (); + + check_inexact (); + check_cmp (argc, argv); + + test_generic (2, 1000, 10); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tacos.c b/mpfr/tests/tacos.c new file mode 100644 index 0000000000..5ceb6245c9 --- /dev/null +++ b/mpfr/tests/tacos.c @@ -0,0 +1,187 @@ +/* Test file for mpfr_acos. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_acos +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int inex1, inex2; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 32); + + mpfr_set_str_binary (x, "0.10001000001001011000100001E-6"); + mpfr_acos (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "1.10001111111111110001110110001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_acos (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.01101011110111100111010011001011"); + mpfr_acos (y, x, MPFR_RNDZ); + mpfr_set_str_binary (x, "10.0000000101111000011101000101"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_acos (2)\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 0, MPFR_RNDN); + inex1 = mpfr_acos (x, x, MPFR_RNDN); /* Pi/2 */ + inex2 = mpfr_const_pi (x, MPFR_RNDN); + if (inex1 != inex2) + { + printf ("Error in mpfr_acos (3) for prec=2\n"); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); +} + +static void +special_overflow (void) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + mpfr_init2 (x, 24); + mpfr_init2 (y, 48); + mpfr_set_str_binary (x, "0.101100100000000000110100E0"); + mpfr_acos (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.110011010100101111000100111010111011010000001001E0", + 2, MPFR_RNDN)) + { + printf("Special Overflow error.\n"); + mpfr_dump (y); + exit (1); + } + mpfr_clear (y); + mpfr_clear (x); + set_emin (emin); + set_emax (emax); +} + +int +main (void) +{ + mpfr_t x, y; + int r; + + tests_start_mpfr (); + + special_overflow (); + special (); + + mpfr_init (x); + mpfr_init (y); + + MPFR_SET_NAN(x); + mpfr_acos (y, x, MPFR_RNDN); + if (mpfr_nan_p(y) == 0) + { + printf ("Error: acos(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_acos (y, x, MPFR_RNDN); + if (mpfr_nan_p(y) == 0) + { + printf ("Error: acos(2) != NaN\n"); + exit (1); + } + + mpfr_set_si (x, -2, MPFR_RNDN); + mpfr_acos (y, x, MPFR_RNDN); + if (mpfr_nan_p(y) == 0) + { + printf ("Error: acos(-2) != NaN\n"); + exit (1); + } + + /* acos (1) = 0 */ + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_acos (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: acos(1) != +0.0\n"); + exit (1); + } + + /* acos (0) = Pi/2 */ + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_set_ui (x, 0, MPFR_RNDN); /* exact */ + mpfr_acos (y, x, (mpfr_rnd_t) r); + mpfr_const_pi (x, (mpfr_rnd_t) r); + mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */ + if (mpfr_cmp (x, y)) + { + printf ("Error: acos(0) != Pi/2 for rnd=%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + /* acos (-1) = Pi */ + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_set_si (x, -1, MPFR_RNDN); /* exact */ + mpfr_acos (y, x, (mpfr_rnd_t) r); + mpfr_const_pi (x, (mpfr_rnd_t) r); + if (mpfr_cmp (x, y)) + { + printf ("Error: acos(1) != Pi for rnd=%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + test_generic (2, 100, 7); + + mpfr_clear (x); + mpfr_clear (y); + + data_check ("data/acos", mpfr_acos, "mpfr_acos"); + bad_cases (mpfr_acos, mpfr_cos, "mpfr_acos", 0, -40, 2, 4, 128, 800, 30); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tacosh.c b/mpfr/tests/tacosh.c new file mode 100644 index 0000000000..1d72dd5d5c --- /dev/null +++ b/mpfr/tests/tacosh.c @@ -0,0 +1,219 @@ +/* Test file for mpfr_acosh. + +Copyright 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_acosh +#define TEST_RANDOM_POS 4 +#define TEST_RANDOM_EMIN 1 +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_acosh +#define TEST_RANDOM_POS 1 +#define TEST_RANDOM_EMIN MPFR_EMAX_MAX +#define TEST_RANDOM_EMAX MPFR_EMAX_MAX +#define test_generic test_generic_huge +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + MPFR_SET_INF(x); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_acosh (x, y, MPFR_RNDN); + if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) + { + printf ("Inf flag not clears in acosh!\n"); + exit (1); + } + if (mpfr_cmp_ui (x, 0)) + { + printf ("Error: mpfr_acosh(1) <> 0\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_acosh (x, y, MPFR_RNDN); + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x) ) + { + printf ("NAN flag not clears in acosh!\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_acosh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(0) <> NaN\n"); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_acosh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(-1) <> NaN\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_acosh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(NaN) <> NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_acosh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_acosh(+Inf) <> +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_acosh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(-Inf) <> NaN\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2exp (x, x, 1, MPFR_RNDN); + mpfr_acosh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(1/2) <> NaN\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "1.000001101011101111001011"); + mpfr_acosh (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.111010100101101001010001101001E-2"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_acosh (1)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +/* With MPFR 2.3.0, this yields an assertion failure in mpfr_acosh. */ +static void +bug20070831 (void) +{ + mpfr_t x, y, z; + int inex; + + mpfr_init2 (x, 256); + mpfr_init2 (y, 32); + mpfr_init2 (z, 32); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextabove (x); + inex = mpfr_acosh (y, x, MPFR_RNDZ); + mpfr_set_ui_2exp (z, 1, -127, MPFR_RNDN); + mpfr_nextbelow (z); + if (!mpfr_equal_p (y, z)) + { + printf ("Error in bug20070831 (1):\nexpected "); + mpfr_dump (z); + printf ("got "); + mpfr_dump (y); + exit (1); + } + MPFR_ASSERTN (inex < 0); + + mpfr_nextabove (x); + mpfr_set_prec (y, 29); + inex = mpfr_acosh (y, x, MPFR_RNDN); + mpfr_set_str_binary (z, "1.011010100000100111100110011E-127"); + if (!mpfr_equal_p (y, z)) + { + printf ("Error in bug20070831 (2):\nexpected "); + mpfr_dump (z); + printf ("got "); + mpfr_dump (y); + exit (1); + } + MPFR_ASSERTN (inex < 0); + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static void +huge (void) +{ + mpfr_t x, y, z; + int inex; + + /* TODO: extend the exponent range and use mpfr_get_emax (). */ + mpfr_inits2 (32, x, y, z, (mpfr_ptr) 0); + mpfr_set_ui_2exp (x, 1, 1073741822, MPFR_RNDN); + inex = mpfr_acosh (y, x, MPFR_RNDN); + mpfr_set_str_binary (z, "0.10110001011100100001011111110101E30"); + if (!mpfr_equal_p (y, z)) + { + printf ("Error in huge:\nexpected "); + mpfr_dump (z); + printf ("got "); + mpfr_dump (y); + exit (1); + } + MPFR_ASSERTN (inex < 0); + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + bug20070831 (); + huge (); + + test_generic (2, 100, 25); + test_generic_huge (2, 100, 5); + + data_check ("data/acosh", mpfr_acosh, "mpfr_acosh"); + bad_cases (mpfr_acosh, mpfr_cosh, "mpfr_acosh", 0, -128, 29, + 4, 128, 800, 40); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tadd.c b/mpfr/tests/tadd.c new file mode 100644 index 0000000000..00390c3c4d --- /dev/null +++ b/mpfr/tests/tadd.c @@ -0,0 +1,1120 @@ +/* Test file for mpfr_add and mpfr_sub. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#define N 30000 + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +/* If the precisions are the same, we want to test both mpfr_add1sp + and mpfr_add1. */ + +static int usesp; + +static int +test_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + int res; +#ifdef CHECK_EXTERNAL + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c); + if (ok) + { + mpfr_print_raw (b); + printf (" "); + mpfr_print_raw (c); + } +#endif + if (usesp || MPFR_ARE_SINGULAR(b,c) || MPFR_SIGN(b) != MPFR_SIGN(c)) + res = mpfr_add (a, b, c, rnd_mode); + else + { + if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c)) + res = mpfr_add1(a, c, b, rnd_mode); + else + res = mpfr_add1(a, b, c, rnd_mode); + } +#ifdef CHECK_EXTERNAL + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } +#endif + return res; +} + +/* checks that xs+ys gives the expected result zs */ +static void +check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, + unsigned int px, unsigned int py, unsigned int pz, const char *zs) +{ + mpfr_t xx,yy,zz; + + mpfr_init2 (xx, px); + mpfr_init2 (yy, py); + mpfr_init2 (zz, pz); + + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_add (zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, zs) ) + { + printf ("expected sum is %s, got ", zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + printf ("mpfr_add failed for x=%s y=%s with rnd_mode=%s\n", + xs, ys, mpfr_print_rnd_mode (rnd_mode)); + exit (1); + } + mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); +} + +static void +check2b (const char *xs, int px, + const char *ys, int py, + const char *rs, int pz, + mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, yy, zz; + + mpfr_init2 (xx,px); + mpfr_init2 (yy,py); + mpfr_init2 (zz,pz); + mpfr_set_str_binary (xx, xs); + mpfr_set_str_binary (yy, ys); + test_add (zz, xx, yy, rnd_mode); + if (mpfr_cmp_str (zz, rs, 2, MPFR_RNDN)) + { + printf ("(2) x=%s,%d y=%s,%d pz=%d,rnd=%s\n", + xs, px, ys, py, pz, mpfr_print_rnd_mode (rnd_mode)); + printf ("got "); mpfr_print_binary(zz); puts (""); + mpfr_set_str(zz, rs, 2, MPFR_RNDN); + printf ("instead of "); mpfr_print_binary(zz); puts (""); + exit (1); + } + mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); +} + +static void +check64 (void) +{ + mpfr_t x, t, u; + + mpfr_init (x); + mpfr_init (t); + mpfr_init (u); + + mpfr_set_prec (x, 29); + mpfr_set_str_binary (x, "1.1101001000101111011010010110e-3"); + mpfr_set_prec (t, 58); + mpfr_set_str_binary (t, "0.11100010011111001001100110010111110110011000000100101E-1"); + mpfr_set_prec (u, 29); + test_add (u, x, t, MPFR_RNDD); + mpfr_set_str_binary (t, "1.0101011100001000011100111110e-1"); + if (mpfr_cmp (u, t)) + { + printf ("mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n"); + printf ("expected "); mpfr_out_str (stdout, 2, 29, t, MPFR_RNDN); + puts (""); + printf ("got "); mpfr_out_str (stdout, 2, 29, u, MPFR_RNDN); + puts (""); + exit(1); + } + + mpfr_set_prec (x, 4); + mpfr_set_str_binary (x, "-1.0E-2"); + mpfr_set_prec (t, 2); + mpfr_set_str_binary (t, "-1.1e-2"); + mpfr_set_prec (u, 2); + test_add (u, x, t, MPFR_RNDN); + if (MPFR_MANT(u)[0] << 2) + { + printf ("result not normalized for prec=2\n"); + mpfr_print_binary (u); puts (""); + exit (1); + } + mpfr_set_str_binary (t, "-1.0e-1"); + if (mpfr_cmp (u, t)) + { + printf ("mpfr_add(u, x, t) failed for prec(x)=4, prec(t)=2\n"); + printf ("expected -1.0e-1\n"); + printf ("got "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN); + puts (""); + exit (1); + } + + mpfr_set_prec (x, 8); + mpfr_set_str_binary (x, "-0.10011010"); /* -77/128 */ + mpfr_set_prec (t, 4); + mpfr_set_str_binary (t, "-1.110e-5"); /* -7/128 */ + mpfr_set_prec (u, 4); + test_add (u, x, t, MPFR_RNDN); /* should give -5/8 */ + mpfr_set_str_binary (t, "-1.010e-1"); + if (mpfr_cmp (u, t)) { + printf ("mpfr_add(u, x, t) failed for prec(x)=8, prec(t)=4\n"); + printf ("expected -1.010e-1\n"); + printf ("got "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN); + puts (""); + exit (1); + } + + mpfr_set_prec (x, 112); mpfr_set_prec (t, 98); mpfr_set_prec (u, 54); + mpfr_set_str_binary (x, "-0.11111100100000000011000011100000101101010001000111E-401"); + mpfr_set_str_binary (t, "0.10110000100100000101101100011111111011101000111000101E-464"); + test_add (u, x, t, MPFR_RNDN); + if (mpfr_cmp (u, x)) + { + printf ("mpfr_add(u, x, t) failed for prec(x)=112, prec(t)=98\n"); + exit (1); + } + + mpfr_set_prec (x, 92); mpfr_set_prec (t, 86); mpfr_set_prec (u, 53); + mpfr_set_str (x, "-5.03525136761487735093e-74", 10, MPFR_RNDN); + mpfr_set_str (t, "8.51539046314262304109e-91", 10, MPFR_RNDN); + test_add (u, x, t, MPFR_RNDN); + if (mpfr_cmp_str1 (u, "-5.0352513676148773509283672e-74") ) + { + printf ("mpfr_add(u, x, t) failed for prec(x)=92, prec(t)=86\n"); + exit (1); + } + + mpfr_set_prec(x, 53); mpfr_set_prec(t, 76); mpfr_set_prec(u, 76); + mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32"); + mpfr_set_str_binary(t, "-0.1011000101110010000101111111011111010001110011110111100110101011110010011111"); + mpfr_sub(u, x, t, MPFR_RNDU); + mpfr_set_str_binary(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100"); + if (mpfr_cmp(u,t)) + { + printf ("expect "); mpfr_print_binary(t); puts (""); + printf ("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_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32"); + mpfr_set_str_binary(t, "-0.101100010111001000010111111101111101000111001111011110011010101111001001111000111011001110011000000000111111"); + mpfr_sub(u, x, t, MPFR_RNDU); + mpfr_set_str_binary(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111"); + if (mpfr_cmp(u,t)) + { + printf ("expect "); mpfr_print_binary(t); puts (""); + printf ("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_binary(x, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010000000000000000E-39"); + mpfr_set_ui(t, 1, MPFR_RNDN); + test_add (u, x, t, MPFR_RNDN); + mpfr_set_str_binary(x, "0.1000000000000000000000000000000000000000111110110000100000000101100011011110100000101111100010001E1"); + if (mpfr_cmp(u,x)) + { + printf ("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_binary(x, "0.10101011111001001010111011001000101100111101000000111111111011010100001100011101010001010111111101111010100110111111100101100010E-4"); + mpfr_set(t, x, MPFR_RNDN); + mpfr_sub(u, x, t, MPFR_RNDN); + mpfr_set_prec(x, 96); mpfr_set_prec(t, 96); mpfr_set_prec(u, 96); + mpfr_set_str_binary(x, "0.111000000001110100111100110101101001001010010011010011100111100011010100011001010011011011000010E-4"); + mpfr_set(t, x, MPFR_RNDN); + mpfr_sub(u, x, t, MPFR_RNDN); + mpfr_set_prec(x, 85); mpfr_set_prec(t, 85); mpfr_set_prec(u, 85); + mpfr_set_str_binary(x, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4"); + mpfr_set_str_binary(t, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4"); + mpfr_sub(u, x, t, MPFR_RNDU); + mpfr_sub(x, x, t, MPFR_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 ((MPFR_MANT(u)[(MPFR_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 (1)\n"); + exit (1); + } + mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65); + mpfr_set_str_binary(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623"); + mpfr_set_str_binary(t, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); + mpfr_sub(u, x, t, MPFR_RNDU); + if (mpfr_cmp_ui_2exp(u, 1, 558)) + { /* 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_binary(x, "0.1000011110101111011110111111000011101011101111101101101100000100E-220"); + mpfr_set_str_binary(t, "0.1000011110101111011110111111000011101011101111101101010011111101E-220"); + test_add (u, x, t, MPFR_RNDU); + if ((MPFR_MANT(u)[0] & 1) != 1) + { + printf ("error in mpfr_add with rnd_mode=MPFR_RNDU\n"); + printf ("b= "); mpfr_print_binary(x); puts (""); + printf ("c= "); mpfr_print_binary(t); puts (""); + printf ("b+c="); mpfr_print_binary(u); puts (""); + exit (1); + } + + /* bug found by Norbert Mueller, 14 Sep 2000 */ + mpfr_set_prec(x, 56); mpfr_set_prec(t, 83); mpfr_set_prec(u, 10); + mpfr_set_str_binary(x, "0.10001001011011001111101100110100000101111010010111010111E-7"); + mpfr_set_str_binary(t, "0.10001001011011001111101100110100000101111010010111010111000000000111110110110000100E-7"); + mpfr_sub(u, x, t, MPFR_RNDU); + + /* array bound write found by Norbert Mueller, 26 Sep 2000 */ + mpfr_set_prec(x, 109); mpfr_set_prec(t, 153); mpfr_set_prec(u, 95); + mpfr_set_str_binary(x,"0.1001010000101011101100111000110001111111111111111111111111111111111111111111111111111111111111100000000000000E33"); + mpfr_set_str_binary(t,"-0.100101000010101110110011100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100101101000000100100001100110111E33"); + test_add (u, x, t, MPFR_RNDN); + + /* array bound writes found by Norbert Mueller, 27 Sep 2000 */ + mpfr_set_prec(x, 106); mpfr_set_prec(t, 53); mpfr_set_prec(u, 23); + mpfr_set_str_binary(x, "-0.1000011110101111111001010001000100001011000000000000000000000000000000000000000000000000000000000000000000E-59"); + mpfr_set_str_binary(t, "-0.10000111101011111110010100010001101100011100110100000E-59"); + mpfr_sub(u, x, t, MPFR_RNDN); + mpfr_set_prec(x, 177); mpfr_set_prec(t, 217); mpfr_set_prec(u, 160); + mpfr_set_str_binary(x, "-0.111010001011010000111001001010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E35"); + mpfr_set_str_binary(t, "0.1110100010110100001110010010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111011010011100001111001E35"); + test_add (u, x, t, MPFR_RNDN); + mpfr_set_prec(x, 214); mpfr_set_prec(t, 278); mpfr_set_prec(u, 207); + mpfr_set_str_binary(x, "0.1000100110100110101101101101000000010000100111000001001110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E66"); + mpfr_set_str_binary(t, "-0.10001001101001101011011011010000000100001001110000010011100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111011111001001100011E66"); + test_add (u, x, t, MPFR_RNDN); + mpfr_set_prec(x, 32); mpfr_set_prec(t, 247); mpfr_set_prec(u, 223); + mpfr_set_str_binary(x, "0.10000000000000000000000000000000E1"); + mpfr_set_str_binary(t, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100000100011110000101110110011101110100110110111111011010111100100000000000000000000000000E0"); + mpfr_sub(u, x, t, MPFR_RNDN); + if ((MPFR_MANT(u)[(MPFR_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 (2)\n"); + exit (1); + } + + /* bug found by Nathalie Revol, 21 March 2001 */ + mpfr_set_prec (x, 65); + mpfr_set_prec (t, 65); + mpfr_set_prec (u, 65); + mpfr_set_str_binary (x, "0.11100100101101001100111011111111110001101001000011101001001010010E-35"); + mpfr_set_str_binary (t, "0.10000000000000000000000000000000000001110010010110100110011110000E1"); + mpfr_sub (u, t, x, MPFR_RNDU); + if ((MPFR_MANT(u)[(MPFR_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 (3)\n"); + exit (1); + } + + /* bug found by Fabrice Rouillier, 27 Mar 2001 */ + mpfr_set_prec (x, 107); + mpfr_set_prec (t, 107); + mpfr_set_prec (u, 107); + mpfr_set_str_binary (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315"); + mpfr_set_str_binary (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350"); + mpfr_sub (u, x, t, MPFR_RNDU); + if ((MPFR_MANT(u)[(MPFR_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 (4)\n"); + exit (1); + } + + /* checks that NaN flag is correctly reset */ + mpfr_set_ui (t, 1, MPFR_RNDN); + mpfr_set_ui (u, 1, MPFR_RNDN); + mpfr_set_nan (x); + test_add (x, t, u, MPFR_RNDN); + if (mpfr_cmp_ui (x, 2)) + { + printf ("Error in mpfr_add: 1+1 gives "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); + exit (1); + } + + mpfr_clear(x); mpfr_clear(t); mpfr_clear(u); +} + +/* check case when c does not overlap with a, but both b and c count + for rounding */ +static void +check_case_1b (void) +{ + mpfr_t a, b, c; + unsigned int prec_a, prec_b, prec_c, dif; + + mpfr_init (a); + mpfr_init (b); + mpfr_init (c); + + { + prec_a = MPFR_PREC_MIN + (randlimb () % 63); + mpfr_set_prec (a, prec_a); + for (prec_b = prec_a + 2; prec_b <= 64; prec_b++) + { + dif = prec_b - prec_a; + mpfr_set_prec (b, prec_b); + /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */ + mpfr_set_ui (b, 1, MPFR_RNDN); + mpfr_div_2exp (b, b, dif, MPFR_RNDN); + mpfr_sub_ui (b, b, 1, MPFR_RNDN); + mpfr_div_2exp (b, b, prec_a, MPFR_RNDN); + mpfr_add_ui (b, b, 1, MPFR_RNDN); + for (prec_c = dif; prec_c <= 64; prec_c++) + { + /* c = 2^(-prec_a) - 2^(-prec_b) */ + mpfr_set_prec (c, prec_c); + mpfr_set_si (c, -1, MPFR_RNDN); + mpfr_div_2exp (c, c, dif, MPFR_RNDN); + mpfr_add_ui (c, c, 1, MPFR_RNDN); + mpfr_div_2exp (c, c, prec_a, MPFR_RNDN); + test_add (a, b, c, MPFR_RNDN); + if (mpfr_cmp_ui (a, 1) != 0) + { + printf ("case (1b) failed for prec_a=%u, prec_b=%u," + " prec_c=%u\n", prec_a, prec_b, prec_c); + printf ("b="); mpfr_print_binary(b); puts (""); + printf ("c="); mpfr_print_binary(c); puts (""); + printf ("a="); mpfr_print_binary(a); puts (""); + exit (1); + } + } + } + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); +} + +/* check case when c overlaps with a */ +static void +check_case_2 (void) +{ + mpfr_t a, b, c, d; + + mpfr_init2 (a, 300); + mpfr_init2 (b, 800); + mpfr_init2 (c, 500); + mpfr_init2 (d, 800); + + mpfr_set_str_binary(a, "1E110"); /* a = 2^110 */ + mpfr_set_str_binary(b, "1E900"); /* b = 2^900 */ + mpfr_set_str_binary(c, "1E500"); /* c = 2^500 */ + test_add (c, c, a, MPFR_RNDZ); /* c = 2^500 + 2^110 */ + mpfr_sub (d, b, c, MPFR_RNDZ); /* d = 2^900 - 2^500 - 2^110 */ + test_add (b, b, c, MPFR_RNDZ); /* b = 2^900 + 2^500 + 2^110 */ + test_add (a, b, d, MPFR_RNDZ); /* a = 2^901 */ + if (mpfr_cmp_ui_2exp (a, 1, 901)) + { + printf ("b + d fails for b=2^900+2^500+2^110, d=2^900-2^500-2^110\n"); + printf ("expected 1.0e901, got "); + mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpfr_clear (d); +} + +/* checks when source and destination are equal */ +static void +check_same (void) +{ + mpfr_t x; + + mpfr_init(x); mpfr_set_ui(x, 1, MPFR_RNDZ); + test_add (x, x, x, MPFR_RNDZ); + if (mpfr_cmp_ui (x, 2)) + { + printf ("Error when all 3 operands are equal\n"); + exit (1); + } + mpfr_clear(x); +} + +#define check53(x, y, r, z) check(x, y, r, 53, 53, 53, z) + +#define MAX_PREC 256 + +static void +check_inexact (void) +{ + mpfr_t x, y, z, u; + mpfr_prec_t px, py, pu, pz; + int inexact, cmp; + mpfr_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (u); + + mpfr_set_prec (x, 2); + mpfr_set_str_binary (x, "0.1E-4"); + mpfr_set_prec (u, 33); + mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1"); + mpfr_set_prec (y, 31); + if ((inexact = test_add (y, x, u, MPFR_RNDN))) + { + printf ("Wrong inexact flag (2): expected 0, got %d\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_str_binary (x, "0.1E-4"); + mpfr_set_prec (u, 33); + mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1"); + mpfr_set_prec (y, 28); + if ((inexact = test_add (y, x, u, MPFR_RNDN))) + { + printf ("Wrong inexact flag (1): expected 0, got %d\n", inexact); + exit (1); + } + + for (px=2; px<MAX_PREC; px++) + { + mpfr_set_prec (x, px); + do + { + mpfr_urandomb (x, RANDS); + } + while (mpfr_cmp_ui (x, 0) == 0); + for (pu=2; pu<MAX_PREC; pu++) + { + mpfr_set_prec (u, pu); + do + { + mpfr_urandomb (u, RANDS); + } + while (mpfr_cmp_ui (u, 0) == 0); + { + py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - 1)); + mpfr_set_prec (y, py); + pz = (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u) + : MPFR_EXP(u) - MPFR_EXP(x); + /* x + u is exactly representable with precision + abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */ + pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)) + 1; + mpfr_set_prec (z, pz); + rnd = RND_RAND (); + if (test_add (z, x, u, rnd)) + { + printf ("z <- x + u should be exact\n"); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("u="); mpfr_print_binary (u); puts (""); + printf ("z="); mpfr_print_binary (z); puts (""); + exit (1); + } + { + rnd = RND_RAND (); + inexact = test_add (y, x, u, rnd); + cmp = mpfr_cmp (y, z); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong inexact flag for rnd=%s\n", + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("u="); mpfr_print_binary (u); puts (""); + printf ("y= "); mpfr_print_binary (y); puts (""); + printf ("x+u="); mpfr_print_binary (z); puts (""); + exit (1); + } + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); +} + +static void +check_nans (void) +{ + mpfr_t s, x, y; + + mpfr_init2 (x, 8L); + mpfr_init2 (y, 8L); + mpfr_init2 (s, 8L); + + /* +inf + -inf == nan */ + mpfr_set_inf (x, 1); + mpfr_set_inf (y, -1); + test_add (s, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (s)); + + /* +inf + 1 == +inf */ + mpfr_set_inf (x, 1); + mpfr_set_ui (y, 1L, MPFR_RNDN); + test_add (s, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (s)); + MPFR_ASSERTN (mpfr_sgn (s) > 0); + + /* -inf + 1 == -inf */ + mpfr_set_inf (x, -1); + mpfr_set_ui (y, 1L, MPFR_RNDN); + test_add (s, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (s)); + MPFR_ASSERTN (mpfr_sgn (s) < 0); + + /* 1 + +inf == +inf */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_inf (y, 1); + test_add (s, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (s)); + MPFR_ASSERTN (mpfr_sgn (s) > 0); + + /* 1 + -inf == -inf */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_inf (y, -1); + test_add (s, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (s)); + MPFR_ASSERTN (mpfr_sgn (s) < 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (s); +} + +static void +check_alloc (void) +{ + mpfr_t a; + + mpfr_init2 (a, 10000); + mpfr_set_prec (a, 53); + mpfr_set_ui (a, 15236, MPFR_RNDN); + test_add (a, a, a, MPFR_RNDN); + mpfr_mul (a, a, a, MPFR_RNDN); + mpfr_div (a, a, a, MPFR_RNDN); + mpfr_sub (a, a, a, MPFR_RNDN); + mpfr_clear (a); +} + +static void +check_overflow (void) +{ + mpfr_t a, b, c; + mpfr_prec_t prec_a; + int r; + + mpfr_init2 (a, 256); + mpfr_init2 (b, 256); + mpfr_init2 (c, 256); + + mpfr_set_ui (b, 1, MPFR_RNDN); + mpfr_setmax (b, mpfr_get_emax ()); + mpfr_set_ui (c, 1, MPFR_RNDN); + mpfr_set_exp (c, mpfr_get_emax () - 192); + RND_LOOP(r) + for (prec_a = 128; prec_a < 512; prec_a += 64) + { + mpfr_set_prec (a, prec_a); + mpfr_clear_overflow (); + test_add (a, b, c, (mpfr_rnd_t) r); + if (!mpfr_overflow_p ()) + { + printf ("No overflow in check_overflow\n"); + exit (1); + } + } + + mpfr_set_exp (c, mpfr_get_emax () - 512); + mpfr_set_prec (a, 256); + mpfr_clear_overflow (); + test_add (a, b, c, MPFR_RNDU); + if (!mpfr_overflow_p ()) + { + printf ("No overflow in check_overflow\n"); + exit (1); + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); +} + +static void +check_1111 (void) +{ + mpfr_t one; + long n; + + mpfr_init2 (one, MPFR_PREC_MIN); + mpfr_set_ui (one, 1, MPFR_RNDN); + for (n = 0; n < N; n++) + { + mpfr_prec_t prec_a, prec_b, prec_c; + mpfr_exp_t tb=0, tc, diff; + mpfr_t a, b, c, s; + int m = 512; + int sb, sc; + int inex_a, inex_s; + mpfr_rnd_t rnd_mode; + + prec_a = MPFR_PREC_MIN + (randlimb () % m); + prec_b = MPFR_PREC_MIN + (randlimb () % m); + prec_c = MPFR_PREC_MIN + (randlimb () % m); + mpfr_init2 (a, prec_a); + mpfr_init2 (b, prec_b); + mpfr_init2 (c, prec_c); + sb = randlimb () % 3; + if (sb != 0) + { + tb = 1 + (randlimb () % (prec_b - (sb != 2))); + mpfr_div_2ui (b, one, tb, MPFR_RNDN); + if (sb == 2) + mpfr_neg (b, b, MPFR_RNDN); + test_add (b, b, one, MPFR_RNDN); + } + else + mpfr_set (b, one, MPFR_RNDN); + tc = 1 + (randlimb () % (prec_c - 1)); + mpfr_div_2ui (c, one, tc, MPFR_RNDN); + sc = randlimb () % 2; + if (sc) + mpfr_neg (c, c, MPFR_RNDN); + test_add (c, c, one, MPFR_RNDN); + diff = (randlimb () % (2*m)) - m; + mpfr_mul_2si (c, c, diff, MPFR_RNDN); + rnd_mode = RND_RAND (); + inex_a = test_add (a, b, c, rnd_mode); + mpfr_init2 (s, MPFR_PREC_MIN + 2*m); + inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */ + if (inex_s) + { + printf ("check_1111: result should have been exact.\n"); + exit (1); + } + inex_s = mpfr_prec_round (s, prec_a, rnd_mode); + if ((inex_a < 0 && inex_s >= 0) || + (inex_a == 0 && inex_s != 0) || + (inex_a > 0 && inex_s <= 0) || + !mpfr_equal_p (a, s)) + { + printf ("check_1111: results are different.\n"); + printf ("prec_a = %d, prec_b = %d, prec_c = %d\n", + (int) prec_a, (int) prec_b, (int) prec_c); + printf ("tb = %d, tc = %d, diff = %d, rnd = %s\n", + (int) tb, (int) tc, (int) diff, + mpfr_print_rnd_mode (rnd_mode)); + printf ("sb = %d, sc = %d\n", sb, sc); + printf ("a = "); mpfr_print_binary (a); puts (""); + printf ("s = "); mpfr_print_binary (s); puts (""); + printf ("inex_a = %d, inex_s = %d\n", inex_a, inex_s); + exit (1); + } + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpfr_clear (s); + } + mpfr_clear (one); +} + +static void +check_1minuseps (void) +{ + static mpfr_prec_t prec_a[] = { + MPFR_PREC_MIN, 30, 31, 32, 33, 62, 63, 64, 65, 126, 127, 128, 129 + }; + static int supp_b[] = { + 0, 1, 2, 3, 4, 29, 30, 31, 32, 33, 34, 35, 61, 62, 63, 64, 65, 66, 67 + }; + mpfr_t a, b, c; + unsigned int ia, ib, ic; + + mpfr_init2 (c, MPFR_PREC_MIN); + + for (ia = 0; ia < numberof (prec_a); ia++) + for (ib = 0; ib < numberof(supp_b); ib++) + { + mpfr_prec_t prec_b; + int rnd_mode; + + prec_b = prec_a[ia] + supp_b[ib]; + + mpfr_init2 (a, prec_a[ia]); + mpfr_init2 (b, prec_b); + + mpfr_set_ui (c, 1, MPFR_RNDN); + mpfr_div_ui (b, c, prec_a[ia], MPFR_RNDN); + mpfr_sub (b, c, b, MPFR_RNDN); /* b = 1 - 2^(-prec_a) */ + + for (ic = 0; ic < numberof(supp_b); ic++) + for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++) + { + mpfr_t s; + int inex_a, inex_s; + + mpfr_set_ui (c, 1, MPFR_RNDN); + mpfr_div_ui (c, c, prec_a[ia] + supp_b[ic], MPFR_RNDN); + inex_a = test_add (a, b, c, (mpfr_rnd_t) rnd_mode); + mpfr_init2 (s, 256); + inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */ + if (inex_s) + { + printf ("check_1minuseps: result should have been exact " + "(ia = %u, ib = %u, ic = %u)\n", ia, ib, ic); + exit (1); + } + inex_s = mpfr_prec_round (s, prec_a[ia], (mpfr_rnd_t) rnd_mode); + if ((inex_a < 0 && inex_s >= 0) || + (inex_a == 0 && inex_s != 0) || + (inex_a > 0 && inex_s <= 0) || + !mpfr_equal_p (a, s)) + { + printf ("check_1minuseps: results are different.\n"); + printf ("ia = %u, ib = %u, ic = %u\n", ia, ib, ic); + exit (1); + } + mpfr_clear (s); + } + + mpfr_clear (a); + mpfr_clear (b); + } + + mpfr_clear (c); +} + +/* Test case bk == 0 in add1.c (b has entirely been read and + c hasn't been taken into account). */ +static void +coverage_bk_eq_0 (void) +{ + mpfr_t a, b, c; + int inex; + + mpfr_init2 (a, GMP_NUMB_BITS); + mpfr_init2 (b, 2 * GMP_NUMB_BITS); + mpfr_init2 (c, GMP_NUMB_BITS); + + mpfr_set_ui_2exp (b, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN); + mpfr_sub_ui (b, b, 1, MPFR_RNDN); + /* b = 111...111 (in base 2) where the 1's fit 2 whole limbs */ + + mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN); /* c = 1/2 */ + + inex = mpfr_add (a, b, c, MPFR_RNDU); + mpfr_set_ui_2exp (c, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN); + if (! mpfr_equal_p (a, c)) + { + printf ("Error in coverage_bk_eq_0\n"); + printf ("Expected "); + mpfr_dump (c); + printf ("Got "); + mpfr_dump (a); + exit (1); + } + MPFR_ASSERTN (inex > 0); + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); +} + +static void +tests (void) +{ + check_alloc (); + check_nans (); + check_inexact (); + check_case_1b (); + check_case_2 (); + check64(); + coverage_bk_eq_0 (); + + check("293607738.0", "1.9967571564050541e-5", MPFR_RNDU, 64, 53, 53, + "2.9360773800002003e8"); + check("880524.0", "-2.0769715792901673e-5", MPFR_RNDN, 64, 53, 53, + "8.8052399997923023e5"); + check("1196426492.0", "-1.4218093058435347e-3", MPFR_RNDN, 64, 53, 53, + "1.1964264919985781e9"); + check("982013018.0", "-8.941829477291838e-7", MPFR_RNDN, 64, 53, 53, + "9.8201301799999905e8"); + check("1092583421.0", "1.0880649218158844e9", MPFR_RNDN, 64, 53, 53, + "2.1806483428158846e9"); + check("1.8476886419022969e-6", "961494401.0", MPFR_RNDN, 53, 64, 53, + "9.6149440100000179e8"); + check("-2.3222118418069868e5", "1229318102.0", MPFR_RNDN, 53, 64, 53, + "1.2290858808158193e9"); + check("-3.0399171300395734e-6", "874924868.0", MPFR_RNDN, 53, 64, 53, + "8.749248679999969e8"); + check("9.064246624706179e1", "663787413.0", MPFR_RNDN, 53, 64, 53, + "6.6378750364246619e8"); + check("-1.0954322421551264e2", "281806592.0", MPFR_RNDD, 53, 64, 53, + "2.8180648245677572e8"); + check("5.9836930386056659e-8", "1016217213.0", MPFR_RNDN, 53, 64, 53, + "1.0162172130000001e9"); + check("-1.2772161928500301e-7", "1237734238.0", MPFR_RNDN, 53, 64, 53, + "1.2377342379999998e9"); + check("-4.567291988483277e8", "1262857194.0", MPFR_RNDN, 53, 64, 53, + "8.0612799515167236e8"); + check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 53, 53, + "2.4380935175292528e8"); + check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 64, 53, + "2.4380935175292528e8"); + check("-1.716113812768534e-140", "1271212614.0", MPFR_RNDZ, 53, 64, 53, + "1.2712126139999998e9"); + check("-1.2927455200185474e-50", "1675676122.0", MPFR_RNDD, 53, 64, 53, + "1.6756761219999998e9"); + + check53("1.22191250737771397120e+20", "948002822.0", MPFR_RNDN, + "122191250738719408128.0"); + check53("9966027674114492.0", "1780341389094537.0", MPFR_RNDN, + "11746369063209028.0"); + check53("2.99280481918991653800e+272", "5.34637717585790933424e+271", + MPFR_RNDN, "3.5274425367757071711e272"); + check_same(); + check53("6.14384195492641560499e-02", "-6.14384195401037683237e-02", + MPFR_RNDU, "9.1603877261370314499e-12"); + check53("1.16809465359248765399e+196", "7.92883212101990665259e+196", + MPFR_RNDU, "9.0969267746123943065e196"); + check53("3.14553393112021279444e-67", "3.14553401015952024126e-67", MPFR_RNDU, + "6.2910679412797336946e-67"); + + check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDN, + "5.4388530464436950905e185"); + check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDZ, + "5.4388530464436944867e185"); + check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDU, + "5.4388530464436950905e185"); + check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDD, + "5.4388530464436944867e185"); + + check2b("1.001010101110011000000010100101110010111001010000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e358",187, + "-1.11100111001101100010001111111110101101110001000000000000000000000000000000000000000000e160",87, + "1.001010101110011000000010100101110010111001010000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e358",178, + MPFR_RNDD); + check2b("-1.111100100011100111010101010101001010100100000111001000000000000000000e481",70, + "1.1111000110100011110101111110110010010000000110101000000000000000e481",65, + "-1.001010111111101011010000001100011101100101000000000000000000e472",61, + MPFR_RNDD); + check2b("1.0100010111010000100101000000111110011100011001011010000000000000000000000000000000e516",83, + "-1.1001111000100001011100000001001100110011110010111111000000e541",59, + "-1.1001111000100001011011110111000001001011100000011110100000110001110011010011000000000000000000000000000000000000000000000000e541",125, + MPFR_RNDZ); + check2b("-1.0010111100000100110001011011010000000011000111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",155, + "-1.00111110100011e239",15, + "-1.00101111000001001100101010101110001100110001111010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",159, + MPFR_RNDD); + check2b("-1.110111000011111011000000001001111101101001010100111000000000000000000000000e880",76, + "-1.1010010e-634",8, + "-1.11011100001111101100000000100111110110100101010011100000000000000000000000e880",75, + MPFR_RNDZ); + check2b("1.00100100110110101001010010101111000001011100100101010000000000000000000000000000e-530",81, + "-1.101101111100000111000011001010110011001011101001110100000e-908",58, + "1.00100100110110101001010010101111000001011100100101010e-530",54, + MPFR_RNDN); + check2b("1.0101100010010111101000000001000010010010011000111011000000000000000000000000000000000000000000000000000000000000000000e374",119, + "1.11100101100101e358",15, + "1.01011000100110011000010110100100100100100110001110110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e374",150, + MPFR_RNDZ); + check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117, + "1.111011100000101010110000100100110100100001001000011100000000e-173",61, + "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68, + MPFR_RNDZ); + check2b("-1.011110000111101011100001100110100011100101000011011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-189",175, + "1.1e631",2, + "1.011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e631",115, + MPFR_RNDZ); + check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94, + "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66, + "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111, + MPFR_RNDU); + check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94, + "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66, + "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111, + MPFR_RNDD); + check2b("-1.1001000011101000110000111110010100100101110101111100000000000000000000000000000000000000000000000000000000e-72",107, + "-1.001100011101100100010101101010101011010010111111010000000000000000000000000000e521",79, + "-1.00110001110110010001010110101010101101001011111101000000000000000000000000000000000000000000000001e521",99, + MPFR_RNDD); + check2b("-1.01010001111000000101010100100100110101011011100001110000000000e498",63, + "1.010000011010101111000100111100011100010101011110010100000000000e243",64, + "-1.010100011110000001010101001001001101010110111000011100000000000e498",64, + MPFR_RNDN); + check2b("1.00101100010101000011010000011000111111011110010111000000000000000000000000000000000000000000000000000000000e178",108, + "-1.10101101010101000110011011111001001101111111110000100000000e160",60, + "1.00101100010100111100100011000011111001000010011101110010000000001111100000000000000000000000000000000000e178",105, + MPFR_RNDN); + check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99, + "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67, + "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94, + MPFR_RNDU); + check2b("-1.100000111100101001100111011100011011000001101001111100000000000000000000000000e843",79, + "-1.1101101010110000001001000100001100110011000110110111000000000000000000000000000000000000000000e414",95, + "-1.1000001111001010011001110111000110110000011010100000e843",53, + MPFR_RNDD); + check2b("-1.110110010110100010100011000110111001010000010111110000000000e-415",61, + "-1.0000100101100001111100110011111111110100011101101011000000000000000000e751",71, + "-1.00001001011000011111001100111111111101000111011010110e751",54, + MPFR_RNDN); + check2b("-1.1011011011110001001101010101001000010100010110111101000000000000000000000e258",74, + "-1.00011100010110110101001011000100100000100010101000010000000000000000000000000000000000000000000000e268",99, + "-1.0001110011001001000011110001000111010110101011110010011011110100000000000000000000000000000000000000e268",101, + MPFR_RNDD); + check2b("-1.1011101010011101011000000100100110101101101110000001000000000e629",62, + "1.111111100000011100100011100000011101100110111110111000000000000000000000000000000000000000000e525",94, + "-1.101110101001110101100000010010011010110110111000000011111111111111111111111111111111111111111111111111101e629",106, + MPFR_RNDD); + check2b("1.111001000010001100010000001100000110001011110111011000000000000000000000000000000000000e152",88, + "1.111110111001100100000100111111010111000100111111001000000000000000e152",67, + "1.1110111111011110000010101001011011101010000110110100e153",53, + MPFR_RNDN); + check2b("1.000001100011110010110000110100001010101101111011110100e696",55, + "-1.1011001111011100100001011110100101010101110111010101000000000000000000000000000000000000000000000000000000000000e730",113, + "-1.1011001111011100100001011110100100010100010011100010e730",53, + MPFR_RNDN); + check2b("-1.11010111100001001111000001110101010010001111111001100000000000000000000000000000000000000000000000000000000000e530",111, + "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000e530",99, + "-1.1000110011110011101010101101111101010011011111000000000000000e528",62, + MPFR_RNDD); + check2b("-1.0001100010010100111101101011101000100100010011100011000000000000000000000000000000000000000000000000000000000e733",110, + "-1.001000000111110010100101010100110111001111011011001000000000000000000000000000000000000000000000000000000000e710",109, + "-1.000110001001010011111000111110110001110110011000110110e733",55, + MPFR_RNDN); + check2b("-1.1101011110000100111100000111010101001000111111100110000000000000000000000e530",74, + "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000000000000000e530",111, + "-1.10001100111100111010101011011111010100110111110000000000000000000000000000e528",75, + MPFR_RNDU); + check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99, + "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67, + "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94, + MPFR_RNDU); + check2b("-1.100101111110110000000110111111011010011101101111100100000000000000e-624",67, + "1.10111010101110100000010110101000000000010011100000100000000e-587",60, + "1.1011101010111010000001011010011111110100011110001011111111001000000100101100010010000011100000000000000000000e-587",110, + MPFR_RNDU); + check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117, + "1.111011100000101010110000100100110100100001001000011100000000e-173",61, + "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68, + MPFR_RNDZ); + check2b("1.1000111000110010101001010011010011101100010110001001000000000000000000000000000000000000000000000000e167",101, + "1.0011110010000110000000101100100111000001110110110000000000000000000000000e167",74, + "1.01100101010111000101001111111111010101110001100111001000000000000000000000000000000000000000000000000000e168",105, + MPFR_RNDZ); + check2b("1.100101111111110010100101110111100001110000100001010000000000000000000000000000000000000000000000e808",97, + "-1.1110011001100000100000111111110000110010100111001011000000000000000000000000000000e807",83, + "1.01001001100110001100011111000000000001011010010111010000000000000000000000000000000000000000000e807",96, + MPFR_RNDN); + check2b("1e128",128, + "1e0",128, + "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e0",256, + MPFR_RNDN); + + /* Checking double precision (53 bits) */ + check53("-8.22183238641455905806e-19", "7.42227178769761587878e-19",MPFR_RNDD, + "-7.9956059871694317927e-20"); + check53("5.82106394662028628236e+234","-5.21514064202368477230e+89",MPFR_RNDD, + "5.8210639466202855763e234"); + check53("5.72931679569871602371e+122","-5.72886070363264321230e+122", + MPFR_RNDN, "4.5609206607281141508e118"); + check53("-5.09937369394650450820e+238", "2.70203299854862982387e+250", + MPFR_RNDD, "2.7020329985435301323e250"); + check53("-2.96695924472363684394e+27", "1.22842938251111500000e+16",MPFR_RNDD, + "-2.96695924471135255027e27"); + check53("1.74693641655743793422e-227", "-7.71776956366861843469e-229", + MPFR_RNDN, "1.669758720920751867e-227"); + /* x = -7883040437021647.0; for (i=0; i<468; i++) x = x / 2.0;*/ + check53("-1.03432206392780011159e-125", "1.30127034799251347548e-133", + MPFR_RNDN, + "-1.0343220509150965661100887242027378881805094180354e-125"); + check53("1.05824655795525779205e+71", "-1.06022698059744327881e+71",MPFR_RNDZ, + "-1.9804226421854867632e68"); + check53("-5.84204911040921732219e+240", "7.26658169050749590763e+240", + MPFR_RNDD, "1.4245325800982785854e240"); + check53("1.00944884131046636376e+221","2.33809162651471520268e+215",MPFR_RNDN, + "1.0094511794020929787e221"); + /*x = 7045852550057985.0; for (i=0; i<986; i++) x = x / 2.0;*/ + check53("4.29232078932667367325e-278", + "1.0773525047389793833221116707010783793203080117586e-281" + , MPFR_RNDU, "4.2933981418314132787e-278"); + check53("5.27584773801377058681e-80", "8.91207657803547196421e-91", MPFR_RNDN, + "5.2758477381028917269e-80"); + check53("2.99280481918991653800e+272", "5.34637717585790933424e+271", + MPFR_RNDN, "3.5274425367757071711e272"); + check53("4.67302514390488041733e-184", "2.18321376145645689945e-190", + MPFR_RNDN, "4.6730273271186420541e-184"); + check53("5.57294120336300389254e+71", "2.60596167942024924040e+65", MPFR_RNDZ, + "5.5729438093246831053e71"); + check53("6.6052588496951015469e24", "4938448004894539.0", MPFR_RNDU, + "6.6052588546335505068e24"); + check53("1.23056185051606761523e-190", "1.64589756643433857138e-181", + MPFR_RNDU, "1.6458975676649006598e-181"); + check53("2.93231171510175981584e-280", "3.26266919161341483877e-273", + MPFR_RNDU, "3.2626694848445867288e-273"); + check53("5.76707395945001907217e-58", "4.74752971449827687074e-51", MPFR_RNDD, + "4.747530291205672325e-51"); + check53("277363943109.0", "11.0", MPFR_RNDN, "277363943120.0"); + check53("1.44791789689198883921e-140", "-1.90982880222349071284e-121", + MPFR_RNDN, "-1.90982880222349071e-121"); + + + /* tests for particular cases (Vincent Lefevre, 22 Aug 2001) */ + check53("9007199254740992.0", "1.0", MPFR_RNDN, "9007199254740992.0"); + check53("9007199254740994.0", "1.0", MPFR_RNDN, "9007199254740996.0"); + check53("9007199254740992.0", "-1.0", MPFR_RNDN, "9007199254740991.0"); + check53("9007199254740994.0", "-1.0", MPFR_RNDN, "9007199254740992.0"); + check53("9007199254740996.0", "-1.0", MPFR_RNDN, "9007199254740996.0"); + + check_overflow (); + check_1111 (); + check_1minuseps (); +} + +#define TEST_FUNCTION test_add +#define TWO_ARGS +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + usesp = 0; + tests (); + +#ifndef CHECK_EXTERNAL /* no need to check twice */ + usesp = 1; + tests (); +#endif + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tadd1sp.c b/mpfr/tests/tadd1sp.c new file mode 100644 index 0000000000..1a332e231f --- /dev/null +++ b/mpfr/tests/tadd1sp.c @@ -0,0 +1,189 @@ +/* Test file for mpfr_add1sp. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void check_special (void); +static void check_random (mpfr_prec_t p); + +static void +check_overflow (void) +{ + mpfr_t x, y, z1, z2; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-1021); + set_emax (1024); + + mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0); + + mpfr_set_str1 (x, "8.00468257869324898448e+307"); + mpfr_set_str1 (y, "7.44784712422708645156e+307"); + mpfr_add1sp (z1, x, y, MPFR_RNDN); + mpfr_add1 (z2, x, y, MPFR_RNDN); + if (mpfr_cmp (z1, z2)) + { + printf ("Overflow bug in add1sp.\n"); + exit (1); + } + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +int +main (void) +{ + mpfr_prec_t p; + + tests_start_mpfr (); + + check_special (); + for(p = 2 ; p < 200 ; p++) + check_random (p); + check_overflow (); + + tests_end_mpfr (); + return 0; +} + +#define STD_ERROR \ + do \ + { \ + printf("ERROR: for %s and p=%lu and i=%d:\nB=", \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \ + mpfr_print_binary(b); \ + printf("\nC="); mpfr_print_binary(c); \ + printf("\nadd1 : "); mpfr_print_binary(a1); \ + printf("\nadd1sp: "); mpfr_print_binary(a2); \ + putchar('\n'); \ + exit(1); \ + } \ + while (0) + +#define STD_ERROR2 \ + do \ + { \ + printf("ERROR: Wrong inexact flag for %s and p=%lu and i=%d:\nB=", \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \ + mpfr_print_binary(b); \ + printf("\nC="); mpfr_print_binary(c); \ + printf("\nA="); mpfr_print_binary(a1); \ + printf("\nAdd1: %d. Add1sp: %d\n", \ + inexact1, inexact2); \ + exit(1); \ + } \ + while (0) + +#define SET_PREC(_p) \ + { \ + p = _p; \ + mpfr_set_prec(a1, _p); mpfr_set_prec(a2, _p); \ + mpfr_set_prec(b, _p); mpfr_set_prec(c, _p); \ + } + +static void +check_random (mpfr_prec_t p) +{ + mpfr_t a1,b,c,a2; + int r; + int i, inexact1, inexact2; + + mpfr_inits2 (p, a1, b, c, a2, (mpfr_ptr) 0); + + for (i = 0 ; i < 500 ; i++) + { + mpfr_urandomb (b, RANDS); + mpfr_urandomb (c, RANDS); + if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c)) + { + if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c)) + mpfr_swap(b, c); + if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c)) + for (r = 0 ; r < MPFR_RND_MAX ; r++) + { + inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r); + inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r); + if (mpfr_cmp(a1, a2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + } + } + } + + mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0); +} + +static void +check_special (void) +{ + mpfr_t a1,a2,b,c; + int r; + mpfr_prec_t p; + int i = -1, inexact1, inexact2; + + mpfr_inits (a1, a2, b, c, (mpfr_ptr) 0); + + for (r = 0 ; r < MPFR_RND_MAX ; r++) + { + SET_PREC(53); + mpfr_set_str1 (b, "1@100"); + mpfr_set_str1 (c, "1@1"); + inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r); + inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r); + if (mpfr_cmp(a1, a2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + mpfr_set_str_binary (b, "1E53"); + mpfr_set_str_binary (c, "1E0"); + inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r); + inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r); + if (mpfr_cmp(a1, a2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + } + + mpfr_set_prec (c, 2); + mpfr_set_prec (a1, 2); + mpfr_set_prec (a2, 2); + mpfr_set_str_binary (c, "1.0e1"); + mpfr_set_str_binary (a2, "1.1e-1"); + mpfr_set_str_binary (a1, "0.11E2"); + mpfr_add1sp (a2, c, a2, MPFR_RNDN); + if (mpfr_cmp (a1, a2)) + { + printf ("Regression reuse test failed!\n"); + exit (1); + } + + mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0); +} diff --git a/mpfr/tests/tadd_d.c b/mpfr/tests/tadd_d.c new file mode 100644 index 0000000000..5042cf121b --- /dev/null +++ b/mpfr/tests/tadd_d.c @@ -0,0 +1,161 @@ +/* Test file for mpfr_add_d + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check_regulars (void) +{ + mpfr_t x, y, z; + double d; + int inexact; + + /* (1) check with enough precision */ + mpfr_init2 (x, IEEE_DBL_MANT_DIG); + mpfr_init2 (y, IEEE_DBL_MANT_DIG); + mpfr_init2 (z, IEEE_DBL_MANT_DIG); + + mpfr_set_str (y, "4096", 10, MPFR_RNDN); + d = 0.125; + mpfr_clear_flags (); + inexact = mpfr_add_d (x, y, d, MPFR_RNDN); + if (inexact != 0) + { + printf ("Inexact flag error in mpfr_add_d (1)\n"); + exit (1); + } + mpfr_set_str (z, "4096.125", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_add_d ("); + mpfr_out_str (stdout, 10, 7, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + /* (2) check inexact flag */ + mpfr_set_prec (x, 2); + mpfr_set_prec (z, 2); + + mpfr_clear_flags (); + inexact = mpfr_add_d (x, y, d, MPFR_RNDN); + if (inexact == 0) + { + printf ("Inexact flag error in mpfr_add_d (2)\n"); + exit (1); + } + mpfr_set_str (z, "4096.125", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_add_d ("); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static void +check_nans (void) +{ +#if !defined(MPFR_ERRDIVZERO) + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + /* nan + 1.0 is nan */ + mpfr_set_nan (x); + mpfr_clear_flags (); + inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf + 1.0 == +inf */ + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* -inf + 1.0 == -inf */ + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + mpfr_clear (x); + mpfr_clear (y); +#endif +} + +#define TEST_FUNCTION mpfr_add_d +#define DOUBLE_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + tests_start_mpfr (); + + check_nans (); + check_regulars (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tadd_ui.c b/mpfr/tests/tadd_ui.c new file mode 100644 index 0000000000..422629fee2 --- /dev/null +++ b/mpfr/tests/tadd_ui.c @@ -0,0 +1,117 @@ +/* Test file for mpfr_add_ui + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +/* checks that x+y gives the right results with 53 bits of precision */ +static void +check3 (const char *xs, unsigned long y, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, zz; + + mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_add_ui (zz, xx, y, rnd_mode); + if (mpfr_cmp_str1(zz, zs) ) + { + printf ("expected sum is %s, got ",zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + printf ("\nmpfr_add_ui failed for x=%s y=%lu with rnd_mode=%s\n", + xs, y, mpfr_print_rnd_mode(rnd_mode)); + exit (1); + } + mpfr_clears (xx, zz, (mpfr_ptr) 0); +} + +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 63); + mpfr_init2 (y, 63); + mpfr_set_str_binary (x, "0.110100000000000001110001110010111111000000000101100011100100011"); + mpfr_add_ui (y, x, 1, MPFR_RNDD); + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_nans (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + /* nan + 2394875 == nan */ + mpfr_set_nan (x); + mpfr_add_ui (y, x, 2394875L, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf + 2394875 == +inf */ + mpfr_set_inf (x, 1); + mpfr_add_ui (y, x, 2394875L, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) > 0); + + /* -inf + 2394875 == -inf */ + mpfr_set_inf (x, -1); + mpfr_add_ui (y, x, 2394875L, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) < 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_add_ui +#define ULONG_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_nans (); + + special (); + check3 ("-1.716113812768534e-140", 1271212614, MPFR_RNDZ, + "1.27121261399999976e9"); + check3 ("1.22191250737771397120e+20", 948002822, MPFR_RNDN, + "122191250738719408128.0"); + check3 ("-6.72658901114033715233e-165", 2000878121, MPFR_RNDZ, + "2.0008781209999997615e9"); + check3 ("-2.0769715792901673e-5", 880524, MPFR_RNDN, + "8.8052399997923023e5"); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tagm.c b/mpfr/tests/tagm.c new file mode 100644 index 0000000000..81eb81894c --- /dev/null +++ b/mpfr/tests/tagm.c @@ -0,0 +1,317 @@ +/* Test file for mpfr_agm. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define check(a,b,r) check4(a,b,r,0.0) + +static void +check4 (const char *as, const char *bs, mpfr_rnd_t rnd_mode, + const char *res, int inex) +{ + mpfr_t ta, tb, tc, tres; + mpfr_exp_t emin, emax; + int i; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_inits2 (53, ta, tb, tc, tres, (mpfr_ptr) 0); + + for (i = 0; i <= 2; i++) + { + unsigned int expflags, newflags; + int inex2; + + mpfr_set_str1 (ta, as); + mpfr_set_str1 (tb, bs); + mpfr_set_str1 (tc, res); + + if (i > 0) + { + mpfr_exp_t ea, eb, ec, e0; + + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + ea = mpfr_get_exp (ta); + eb = mpfr_get_exp (tb); + ec = mpfr_get_exp (tc); + + e0 = i == 1 ? __gmpfr_emin : __gmpfr_emax; + if ((i == 1 && ea < eb) || (i == 2 && ea > eb)) + { + mpfr_set_exp (ta, e0); + mpfr_set_exp (tb, e0 + (eb - ea)); + mpfr_set_exp (tc, e0 + (ec - ea)); + } + else + { + mpfr_set_exp (ta, e0 + (ea - eb)); + mpfr_set_exp (tb, e0); + mpfr_set_exp (tc, e0 + (ec - eb)); + } + } + + __gmpfr_flags = expflags = + (randlimb () & 1) ? MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE : 0; + inex2 = mpfr_agm (tres, ta, tb, rnd_mode); + newflags = __gmpfr_flags; + expflags |= MPFR_FLAGS_INEXACT; + + if (SIGN (inex2) != inex || newflags != expflags || + ! mpfr_equal_p (tres, tc)) + { + printf ("mpfr_agm failed in rnd_mode=%s for\n", + mpfr_print_rnd_mode (rnd_mode)); + printf (" a = "); + mpfr_out_str (stdout, 10, 0, ta, MPFR_RNDN); + printf ("\n"); + printf (" b = "); + mpfr_out_str (stdout, 10, 0, tb, MPFR_RNDN); + printf ("\n"); + printf ("expected inex = %d, flags = %u,\n" + " ", inex, expflags); + mpfr_dump (tc); + printf ("got inex = %d, flags = %u,\n" + " ", inex2, newflags); + mpfr_dump (tres); + exit (1); + } + + set_emin (emin); + set_emax (emax); + } + + mpfr_clears (ta, tb, tc, tres, (mpfr_ptr) 0); +} + +static void +check_large (void) +{ + mpfr_t a, b, agm; + int inex; + + mpfr_init2 (a, 82); + mpfr_init2 (b, 82); + mpfr_init2 (agm, 82); + + mpfr_set_ui (a, 1, MPFR_RNDN); + mpfr_set_str_binary (b, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010E-39"); + mpfr_agm (agm, a, b, MPFR_RNDN); + mpfr_set_str_binary (a, "0.1110001000111101101010101010101101001010001001001011100101111011110101111001111100E-4"); + if (mpfr_cmp (agm, a)) + { + printf ("mpfr_agm failed for precision 82\n"); + exit (1); + } + + /* problem found by Damien Fischer <damien@maths.usyd.edu.au> 4 Aug 2003: + produced a divide-by-zero exception */ + mpfr_set_prec (a, 268); + mpfr_set_prec (b, 268); + mpfr_set_prec (agm, 268); + mpfr_set_str (a, "703.93543315330225238487276503953366664991725089988315253092140138947103394917006", 10, MPFR_RNDN); + mpfr_set_str (b, "703.93543315330225238487279020523738740563816490895994499256063816906728642622316", 10, MPFR_RNDN); + mpfr_agm (agm, a, b, MPFR_RNDN); + + mpfr_set_prec (a, 18); + mpfr_set_prec (b, 70); + mpfr_set_prec (agm, 67); + mpfr_set_str_binary (a, "0.111001111100101000e8"); + mpfr_set_str_binary (b, "0.1101110111100100010100110000010111011011011100110100111001010100100001e10"); + inex = mpfr_agm (agm, a, b, MPFR_RNDN); + mpfr_set_str_binary (b, "0.1111110010011101101100010101011011010010010000001010100011000110011e9"); + if (mpfr_cmp (agm, b)) + { + printf ("Error in mpfr_agm (1)\n"); + exit (1); + } + if (inex >= 0) + { + printf ("Wrong flag for mpfr_agm (1)\n"); + exit (1); + } + + /* test worst case: 9 consecutive ones after the last bit */ + mpfr_set_prec (a, 2); + mpfr_set_prec (b, 2); + mpfr_set_ui (a, 1, MPFR_RNDN); + mpfr_set_ui (b, 2, MPFR_RNDN); + mpfr_set_prec (agm, 904); + mpfr_agm (agm, a, b, MPFR_RNDZ); + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (agm); +} + +static void +check_eq (void) +{ + mpfr_t a, b, agm; + int p; + + mpfr_init2 (a, 17); + mpfr_init2 (b, 9); + + mpfr_set_str_binary (b, "0.101000000E-3"); + mpfr_set (a, b, MPFR_RNDN); + + for (p = MPFR_PREC_MIN; p <= 2; p++) + { + int inex; + + mpfr_init2 (agm, p); + inex = mpfr_agm (agm, a, b, MPFR_RNDU); + if (mpfr_cmp_ui_2exp (agm, 5 - p, -5) != 0) + { + printf ("Error in check_eq for p = %d: expected %d*2^(-5), got ", + p, 5 - p); + mpfr_dump (agm); + exit (1); + } + if (inex <= 0) + { + printf ("Wrong ternary value in check_eq for p = %d\n", p); + printf ("expected 1\n"); + printf ("got %d\n", inex); + exit (1); + } + mpfr_clear (agm); + } + + mpfr_clear (a); + mpfr_clear (b); +} + +static void +check_nans (void) +{ + mpfr_t x, y, m; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + mpfr_init2 (m, 123L); + + /* agm(1,nan) == nan */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_nan (y); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (m)); + + /* agm(1,+inf) == +inf */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_inf (y, 1); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (m)); + MPFR_ASSERTN (mpfr_sgn (m) > 0); + + /* agm(+inf,+inf) == +inf */ + mpfr_set_inf (x, 1); + mpfr_set_inf (y, 1); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (m)); + MPFR_ASSERTN (mpfr_sgn (m) > 0); + + /* agm(-inf,+inf) == nan */ + mpfr_set_inf (x, -1); + mpfr_set_inf (y, 1); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (m)); + + /* agm(+0,+inf) == nan */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_inf (y, 1); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (m)); + + /* agm(+0,1) == +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (m) && MPFR_IS_POS(m)); + + /* agm(-0,1) == +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (m) && MPFR_IS_POS(m)); + + /* agm(-0,+0) == +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (m) && MPFR_IS_POS(m)); + + /* agm(1,1) == 1 */ + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (m ,1) == 0); + + /* agm(-1,-2) == NaN */ + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_set_si (y, -2, MPFR_RNDN); + mpfr_agm (m, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (m)); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (m); +} + +#define TEST_FUNCTION mpfr_agm +#define TWO_ARGS +#define TEST_RANDOM_POS 4 +#define TEST_RANDOM_POS2 4 +#include "tgeneric.c" + +int +main (int argc, char* argv[]) +{ + tests_start_mpfr (); + + check_nans (); + + check_large (); + check_eq (); + check4 ("2.0", "1.0", MPFR_RNDN, "1.456791031046906869", -1); + check4 ("6.0", "4.0", MPFR_RNDN, "4.949360872472608925", 1); + check4 ("62.0", "61.0", MPFR_RNDN, "61.498983718845075902", -1); + check4 ("0.5", "1.0", MPFR_RNDN, "0.72839551552345343459", -1); + check4 ("1.0", "2.0", MPFR_RNDN, "1.456791031046906869", -1); + check4 ("234375765.0", "234375000.0", MPFR_RNDN, "234375382.49984394025", 1); + check4 ("8.0", "1.0", MPFR_RNDU, "3.61575617759736274873", 1); + check4 ("1.0", "44.0", MPFR_RNDU, "13.3658354512981243907", 1); + check4 ("1.0", "3.7252902984619140625e-9", MPFR_RNDU, + "0.07553933569711989657765", 1); + test_generic (2, 300, 17); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tai.c b/mpfr/tests/tai.c new file mode 100644 index 0000000000..3aa3613930 --- /dev/null +++ b/mpfr/tests/tai.c @@ -0,0 +1,109 @@ +/* Test file for mpfr_ai. + +Copyright 2010-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_ai +#define TEST_RANDOM_EMIN -5 +#define TEST_RANDOM_EMAX 5 +#define REDUCE_EMAX 7 /* this is to avoid that test_generic() calls mpfr_ai + with too large inputs. FIXME: remove this once + mpfr_ai can handle large inputs */ +#include "tgeneric.c" + +static void +check_large (void) +{ + mpfr_t x, y, z; + + mpfr_init2 (x, 38); + mpfr_init2 (y, 110); + mpfr_init2 (z, 110); + mpfr_set_str_binary (x, "-1E8"); + mpfr_ai (y, x, MPFR_RNDN); + mpfr_set_str_binary (z, "-10001110100001011111110001100011101100011100010000110100100101011111011100000101110101010010000000101110011111E-112"); + if (mpfr_equal_p (y, z) == 0) + { + printf ("Error in mpfr_ai for x=-2^8\n"); + exit (1); + } +#if 0 /* disabled since mpfr_ai does not currently handle large arguments */ + mpfr_set_str_binary (x, "-1E26"); + mpfr_ai (y, x, MPFR_RNDN); + mpfr_set_str_binary (z, "-110001111100000011001010010101001101001011001011101011001010100100001110001101101101000010000011001000001011E-118"); + if (mpfr_equal_p (y, z) == 0) + { + printf ("Error in mpfr_ai for x=-2^26\n"); + exit (1); + } + mpfr_set_str_binary (x, "-0.11111111111111111111111111111111111111E1073741823"); + mpfr_ai (y, x, MPFR_RNDN); + /* FIXME: compute the correctly rounded value we should get for Ai(x), + and check we get this value */ +#endif + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_zero (void) +{ + mpfr_t x, y, r; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_init2 (r, 53); + + mpfr_set_str_binary (r, "10110101110001100011110010110001001110001010110111E-51"); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_ai (y, x, MPFR_RNDN); + if (mpfr_equal_p (y, r) == 0) + { + printf ("Error in mpfr_ai for x=0\n"); + printf ("Expected "); mpfr_dump (r); + printf ("Got "); mpfr_dump (y); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (r); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_large (); + check_zero (); + + test_generic (2, 100, 5); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tasin.c b/mpfr/tests/tasin.c new file mode 100644 index 0000000000..a83587394a --- /dev/null +++ b/mpfr/tests/tasin.c @@ -0,0 +1,285 @@ +/* Test file for mpfr_asin. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_asin +#define TEST_RANDOM_EMAX 7 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int r; + + mpfr_init (x); + mpfr_init (y); + + /* asin(NaN) = NaN */ + mpfr_set_nan (x); + mpfr_asin (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (NaN) <> NaN\n"); + exit (1); + } + + /* asin(+/-Inf) = NaN */ + mpfr_set_inf (x, 1); + mpfr_asin (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (+Inf) <> NaN\n"); + exit (1); + } + mpfr_set_inf (x, -1); + mpfr_asin (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (-Inf) <> NaN\n"); + exit (1); + } + + /* asin(+/-2) = NaN */ + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_asin (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (+2) <> NaN\n"); + exit (1); + } + mpfr_set_si (x, -2, MPFR_RNDN); + mpfr_asin (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (-2) <> NaN\n"); + exit (1); + } + + /* asin(+/-0) = +/-0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_asin (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_asin (+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_asin (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_asin (-0) <> -0\n"); + exit (1); + } + + /* asin(1) = Pi/2 */ + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_set_ui (x, 1, MPFR_RNDN); /* exact */ + mpfr_asin (y, x, (mpfr_rnd_t) r); + mpfr_const_pi (x, (mpfr_rnd_t) r); + mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */ + if (mpfr_cmp (x, y)) + { + printf ("Error: asin(1) != Pi/2 for rnd=%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + /* asin(-1) = -Pi/2 */ + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_set_si (x, -1, MPFR_RNDN); /* exact */ + mpfr_asin (y, x, (mpfr_rnd_t) r); + mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r)); + mpfr_neg (x, x, MPFR_RNDN); /* exact */ + mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */ + if (mpfr_cmp (x, y)) + { + printf ("Error: asin(-1) != -Pi/2 for rnd=%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1101110111111111001011101000101"); + mpfr_asin (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "1.00001100101011000001111100111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asin (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.01110111000011101010111100000101"); + mpfr_asin (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.0111101111010100011111110101"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asin (2)\n"); + mpfr_print_binary (x); printf ("\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 9); + mpfr_set_prec (y, 19); + mpfr_set_str_binary (x, "0.110000000E-6"); + mpfr_asin (y, x, MPFR_RNDD); + mpfr_set_prec (x, 19); + mpfr_set_str_binary (x, "0.1100000000000001001E-6"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asin (3)\n"); + mpfr_dump (x); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +special_overflow (void) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + mpfr_init2 (x, 24); + mpfr_init2 (y, 48); + mpfr_set_str_binary (x, "0.101100100000000000110100E0"); + mpfr_asin (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.110001001101001111110000010110001000111011001000E0", + 2, MPFR_RNDN)) + { + printf("Special Overflow error.\n"); + mpfr_dump (y); + exit (1); + } + mpfr_clear (y); + mpfr_clear (x); + set_emin (emin); + set_emax (emax); +} + +/* bug reported by Kevin Rauch on 15 December 2007 */ +static void +test20071215 (void) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_asin (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_NEG(y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_si (y, -1, MPFR_RNDN); + mpfr_asin (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_POS(y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +reduced_expo_range (void) +{ + mpfr_exp_t emin, emax; + mpfr_t x, y, ex_y; + int inex, ex_inex; + unsigned int flags, ex_flags; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_inits2 (4, x, y, ex_y, (mpfr_ptr) 0); + mpfr_set_str (x, "-0.1e1", 2, MPFR_RNDN); + + mpfr_set_emin (1); + mpfr_set_emax (1); + mpfr_clear_flags (); + inex = mpfr_asin (y, x, MPFR_RNDA); + flags = __gmpfr_flags; + mpfr_set_emin (emin); + mpfr_set_emax (emax); + + mpfr_set_str (ex_y, "-0.1101e1", 2, MPFR_RNDN); + ex_inex = -1; + ex_flags = MPFR_FLAGS_INEXACT; + + if (SIGN (inex) != ex_inex || flags != ex_flags || + ! mpfr_equal_p (y, ex_y)) + { + printf ("Error in reduced_expo_range\non x = "); + mpfr_dump (x); + printf ("Expected y = "); + mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN); + printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); + printf ("Got y = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); + exit (1); + } + + mpfr_clears (x, y, ex_y, (mpfr_ptr) 0); +} + +int +main (void) +{ + tests_start_mpfr (); + + special (); + special_overflow (); + reduced_expo_range (); + + test_generic (2, 100, 15); + + tests_end_mpfr (); + + data_check ("data/asin", mpfr_asin, "mpfr_asin"); + bad_cases (mpfr_asin, mpfr_sin, "mpfr_asin", 256, -40, 1, 4, 128, 800, 30); + + test20071215 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tasinh.c b/mpfr/tests/tasinh.c new file mode 100644 index 0000000000..e94d02b837 --- /dev/null +++ b/mpfr/tests/tasinh.c @@ -0,0 +1,161 @@ +/* Test file for mpfr_asinh. + +Copyright 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_asinh +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y, z; + + mpfr_init (x); + mpfr_init (y); + + MPFR_SET_INF(x); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_asinh (x, y, MPFR_RNDN); + if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) + { + printf ("Inf flag not clears in asinh!\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_asinh (x, y, MPFR_RNDN); + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) + { + printf ("NAN flag not clears in asinh!\n"); + exit (1); + } + + /* asinh(+0) = +0, asinh(-0) = -0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_asinh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_asinh(+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_asinh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_asinh(-0) <> -0\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_asinh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asinh(NaN) <> NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_asinh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_asinh(+Inf) <> +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_asinh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_asinh(-Inf) <> -Inf\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1"); + mpfr_asinh (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.10100110010010101101010011011101E-1"); + if (!mpfr_equal_p (x, y)) + { + printf ("Error: mpfr_asinh (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-.10110011011010111110010001100001"); + mpfr_asinh (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "-.10100111010000111001011100110011"); + if (!mpfr_equal_p (x, y)) + { + printf ("Error: mpfr_asinh (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 43); + mpfr_set_str_binary (x, "0.111001101100000110011001010000101"); + mpfr_asinh (y, x, MPFR_RNDZ); + mpfr_init2 (z, 43); + mpfr_set_str_binary (z, "0.1100111101010101101010101110000001000111001"); + if (!mpfr_equal_p (y, z)) + { + printf ("Error: mpfr_asinh (3)\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 2); + mpfr_set_str (x, "1.8000000000009@-6", 16, MPFR_RNDN); + mpfr_asinh (y, x, MPFR_RNDZ); + mpfr_set_prec (z, 2); + mpfr_set_str (z, "1.0@-6", 16, MPFR_RNDN); + if (!mpfr_equal_p (y, z)) + { + printf ("Error: mpfr_asinh (4)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 25); + + data_check ("data/asinh", mpfr_asinh, "mpfr_asinh"); + bad_cases (mpfr_asinh, mpfr_sinh, "mpfr_asinh", 256, -128, 29, + 4, 128, 800, 40); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tatan.c b/mpfr/tests/tatan.c new file mode 100644 index 0000000000..403d0126c0 --- /dev/null +++ b/mpfr/tests/tatan.c @@ -0,0 +1,643 @@ +/* Test file for mpfr_atan. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +special (void) +{ + mpfr_t x, y, z; + int r; + int i; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_init2 (z, 53); + + mpfr_set_str_binary (x, "1.0000100110000001100111100011001110101110100111011101"); + mpfr_set_str_binary (y, "1.1001101101110100101100110011011101101000011010111110e-1"); + mpfr_atan (z, x, MPFR_RNDN); + if (mpfr_cmp (y, z)) + { + printf ("Error in mpfr_atan for prec=53, rnd=MPFR_RNDN\n"); + printf ("x="); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\nexpected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + /* atan(+Inf) = Pi/2 */ + for (r = 0; r < MPFR_RND_MAX ; r++) + { + mpfr_set_inf (x, 1); + mpfr_atan (y, x, (mpfr_rnd_t) r); + mpfr_const_pi (x, (mpfr_rnd_t) r); + mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atan(+Inf), rnd=%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + /* atan(-Inf) = - Pi/2 */ + for (r = 0; r < MPFR_RND_MAX ; r++) + { + mpfr_set_inf (x, -1); + mpfr_atan (y, x, (mpfr_rnd_t) r); + mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r)); + mpfr_neg (x, x, (mpfr_rnd_t) r); + mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atan(-Inf), rnd=%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + /* atan(NaN) = NaN */ + mpfr_set_nan (x); + mpfr_atan (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atan(NaN) <> NaN\n"); + exit (1); + } + + /* atan(+/-0) = +/-0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + MPFR_SET_NEG (y); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y)) + { + printf ("Error: mpfr_atan (+0) <> +0\n"); + exit (1); + } + mpfr_atan (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) || MPFR_IS_NEG (x)) + { + printf ("Error: mpfr_atan (+0) <> +0 (in place)\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + MPFR_SET_POS (y); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || MPFR_IS_POS (y)) + { + printf ("Error: mpfr_atan (-0) <> -0\n"); + exit (1); + } + mpfr_atan (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) || MPFR_IS_POS (x)) + { + printf ("Error: mpfr_atan (-0) <> -0 (in place)\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + /* test one random positive argument */ + mpfr_set_str_binary (x, "0.10000100001100101001001001011001"); + mpfr_atan (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_atan (1)\n"); + exit (1); + } + + /* test one random negative argument */ + mpfr_set_str_binary (x, "-0.1100001110110000010101011001011"); + mpfr_atan (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.101001110001010010110001110001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_atan (2)\n"); + mpfr_print_binary (x); printf ("\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 192); + mpfr_set_prec (z, 192); + mpfr_set_str_binary (x, "-0.100e1"); + mpfr_atan (z, x, MPFR_RNDD); + mpfr_set_str_binary (y, "-0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110000011100110100010010100100000010010011100000100010001010011001111100110001110101"); + if (mpfr_cmp (z, y)) + { + printf ("Error in mpfr_atan (3)\n"); + printf ("Expected "); mpfr_print_binary (y); printf ("\n"); + printf ("Got "); mpfr_print_binary (z); printf ("\n"); + exit (1); + } + + /* Test regression */ + mpfr_set_prec (x, 51); + mpfr_set_prec (y, 51); + mpfr_set_str_binary (x, + "0.101100100000101111111010001111111000001000000000000E-11"); + i = mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, + "1.01100100000101111111001110011001010110100100000000e-12", 2, MPFR_RNDN) + || i >= 0) + { + printf ("Wrong Regression test (%d)\n", i); + mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_atan (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_NEG (x)); + + /* Test regression */ + mpfr_set_prec (x, 48); + mpfr_set_prec (y, 48); + mpfr_set_str_binary (x, "1.11001110010000011111100000010000000000000000000e-19"); + mpfr_atan (y, x, MPFR_RNDD); + if (mpfr_cmp_str (y, "0.111001110010000011111100000001111111110000010011E-18", 2, MPFR_RNDN)) + { + printf ("Error in mpfr_atan (4)\n"); + printf ("Input 1.11001110010000011111100000010000000000000000000e-19 [prec=48]\n"); + printf ("Expected 0.111001110010000011111100000001111111110000010011E-18\n"); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +#define TEST_FUNCTION mpfr_atan +#define test_generic test_generic_atan +#define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), mpfr_mul_2si (x, x, (randlimb () %1000-500), MPFR_RNDN)) +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_atan2 +#define TWO_ARGS +#define test_generic test_generic_atan2 +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_atan2 +#define TWO_ARGS +#define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), MPFR_SET_NEG (x)) +#define test_generic test_generic_atan2_neg +#include "tgeneric.c" + +static void +special_overflow (void) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + mpfr_init2 (x, 24); + mpfr_init2 (y, 48); + mpfr_set_str_binary (x, "0.101101010001001101111010E0"); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0", + 2, MPFR_RNDN)) + { + printf("Special Overflow error.\n"); + mpfr_dump (y); + exit (1); + } + + /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */ + set_emax (1); + mpfr_set_inf (x, +1); + mpfr_clear_flags (); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN) + || mpfr_overflow_p ()) + { + printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n", + (long int) mpfr_get_emax ()); + mpfr_dump (y); + exit (1); + } + + /* atan(+Inf) = Pi/2 underflows */ + set_emax (128); + set_emin (3); + mpfr_clear_flags (); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ()) + { + printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n", + (long int) mpfr_get_emin ()); + mpfr_dump (y); + exit (1); + } + + /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */ + set_emax (1); + set_emin (-128); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN) + || mpfr_overflow_p ()) + { + printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n", + (long int) mpfr_get_emax ()); + mpfr_dump (y); + exit (1); + } + + /* atan(+1) = Pi/4 underflows and is rounded up to 1 */ + set_emax (128); + set_emin (1); + mpfr_set_prec (y, 2); + mpfr_clear_flags (); + mpfr_atan (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ()) + { + printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n", + (long int) mpfr_get_emin ()); + mpfr_dump (y); + exit (1); + } + + /* atan(+1) = Pi/4 underflows and is rounded down to 0 */ + mpfr_clear_flags (); + mpfr_atan (y, x, MPFR_RNDD); + if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ()) + { + printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n", + (long int) mpfr_get_emin ()); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); + set_emin (emin); + set_emax (emax); +} + +static void +special_atan2 (void) +{ + mpfr_t x, y, z; + + mpfr_inits2 (4, x, y, z, (mpfr_ptr) 0); + + /* Anything with NAN should be set to NAN */ + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_set_nan (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_NAN (z)); + mpfr_swap (x, y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_NAN (z)); + + /* 0+ 0+ --> 0+ */ + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z)); + /* 0- 0+ --> 0- */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z)); + /* 0- 0- --> -PI */ + MPFR_CHANGE_SIGN (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0); + /* 0+ 0- --> +PI */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0); + /* 0+ -1 --> PI */ + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0); + /* 0- -1 --> -PI */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0); + /* 0- +1 --> 0- */ + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z)); + /* 0+ +1 --> 0+ */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z)); + /* +1 0+ --> PI/2 */ + mpfr_swap (x, y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0); + /* +1 0- --> PI/2 */ + MPFR_CHANGE_SIGN (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0); + /* -1 0- --> -PI/2 */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0); + /* -1 0+ --> -PI/2 */ + MPFR_CHANGE_SIGN (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0); + + /* -1 +INF --> -0 */ + MPFR_SET_INF (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z)); + /* +1 +INF --> +0 */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z)); + /* +1 -INF --> +PI */ + MPFR_CHANGE_SIGN (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0); + /* -1 -INF --> -PI */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0); + /* -INF -1 --> -PI/2 */ + mpfr_swap (x, y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0); + /* +INF -1 --> PI/2 */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0); + /* +INF -INF --> 3*PI/4 */ + MPFR_SET_INF (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "2.356194490192344928", 10, MPFR_RNDN) == 0); + /* +INF +INF --> PI/4 */ + MPFR_CHANGE_SIGN (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "0.785375", 10, MPFR_RNDN) == 0); + /* -INF +INF --> -PI/4 */ + MPFR_CHANGE_SIGN (y); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-0.785375", 10, MPFR_RNDN) == 0); + /* -INF -INF --> -3*PI/4 */ + MPFR_CHANGE_SIGN (x); + mpfr_atan2 (z, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_str (z, "-2.356194490192344928", 10, MPFR_RNDN) == 0); + mpfr_set_prec (z, 905); /* exercises Ziv's loop */ + mpfr_atan2 (z, y, x, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_str (z, "-2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488496172998532038345716293667379401955609636083808771307702645389082916973346721171619778647332160823174945008459635673617534008737395340143185923642519259526145784", 10, MPFR_RNDN) == 0); + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +/* from Christopher Creutzig, 18 Jul 2007 */ +static void +smallvals_atan2 (void) +{ + mpfr_t a, x, y; + mpfr_exp_t old_emin; + + mpfr_inits (a, x, y, (mpfr_ptr) 0); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_nextbelow (y); + mpfr_set_ui (x, 1, MPFR_RNDN); + /* y=-2^(-emin-1), x=1 */ + + mpfr_atan2 (a, y, x, MPFR_RNDD); + MPFR_ASSERTN (mpfr_equal_p (a, y)); + + mpfr_atan2 (a, y, x, MPFR_RNDU); + MPFR_ASSERTN (mpfr_zero_p (a) && MPFR_IS_NEG(a)); + + mpfr_set_prec (x, 8); + mpfr_set_prec (y, 8); + mpfr_set_prec (a, 8); + old_emin = mpfr_get_emin (); + mpfr_set_emin (MPFR_EMIN_MIN); + + mpfr_set_si (y, 3, MPFR_RNDN); + mpfr_set_exp (y, mpfr_get_emin ()); + mpfr_set_str_binary (x, "1.1"); + mpfr_atan2 (a, y, x, MPFR_RNDU); + mpfr_set_si (y, 1, MPFR_RNDN); + mpfr_set_exp (y, mpfr_get_emin ()); + MPFR_ASSERTN (mpfr_equal_p (a, y)); + + /* From a bug reported by Christopher Creutzig on 2007-08-28. + Added test in each rounding mode. + Segmentation fault or assertion failure due to an infinite Ziv loop. */ + mpfr_set_si (y, 1, MPFR_RNDN); + mpfr_set_exp (y, mpfr_get_emin ()); + mpfr_set_str_binary (x, "1.01"); + mpfr_atan2 (a, y, x, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_zero_p (a)); + mpfr_atan2 (a, y, x, MPFR_RNDD); + MPFR_ASSERTN (mpfr_zero_p (a)); + mpfr_atan2 (a, y, x, MPFR_RNDU); + MPFR_ASSERTN (mpfr_equal_p (a, y)); + mpfr_atan2 (a, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_equal_p (a, y)); + + /* trigger underflow with rounding to nearest */ + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_atan2 (a, y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (a)); + + mpfr_set_emin (old_emin); + + mpfr_clears (a, x, y, (mpfr_ptr) 0); +} + +/* Bug found by Robert Bajema (regression in MPFR 2.3.0). + The cause is the underflow flag set before the mpfr_atan2 call. */ +static void +atan2_bug_20071003 (void) +{ + mpfr_t a, x, y, z; + + mpfr_inits (a, x, y, z, (mpfr_ptr) 0); + + mpfr_set_underflow (); + mpfr_set_str_binary (y, + "-0.10100110110100110111010110111111100110100010001110110E2"); + mpfr_set_str_binary (x, + "0.10100101010110010100010010111000110110011110001011110E3"); + mpfr_set_str_binary (z, + "-0.11101111001101101100111011001101000010010111101110110E-1"); + mpfr_atan2 (a, y, x, MPFR_RNDN); + if (! mpfr_equal_p (a, z)) + { + printf ("mpfr_atan2 fails on:\n"); + printf (" y = "); + mpfr_dump (y); + printf (" x = "); + mpfr_dump (x); + printf ("Expected "); + mpfr_dump (z); + printf ("Got "); + mpfr_dump (a); + exit (1); + } + + mpfr_clears (a, x, y, z, (mpfr_ptr) 0); +} + +/* Bug found on 2009-04-29 by Christopher Creutzig. + * With r6179: atan.c:62: MPFR assertion failed: r > n + */ +static void +atan2_different_prec (void) +{ + mpfr_t a, x, y; + + mpfr_init2 (a, 59); + mpfr_init2 (x, 59); + mpfr_init2 (y, 86); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_nextbelow (y); + mpfr_atan2 (a, y, x, MPFR_RNDN); + + mpfr_clears (a, x, y, (mpfr_ptr) 0); +} + +static void +atan2_pow_of_2 (void) +{ + mpfr_t x, y, r, g; + int i; + int d[] = { 0, -1, 1 }; + int ntests = sizeof (d) / sizeof (int); + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_init2 (r, 53); + mpfr_init2 (g, 53); + + /* atan(42) */ + mpfr_set_str_binary (g, "1100011000000011110011111001100110101000011010010011E-51"); + + for (i = 0; i < ntests; ++i) + { + mpfr_set_ui (y, 42, MPFR_RNDN); + mpfr_mul_2si (y, y, d[i], MPFR_RNDN); + mpfr_set_ui_2exp (x, 1, d[i], MPFR_RNDN); + mpfr_atan2 (r, y, x, MPFR_RNDN); + if (mpfr_equal_p (r, g) == 0) + { + printf ("Error in mpfr_atan2 (5)\n"); + printf ("Expected "); mpfr_print_binary (g); printf ("\n"); + printf ("Got "); mpfr_print_binary (r); printf ("\n"); + exit (1); + } + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (r); + mpfr_clear (g); +} + +/* https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00008.html + * Incorrect flags (in debug mode on a 32-bit machine, assertion failure). + */ +static void +reduced_expo_range (void) +{ + mpfr_exp_t emin, emax; + mpfr_t x, y, ex_y; + int inex, ex_inex; + unsigned int flags, ex_flags; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_inits2 (12, x, y, ex_y, (mpfr_ptr) 0); + mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN); + + mpfr_set_emin (-5); + mpfr_set_emax (-5); + mpfr_clear_flags (); + inex = mpfr_atan (y, x, MPFR_RNDN); + flags = __gmpfr_flags; + mpfr_set_emin (emin); + mpfr_set_emax (emax); + + mpfr_set_str (ex_y, "0.1e-5", 2, MPFR_RNDN); + ex_inex = 1; + ex_flags = MPFR_FLAGS_INEXACT; + + if (SIGN (inex) != ex_inex || flags != ex_flags || + ! mpfr_equal_p (y, ex_y)) + { + printf ("Error in reduced_expo_range\non x = "); + mpfr_dump (x); + printf ("Expected y = "); + mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN); + printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); + printf ("Got y = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); + exit (1); + } + + mpfr_clears (x, y, ex_y, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special_overflow (); + special (); + special_atan2 (); + smallvals_atan2 (); + atan2_bug_20071003 (); + atan2_different_prec (); + reduced_expo_range (); + + test_generic_atan (2, 200, 17); + test_generic_atan2 (2, 200, 17); + test_generic_atan2_neg (2, 200, 17); + + data_check ("data/atan", mpfr_atan, "mpfr_atan"); + bad_cases (mpfr_atan, mpfr_tan, "mpfr_atan", 256, -40, 1, 4, 128, 800, 40); + atan2_pow_of_2 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tatanh.c b/mpfr/tests/tatanh.c new file mode 100644 index 0000000000..7c920d5fbc --- /dev/null +++ b/mpfr/tests/tatanh.c @@ -0,0 +1,189 @@ +/* Test file for mpfr_atanh. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_atanh +#define TEST_RANDOM_EMAX 7 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y, z; + int i; + + mpfr_init (x); + mpfr_init (y); + + MPFR_SET_INF(x); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_atanh (x, y, MPFR_RNDN); + if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) + { + printf ("Inf flag not clears in atanh!\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_atanh (x, y, MPFR_RNDN); + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) + { + printf ("NAN flag not clears in atanh!\n"); + exit (1); + } + + /* atanh(+/-x) = NaN if x > 1 */ + for (i = 3; i <= 6; i++) + { + mpfr_set_si (x, i, MPFR_RNDN); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(%d/2) <> NaN\n", i); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(-%d/2) <> NaN\n", i); + exit (1); + } + } + + /* atanh(+0) = +0, atanh(-0) = -0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_atanh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_atanh(+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_atanh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_atanh(-0) <> -0\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(NaN) <> NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(+Inf) <> NaN\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(-Inf) <> NaN\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_atanh(1) <> +Inf\n"); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_atanh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_atanh(-1) <> -Inf\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.10001000001001011000100001E-6"); + mpfr_atanh (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.10001000001001100101010110100001E-6"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atanh (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.1101011110111100111010011001011E-1"); + mpfr_atanh (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.11100110000100001111101100010111E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atanh (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 43); + mpfr_set_str_binary (x, "0.111001101100000110011001010000101"); + mpfr_atanh (y, x, MPFR_RNDZ); + mpfr_init2 (z, 43); + mpfr_set_str_binary (z, "1.01111010110001101001000000101101011110101"); + if (mpfr_cmp (y, z)) + { + printf ("Error: mpfr_atanh (3)\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 25); + + data_check ("data/atanh", mpfr_atanh, "mpfr_atanh"); + bad_cases (mpfr_atanh, mpfr_tanh, "mpfr_atanh", 256, -128, 9, + 4, 128, 800, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/taway.c b/mpfr/tests/taway.c new file mode 100644 index 0000000000..fde80e820a --- /dev/null +++ b/mpfr/tests/taway.c @@ -0,0 +1,497 @@ +/* Test file for round away. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define DISP(s, t) {printf(s); mpfr_out_str(stdout, 2, 0, t, MPFR_RNDN); } +#define DISP2(s,t) {DISP(s,t); putchar('\n');} + +#define SPECIAL_MAX 12 + +static void +set_special (mpfr_ptr x, unsigned int select) +{ + MPFR_ASSERTN (select < SPECIAL_MAX); + switch (select) + { + case 0: + MPFR_SET_NAN (x); + break; + case 1: + MPFR_SET_INF (x); + MPFR_SET_POS (x); + break; + case 2: + MPFR_SET_INF (x); + MPFR_SET_NEG (x); + break; + case 3: + MPFR_SET_ZERO (x); + MPFR_SET_POS (x); + break; + case 4: + MPFR_SET_ZERO (x); + MPFR_SET_NEG (x); + break; + case 5: + mpfr_set_str_binary (x, "1"); + break; + case 6: + mpfr_set_str_binary (x, "-1"); + break; + case 7: + mpfr_set_str_binary (x, "1e-1"); + break; + case 8: + mpfr_set_str_binary (x, "1e+1"); + break; + case 9: + mpfr_const_pi (x, MPFR_RNDN); + break; + case 10: + mpfr_const_pi (x, MPFR_RNDN); + MPFR_SET_EXP (x, MPFR_GET_EXP (x)-1); + break; + default: + mpfr_urandomb (x, RANDS); + break; + } +} +/* same than mpfr_cmp, but returns 0 for both NaN's */ +static int +mpfr_compare (mpfr_srcptr a, mpfr_srcptr b) +{ + return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) : + (MPFR_IS_NAN(b) || mpfr_cmp(a, b)); +} + +static void +test3 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t), + const char *foo) +{ + mpfr_t ref1, ref2, ref3; + mpfr_t res1; + mpfr_prec_t p1, p2, p3; + int i, inexa, inexd; + mpfr_rnd_t r; + + p1 = (randlimb () % 200) + MPFR_PREC_MIN; + p2 = (randlimb () % 200) + MPFR_PREC_MIN; + p3 = (randlimb () % 200) + MPFR_PREC_MIN; + + mpfr_init2 (ref1, p1); + mpfr_init2 (ref2, p2); + mpfr_init2 (ref3, p3); + mpfr_init2 (res1, p1); + + /* for each variable, consider each of the following 6 possibilities: + NaN, +Infinity, -Infinity, +0, -0 or a random number */ + for (i = 0; i < SPECIAL_MAX * SPECIAL_MAX; i++) + { + set_special (ref2, i%SPECIAL_MAX); + set_special (ref3, i/SPECIAL_MAX); + + inexa = testfunc (res1, ref2, ref3, MPFR_RNDA); + r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref1, ref2, ref3, r); + + if (mpfr_compare (res1, ref1) || inexa != inexd) + { + printf ("Error with RNDA for %s with ", foo); + DISP("x=",ref2); DISP2(", y=",ref3); + printf ("inexa=%d inexd=%d\n", inexa, inexd); + printf ("expected "); mpfr_print_binary (ref1); puts (""); + printf ("got "); mpfr_print_binary (res1); puts (""); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (ref3); + mpfr_clear (res1); +} + +static void +test4 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, + mpfr_rnd_t), const char *foo) +{ + mpfr_t ref, op1, op2, op3; + mpfr_prec_t pout, p1, p2, p3; + mpfr_t res; + int i, j, k, inexa, inexd; + mpfr_rnd_t r; + + pout = (randlimb () % 200) + MPFR_PREC_MIN; + p1 = (randlimb () % 200) + MPFR_PREC_MIN; + p2 = (randlimb () % 200) + MPFR_PREC_MIN; + p3 = (randlimb () % 200) + MPFR_PREC_MIN; + + mpfr_init2 (ref, pout); + mpfr_init2 (res, pout); + mpfr_init2 (op1, p1); + mpfr_init2 (op2, p2); + mpfr_init2 (op3, p3); + + /* for each variable, consider each of the following 6 possibilities: + NaN, +Infinity, -Infinity, +0, -0 or a random number */ + + for (i = 0; i < SPECIAL_MAX; i++) + { + set_special (op1, i); + for (j = 0; j < SPECIAL_MAX; j++) + { + set_special (op2, j); + for (k = 0; k < SPECIAL_MAX; k++) + { + set_special (op3, k); + + inexa = testfunc (res, op1, op2, op3, MPFR_RNDA); + r = MPFR_SIGN(res) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref, op1, op2, op3, r); + + if (mpfr_compare (res, ref) || inexa != inexd) + { + printf ("Error with RNDA for %s with ", foo); + DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3); + printf ("inexa=%d inexd=%d\n", inexa, inexd); + DISP("expected ", ref); DISP2(", got ", res); + exit (1); + } + } + } + } + + mpfr_clear (ref); + mpfr_clear (op1); + mpfr_clear (op2); + mpfr_clear (op3); + mpfr_clear (res); +} + +static void +test2ui (int (*testfunc)(mpfr_ptr, mpfr_srcptr, unsigned long int, mpfr_rnd_t), + const char *foo) +{ + mpfr_t ref1, ref2; + unsigned int ref3; + mpfr_t res1; + mpfr_prec_t p1, p2; + int i, inexa, inexd; + mpfr_rnd_t r; + + p1 = (randlimb () % 200) + MPFR_PREC_MIN; + p2 = (randlimb () % 200) + MPFR_PREC_MIN; + + mpfr_init2 (ref1, p1); + mpfr_init2 (ref2, p2); + mpfr_init2 (res1, p1); + + /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number + ref3 can be 0 or any number */ + for (i = 0; i < SPECIAL_MAX * 2; i++) + { + set_special (ref2, i % SPECIAL_MAX); + ref3 = i / SPECIAL_MAX == 0 ? 0 : randlimb (); + + inexa = testfunc (res1, ref2, ref3, MPFR_RNDA); + r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref1, ref2, ref3, r); + + if (mpfr_compare (res1, ref1) || inexa != inexd) + { + printf ("Error with RNDA for %s for c=%u\n", foo, ref3); + DISP2("a=",ref2); + printf ("inexa=%d inexd=%d\n", inexa, inexd); + printf ("expected "); mpfr_print_binary (ref1); puts (""); + printf ("got "); mpfr_print_binary (res1); puts (""); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (res1); +} + +static void +testui2 (int (*testfunc)(mpfr_ptr, unsigned long int, mpfr_srcptr, mpfr_rnd_t), + const char *foo) +{ + mpfr_t ref1, ref3; + unsigned int ref2; + mpfr_t res1; + mpfr_prec_t p1, p3; + int i, inexa, inexd; + mpfr_rnd_t r; + + p1 = (randlimb () % 200) + MPFR_PREC_MIN; + p3 = (randlimb () % 200) + MPFR_PREC_MIN; + + mpfr_init2 (ref1, p1); + mpfr_init2 (ref3, p3); + mpfr_init2 (res1, p1); + + for (i = 0; i < SPECIAL_MAX * 2; i++) + { + set_special (ref3, i % SPECIAL_MAX); + ref2 = i / SPECIAL_MAX == 0 ? 0 : randlimb (); + + inexa = testfunc (res1, ref2, ref3, MPFR_RNDA); + r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref1, ref2, ref3, r); + + if (mpfr_compare (res1, ref1) || inexa != inexd) + { + printf ("Error with RNDA for %s for b=%u\n", foo, ref2); + DISP2("a=", ref3); + printf ("inexa=%d inexd=%d\n", inexa, inexd); + DISP("expected ", ref1); DISP2(", got ", res1); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref3); + mpfr_clear (res1); +} + +/* foo(mpfr_ptr, mpfr_srcptr, mp_rndt) */ +static void +test2 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), const char *foo) +{ + mpfr_t ref1, ref2; + mpfr_t res1; + mpfr_prec_t p1, p2; + int i, inexa, inexd; + mpfr_rnd_t r; + + p1 = (randlimb () % 200) + MPFR_PREC_MIN; + p2 = (randlimb () % 200) + MPFR_PREC_MIN; + + mpfr_init2 (ref1, p1); + mpfr_init2 (ref2, p2); + mpfr_init2 (res1, p1); + + for (i = 0; i < SPECIAL_MAX; i++) + { + set_special (ref2, i); + + /* first round to away */ + inexa = testfunc (res1, ref2, MPFR_RNDA); + + r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref1, ref2, r); + if (mpfr_compare (res1, ref1) || inexa != inexd) + { + printf ("Error with RNDA for %s with ", foo); + DISP2("x=", ref2); + printf ("inexa=%d inexd=%d\n", inexa, inexd); + DISP("expected ", ref1); DISP2(", got ", res1); + exit (1); + } + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (res1); +} + +/* one operand, two results, like mpfr_sin_cos */ +static void +test3a (int (*testfunc)(mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), + const char *foo) +{ + mpfr_t ref1, ref2, ref3; + mpfr_t res1, res2; + mpfr_prec_t p1, p2, p3; + int i, inexa, inexd; + mpfr_rnd_t r; + + p1 = (randlimb () % 200) + MPFR_PREC_MIN; + p2 = (randlimb () % 200) + MPFR_PREC_MIN; + p3 = (randlimb () % 200) + MPFR_PREC_MIN; + + mpfr_init2 (ref1, p1); + mpfr_init2 (ref2, p2); + mpfr_init2 (ref3, p3); + mpfr_init2 (res1, p1); + mpfr_init2 (res2, p2); + + for (i = 0; i < SPECIAL_MAX; i++) + { + set_special (ref3, i); + + inexa = testfunc (res1, res2, ref3, MPFR_RNDA); + + /* first check wrt the first operand */ + r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref1, ref2, ref3, r); + /* the low 2 bits of the inexact flag concern the 1st operand */ + if (mpfr_compare (res1, ref1) || (inexa & 3) != (inexd & 3)) + { + printf ("Error with RNDA for %s (1st operand)\n", foo); + DISP2("a=",ref3); + DISP("expected ", ref1); printf ("\n"); + DISP("got ", res1); printf ("\n"); + printf ("inexa=%d inexd=%d\n", inexa & 3, inexd & 3); + exit (1); + } + + /* now check wrt the second operand */ + r = MPFR_SIGN(res2) > 0 ? MPFR_RNDU : MPFR_RNDD; + inexd = testfunc (ref1, ref2, ref3, r); + /* bits 2..3 of the inexact flag concern the 2nd operand */ + if (mpfr_compare (res2, ref2) || (inexa >> 2) != (inexd >> 2)) + { + printf ("Error with RNDA for %s (2nd operand)\n", foo); + DISP2("a=",ref3); + DISP("expected ", ref2); printf ("\n"); + DISP("got ", res2); printf ("\n"); + printf ("inexa=%d inexd=%d\n", inexa >> 2, inexd >> 2); + exit (1); + } + + } + + mpfr_clear (ref1); + mpfr_clear (ref2); + mpfr_clear (ref3); + mpfr_clear (res1); + mpfr_clear (res2); +} + +int +main (void) +{ + int N = 20; + + tests_start_mpfr (); + + while (N--) + { + /* no need to test mpfr_round, mpfr_ceil, mpfr_floor, mpfr_trunc since + they take no rounding mode */ + + test2ui (mpfr_add_ui, "mpfr_add_ui"); + test2ui (mpfr_div_2exp, "mpfr_div_2exp"); + test2ui (mpfr_div_ui, "mpfr_div_ui"); + test2ui (mpfr_mul_2exp, "mpfr_mul_2exp"); + test2ui (mpfr_mul_ui, "mpfr_mul_ui"); + test2ui (mpfr_pow_ui, "mpfr_pow_ui"); + test2ui (mpfr_sub_ui, "mpfr_sub_ui"); + + testui2 (mpfr_ui_div, "mpfr_ui_div"); + testui2 (mpfr_ui_sub, "mpfr_ui_sub"); + testui2 (mpfr_ui_pow, "mpfr_ui_pow"); + + test2 (mpfr_sqr, "mpfr_sqr"); + test2 (mpfr_sqrt, "mpfr_sqrt"); + test2 (mpfr_abs, "mpfr_abs"); + test2 (mpfr_neg, "mpfr_neg"); + + test2 (mpfr_log, "mpfr_log"); + test2 (mpfr_log2, "mpfr_log2"); + test2 (mpfr_log10, "mpfr_log10"); + test2 (mpfr_log1p, "mpfr_log1p"); + + test2 (mpfr_exp, "mpfr_exp"); + test2 (mpfr_exp2, "mpfr_exp2"); + test2 (mpfr_exp10, "mpfr_exp10"); + test2 (mpfr_expm1, "mpfr_expm1"); + test2 (mpfr_eint, "mpfr_eint"); + + test2 (mpfr_sinh, "mpfr_sinh"); + test2 (mpfr_cosh, "mpfr_cosh"); + test2 (mpfr_tanh, "mpfr_tanh"); + test2 (mpfr_asinh, "mpfr_asinh"); + test2 (mpfr_acosh, "mpfr_acosh"); + test2 (mpfr_atanh, "mpfr_atanh"); + test2 (mpfr_sech, "mpfr_sech"); + test2 (mpfr_csch, "mpfr_csch"); + test2 (mpfr_coth, "mpfr_coth"); + + test2 (mpfr_asin, "mpfr_asin"); + test2 (mpfr_acos, "mpfr_acos"); + test2 (mpfr_atan, "mpfr_atan"); + test2 (mpfr_cos, "mpfr_cos"); + test2 (mpfr_sin, "mpfr_sin"); + test2 (mpfr_tan, "mpfr_tan"); + test2 (mpfr_sec, "mpfr_sec"); + test2 (mpfr_csc, "mpfr_csc"); + test2 (mpfr_cot, "mpfr_cot"); + + test2 (mpfr_erf, "mpfr_erf"); + test2 (mpfr_erfc, "mpfr_erfc"); + test2 (mpfr_j0, "mpfr_j0"); + test2 (mpfr_j1, "mpfr_j1"); + test2 (mpfr_y0, "mpfr_y0"); + test2 (mpfr_y1, "mpfr_y1"); + test2 (mpfr_zeta, "mpfr_zeta"); + test2 (mpfr_gamma, "mpfr_gamma"); + test2 (mpfr_lngamma, "mpfr_lngamma"); + + test2 (mpfr_rint, "mpfr_rint"); + test2 (mpfr_rint_ceil, "mpfr_rint_ceil"); + test2 (mpfr_rint_floor, "mpfr_rint_floor"); + test2 (mpfr_rint_round, "mpfr_rint_round"); + test2 (mpfr_rint_trunc, "mpfr_rint_trunc"); + test2 (mpfr_frac, "mpfr_frac"); + + test3 (mpfr_add, "mpfr_add"); + test3 (mpfr_sub, "mpfr_sub"); + test3 (mpfr_mul, "mpfr_mul"); + test3 (mpfr_div, "mpfr_div"); + + test3 (mpfr_agm, "mpfr_agm"); + test3 (mpfr_min, "mpfr_min"); + test3 (mpfr_max, "mpfr_max"); + + /* we don't test reldiff since it does not guarantee correct rounding, + thus we can get different results with RNDA and RNDU or RNDD. */ + test3 (mpfr_dim, "mpfr_dim"); + + test3 (mpfr_remainder, "mpfr_remainder"); + test3 (mpfr_pow, "mpfr_pow"); + test3 (mpfr_atan2, "mpfr_atan2"); + test3 (mpfr_hypot, "mpfr_hypot"); + + test3a (mpfr_sin_cos, "mpfr_sin_cos"); + + test4 (mpfr_fma, "mpfr_fma"); + test4 (mpfr_fms, "mpfr_fms"); + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + test2 (mpfr_li2, "mpfr_li2"); + test2 (mpfr_rec_sqrt, "mpfr_rec_sqrt"); + test3 (mpfr_fmod, "mpfr_fmod"); + test3a (mpfr_modf, "mpfr_modf"); + test3a (mpfr_sinh_cosh, "mpfr_sinh_cosh"); +#endif + } + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tbuildopt.c b/mpfr/tests/tbuildopt.c new file mode 100644 index 0000000000..fbc3fffef9 --- /dev/null +++ b/mpfr/tests/tbuildopt.c @@ -0,0 +1,89 @@ +/* tbuildopt.c -- test file for mpfr_buildopt_tls_p and + mpfr_buildopt_decimal_p. + +Copyright 2009-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include "mpfr-test.h" + +static void +check_tls_p (void) +{ +#ifdef MPFR_USE_THREAD_SAFE + if (!mpfr_buildopt_tls_p()) + { + printf ("Error: mpfr_buildopt_tls_p should return true\n"); + exit (1); + } +#else + if (mpfr_buildopt_tls_p()) + { + printf ("Error: mpfr_buildopt_tls_p should return false\n"); + exit (1); + } +#endif +} + +static void +check_decimal_p (void) +{ +#ifdef MPFR_WANT_DECIMAL_FLOATS + if (!mpfr_buildopt_decimal_p()) + { + printf ("Error: mpfr_buildopt_decimal_p should return true\n"); + exit (1); + } +#else + if (mpfr_buildopt_decimal_p()) + { + printf ("Error: mpfr_buildopt_decimal_p should return false\n"); + exit (1); + } +#endif +} + +static void +check_gmpinternals_p (void) +{ +#if defined(MPFR_HAVE_GMP_IMPL) || defined(WANT_GMP_INTERNALS) + if (!mpfr_buildopt_gmpinternals_p()) + { + printf ("Error: mpfr_buildopt_gmpinternals_p should return true\n"); + exit (1); + } +#else + if (mpfr_buildopt_gmpinternals_p()) + { + printf ("Error: mpfr_buildopt_gmpinternals_p should return false\n"); + exit (1); + } +#endif +} + +int +main (void) +{ + check_tls_p(); + check_decimal_p(); + check_gmpinternals_p(); + + return 0; +} diff --git a/mpfr/tests/tcan_round.c b/mpfr/tests/tcan_round.c new file mode 100644 index 0000000000..a415d2f5d2 --- /dev/null +++ b/mpfr/tests/tcan_round.c @@ -0,0 +1,208 @@ +/* Test file for mpfr_can_round and mpfr_round_p. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define MAX_LIMB_SIZE 100 + +static void +check_round_p (void) +{ + mp_limb_t buf[MAX_LIMB_SIZE]; + mp_size_t n, i; + mpfr_prec_t p; + mpfr_exp_t err; + int r1, r2; + + for (n = 2 ; n <= MAX_LIMB_SIZE ; n++) + { + /* avoid mpn_random which leaks memory */ + for (i = 0; i < n; i++) + buf[i] = randlimb (); + /* force the number to be normalized */ + buf[n - 1] |= MPFR_LIMB_HIGHBIT; + p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN; + err = p + randlimb () % GMP_NUMB_BITS; + r1 = mpfr_round_p (buf, n, err, p); + r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err, + MPFR_RNDN, MPFR_RNDZ, p); + if (r1 != r2) + { + printf ("mpfr_round_p(%d) != mpfr_can_round(%d)!\n" + "bn = %ld, err0 = %ld, prec = %lu\nbp = ", + r1, r2, n, (long) err, (unsigned long) p); + gmp_printf ("%NX\n", buf, n); + exit (1); + } + } +} + +/* check x=2^i with precision px, error at most 1, and target precision prec */ +static void +test_pow2 (mpfr_exp_t i, mpfr_prec_t px, mpfr_rnd_t r1, mpfr_rnd_t r2, + mpfr_prec_t prec) +{ + mpfr_t x; + int b, expected_b, b2; + + mpfr_init2 (x, px); + mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN); + b = !!mpfr_can_round (x, i+1, r1, r2, prec); + /* Note: If mpfr_can_round succeeds for both + (r1,r2) = (MPFR_RNDD,MPFR_RNDN) and + (r1,r2) = (MPFR_RNDU,MPFR_RNDN), then it should succeed for + (r1,r2) = (MPFR_RNDN,MPFR_RNDN). So, the condition on prec below + for r1 = MPFR_RNDN should be the most restrictive between those + for r1 = any directed rounding mode. + For r1 like MPFR_RNDA, the unrounded, unknown number may be anyone + in [2^i-1,i]. As both 2^i-1 and 2^i fit on i bits, one cannot round + in any precision >= i bits, hence the condition prec < i; prec = i-1 + will work here for r2 = MPFR_RNDN thanks to the even-rounding rule + (and also with rounding ties away from zero). */ + expected_b = + MPFR_IS_LIKE_RNDD (r1, MPFR_SIGN_POS) ? + (MPFR_IS_LIKE_RNDU (r2, MPFR_SIGN_POS) ? 0 : prec <= i) : + MPFR_IS_LIKE_RNDU (r1, MPFR_SIGN_POS) ? + (MPFR_IS_LIKE_RNDD (r2, MPFR_SIGN_POS) ? 0 : prec < i) : + (r2 != MPFR_RNDN ? 0 : prec < i); + /* We only require mpfr_can_round to return 1 when we can really + round, it is allowed to return 0 in some rare boundary cases, + for example when x = 2^k and the error is 0.25 ulp. + Note: if this changes in the future, the test could be improved by + removing the "&& expected_b == 0" below. */ + if (b != expected_b && expected_b == 0) + { + printf ("Error for x=2^%d, px=%lu, err=%d, r1=%s, r2=%s, prec=%d\n", + (int) i, (unsigned long) px, (int) i + 1, + mpfr_print_rnd_mode (r1), mpfr_print_rnd_mode (r2), (int) prec); + printf ("Expected %d, got %d\n", expected_b, b); + exit (1); + } + + if (r1 == MPFR_RNDN && r2 == MPFR_RNDZ) + { + /* Similar test to the one done in src/round_p.c + for MPFR_WANT_ASSERT >= 2. */ + b2 = !!mpfr_round_p (MPFR_MANT(x), MPFR_LIMB_SIZE(x), i+1, prec); + if (b2 != b) + { + printf ("Error for x=2^%d, px=%lu, err=%d, prec=%d\n", + (int) i, (unsigned long) px, (int) i + 1, (int) prec); + printf ("mpfr_can_round gave %d, mpfr_round_p gave %d\n", b, b2); + exit (1); + } + } + + mpfr_clear (x); +} + +int +main (void) +{ + mpfr_t x; + mpfr_prec_t i, j, k; + int r1, r2; + int n; + + tests_start_mpfr (); + + /* checks that rounds to nearest sets the last + bit to zero in case of equal distance */ + mpfr_init2 (x, 59); + mpfr_set_str_binary (x, "-0.10010001010111000011110010111010111110000000111101100111111E663"); + if (mpfr_can_round (x, 54, MPFR_RNDZ, MPFR_RNDZ, 53) != 0) + { + printf ("Error (1) in mpfr_can_round\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-Inf"); + if (mpfr_can_round (x, 2000, MPFR_RNDZ, MPFR_RNDZ, 2000) != 0) + { + printf ("Error (2) in mpfr_can_round\n"); + exit (1); + } + + mpfr_set_prec (x, 64); + mpfr_set_str_binary (x, "0.1011001000011110000110000110001111101011000010001110011000000000"); + if (mpfr_can_round (x, 65, MPFR_RNDN, MPFR_RNDN, 54)) + { + printf ("Error (3) in mpfr_can_round\n"); + exit (1); + } + + mpfr_set_prec (x, 137); + mpfr_set_str_binary (x, "-0.10111001101001010110011000110100111010011101101010010100101100001110000100111111011101010110001010111100100101110111100001000010000000000E-97"); + if (mpfr_can_round (x, 132, MPFR_RNDU, MPFR_RNDZ, 128) == 0) + { + printf ("Error (4) in mpfr_can_round\n"); + exit (1); + } + + /* in the following, we can round but cannot determine the inexact flag */ + mpfr_set_prec (x, 86); + mpfr_set_str_binary (x, "-0.11100100010011001111011010100111101010011000000000000000000000000000000000000000000000E-80"); + if (mpfr_can_round (x, 81, MPFR_RNDU, MPFR_RNDZ, 44) == 0) + { + printf ("Error (5) in mpfr_can_round\n"); + exit (1); + } + + mpfr_set_prec (x, 62); + mpfr_set_str (x, "0.ff4ca619c76ba69", 16, MPFR_RNDZ); + for (i = 30; i < 99; i++) + for (j = 30; j < 99; j++) + for (r1 = 0; r1 < MPFR_RND_MAX; r1++) + for (r2 = 0; r2 < MPFR_RND_MAX; r2++) + { + /* test for assertions */ + mpfr_can_round (x, i, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j); + } + + test_pow2 (32, 32, MPFR_RNDN, MPFR_RNDN, 32); + test_pow2 (174, 174, MPFR_RNDN, MPFR_RNDN, 174); + test_pow2 (174, 174, MPFR_RNDU, MPFR_RNDN, 174); + test_pow2 (176, 129, MPFR_RNDU, MPFR_RNDU, 174); + test_pow2 (176, 2, MPFR_RNDZ, MPFR_RNDZ, 174); + test_pow2 (176, 2, MPFR_RNDU, MPFR_RNDU, 176); + + /* Tests for x = 2^i (E(x) = i+1) with error at most 1 = 2^0. */ + for (n = 0; n < 100; n++) + { + i = (randlimb() % 200) + 4; + for (j = i - 2; j < i + 2; j++) + for (r1 = 0; r1 < MPFR_RND_MAX; r1++) + for (r2 = 0; r2 < MPFR_RND_MAX; r2++) + for (k = MPFR_PREC_MIN; k <= i + 2; k++) + test_pow2 (i, k, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j); + } + + mpfr_clear (x); + + check_round_p (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcbrt.c b/mpfr/tests/tcbrt.c new file mode 100644 index 0000000000..58e65ffd5c --- /dev/null +++ b/mpfr/tests/tcbrt.c @@ -0,0 +1,219 @@ +/* Test file for mpfr_cbrt. + +Copyright 2002-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + /* cbrt(NaN) = NaN */ + mpfr_set_nan (x); + mpfr_cbrt (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: cbrt(NaN) <> NaN\n"); + exit (1); + } + + /* cbrt(+Inf) = +Inf */ + mpfr_set_inf (x, 1); + mpfr_cbrt (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: cbrt(+Inf) <> +Inf\n"); + exit (1); + } + + /* cbrt(-Inf) = -Inf */ + mpfr_set_inf (x, -1); + mpfr_cbrt (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error: cbrt(-Inf) <> -Inf\n"); + exit (1); + } + + /* cbrt(+/-0) = +/-0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_cbrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: cbrt(+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_cbrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: cbrt(-0) <> -0\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_str (x, "8.39005285514734966412e-01", 10, MPFR_RNDN); + mpfr_cbrt (x, x, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01")) + { + printf ("Error in crbrt (1)\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "0.10000100001100101001001001011001"); + mpfr_cbrt (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.11001101011000100111000111111001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "-0.1100001110110000010101011001011"); + mpfr_cbrt (x, x, MPFR_RNDD); + mpfr_set_str_binary (y, "-0.11101010000100100101000101011001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (3)\n"); + exit (1); + } + + mpfr_set_prec (x, 82); + mpfr_set_prec (y, 27); + mpfr_set_str_binary (x, "0.1010001111011101011011000111001011001101100011110110010011011011011010011001100101e-7"); + mpfr_cbrt (y, x, MPFR_RNDD); + mpfr_set_str_binary (x, "0.101011110001110001000100011E-2"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (4)\n"); + exit (1); + } + + mpfr_set_prec (x, 204); + mpfr_set_prec (y, 38); + mpfr_set_str_binary (x, "0.101000000001101000000001100111111011111001110110100001111000100110100111001101100111110001110001011011010110010011100101111001111100001010010100111011101100000011011000101100010000000011000101001010001001E-5"); + mpfr_cbrt (y, x, MPFR_RNDD); + mpfr_set_str_binary (x, "0.10001001111010011011101000010110110010E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (5)\n"); + exit (1); + } + + /* Bug (in the compiler?) found on Linux/m68k with gcc 4.0.2 */ + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_str_binary (x, "1.1000E-2"); + mpfr_cbrt (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "1.0111E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (6)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_cbrt +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x; + int r; + mpfr_prec_t p; + + tests_start_mpfr (); + + special (); + + mpfr_init (x); + + for (p=2; p<100; p++) + { + mpfr_set_prec (x, p); + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_cbrt (x, x, (mpfr_rnd_t) r); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_cbrt for x=1, rnd=%s\ngot ", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_cbrt (x, x, (mpfr_rnd_t) r); + if (mpfr_cmp_si (x, -1)) + { + printf ("Error in mpfr_cbrt for x=-1, rnd=%s\ngot ", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + if (p >= 5) + { + int i; + for (i = -12; i <= 12; i++) + { + mpfr_set_ui (x, 27, MPFR_RNDN); + mpfr_mul_2si (x, x, 3*i, MPFR_RNDN); + mpfr_cbrt (x, x, MPFR_RNDN); + if (mpfr_cmp_si_2exp (x, 3, i)) + { + printf ("Error in mpfr_cbrt for " + "x = 27.0 * 2^(%d), rnd=%s\ngot ", + 3*i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ninstead of 3 * 2^(%d)\n", i); + exit (1); + } + } + } + } + } + mpfr_clear (x); + + test_generic (2, 200, 10); + + data_check ("data/cbrt", mpfr_cbrt, "mpfr_cbrt"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcheck.c b/mpfr/tests/tcheck.c new file mode 100644 index 0000000000..4f3d509811 --- /dev/null +++ b/mpfr/tests/tcheck.c @@ -0,0 +1,125 @@ +/* Test file for mpfr_check. + +Copyright 2003-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <stdio.h> + +#include "mpfr-test.h" + +#define ERROR(s) \ + (printf ("mpfr_check failed " s " Prec=%lu\n", (unsigned long) pr), \ + exit(1)) + +int +main (void) +{ + mpfr_t a; + mp_limb_t *p, tmp; + mp_size_t s; + mpfr_prec_t pr; + int max; + + tests_start_mpfr (); + for(pr = MPFR_PREC_MIN ; pr < 500 ; pr++) + { + mpfr_init2 (a, pr); + if (!mpfr_check(a)) ERROR("for init"); + /* Check special cases */ + MPFR_SET_NAN(a); + if (!mpfr_check(a)) ERROR("for nan"); + MPFR_SET_POS(a); + MPFR_SET_INF(a); + if (!mpfr_check(a)) ERROR("for inf"); + MPFR_SET_ZERO(a); + if (!mpfr_check(a)) ERROR("for zero"); + /* Check var */ + mpfr_set_ui(a, 2, MPFR_RNDN); + if (!mpfr_check(a)) ERROR("for set_ui"); + mpfr_clear_overflow(); + max = 1000; /* Allows max 2^1000 bits for the exponent */ + while ((!mpfr_overflow_p()) && (max>0)) + { + mpfr_mul(a, a, a, MPFR_RNDN); + if (!mpfr_check(a)) ERROR("for mul"); + max--; + } + if (max==0) ERROR("can't reach overflow"); + mpfr_set_ui(a, 2137, MPFR_RNDN); + /* Corrupt a and check for it */ + MPFR_SIGN(a) = 2; + if (mpfr_check(a)) ERROR("sgn"); + MPFR_SET_POS(a); + /* Check prec */ + MPFR_PREC(a) = 1; + if (mpfr_check(a)) ERROR("precmin"); +#if MPFR_VERSION_MAJOR < 3 + /* Disable the test with MPFR >= 3 since mpfr_prec_t is now signed. + The "if" below is sufficient, but the MPFR_PREC_MAX+1 generates + a warning with GCC 4.4.4 even though the test is always false. */ + if ((mpfr_prec_t) 0 - 1 > 0) + { + MPFR_PREC(a) = MPFR_PREC_MAX+1; + if (mpfr_check(a)) ERROR("precmax"); + } +#endif + MPFR_PREC(a) = pr; + if (!mpfr_check(a)) ERROR("prec"); + /* Check exponent */ + MPFR_EXP(a) = MPFR_EXP_INVALID; + if (mpfr_check(a)) ERROR("exp invalid"); + MPFR_EXP(a) = -MPFR_EXP_INVALID; + if (mpfr_check(a)) ERROR("-exp invalid"); + MPFR_EXP(a) = 0; + if (!mpfr_check(a)) ERROR("exp 0"); + /* Check Mantissa */ + p = MPFR_MANT(a); + MPFR_MANT(a) = NULL; + if (mpfr_check(a)) ERROR("Mantissa Null Ptr"); + MPFR_MANT(a) = p; + /* Check size */ + s = MPFR_GET_ALLOC_SIZE(a); + MPFR_SET_ALLOC_SIZE(a, 0); + if (mpfr_check(a)) ERROR("0 size"); + MPFR_SET_ALLOC_SIZE(a, MP_SIZE_T_MIN); + if (mpfr_check(a)) ERROR("min size"); + MPFR_SET_ALLOC_SIZE(a, MPFR_LIMB_SIZE(a)-1 ); + if (mpfr_check(a)) ERROR("size < prec"); + MPFR_SET_ALLOC_SIZE(a, s); + /* Check normal form */ + tmp = MPFR_MANT(a)[0]; + if ((pr % GMP_NUMB_BITS) != 0) + { + MPFR_MANT(a)[0] = ~0; + if (mpfr_check(a)) ERROR("last bits non 0"); + } + MPFR_MANT(a)[0] = tmp; + MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] &= MPFR_LIMB_MASK (GMP_NUMB_BITS-1); + if (mpfr_check(a)) ERROR("last bits non 0"); + /* Final */ + mpfr_set_ui(a, 2137, MPFR_RNDN); + if (!mpfr_check(a)) ERROR("after last set"); + mpfr_clear (a); + if (mpfr_check(a)) ERROR("after clear"); + } + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcmp.c b/mpfr/tests/tcmp.c new file mode 100644 index 0000000000..92a119fe03 --- /dev/null +++ b/mpfr/tests/tcmp.c @@ -0,0 +1,220 @@ +/* Test file for mpfr_cmp. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + double x, y; + mpfr_t xx, yy; + int c; + long i; + mpfr_prec_t p; + + tests_start_mpfr (); + + mpfr_init (xx); + mpfr_init (yy); + + mpfr_set_prec (xx, 2); + mpfr_set_prec (yy, 2); + mpfr_set_str_binary(xx, "-0.10E0"); + mpfr_set_str_binary(yy, "-0.10E0"); + if ((mpfr_cmp) (xx, yy)) + { + printf ("mpfr_cmp (xx, yy) returns non-zero for prec=2\n"); + exit (1); + } + + mpfr_set_prec (xx, 65); + mpfr_set_prec (yy, 65); + mpfr_set_str_binary(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623"); + mpfr_set_str_binary(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); + p = 0; + if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 64) + { + printf ("Error (1) in mpfr_cmp2\n"); + exit (1); + } + mpfr_set_str_binary(xx, "0.10100010001110110111000010001000010011111101000100011101000011100"); + mpfr_set_str_binary(yy, "0.10100010001110110111000010001000010011111101000100011101000011011"); + p = 0; + if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 64) + { + printf ("Error (2) in mpfr_cmp2\n"); + exit (1); + } + + mpfr_set_prec (xx, 160); mpfr_set_prec (yy, 160); + mpfr_set_str_binary (xx, "0.1E1"); + mpfr_set_str_binary (yy, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100"); + p = 0; + if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 144) + { + printf ("Error (3) in mpfr_cmp2\n"); + exit (1); + } + + mpfr_set_prec (xx, 53); + mpfr_set_prec (yy, 200); + mpfr_set_ui (xx, 1, (mpfr_rnd_t) 0); + mpfr_set_ui (yy, 1, (mpfr_rnd_t) 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_str (xx, "1.0000000002", 10, (mpfr_rnd_t) 0); + mpfr_set_ui (yy, 1, (mpfr_rnd_t) 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); + + /* bug found by Gerardo Ballabio */ + mpfr_set_ui(xx, 0, MPFR_RNDN); + mpfr_set_str (yy, "0.1", 10, MPFR_RNDN); + if ((c = mpfr_cmp (xx, yy)) >= 0) + { + printf ("Error in mpfr_cmp(0.0, 0.1), gives %d\n", c); + exit (1); + } + + mpfr_set_inf (xx, 1); + mpfr_set_str (yy, "-23489745.0329", 10, MPFR_RNDN); + if ((c = mpfr_cmp (xx, yy)) <= 0) + { + printf ("Error in mpfr_cmp(Infp, 23489745.0329), gives %d\n", c); + exit (1); + } + + mpfr_set_inf (xx, 1); + mpfr_set_inf (yy, -1); + if ((c = mpfr_cmp (xx, yy)) <= 0) + { + printf ("Error in mpfr_cmp(Infp, Infm), gives %d\n", c); + exit (1); + } + + mpfr_set_inf (xx, -1); + mpfr_set_inf (yy, 1); + if ((c = mpfr_cmp (xx, yy)) >= 0) + { + printf ("Error in mpfr_cmp(Infm, Infp), gives %d\n", c); + exit (1); + } + + mpfr_set_inf (xx, 1); + mpfr_set_inf (yy, 1); + if ((c = mpfr_cmp (xx, yy)) != 0) + { + printf ("Error in mpfr_cmp(Infp, Infp), gives %d\n", c); + exit (1); + } + + mpfr_set_inf (xx, -1); + mpfr_set_inf (yy, -1); + if ((c = mpfr_cmp (xx, yy)) != 0) + { + printf ("Error in mpfr_cmp(Infm, Infm), gives %d\n", c); + exit (1); + } + + mpfr_set_inf (xx, -1); + mpfr_set_str (yy, "2346.09234", 10, MPFR_RNDN); + if ((c = mpfr_cmp (xx, yy)) >= 0) + { + printf ("Error in mpfr_cmp(Infm, 2346.09234), gives %d\n", c); + exit (1); + } + + mpfr_set_ui (xx, 0, MPFR_RNDN); + mpfr_set_ui (yy, 1, MPFR_RNDN); + if ((c = mpfr_cmp3 (xx, yy, 1)) >= 0) + { + printf ("Error: mpfr_cmp3 (0, 1, 1) gives %d instead of" + " a negative value\n", c); + exit (1); + } + if ((c = mpfr_cmp3 (xx, yy, -1)) <= 0) + { + printf ("Error: mpfr_cmp3 (0, 1, -1) gives %d instead of" + " a positive value\n", c); + exit (1); + } + + for (i=0; i<500000; ) + { + x = DBL_RAND (); + y = DBL_RAND (); + if (!Isnan(x) && !Isnan(y)) + { + i++; + mpfr_set_d (xx, x, MPFR_RNDN); + mpfr_set_d (yy, y, MPFR_RNDN); + 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); + } + } + } + + /* Check for NAN */ + mpfr_set_nan (xx); + mpfr_clear_erangeflag (); + c = (mpfr_cmp) (xx, yy); + if (c != 0 || !mpfr_erangeflag_p () ) + { + printf ("NAN error (1)\n"); + exit (1); + } + mpfr_clear_erangeflag (); + c = (mpfr_cmp) (yy, xx); + if (c != 0 || !mpfr_erangeflag_p () ) + { + printf ("NAN error (2)\n"); + exit (1); + } + mpfr_clear_erangeflag (); + c = (mpfr_cmp) (xx, xx); + if (c != 0 || !mpfr_erangeflag_p () ) + { + printf ("NAN error (3)\n"); + exit (1); + } + + mpfr_clear (xx); + mpfr_clear (yy); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcmp2.c b/mpfr/tests/tcmp2.c new file mode 100644 index 0000000000..8187b376db --- /dev/null +++ b/mpfr/tests/tcmp2.c @@ -0,0 +1,348 @@ +/* Test file for mpfr_cmp2. + +Copyright 1999-2003, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* set bit n of x to b, where bit 0 is the most significant one */ +static void +set_bit (mpfr_t x, unsigned int n, int b) +{ + unsigned l; + mp_size_t xn; + + xn = (MPFR_PREC(x) - 1) / mp_bits_per_limb; + l = n / mp_bits_per_limb; + n %= mp_bits_per_limb; + n = mp_bits_per_limb - 1 - n; + if (b) + MPFR_MANT(x)[xn - l] |= (mp_limb_t) 1 << n; + else + MPFR_MANT(x)[xn - l] &= ~((mp_limb_t) 1 << n); +} + +/* check that for x = 1.u 1 v 0^k low(x) + y = 1.u 0 v 1^k low(y) + mpfr_cmp2 (x, y) returns 1 + |u| + |v| + k for low(x) >= low(y), + and 1 + |u| + |v| + k + 1 otherwise */ +static void +worst_cases (void) +{ + mpfr_t x, y; + unsigned int i, j, k, b, expected; + mpfr_prec_t l; + + mpfr_init2 (x, 200); + mpfr_init2 (y, 200); + + mpfr_set_ui (y, 1, MPFR_RNDN); + for (i = 1; i < MPFR_PREC(x); i++) + { + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2exp (y, y, 1, MPFR_RNDN); /* y = 1/2^i */ + + l = 0; + if (mpfr_cmp2 (x, y, &l) <= 0 || l != 1) + { + printf ("Error in mpfr_cmp2:\nx="); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ny="); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\ngot %lu instead of 1\n", (unsigned long) l); + exit (1); + } + + mpfr_add (x, x, y, MPFR_RNDN); /* x = 1 + 1/2^i */ + l = 0; + if (mpfr_cmp2 (x, y, &l) <= 0 || l != 0) + { + printf ("Error in mpfr_cmp2:\nx="); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ny="); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\ngot %lu instead of 0\n", (unsigned long) l); + exit (1); + } + } + + for (i = 0; i < 64; i++) /* |u| = i */ + { + mpfr_urandomb (x, RANDS); + mpfr_set (y, x, MPFR_RNDN); + set_bit (x, i + 1, 1); + set_bit (y, i + 1, 0); + for (j = 0; j < 64; j++) /* |v| = j */ + { + b = randlimb () % 2; + set_bit (x, i + j + 2, b); + set_bit (y, i + j + 2, b); + for (k = 0; k < 64; k++) + { + if (k) + set_bit (x, i + j + k + 1, 0); + if (k) + set_bit (y, i + j + k + 1, 1); + set_bit (x, i + j + k + 2, 1); + set_bit (y, i + j + k + 2, 0); + l = 0; mpfr_cmp2 (x, y, &l); + expected = i + j + k + 1; + if (l != expected) + { + printf ("Error in mpfr_cmp2:\nx="); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ny="); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\ngot %lu instead of %u\n", + (unsigned long) l, expected); + exit (1); + } + set_bit (x, i + j + k + 2, 0); + set_bit (x, i + j + k + 3, 0); + set_bit (y, i + j + k + 3, 1); + l = 0; mpfr_cmp2 (x, y, &l); + expected = i + j + k + 2; + if (l != expected) + { + printf ("Error in mpfr_cmp2:\nx="); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ny="); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\ngot %lu instead of %u\n", + (unsigned long) l, expected); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +tcmp2 (double x, double y, int i) +{ + mpfr_t xx, yy; + mpfr_prec_t j; + + if (i == -1) + { + if (x == y) + i = 53; + else + i = (int) (__gmpfr_floor_log2 (x) - __gmpfr_floor_log2 (x - y)); + } + mpfr_init2(xx, 53); mpfr_init2(yy, 53); + mpfr_set_d (xx, x, MPFR_RNDN); + mpfr_set_d (yy, y, MPFR_RNDN); + j = 0; + if (mpfr_cmp2 (xx, yy, &j) == 0) + { + if (x != y) + { + printf ("Error in mpfr_cmp2 for\nx="); + mpfr_out_str (stdout, 2, 0, xx, MPFR_RNDN); + printf ("\ny="); + mpfr_out_str (stdout, 2, 0, yy, MPFR_RNDN); + printf ("\ngot sign 0 for x != y\n"); + exit (1); + } + } + else if (j != (unsigned) i) + { + printf ("Error in mpfr_cmp2 for\nx="); + mpfr_out_str (stdout, 2, 0, xx, MPFR_RNDN); + printf ("\ny="); + mpfr_out_str (stdout, 2, 0, yy, MPFR_RNDN); + printf ("\ngot %lu instead of %d\n", (unsigned long) j, i); + exit (1); + } + mpfr_clear(xx); mpfr_clear(yy); +} + +static void +special (void) +{ + mpfr_t x, y; + mpfr_prec_t j; + + mpfr_init (x); mpfr_init (y); + + /* bug found by Nathalie Revol, 21 March 2001 */ + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 65); + mpfr_set_str_binary (x, "0.10000000000000000000000000000000000001110010010110100110011110000E1"); + mpfr_set_str_binary (y, "0.11100100101101001100111011111111110001101001000011101001001010010E-35"); + j = 0; + if (mpfr_cmp2 (x, y, &j) <= 0 || j != 1) + { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); + mpfr_print_binary (x); + puts (""); + printf ("y="); + mpfr_print_binary (y); + puts (""); + printf ("got %lu, expected 1\n", (unsigned long) j); + exit (1); + } + + mpfr_set_prec(x, 127); mpfr_set_prec(y, 127); + mpfr_set_str_binary(x, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6"); + mpfr_set_str_binary(y, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6"); + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 32) + { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); mpfr_print_binary(x); puts (""); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("got %lu, expected 32\n", (unsigned long) j); + exit (1); + } + + mpfr_set_prec (x, 128); mpfr_set_prec (y, 239); + mpfr_set_str_binary (x, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100100000000000E167"); + mpfr_set_str_binary (y, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100011111111111111111111111111111111111111111111111011111100101011100011001101000100111000010000000000101100110000111111000101E167"); + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 164) + { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); mpfr_print_binary(x); puts (""); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("got %lu, expected 164\n", (unsigned long) j); + exit (1); + } + + /* bug found by Nathalie Revol, 29 March 2001 */ + mpfr_set_prec (x, 130); mpfr_set_prec (y, 130); + mpfr_set_str_binary (x, "0.1100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2"); + mpfr_set_str_binary (y, "0.1011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100E2"); + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 127) + { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); mpfr_print_binary(x); puts (""); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("got %lu, expected 127\n", (unsigned long) j); + exit (1); + } + + /* bug found by Nathalie Revol, 2 Apr 2001 */ + mpfr_set_prec (x, 65); mpfr_set_prec (y, 65); + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_set_str_binary (y, "0.10011111111111111111111111111111111111111111111111111111111111101E3"); + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 63) + { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); mpfr_print_binary(x); puts (""); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("got %lu, expected 63\n", (unsigned long) j); + exit (1); + } + + /* bug found by Nathalie Revol, 2 Apr 2001 */ + mpfr_set_prec (x, 65); mpfr_set_prec (y, 65); + mpfr_set_str_binary (x, "0.10011011111000101001110000000000000000000000000000000000000000000E-69"); + mpfr_set_str_binary (y, "0.10011011111000101001101111111111111111111111111111111111111111101E-69"); + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 63) + { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); mpfr_print_binary(x); puts (""); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("got %lu, expected 63\n", (unsigned long) j); + exit (1); + } + + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101"); + mpfr_set_str_binary (y, "0.11101110111100011101110111111111"); + if (mpfr_cmp2 (x, y, &j) <= 0 || j != 0) + { + printf ("Error in mpfr_cmp2 (1)\n"); + exit (1); + } + + mpfr_set_prec (x, 2 * GMP_NUMB_BITS); + mpfr_set_prec (y, GMP_NUMB_BITS); + mpfr_set_ui (x, 1, MPFR_RNDN); /* x = 1 */ + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_nextbelow (y); /* y = 1 - 2^(-GMP_NUMB_BITS) */ + mpfr_cmp2 (x, y, &j); + if (mpfr_cmp2 (x, y, &j) <= 0 || j != GMP_NUMB_BITS) + { + printf ("Error in mpfr_cmp2 (2)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (void) +{ + int i; + long j; + double x, y, z; + + tests_start_mpfr (); + mpfr_test_init (); + + worst_cases (); + special (); + tcmp2 (5.43885304644369510000e+185, -1.87427265794105340000e-57, 1); + tcmp2 (1.06022698059744327881e+71, 1.05824655795525779205e+71, -1); + tcmp2 (1.0, 1.0, 53); + /* warning: cmp2 does not allow 0 as input */ + for (x = 0.5, i = 1; i < 54; i++) + { + tcmp2 (1.0, 1.0-x, i); + x /= 2.0; + } + for (x = 0.5, i = 1; i < 100; i++) + { + tcmp2 (1.0, x, 1); + x /= 2.0; + } + for (j = 0; j < 100000; j++) + { + x = DBL_RAND (); + y = DBL_RAND (); + if (x < y) + { + z = x; + x = y; + y = z; + } + if (y != 0.0) + tcmp2 (x, y, -1); + } + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tcmp_d.c b/mpfr/tests/tcmp_d.c new file mode 100644 index 0000000000..e906ab893e --- /dev/null +++ b/mpfr/tests/tcmp_d.c @@ -0,0 +1,130 @@ +/* Test file for mpfr_cmp_d. + +Copyright 1999, 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x; + mpfr_exp_t emin; + + tests_start_mpfr (); + emin = mpfr_get_emin (); + + mpfr_init2(x, IEEE_DBL_MANT_DIG); + + mpfr_set_d (x, 2.34763465, MPFR_RNDN); + if (mpfr_cmp_d(x, 2.34763465)!=0) { + printf("Error in mpfr_cmp_d 2.34763465 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + if (mpfr_cmp_d(x, 2.345)<=0) { + printf("Error in mpfr_cmp_d 2.345 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + if (mpfr_cmp_d(x, 2.4)>=0) { + printf("Error in mpfr_cmp_d 2.4 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_neg (x, x, MPFR_RNDZ); + if (mpfr_cmp_d (x, 0.0)) { + printf("Error in mpfr_cmp_d 0.0 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_ui_div (x, 1, x, MPFR_RNDU); + if (mpfr_cmp_d (x, 0.0) == 0) + { + printf ("Error in mpfr_cmp_d (Inf, 0)\n"); + exit (1); + } + + /* Test in reduced exponent range. */ + set_emin (1); + mpfr_set_ui (x, 1, MPFR_RNDN); + if (mpfr_cmp_d (x, 0.9) <= 0) + { + printf ("Error in reduced exponent range.\n"); + exit (1); + } + set_emin (emin); + +#if !defined(MPFR_ERRDIVZERO) + /* Check NAN */ + { + int c; + + mpfr_clear_flags (); + c = mpfr_cmp_d (x, DBL_NAN); + if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE) + { + printf ("ERROR for NAN (1)\n"); + printf ("Expected 0, got %d\n", c); + printf ("Expected flags:"); + flags_out (MPFR_FLAGS_ERANGE); + printf ("Got flags: "); + flags_out (__gmpfr_flags); +#ifdef MPFR_NANISNAN + printf ("The reason is that NAN == NAN. Please look at the configure " + "output\nand Section \"In case of problem\" of the INSTALL " + "file.\n"); +#endif + exit (1); + } + + mpfr_set_nan (x); + mpfr_clear_flags (); + c = mpfr_cmp_d (x, 2.0); + if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE) + { + printf ("ERROR for NAN (2)\n"); + printf ("Expected 0, got %d\n", c); + printf ("Expected flags:"); + flags_out (MPFR_FLAGS_ERANGE); + printf ("Got flags: "); + flags_out (__gmpfr_flags); +#ifdef MPFR_NANISNAN + printf ("The reason is that NAN == NAN. Please look at the configure " + "output\nand Section \"In case of problem\" of the INSTALL " + "file.\n"); +#endif + exit (1); + } + } +#endif /* MPFR_ERRDIVZERO */ + + mpfr_clear(x); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcmp_ld.c b/mpfr/tests/tcmp_ld.c new file mode 100644 index 0000000000..0f257bef62 --- /dev/null +++ b/mpfr/tests/tcmp_ld.c @@ -0,0 +1,131 @@ +/* Test file for mpfr_cmp_ld. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x; + mpfr_exp_t emin; + + tests_start_mpfr (); + emin = mpfr_get_emin (); + + mpfr_init2(x, MPFR_LDBL_MANT_DIG); + + mpfr_set_ld (x, 2.34763465L, MPFR_RNDN); + if (mpfr_cmp_ld(x, 2.34763465L)!=0) { + printf("Error in mpfr_cmp_ld 2.34763465 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + if (mpfr_cmp_ld(x, 2.345L)<=0) { + printf("Error in mpfr_cmp_ld 2.345 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + if (mpfr_cmp_ld(x, 2.4L)>=0) { + printf("Error in mpfr_cmp_ld 2.4 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_neg (x, x, MPFR_RNDZ); + if (mpfr_cmp_ld (x, 0.0)) { + printf("Error in mpfr_cmp_ld 0.0 and "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit(1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_ui_div (x, 1, x, MPFR_RNDU); + if (mpfr_cmp_ld (x, 0.0) == 0) + { + printf ("Error in mpfr_cmp_ld (Inf, 0)\n"); + exit (1); + } + + /* Test in reduced exponent range. */ + set_emin (1); + mpfr_set_ui (x, 1, MPFR_RNDN); + if (mpfr_cmp_ld (x, 0.9) <= 0) + { + printf ("Error in reduced exponent range.\n"); + exit (1); + } + set_emin (emin); + +#if !defined(MPFR_ERRDIVZERO) + /* Check NAN */ + { + int c; + + mpfr_clear_flags (); + c = mpfr_cmp_ld (x, DBL_NAN); + if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE) + { + printf ("ERROR for NAN (1)\n"); + printf ("Expected 0, got %d\n", c); + printf ("Expected flags:"); + flags_out (MPFR_FLAGS_ERANGE); + printf ("Got flags: "); + flags_out (__gmpfr_flags); +#ifdef MPFR_NANISNAN + printf ("The reason is that NAN == NAN. Please look at the configure " + "output\nand Section \"In case of problem\" of the INSTALL " + "file.\n"); +#endif + exit (1); + } + + mpfr_set_nan (x); + mpfr_clear_flags (); + c = mpfr_cmp_ld (x, 2.0); + if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE) + { + printf ("ERROR for NAN (2)\n"); + printf ("Expected 0, got %d\n", c); + printf ("Expected flags:"); + flags_out (MPFR_FLAGS_ERANGE); + printf ("Got flags: "); + flags_out (__gmpfr_flags); +#ifdef MPFR_NANISNAN + printf ("The reason is that NAN == NAN. Please look at the configure " + "output\nand Section \"In case of problem\" of the INSTALL " + "file.\n"); +#endif + exit (1); + } + } +#endif /* MPFR_ERRDIVZERO */ + + mpfr_clear(x); + + tests_end_mpfr (); + return 0; +} + + diff --git a/mpfr/tests/tcmp_ui.c b/mpfr/tests/tcmp_ui.c new file mode 100644 index 0000000000..c55a869460 --- /dev/null +++ b/mpfr/tests/tcmp_ui.c @@ -0,0 +1,346 @@ +/* Test file for mpfr_cmp_ui and mpfr_cmp_si. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef TCMP_UI_CHECK_NAN + +mpfr_clear_erangeflag (); +c = mpfr_cmp_si (x, TCMP_UI_CHECK_NAN); +if (c != 0 || !mpfr_erangeflag_p ()) + { + printf ("NaN error on %d (1)\n", TCMP_UI_CHECK_NAN); + exit (1); + } +mpfr_clear_erangeflag (); +c = (mpfr_cmp_si) (x, TCMP_UI_CHECK_NAN); +if (c != 0 || !mpfr_erangeflag_p ()) + { + printf ("NaN error on %d (2)\n", TCMP_UI_CHECK_NAN); + exit (1); + } +if (TCMP_UI_CHECK_NAN >= 0) + { + mpfr_clear_erangeflag (); + c = mpfr_cmp_ui (x, TCMP_UI_CHECK_NAN); + if (c != 0 || !mpfr_erangeflag_p ()) + { + printf ("NaN error on %d (3)\n", TCMP_UI_CHECK_NAN); + exit (1); + } + mpfr_clear_erangeflag (); + c = (mpfr_cmp_ui) (x, TCMP_UI_CHECK_NAN); + if (c != 0 || !mpfr_erangeflag_p ()) + { + printf ("NaN error on %d (4)\n", TCMP_UI_CHECK_NAN); + exit (1); + } + } + +#else + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check_nan (void) +{ + mpfr_t x; + int c, i; + + mpfr_init (x); + mpfr_set_nan (x); + /* We need constants to completely test the macros. */ +#undef TCMP_UI_CHECK_NAN +#define TCMP_UI_CHECK_NAN -17 +#include "tcmp_ui.c" +#undef TCMP_UI_CHECK_NAN +#define TCMP_UI_CHECK_NAN 0 +#include "tcmp_ui.c" +#undef TCMP_UI_CHECK_NAN +#define TCMP_UI_CHECK_NAN 17 +#include "tcmp_ui.c" + for (i = -17; i <= 17; i += 17) + { +#undef TCMP_UI_CHECK_NAN +#define TCMP_UI_CHECK_NAN i +#include "tcmp_ui.c" + } + mpfr_clear (x); +} + +/* Since mpfr_cmp_ui and mpfr_cmp_si are also implemented by a macro + with __builtin_constant_p for GCC, check that side effects are + handled correctly. */ +static void +check_macros (void) +{ + mpfr_t x; + int c; + + mpfr_init2 (x, 32); + + c = 0; + mpfr_set_ui (x, 17, MPFR_RNDN); + if (mpfr_cmp_ui (x, 17) != 0) + { + printf ("Error 1 on mpfr_cmp_ui(x,17) in check_macros\n"); + exit (1); + } + if (mpfr_cmp_ui (x, (c++, 17)) != 0) + { + printf ("Error 2 on mpfr_cmp_ui(x,17) in check_macros\n"); + exit (1); + } + if (c != 1) + { + printf ("Error 3 on mpfr_cmp_ui(x,17) in check_macros\n" + "(c = %d instead of 1)\n", c); + exit (1); + } + if (mpfr_cmp_si (x, 17) != 0) + { + printf ("Error 1 on mpfr_cmp_si(x,17) in check_macros\n"); + exit (1); + } + if (mpfr_cmp_si (x, (c++, 17)) != 0) + { + printf ("Error 2 on mpfr_cmp_si(x,17) in check_macros\n"); + exit (1); + } + if (c != 2) + { + printf ("Error 3 on mpfr_cmp_si(x,17) in check_macros\n" + "(c = %d instead of 2)\n", c); + exit (1); + } + + c = 0; + mpfr_set_ui (x, 0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) != 0) + { + printf ("Error 1 on mpfr_cmp_ui(x,0) in check_macros\n"); + exit (1); + } + if (mpfr_cmp_ui (x, (c++, 0)) != 0) + { + printf ("Error 2 on mpfr_cmp_ui(x,0) in check_macros\n"); + exit (1); + } + if (c != 1) + { + printf ("Error 3 on mpfr_cmp_ui(x,0) in check_macros\n" + "(c = %d instead of 1)\n", c); + exit (1); + } + if (mpfr_cmp_si (x, 0) != 0) + { + printf ("Error 1 on mpfr_cmp_si(x,0) in check_macros\n"); + exit (1); + } + if (mpfr_cmp_si (x, (c++, 0)) != 0) + { + printf ("Error 2 on mpfr_cmp_si(x,0) in check_macros\n"); + exit (1); + } + if (c != 2) + { + printf ("Error 3 on mpfr_cmp_si(x,0) in check_macros\n" + "(c = %d instead of 2)\n", c); + exit (1); + } + + mpfr_clear (x); +} + +/* Bug in r7114 */ +static void +test_macros (void) +{ + mpfr_t x[3]; + mpfr_ptr p; + + mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0); + mpfr_set_ui (x[0], 0, MPFR_RNDN); + p = x[0]; + if (mpfr_cmp_ui (p++, 0) != 0) + { + printf ("Error in mpfr_cmp_ui macro: result should be 0.\n"); + exit (1); + } + if (p != x[1]) + { + printf ("Error in mpfr_cmp_ui macro: p - x[0] = %d (expecting 1)\n", + (int) (p - x[0])); + exit (1); + } + p = x[0]; + if (mpfr_cmp_si (p++, 0) != 0) + { + printf ("Error in mpfr_cmp_si macro: result should be 0.\n"); + exit (1); + } + if (p != x[1]) + { + printf ("Error in mpfr_cmp_si macro: p - x[0] = %d (expecting 1)\n", + (int) (p - x[0])); + exit (1); + } + mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0); +} + +int +main (void) +{ + mpfr_t x; + unsigned long i; + long s; + + tests_start_mpfr (); + + mpfr_init(x); + + /* tests for cmp_ui */ + mpfr_set_ui (x, 3, MPFR_RNDZ); + if ((mpfr_cmp_ui) (x, i = 3) != 0) + { + printf ("Error in mpfr_cmp_ui(3.0, 3)\n"); + exit (1); + } + if (mpfr_cmp_ui (x, i = 2) <= 0) + { + printf ("Error in mpfr_cmp_ui(3.0,2)\n"); + exit (1); + } + if (mpfr_cmp_ui (x, i = 4) >= 0) + { + printf ("Error in mpfr_cmp_ui(3.0,4)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_neg (x, x, MPFR_RNDZ); + if (mpfr_cmp_ui (x, i = 0)) + { + printf ("Error in mpfr_cmp_ui(0.0,0)\n"); + exit (1); + } + mpfr_set_ui (x, 1, MPFR_RNDZ); + if (mpfr_cmp_ui (x, i = 0) == 0) + { + printf ("Error in mpfr_cmp_ui(1.0,0)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + if (mpfr_cmp_ui (x, 1) <= 0) + { + printf ("Error in mpfr_cmp_ui (Inf, 0)\n"); + exit (1); + } + mpfr_set_inf (x, -1); + if (mpfr_cmp_ui (x, 1) >= 0) + { + printf ("Error in mpfr_cmp_ui (-Inf, 0)\n"); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 1) < 0); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) < 0); + + mpfr_set_ui (x, 1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) > 0); + + /* tests for cmp_si */ + (mpfr_set_si) (x, -3, MPFR_RNDZ); + if ((mpfr_cmp_si) (x, s = -3) != 0) + { + printf ("Error in mpfr_cmp_si(-3.0,-3)\n"); + exit (1); + } + if (mpfr_cmp_si (x, s = -4) <= 0) + { + printf ("Error in mpfr_cmp_si(-3.0,-4)\n"); + exit (1); + } + if (mpfr_cmp_si (x, s = 1) >= 0) + { + printf ("Error in mpfr_cmp_si(-3.0,1)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + if (mpfr_cmp_si (x, -1) <= 0) + { + printf ("Error in mpfr_cmp_si (Inf, 0)\n"); + exit (1); + } + mpfr_set_inf (x, -1); + if (mpfr_cmp_si (x, -1) >= 0) + { + printf ("Error in mpfr_cmp_si (-Inf, 0)\n"); + exit (1); + } + + /* case b=0 */ + mpfr_set_ui (x, 0, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) == 0); + MPFR_ASSERTN(mpfr_cmp_si (x, 1) < 0); + MPFR_ASSERTN(mpfr_cmp_si (x, -1) > 0); + + /* case i=0 */ + mpfr_set_ui (x, 1, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) > 0); + mpfr_set_ui (x, 0, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) == 0); + mpfr_neg (x, x, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) == 0); + mpfr_set_si (x, -1, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) < 0); + + /* case large x */ + mpfr_set_str_binary (x, "1E100"); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) > 0); + MPFR_ASSERTN(mpfr_cmp_si (x, 1) > 0); + MPFR_ASSERTN(mpfr_cmp_si (x, -1) > 0); + mpfr_set_str_binary (x, "-1E100"); + MPFR_ASSERTN(mpfr_cmp_si (x, 0) < 0); + MPFR_ASSERTN(mpfr_cmp_si (x, 1) < 0); + MPFR_ASSERTN(mpfr_cmp_si (x, -1) < 0); + + /* corner case */ + mpfr_set_ui (x, 1, MPFR_RNDZ); + mpfr_mul_2exp (x, x, GMP_NUMB_BITS - 1, MPFR_RNDZ); + /* now EXP(x)=GMP_NUMB_BITS */ + MPFR_ASSERTN(mpfr_cmp_si (x, 1) > 0); + + mpfr_clear (x); + + check_nan (); + check_macros (); + test_macros (); + + tests_end_mpfr (); + return 0; +} + +#endif diff --git a/mpfr/tests/tcmpabs.c b/mpfr/tests/tcmpabs.c new file mode 100644 index 0000000000..09505ef0f6 --- /dev/null +++ b/mpfr/tests/tcmpabs.c @@ -0,0 +1,149 @@ +/* Test file for mpfr_cmpabs. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define ERROR(s) do { printf(s); exit(1); } while (0) + +int +main (void) +{ + mpfr_t xx, yy; + int c; + + tests_start_mpfr (); + + mpfr_init2 (xx, 2); + mpfr_init2 (yy, 2); + + mpfr_clear_erangeflag (); + MPFR_SET_NAN (xx); + MPFR_SET_NAN (yy); + if (mpfr_cmpabs (xx, yy) != 0) + ERROR ("mpfr_cmpabs (NAN,NAN) returns non-zero\n"); + if (!mpfr_erangeflag_p ()) + ERROR ("mpfr_cmpabs (NAN,NAN) doesn't set erange flag\n"); + + mpfr_set_str_binary (xx, "0.10E0"); + mpfr_set_str_binary (yy, "-0.10E0"); + if (mpfr_cmpabs (xx, yy) != 0) + ERROR ("mpfr_cmpabs (xx, yy) returns non-zero for prec=2\n"); + + mpfr_set_prec (xx, 65); + mpfr_set_prec (yy, 65); + mpfr_set_str_binary (xx, "-0.10011010101000110101010000000011001001001110001011101011111011101E623"); + mpfr_set_str_binary (yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); + if (mpfr_cmpabs (xx, yy) <= 0) + ERROR ("Error (1) in mpfr_cmpabs\n"); + + mpfr_set_str_binary (xx, "-0.10100010001110110111000010001000010011111101000100011101000011100"); + mpfr_set_str_binary (yy, "-0.10100010001110110111000010001000010011111101000100011101000011011"); + if (mpfr_cmpabs (xx, yy) <= 0) + ERROR ("Error (2) in mpfr_cmpabs\n"); + + mpfr_set_prec (xx, 160); + mpfr_set_prec (yy, 160); + mpfr_set_str_binary (xx, "0.1E1"); + mpfr_set_str_binary (yy, "-0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100"); + if (mpfr_cmpabs (xx, yy) <= 0) + ERROR ("Error (3) in mpfr_cmpabs\n"); + + mpfr_set_prec(xx, 53); + mpfr_set_prec(yy, 200); + mpfr_set_ui (xx, 1, (mpfr_rnd_t) 0); + mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0); + if (mpfr_cmpabs(xx, yy) != 0) + ERROR ("Error in mpfr_cmpabs: 1.0 != 1.0\n"); + + mpfr_set_prec (yy, 31); + mpfr_set_str (xx, "-1.0000000002", 10, (mpfr_rnd_t) 0); + mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0); + if (!(mpfr_cmpabs(xx,yy)>0)) + ERROR ("Error in mpfr_cmpabs: not 1.0000000002 > 1.0\n"); + mpfr_set_prec(yy, 53); + + mpfr_set_ui(xx, 0, MPFR_RNDN); + mpfr_set_str (yy, "-0.1", 10, MPFR_RNDN); + if (mpfr_cmpabs(xx, yy) >= 0) + ERROR ("Error in mpfr_cmpabs(0.0, 0.1)\n"); + + mpfr_set_inf (xx, -1); + mpfr_set_str (yy, "23489745.0329", 10, MPFR_RNDN); + if (mpfr_cmpabs(xx, yy) <= 0) + ERROR ("Error in mpfr_cmp(-Inf, 23489745.0329)\n"); + + mpfr_set_inf (xx, 1); + mpfr_set_inf (yy, -1); + if (mpfr_cmpabs(xx, yy) != 0) + ERROR ("Error in mpfr_cmpabs(Inf, -Inf)\n"); + + mpfr_set_inf (yy, -1); + mpfr_set_str (xx, "2346.09234", 10, MPFR_RNDN); + if (mpfr_cmpabs (xx, yy) >= 0) + ERROR ("Error in mpfr_cmpabs(-Inf, 2346.09234)\n"); + + mpfr_set_prec (xx, 2); + mpfr_set_prec (yy, 128); + mpfr_set_str_binary (xx, "0.1E10"); + mpfr_set_str_binary (yy, + "0.100000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000001E10"); + if (mpfr_cmpabs (xx, yy) >= 0) + ERROR ("Error in mpfr_cmpabs(10.235, 2346.09234)\n"); + mpfr_swap (xx, yy); + if (mpfr_cmpabs(xx, yy) <= 0) + ERROR ("Error in mpfr_cmpabs(2346.09234, 10.235)\n"); + mpfr_swap (xx, yy); + + /* Check for NAN */ + mpfr_set_nan (xx); + mpfr_clear_erangeflag (); + c = (mpfr_cmp) (xx, yy); + if (c != 0 || !mpfr_erangeflag_p () ) + { + printf ("NAN error (1)\n"); + exit (1); + } + mpfr_clear_erangeflag (); + c = (mpfr_cmp) (yy, xx); + if (c != 0 || !mpfr_erangeflag_p () ) + { + printf ("NAN error (2)\n"); + exit (1); + } + mpfr_clear_erangeflag (); + c = (mpfr_cmp) (xx, xx); + if (c != 0 || !mpfr_erangeflag_p () ) + { + printf ("NAN error (3)\n"); + exit (1); + } + + mpfr_clear (xx); + mpfr_clear (yy); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcomparisons.c b/mpfr/tests/tcomparisons.c new file mode 100644 index 0000000000..67feceef09 --- /dev/null +++ b/mpfr/tests/tcomparisons.c @@ -0,0 +1,131 @@ +/* Test file for mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p, + mpfr_lessequal_p, mpfr_lessgreater_p, mpfr_equal_p, mpfr_unordered_p + functions. + +Copyright 2003, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +cmp_tests (void) +{ + mpfr_t x, y; + long i; + + mpfr_inits (x, y, (mpfr_ptr) 0); + for (i = 0; i < 80000; i++) + { + mpfr_prec_t precx, precy; + int signx, signy, cmp; + unsigned int cmpbool = 0; + + precx = (randlimb () % 17) * 11 + MPFR_PREC_MIN; + precy = (randlimb () % 17) * 11 + MPFR_PREC_MIN; + mpfr_set_prec (x, precx); + mpfr_set_prec (y, precy); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + signx = randlimb () & 1; + signy = randlimb () % 256 ? signx : 1 - signx; + /* signy = signx most of the time (most interesting case) */ + if (signx) + mpfr_neg (x, x, MPFR_RNDN); + if (signy) + mpfr_neg (y, y, MPFR_RNDN); + if (i <= 1) + mpfr_set_nan (x); + if (i == 0 || i == 2) + mpfr_set_nan (y); + if (mpfr_greater_p (x, y)) + cmpbool |= 0x01; + if (mpfr_greaterequal_p (x, y)) + cmpbool |= 0x02; + if (mpfr_less_p (x, y)) + cmpbool |= 0x04; + if (mpfr_lessequal_p (x, y)) + cmpbool |= 0x08; + if (mpfr_lessgreater_p (x, y)) + cmpbool |= 0x10; + if (mpfr_equal_p (x, y)) + cmpbool |= 0x20; + if (mpfr_unordered_p (x, y)) + cmpbool |= 0x40; + if ((i <= 2 && cmpbool != 0x40) || + (i > 2 && (cmp = mpfr_cmp (x, y), + (cmp == 0 && cmpbool != 0x2a) || + (cmp < 0 && cmpbool != 0x1c) || + (cmp > 0 && cmpbool != 0x13)))) + { + printf ("Error in cmp_tests for\nx = "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" and\ny = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +static void +eq_tests (void) +{ + mpfr_t x, y; + long i; + + mpfr_inits (x, y, (mpfr_ptr) 0); + for (i = 0; i < 20000; i++) + { + mpfr_prec_t precx; + + precx = (randlimb () % 17) * 11 + MPFR_PREC_MIN; + mpfr_set_prec (x, precx); + mpfr_set_prec (y, precx + (randlimb () % 64)); + mpfr_urandomb (x, RANDS); + if (randlimb () & 1) + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set (y, x, MPFR_RNDN); /* exact -> x = y */ + if (mpfr_greater_p (x, y) || !mpfr_greaterequal_p (x, y) || + mpfr_less_p (x, y) || !mpfr_lessequal_p (x, y) || + mpfr_lessgreater_p (x, y) || !mpfr_equal_p (x, y) || + mpfr_unordered_p (x, y)) + { + printf ("Error in eq_tests for x = "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +int +main (void) +{ + tests_start_mpfr (); + cmp_tests (); + eq_tests (); + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tconst_catalan.c b/mpfr/tests/tconst_catalan.c new file mode 100644 index 0000000000..2615e961a5 --- /dev/null +++ b/mpfr/tests/tconst_catalan.c @@ -0,0 +1,59 @@ +/* Test file for mpfr_const_catalan. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include "mpfr-test.h" + +/* Wrapper for tgeneric */ +static int +my_const_catalan (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) +{ + return mpfr_const_catalan (x, r); +} + +#define RAND_FUNCTION(x) mpfr_set_ui(x,0,MPFR_RNDN) +#define TEST_FUNCTION my_const_catalan +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + + tests_start_mpfr (); + + mpfr_init2 (x, 32); + (mpfr_const_catalan) (x, MPFR_RNDN); + mpfr_mul_2exp (x, x, 32, MPFR_RNDN); + if (mpfr_cmp_ui (x, 3934042271UL)) + { + printf ("Error in const_catalan for prec=32\n"); + exit (1); + } + mpfr_clear (x); + + test_generic (2, 200, 1); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tconst_euler.c b/mpfr/tests/tconst_euler.c new file mode 100644 index 0000000000..fa625eff6f --- /dev/null +++ b/mpfr/tests/tconst_euler.c @@ -0,0 +1,116 @@ +/* Test file for mpfr_const_euler. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* Wrapper for tgeneric */ +static int +my_const_euler (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) +{ + return mpfr_const_euler (x, r); +} + +#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN) +#define TEST_FUNCTION my_const_euler +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t gamma, y, z, t; + unsigned int err, prec, yprec, p0 = 2, p1 = 200; + int rnd; + + tests_start_mpfr (); + + prec = (argc < 2) ? 53 : atoi(argv[1]); + + if (argc > 1) + { + mpfr_init2 (gamma, prec); + mpfr_const_euler (gamma, MPFR_RNDN); + printf("gamma="); mpfr_out_str (stdout, 10, 0, gamma, MPFR_RNDD); + puts (""); + mpfr_clear (gamma); + return 0; + } + + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + mpfr_set_prec (y, 32); + mpfr_set_prec (z, 32); + (mpfr_const_euler) (y, MPFR_RNDN); + mpfr_set_str_binary (z, "0.10010011110001000110011111100011"); + if (mpfr_cmp (y, z)) + { + printf ("Error for prec=32\n"); + exit (1); + } + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + mpfr_set_prec (y, yprec); + mpfr_const_euler (y, (mpfr_rnd_t) rnd); + err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, (mpfr_rnd_t) rnd, (mpfr_rnd_t) rnd, prec)) + { + mpfr_set (t, y, (mpfr_rnd_t) rnd); + mpfr_const_euler (z, (mpfr_rnd_t) rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + puts (""); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf (" approximation was "); + mpfr_print_binary (y); + puts (""); + exit (1); + } + } + } + } + + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + test_generic (2, 200, 1); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tconst_log2.c b/mpfr/tests/tconst_log2.c new file mode 100644 index 0000000000..340415b039 --- /dev/null +++ b/mpfr/tests/tconst_log2.c @@ -0,0 +1,201 @@ +/* Test file for mpfr_const_log2. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* tlog2 [prec] [rnd] [0 = no print] */ + +static void +check (mpfr_prec_t p0, mpfr_prec_t p1) +{ + mpfr_t x, y, z; + mpfr_rnd_t rnd; + int dif; + + mpfr_init (x); + mpfr_init (y); + mpfr_init2 (z, p1 + 10); + mpfr_const_log2 (z, MPFR_RNDN); + mpfr_clear_cache (__gmpfr_cache_const_log2); + + for (; p0<=p1; p0++) + { + mpfr_set_prec (x, p0); + mpfr_set_prec (y, p0); + { + rnd = RND_RAND (); + mpfr_const_log2 (x, rnd); + mpfr_set (y, z, rnd); + if ((dif = mpfr_cmp (x, y)) + && mpfr_can_round (z, mpfr_get_prec(z), MPFR_RNDN, + rnd, p0)) + { + printf ("mpfr_const_log2 fails for prec=%u, rnd=%s Diff=%d\n", + (unsigned int) p0, mpfr_print_rnd_mode (rnd), dif); + printf ("expected "), mpfr_dump (y); + printf ("got "), mpfr_dump (x); + exit (1); + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_large (void) +{ + mpfr_t x, y; + mpfr_init2 (x, 25000); + mpfr_init2 (y, 26000); + (mpfr_const_log2) (x, MPFR_RNDN); /* First one ! */ + (mpfr_const_log2) (y, MPFR_RNDN); /* Then the other - cache - */ + mpfr_prec_round (y, 25000, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("const_log2: error for large prec\n"); + exit (1); + } + + /* worst-case with 15 successive ones after last bit, + to exercise can_round loop */ + mpfr_set_prec (x, 26249); + mpfr_const_log2 (x, MPFR_RNDZ); + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +static void +check_cache (void) +{ + mpfr_t x; + int i; + + mpfr_init2 (x, 195); + mpfr_free_cache (); + i = mpfr_const_log2 (x, MPFR_RNDN); + if (i == 0) + { + printf("Error for log2. Invalid ternary value (1).\n"); + exit (1); + } + mpfr_set_prec (x, 194); + i = mpfr_const_log2 (x, MPFR_RNDN); + if (i == 0) + { + printf("Error for log2. Invalid ternary value (2).\n"); + exit (1); + } + + mpfr_free_cache (); + mpfr_set_prec (x, 9); + mpfr_const_log2 (x, MPFR_RNDN); + mpfr_set_prec (x, 8); + mpfr_const_log2 (x, MPFR_RNDN); + if (mpfr_cmp_str (x, "0.10110001E0", 2, MPFR_RNDN)) + { + printf("Error for log2. Wrong rounding.\n"); + exit (1); + } + + mpfr_clear (x); +} + +/* Wrapper for tgeneric */ +static int +my_const_log2 (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) +{ + return mpfr_const_log2 (x, r); +} + +#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN) +#define TEST_FUNCTION my_const_log2 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + int p; + mpfr_rnd_t rnd; + + tests_start_mpfr (); + + p = (argc>1) ? atoi(argv[1]) : 53; + rnd = (argc>2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ; + + mpfr_init (x); + + check (2, 1000); + + /* check precision of 2 bits */ + mpfr_set_prec (x, 2); + mpfr_const_log2 (x, MPFR_RNDN); + if (mpfr_cmp_ui_2exp(x, 3, -2)) /* 3*2^-2 */ + { + printf ("mpfr_const_log2 failed for prec=2, rnd=MPFR_RNDN\n" + "expected 0.75, got "); + mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); + putchar('\n'); + exit (1); + } + + if (argc>=2) + { + mpfr_set_prec (x, p); + mpfr_const_log2 (x, rnd); + printf ("log(2)="); + mpfr_out_str (stdout, 10, 0, x, rnd); + puts (""); + } + + mpfr_set_prec (x, 53); + mpfr_const_log2 (x, MPFR_RNDZ); + if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") ) + { + printf ("mpfr_const_log2 failed for prec=53\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_const_log2 (x, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "0.69314718060195446")) + { + printf ("mpfr_const_log2 failed for prec=32\n"); + exit (1); + } + + mpfr_clear(x); + + check_large(); + check_cache (); + + test_generic (2, 200, 1); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tconst_pi.c b/mpfr/tests/tconst_pi.c new file mode 100644 index 0000000000..a64cadeacc --- /dev/null +++ b/mpfr/tests/tconst_pi.c @@ -0,0 +1,186 @@ +/* Test file for mpfr_const_pi. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* tconst_pi [prec] [rnd] [0 = no print] */ + +static void +check_large (void) +{ + mpfr_t x, y, z; + + mpfr_init2 (x, 20000); + mpfr_init2 (y, 21000); + mpfr_init2 (z, 11791); + + /* The algo failed to round for p=11791. */ + (mpfr_const_pi) (z, MPFR_RNDU); + mpfr_const_pi (x, MPFR_RNDN); /* First one ! */ + mpfr_const_pi (y, MPFR_RNDN); /* Then the other - cache - */ + mpfr_prec_round (y, 20000, MPFR_RNDN); + if (mpfr_cmp (x, y)) { + printf ("const_pi: error for large prec (%d)\n", 1); + exit (1); + } + mpfr_prec_round (y, 11791, MPFR_RNDU); + if (mpfr_cmp (z, y)) { + printf ("const_pi: error for large prec (%d)\n", 2); + exit (1); + } + + /* a worst-case to exercise recomputation */ + if (MPFR_PREC_MAX > 33440) { + mpfr_set_prec (x, 33440); + mpfr_const_pi (x, MPFR_RNDZ); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +/* Wrapper for tgeneric */ +static int +my_const_pi (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) +{ + return mpfr_const_pi (x, r); +} + +#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN) +#define TEST_FUNCTION my_const_pi +#include "tgeneric.c" + +static void +bug20091030 (void) +{ + mpfr_t x, x_ref; + int inex, inex_ref; + mpfr_prec_t p; + int r; + + mpfr_free_cache (); + mpfr_init2 (x, MPFR_PREC_MIN); + for (p = MPFR_PREC_MIN; p <= 100; p++) + { + mpfr_set_prec (x, p); + inex = mpfr_const_pi (x, MPFR_RNDU); + if (inex < 0) + { + printf ("Error, inex < 0 for RNDU (prec=%lu)\n", + (unsigned long) p); + exit (1); + } + inex = mpfr_const_pi (x, MPFR_RNDD); + if (inex > 0) + { + printf ("Error, inex > 0 for RNDD (prec=%lu)\n", + (unsigned long) p); + exit (1); + } + } + mpfr_free_cache (); + mpfr_init2 (x_ref, MPFR_PREC_MIN); + for (p = MPFR_PREC_MIN; p <= 100; p++) + { + mpfr_set_prec (x, p + 10); + mpfr_const_pi (x, MPFR_RNDN); + mpfr_set_prec (x, p); + mpfr_set_prec (x_ref, p); + for (r = 0; r < MPFR_RND_MAX; r++) + { + inex = mpfr_const_pi (x, (mpfr_rnd_t) r); + inex_ref = mpfr_const_pi_internal (x_ref, (mpfr_rnd_t) r); + if (inex != inex_ref || mpfr_cmp (x, x_ref) != 0) + { + printf ("mpfr_const_pi and mpfr_const_pi_internal disagree\n"); + printf ("mpfr_const_pi gives "); + mpfr_dump (x); + printf ("mpfr_const_pi_internal gives "); + mpfr_dump (x_ref); + printf ("inex=%d inex_ref=%d\n", inex, inex_ref); + exit (1); + } + } + } + mpfr_clear (x); + mpfr_clear (x_ref); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + mpfr_prec_t p; + mpfr_rnd_t rnd; + + tests_start_mpfr (); + + p = 53; + if (argc > 1) + { + long a = atol (argv[1]); + if (a >= MPFR_PREC_MIN && a <= MPFR_PREC_MAX) + p = a; + } + + rnd = (argc > 2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ; + + mpfr_init2 (x, p); + mpfr_const_pi (x, rnd); + if (argc >= 2) + { + if (argc < 4 || atoi (argv[3]) != 0) + { + printf ("Pi="); + mpfr_out_str (stdout, 10, 0, x, rnd); + puts (""); + } + } + else if (mpfr_cmp_str1 (x, "3.141592653589793116") ) + { + printf ("mpfr_const_pi failed for prec=53\n"); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n'); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_const_pi (x, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "3.141592653468251") ) + { + printf ("mpfr_const_pi failed for prec=32\n"); + exit (1); + } + + mpfr_clear (x); + + bug20091030 (); + + check_large (); + + test_generic (2, 200, 1); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tcopysign.c b/mpfr/tests/tcopysign.c new file mode 100644 index 0000000000..c6f7628b79 --- /dev/null +++ b/mpfr/tests/tcopysign.c @@ -0,0 +1,116 @@ +/* Test file for mpfr_copysign, mpfr_setsign and mpfr_signbit. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +copysign_variant (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, + mpfr_rnd_t rnd_mode, int k) +{ + mpfr_clear_flags (); + switch (k) + { + case 0: + mpfr_copysign (z, x, y, MPFR_RNDN); + return; + case 1: + (mpfr_copysign) (z, x, y, MPFR_RNDN); + return; + case 2: + mpfr_setsign (z, x, mpfr_signbit (y), MPFR_RNDN); + return; + case 3: + mpfr_setsign (z, x, (mpfr_signbit) (y), MPFR_RNDN); + return; + case 4: + (mpfr_setsign) (z, x, mpfr_signbit (y), MPFR_RNDN); + return; + case 5: + (mpfr_setsign) (z, x, (mpfr_signbit) (y), MPFR_RNDN); + return; + } +} + +int +main (void) +{ + mpfr_t x, y, z; + int i, j, k; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + for (i = 0; i <= 1; i++) + for (j = 0; j <= 1; j++) + for (k = 0; k <= 5; k++) + { + mpfr_set_nan (x); + i ? MPFR_SET_NEG (x) : MPFR_SET_POS (x); + mpfr_set_nan (y); + j ? MPFR_SET_NEG (y) : MPFR_SET_POS (y); + copysign_variant (z, x, y, MPFR_RNDN, k); + if (MPFR_SIGN (z) != MPFR_SIGN (y) || !mpfr_nanflag_p ()) + { + printf ("Error in mpfr_copysign (%cNaN, %cNaN)\n", + i ? '-' : '+', j ? '-' : '+'); + exit (1); + } + + mpfr_set_si (x, i ? -1250 : 1250, MPFR_RNDN); + mpfr_set_nan (y); + j ? MPFR_SET_NEG (y) : MPFR_SET_POS (y); + copysign_variant (z, x, y, MPFR_RNDN, k); + if (i != j) + mpfr_neg (x, x, MPFR_RNDN); + if (! mpfr_equal_p (z, x) || mpfr_nanflag_p ()) + { + printf ("Error in mpfr_copysign (%c1250, %cNaN)\n", + i ? '-' : '+', j ? '-' : '+'); + exit (1); + } + + mpfr_set_si (x, i ? -1250 : 1250, MPFR_RNDN); + mpfr_set_si (y, j ? -1717 : 1717, MPFR_RNDN); + copysign_variant (z, x, y, MPFR_RNDN, k); + if (i != j) + mpfr_neg (x, x, MPFR_RNDN); + if (! mpfr_equal_p (z, x) || mpfr_nanflag_p ()) + { + printf ("Error in mpfr_copysign (%c1250, %c1717)\n", + i ? '-' : '+', j ? '-' : '+'); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcos.c b/mpfr/tests/tcos.c new file mode 100644 index 0000000000..5ce4ccb1f8 --- /dev/null +++ b/mpfr/tests/tcos.c @@ -0,0 +1,383 @@ +/* Test file for mpfr_cos. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_cos (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_cos (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_cos mpfr_cos +#endif + +static void +check53 (const char *xs, const char *cos_xs, mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, c; + + mpfr_inits2 (53, xx, c, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); /* should be exact */ + test_cos (c, xx, rnd_mode); + if (mpfr_cmp_str1 (c, cos_xs)) + { + printf ("mpfr_cos failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode (rnd_mode)); + printf ("mpfr_cos gives cos(x)="); + mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN); + printf(", expected %s\n", cos_xs); + exit (1); + } + mpfr_clears (xx, c, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION test_cos +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +static void +check_nans (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + test_cos (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: cos(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + test_cos (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: cos(Inf) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + test_cos (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: cos(-Inf) != NaN\n"); + exit (1); + } + + /* cos(+/-0) = 1 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + test_cos (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cos(+0) != 1\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + test_cos (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cos(-0) != 1\n"); + exit (1); + } + + /* Compute ~Pi/2 to check */ + /* FIXME: Too slow! + mpfr_set_prec (x, 20000); + mpfr_const_pi (x, MPFR_RNDD); mpfr_div_2ui (x, x, 1, MPFR_RNDN); + mpfr_set_prec (y, 24); + test_cos (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.111001010110100011000001E-20000", 2, MPFR_RNDN)) + { + printf("Error computing cos(~Pi/2)\n"); + mpfr_dump (y); + exit (1); + } */ + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +special_overflow (void) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init2 (x, 24); + mpfr_init2 (y, 73); + + /* Check special case: An overflow in const_pi could occurs! */ + set_emin (-125); + set_emax (128); + mpfr_set_str_binary (x, "0.111101010110110011101101E6"); + test_cos (y, x, MPFR_RNDZ); + set_emin (emin); + set_emax (emax); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +overflowed_cos0 (void) +{ + mpfr_t x, y; + int emax, i, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (emax); /* 1 is not representable. */ + /* and if emax < 0, 1 - eps is not representable either. */ + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_cos (x, x, (mpfr_rnd_t) rnd); + if ((i == 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && + ! mpfr_overflow_p ()) + { + printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n" + " The overflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +static void +bug20091030 (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 5); + mpfr_init2 (y, 2); + mpfr_set_str (x, "-0.11001E3", 2, MPFR_RNDN); + mpfr_cos (y, x, MPFR_RNDN); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + int inex; + + tests_start_mpfr (); + + special_overflow (); + check_nans (); + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 2); + mpfr_set_str (x, "9.81333845856942e-1", 10, MPFR_RNDN); + test_cos (y, x, MPFR_RNDN); + + mpfr_set_prec (x, 30); + mpfr_set_prec (y, 30); + mpfr_set_str_binary (x, "1.00001010001101110010100010101e-1"); + test_cos (y, x, MPFR_RNDU); + mpfr_set_str_binary (x, "1.10111100010101011110101010100e-1"); + if (mpfr_cmp (y, x)) + { + printf ("Error for prec=30, rnd=MPFR_RNDU\n"); + printf ("expected "); mpfr_print_binary (x); puts (""); + printf (" got "); mpfr_print_binary (y); puts (""); + exit (1); + } + + mpfr_set_prec (x, 59); + mpfr_set_prec (y, 59); + mpfr_set_str_binary (x, "1.01101011101111010011111110111111111011011101100111100011e-3"); + test_cos (y, x, MPFR_RNDU); + mpfr_set_str_binary (x, "1.1111011111110010001001001011100111101110100010000010010011e-1"); + if (mpfr_cmp (y, x)) + { + printf ("Error for prec=59, rnd=MPFR_RNDU\n"); + printf ("expected "); mpfr_print_binary (x); puts (""); + printf (" got "); mpfr_print_binary (y); puts (""); + exit (1); + } + + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_str_binary (x, "1.1100e-2"); + test_cos (y, x, MPFR_RNDD); + mpfr_set_str_binary (x, "1.1100e-1"); + if (mpfr_cmp (y, x)) + { + printf ("Error for x=1.1100e-2, rnd=MPFR_RNDD\n"); + printf ("expected 1.1100e-1, got "); mpfr_print_binary (y); puts (""); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.10001000001001011000100001E-6"); + mpfr_set_str_binary (y, "0.1111111111111101101111001100001"); + test_cos (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for prec=32 (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.1101011110111100111010011001011E-1"); + mpfr_set_str_binary (y, "0.11101001100110111011011010100011"); + test_cos (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for prec=32 (2)\n"); + exit (1); + } + + /* huge argument reduction */ + mpfr_set_str_binary (x, "0.10000010000001101011101111001011E40"); + mpfr_set_str_binary (y, "0.10011000001111010000101011001011E-1"); + test_cos (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for prec=32 (3)\n"); + exit (1); + } + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 3); + mpfr_set_str_binary (x, "0.110E60"); + inex = mpfr_cos (y, x, MPFR_RNDD); + MPFR_ASSERTN(inex < 0); + + /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */ + check53 ("4.984987858808754279e-1", "8.783012931285841817e-1", MPFR_RNDN); + check53 ("4.984987858808754279e-1", "8.783012931285840707e-1", MPFR_RNDD); + check53 ("4.984987858808754279e-1", "8.783012931285840707e-1", MPFR_RNDZ); + check53 ("4.984987858808754279e-1", "8.783012931285841817e-1", MPFR_RNDU); + check53 ("1.00031274099908640274", "0.540039116973283217504", MPFR_RNDN); + check53 ("1.00229256850978698523", "0.538371757797526551137", MPFR_RNDZ); + check53 ("1.00288304857059840103", "0.537874062022526966409", MPFR_RNDZ); + check53 ("1.00591265847407274059", "0.53531755997839769456", MPFR_RNDN); + + check53 ("1.00591265847407274059", "0.53531755997839769456", MPFR_RNDN); + + overflowed_cos0 (); + test_generic (2, 100, 15); + + /* check inexact flag */ + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 13); + mpfr_set_str_binary (x, "-0.100E196"); + inex = mpfr_cos (y, x, MPFR_RNDU); + mpfr_set_prec (x, 13); + mpfr_set_str_binary (x, "0.1111111100101"); + MPFR_ASSERTN (inex > 0 && mpfr_equal_p (x, y)); + + mpfr_clear (x); + mpfr_clear (y); + + bug20091030 (); + + data_check ("data/cos", mpfr_cos, "mpfr_cos"); + bad_cases (mpfr_cos, mpfr_acos, "mpfr_cos", 256, -40, 0, 4, 128, 800, 50); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcosh.c b/mpfr/tests/tcosh.c new file mode 100644 index 0000000000..1e08704f38 --- /dev/null +++ b/mpfr/tests/tcosh.c @@ -0,0 +1,204 @@ +/* Test file for mpfr_cosh. + +Copyright 2001-2002, 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_cosh +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int i; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_cosh (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: cosh(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_cosh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: cosh(+Inf) != +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_cosh (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: cosh(-Inf) != +Inf\n"); + exit (1); + } + + /* cosh(+/-0) = 1 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_cosh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cosh(+0) != 1\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_cosh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cosh(-0) != 1\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1101110111111111001011101000101"); + mpfr_set_str_binary (y, "1.0110011001110000101100011001001"); + mpfr_cosh (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_cosh for prec=32 (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.1110111000011101010111100000101E-1"); + mpfr_set_str_binary (y, "1.0001110000101111111111100110101"); + mpfr_cosh (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_cosh for prec=32 (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_clear_flags (); + mpfr_set_str_binary (x, "1E1000000000"); + i = mpfr_cosh (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1E1000000000"); + i = mpfr_cosh (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1E1000000000"); + i = mpfr_cosh (x, x, MPFR_RNDD); + MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == -1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1E1000000000"); + i = mpfr_cosh (x, x, MPFR_RNDU); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +special_overflow (void) +{ + /* Check for overflow in 3 cases: + 1. cosh(x) is representable, but not exp(x) + 2. cosh(x) is not representable in the selected range of exp. + 3. cosh(x) exp overflow even with the largest range of exp */ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + + mpfr_init2 (x, 24); + mpfr_init2 (y, 24); + + mpfr_set_str_binary (x, "0.101100100000000000110100E7"); + mpfr_cosh (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.101010001111001010001110E128", 2, MPFR_RNDN)) + { + printf("Special overflow error 1.\n"); + mpfr_dump (y); + exit (1); + } + + mpfr_set_str_binary (x, "0.101100100000000000110100E8"); + mpfr_cosh (y, x, MPFR_RNDN); + if (!mpfr_inf_p(y)) + { + printf("Special overflow error 2.\n"); + mpfr_dump (y); + exit (1); + } + + set_emin (emin); + set_emax (emax); + + mpfr_set_str_binary (x, "0.101100100000000000110100E1000000"); + mpfr_cosh (y, x, MPFR_RNDN); + if (!mpfr_inf_p(y)) + { + printf("Special overflow error 3.\n"); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special_overflow (); + special (); + + test_generic (2, 100, 100); + + data_check ("data/cosh", mpfr_cosh, "mpfr_cosh"); + bad_cases (mpfr_cosh, mpfr_acosh, "mpfr_cosh", 0, 1, 255, 4, 128, 800, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcot.c b/mpfr/tests/tcot.c new file mode 100644 index 0000000000..71acf0c339 --- /dev/null +++ b/mpfr/tests/tcot.c @@ -0,0 +1,144 @@ +/* Test file for mpfr_cot. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_cot +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_cot (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: cot(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_cot (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: cot(Inf) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_cot (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: cot(-Inf) != NaN\n"); + exit (1); + } + + /* cot(+/-0) = +/-Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_cot (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0)) + { + printf ("Error: cot(+0) != +Inf\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_cot (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0)) + { + printf ("Error: cot(-0) != -Inf\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +two2emin (mpfr_exp_t e) +{ + mpfr_exp_t old_emin, old_emax; + mpfr_t x, y; + int i, rnd; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + if (mpfr_set_emin (-e) || mpfr_set_emax (e)) + { + printf ("Can't change exponent range\n"); + exit (1); + } + + mpfr_inits2 (53, x, y, (mpfr_ptr) 0); + for (i = -4; i <= 4; i++) + RND_LOOP (rnd) + { + mpfr_set_si (y, i, MPFR_RNDN); + mpfr_ui_div (y, 1, y, (mpfr_rnd_t) rnd); /* no overflow/underflow */ + mpfr_set_si_2exp (x, i, -e, MPFR_RNDN); + if (ABS (i) != 3) /* not a power of 2 (not 0 either) */ + mpfr_sub (y, y, x, (mpfr_rnd_t) rnd); /* no overflow/underflow */ + mpfr_set_ui_2exp (x, 1, -e, MPFR_RNDN); + mpfr_div (y, y, x, (mpfr_rnd_t) rnd); /* 1/x - SIGN(x).epsilon */ + mpfr_set_si_2exp (x, i, -e, MPFR_RNDN); + mpfr_cot (x, x, (mpfr_rnd_t) rnd); + if (! mpfr_equal_p (x, y)) + { + printf ("Error in two2emin for i = %d and rnd = %s\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Got "); + mpfr_dump (x); + printf ("instead of "); + mpfr_dump (y); + exit (1); + } + } + mpfr_clears (x, y, (mpfr_ptr) 0); + + mpfr_set_emin (old_emin); + mpfr_set_emax (old_emax); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_specials (); + two2emin (256); + two2emin (MPFR_EMAX_DEFAULT); + if (MPFR_EMAX_MAX != MPFR_EMAX_DEFAULT) + two2emin (MPFR_EMAX_MAX); + test_generic (2, 200, 5); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcoth.c b/mpfr/tests/tcoth.c new file mode 100644 index 0000000000..45039d522e --- /dev/null +++ b/mpfr/tests/tcoth.c @@ -0,0 +1,213 @@ +/* Test file for mpfr_coth. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_coth +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_coth (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: coth(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_coth (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: coth(Inf) != 1\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_coth (y, x, MPFR_RNDN); + if (mpfr_cmp_si (y, -1)) + { + printf ("Error: coth(-Inf) != -1\n"); + exit (1); + } + + /* coth(+/-0) = +/-Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_coth (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error: coth(+0) != +Inf\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_coth (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && MPFR_SIGN (y) < 0)) + { + printf ("Error: coth(-0) != -Inf\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_bugs (void) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + /* bug found by Rob (Sisyphus) on 16 Sep 2005 */ + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_set_prec (y, 2); + mpfr_coth (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error for coth(2), expected 1, got "); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_str (x, "18.368400284838550", 10, MPFR_RNDN); + mpfr_set_str (y, "1.0000000000000002", 10, MPFR_RNDN); + mpfr_coth (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for coth(18.368400284838550)\n"); + exit (1); + } + + mpfr_set_str (x, "18.714973875118520", 10, MPFR_RNDN); + mpfr_coth (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for coth(18.714973875118520)\n"); + exit (1); + } + + mpfr_set_str (x, "18.714973875118524", 10, MPFR_RNDN); + mpfr_coth (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1) != 0) + { + printf ("Error for coth(18.714973875118524)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +underflowed_cothinf (void) +{ + mpfr_t x, y; + int i, inex, rnd, err = 0; + mpfr_exp_t old_emin; + + old_emin = mpfr_get_emin (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (i = -1; i <= 1; i += 2) + RND_LOOP (rnd) + { + mpfr_set_inf (x, i); + mpfr_clear_flags (); + set_emin (2); /* 1 is not representable. */ + inex = mpfr_coth (x, x, (mpfr_rnd_t) rnd); + set_emin (old_emin); + if (! mpfr_underflow_p ()) + { + printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" + " The underflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + mpfr_set_si (y, (i < 0 && (rnd == MPFR_RNDD || rnd == MPFR_RNDA)) || + (i > 0 && (rnd == MPFR_RNDU || rnd == MPFR_RNDA)) + ? 2 : 0, MPFR_RNDN); + if (i < 0) + mpfr_neg (y, y, MPFR_RNDN); + if (! (mpfr_equal_p (x, y) && + MPFR_MULT_SIGN (MPFR_SIGN (x), MPFR_SIGN (y)) > 0)) + { + printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of "); + mpfr_print_binary (y); + printf (".\n"); + err = 1; + } + if ((rnd == MPFR_RNDD || + (i > 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex >= 0) + { + printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if ((rnd == MPFR_RNDU || + (i < 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex <= 0) + { + printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_specials (); + check_bugs (); + test_generic (2, 200, 10); + underflowed_cothinf (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcsc.c b/mpfr/tests/tcsc.c new file mode 100644 index 0000000000..d390110f10 --- /dev/null +++ b/mpfr/tests/tcsc.c @@ -0,0 +1,95 @@ +/* Test file for mpfr_csc. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_csc +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_csc (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: csc(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_csc (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: csc(Inf) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_csc (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: csc(-Inf) != NaN\n"); + exit (1); + } + + /* csc(+/-0) = +/-Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_csc (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0)) + { + printf ("Error: csc(+0) != +Inf\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_csc (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0)) + { + printf ("Error: csc(-0) != -Inf\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_specials (); + + test_generic (2, 100, 10); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tcsch.c b/mpfr/tests/tcsch.c new file mode 100644 index 0000000000..348a3c9cb6 --- /dev/null +++ b/mpfr/tests/tcsch.c @@ -0,0 +1,110 @@ +/* Test file for mpfr_csch. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_csch +#define TEST_RANDOM_EMAX 63 +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_csch (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: csch(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_csch (y, x, MPFR_RNDN); + if (! (mpfr_zero_p (y) && MPFR_SIGN (y) >0)) + { + printf ("Error: csch(+Inf) != +0\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_csch (y, x, MPFR_RNDN); + if (! (mpfr_zero_p (y) && MPFR_SIGN (y) <0)) + { + printf ("Error: csch(-0) != -0\n"); + exit (1); + } + + /* csc(+/-0) = +/-Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_csch (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0)) + { + printf ("Error: csch(+0) != +Inf\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_csch (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0)) + { + printf ("Error: csch(-0) != -Inf\n"); + exit (1); + } + + /* check huge x */ + mpfr_set_str (x, "8e8", 10, MPFR_RNDN); + mpfr_csch (y, x, MPFR_RNDN); + if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error: csch(8e8) != +0\n"); + exit (1); + } + mpfr_set_str (x, "-8e8", 10, MPFR_RNDN); + mpfr_csch (y, x, MPFR_RNDN); + if (! (mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) + { + printf ("Error: csch(-8e8) != -0\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_specials (); + test_generic (2, 200, 10); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/td_div.c b/mpfr/tests/td_div.c new file mode 100644 index 0000000000..9316b4a25a --- /dev/null +++ b/mpfr/tests/td_div.c @@ -0,0 +1,209 @@ +/* Test file for mpfr_d_div + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check_nans (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + /* 1.0 / nan is nan */ + mpfr_set_nan (x); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* 1.0 / +inf == +0 */ + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_zero_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* 1.0 / -inf == -0 */ + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_zero_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + +#if !defined(MPFR_ERRDIVZERO) + + /* 1.0 / 0 == +inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* -1.0 / 0 == -inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, -1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + /* 1.0 / -0 == -inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + /* -1.0 / -0 == +inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, -1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* +inf / 0 == +inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, DBL_POS_INF, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* -inf / 0 == -inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, DBL_NEG_INF, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + /* +inf / -0 == -inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, DBL_POS_INF, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + /* -inf / -0 == +inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_d_div (y, DBL_NEG_INF, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + +#endif + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_d_div +#define DOUBLE_ARG1 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z; + double d; + int inexact; + + tests_start_mpfr (); + + /* check with enough precision */ + mpfr_init2 (x, IEEE_DBL_MANT_DIG); + mpfr_init2 (y, IEEE_DBL_MANT_DIG); + mpfr_init2 (z, IEEE_DBL_MANT_DIG); + + mpfr_set_str (y, "4096", 10, MPFR_RNDN); + d = 0.125; + mpfr_clear_flags (); + inexact = mpfr_d_div (x, d, y, MPFR_RNDN); + if (inexact != 0) + { + printf ("Inexact flag error in mpfr_d_div\n"); + exit (1); + } + mpfr_set_str (z, " 0.000030517578125", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_d_div ("); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + check_nans (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/td_sub.c b/mpfr/tests/td_sub.c new file mode 100644 index 0000000000..7708343008 --- /dev/null +++ b/mpfr/tests/td_sub.c @@ -0,0 +1,129 @@ +/* Test file for mpfr_d_sub + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check_nans (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + /* 1.0 - nan is nan */ + mpfr_set_nan (x); + mpfr_clear_flags (); + inexact = mpfr_d_sub (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* 1.0 - +inf == -inf */ + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + inexact = mpfr_d_sub (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + /* 1.0 - -inf == +inf */ + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + inexact = mpfr_d_sub (y, 1.0, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_d_sub +#define DOUBLE_ARG1 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z; + double d; + int inexact; + + tests_start_mpfr (); + + /* check with enough precision */ + mpfr_init2 (x, IEEE_DBL_MANT_DIG); + mpfr_init2 (y, IEEE_DBL_MANT_DIG); + mpfr_init2 (z, IEEE_DBL_MANT_DIG); + + mpfr_set_str (y, "4096", 10, MPFR_RNDN); + d = 0.125; + mpfr_clear_flags (); + inexact = mpfr_d_sub (x, d, y, MPFR_RNDN); + if (inexact != 0) + { + printf ("Inexact flag error in mpfr_d_sub\n"); + exit (1); + } + mpfr_set_str (z, "-4095.875", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_d_sub ("); + mpfr_out_str (stdout, 10, 7, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + check_nans (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tdigamma.c b/mpfr/tests/tdigamma.c new file mode 100644 index 0000000000..4609fbb72a --- /dev/null +++ b/mpfr/tests/tdigamma.c @@ -0,0 +1,68 @@ +/* test file for digamma function + +Copyright 2009-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_digamma +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_inf (y, -1); + mpfr_set_inf (x, 1); + mpfr_digamma (y, x, MPFR_RNDN); + if (mpfr_inf_p (y) == 0 || mpfr_sgn (y) < 0) + { + printf ("error for Psi(+Inf)\n"); + printf ("expected +Inf\n"); + printf ("got "); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 2); + + data_check ("data/digamma", mpfr_digamma, "mpfr_digamma"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tdim.c b/mpfr/tests/tdim.c new file mode 100644 index 0000000000..f7420b4de0 --- /dev/null +++ b/mpfr/tests/tdim.c @@ -0,0 +1,114 @@ +/* Test file for mpfr_dim. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_dim +#define TWO_ARGS +#define TEST_RANDOM_EMIN -20 +#define TEST_RANDOM_EMAX 20 +#define TGENERIC_NOWARNING 1 +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + /* case x=NaN */ + mpfr_set_nan (x); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_dim (z, x, y, MPFR_RNDN); + if (!mpfr_nan_p (z)) + { + printf ("Error in mpfr_dim (NaN, 0)\n"); + exit (1); + } + + /* case x=+Inf */ + mpfr_set_inf (x, 1); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_dim (z, x, y, MPFR_RNDN); + if (!mpfr_inf_p (z) || mpfr_sgn (z) < 0) + { + printf ("Error in mpfr_dim (+Inf, 0)\n"); + exit (1); + } + + /* case x=-Inf */ + mpfr_set_inf (x, -1); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_dim (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0) || mpfr_sgn (z) < 0) + { + printf ("Error in mpfr_dim (-Inf, 0)\n"); + exit (1); + } + + /* case x=y=+Inf */ + mpfr_set_inf (x, 1); + mpfr_set_inf (y, 1); + mpfr_dim (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0) || mpfr_sgn (z) < 0) + { + printf ("Error in mpfr_dim (+Inf, +Inf)\n"); + exit (1); + } + + /* case x > y */ + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_dim (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 1)) + { + printf ("Error in mpfr_dim (2, 1)\n"); + exit (1); + } + + /* case x < y */ + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 2, MPFR_RNDN); + mpfr_dim (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0)) + { + printf ("Error in mpfr_dim (1, 2)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + test_generic (2, 220, 42); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tdiv.c b/mpfr/tests/tdiv.c new file mode 100644 index 0000000000..e9052471ff --- /dev/null +++ b/mpfr/tests/tdiv.c @@ -0,0 +1,1291 @@ +/* Test file for mpfr_div (and some mpfr_div_ui, etc. tests). + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check_equal (mpfr_srcptr a, mpfr_srcptr a2, char *s, + mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t r) +{ + if ((MPFR_IS_NAN (a) && MPFR_IS_NAN (a2)) || + mpfr_equal_p (a, a2)) + return; + printf ("Error in %s\n", mpfr_print_rnd_mode (r)); + printf ("b = "); + mpfr_dump (b); + printf ("c = "); + mpfr_dump (c); + printf ("mpfr_div result: "); + mpfr_dump (a); + printf ("%s result: ", s); + mpfr_dump (a2); + exit (1); +} + +static int +mpfr_all_div (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t r) +{ + mpfr_t a2; + unsigned int oldflags, newflags; + int inex, inex2; + + oldflags = __gmpfr_flags; + inex = mpfr_div (a, b, c, r); + + if (a == b || a == c) + return inex; + + newflags = __gmpfr_flags; + + mpfr_init2 (a2, MPFR_PREC (a)); + + if (mpfr_integer_p (b) && ! (MPFR_IS_ZERO (b) && MPFR_IS_NEG (b))) + { + /* b is an integer, but not -0 (-0 is rejected as + it becomes +0 when converted to an integer). */ + if (mpfr_fits_ulong_p (b, MPFR_RNDA)) + { + __gmpfr_flags = oldflags; + inex2 = mpfr_ui_div (a2, mpfr_get_ui (b, MPFR_RNDN), c, r); + MPFR_ASSERTN (SAME_SIGN (inex2, inex)); + MPFR_ASSERTN (__gmpfr_flags == newflags); + check_equal (a, a2, "mpfr_ui_div", b, c, r); + } + if (mpfr_fits_slong_p (b, MPFR_RNDA)) + { + __gmpfr_flags = oldflags; + inex2 = mpfr_si_div (a2, mpfr_get_si (b, MPFR_RNDN), c, r); + MPFR_ASSERTN (SAME_SIGN (inex2, inex)); + MPFR_ASSERTN (__gmpfr_flags == newflags); + check_equal (a, a2, "mpfr_si_div", b, c, r); + } + } + + if (mpfr_integer_p (c) && ! (MPFR_IS_ZERO (c) && MPFR_IS_NEG (c))) + { + /* c is an integer, but not -0 (-0 is rejected as + it becomes +0 when converted to an integer). */ + if (mpfr_fits_ulong_p (c, MPFR_RNDA)) + { + __gmpfr_flags = oldflags; + inex2 = mpfr_div_ui (a2, b, mpfr_get_ui (c, MPFR_RNDN), r); + MPFR_ASSERTN (SAME_SIGN (inex2, inex)); + MPFR_ASSERTN (__gmpfr_flags == newflags); + check_equal (a, a2, "mpfr_div_ui", b, c, r); + } + if (mpfr_fits_slong_p (c, MPFR_RNDA)) + { + __gmpfr_flags = oldflags; + inex2 = mpfr_div_si (a2, b, mpfr_get_si (c, MPFR_RNDN), r); + MPFR_ASSERTN (SAME_SIGN (inex2, inex)); + MPFR_ASSERTN (__gmpfr_flags == newflags); + check_equal (a, a2, "mpfr_div_si", b, c, r); + } + } + + mpfr_clear (a2); + + return inex; +} + +#ifdef CHECK_EXTERNAL +static int +test_div (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c); + if (ok) + { + mpfr_print_raw (b); + printf (" "); + mpfr_print_raw (c); + } + res = mpfr_all_div (a, b, c, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_div mpfr_all_div +#endif + +#define check53(n, d, rnd, res) check4(n, d, rnd, 53, res) + +/* return 0 iff a and b are of the same sign */ +static int +inex_cmp (int a, int b) +{ + if (a > 0) + return (b > 0) ? 0 : 1; + else if (a == 0) + return (b == 0) ? 0 : 1; + else + return (b < 0) ? 0 : 1; +} + +static void +check4 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, int p, + const char *Qs) +{ + mpfr_t q, n, d; + + mpfr_inits2 (p, q, n, d, (mpfr_ptr) 0); + mpfr_set_str1 (n, Ns); + mpfr_set_str1 (d, Ds); + test_div(q, n, d, rnd_mode); + if (mpfr_cmp_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN) ) + { + printf ("mpfr_div failed for n=%s, d=%s, p=%d, rnd_mode=%s\n", + Ns, Ds, p, mpfr_print_rnd_mode (rnd_mode)); + printf ("got ");mpfr_print_binary(q); + mpfr_set_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN); + printf("\nexpected "); mpfr_print_binary(q); + putchar('\n'); + exit (1); + } + mpfr_clears (q, n, d, (mpfr_ptr) 0); +} + +static void +check24 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, const char *Qs) +{ + mpfr_t q, n, d; + + mpfr_inits2 (24, q, n, d, (mpfr_ptr) 0); + + mpfr_set_str1 (n, Ns); + mpfr_set_str1 (d, Ds); + test_div(q, n, d, rnd_mode); + if (mpfr_cmp_str1 (q, Qs) ) + { + printf ("mpfr_div failed for n=%s, d=%s, prec=24, rnd_mode=%s\n", + Ns, Ds, mpfr_print_rnd_mode(rnd_mode)); + printf ("expected quotient is %s, got ", Qs); + mpfr_out_str(stdout,10,0,q, MPFR_RNDN); putchar('\n'); + exit (1); + } + mpfr_clears (q, n, d, (mpfr_ptr) 0); +} + +/* the following examples come from the paper "Number-theoretic Test + Generation for Directed Rounding" from Michael Parks, Table 2 */ +static void +check_float(void) +{ + check24("70368760954880.0", "8388609.0", MPFR_RNDN, "8.388609e6"); + check24("140737479966720.0", "16777213.0", MPFR_RNDN, "8.388609e6"); + check24("70368777732096.0", "8388611.0", MPFR_RNDN, "8.388609e6"); + check24("105553133043712.0", "12582911.0", MPFR_RNDN, "8.38861e6"); + /* the exponent for the following example was forgotten in + the Arith'14 version of Parks' paper */ + check24 ("12582913.0", "12582910.0", MPFR_RNDN, "1.000000238"); + check24 ("105553124655104.0", "12582910.0", MPFR_RNDN, "8388610.0"); + check24("140737479966720.0", "8388609.0", MPFR_RNDN, "1.6777213e7"); + check24("70368777732096.0", "8388609.0", MPFR_RNDN, "8.388611e6"); + check24("105553133043712.0", "8388610.0", MPFR_RNDN, "1.2582911e7"); + check24("105553124655104.0", "8388610.0", MPFR_RNDN, "1.258291e7"); + + check24("70368760954880.0", "8388609.0", MPFR_RNDZ, "8.388608e6"); + check24("140737479966720.0", "16777213.0", MPFR_RNDZ, "8.388609e6"); + check24("70368777732096.0", "8388611.0", MPFR_RNDZ, "8.388608e6"); + check24("105553133043712.0", "12582911.0", MPFR_RNDZ, "8.38861e6"); + check24("12582913.0", "12582910.0", MPFR_RNDZ, "1.000000238"); + check24 ("105553124655104.0", "12582910.0", MPFR_RNDZ, "8388610.0"); + check24("140737479966720.0", "8388609.0", MPFR_RNDZ, "1.6777213e7"); + check24("70368777732096.0", "8388609.0", MPFR_RNDZ, "8.38861e6"); + check24("105553133043712.0", "8388610.0", MPFR_RNDZ, "1.2582911e7"); + check24("105553124655104.0", "8388610.0", MPFR_RNDZ, "1.258291e7"); + + check24("70368760954880.0", "8388609.0", MPFR_RNDU, "8.388609e6"); + check24("140737479966720.0", "16777213.0", MPFR_RNDU, "8.38861e6"); + check24("70368777732096.0", "8388611.0", MPFR_RNDU, "8.388609e6"); + check24("105553133043712.0", "12582911.0", MPFR_RNDU, "8.388611e6"); + check24("12582913.0", "12582910.0", MPFR_RNDU, "1.000000357"); + check24 ("105553124655104.0", "12582910.0", MPFR_RNDU, "8388611.0"); + check24("140737479966720.0", "8388609.0", MPFR_RNDU, "1.6777214e7"); + check24("70368777732096.0", "8388609.0", MPFR_RNDU, "8.388611e6"); + check24("105553133043712.0", "8388610.0", MPFR_RNDU, "1.2582912e7"); + check24("105553124655104.0", "8388610.0", MPFR_RNDU, "1.2582911e7"); + + check24("70368760954880.0", "8388609.0", MPFR_RNDD, "8.388608e6"); + check24("140737479966720.0", "16777213.0", MPFR_RNDD, "8.388609e6"); + check24("70368777732096.0", "8388611.0", MPFR_RNDD, "8.388608e6"); + check24("105553133043712.0", "12582911.0", MPFR_RNDD, "8.38861e6"); + check24("12582913.0", "12582910.0", MPFR_RNDD, "1.000000238"); + check24 ("105553124655104.0", "12582910.0", MPFR_RNDD, "8388610.0"); + check24("140737479966720.0", "8388609.0", MPFR_RNDD, "1.6777213e7"); + check24("70368777732096.0", "8388609.0", MPFR_RNDD, "8.38861e6"); + check24("105553133043712.0", "8388610.0", MPFR_RNDD, "1.2582911e7"); + check24("105553124655104.0", "8388610.0", MPFR_RNDD, "1.258291e7"); + + check24("70368760954880.0", "8388609.0", MPFR_RNDA, "8.388609e6"); +} + +static void +check_double(void) +{ + check53("0.0", "1.0", MPFR_RNDZ, "0.0"); + check53("-7.4988969224688591e63", "4.8816866450288732e306", MPFR_RNDD, + "-1.5361282826510687291e-243"); + check53("-1.33225773037748601769e+199", "3.63449540676937123913e+79", + MPFR_RNDZ, "-3.6655920045905428978e119"); + check53("9.89438396044940256501e-134", "5.93472984109987421717e-67",MPFR_RNDU, + "1.6672003992376663654e-67"); + check53("9.89438396044940256501e-134", "5.93472984109987421717e-67",MPFR_RNDA, + "1.6672003992376663654e-67"); + check53("9.89438396044940256501e-134", "-5.93472984109987421717e-67", + MPFR_RNDU, "-1.6672003992376663654e-67"); + check53("-4.53063926135729747564e-308", "7.02293374921793516813e-84", + MPFR_RNDD, "-6.4512060388748850857e-225"); + check53("6.25089225176473806123e-01","-2.35527154824420243364e-230", + MPFR_RNDD, "-2.6540006635008291192e229"); + check53("6.25089225176473806123e-01","-2.35527154824420243364e-230", + MPFR_RNDA, "-2.6540006635008291192e229"); + check53("6.52308934689126e15", "-1.62063546601505417497e273", MPFR_RNDN, + "-4.0250194961676020848e-258"); + check53("1.04636807108079349236e-189", "3.72295730823253012954e-292", + MPFR_RNDZ, "2.810583051186143125e102"); + /* problems found by Kevin under HP-PA */ + check53 ("2.861044553323177e-136", "-1.1120354257068143e+45", MPFR_RNDZ, + "-2.5727998292003016e-181"); + check53 ("-4.0559157245809205e-127", "-1.1237723844524865e+77", MPFR_RNDN, + "3.6091968273068081e-204"); + check53 ("-1.8177943561493235e-93", "-8.51233984260364e-104", MPFR_RNDU, + "2.1354814184595821e+10"); +} + +static void +check_64(void) +{ + mpfr_t x,y,z; + + mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0); + + mpfr_set_str_binary(x, "1.00100100110110101001010010101111000001011100100101010000000000E54"); + mpfr_set_str_binary(y, "1.00000000000000000000000000000000000000000000000000000000000000E584"); + test_div(z, x, y, MPFR_RNDU); + if (mpfr_cmp_str (z, "0.1001001001101101010010100101011110000010111001001010100000000000E-529", 2, MPFR_RNDN)) + { + printf("Error for tdiv for MPFR_RNDU and p=64\nx="); + mpfr_print_binary(x); + printf("\ny="); + mpfr_print_binary(y); + printf("\ngot "); + mpfr_print_binary(z); + printf("\nexpected 0.1001001001101101010010100101011110000010111001001010100000000000E-529\n"); + exit(1); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static void +check_convergence (void) +{ + mpfr_t x, y; int i, j; + + mpfr_init2(x, 130); + mpfr_set_str_binary(x, "0.1011111101011010101000001010011111101000011100011101010011111011000011001010000000111100100111110011001010110100100001001000111001E6944"); + mpfr_init2(y, 130); + mpfr_set_ui(y, 5, MPFR_RNDN); + test_div(x, x, y, MPFR_RNDD); /* exact division */ + + mpfr_set_prec(x, 64); + mpfr_set_prec(y, 64); + mpfr_set_str_binary(x, "0.10010010011011010100101001010111100000101110010010101E55"); + mpfr_set_str_binary(y, "0.1E585"); + test_div(x, x, y, MPFR_RNDN); + mpfr_set_str_binary(y, "0.10010010011011010100101001010111100000101110010010101E-529"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_div for prec=64, rnd=MPFR_RNDN\n"); + printf ("got "); mpfr_print_binary(x); puts (""); + printf ("instead of "); mpfr_print_binary(y); puts (""); + exit(1); + } + + for (i=32; i<=64; i+=32) + { + mpfr_set_prec(x, i); + mpfr_set_prec(y, i); + mpfr_set_ui(x, 1, MPFR_RNDN); + RND_LOOP(j) + { + mpfr_set_ui (y, 1, MPFR_RNDN); + test_div (y, x, y, (mpfr_rnd_t) j); + if (mpfr_cmp_ui (y, 1)) + { + printf ("mpfr_div failed for x=1.0, y=1.0, prec=%d rnd=%s\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) j)); + printf ("got "); mpfr_print_binary(y); puts (""); + exit (1); + } + } + } + + mpfr_clear (x); + mpfr_clear (y); +} + +#define KMAX 10000 + +/* given y = o(x/u), x, u, find the inexact flag by + multiplying y by u */ +static int +get_inexact (mpfr_t y, mpfr_t x, mpfr_t u) +{ + mpfr_t xx; + int inex; + mpfr_init2 (xx, mpfr_get_prec (y) + mpfr_get_prec (u)); + mpfr_mul (xx, y, u, MPFR_RNDN); /* exact */ + inex = mpfr_cmp (xx, x); + mpfr_clear (xx); + return inex; +} + +static void +check_hard (void) +{ + mpfr_t u, v, q, q2; + mpfr_prec_t precu, precv, precq; + int rnd; + int inex, inex2, i, j; + + mpfr_init (q); + mpfr_init (q2); + mpfr_init (u); + mpfr_init (v); + + for (precq = MPFR_PREC_MIN; precq <= 64; precq ++) + { + mpfr_set_prec (q, precq); + mpfr_set_prec (q2, precq + 1); + for (j = 0; j < 2; j++) + { + if (j == 0) + { + do + { + mpfr_urandomb (q2, RANDS); + } + while (mpfr_cmp_ui (q2, 0) == 0); + } + else /* use q2=1 */ + mpfr_set_ui (q2, 1, MPFR_RNDN); + for (precv = precq; precv <= 10 * precq; precv += precq) + { + mpfr_set_prec (v, precv); + do + { + mpfr_urandomb (v, RANDS); + } + while (mpfr_cmp_ui (v, 0) == 0); + for (precu = precq; precu <= 10 * precq; precu += precq) + { + mpfr_set_prec (u, precu); + mpfr_mul (u, v, q2, MPFR_RNDN); + mpfr_nextbelow (u); + for (i = 0; i <= 2; i++) + { + RND_LOOP(rnd) + { + inex = test_div (q, u, v, (mpfr_rnd_t) rnd); + inex2 = get_inexact (q, u, v); + if (inex_cmp (inex, inex2)) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex2, inex); + printf ("u= "); mpfr_dump (u); + printf ("v= "); mpfr_dump (v); + printf ("q= "); mpfr_dump (q); + mpfr_set_prec (q2, precq + precv); + mpfr_mul (q2, q, v, MPFR_RNDN); + printf ("q*v="); mpfr_dump (q2); + exit (1); + } + } + mpfr_nextabove (u); + } + } + } + } + } + + mpfr_clear (q); + mpfr_clear (q2); + mpfr_clear (u); + mpfr_clear (v); +} + +static void +check_lowr (void) +{ + mpfr_t x, y, z, z2, z3, tmp; + int k, c, c2; + + + mpfr_init2 (x, 1000); + mpfr_init2 (y, 100); + mpfr_init2 (tmp, 850); + mpfr_init2 (z, 10); + mpfr_init2 (z2, 10); + mpfr_init2 (z3, 50); + + for (k = 1; k < KMAX; k++) + { + do + { + mpfr_urandomb (z, RANDS); + } + while (mpfr_cmp_ui (z, 0) == 0); + do + { + mpfr_urandomb (tmp, RANDS); + } + while (mpfr_cmp_ui (tmp, 0) == 0); + mpfr_mul (x, z, tmp, MPFR_RNDN); /* exact */ + c = test_div (z2, x, tmp, MPFR_RNDN); + + if (c || mpfr_cmp (z2, z)) + { + printf ("Error in mpfr_div rnd=MPFR_RNDN\n"); + printf ("got "); mpfr_print_binary(z2); puts (""); + printf ("instead of "); mpfr_print_binary(z); puts (""); + printf ("inex flag = %d, expected 0\n", c); + exit (1); + } + } + + /* x has still precision 1000, z precision 10, and tmp prec 850 */ + mpfr_set_prec (z2, 9); + for (k = 1; k < KMAX; k++) + { + mpfr_urandomb (z, RANDS); + do + { + mpfr_urandomb (tmp, RANDS); + } + while (mpfr_cmp_ui (tmp, 0) == 0); + mpfr_mul (x, z, tmp, MPFR_RNDN); /* exact */ + c = test_div (z2, x, tmp, MPFR_RNDN); + /* since z2 has one less bit that z, either the division is exact + if z is representable on 9 bits, or we have an even round case */ + + c2 = get_inexact (z2, x, tmp); + if ((mpfr_cmp (z2, z) == 0 && c) || inex_cmp (c, c2)) + { + printf ("Error in mpfr_div rnd=MPFR_RNDN\n"); + printf ("got "); mpfr_print_binary(z2); puts (""); + printf ("instead of "); mpfr_print_binary(z); puts (""); + printf ("inex flag = %d, expected %d\n", c, c2); + exit (1); + } + else if (c == 2) + { + mpfr_nexttoinf (z); + if (mpfr_cmp(z2, z)) + { + printf ("Error in mpfr_div [even rnd?] rnd=MPFR_RNDN\n"); + printf ("Dividing "); + printf ("got "); mpfr_print_binary(z2); puts (""); + printf ("instead of "); mpfr_print_binary(z); puts (""); + printf ("inex flag = %d\n", 1); + exit (1); + } + } + else if (c == -2) + { + mpfr_nexttozero (z); + if (mpfr_cmp(z2, z)) + { + printf ("Error in mpfr_div [even rnd?] rnd=MPFR_RNDN\n"); + printf ("Dividing "); + printf ("got "); mpfr_print_binary(z2); puts (""); + printf ("instead of "); mpfr_print_binary(z); puts (""); + printf ("inex flag = %d\n", 1); + exit (1); + } + } + } + + mpfr_set_prec(x, 1000); + mpfr_set_prec(y, 100); + mpfr_set_prec(tmp, 850); + mpfr_set_prec(z, 10); + mpfr_set_prec(z2, 10); + + /* almost exact divisions */ + for (k = 1; k < KMAX; k++) + { + do + { + mpfr_urandomb (z, RANDS); + } + while (mpfr_cmp_ui (z, 0) == 0); + do + { + mpfr_urandomb (tmp, RANDS); + } + while (mpfr_cmp_ui (tmp, 0) == 0); + mpfr_mul(x, z, tmp, MPFR_RNDN); + mpfr_set(y, tmp, MPFR_RNDD); + mpfr_nexttoinf (x); + + c = test_div(z2, x, y, MPFR_RNDD); + test_div(z3, x, y, MPFR_RNDD); + mpfr_set(z, z3, MPFR_RNDD); + + if (c != -1 || mpfr_cmp(z2, z)) + { + printf ("Error in mpfr_div rnd=MPFR_RNDD\n"); + printf ("got "); mpfr_print_binary(z2); puts (""); + printf ("instead of "); mpfr_print_binary(z); puts (""); + printf ("inex flag = %d\n", c); + exit (1); + } + + mpfr_set (y, tmp, MPFR_RNDU); + test_div (z3, x, y, MPFR_RNDU); + mpfr_set (z, z3, MPFR_RNDU); + c = test_div (z2, x, y, MPFR_RNDU); + if (c != 1 || mpfr_cmp (z2, z)) + { + printf ("Error in mpfr_div rnd=MPFR_RNDU\n"); + printf ("u="); mpfr_dump (x); + printf ("v="); mpfr_dump (y); + printf ("got "); mpfr_print_binary (z2); puts (""); + printf ("instead of "); mpfr_print_binary (z); puts (""); + printf ("inex flag = %d\n", c); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (z2); + mpfr_clear (z3); + mpfr_clear (tmp); +} + +#define MAX_PREC 128 + +static void +check_inexact (void) +{ + mpfr_t x, y, z, u; + mpfr_prec_t px, py, pu; + int inexact, cmp; + mpfr_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (u); + + mpfr_set_prec (x, 28); + mpfr_set_prec (y, 28); + mpfr_set_prec (z, 1023); + mpfr_set_str_binary (x, "0.1000001001101101111100010011E0"); + mpfr_set_str (z, "48284762641021308813686974720835219181653367326353400027913400579340343320519877153813133510034402932651132854764198688352364361009429039801248971901380781746767119334993621199563870113045276395603170432175354501451429471578325545278975153148347684600400321033502982713296919861760382863826626093689036010394", 10, MPFR_RNDN); + mpfr_div (x, x, z, MPFR_RNDN); + mpfr_set_str_binary (y, "0.1111001011001101001001111100E-1023"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_div for prec=28, RNDN\n"); + printf ("Expected "); mpfr_dump (y); + printf ("Got "); mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_str_binary (x, "0.11101100110010100011011000000100001111011111110010101E0"); + mpfr_set_prec (u, 127); + mpfr_set_str_binary (u, "0.1000001100110110110101110110101101111000110000001111111110000000011111001010110100110010111111111101000001011011101011101101000E-2"); + mpfr_set_prec (y, 95); + inexact = test_div (y, x, u, MPFR_RNDN); + if (inexact != (cmp = get_inexact (y, x, u))) + { + printf ("Wrong inexact flag (0): expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_out_str (stdout, 10, 99, x, MPFR_RNDN); printf ("\n"); + printf ("u="); mpfr_out_str (stdout, 10, 99, u, MPFR_RNDN); printf ("\n"); + printf ("y="); mpfr_out_str (stdout, 10, 99, y, MPFR_RNDN); printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_str_binary (x, "0.101111100011011101010011101100001E0"); + mpfr_set_prec (u, 2); + mpfr_set_str_binary (u, "0.1E0"); + mpfr_set_prec (y, 28); + if ((inexact = test_div (y, x, u, MPFR_RNDN) >= 0)) + { + printf ("Wrong inexact flag (1): expected -1, got %d\n", + inexact); + exit (1); + } + + mpfr_set_prec (x, 129); + mpfr_set_str_binary (x, "0.111110101111001100000101011100101100110011011101010001000110110101100101000010000001110110100001101010001010100010001111001101010E-2"); + mpfr_set_prec (u, 15); + mpfr_set_str_binary (u, "0.101101000001100E-1"); + mpfr_set_prec (y, 92); + if ((inexact = test_div (y, x, u, MPFR_RNDN)) <= 0) + { + printf ("Wrong inexact flag for rnd=MPFR_RNDN(1): expected 1, got %d\n", + inexact); + mpfr_dump (x); + mpfr_dump (u); + mpfr_dump (y); + exit (1); + } + + for (px=2; px<MAX_PREC; px++) + { + mpfr_set_prec (x, px); + mpfr_urandomb (x, RANDS); + for (pu=2; pu<=MAX_PREC; pu++) + { + mpfr_set_prec (u, pu); + do { mpfr_urandomb (u, RANDS); } while (mpfr_cmp_ui (u, 0) == 0); + { + py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - MPFR_PREC_MIN)); + mpfr_set_prec (y, py); + mpfr_set_prec (z, py + pu); + { + rnd = RND_RAND (); + inexact = test_div (y, x, u, rnd); + if (mpfr_mul (z, y, u, rnd)) + { + printf ("z <- y * u should be exact\n"); + exit (1); + } + cmp = mpfr_cmp (z, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong inexact flag for rnd=%s\n", + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("u="); mpfr_print_binary (u); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + printf ("y*u="); mpfr_print_binary (z); puts (""); + exit (1); + } + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); +} + +static void +check_special (void) +{ + mpfr_t a, d, q; + mpfr_exp_t emax, emin; + int i; + + mpfr_init2 (a, 100L); + mpfr_init2 (d, 100L); + mpfr_init2 (q, 100L); + + /* 1/nan == nan */ + mpfr_set_ui (a, 1L, MPFR_RNDN); + MPFR_SET_NAN (d); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + /* nan/1 == nan */ + MPFR_SET_NAN (a); + mpfr_set_ui (d, 1L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + /* +inf/1 == +inf */ + MPFR_SET_INF (a); + MPFR_SET_POS (a); + mpfr_set_ui (d, 1L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* +inf/-1 == -inf */ + MPFR_SET_INF (a); + MPFR_SET_POS (a); + mpfr_set_si (d, -1, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* -inf/1 == -inf */ + MPFR_SET_INF (a); + MPFR_SET_NEG (a); + mpfr_set_ui (d, 1L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* -inf/-1 == +inf */ + MPFR_SET_INF (a); + MPFR_SET_NEG (a); + mpfr_set_si (d, -1, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* 1/+inf == +0 */ + mpfr_set_ui (a, 1L, MPFR_RNDN); + MPFR_SET_INF (d); + MPFR_SET_POS (d); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) == 0); + MPFR_ASSERTN (MPFR_IS_POS (q)); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* 1/-inf == -0 */ + mpfr_set_ui (a, 1L, MPFR_RNDN); + MPFR_SET_INF (d); + MPFR_SET_NEG (d); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) == 0); + MPFR_ASSERTN (MPFR_IS_NEG (q)); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* -1/+inf == -0 */ + mpfr_set_si (a, -1, MPFR_RNDN); + MPFR_SET_INF (d); + MPFR_SET_POS (d); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) == 0); + MPFR_ASSERTN (MPFR_IS_NEG (q)); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* -1/-inf == +0 */ + mpfr_set_si (a, -1, MPFR_RNDN); + MPFR_SET_INF (d); + MPFR_SET_NEG (d); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) == 0); + MPFR_ASSERTN (MPFR_IS_POS (q)); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* 0/0 == nan */ + mpfr_set_ui (a, 0L, MPFR_RNDN); + mpfr_set_ui (d, 0L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + /* +inf/+inf == nan */ + MPFR_SET_INF (a); + MPFR_SET_POS (a); + MPFR_SET_INF (d); + MPFR_SET_POS (d); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + /* 1/+0 = +inf */ + mpfr_set_ui (a, 1, MPFR_RNDZ); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + /* 1/-0 = -inf */ + mpfr_set_ui (a, 1, MPFR_RNDZ); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_neg (d, d, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + /* -1/+0 = -inf */ + mpfr_set_si (a, -1, MPFR_RNDZ); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + /* -1/-0 = +inf */ + mpfr_set_si (a, -1, MPFR_RNDZ); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_neg (d, d, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + /* +inf/+0 = +inf */ + MPFR_SET_INF (a); + MPFR_SET_POS (a); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* +inf/-0 = -inf */ + MPFR_SET_INF (a); + MPFR_SET_POS (a); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_neg (d, d, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* -inf/+0 = -inf */ + MPFR_SET_INF (a); + MPFR_SET_NEG (a); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* -inf/-0 = +inf */ + MPFR_SET_INF (a); + MPFR_SET_NEG (a); + mpfr_set_ui (d, 0, MPFR_RNDZ); + mpfr_neg (d, d, MPFR_RNDZ); + mpfr_clear_flags (); + MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* check overflow */ + emax = mpfr_get_emax (); + set_emax (1); + mpfr_set_ui (a, 1, MPFR_RNDZ); + mpfr_set_ui (d, 1, MPFR_RNDZ); + mpfr_div_2exp (d, d, 1, MPFR_RNDZ); + mpfr_clear_flags (); + test_div (q, a, d, MPFR_RNDU); /* 1 / 0.5 = 2 -> overflow */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)); + set_emax (emax); + + /* check underflow */ + emin = mpfr_get_emin (); + set_emin (-1); + mpfr_set_ui (a, 1, MPFR_RNDZ); + mpfr_div_2exp (a, a, 2, MPFR_RNDZ); + mpfr_set_prec (d, mpfr_get_prec (q) + 8); + for (i = -1; i <= 1; i++) + { + int sign; + + /* Test 2^(-2) / (+/- (2 + eps)), with eps < 0, eps = 0, eps > 0. + -> underflow. + With div.c r5513, this test fails for eps > 0 in MPFR_RNDN. */ + mpfr_set_ui (d, 2, MPFR_RNDZ); + if (i < 0) + mpfr_nextbelow (d); + if (i > 0) + mpfr_nextabove (d); + for (sign = 0; sign <= 1; sign++) + { + mpfr_clear_flags (); + test_div (q, a, d, MPFR_RNDZ); /* result = 0 */ + MPFR_ASSERTN (__gmpfr_flags == + (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT)); + MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q)); + MPFR_ASSERTN (MPFR_IS_ZERO (q)); + mpfr_clear_flags (); + test_div (q, a, d, MPFR_RNDN); /* result = 0 iff eps >= 0 */ + MPFR_ASSERTN (__gmpfr_flags == + (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT)); + MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q)); + if (i < 0) + mpfr_nexttozero (q); + MPFR_ASSERTN (MPFR_IS_ZERO (q)); + mpfr_neg (d, d, MPFR_RNDN); + } + } + set_emin (emin); + + mpfr_clear (a); + mpfr_clear (d); + mpfr_clear (q); +} + +static void +consistency (void) +{ + mpfr_t x, y, z1, z2; + int i; + + mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0); + + for (i = 0; i < 10000; i++) + { + mpfr_rnd_t rnd; + mpfr_prec_t px, py, pz, p; + int inex1, inex2; + + rnd = RND_RAND (); + px = (randlimb () % 256) + 2; + py = (randlimb () % 128) + 2; + pz = (randlimb () % 256) + 2; + mpfr_set_prec (x, px); + mpfr_set_prec (y, py); + mpfr_set_prec (z1, pz); + mpfr_set_prec (z2, pz); + mpfr_urandomb (x, RANDS); + do + mpfr_urandomb (y, RANDS); + while (mpfr_zero_p (y)); + inex1 = mpfr_div (z1, x, y, rnd); + MPFR_ASSERTN (!MPFR_IS_NAN (z1)); + p = MAX (MAX (px, py), pz); + if (mpfr_prec_round (x, p, MPFR_RNDN) != 0 || + mpfr_prec_round (y, p, MPFR_RNDN) != 0) + { + printf ("mpfr_prec_round error for i = %d\n", i); + exit (1); + } + inex2 = mpfr_div (z2, x, y, rnd); + MPFR_ASSERTN (!MPFR_IS_NAN (z2)); + if (inex1 != inex2 || mpfr_cmp (z1, z2) != 0) + { + printf ("Consistency error for i = %d\n", i); + exit (1); + } + } + + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); +} + +/* Reported by Carl Witty on 2007-06-03 */ +static void +test_20070603 (void) +{ + mpfr_t n, d, q, c; + + mpfr_init2 (n, 128); + mpfr_init2 (d, 128); + mpfr_init2 (q, 31); + mpfr_init2 (c, 31); + + mpfr_set_str (n, "10384593717069655257060992206846485", 10, MPFR_RNDN); + mpfr_set_str (d, "10384593717069655257060992206847132", 10, MPFR_RNDN); + mpfr_div (q, n, d, MPFR_RNDU); + + mpfr_set_ui (c, 1, MPFR_RNDN); + if (mpfr_cmp (q, c) != 0) + { + printf ("Error in test_20070603\nGot "); + mpfr_dump (q); + printf ("instead of "); + mpfr_dump (c); + exit (1); + } + + /* same for 64-bit machines */ + mpfr_set_prec (n, 256); + mpfr_set_prec (d, 256); + mpfr_set_prec (q, 63); + mpfr_set_str (n, "822752278660603021077484591278675252491367930877209729029898240", 10, MPFR_RNDN); + mpfr_set_str (d, "822752278660603021077484591278675252491367930877212507873738752", 10, MPFR_RNDN); + mpfr_div (q, n, d, MPFR_RNDU); + if (mpfr_cmp (q, c) != 0) + { + printf ("Error in test_20070603\nGot "); + mpfr_dump (q); + printf ("instead of "); + mpfr_dump (c); + exit (1); + } + + mpfr_clear (n); + mpfr_clear (d); + mpfr_clear (q); + mpfr_clear (c); +} + +/* Bug found while adding tests for mpfr_cot */ +static void +test_20070628 (void) +{ + mpfr_exp_t old_emax; + mpfr_t x, y; + int inex, err = 0; + + old_emax = mpfr_get_emax (); + + if (mpfr_set_emax (256)) + { + printf ("Can't change exponent range\n"); + exit (1); + } + + mpfr_inits2 (53, x, y, (mpfr_ptr) 0); + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_set_si_2exp (y, 1, -256, MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_div (x, x, y, MPFR_RNDD); + if (MPFR_SIGN (x) >= 0 || ! mpfr_inf_p (x)) + { + printf ("Error in test_20070628: expected -Inf, got\n"); + mpfr_dump (x); + err++; + } + if (inex >= 0) + { + printf ("Error in test_20070628: expected inex < 0, got %d\n", inex); + err++; + } + if (! mpfr_overflow_p ()) + { + printf ("Error in test_20070628: overflow flag is not set\n"); + err++; + } + mpfr_clears (x, y, (mpfr_ptr) 0); + mpfr_set_emax (old_emax); +} + +/* Bug in mpfr_divhigh_n_basecase when all limbs of q (except the most + significant one) are B-1 where B=2^GMP_NUMB_BITS. Since we truncate + the divisor at each step, it might happen at some point that + (np[n-1],np[n-2]) > (d1,d0), and not only the equality. + Reported by Ricky Farr + <https://sympa.inria.fr/sympa/arc/mpfr/2015-10/msg00023.html> + To get a failure, a MPFR_DIVHIGH_TAB entry below the MPFR_DIV_THRESHOLD + limit must have a value 0. With most mparam.h files, this cannot occur. */ +static void +test_20151023 (void) +{ + mpfr_prec_t p; + mpfr_t n, d, q, q0; + int inex, i; + + for (p = GMP_NUMB_BITS; p <= 2000; p++) + { + mpfr_init2 (n, 2*p); + mpfr_init2 (d, p); + mpfr_init2 (q, p); + mpfr_init2 (q0, GMP_NUMB_BITS); + + /* generate a random divisor of p bits */ + mpfr_urandomb (d, RANDS); + /* generate a random quotient of GMP_NUMB_BITS bits */ + mpfr_urandomb (q0, RANDS); + /* zero-pad the quotient to p bits */ + inex = mpfr_prec_round (q0, p, MPFR_RNDN); + MPFR_ASSERTN(inex == 0); + + for (i = 0; i < 3; i++) + { + /* i=0: try with the original quotient xxx000...000 + i=1: try with the original quotient minus one ulp + i=2: try with the original quotient plus one ulp */ + if (i == 1) + mpfr_nextbelow (q0); + else if (i == 2) + { + mpfr_nextabove (q0); + mpfr_nextabove (q0); + } + + inex = mpfr_mul (n, d, q0, MPFR_RNDN); + MPFR_ASSERTN(inex == 0); + mpfr_nextabove (n); + mpfr_div (q, n, d, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp (q, q0) == 0); + + inex = mpfr_mul (n, d, q0, MPFR_RNDN); + MPFR_ASSERTN(inex == 0); + mpfr_nextbelow (n); + mpfr_div (q, n, d, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp (q, q0) == 0); + } + + mpfr_clear (n); + mpfr_clear (d); + mpfr_clear (q); + mpfr_clear (q0); + } +} + +#define TEST_FUNCTION test_div +#define TWO_ARGS +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) +#include "tgeneric.c" + +static void +test_extreme (void) +{ + mpfr_t x, y, z; + mpfr_exp_t emin, emax; + mpfr_prec_t p[4] = { 8, 32, 64, 256 }; + int xi, yi, zi, j, r; + unsigned int flags, ex_flags; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_set_emax (MPFR_EMAX_MAX); + + for (xi = 0; xi < 4; xi++) + { + mpfr_init2 (x, p[xi]); + mpfr_setmax (x, MPFR_EMAX_MAX); + MPFR_ASSERTN (mpfr_check (x)); + for (yi = 0; yi < 4; yi++) + { + mpfr_init2 (y, p[yi]); + mpfr_setmin (y, MPFR_EMIN_MIN); + for (j = 0; j < 2; j++) + { + MPFR_ASSERTN (mpfr_check (y)); + for (zi = 0; zi < 4; zi++) + { + mpfr_init2 (z, p[zi]); + RND_LOOP (r) + { + mpfr_clear_flags (); + mpfr_div (z, x, y, (mpfr_rnd_t) r); + flags = __gmpfr_flags; + MPFR_ASSERTN (mpfr_check (z)); + ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("Bad flags in test_extreme on z = a/b" + " with %s and\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + printf ("a = "); + mpfr_dump (x); + printf ("b = "); + mpfr_dump (y); + printf ("Expected flags:"); + flags_out (ex_flags); + printf ("Got flags: "); + flags_out (flags); + printf ("z = "); + mpfr_dump (z); + exit (1); + } + mpfr_clear_flags (); + mpfr_div (z, y, x, (mpfr_rnd_t) r); + flags = __gmpfr_flags; + MPFR_ASSERTN (mpfr_check (z)); + ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("Bad flags in test_extreme on z = a/b" + " with %s and\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + printf ("a = "); + mpfr_dump (y); + printf ("b = "); + mpfr_dump (x); + printf ("Expected flags:"); + flags_out (ex_flags); + printf ("Got flags: "); + flags_out (flags); + printf ("z = "); + mpfr_dump (z); + exit (1); + } + } + mpfr_clear (z); + } /* zi */ + mpfr_nextabove (y); + } /* j */ + mpfr_clear (y); + } /* yi */ + mpfr_clear (x); + } /* xi */ + + set_emin (emin); + set_emax (emax); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_inexact (); + check_hard (); + check_special (); + check_lowr (); + check_float (); /* checks single precision */ + check_double (); + check_convergence (); + check_64 (); + + check4("4.0","4.503599627370496e15", MPFR_RNDZ, 62, + "0.10000000000000000000000000000000000000000000000000000000000000E-49"); + check4("1.0","2.10263340267725788209e+187", MPFR_RNDU, 65, + "0.11010011111001101011111001100111110100000001101001111100111000000E-622"); + check4("2.44394909079968374564e-150", "2.10263340267725788209e+187",MPFR_RNDU, + 65, + "0.11010011111001101011111001100111110100000001101001111100111000000E-1119"); + + consistency (); + test_20070603 (); + test_20070628 (); + test_20151023 (); + test_generic (2, 800, 50); + test_extreme (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tdiv_d.c b/mpfr/tests/tdiv_d.c new file mode 100644 index 0000000000..05cf64b5cc --- /dev/null +++ b/mpfr/tests/tdiv_d.c @@ -0,0 +1,155 @@ +/* Test file for mpfr_div_d + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check_nans (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + /* nan / 1.0 is nan */ + mpfr_set_nan (x); + mpfr_clear_flags (); + inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf / 1.0 == +inf */ + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* -inf / 1.0 == -inf */ + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + /* 0.0 / 0.0 is nan */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* 1.0 / 0.0 == +inf */ + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* -1.0 / 0.0 == -inf */ + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_div_d +#define DOUBLE_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z; + double d; + int inexact; + + tests_start_mpfr (); + + /* check with enough precision */ + mpfr_init2 (x, IEEE_DBL_MANT_DIG); + mpfr_init2 (y, IEEE_DBL_MANT_DIG); + mpfr_init2 (z, IEEE_DBL_MANT_DIG); + + mpfr_set_str (y, "4096", 10, MPFR_RNDN); + d = 0.125; + mpfr_clear_flags (); + inexact = mpfr_div_d (x, y, d, MPFR_RNDN); + if (inexact != 0) + { + printf ("Inexact flag error in mpfr_div_d\n"); + exit (1); + } + mpfr_set_str (z, "32768", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_div_d ("); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + check_nans (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tdiv_ui.c b/mpfr/tests/tdiv_ui.c new file mode 100644 index 0000000000..397d01e9cf --- /dev/null +++ b/mpfr/tests/tdiv_ui.c @@ -0,0 +1,237 @@ +/* Test file for mpfr_div_ui. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +static void +check (const char *ds, unsigned long u, mpfr_rnd_t rnd, const char *es) +{ + mpfr_t x, y; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_set_str1 (x, ds); + mpfr_div_ui (y, x, u, rnd); + if (mpfr_cmp_str1 (y, es)) + { + printf ("mpfr_div_ui failed for x=%s, u=%lu, rnd=%s\n", ds, u, + mpfr_print_rnd_mode (rnd)); + printf ("expected result is %s, got", es); + mpfr_out_str(stdout, 10, 0, y, MPFR_RNDN); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); +} + +static void +special (void) +{ + mpfr_t x, y; + unsigned xprec, yprec; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_ui (y, x, 3, MPFR_RNDN); + + mpfr_set_prec (x, 100); + mpfr_set_prec (y, 100); + mpfr_urandomb (x, RANDS); + mpfr_div_ui (y, x, 123456, MPFR_RNDN); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_div_ui (y, x, 123456789, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0)) + { + printf ("mpfr_div_ui gives non-zero for 0/ui\n"); + exit (1); + } + + /* bug found by Norbert Mueller, 21 Aug 2001 */ + mpfr_set_prec (x, 110); + mpfr_set_prec (y, 60); + mpfr_set_str_binary (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44"); + mpfr_div_ui (y, x, 17, MPFR_RNDN); + mpfr_set_str_binary (x, "0.11001010100101100011101110000001100001010110101001010011011E-48"); + if (mpfr_cmp (x, y)) + { + printf ("Error in x/17 for x=1/16!\n"); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + /* corner case */ + mpfr_set_prec (x, 2 * mp_bits_per_limb); + mpfr_set_prec (y, 2); + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_nextabove (x); + mpfr_div_ui (y, x, 2, MPFR_RNDN); /* exactly in the middle */ + MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0); + + mpfr_set_prec (x, 3 * mp_bits_per_limb); + mpfr_set_prec (y, 2); + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_nextabove (x); + mpfr_div_ui (y, x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); + + mpfr_set_prec (x, 3 * mp_bits_per_limb); + mpfr_set_prec (y, 2); + mpfr_set_si (x, -4, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_div_ui (y, x, 2, MPFR_RNDD); + MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0); + + for (xprec = 53; xprec <= 128; xprec++) + { + mpfr_set_prec (x, xprec); + mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2"); + for (yprec = 53; yprec <= 128; yprec++) + { + mpfr_set_prec (y, yprec); + mpfr_div_ui (y, x, 1, MPFR_RNDN); + if (mpfr_cmp(x,y)) + { + printf ("division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec); + printf ("expected "); mpfr_print_binary (x); puts (""); + printf ("got "); mpfr_print_binary (y); puts (""); + exit (1); + } + } + } + + /* Bug reported by Mark Dickinson, 6 Nov 2007 */ + mpfr_set_si (x, 0, MPFR_RNDN); + mpfr_set_si (y, -1, MPFR_RNDN); + mpfr_div_ui (y, x, 4, MPFR_RNDN); + MPFR_ASSERTN(MPFR_IS_ZERO(y) && MPFR_IS_POS(y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_inexact (void) +{ + mpfr_t x, y, z; + mpfr_prec_t px, py; + int inexact, cmp; + unsigned long int u; + int rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + for (px=2; px<300; px++) + { + mpfr_set_prec (x, px); + mpfr_urandomb (x, RANDS); + do + { + u = randlimb (); + } + while (u == 0); + for (py=2; py<300; py++) + { + mpfr_set_prec (y, py); + mpfr_set_prec (z, py + mp_bits_per_limb); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + inexact = mpfr_div_ui (y, x, u, (mpfr_rnd_t) rnd); + if (mpfr_mul_ui (z, y, u, (mpfr_rnd_t) rnd)) + { + printf ("z <- y * u should be exact for u=%lu\n", u); + printf ("y="); mpfr_print_binary (y); puts (""); + printf ("z="); mpfr_print_binary (z); puts (""); + exit (1); + } + cmp = mpfr_cmp (z, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong inexact flag for u=%lu, rnd=%s\n", u, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +#define TEST_FUNCTION mpfr_div_ui +#define ULONG_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (int argc, char **argv) +{ + mpfr_t x; + + tests_start_mpfr (); + + special (); + + check_inexact (); + + check("1.0", 3, MPFR_RNDN, "3.3333333333333331483e-1"); + check("1.0", 3, MPFR_RNDZ, "3.3333333333333331483e-1"); + check("1.0", 3, MPFR_RNDU, "3.3333333333333337034e-1"); + check("1.0", 3, MPFR_RNDD, "3.3333333333333331483e-1"); + check("1.0", 2116118, MPFR_RNDN, "4.7256343927890600483e-7"); + check("1.098612288668109782", 5, MPFR_RNDN, "0.21972245773362195087"); + + mpfr_init2 (x, 53); + mpfr_set_ui (x, 3, MPFR_RNDD); + mpfr_log (x, x, MPFR_RNDD); + mpfr_div_ui (x, x, 5, MPFR_RNDD); + if (mpfr_cmp_str1 (x, "0.21972245773362189536")) + { + printf ("Error in mpfr_div_ui for x=ln(3), u=5\n"); + exit (1); + } + mpfr_clear (x); + + test_generic (2, 200, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/teint.c b/mpfr/tests/teint.c new file mode 100644 index 0000000000..1b317c209b --- /dev/null +++ b/mpfr/tests/teint.c @@ -0,0 +1,216 @@ +/* Test file for mpfr_eint. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_eint +#define TEST_RANDOM_POS 8 +#define TEST_RANDOM_EMAX 40 +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_eint (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: eint(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_eint (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0)) + { + printf ("Error: eint(+Inf) != +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_eint (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: eint(-Inf) != NaN\n"); + exit (1); + } + + /* eint(+/-0) = -Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_eint (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0)) + { + printf ("Error: eint(+0) != -Inf\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_eint (y, x, MPFR_RNDN); + if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0)) + { + printf ("Error: eint(-0) != -Inf\n"); + exit (1); + } + + /* eint(x) = NaN for x < 0 */ + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_eint (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: eint(-1) != NaN\n"); + exit (1); + } + + mpfr_set_prec (x, 17); + mpfr_set_prec (y, 17); + mpfr_set_str_binary (x, "1.0111110100100110e-2"); + mpfr_set_str_binary (y, "-1.0010101001110100e-10"); + mpfr_eint (x, x, MPFR_RNDZ); + if (mpfr_cmp (x, y)) + { + printf ("Error for x=1.0111110100100110e-2, MPFR_RNDZ\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "0.10E4"); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_set_str (y, "440.37989953483827", 10, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for x=0.10E4, MPFR_RNDZ\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 63); + mpfr_set_prec (y, 63); + mpfr_set_str_binary (x, "1.01111101011100111000011010001000101101011000011001111101011010e-2"); + mpfr_eint (x, x, MPFR_RNDZ); + mpfr_set_str_binary (y, "1.11010110001101000001010010000100001111001000100100000001011100e-17"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error (1) for MPFR_RNDZ\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + + /* check large x */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "1E6"); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "10100011110001101001110000110010111000100111010001E37"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for x=2^6, MPFR_RNDN\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + mpfr_set_str_binary (x, "1E7"); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "11001100100011110000101001011010110111111011110011E128"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for x=2^7, MPFR_RNDN\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + mpfr_set_str_binary (x, "1E8"); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "1010000110000101111111011011000101001000101011101001E310"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for x=2^8, MPFR_RNDN\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + mpfr_set_str_binary (x, "1E9"); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "11001010101000001010101101110000010110011101110010101E677"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for x=2^9, MPFR_RNDN\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + mpfr_set_str_binary (x, "1E10"); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "10011111111010010110110101101000101100101010101101101E1415"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for x=2^10, MPFR_RNDN\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + if (argc != 1) /* teint x [prec] */ + { + mpfr_t x; + mpfr_prec_t p; + p = (argc < 3) ? 53 : atoi (argv[2]); + mpfr_init2 (x, p); + mpfr_set_str (x, argv[1], 10, MPFR_RNDN); + printf ("eint("); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (")="); + mpfr_eint (x, x, MPFR_RNDN); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + mpfr_clear (x); + } + else + { + check_specials (); + + test_generic (2, 100, 100); + } + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/teq.c b/mpfr/tests/teq.c new file mode 100644 index 0000000000..37a4ad5095 --- /dev/null +++ b/mpfr/tests/teq.c @@ -0,0 +1,208 @@ +/* Test file for mpfr_eq. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +teq (mpfr_t x) +{ + mpfr_t y; + unsigned long k, px, mx; + + mpfr_init2 (y, MPFR_PREC(x)); + + mx = (MPFR_PREC(x) - 1) / mp_bits_per_limb; + px = mp_bits_per_limb - 2; + + for (k = 2; k < MPFR_PREC(x); k++) + { + mpfr_set (y, x, MPFR_RNDN); + + MPFR_MANT(y) [mx] ^= (mp_limb_t) 1 << px; + + if (mpfr_eq(y, x, k) || !mpfr_eq(y, x, k - 1)) + { + printf ("Error in eq.\n"); + printf ("x = "); mpfr_print_binary (x); printf ("\n"); + printf ("y = "); mpfr_print_binary (y); printf ("\n"); + printf ("k = %lu\n", k); + printf ("mpfr_eq(y, x, k) = %d\nmpfr_eq(y, x, k - 1) = %d\n", + mpfr_eq (y, x, k), mpfr_eq (y, x, k - 1)); + exit (1); + } + + if (px) + { + --px; + } + else + { + --mx; + px = mp_bits_per_limb - 1; + } + } + mpfr_clear (y); +} + +static void +special (void) +{ + mpfr_t x, y, z; + int i, error = 0; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_init2 (z, 53); + + mpfr_set_str (x, "1", 10, (mpfr_rnd_t) 0); + mpfr_set_str (y, "1e-10000", 10, (mpfr_rnd_t) 0); + mpfr_add (z, x, y, MPFR_RNDU); + + for (i = 1; i <= 52; i++) + if (mpfr_eq (x, z, i) == 0) + error = 1; + for (i = 53; i <= 100; i++) + if (mpfr_eq (x, z, i) != 0) + error = 1; + if (mpfr_eq (x, z, 1000) != 0) + error = 1; + + if (error) + { + printf ("Error in mpfr_eq (1, 1+1e-1000)\n"); + exit (1); + } + + mpfr_set_nan (x); + mpfr_set_nan (y); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_inf (y, 1); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_ui (y, 0, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, 1); + MPFR_ASSERTN(mpfr_eq (x, y, 1)); + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, -1); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_inf (x, -1); + mpfr_set_inf (y, -1); + MPFR_ASSERTN(mpfr_eq (x, y, 1)); + + mpfr_set_inf (x, 1); + mpfr_set_ui (y, 0, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + MPFR_ASSERTN(mpfr_eq (y, x, 1) == 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1)); + + mpfr_neg (y, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1)); + + mpfr_neg (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1)); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_neg (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_prec (x, 2 * mp_bits_per_limb); + mpfr_set_prec (y, mp_bits_per_limb); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb - 1)); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb)); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb + 1)); + MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb - 1)); + MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb)); + MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb + 1)); + + mpfr_nextabove (x); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb - 1)); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb)); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb + 1)); + MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb - 1)); + MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb) == 0); + MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb + 1) == 0); + MPFR_ASSERTN(mpfr_eq (y, x, mp_bits_per_limb - 1)); + MPFR_ASSERTN(mpfr_eq (y, x, mp_bits_per_limb)); + MPFR_ASSERTN(mpfr_eq (y, x, mp_bits_per_limb + 1)); + MPFR_ASSERTN(mpfr_eq (y, x, 2 * mp_bits_per_limb - 1)); + MPFR_ASSERTN(mpfr_eq (y, x, 2 * mp_bits_per_limb) == 0); + MPFR_ASSERTN(mpfr_eq (y, x, 2 * mp_bits_per_limb + 1) == 0); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0); + + mpfr_set_prec (x, 2 * mp_bits_per_limb); + mpfr_set_prec (y, 2 * mp_bits_per_limb); + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_set_ui (y, 3, MPFR_RNDN); + MPFR_ASSERTN(mpfr_eq (x, y, 1)); + MPFR_ASSERTN(mpfr_eq (x, y, 2) == 0); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb) == 0); + MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb + 1) == 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +int +main (void) +{ + int j; + mpfr_t x; + + tests_start_mpfr (); + + special (); + + mpfr_init2 (x, 500); + + for (j = 0; j < 500; j++) + { + mpfr_urandomb (x, RANDS); + teq (x); + } + + mpfr_clear (x); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/terf.c b/mpfr/tests/terf.c new file mode 100644 index 0000000000..d5999296e0 --- /dev/null +++ b/mpfr/tests/terf.c @@ -0,0 +1,662 @@ +/* Test file for mpfr_erf and mpfr_erfc. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_erf +#define test_generic test_generic_erf +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_erfc +#undef TEST_RANDOM_EMAX +#define TEST_RANDOM_EMAX 63 +#define test_generic test_generic_erfc +#include "tgeneric.c" + +static void +special_erf (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + /* erf(NaN) = NaN */ + mpfr_set_nan (x); + mpfr_erf (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("mpfr_erf failed for x=NaN\n"); + exit (1); + } + + /* erf(+Inf) = 1 */ + mpfr_set_inf (x, 1); + mpfr_erf (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("mpfr_erf failed for x=+Inf\n"); + printf ("expected 1.0, got "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + /* erf(-Inf) = -1 */ + mpfr_set_inf (x, -1); + mpfr_erf (y, x, MPFR_RNDN); + if (mpfr_cmp_si (y, -1)) + { + printf ("mpfr_erf failed for x=-Inf\n"); + exit (1); + } + + /* erf(+0) = +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_erf (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("mpfr_erf failed for x=+0\n"); + exit (1); + } + + /* erf(-0) = -0 */ + mpfr_neg (x, x, MPFR_RNDN); + mpfr_erf (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("mpfr_erf failed for x=-0\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.11010111101110110011110100111010000010000100010001011"); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_erf failed for x=1.0, rnd=MPFR_RNDN\n"); + printf ("expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_str (x, "6.6", 10, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDN\n"); + printf ("expected 1\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_str (x, "-6.6", 10, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp_si (x, -1)) + { + printf ("mpfr_erf failed for x=-6.6, rnd=MPFR_RNDN\n"); + printf ("expected -1\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_str (x, "6.6", 10, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDZ); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111111111111111111111111"); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDZ\n"); + printf ("expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_str (x, "4.5", 10, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.1111111111111111111111111111111100100111110100011"); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_erf failed for x=4.5, rnd=MPFR_RNDN\n"); + printf ("expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 120); + mpfr_set_prec (y, 120); + mpfr_set_str_binary (x, "0.110100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011E3"); + mpfr_erf (x, x, MPFR_RNDN); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111111111111111111111111111111111111100111111000100111011111011010000110101111100011001101"); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDN\n"); + printf ("expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 8); + mpfr_set_prec (y, 8); + mpfr_set_ui (x, 50, MPFR_RNDN); + inex = mpfr_erf (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN\n"); + printf ("expected 1, got "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (inex <= 0) + { + printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN: wrong ternary value\n" + "expected positive, got %d\n", inex); + exit (1); + } + inex = mpfr_erf (x, x, MPFR_RNDZ); + mpfr_nextbelow (y); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDZ\n"); + printf ("expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + printf ("got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (inex >= 0) + { + printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN: wrong ternary value\n" + "expected negative, got %d\n", inex); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1"); + mpfr_set_str_binary (y, "0.10111000001110011010110001101011E-1"); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.10110011011010111110010001100001"); + mpfr_set_str_binary (y, "-0.1010110110101011100010111000111"); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (2)\n"); + mpfr_print_binary (x); printf ("\n"); + exit (1); + } + + mpfr_set_str_binary (x, "100.10001110011110100000110000111"); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (3)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110000111"); + mpfr_erf (x, x, MPFR_RNDZ); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (4)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110000111"); + mpfr_erf (x, x, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (5)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "100.10001110011110100000110001000"); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (6)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110001000"); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + mpfr_erf (x, x, MPFR_RNDZ); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (7)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110001000"); + mpfr_erf (x, x, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (8)\n"); + exit (1); + } + + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (9)\n"); + exit (1); + } + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (10)\n"); + exit (1); + } + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDZ); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (11)\n"); + exit (1); + } + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_erf (x, x, MPFR_RNDD); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (12)\n"); + exit (1); + } + + mpfr_set_prec (x, 43); + mpfr_set_prec (y, 64); + mpfr_set_str_binary (x, "-0.1101110110101111100101011101110101101001001e3"); + mpfr_erf (y, x, MPFR_RNDU); + mpfr_set_prec (x, 64); + mpfr_set_str_binary (x, "-0.1111111111111111111111111111111111111111111111111111111111111111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=43,64 (13)\n"); + exit (1); + } + + /* worst cases */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "1.0000000000000000000000000000000000000110000000101101"); + mpfr_erf (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.110101111011101100111101001110100000101011000011001"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for worst case (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "1.0000000000000000000000000000011000111010101101011010"); + mpfr_erf (y, x, MPFR_RNDU); + mpfr_set_str_binary (x, "0.11010111101110110011110100111100100111100011111000110"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for worst case (2a)\n"); + exit (1); + } + mpfr_set_str_binary (x, "1.0000000000000000000000000000011000111010101101011010"); + mpfr_erf (y, x, MPFR_RNDD); + mpfr_set_str_binary (x, "0.11010111101110110011110100111100100111100011111000101"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for worst case (2b)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +special_erfc (void) +{ + mpfr_t x, y; + + mpfr_inits (x, y, (mpfr_ptr) 0); + + /* erfc (NaN) = NaN */ + mpfr_set_nan (x); + mpfr_erfc (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("mpfr_erfc failed for x=NaN\n"); + exit (1); + } + /* erfc(+Inf) = 0+ */ + mpfr_set_inf (x, 1); + mpfr_erfc (y, x, MPFR_RNDN); + if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y)) + { + printf ("mpfr_erf failed for x=+Inf\n"); + printf ("expected 0+, got "); + mpfr_dump (y); + exit (1); + } + /* erfc(-Inf) = 2 */ + mpfr_set_inf (x, -1); + mpfr_erfc (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 2)) + { + printf ("mpfr_erf failed for x=-Inf\n"); + printf ("expected 2, got "); + mpfr_dump (y); + exit (1); + } + /* erf(+0) = 1 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_erfc (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("mpfr_erf failed for x=+0\n"); + printf ("expected 1, got "); + mpfr_dump (y); + exit (1); + } + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +static void +large_arg (void) +{ + mpfr_t x, y; + unsigned int flags; + + mpfr_init2 (x, 88); + mpfr_init2 (y, 98); + + mpfr_set_si_2exp (x, -1, 173, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_erfc (y, x, MPFR_RNDN); + flags = __gmpfr_flags; + if (mpfr_cmp_ui (y, 2) != 0) + { + printf ("mpfr_erfc failed for large x (1)\n"); + exit (1); + } + if (flags != MPFR_FLAGS_INEXACT) + { + printf ("mpfr_erfc sets incorrect flags for large x (1)\n"); + printf ("Expected %u, got %u\n", + (unsigned int) MPFR_FLAGS_INEXACT, flags); + exit (1); + } + + mpfr_set_si_2exp (x, -1, mpfr_get_emax () - 3, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_erfc (y, x, MPFR_RNDN); + flags = __gmpfr_flags; + if (mpfr_cmp_ui (y, 2) != 0) + { + printf ("mpfr_erfc failed for large x (1b)\n"); + exit (1); + } + if (flags != MPFR_FLAGS_INEXACT) + { + printf ("mpfr_erfc sets incorrect flags for large x (1b)\n"); + printf ("Expected %u, got %u\n", + (unsigned int) MPFR_FLAGS_INEXACT, flags); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 43); + mpfr_set_str_binary (x, "1.11000101010111011000111100101001e6"); + mpfr_erfc (y, x, MPFR_RNDD); + mpfr_set_prec (x, 43); + mpfr_set_str_binary (x, "100010011100101100001101100101011101101E-18579"); + if (mpfr_cmp (x, y) != 0) + { + printf ("mpfr_erfc failed for large x (2)\n"); + exit (1); + } + + mpfr_set_prec (y, 43); + mpfr_set_si_2exp (x, 1, 11, MPFR_RNDN); + mpfr_erfc (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100000100100010101111001111010010001000110E-6051113"); + if (mpfr_cmp (x, y) != 0) + { + printf ("mpfr_erfc failed for large x (3)\n"); + exit (1); + } + + mpfr_set_prec (x, 75); + mpfr_set_prec (y, 85); + mpfr_set_str_binary (x, "0.111110111111010011101011001100001010011110101010011111010010111101010001011E15"); + mpfr_erfc (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("mpfr_erfc failed for large x (3b)\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 21); + mpfr_set_str_binary (x, "-1.0e3"); + mpfr_clear_flags (); + mpfr_erfc (y, x, MPFR_RNDZ); + flags = __gmpfr_flags; + mpfr_set_prec (x, 21); + mpfr_set_str_binary (x, "1.11111111111111111111"); + if (mpfr_cmp (x, y) != 0) + { + printf ("mpfr_erfc failed for large x (4)\n"); + exit (1); + } + if (flags != MPFR_FLAGS_INEXACT) + { + printf ("mpfr_erfc sets incorrect flags for large x (4)\n"); + printf ("Expected %u, got %u\n", + (unsigned int) MPFR_FLAGS_INEXACT, flags); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 31); + mpfr_set_str_binary (x, "-1.0e3"); + mpfr_clear_flags (); + mpfr_erfc (y, x, MPFR_RNDZ); + flags = __gmpfr_flags; + mpfr_set_prec (x, 31); + mpfr_set_str_binary (x, "1.111111111111111111111111111111"); + if (mpfr_cmp (x, y) != 0) + { + printf ("mpfr_erfc failed for x=-8, prec=31 (5)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + if (flags != MPFR_FLAGS_INEXACT) + { + printf ("mpfr_erfc sets incorrect flags for large x (5)\n"); + printf ("Expected %u, got %u\n", + (unsigned int) MPFR_FLAGS_INEXACT, flags); + exit (1); + } + + /* Reported by Christopher Creutzig on 2007-07-10. */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN); + mpfr_erfc (y, x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDN); + if (! mpfr_equal_p (y, x)) + { + printf ("mpfr_erfc failed for x=27281.5, prec=53 (6)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + /* same test with rounding away from zero */ + mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN); + mpfr_erfc (y, x, MPFR_RNDU); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_nextabove (x); + if (! mpfr_equal_p (y, x)) + { + printf ("mpfr_erfc failed for x=27281.5, prec=53 (7)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +test_erfc (void) +{ + mpfr_t x, y, z; + int inex; + mpfr_exp_t emin; + + mpfr_inits2 (40, x, y, z, (mpfr_ptr) 0); + + mpfr_set_si_2exp (x, -1, -10, MPFR_RNDN); + mpfr_set_str_binary (z, "0.1000000000100100000110111010110111100000E1"); + mpfr_erfc (y, x, MPFR_RNDN); + if (mpfr_cmp (y, z) != 0) + { + printf ("mpfr_erfc failed for x = "); + mpfr_dump (x); + printf ("got "); + mpfr_dump (y); + printf ("instead of "); + mpfr_dump (z); + exit (1); + } + + /* slowness detected by Kevin Rauch on 26 Oct 2007 */ + mpfr_set_prec (x, 128); + mpfr_set_si (x, -256, MPFR_RNDN); + inex = mpfr_erfc (x, x, MPFR_RNDN); + MPFR_ASSERTN(inex > 0 && mpfr_cmp_ui (x, 2) == 0); + + /* bug found by Pascal Molin on March 10, 2011 */ + emin = mpfr_get_emin (); + if (! mpfr_set_emin (-1073808789)) + { + /* Typically, a 64-bit machine. */ + mpfr_set_si (x, 27282, MPFR_RNDN); + mpfr_erfc (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) != 0); + mpfr_set_emin (emin); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +/* Failure in r7569 (2011-03-15) due to incorrect flags. */ +static void +reduced_expo_range (void) +{ + mpfr_exp_t emax; + mpfr_t x, y, ex_y; + int inex, ex_inex; + unsigned int flags, ex_flags; + + emax = mpfr_get_emax (); + mpfr_set_emax (3); + mpfr_init2 (x, 33); + mpfr_inits2 (110, y, ex_y, (mpfr_ptr) 0); + mpfr_set_str_binary (x, "-0.111100110111111111011101010101110E3"); + mpfr_clear_flags (); + inex = mpfr_erfc (y, x, MPFR_RNDZ); + flags = __gmpfr_flags; + mpfr_set_str (ex_y, "1.fffffffffffffffffffffe607440", 16, MPFR_RNDN); + ex_inex = -1; + ex_flags = MPFR_FLAGS_INEXACT; + if (SIGN (inex) != ex_inex || flags != ex_flags || + ! mpfr_equal_p (y, ex_y)) + { + printf ("Error in reduced_expo_range\non x = "); + mpfr_dump (x); + printf ("Expected y = "); + mpfr_out_str (stdout, 16, 0, ex_y, MPFR_RNDN); + printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); + printf ("Got y = "); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); + exit (1); + } + mpfr_clears (x, y, ex_y, (mpfr_ptr) 0); + mpfr_set_emax (emax); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special_erf (); + special_erfc (); + large_arg (); + test_erfc (); + reduced_expo_range (); + + test_generic_erf (2, 100, 15); + test_generic_erfc (2, 100, 15); + + data_check ("data/erf", mpfr_erf, "mpfr_erf"); + data_check ("data/erfc", mpfr_erfc, "mpfr_erfc"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tests.c b/mpfr/tests/tests.c new file mode 100644 index 0000000000..d6cb743799 --- /dev/null +++ b/mpfr/tests/tests.c @@ -0,0 +1,1023 @@ +/* Miscellaneous support for test programs. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# if HAVE_CONFIG_H +# include "config.h" /* for a build within gmp */ +# endif +#endif + +#include <stdlib.h> +#include <float.h> +#include <errno.h> + +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif + +#ifdef MPFR_TEST_DIVBYZERO +# include <fenv.h> +#endif + +#ifdef TIME_WITH_SYS_TIME +# include <sys/time.h> /* for struct timeval */ +# include <time.h> +#elif defined HAVE_SYS_TIME_H +# include <sys/time.h> +#else +# include <time.h> +#endif + +/* <sys/fpu.h> is needed to have union fpc_csr defined under IRIX64 + (see below). Let's include it only if need be. */ +#if defined HAVE_SYS_FPU_H && defined HAVE_FPC_CSR +# include <sys/fpu.h> +#endif + +#ifdef MPFR_TESTS_TIMEOUT +#include <sys/resource.h> +#endif + +#include "mpfr-test.h" + +#ifdef MPFR_FPU_PREC +/* This option allows to test MPFR on x86 processors when the FPU + * rounding precision has been changed. As MPFR is a library, this can + * occur in practice, either by the calling software or by some other + * library or plug-in used by the calling software. This option is + * mainly for developers. If it is used, then the <fpu_control.h> + * header is assumed to exist and work like under Linux/x86. MPFR does + * not need to be recompiled. So, a possible usage is the following: + * + * cd tests + * make clean + * make check CFLAGS="-g -O2 -ffloat-store -DMPFR_FPU_PREC=_FPU_SINGLE" + * + * i.e. just add -DMPFR_FPU_PREC=... to the CFLAGS found in Makefile. + * + * Notes: + * + SSE2 (used to implement double's on x86_64, and possibly on x86 + * too, depending on the compiler configuration and flags) is not + * affected by the dynamic precision. + * + When the FPU is set to single precision, the behavior of MPFR + * functions that have a native floating-point type (float, double, + * long double) as argument or return value is not guaranteed. + */ + +#include <fpu_control.h> + +static void +set_fpu_prec (void) +{ + fpu_control_t cw; + + _FPU_GETCW(cw); + cw &= ~(_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE); + cw |= (MPFR_FPU_PREC); + _FPU_SETCW(cw); +} + +#endif + +static mpfr_exp_t default_emin, default_emax; + +static void tests_rand_start (void); +static void tests_rand_end (void); +static void tests_limit_start (void); + +/* We want to always import the function mpfr_dump inside the test + suite, so that we can use it in GDB. But it doesn't work if we build + a Windows DLL (initializer element is not a constant) */ +#if !__GMP_LIBGMP_DLL +extern void (*dummy_func) (mpfr_srcptr); +void (*dummy_func)(mpfr_srcptr) = mpfr_dump; +#endif + +/* Various version checks. + A mismatch on the GMP version is not regarded as fatal. A mismatch + on the MPFR version is regarded as fatal, since this means that we + would not check the MPFR library that has just been built (the goal + of "make check") but a different library that is already installed, + i.e. any test result would be meaningless; in such a case, we exit + immediately with an error (exit status = 1). + Return value: 0 for no errors, 1 in case of any non-fatal error. */ +int +test_version (void) +{ + const char *version; + char buffer[256]; + int err = 0; + + sprintf (buffer, "%d.%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, + __GNU_MP_VERSION_PATCHLEVEL); + if (strcmp (buffer, gmp_version) != 0 && + (__GNU_MP_VERSION_PATCHLEVEL != 0 || + (sprintf (buffer, "%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR), + strcmp (buffer, gmp_version) != 0))) + err = 1; + + /* In some cases, it may be acceptable to have different versions for + the header and the library, in particular when shared libraries are + used (e.g., after a bug-fix upgrade of the library, and versioning + ensures that this can be done only when the binary interface is + compatible). However, when recompiling software like here, this + should never happen (except if GMP has been upgraded between two + "make check" runs, but there's no reason for that). A difference + between the versions of gmp.h and libgmp probably indicates either + a bad configuration or some other inconsistency in the development + environment, and it is better to fail (in particular for automatic + installations). */ + if (err) + { + printf ("ERROR! The versions of gmp.h (%s) and libgmp (%s) do not " + "match.\nThe possible causes are:\n", buffer, gmp_version); + printf (" * A bad configuration in your include/library search paths.\n" + " * An inconsistency in the include/library search paths of\n" + " your development environment; an example:\n" + " http://gcc.gnu.org/ml/gcc-help/2010-11/msg00359.html\n" + " * GMP has been upgraded after the first \"make check\".\n" + " In such a case, try again after a \"make clean\".\n" + " * A new or non-standard version naming is used in GMP.\n" + " In this case, a patch may already be available on the\n" + " MPFR web site. Otherwise please report the problem.\n"); + printf ("In the first two cases, this may lead to errors, in particular" + " with MPFR.\nIf some other tests fail, please solve that" + " problem first.\n"); + } + + /* VL: I get the following error on an OpenSUSE machine, and changing + the value of shlibpath_overrides_runpath in the libtool file from + 'no' to 'yes' fixes the problem. */ + + version = mpfr_get_version (); + if (strcmp (MPFR_VERSION_STRING, version) == 0) + { + char buffer[16]; + int i; + + sprintf (buffer, "%d.%d.%d", MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, + MPFR_VERSION_PATCHLEVEL); + for (i = 0; buffer[i] == version[i]; i++) + if (buffer[i] == '\0') + return err; + if (buffer[i] == '\0' && version[i] == '-') + return err; + printf ("%sMPFR_VERSION_MAJOR.MPFR_VERSION_MINOR.MPFR_VERSION_PATCHLEVEL" + " (%s)\nand MPFR_VERSION_STRING (%s) do not match!\nIt seems " + "that the mpfr.h file has been corrupted.\n", err ? "\n" : "", + buffer, version); + } + else + printf ( + "%sIncorrect MPFR version! (%s header vs %s library)\n" + "Nothing else has been tested since for this reason, any other test\n" + "may fail. Please fix this problem first, as suggested below. It\n" + "probably comes from libtool (included in the MPFR tarball), which\n" + "is responsible for setting up the search paths depending on the\n" + "platform, or automake.\n" + " * On some platforms such as Solaris, $LD_LIBRARY_PATH overrides\n" + " the rpath, and if the MPFR library is already installed in a\n" + " $LD_LIBRARY_PATH directory, you typically get this error. Do\n" + " not use $LD_LIBRARY_PATH on such platforms; it may also break\n" + " other things.\n" + " * Then look at http://www.mpfr.org/mpfr-current/ for any update.\n" + " * Try again on a completely clean source (some errors might come\n" + " from a previous build or previous source changes).\n" + " * If the error still occurs, you can try to change the value of\n" + " shlibpath_overrides_runpath ('yes' or 'no') in the \"libtool\"\n" + " file and rebuild MPFR (make clean && make && make check). You\n" + " may want to report the problem to the libtool and/or automake\n" + " developers, with the effect of this change.\n", + err ? "\n" : "", MPFR_VERSION_STRING, version); + /* Note about $LD_LIBRARY_PATH under Solaris: + * https://en.wikipedia.org/wiki/Rpath#Solaris_ld.so + * This cause has been confirmed by a user who got this error. + */ + exit (1); +} + +void +tests_start_mpfr (void) +{ + test_version (); + + /* don't buffer, so output is not lost if a test causes a segv etc */ + setbuf (stdout, NULL); + +#if defined HAVE_LOCALE_H && defined HAVE_SETLOCALE + /* Added on 2005-07-09. This allows to test MPFR under various + locales. New bugs will probably be found, in particular with + LC_ALL="tr_TR.ISO8859-9" because of the i/I character... */ + setlocale (LC_ALL, ""); +#endif + +#ifdef MPFR_FPU_PREC + set_fpu_prec (); +#endif + +#ifdef MPFR_TEST_DIVBYZERO + /* Define to test the use of MPFR_ERRDIVZERO */ + feclearexcept (FE_ALL_EXCEPT); +#endif + + tests_memory_start (); + tests_rand_start (); + tests_limit_start (); + + default_emin = mpfr_get_emin (); + default_emax = mpfr_get_emax (); +} + +void +tests_end_mpfr (void) +{ + int err = 0; + + if (mpfr_get_emin () != default_emin) + { + printf ("Default emin value has not been restored!\n"); + err = 1; + } + + if (mpfr_get_emax () != default_emax) + { + printf ("Default emax value has not been restored!\n"); + err = 1; + } + + mpfr_free_cache (); + tests_rand_end (); + tests_memory_end (); + +#ifdef MPFR_TEST_DIVBYZERO + /* Define to test the use of MPFR_ERRDIVZERO */ + if (fetestexcept (FE_DIVBYZERO|FE_INVALID)) + { + printf ("A floating-point division by 0 or an invalid operation" + " occurred!\n"); +#ifdef MPFR_ERRDIVZERO + /* This should never occur because the purpose of defining + MPFR_ERRDIVZERO is to avoid all the FP divisions by 0. */ + err = 1; +#endif + } +#endif + + if (err) + exit (err); +} + +static void +tests_limit_start (void) +{ +#ifdef MPFR_TESTS_TIMEOUT + struct rlimit rlim[1]; + char *timeoutp; + int timeout; + + timeoutp = getenv ("MPFR_TESTS_TIMEOUT"); + timeout = timeoutp != NULL ? atoi (timeoutp) : MPFR_TESTS_TIMEOUT; + if (timeout > 0) + { + /* We need to call getrlimit first to initialize rlim_max to + an acceptable value for setrlimit. When enabled, timeouts + are regarded as important: we don't want to take too much + CPU time on machines shared with other users. So, if we + can't set the timeout, we exit immediately. */ + if (getrlimit (RLIMIT_CPU, rlim)) + { + printf ("Error: getrlimit failed\n"); + exit (1); + } + rlim->rlim_cur = timeout; + if (setrlimit (RLIMIT_CPU, rlim)) + { + printf ("Error: setrlimit failed\n"); + exit (1); + } + } +#endif +} + +static void +tests_rand_start (void) +{ + gmp_randstate_ptr rands; + char *perform_seed; + unsigned long seed; + + if (__gmp_rands_initialized) + { + printf ( + "Please let tests_start() initialize the global __gmp_rands, i.e.\n" + "ensure that function is called before the first use of RANDS.\n"); + exit (1); + } + + gmp_randinit_default (__gmp_rands); + __gmp_rands_initialized = 1; + rands = __gmp_rands; + + perform_seed = getenv ("GMP_CHECK_RANDOMIZE"); + if (perform_seed != NULL) + { + seed = strtoul (perform_seed, NULL, 10); + if (! (seed == 0 || seed == 1)) + { + printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed); + gmp_randseed_ui (rands, seed); + } + else + { +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + gettimeofday (&tv, NULL); + seed = tv.tv_sec + tv.tv_usec; +#else + time_t tv; + time (&tv); + seed = tv; +#endif + gmp_randseed_ui (rands, seed); + printf ("Seed GMP_CHECK_RANDOMIZE=%lu " + "(include this in bug reports)\n", seed); + } + } + else + gmp_randseed_ui (rands, 0x2143FEDC); +} + +static void +tests_rand_end (void) +{ + RANDS_CLEAR (); +} + +/* initialization function for tests using the hardware floats + Not very useful now. */ +void +mpfr_test_init (void) +{ +#ifdef HAVE_FPC_CSR + /* to get subnormal 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 + +#ifdef HAVE_DENORMS + { + double d = DBL_MIN; + if (2.0 * (d / 2.0) != d) + { + printf ("Error: HAVE_DENORMS defined, but no subnormals.\n"); + exit (1); + } + } +#endif + + /* generate DBL_EPSILON with a loop to avoid that the compiler + optimizes the code below in non-IEEE 754 mode, deciding that + c = d is always false. */ +#if 0 + for (eps = 1.0; eps != DBL_EPSILON; eps /= 2.0); + c = 1.0 + eps; + d = eps * (1.0 - eps) / 2.0; + d += c; + if (c != d) + { + printf ("Warning: IEEE 754 standard not fully supported\n" + " (maybe extended precision not disabled)\n" + " Some tests may fail\n"); + } +#endif +} + + +/* generate a random limb */ +mp_limb_t +randlimb (void) +{ + mp_limb_t limb; + + mpfr_rand_raw (&limb, RANDS, GMP_NUMB_BITS); + return limb; +} + +/* returns ulp(x) for x a 'normal' double-precision number */ +double +Ulp (double x) +{ + double y, eps; + + if (x < 0) x = -x; + + y = x * 2.220446049250313080847263336181640625e-16 ; /* x / 2^52 */ + + /* as ulp(x) <= y = x/2^52 < 2*ulp(x), + we have x + ulp(x) <= x + y <= x + 2*ulp(x), + therefore o(x + y) = x + ulp(x) or x + 2*ulp(x) */ + + eps = x + y; + eps = eps - x; /* ulp(x) or 2*ulp(x) */ + + return (eps > y) ? 0.5 * eps : eps; +} + +/* returns the number of ulp's between a and b, + where a and b can be any floating-point number, except NaN + */ +int +ulp (double a, double b) +{ + double twoa; + + if (a == b) return 0; /* also deals with a=b=inf or -inf */ + + twoa = a + a; + if (twoa == a) /* a is +/-0.0 or +/-Inf */ + return ((b < a) ? INT_MAX : -INT_MAX); + + return (int) ((a - b) / Ulp (a)); +} + +/* return double m*2^e */ +double +dbl (double m, int e) +{ + if (e >=0 ) + while (e-- > 0) + m *= 2.0; + else + while (e++ < 0) + m /= 2.0; + return m; +} + +/* Warning: NaN values cannot be distinguished if MPFR_NANISNAN is defined. */ +int +Isnan (double d) +{ + return (d) != (d); +} + +void +d_trace (const char *name, double d) +{ + union { + double d; + unsigned char b[sizeof(double)]; + } u; + int i; + + if (name != NULL && name[0] != '\0') + printf ("%s=", name); + + u.d = d; + printf ("["); + for (i = 0; i < (int) sizeof (u.b); i++) + { + if (i != 0) + printf (" "); + printf ("%02X", (int) u.b[i]); + } + printf ("] %.20g\n", d); +} + +void +ld_trace (const char *name, long double ld) +{ + union { + long double ld; + unsigned char b[sizeof(long double)]; + } u; + int i; + + if (name != NULL && name[0] != '\0') + printf ("%s=", name); + + u.ld = ld; + printf ("["); + for (i = 0; i < (int) sizeof (u.b); i++) + { + if (i != 0) + printf (" "); + printf ("%02X", (int) u.b[i]); + } + printf ("] %.20Lg\n", ld); +} + +/* Open a file in the src directory - can't use fopen directly */ +FILE * +src_fopen (const char *filename, const char *mode) +{ +#ifndef SRCDIR + return fopen (filename, mode); +#else + const char *srcdir = SRCDIR; + char *buffer; + size_t buffsize; + FILE *f; + + buffsize = strlen (filename) + strlen (srcdir) + 2; + buffer = (char *) tests_allocate (buffsize); + if (buffer == NULL) + { + printf ("src_fopen: failed to alloc memory)\n"); + exit (1); + } + sprintf (buffer, "%s/%s", srcdir, filename); + f = fopen (buffer, mode); + tests_free (buffer, buffsize); + return f; +#endif +} + +void +set_emin (mpfr_exp_t exponent) +{ + if (mpfr_set_emin (exponent)) + { + printf ("set_emin: setting emin to %ld failed\n", (long int) exponent); + exit (1); + } +} + +void +set_emax (mpfr_exp_t exponent) +{ + if (mpfr_set_emax (exponent)) + { + printf ("set_emax: setting emax to %ld failed\n", (long int) exponent); + exit (1); + } +} + +/* pos is 512 times the proportion of negative numbers. + If pos=256, half of the numbers are negative. + If pos=0, all generated numbers are positive. +*/ +void +tests_default_random (mpfr_ptr x, int pos, mpfr_exp_t emin, mpfr_exp_t emax, + int always_scale) +{ + MPFR_ASSERTN (emin <= emax); + MPFR_ASSERTN (emin >= MPFR_EMIN_MIN); + MPFR_ASSERTN (emax <= MPFR_EMAX_MAX); + /* but it isn't required that emin and emax are in the current + exponent range (see below), so that underflow/overflow checks + can be done on 64-bit machines. */ + + mpfr_urandomb (x, RANDS); + if (MPFR_IS_PURE_FP (x) && (emin >= 1 || always_scale || (randlimb () & 1))) + { + mpfr_exp_t e; + e = MPFR_GET_EXP (x) + + (emin + (mpfr_exp_t) (randlimb () % (emax - emin + 1))); + /* Note: There should be no overflow here because both terms are + between MPFR_EMIN_MIN and MPFR_EMAX_MAX, but the sum e isn't + necessarily between MPFR_EMIN_MIN and MPFR_EMAX_MAX. */ + if (mpfr_set_exp (x, e)) + { + /* The random number doesn't fit in the current exponent range. + In this case, test the function in the extended exponent range, + which should be restored by the caller. */ + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_set_emax (MPFR_EMAX_MAX); + mpfr_set_exp (x, e); + } + } + if (randlimb () % 512 < pos) + mpfr_neg (x, x, MPFR_RNDN); +} + +/* The test_one argument is seen a boolean. If it is true and rnd is + a rounding mode toward infinity, then the function is tested in + only one rounding mode (the one provided in rnd) and the variable + rndnext is not used (due to the break). If it is true and rnd is a + rounding mode toward or away from zero, then the function is tested + twice, first with the provided rounding mode and second with the + rounding mode toward the corresponding infinity (determined by the + sign of the result). If it is false, then the function is tested + in the 5 rounding modes, and rnd must initially be MPFR_RNDZ; thus + rndnext will be initialized in the first iteration. + If the test_one argument is 2, then this means that y is exact, and + the ternary value is checked. + As examples of use, see the calls to test5rm from the data_check and + bad_cases functions. */ +static void +test5rm (int (*fct) (FLIST), mpfr_srcptr x, mpfr_ptr y, mpfr_ptr z, + mpfr_rnd_t rnd, int test_one, const char *name) +{ + mpfr_prec_t yprec = MPFR_PREC (y); + mpfr_rnd_t rndnext = MPFR_RND_MAX; /* means uninitialized */ + + MPFR_ASSERTN (test_one || rnd == MPFR_RNDZ); + mpfr_set_prec (z, yprec); + while (1) + { + int inex; + + MPFR_ASSERTN (rnd != MPFR_RND_MAX); + inex = fct (z, x, rnd); + if (! (mpfr_equal_p (y, z) || (mpfr_nan_p (y) && mpfr_nan_p (z)))) + { + printf ("Error for %s with xprec=%lu, yprec=%lu, rnd=%s\nx = ", + name, (unsigned long) MPFR_PREC (x), (unsigned long) yprec, + mpfr_print_rnd_mode (rnd)); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\nexpected "); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (test_one == 2 && inex != 0) + { + printf ("Error for %s with xprec=%lu, yprec=%lu, rnd=%s\nx = ", + name, (unsigned long) MPFR_PREC (x), (unsigned long) yprec, + mpfr_print_rnd_mode (rnd)); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\nexact case, but non-zero ternary value (%d)\n", inex); + exit (1); + } + if (rnd == MPFR_RNDN) + break; + + if (test_one) + { + if (rnd == MPFR_RNDU || rnd == MPFR_RNDD) + break; + + if (MPFR_IS_NEG (y)) + rnd = (rnd == MPFR_RNDA) ? MPFR_RNDD : MPFR_RNDU; + else + rnd = (rnd == MPFR_RNDA) ? MPFR_RNDU : MPFR_RNDD; + } + else if (rnd == MPFR_RNDZ) + { + rnd = MPFR_IS_NEG (y) ? MPFR_RNDU : MPFR_RNDD; + rndnext = MPFR_RNDA; + } + else + { + rnd = rndnext; + if (rnd == MPFR_RNDA) + { + mpfr_nexttoinf (y); + rndnext = (MPFR_IS_NEG (y)) ? MPFR_RNDD : MPFR_RNDU; + } + else if (rndnext != MPFR_RNDN) + rndnext = MPFR_RNDN; + else + { + if (yprec == MPFR_PREC_MIN) + break; + mpfr_prec_round (y, --yprec, MPFR_RNDZ); + mpfr_set_prec (z, yprec); + } + } + } +} + +/* Check data in file f for function foo, with name 'name'. + Each line consists of the file f one: + + xprec yprec rnd x y + + where: + + xprec is the input precision + yprec is the output precision + rnd is the rounding mode (n, z, u, d, a, Z, *) + x is the input (hexadecimal format) + y is the expected output (hexadecimal format) for foo(x) with rounding rnd + + If rnd is Z, y is the expected output in round-toward-zero, and the + four directed rounding modes are tested, then the round-to-nearest + mode is tested in precision yprec-1. This is useful for worst cases, + where yprec is the minimum value such that one has a worst case in a + directed rounding mode. + + If rnd is *, y must be an exact case. All the rounding modes are tested + and the ternary value is checked (it must be 0). + */ +void +data_check (const char *f, int (*foo) (FLIST), const char *name) +{ + FILE *fp; + long int xprec, yprec; /* not mpfr_prec_t because of the fscanf */ + mpfr_t x, y, z; + mpfr_rnd_t rnd; + char r; + int c; + + fp = fopen (f, "r"); + if (fp == NULL) + fp = src_fopen (f, "r"); + if (fp == NULL) + { + char *v = (char *) MPFR_VERSION_STRING; + + /* In the '-dev' versions, assume that the data file exists and + return an error if the file cannot be opened to make sure + that such failures are detected. */ + while (*v != '\0') + v++; + if (v[-4] == '-' && v[-3] == 'd' && v[-2] == 'e' && v[-1] == 'v') + { + printf ("Error: unable to open file '%s'\n", f); + exit (1); + } + else + return; + } + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + while (!feof (fp)) + { + /* skip whitespace, for consistency */ + if (fscanf (fp, " ") == EOF) + { + if (ferror (fp)) + { + perror ("data_check"); + exit (1); + } + else + break; /* end of file */ + } + + if ((c = getc (fp)) == EOF) + { + if (ferror (fp)) + { + perror ("data_check"); + exit (1); + } + else + break; /* end of file */ + } + + if (c == '#') /* comment: read entire line */ + { + do + { + c = getc (fp); + } + while (!feof (fp) && c != '\n'); + } + else + { + ungetc (c, fp); + + c = fscanf (fp, "%ld %ld %c", &xprec, &yprec, &r); + MPFR_ASSERTN (xprec >= MPFR_PREC_MIN && xprec <= MPFR_PREC_MAX); + MPFR_ASSERTN (yprec >= MPFR_PREC_MIN && yprec <= MPFR_PREC_MAX); + if (c == EOF) + { + perror ("data_check"); + exit (1); + } + else if (c != 3) + { + printf ("Error: corrupted line in file '%s'\n", f); + exit (1); + } + + switch (r) + { + case 'n': + rnd = MPFR_RNDN; + break; + case 'z': case 'Z': + rnd = MPFR_RNDZ; + break; + case 'u': + rnd = MPFR_RNDU; + break; + case 'd': + rnd = MPFR_RNDD; + break; + case '*': + rnd = MPFR_RND_MAX; /* non-existing rounding mode */ + break; + default: + printf ("Error: unexpected rounding mode" + " in file '%s': %c\n", f, (int) r); + exit (1); + } + mpfr_set_prec (x, xprec); + mpfr_set_prec (y, yprec); + if (mpfr_inp_str (x, fp, 0, MPFR_RNDN) == 0) + { + printf ("Error: corrupted argument in file '%s'\n", f); + exit (1); + } + if (mpfr_inp_str (y, fp, 0, MPFR_RNDN) == 0) + { + printf ("Error: corrupted result in file '%s'\n", f); + exit (1); + } + if (getc (fp) != '\n') + { + printf ("Error: result not followed by \\n in file '%s'\n", f); + exit (1); + } + /* Skip whitespace, in particular at the end of the file. */ + if (fscanf (fp, " ") == EOF && ferror (fp)) + { + perror ("data_check"); + exit (1); + } + if (r == '*') + { + int rndint; + RND_LOOP (rndint) + test5rm (foo, x, y, z, (mpfr_rnd_t) rndint, 2, name); + } + else + test5rm (foo, x, y, z, rnd, r != 'Z', name); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + fclose (fp); +} + +/* Test n random bad cases. A precision py in [pymin,pymax] and + * a number y of precision py are chosen randomly. One computes + * x = inv(y) in precision px = py + psup (rounded to nearest). + * Then (in general), y is a bad case for fct in precision py (in + * the directed rounding modes, but also in the rounding-to-nearest + * mode for some lower precision: see data_check). + * fct, inv, name: data related to the function. + * pos, emin, emax: arguments for tests_default_random. + */ +void +bad_cases (int (*fct)(FLIST), int (*inv)(FLIST), const char *name, + int pos, mpfr_exp_t emin, mpfr_exp_t emax, + mpfr_prec_t pymin, mpfr_prec_t pymax, mpfr_prec_t psup, + int n) +{ + mpfr_t x, y, z; + char *dbgenv; + int i, dbg; + mpfr_exp_t old_emin, old_emax; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + dbgenv = getenv ("MPFR_DEBUG_BADCASES"); + dbg = dbgenv != 0 ? atoi (dbgenv) : 0; /* debug level */ + mpfr_inits (x, y, z, (mpfr_ptr) 0); + for (i = 0; i < n; i++) + { + mpfr_prec_t px, py, pz; + int inex; + + if (dbg) + printf ("bad_cases: i = %d\n", i); + py = pymin + (randlimb () % (pymax - pymin + 1)); + mpfr_set_prec (y, py); + tests_default_random (y, pos, emin, emax, 0); + if (dbg) + { + printf ("bad_cases: yprec =%4ld, y = ", (long) py); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\n"); + } + px = py + psup; + mpfr_set_prec (x, px); + mpfr_clear_flags (); + inv (x, y, MPFR_RNDN); + if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ()) + { + if (dbg) + printf ("bad_cases: no normal inverse\n"); + goto next_i; + } + if (dbg > 1) + { + printf ("bad_cases: x = "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + } + pz = px; + do + { + pz += 32; + mpfr_set_prec (z, pz); + if (fct (z, x, MPFR_RNDN) == 0) + { + if (dbg) + printf ("bad_cases: exact case\n"); + goto next_i; + } + if (dbg) + { + if (dbg > 1) + { + printf ("bad_cases: %s(x) ~= ", name); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + } + else + { + printf ("bad_cases: [MPFR_RNDZ] ~= "); + mpfr_out_str (stdout, 16, 40, z, MPFR_RNDZ); + } + printf ("\n"); + } + inex = mpfr_prec_round (z, py, MPFR_RNDN); + if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p () + || ! mpfr_equal_p (z, y)) + { + if (dbg) + printf ("bad_cases: inverse doesn't match\n"); + goto next_i; + } + } + while (inex == 0); + /* We really have a bad case. */ + do + py--; + while (py >= MPFR_PREC_MIN && mpfr_prec_round (z, py, MPFR_RNDZ) == 0); + py++; + /* py is now the smallest output precision such that we have + a bad case in the directed rounding modes. */ + if (mpfr_prec_round (y, py, MPFR_RNDZ) != 0) + { + printf ("Internal error for i = %d\n", i); + exit (1); + } + if ((inex > 0 && MPFR_IS_POS (z)) || + (inex < 0 && MPFR_IS_NEG (z))) + { + mpfr_nexttozero (y); + if (mpfr_zero_p (y)) + goto next_i; + } + if (dbg) + { + printf ("bad_cases: yprec =%4ld, y = ", (long) py); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\n"); + } + /* Note: y is now the expected result rounded toward zero. */ + test5rm (fct, x, y, z, MPFR_RNDZ, 0, name); + next_i: + /* In case the exponent range has been changed by + tests_default_random()... */ + mpfr_set_emin (old_emin); + mpfr_set_emax (old_emax); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +void +flags_out (unsigned int flags) +{ + int none = 1; + + if (flags & MPFR_FLAGS_UNDERFLOW) + none = 0, printf (" underflow"); + if (flags & MPFR_FLAGS_OVERFLOW) + none = 0, printf (" overflow"); + if (flags & MPFR_FLAGS_NAN) + none = 0, printf (" nan"); + if (flags & MPFR_FLAGS_INEXACT) + none = 0, printf (" inexact"); + if (flags & MPFR_FLAGS_ERANGE) + none = 0, printf (" erange"); + if (none) + printf (" none"); + printf (" (%u)\n", flags); +} diff --git a/mpfr/tests/texceptions.c b/mpfr/tests/texceptions.c new file mode 100644 index 0000000000..4aca9de76f --- /dev/null +++ b/mpfr/tests/texceptions.c @@ -0,0 +1,446 @@ +/* Test file for exceptions. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define ERROR(s) do { printf(s"\n"); exit(1); } while(0) + +/* Test powerof2 */ +static void +check_powerof2 (void) +{ + mpfr_t x; + + mpfr_init (x); + mpfr_set_ui (x, 1, MPFR_RNDN); + MPFR_ASSERTN (mpfr_powerof2_raw (x)); + mpfr_set_ui (x, 3, MPFR_RNDN); + MPFR_ASSERTN (!mpfr_powerof2_raw (x)); + mpfr_clear (x); +} + +/* Test default rounding mode */ +static void +check_default_rnd (void) +{ + int r; + mpfr_rnd_t t; + for(r = 0 ; r < MPFR_RND_MAX ; r++) + { + mpfr_set_default_rounding_mode ((mpfr_rnd_t) r); + t = (mpfr_get_default_rounding_mode) (); + if ((mpfr_rnd_t) r != t) + { + printf ("%s %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), + mpfr_print_rnd_mode (t)); + ERROR("ERROR in setting / getting default rounding mode (1)"); + } + } + mpfr_set_default_rounding_mode ((mpfr_rnd_t) MPFR_RND_MAX); + if (mpfr_get_default_rounding_mode() != MPFR_RNDA) + ERROR("ERROR in setting / getting default rounding mode (2)"); + mpfr_set_default_rounding_mode((mpfr_rnd_t) -1); + if (mpfr_get_default_rounding_mode() != MPFR_RNDA) + ERROR("ERROR in setting / getting default rounding mode (3)"); +} + +static void +check_emin_emax (void) +{ + mpfr_exp_t old_emin, old_emax; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + /* Check the functions not the macros ! */ + if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0) + ERROR("set_emin failed!"); + if ((mpfr_get_emin)() != MPFR_EMIN_MIN) + ERROR("get_emin FAILED!"); + if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0) + ERROR("set_emin failed! (2)"); + + if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0) + ERROR("set_emax failed!"); + if ((mpfr_get_emax)() != MPFR_EMAX_MAX) + ERROR("get_emax FAILED!"); + if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0) + ERROR("set_emax failed! (2)"); + + if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN) + ERROR ("get_emin_min"); + if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX) + ERROR ("get_emin_max"); + if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN) + ERROR ("get_emax_min"); + if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX) + ERROR ("get_emax_max"); + + set_emin (old_emin); + set_emax (old_emax); +} + +static void +check_set_get_prec (void) +{ + mpfr_t x; + + mpfr_init2 (x, 17); + if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17) + ERROR ("mpfr_get_prec"); + mpfr_clear (x); +} + +static void +mpfr_set_double_range (void) +{ + mpfr_set_default_prec (54); + if (mpfr_get_default_prec () != 54) + ERROR ("get_default_prec failed (1)"); + mpfr_set_default_prec (53); + if ((mpfr_get_default_prec) () != 53) + ERROR ("get_default_prec failed (2)"); + + /* in double precision format, the unbiased exponent is between 0 and + 2047, where 0 is used for subnormal numbers, and 2047 for special + numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers + have an exponent between -1022 and 1023, corresponding to numbers + between 2^(-1022) and previous(2^(1024)). + (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).) + + The smallest normal power of two is 1.0*2^(-1022). + The largest normal power of two is 2^1023. + (We have to add one for mpfr since mantissa are between 1/2 and 1.) + */ + + set_emin (-1021); + set_emax (1024); +} + +static void +check_flags (void) +{ + mpfr_t x; + mpfr_exp_t old_emin, old_emax; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + mpfr_init (x); + + /* Check the functions not the macros ! */ + (mpfr_clear_flags)(); + mpfr_set_double_range (); + + mpfr_set_ui (x, 1, MPFR_RNDN); + (mpfr_clear_overflow)(); + mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); + if (!(mpfr_overflow_p)()) + ERROR("ERROR: No overflow detected!\n"); + + (mpfr_clear_underflow)(); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2exp (x, x, 1025, MPFR_RNDN); + if (!(mpfr_underflow_p)()) + ERROR("ERROR: No underflow detected!\n"); + + (mpfr_clear_nanflag)(); + MPFR_SET_NAN(x); + mpfr_add (x, x, x, MPFR_RNDN); + if (!(mpfr_nanflag_p)()) + ERROR("ERROR: No NaN flag!\n"); + + (mpfr_clear_inexflag)(); + mpfr_set_ui(x, 2, MPFR_RNDN); + mpfr_cos(x, x, MPFR_RNDN); + if (!(mpfr_inexflag_p)()) + ERROR("ERROR: No inexact flag!\n"); + + (mpfr_clear_erangeflag) (); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); + mpfr_get_ui (x, MPFR_RNDN); + if (!(mpfr_erangeflag_p)()) + ERROR ("ERROR: No erange flag!\n"); + + mpfr_clear (x); + set_emin (old_emin); + set_emax (old_emax); +} + +static void +test_set_underflow (void) +{ + mpfr_t x, zero, min; + mpfr_ptr r[MPFR_RND_MAX]; + int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */ + int i; + int s; + + mpfr_inits (x, zero, min, (mpfr_ptr) 0); + mpfr_set_ui (zero, 0, MPFR_RNDN); + mpfr_set_ui (min, 0, MPFR_RNDN); + mpfr_nextabove (min); + r[0] = r[2] = r[4] = min; /* RNDN, RNDU, RNDA */ + r[1] = r[3] = zero; /* RNDZ, RNDD */ + for (s = 1; s > 0; s = -1) + { + for (i = 0; i < MPFR_RND_MAX ; i++) + { + int j; + int inex; + + j = s < 0 && i > 1 ? 5 - i : i; + inex = mpfr_underflow (x, (mpfr_rnd_t) i, s); + if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0) + { + printf ("Error in test_set_underflow, sign = %d," + " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i)); + printf ("Got\n"); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (", inex = %d\ninstead of\n", inex); + mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN); + printf (", inex = %d\n", t[j]); + exit (1); + } + } + mpfr_neg (zero, zero, MPFR_RNDN); + mpfr_neg (min, min, MPFR_RNDN); + } + mpfr_clears (x, zero, min, (mpfr_ptr) 0); +} + +static void +test_set_overflow (void) +{ + mpfr_t x, inf, max; + mpfr_ptr r[MPFR_RND_MAX]; + int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */ + int i; + int s; + + mpfr_inits2 (32, x, inf, max, (mpfr_ptr) 0); + mpfr_set_inf (inf, 1); + mpfr_set_inf (max, 1); + mpfr_nextbelow (max); + r[0] = r[2] = r[4] = inf; /* RNDN, RNDU, RNDA */ + r[1] = r[3] = max; /* RNDZ, RNDD */ + for (s = 1; s > 0; s = -1) + { + for (i = 0; i < MPFR_RND_MAX ; i++) + { + int j; + int inex; + + j = s < 0 && i > 1 ? 5 - i : i; + inex = mpfr_overflow (x, (mpfr_rnd_t) i, s); + if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0) + { + printf ("Error in test_set_overflow, sign = %d," + " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i)); + printf ("Got\n"); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (", inex = %d\ninstead of\n", inex); + mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN); + printf (", inex = %d\n", t[j]); + exit (1); + } + } + mpfr_neg (inf, inf, MPFR_RNDN); + mpfr_neg (max, max, MPFR_RNDN); + } + mpfr_clears (x, inf, max, (mpfr_ptr) 0); +} + +static void +check_set (void) +{ + mpfr_clear_flags (); + + mpfr_set_overflow (); + MPFR_ASSERTN ((mpfr_overflow_p) ()); + mpfr_set_underflow (); + MPFR_ASSERTN ((mpfr_underflow_p) ()); + mpfr_set_divby0 (); + MPFR_ASSERTN ((mpfr_divby0_p) ()); + mpfr_set_nanflag (); + MPFR_ASSERTN ((mpfr_nanflag_p) ()); + mpfr_set_inexflag (); + MPFR_ASSERTN ((mpfr_inexflag_p) ()); + mpfr_set_erangeflag (); + MPFR_ASSERTN ((mpfr_erangeflag_p) ()); + + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL); + + mpfr_clear_overflow (); + MPFR_ASSERTN (! (mpfr_overflow_p) ()); + mpfr_clear_underflow (); + MPFR_ASSERTN (! (mpfr_underflow_p) ()); + mpfr_clear_divby0 (); + MPFR_ASSERTN (! (mpfr_divby0_p) ()); + mpfr_clear_nanflag (); + MPFR_ASSERTN (! (mpfr_nanflag_p) ()); + mpfr_clear_inexflag (); + MPFR_ASSERTN (! (mpfr_inexflag_p) ()); + mpfr_clear_erangeflag (); + MPFR_ASSERTN (! (mpfr_erangeflag_p) ()); + + MPFR_ASSERTN (__gmpfr_flags == 0); + + (mpfr_set_overflow) (); + MPFR_ASSERTN (mpfr_overflow_p ()); + (mpfr_set_underflow) (); + MPFR_ASSERTN (mpfr_underflow_p ()); + (mpfr_set_divby0) (); + MPFR_ASSERTN (mpfr_divby0_p ()); + (mpfr_set_nanflag) (); + MPFR_ASSERTN (mpfr_nanflag_p ()); + (mpfr_set_inexflag) (); + MPFR_ASSERTN (mpfr_inexflag_p ()); + (mpfr_set_erangeflag) (); + MPFR_ASSERTN (mpfr_erangeflag_p ()); + + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL); + + (mpfr_clear_overflow) (); + MPFR_ASSERTN (! mpfr_overflow_p ()); + (mpfr_clear_underflow) (); + MPFR_ASSERTN (! mpfr_underflow_p ()); + (mpfr_clear_divby0) (); + MPFR_ASSERTN (! mpfr_divby0_p ()); + (mpfr_clear_nanflag) (); + MPFR_ASSERTN (! mpfr_nanflag_p ()); + (mpfr_clear_inexflag) (); + MPFR_ASSERTN (! mpfr_inexflag_p ()); + (mpfr_clear_erangeflag) (); + MPFR_ASSERTN (! mpfr_erangeflag_p ()); + + MPFR_ASSERTN (__gmpfr_flags == 0); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + tests_start_mpfr (); + + test_set_underflow (); + test_set_overflow (); + check_default_rnd(); + + mpfr_init (x); + mpfr_init (y); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + if (emin >= emax) + { + printf ("Error: emin >= emax\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); + mpfr_set_double_range (); + mpfr_check_range (x, 0, MPFR_RNDN); + if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) + { + printf ("Error: 2^1024 rounded to nearest should give +Inf\n"); + exit (1); + } + + set_emax (1025); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); + mpfr_set_double_range (); + mpfr_check_range (x, 0, MPFR_RNDD); + if (!mpfr_number_p (x)) + { + printf ("Error: 2^1024 rounded down should give a normal number\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_mul_2exp (x, x, 1023, MPFR_RNDN); + mpfr_add (x, x, x, MPFR_RNDN); + if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) + { + printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n"); + printf ("emax = %ld\n", (long) mpfr_get_emax ()); + printf ("got "); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_mul_2exp (x, x, 1023, MPFR_RNDN); + mpfr_add (x, x, x, MPFR_RNDD); + if (!mpfr_number_p (x)) + { + printf ("Error: x+x rounded down for x=2^1023 should give" + " a normal number\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2exp (x, x, 1022, MPFR_RNDN); + mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */ + mpfr_sub (y, y, x, MPFR_RNDZ); + if (mpfr_cmp_ui (y, 0)) + { + printf ("Error: y-x rounded to zero should give 0" + " for y=3/2*2^(-1022), x=2^(-1022)\n"); + printf ("y="); mpfr_print_binary (y); puts (""); + exit (1); + } + + set_emin (-1026); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2exp (x, x, 1025, MPFR_RNDN); + mpfr_set_double_range (); + mpfr_check_range (x, 0, MPFR_RNDN); + if (!MPFR_IS_ZERO (x) ) + { + printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n"); + printf ("emin = %ld\n", (long) mpfr_get_emin ()); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + + set_emin (emin); + set_emax (emax); + + check_emin_emax(); + check_flags(); + check_set_get_prec (); + check_powerof2 (); + check_set (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/texp.c b/mpfr/tests/texp.c new file mode 100644 index 0000000000..bab32e8b0a --- /dev/null +++ b/mpfr/tests/texp.c @@ -0,0 +1,1038 @@ +/* Test file for mpfr_exp. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_exp (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_exp (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_exp mpfr_exp +#endif + +/* returns the number of ulp of error */ +static void +check3 (const char *op, mpfr_rnd_t rnd, const char *res) +{ + mpfr_t x, y; + + mpfr_inits2 (53, x, y, (mpfr_ptr) 0); + /* y negative. If we forget to set the sign in mpfr_exp, we'll see it. */ + mpfr_set_si (y, -1, MPFR_RNDN); + mpfr_set_str1 (x, op); + test_exp (y, x, rnd); + if (mpfr_cmp_str1 (y, res) ) + { + printf ("mpfr_exp failed for x=%s, rnd=%s\n", + op, mpfr_print_rnd_mode (rnd)); + printf ("expected result is %s, got ", res); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + putchar('\n'); + exit (1); + } + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +/* expx is the value of exp(X) rounded toward -infinity */ +static void +check_worst_case (const char *Xs, const char *expxs) +{ + mpfr_t x, y; + + mpfr_inits2 (53, x, y, (mpfr_ptr) 0); + mpfr_set_str1(x, Xs); + test_exp(y, x, MPFR_RNDD); + if (mpfr_cmp_str1 (y, expxs)) + { + printf ("exp(x) rounded toward -infinity is wrong\n"); + exit(1); + } + mpfr_set_str1(x, Xs); + test_exp(x, x, MPFR_RNDU); + mpfr_nexttoinf (y); + if (mpfr_cmp(x,y)) + { + printf ("exp(x) rounded toward +infinity is wrong\n"); + exit(1); + } + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +/* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */ +static int +check_worst_cases (void) +{ + mpfr_t x; mpfr_t y; + + mpfr_init(x); + mpfr_set_prec (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", MPFR_RNDN, "1.00000000017617773906"); + check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676"); + check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881"); + /* bug found by Vincent Lefe`vre on December 8, 1999 */ + check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236"); + /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */ + check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622"); + check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757"); + check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832"); + check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792"); + check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835"); + check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425"); + + mpfr_set_prec (x, 601); + mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ); + mpfr_init2 (y, 601); + mpfr_exp_2 (y, x, MPFR_RNDD); + mpfr_exp_3 (x, x, MPFR_RNDD); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n"); + printf ("mpfr_exp_2 gives "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\nmpfr_exp_3 gives "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 13001); + mpfr_set_prec (y, 13001); + mpfr_urandomb (x, RANDS); + mpfr_exp_3 (y, x, MPFR_RNDN); + mpfr_exp_2 (x, x, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n"); + exit (1); + } + + mpfr_set_prec (x, 118); + mpfr_set_str_binary (x, "0.1110010100011101010000111110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E-86"); + mpfr_set_prec (y, 118); + mpfr_exp_2 (y, x, MPFR_RNDU); + mpfr_exp_3 (x, x, MPFR_RNDU); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=118\n"); + printf ("mpfr_exp_2 gives "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\nmpfr_exp_3 gives "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + return 0; +} + +static void +compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1) +{ + mpfr_t x, y, z; + mpfr_prec_t prec; + mpfr_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + for (prec = p0; prec <= p1; prec ++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_prec (z, prec); + do + mpfr_urandomb (x, RANDS); + while (MPFR_IS_ZERO (x)); /* 0 is handled by mpfr_exp only */ + rnd = RND_RAND (); + mpfr_exp_2 (y, x, rnd); + mpfr_exp_3 (z, x, rnd); + if (mpfr_cmp (y,z)) + { + printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=", + mpfr_print_rnd_mode (rnd)); + mpfr_print_binary (x); + puts (""); + printf ("mpfr_exp_2 gives "); + mpfr_print_binary (y); + puts (""); + printf ("mpfr_exp_3 gives "); + mpfr_print_binary (z); + puts (""); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_large (void) +{ + mpfr_t x, z; + mpfr_prec_t prec; + + /* bug found by Patrick Pe'lissier on 7 Jun 2004 */ + prec = 203780; + mpfr_init2 (x, prec); + mpfr_init2 (z, prec); + mpfr_set_ui (x, 3, MPFR_RNDN); + mpfr_sqrt (x, x, MPFR_RNDN); + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + mpfr_exp_3 (z, x, MPFR_RNDN); + mpfr_clear (x); + mpfr_clear (z); +} + +#define TEST_FUNCTION test_exp +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +check_special (void) +{ + mpfr_t x, y, z; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + /* check exp(NaN) = NaN */ + mpfr_set_nan (x); + test_exp (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for exp(NaN)\n"); + exit (1); + } + + /* check exp(+inf) = +inf */ + mpfr_set_inf (x, 1); + test_exp (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for exp(+inf)\n"); + exit (1); + } + + /* check exp(-inf) = +0 */ + mpfr_set_inf (x, -1); + test_exp (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error for exp(-inf)\n"); + exit (1); + } + + /* Check overflow. Corner case of mpfr_exp_2 */ + mpfr_set_prec (x, 64); + mpfr_set_emax (MPFR_EMAX_DEFAULT); + mpfr_set_emin (MPFR_EMIN_DEFAULT); + mpfr_set_str (x, + "0.1011000101110010000101111111010100001100000001110001100111001101E30", + 2, MPFR_RNDN); + mpfr_exp (x, x, MPFR_RNDD); + if (mpfr_cmp_str (x, +".1111111111111111111111111111111111111111111111111111111111111111E1073741823", + 2, MPFR_RNDN) != 0) + { + printf ("Wrong overflow detection in mpfr_exp\n"); + mpfr_dump (x); + exit (1); + } + /* Check underflow. Corner case of mpfr_exp_2 */ + mpfr_set_str (x, +"-0.1011000101110010000101111111011111010001110011110111100110101100E30", + 2, MPFR_RNDN); + mpfr_exp (x, x, MPFR_RNDN); + if (mpfr_cmp_str (x, "0.1E-1073741823", 2, MPFR_RNDN) != 0) + { + printf ("Wrong underflow (1) detection in mpfr_exp\n"); + mpfr_dump (x); + exit (1); + } + mpfr_set_str (x, +"-0.1011001101110010000101111111011111010001110011110111100110111101E30", + 2, MPFR_RNDN); + mpfr_exp (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) != 0) + { + printf ("Wrong underflow (2) detection in mpfr_exp\n"); + mpfr_dump (x); + exit (1); + } + /* Check overflow. Corner case of mpfr_exp_3 */ + if (MPFR_PREC_MAX >= MPFR_EXP_THRESHOLD + 10 && MPFR_PREC_MAX >= 64) + { + /* this ensures that for small MPFR_EXP_THRESHOLD, the following + mpfr_set_str conversion is exact */ + mpfr_set_prec (x, (MPFR_EXP_THRESHOLD + 10 > 64) + ? MPFR_EXP_THRESHOLD + 10 : 64); + mpfr_set_str (x, + "0.1011000101110010000101111111010100001100000001110001100111001101E30", + 2, MPFR_RNDN); + mpfr_clear_overflow (); + mpfr_exp (x, x, MPFR_RNDD); + if (!mpfr_overflow_p ()) + { + printf ("Wrong overflow detection in mpfr_exp_3\n"); + mpfr_dump (x); + exit (1); + } + /* Check underflow. Corner case of mpfr_exp_3 */ + mpfr_set_str (x, + "-0.1011000101110010000101111111011111010001110011110111100110101100E30", + 2, MPFR_RNDN); + mpfr_clear_underflow (); + mpfr_exp (x, x, MPFR_RNDN); + if (!mpfr_underflow_p ()) + { + printf ("Wrong underflow detection in mpfr_exp_3\n"); + mpfr_dump (x); + exit (1); + } + mpfr_set_prec (x, 53); + } + + /* check overflow */ + set_emax (10); + mpfr_set_ui (x, 7, MPFR_RNDN); + test_exp (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for exp(7) for emax=10\n"); + exit (1); + } + set_emax (emax); + + /* check underflow */ + set_emin (-10); + mpfr_set_si (x, -9, MPFR_RNDN); + test_exp (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error for exp(-9) for emin=-10\n"); + printf ("Expected +0\n"); + printf ("Got "); mpfr_print_binary (y); puts (""); + exit (1); + } + set_emin (emin); + + /* check case EXP(x) < -precy */ + mpfr_set_prec (y, 2); + mpfr_set_str_binary (x, "-0.1E-3"); + test_exp (y, x, MPFR_RNDD); + if (mpfr_cmp_ui_2exp (y, 3, -2)) + { + printf ("Error for exp(-1/16), prec=2, RNDD\n"); + printf ("expected 0.11, got "); + mpfr_dump (y); + exit (1); + } + test_exp (y, x, MPFR_RNDZ); + if (mpfr_cmp_ui_2exp (y, 3, -2)) + { + printf ("Error for exp(-1/16), prec=2, RNDZ\n"); + printf ("expected 0.11, got "); + mpfr_dump (y); + exit (1); + } + mpfr_set_str_binary (x, "0.1E-3"); + test_exp (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error for exp(1/16), prec=2, RNDN\n"); + exit (1); + } + test_exp (y, x, MPFR_RNDU); + if (mpfr_cmp_ui_2exp (y, 3, -1)) + { + printf ("Error for exp(1/16), prec=2, RNDU\n"); + exit (1); + } + + /* bug reported by Franky Backeljauw, 28 Mar 2003 */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28"); + test_exp (y, x, MPFR_RNDN); + + mpfr_set_prec (x, 153); + mpfr_set_prec (z, 153); + mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28"); + test_exp (z, x, MPFR_RNDN); + mpfr_prec_round (z, 53, MPFR_RNDN); + + if (mpfr_cmp (y, z)) + { + printf ("Error in mpfr_exp for large argument\n"); + exit (1); + } + + /* corner cases in mpfr_exp_3 */ + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_prec (y, 2); + mpfr_exp_3 (y, x, MPFR_RNDN); + + /* Check some little things about overflow detection */ + set_emin (-125); + set_emax (128); + mpfr_set_prec (x, 107); + mpfr_set_prec (y, 107); + mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000" + "00000000E4"); + test_exp (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000" + "1101110111100010111001011111111000110111001011001101010" + "01E22", 2, MPFR_RNDN)) + { + printf ("Special overflow error (1)\n"); + mpfr_dump (y); + exit (1); + } + + set_emin (emin); + set_emax (emax); + + /* Check for overflow producing a segfault with HUGE exponent */ + mpfr_set_ui (x, 3, MPFR_RNDN); + mpfr_mul_2ui (x, x, 32, MPFR_RNDN); + test_exp (y, x, MPFR_RNDN); /* Can't test return value: May overflow or not*/ + + /* Bug due to wrong approximation of (x)/log2 */ + mpfr_set_prec (x, 163); + + mpfr_set_str (x, "-4.28ac8fceeadcda06bb56359017b1c81b85b392e7", 16, + MPFR_RNDN); + mpfr_exp (x, x, MPFR_RNDN); + if (mpfr_cmp_str (x, "3.fffffffffffffffffffffffffffffffffffffffe8@-2", + 16, MPFR_RNDN)) + { + printf ("Error for x= -4.28ac8fceeadcda06bb56359017b1c81b85b392e7"); + printf ("expected 3.fffffffffffffffffffffffffffffffffffffffe8@-2"); + printf ("Got "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + } + + /* bug found by Guillaume Melquiond, 13 Sep 2005 */ + mpfr_set_prec (x, 53); + mpfr_set_str_binary (x, "-1E-400"); + mpfr_exp (x, x, MPFR_RNDZ); + if (mpfr_cmp_ui (x, 1) == 0) + { + printf ("Error for exp(-2^(-400))\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +/* check sign of inexact flag */ +static void +check_inexact (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + mpfr_set_str_binary (x, + "1.0000000000001001000110100100101000001101101011100101e2"); + inexact = test_exp (y, x, MPFR_RNDN); + if (inexact <= 0) + { + printf ("Wrong inexact flag (Got %d instead of 1)\n", inexact); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_exp10(void) +{ + mpfr_t x; + int inexact; + + mpfr_init2 (x, 200); + mpfr_set_ui(x, 4, MPFR_RNDN); + + inexact = mpfr_exp10 (x, x, MPFR_RNDN); + if (mpfr_cmp_ui(x, 10*10*10*10)) + { + printf ("exp10: Wrong returned value\n"); + exit (1); + } + if (inexact != 0) + { + printf ("exp10: Wrong inexact flag\n"); + exit (1); + } + + mpfr_clear (x); +} + +static void +overflowed_exp0 (void) +{ + mpfr_t x, y; + int emax, i, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (emax); /* 1 is not representable. */ + /* and if emax < 0, 1 - eps is not representable either. */ + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_exp (x, x, (mpfr_rnd_t) rnd); + if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && + ! mpfr_overflow_p ()) + { + printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" + " The overflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +/* This bug occurs in mpfr_exp_2 on a Linux-64 machine, r5475. */ +static void +bug20080731 (void) +{ + mpfr_exp_t emin; + mpfr_t x, y1, y2; + mpfr_prec_t prec = 64; + + emin = mpfr_get_emin (); + set_emin (MPFR_EMIN_MIN); + + mpfr_init2 (x, 200); + mpfr_set_str (x, "-2.c5c85fdf473de6af278ece700fcbdabd03cd0cb9ca62d8b62c@7", + 16, MPFR_RNDN); + + mpfr_init2 (y1, prec); + mpfr_exp (y1, x, MPFR_RNDU); + + /* Compute the result with a higher internal precision. */ + mpfr_init2 (y2, 300); + mpfr_exp (y2, x, MPFR_RNDU); + mpfr_prec_round (y2, prec, MPFR_RNDU); + + if (mpfr_cmp0 (y1, y2) != 0) + { + printf ("Error in bug20080731\nExpected "); + mpfr_out_str (stdout, 16, 0, y2, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 16, 0, y1, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); + set_emin (emin); +} + +/* Emulate mpfr_exp with mpfr_exp_3 in the general case. */ +static int +exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) +{ + int inexact; + + inexact = mpfr_exp_3 (y, x, rnd_mode); + return mpfr_check_range (y, inexact, rnd_mode); +} + +static void +underflow_up (int extended_emin) +{ + mpfr_t minpos, x, y, t, t2; + int precx, precy; + int inex; + int rnd; + int e3; + int i, j; + + mpfr_init2 (minpos, 2); + mpfr_set_ui (minpos, 0, MPFR_RNDN); + mpfr_nextabove (minpos); + + /* Let's test values near the underflow boundary. + * + * Minimum representable positive number: minpos = 2^(emin - 1). + * Let's choose an MPFR number x = log(minpos) + eps, with |eps| small + * (note: eps cannot be 0, and cannot be a rational number either). + * Then exp(x) = minpos * exp(eps) ~= minpos * (1 + eps + eps^2). + * We will compute y = rnd(exp(x)) in some rounding mode, precision p. + * 1. If eps > 0, then in any rounding mode: + * rnd(exp(x)) >= minpos and no underflow. + * So, let's take x1 = rndu(log(minpos)) in some precision. + * 2. If eps < 0, then exp(x) < minpos and the result will be either 0 + * or minpos. An underflow always occurs in MPFR_RNDZ and MPFR_RNDD, + * but not necessarily in MPFR_RNDN and MPFR_RNDU (this is underflow + * after rounding in an unbounded exponent range). If -a < eps < -b, + * minpos * (1 - a) < exp(x) < minpos * (1 - b + b^2). + * - If eps > -2^(-p), no underflow in MPFR_RNDU. + * - If eps > -2^(-p-1), no underflow in MPFR_RNDN. + * - If eps < - (2^(-p-1) + 2^(-2p-1)), underflow in MPFR_RNDN. + * - If eps < - (2^(-p) + 2^(-2p+1)), underflow in MPFR_RNDU. + * - In MPFR_RNDN, result is minpos iff exp(eps) > 1/2, i.e. + * - log(2) < eps < ... + * + * Moreover, since precy < MPFR_EXP_THRESHOLD (to avoid tests that take + * too much time), mpfr_exp() always selects mpfr_exp_2(); so, we need + * to test mpfr_exp_3() too. This will be done via the e3 variable: + * e3 = 0: mpfr_exp(), thus mpfr_exp_2(). + * e3 = 1: mpfr_exp_3(), via the exp_3() wrapper. + * i.e.: inex = e3 ? exp_3 (y, x, rnd) : mpfr_exp (y, x, rnd); + */ + + /* Case eps > 0. In revision 5461 (trunk) on a 64-bit Linux machine: + * Incorrect flags in underflow_up, eps > 0, MPFR_RNDN and extended emin + * for precx = 96, precy = 16, mpfr_exp_3 + * Got 9 instead of 8. + * Note: testing this case in several precisions for x and y introduces + * some useful random. Indeed, the bug is not always triggered. + * Fixed in r5469. + */ + for (precx = 16; precx <= 128; precx += 16) + { + mpfr_init2 (x, precx); + mpfr_log (x, minpos, MPFR_RNDU); + for (precy = 16; precy <= 128; precy += 16) + { + mpfr_init2 (y, precy); + + for (e3 = 0; e3 <= 1; e3++) + { + RND_LOOP (rnd) + { + int err = 0; + + mpfr_clear_flags (); + inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd) + : mpfr_exp (y, x, (mpfr_rnd_t) rnd); + if (__gmpfr_flags != MPFR_FLAGS_INEXACT) + { + printf ("Incorrect flags in underflow_up, eps > 0, %s", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + if (extended_emin) + printf (" and extended emin"); + printf ("\nfor precx = %d, precy = %d, %s\n", + precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp"); + printf ("Got %u instead of %u.\n", __gmpfr_flags, + (unsigned int) MPFR_FLAGS_INEXACT); + err = 1; + } + if (mpfr_cmp0 (y, minpos) < 0) + { + printf ("Incorrect result in underflow_up, eps > 0, %s", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + if (extended_emin) + printf (" and extended emin"); + printf ("\nfor precx = %d, precy = %d, %s\n", + precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp"); + mpfr_dump (y); + err = 1; + } + MPFR_ASSERTN (inex != 0); + if (rnd == MPFR_RNDD || rnd == MPFR_RNDZ) + MPFR_ASSERTN (inex < 0); + if (rnd == MPFR_RNDU) + MPFR_ASSERTN (inex > 0); + if (err) + exit (1); + } + } + + mpfr_clear (y); + } + mpfr_clear (x); + } + + /* Case - log(2) < eps < 0 in MPFR_RNDN, starting with small-precision x; + * only check the result and the ternary value. + * Previous to r5453 (trunk), on 32-bit and 64-bit machines, this fails + * for precx = 65 and precy = 16, e.g.: + * exp_2.c:264: assertion failed: ... + * because mpfr_sub (r, x, r, MPFR_RNDU); yields a null value. This is + * fixed in r5453 by going to next Ziv's iteration. + */ + for (precx = sizeof(mpfr_exp_t) * CHAR_BIT + 1; precx <= 81; precx += 8) + { + mpfr_init2 (x, precx); + mpfr_log (x, minpos, MPFR_RNDD); /* |ulp| <= 1/2 */ + for (precy = 16; precy <= 128; precy += 16) + { + mpfr_init2 (y, precy); + inex = mpfr_exp (y, x, MPFR_RNDN); + if (inex <= 0 || mpfr_cmp0 (y, minpos) != 0) + { + printf ("Error in underflow_up, - log(2) < eps < 0"); + if (extended_emin) + printf (" and extended emin"); + printf (" for prec = %d\nExpected ", precy); + mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN); + printf (" (minimum positive MPFR number) and inex > 0\nGot "); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\nwith inex = %d\n", inex); + exit (1); + } + mpfr_clear (y); + } + mpfr_clear (x); + } + + /* Cases eps ~ -2^(-p) and eps ~ -2^(-p-1). More precisely, + * _ for j = 0, eps > -2^(-(p+i)), + * _ for j = 1, eps < - (2^(-(p+i)) + 2^(1-2(p+i))), + * where i = 0 or 1. + */ + mpfr_inits2 (2, t, t2, (mpfr_ptr) 0); + for (precy = 16; precy <= 128; precy += 16) + { + mpfr_set_ui_2exp (t, 1, - precy, MPFR_RNDN); /* 2^(-p) */ + mpfr_set_ui_2exp (t2, 1, 1 - 2 * precy, MPFR_RNDN); /* 2^(-2p+1) */ + precx = sizeof(mpfr_exp_t) * CHAR_BIT + 2 * precy + 8; + mpfr_init2 (x, precx); + mpfr_init2 (y, precy); + for (i = 0; i <= 1; i++) + { + for (j = 0; j <= 1; j++) + { + if (j == 0) + { + /* Case eps > -2^(-(p+i)). */ + mpfr_log (x, minpos, MPFR_RNDU); + } + else /* j == 1 */ + { + /* Case eps < - (2^(-(p+i)) + 2^(1-2(p+i))). */ + mpfr_log (x, minpos, MPFR_RNDD); + inex = mpfr_sub (x, x, t2, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + } + inex = mpfr_sub (x, x, t, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + RND_LOOP (rnd) + for (e3 = 0; e3 <= 1; e3++) + { + int err = 0; + unsigned int flags; + + flags = MPFR_FLAGS_INEXACT | + (((rnd == MPFR_RNDU || rnd == MPFR_RNDA) + && (i == 1 || j == 0)) || + (rnd == MPFR_RNDN && (i == 1 && j == 0)) ? + 0 : MPFR_FLAGS_UNDERFLOW); + mpfr_clear_flags (); + inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd) + : mpfr_exp (y, x, (mpfr_rnd_t) rnd); + if (__gmpfr_flags != flags) + { + printf ("Incorrect flags in underflow_up, %s", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + if (extended_emin) + printf (" and extended emin"); + printf ("\nfor precx = %d, precy = %d, ", + precx, precy); + if (j == 0) + printf ("eps >~ -2^(-%d)", precy + i); + else + printf ("eps <~ - (2^(-%d) + 2^(%d))", + precy + i, 1 - 2 * (precy + i)); + printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp"); + printf ("Got %u instead of %u.\n", + __gmpfr_flags, flags); + err = 1; + } + if (rnd == MPFR_RNDU || rnd == MPFR_RNDA || rnd == MPFR_RNDN ? + mpfr_cmp0 (y, minpos) != 0 : MPFR_NOTZERO (y)) + { + printf ("Incorrect result in underflow_up, %s", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + if (extended_emin) + printf (" and extended emin"); + printf ("\nfor precx = %d, precy = %d, ", + precx, precy); + if (j == 0) + printf ("eps >~ -2^(-%d)", precy + i); + else + printf ("eps <~ - (2^(-%d) + 2^(%d))", + precy + i, 1 - 2 * (precy + i)); + printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp"); + mpfr_dump (y); + err = 1; + } + if (err) + exit (1); + } /* for (e3 ...) */ + } /* for (j ...) */ + mpfr_div_2si (t, t, 1, MPFR_RNDN); + mpfr_div_2si (t2, t2, 2, MPFR_RNDN); + } /* for (i ...) */ + mpfr_clears (x, y, (mpfr_ptr) 0); + } /* for (precy ...) */ + mpfr_clears (t, t2, (mpfr_ptr) 0); + + /* Case exp(eps) ~= 1/2, i.e. eps ~= - log(2). + * We choose x0 and x1 with high enough precision such that: + * x0 = rndd(rndd(log(minpos)) - rndu(log(2))) + * x1 = rndu(rndu(log(minpos)) - rndd(log(2))) + * In revision 5507 (trunk) on a 64-bit Linux machine, this fails: + * Error in underflow_up, eps >~ - log(2) and extended emin + * for precy = 16, mpfr_exp + * Expected 1.0@-1152921504606846976 (minimum positive MPFR number), + * inex > 0 and flags = 9 + * Got 0 + * with inex = -1 and flags = 9 + * due to a double-rounding problem in mpfr_mul_2si when rescaling + * the result. + */ + mpfr_inits2 (sizeof(mpfr_exp_t) * CHAR_BIT + 64, x, t, (mpfr_ptr) 0); + for (i = 0; i <= 1; i++) + { + mpfr_log (x, minpos, i ? MPFR_RNDU : MPFR_RNDD); + mpfr_const_log2 (t, i ? MPFR_RNDD : MPFR_RNDU); + mpfr_sub (x, x, t, i ? MPFR_RNDU : MPFR_RNDD); + for (precy = 16; precy <= 128; precy += 16) + { + mpfr_init2 (y, precy); + for (e3 = 0; e3 <= 1; e3++) + { + unsigned int flags, uflags = + MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW; + + mpfr_clear_flags (); + inex = e3 ? exp_3 (y, x, MPFR_RNDN) : mpfr_exp (y, x, MPFR_RNDN); + flags = __gmpfr_flags; + if (flags != uflags || + (i ? (inex <= 0 || mpfr_cmp0 (y, minpos) != 0) + : (inex >= 0 || MPFR_NOTZERO (y)))) + { + printf ("Error in underflow_up, eps %c~ - log(2)", + i ? '>' : '<'); + if (extended_emin) + printf (" and extended emin"); + printf ("\nfor precy = %d, %s\nExpected ", precy, + e3 ? "mpfr_exp_3" : "mpfr_exp"); + if (i) + { + mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN); + printf (" (minimum positive MPFR number),\ninex >"); + } + else + { + printf ("+0, inex <"); + } + printf (" 0 and flags = %u\nGot ", uflags); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\nwith inex = %d and flags = %u\n", inex, flags); + exit (1); + } + } + mpfr_clear (y); + } + } + mpfr_clears (x, t, (mpfr_ptr) 0); + + mpfr_clear (minpos); +} + +static void +underflow (void) +{ + mpfr_exp_t emin; + + underflow_up (0); + + emin = mpfr_get_emin (); + set_emin (MPFR_EMIN_MIN); + if (mpfr_get_emin () != emin) + { + underflow_up (1); + set_emin (emin); + } +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + if (argc > 1) + check_large (); + + check_inexact (); + check_special (); + + test_generic (2, 100, 100); + + compare_exp2_exp3 (20, 1000); + check_worst_cases(); + check3("0.0", MPFR_RNDU, "1.0"); + check3("-1e-170", MPFR_RNDU, "1.0"); + check3("-1e-170", MPFR_RNDN, "1.0"); + check3("-8.88024741073346941839e-17", MPFR_RNDU, "1.0"); + check3("8.70772839244701057915e-01", MPFR_RNDN, "2.38875626491680437269"); + check3("1.0", MPFR_RNDN, "2.71828182845904509080"); + check3("-3.42135637628104173534e-07", MPFR_RNDZ, "0.999999657864420798958"); + /* worst case for argument reduction, very near from 5*log(2), + thanks to Jean-Michel Muller */ + check3("3.4657359027997265421", MPFR_RNDN, "32.0"); + check3("3.4657359027997265421", MPFR_RNDU, "32.0"); + check3("3.4657359027997265421", MPFR_RNDD, "31.999999999999996447"); + check3("2.26523754332090625496e+01", MPFR_RNDD, "6.8833785261699581146e9"); + check3("1.31478962104089092122e+01", MPFR_RNDZ, "5.12930793917860137299e+05"); + check3("4.25637507920002378103e-01", MPFR_RNDU, "1.53056585656161181497e+00"); + check3("6.26551618962329307459e-16", MPFR_RNDU, "1.00000000000000066613e+00"); + check3("-3.35589513871216568383e-03",MPFR_RNDD, "9.96649729583626853291e-01"); + check3("1.95151388850007272424e+01", MPFR_RNDU, "2.98756340674767792225e+08"); + check3("2.45045953503350730784e+01", MPFR_RNDN, "4.38743344916128387451e+10"); + check3("2.58165606081678085104e+01", MPFR_RNDD, "1.62925781879432281494e+11"); + check3("-2.36539020084338638128e+01",MPFR_RNDZ, "5.33630792749924762447e-11"); + check3("2.39211946135858077866e+01", MPFR_RNDU, "2.44817704330214385986e+10"); + check3("-2.78190533055889162029e+01",MPFR_RNDZ, "8.2858803483596879512e-13"); + check3("2.64028186174889789584e+01", MPFR_RNDD, "2.9281844652878973388e11"); + check3("2.92086338843268329413e+01", MPFR_RNDZ, "4.8433797301907177734e12"); + check3("-2.46355324071459982349e+01",MPFR_RNDZ, "1.9995129297760994791e-11"); + check3("-2.23509444608605427618e+01",MPFR_RNDZ, "1.9638492867489702307e-10"); + check3("-2.41175390197331687148e+01",MPFR_RNDD, "3.3564940885530624592e-11"); + check3("2.46363885231578088053e+01", MPFR_RNDU, "5.0055014282693267822e10"); + check3("111.1263531080090984914932050742208957672119140625", MPFR_RNDN, "1.8262572323517295459e48"); + check3("-3.56196340354684821250e+02",MPFR_RNDN, "2.0225297096141478156e-155"); + check3("6.59678273772710895173e+02", MPFR_RNDU, "3.1234469273830195529e286"); + check3("5.13772529701934331570e+02", MPFR_RNDD, "1.3445427121297197752e223"); + check3("3.57430211008718345056e+02", MPFR_RNDD, "1.6981197246857298443e155"); + check3("3.82001814471465536371e+02", MPFR_RNDU, "7.9667300591087367805e165"); + check3("5.92396038219384422518e+02", MPFR_RNDD, "1.880747529554661989e257"); + check3("-5.02678550462488090034e+02",MPFR_RNDU, "4.8919201895446217839e-219"); + check3("5.30015757134837031117e+02", MPFR_RNDD, "1.5237672861171573939e230"); + check3("5.16239362447650933063e+02", MPFR_RNDZ, "1.5845518406744492105e224"); + check3("6.00812634798592370977e-01", MPFR_RNDN, "1.823600119339019443"); + check_exp10 (); + + bug20080731 (); + + overflowed_exp0 (); + underflow (); + + data_check ("data/exp", mpfr_exp, "mpfr_exp"); + bad_cases (mpfr_exp, mpfr_log, "mpfr_exp", 0, -256, 255, 4, 128, 800, 50); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/texp10.c b/mpfr/tests/texp10.c new file mode 100644 index 0000000000..8fc442d4f1 --- /dev/null +++ b/mpfr/tests/texp10.c @@ -0,0 +1,318 @@ +/* Test file for mpfr_exp10. + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_exp10 +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +special_overflow (void) +{ + mpfr_t x, y; + int inex; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + + mpfr_init2 (x, 24); + mpfr_init2 (y, 24); + + mpfr_set_str_binary (x, "0.101100100000000000110100E15"); + inex = mpfr_exp10 (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || inex <= 0) + { + printf ("Overflow error.\n"); + mpfr_dump (y); + printf ("inex = %d\n", inex); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); + set_emin (emin); + set_emax (emax); +} + +static void +emax_m_eps (void) +{ + if (mpfr_get_emax () <= LONG_MAX) + { + mpfr_t x, y; + int inex, ov; + + mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4); + mpfr_init2 (y, 8); + mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN); + + mpfr_clear_flags (); + inex = mpfr_exp10 (y, x, MPFR_RNDN); + ov = mpfr_overflow_p (); + if (!ov || !mpfr_inf_p (y) || inex <= 0) + { + printf ("Overflow error for x = emax, MPFR_RNDN.\n"); + mpfr_dump (y); + printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + } +} + +static void +exp_range (void) +{ + mpfr_t x; + mpfr_exp_t emin; + + emin = mpfr_get_emin (); + set_emin (3); + mpfr_init2 (x, 16); + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_exp10 (x, x, MPFR_RNDN); + set_emin (emin); + if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 10000) != 0) + { + printf ("Error in mpfr_exp10 for x = 4, with emin = 3\n"); + printf ("Expected 10000, got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clear (x); +} + +static void +overfl_exp10_0 (void) +{ + mpfr_t x, y; + int emax, i, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (emax); /* 1 is not representable. */ + /* and if emax < 0, 1 - eps is not representable either. */ + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_exp10 (x, x, (mpfr_rnd_t) rnd); + if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && + ! mpfr_overflow_p ()) + { + printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" + " The overflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + int inex, ov; + + tests_start_mpfr (); + + special_overflow (); + emax_m_eps (); + exp_range (); + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_exp10 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 10000) != 0) + { + printf ("Error for 10^4, MPFR_RNDN\n"); + exit (1); + } + mpfr_exp10 (y, x, MPFR_RNDD); + if (mpfr_cmp_ui (y, 10000) != 0) + { + printf ("Error for 10^4, MPFR_RNDD\n"); + exit (1); + } + mpfr_exp10 (y, x, MPFR_RNDU); + if (mpfr_cmp_ui (y, 10000) != 0) + { + printf ("Error for 10^4, MPFR_RNDU\n"); + exit (1); + } + + mpfr_set_prec (x, 10); + mpfr_set_prec (y, 10); + /* save emin */ + emin = mpfr_get_emin (); + set_emin (-11); + mpfr_set_si (x, -4, MPFR_RNDN); + mpfr_exp10 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error for emin = -11, x = -4, RNDN\n"); + printf ("Expected +0\n"); + printf ("Got "); mpfr_print_binary (y); puts (""); + exit (1); + } + /* restore emin */ + set_emin (emin); + + /* save emax */ + emax = mpfr_get_emax (); + set_emax (13); + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_exp10 (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for emax = 13, x = 4, RNDN\n"); + printf ("Expected +inf\n"); + printf ("Got "); mpfr_print_binary (y); puts (""); + exit (1); + } + /* restore emax */ + set_emax (emax); + + MPFR_SET_INF (x); + MPFR_SET_POS (x); + mpfr_exp10 (y, x, MPFR_RNDN); + if (!MPFR_IS_INF (y)) + { + printf ("evaluation of function in INF does not return INF\n"); + exit (1); + } + + MPFR_CHANGE_SIGN (x); + mpfr_exp10 (y, x, MPFR_RNDN); + if (!MPFR_IS_ZERO (y)) + { + printf ("evaluation of function in -INF does not return 0\n"); + exit (1); + } + + MPFR_SET_NAN (x); + mpfr_exp10 (y, x, MPFR_RNDN); + if (!MPFR_IS_NAN (y)) + { + printf ("evaluation of function in NaN does not return NaN\n"); + exit (1); + } + + if ((mpfr_uexp_t) 8 << 31 != 0 || + mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) + { + /* emax <= 10000000000 */ + mpfr_set_prec (x, 40); + mpfr_set_prec (y, 40); + mpfr_set_str (x, "3010299957", 10, MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_exp10 (y, x, MPFR_RNDN); + ov = mpfr_overflow_p (); + if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov)) + { + printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n"); + mpfr_dump (y); + printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); + exit (1); + } + } + + test_generic (2, 100, 100); + + mpfr_clear (x); + mpfr_clear (y); + + overfl_exp10_0 (); + + data_check ("data/exp10", mpfr_exp10, "mpfr_exp10"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/texp2.c b/mpfr/tests/texp2.c new file mode 100644 index 0000000000..1768451b83 --- /dev/null +++ b/mpfr/tests/texp2.c @@ -0,0 +1,379 @@ +/* Test file for mpfr_exp2. + +Copyright 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_exp2 +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +special_overflow (void) +{ + mpfr_t x, y; + int inex; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + + mpfr_init2 (x, 24); + mpfr_init2 (y, 24); + + mpfr_set_str_binary (x, "0.101100100000000000110100E15"); + inex = mpfr_exp2 (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || inex <= 0) + { + printf ("Overflow error.\n"); + mpfr_dump (y); + printf ("inex = %d\n", inex); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); + set_emin (emin); + set_emax (emax); +} + +static void +emax_m_eps (void) +{ + if (mpfr_get_emax () <= LONG_MAX) + { + mpfr_t x, y; + int inex, ov; + + mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4); + mpfr_init2 (y, 8); + mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN); + + mpfr_clear_flags (); + inex = mpfr_exp2 (y, x, MPFR_RNDN); + ov = mpfr_overflow_p (); + if (!ov || !mpfr_inf_p (y) || inex <= 0) + { + printf ("Overflow error for x = emax, MPFR_RNDN.\n"); + mpfr_dump (y); + printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); + exit (1); + } + + mpfr_nextbelow (x); + + mpfr_clear_flags (); + inex = mpfr_exp2 (y, x, MPFR_RNDN); + ov = mpfr_overflow_p (); + if (!ov || !mpfr_inf_p (y) || inex <= 0) + { + printf ("Overflow error for x = emax - eps, MPFR_RNDN.\n"); + mpfr_dump (y); + printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); + exit (1); + } + + mpfr_clear_flags (); + inex = mpfr_exp2 (y, x, MPFR_RNDD); + ov = mpfr_overflow_p (); + if (ov || mpfr_inf_p (y) || inex >= 0 || + (mpfr_nextabove (y), !mpfr_inf_p (y))) + { + printf ("Overflow error for x = emax - eps, MPFR_RNDD.\n"); + mpfr_dump (y); + printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + } +} + +static void +exp_range (void) +{ + mpfr_t x; + mpfr_exp_t emin; + + emin = mpfr_get_emin (); + set_emin (3); + mpfr_init2 (x, 8); + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_exp2 (x, x, MPFR_RNDN); + set_emin (emin); + if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 32) != 0) + { + printf ("Error in mpfr_exp2 for x = 5, with emin = 3\n"); + printf ("Expected 32, got "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clear (x); +} + +static void +overflowed_exp2_0 (void) +{ + mpfr_t x, y; + int emax, i, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (emax); /* 1 is not representable. */ + /* and if emax < 0, 1 - eps is not representable either. */ + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_exp2 (x, x, (mpfr_rnd_t) rnd); + if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && + ! mpfr_overflow_p ()) + { + printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" + " The overflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + + tests_start_mpfr (); + + special_overflow (); + emax_m_eps (); + exp_range (); + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_exp2 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 16) != 0) + { + printf ("Error for 2^4, MPFR_RNDN\n"); + exit (1); + } + mpfr_exp2 (y, x, MPFR_RNDD); + if (mpfr_cmp_ui (y, 16) != 0) + { + printf ("Error for 2^4, MPFR_RNDD\n"); + exit (1); + } + mpfr_exp2 (y, x, MPFR_RNDU); + if (mpfr_cmp_ui (y, 16) != 0) + { + printf ("Error for 2^4, MPFR_RNDU\n"); + exit (1); + } + + mpfr_set_si (x, -4, MPFR_RNDN); + mpfr_exp2 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) + { + printf ("Error for 2^(-4), MPFR_RNDN\n"); + exit (1); + } + mpfr_exp2 (y, x, MPFR_RNDD); + if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) + { + printf ("Error for 2^(-4), MPFR_RNDD\n"); + exit (1); + } + mpfr_exp2 (y, x, MPFR_RNDU); + if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) + { + printf ("Error for 2^(-4), MPFR_RNDU\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/ + "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN); + mpfr_exp2 (y, x, MPFR_RNDN); + if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231")) + { + printf ("Error for x=-1683977482443233/2^41\n"); + exit (1); + } + + mpfr_set_prec (x, 10); + mpfr_set_prec (y, 10); + /* save emin */ + emin = mpfr_get_emin (); + set_emin (-10); + mpfr_set_si (x, -12, MPFR_RNDN); + mpfr_exp2 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error for x=emin-2, RNDN\n"); + printf ("Expected +0\n"); + printf ("Got "); mpfr_print_binary (y); puts (""); + exit (1); + } + /* restore emin */ + set_emin (emin); + + /* save emax */ + emax = mpfr_get_emax (); + set_emax (10); + mpfr_set_ui (x, 11, MPFR_RNDN); + mpfr_exp2 (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for x=emax+1, RNDN\n"); + exit (1); + } + /* restore emax */ + set_emax (emax); + + MPFR_SET_INF(x); + MPFR_SET_POS(x); + mpfr_exp2 (y, x, MPFR_RNDN); + if(!MPFR_IS_INF(y)) + { + printf ("evaluation of function in INF does not return INF\n"); + exit (1); + } + + MPFR_CHANGE_SIGN(x); + mpfr_exp2 (y, x, MPFR_RNDN); + if(!MPFR_IS_ZERO(y)) + { + printf ("evaluation of function in -INF does not return 0\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_exp2 (y, x, MPFR_RNDN); + if(!MPFR_IS_NAN(y)) + { + printf ("evaluation of function in NaN does not return NaN\n"); + exit (1); + } + + if ((mpfr_uexp_t) 8 << 31 != 0 || + mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) + { + /* emax <= 10000000000 */ + mpfr_set_prec (x, 40); + mpfr_set_prec (y, 40); + mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_exp2 (y, x, MPFR_RNDN); + if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ())) + { + printf ("exp2(10000000000.5) should overflow.\n"); + exit (1); + } + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_str_binary (x, "-1.0E-26"); + mpfr_exp2 (y, x, MPFR_RNDD); + mpfr_set_str_binary (x, "1.1E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error for exp(-2^(-26)) for prec=2\n"); + exit (1); + } + + test_generic (2, 100, 100); + + mpfr_clear (x); + mpfr_clear (y); + + overflowed_exp2_0 (); + + data_check ("data/exp2", mpfr_exp2, "mpfr_exp2"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/texpm1.c b/mpfr/tests/texpm1.c new file mode 100644 index 0000000000..c8da8d32d1 --- /dev/null +++ b/mpfr/tests/texpm1.c @@ -0,0 +1,173 @@ +/* Test file for mpfr_expm1. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_expm1 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_expm1 (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_expm1 mpfr_expm1 +#endif + +#define TEST_FUNCTION test_expm1 +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int i; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + test_expm1 (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for expm1(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + test_expm1 (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for expm1(+Inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + test_expm1 (y, x, MPFR_RNDN); + if (mpfr_cmp_si (y, -1)) + { + printf ("Error for expm1(-Inf)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + test_expm1 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error for expm1(+0)\n"); + exit (1); + } + + mpfr_neg (x, x, MPFR_RNDN); + test_expm1 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error for expm1(-0)\n"); + exit (1); + } + + /* Check overflow of expm1(x) */ + mpfr_clear_flags (); + mpfr_set_str_binary (x, "1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDU); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDD); + MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p ()); + MPFR_ASSERTN (i == -1); + + /* Check internal underflow of expm1 (x) */ + mpfr_set_prec (x, 2); + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0); + MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == -1); + + mpfr_set_str_binary (x, "-1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDD); + MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0); + MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == -1); + + mpfr_set_str_binary (x, "-1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0); + MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_set_str_binary (x, "-1.1E1000000000"); + i = test_expm1 (x, x, MPFR_RNDU); + MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0); + MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 100); + + data_check ("data/expm1", mpfr_expm1, "mpfr_expm1"); + bad_cases (mpfr_expm1, mpfr_log1p, "mpfr_expm1", 256, -256, 255, + 4, 128, 800, 40); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tfactorial.c b/mpfr/tests/tfactorial.c new file mode 100644 index 0000000000..49cc3477ce --- /dev/null +++ b/mpfr/tests/tfactorial.c @@ -0,0 +1,287 @@ +/* Test file for mpfr_factorial. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_fac_ui + +static void +special (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 21); + mpfr_set_prec (y, 21); + mpfr_fac_ui (x, 119, MPFR_RNDZ); + mpfr_set_str_binary (y, "0.101111101110100110110E654"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_fac_ui (119)\n"); + exit (1); + } + + mpfr_set_prec (y, 206); + inex = mpfr_fac_ui (y, 767, MPFR_RNDN); + mpfr_set_prec (x, 206); + mpfr_set_str_binary (x, "0.110111100001000001101010010001000111000100000100111000010011100011011111001100011110101000111101101100110001001100110100001001111110000101010000100100011100010011101110000001000010001100010000101001111E6250"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_fac_ui (767)\n"); + exit (1); + } + if (inex <= 0) + { + printf ("Wrong flag for mpfr_fac_ui (767)\n"); + exit (1); + } + + mpfr_set_prec (y, 202); + mpfr_fac_ui (y, 69, MPFR_RNDU); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +test_int (void) +{ + unsigned long n0 = 1, n1 = 80, n; + mpz_t f; + mpfr_t x, y; + mpfr_prec_t prec_f, p; + int r; + int inex1, inex2; + + mpz_init (f); + mpfr_init (x); + mpfr_init (y); + + mpz_fac_ui (f, n0 - 1); + for (n = n0; n <= n1; n++) + { + mpz_mul_ui (f, f, n); /* f = n! */ + prec_f = mpz_sizeinbase (f, 2) - mpz_scan1 (f, 0); + for (p = MPFR_PREC_MIN; p <= prec_f; p++) + { + mpfr_set_prec (x, p); + mpfr_set_prec (y, p); + for (r = 0; r < MPFR_RND_MAX; r++) + { + inex1 = mpfr_fac_ui (x, n, (mpfr_rnd_t) r); + inex2 = mpfr_set_z (y, f, (mpfr_rnd_t) r); + if (mpfr_cmp (x, y)) + { + printf ("Error for n=%lu prec=%lu rnd=%s\n", + n, (unsigned long) p, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + if ((inex1 < 0 && inex2 >= 0) || (inex1 == 0 && inex2 != 0) + || (inex1 > 0 && inex2 <= 0)) + { + printf ("Wrong inexact flag for n=%lu prec=%lu rnd=%s\n", + n, (unsigned long) p, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + } + } + + mpz_clear (f); + mpfr_clear (x); + mpfr_clear (y); +} + +static void +overflowed_fac0 (void) +{ + mpfr_t x, y; + int inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (0); /* 1 is not representable. */ + RND_LOOP (rnd) + { + mpfr_clear_flags (); + inex = mpfr_fac_ui (x, 0, (mpfr_rnd_t) rnd); + if (! mpfr_overflow_p ()) + { + printf ("Error in overflowed_fac0 (rnd = %s):\n" + " The overflow flag is not set.\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overflowed_fac0 (rnd = %s):\n" + " The inexact value must be negative.\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overflowed_fac0 (rnd = %s):\n" + " Got ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E0.\n"); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overflowed_fac0 (rnd = %s):\n" + " The inexact value must be positive.\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overflowed_fac0 (rnd = %s):\n" + " Got ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + unsigned int prec, err, yprec, n, k, zeros; + int rnd; + mpfr_t x, y, z, t; + int inexact; + + tests_start_mpfr (); + + special (); + + test_int (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + mpfr_fac_ui (y, 0, MPFR_RNDN); + + if (mpfr_cmp_ui (y, 1)) + { + printf ("mpfr_fac_ui(0) does not give 1\n"); + exit (1); + } + + for (prec = 2; prec <= 100; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + mpfr_set_prec (y, yprec); + + for (n = 0; n < 50; n++) + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + inexact = mpfr_fac_ui (y, n, (mpfr_rnd_t) rnd); + err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, (mpfr_rnd_t) rnd, (mpfr_rnd_t) rnd, prec)) + { + mpfr_set (t, y, (mpfr_rnd_t) rnd); + inexact = mpfr_fac_ui (z, n, (mpfr_rnd_t) rnd); + /* fact(n) ends with floor(n/2)+floor(n/4)+... zeros */ + for (k=n/2, zeros=0; k; k >>= 1) + zeros += k; + if (MPFR_EXP(y) <= (mpfr_exp_t) (prec + zeros)) + /* result should be exact */ + { + if (inexact) + { + printf ("Wrong inexact flag: expected exact\n"); + exit (1); + } + } + else /* result is inexact */ + { + if (!inexact) + { + printf ("Wrong inexact flag: expected inexact\n"); + printf ("n=%u prec=%u\n", n, prec); + mpfr_print_binary(z); puts (""); + exit (1); + } + } + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf (" prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + puts (""); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf (" approximation was "); + mpfr_print_binary (y); + puts (""); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + overflowed_fac0 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tfits.c b/mpfr/tests/tfits.c new file mode 100644 index 0000000000..3d768118ea --- /dev/null +++ b/mpfr/tests/tfits.c @@ -0,0 +1,276 @@ +/* Test file for: + mpfr_fits_sint_p, mpfr_fits_slong_p, mpfr_fits_sshort_p, + mpfr_fits_uint_p, mpfr_fits_ulong_p, mpfr_fits_ushort_p + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" /* for a build within gmp */ +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-intmax.h" +#include "mpfr-test.h" + +#define FTEST_AUX(N,NOT,FCT) \ + do \ + { \ + __gmpfr_flags = ex_flags; \ + if (NOT FCT (x, (mpfr_rnd_t) r)) \ + { \ + printf ("Error %d for %s, rnd = %s and x = ", \ + N, #FCT, \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \ + mpfr_dump (x); \ + exit (1); \ + } \ + if (__gmpfr_flags != ex_flags) \ + { \ + unsigned int flags = __gmpfr_flags; \ + printf ("Flags error %d for %s, rnd = %s and x = ", \ + N, #FCT, \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \ + mpfr_dump(x); \ + printf ("Expected flags:"); \ + flags_out (ex_flags); \ + printf ("Got flags: "); \ + flags_out (flags); \ + exit (1); \ + } \ + } \ + while (0) + +#define FTEST(N,NOT,FCT) \ + do \ + { \ + mpfr_exp_t e; \ + FTEST_AUX (N,NOT,FCT); \ + if (MPFR_IS_SINGULAR (x)) \ + break; \ + e = mpfr_get_exp (x); \ + set_emin (e); \ + set_emax (e); \ + FTEST_AUX (N,NOT,FCT); \ + set_emin (emin); \ + set_emax (emax); \ + } \ + while (0) + +#define CHECK_ALL(N,NOT) \ + do \ + { \ + FTEST (N, NOT, mpfr_fits_ulong_p); \ + FTEST (N, NOT, mpfr_fits_slong_p); \ + FTEST (N, NOT, mpfr_fits_uint_p); \ + FTEST (N, NOT, mpfr_fits_sint_p); \ + FTEST (N, NOT, mpfr_fits_ushort_p); \ + FTEST (N, NOT, mpfr_fits_sshort_p); \ + } \ + while (0) + +#define CHECK_MAX(N,NOT) \ + do \ + { \ + FTEST (N, NOT, mpfr_fits_uintmax_p); \ + FTEST (N, NOT, mpfr_fits_intmax_p); \ + } \ + while (0) + +/* V is a non-zero limit for the type (*_MIN for a signed type or *_MAX). + * If V is positive, then test V, V + 1/4, V + 3/4 and V + 1. + * If V is negative, then test V, V - 1/4, V - 3/4 and V - 1. + */ +#define CHECK_LIM(N,V,SET,FCT) \ + do \ + { \ + SET (x, V, MPFR_RNDN); \ + FTEST (N, !, FCT); \ + mpfr_set_si_2exp (y, (V) < 0 ? -1 : 1, -2, MPFR_RNDN); \ + mpfr_add (x, x, y, MPFR_RNDN); \ + FTEST (N+1, (r == MPFR_RNDN || \ + MPFR_IS_LIKE_RNDZ (r, (V) < 0)) ^ !!, FCT); \ + mpfr_add (x, x, y, MPFR_RNDN); \ + mpfr_add (x, x, y, MPFR_RNDN); \ + FTEST (N+3, MPFR_IS_LIKE_RNDZ (r, (V) < 0) ^ !!, FCT); \ + mpfr_add (x, x, y, MPFR_RNDN); \ + FTEST (N+4, !!, FCT); \ + } \ + while (0) + +int +main (void) +{ + mpfr_exp_t emin, emax; + mpfr_t x, y; + unsigned int flags[2] = { 0, MPFR_FLAGS_ALL }, ex_flags; + int i, r, fi; + + tests_start_mpfr (); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 2); + mpfr_init2 (y, 8); + + RND_LOOP (r) + for (fi = 0; fi < numberof (flags); fi++) + { + ex_flags = flags[fi]; + + /* Check NaN */ + mpfr_set_nan (x); + CHECK_ALL (1, !!); + + /* Check +Inf */ + mpfr_set_inf (x, 1); + CHECK_ALL (2, !!); + + /* Check -Inf */ + mpfr_set_inf (x, -1); + CHECK_ALL (3, !!); + + /* Check +0 */ + mpfr_set_zero (x, 1); + CHECK_ALL (4, !); + + /* Check -0 */ + mpfr_set_zero (x, -1); + CHECK_ALL (5, !); + + /* Check small positive op */ + mpfr_set_str1 (x, "1@-1"); + CHECK_ALL (6, !); + + /* Check 17 */ + mpfr_set_ui (x, 17, MPFR_RNDN); + CHECK_ALL (7, !); + + /* Check large values (no fit) */ + mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN); + mpfr_mul_2exp (x, x, 1, MPFR_RNDN); + CHECK_ALL (8, !!); + mpfr_mul_2exp (x, x, 40, MPFR_RNDN); + CHECK_ALL (9, !!); + + /* Check a non-integer number just below a power of two. */ + mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN); + CHECK_ALL (10, !); + + /* Check the limits of the types (except 0 for unsigned types) */ + CHECK_LIM (20, ULONG_MAX, mpfr_set_ui, mpfr_fits_ulong_p); + CHECK_LIM (30, LONG_MAX, mpfr_set_si, mpfr_fits_slong_p); + CHECK_LIM (35, LONG_MIN, mpfr_set_si, mpfr_fits_slong_p); + CHECK_LIM (40, UINT_MAX, mpfr_set_ui, mpfr_fits_uint_p); + CHECK_LIM (50, INT_MAX, mpfr_set_si, mpfr_fits_sint_p); + CHECK_LIM (55, INT_MIN, mpfr_set_si, mpfr_fits_sint_p); + CHECK_LIM (60, USHRT_MAX, mpfr_set_ui, mpfr_fits_ushort_p); + CHECK_LIM (70, SHRT_MAX, mpfr_set_si, mpfr_fits_sshort_p); + CHECK_LIM (75, SHRT_MIN, mpfr_set_si, mpfr_fits_sshort_p); + + /* Check negative op */ + for (i = 1; i <= 4; i++) + { + int inv; + + mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN); + mpfr_rint (y, x, (mpfr_rnd_t) r); + inv = MPFR_NOTZERO (y); + FTEST (80, inv ^ !, mpfr_fits_ulong_p); + FTEST (81, !, mpfr_fits_slong_p); + FTEST (82, inv ^ !, mpfr_fits_uint_p); + FTEST (83, !, mpfr_fits_sint_p); + FTEST (84, inv ^ !, mpfr_fits_ushort_p); + FTEST (85, !, mpfr_fits_sshort_p); + } + } + +#ifdef _MPFR_H_HAVE_INTMAX_T + + mpfr_set_prec (x, sizeof (uintmax_t) * CHAR_BIT + 2); + + RND_LOOP (r) + { + /* Check NaN */ + mpfr_set_nan (x); + CHECK_MAX (1, !!); + + /* Check +Inf */ + mpfr_set_inf (x, 1); + CHECK_MAX (2, !!); + + /* Check -Inf */ + mpfr_set_inf (x, -1); + CHECK_MAX (3, !!); + + /* Check +0 */ + mpfr_set_zero (x, 1); + CHECK_MAX (4, !); + + /* Check -0 */ + mpfr_set_zero (x, -1); + CHECK_MAX (5, !); + + /* Check small positive op */ + mpfr_set_str1 (x, "1@-1"); + CHECK_MAX (6, !); + + /* Check 17 */ + mpfr_set_ui (x, 17, MPFR_RNDN); + CHECK_MAX (7, !); + + /* Check hugest */ + mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN); + CHECK_MAX (8, !!); + + /* Check a non-integer number just below a power of two. */ + mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN); + CHECK_MAX (10, !); + + /* Check the limits of the types (except 0 for uintmax_t) */ + CHECK_LIM (20, MPFR_UINTMAX_MAX, mpfr_set_uj, mpfr_fits_uintmax_p); + CHECK_LIM (30, MPFR_INTMAX_MAX, mpfr_set_sj, mpfr_fits_intmax_p); + CHECK_LIM (35, MPFR_INTMAX_MIN, mpfr_set_sj, mpfr_fits_intmax_p); + + /* Check negative op */ + for (i = 1; i <= 4; i++) + { + int inv; + + mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN); + mpfr_rint (y, x, (mpfr_rnd_t) r); + inv = MPFR_NOTZERO (y); + FTEST (80, inv ^ !, mpfr_fits_uintmax_p); + FTEST (81, !, mpfr_fits_intmax_p); + } + } + +#endif /* _MPFR_H_HAVE_INTMAX_T */ + + mpfr_clear (x); + mpfr_clear (y); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tfma.c b/mpfr/tests/tfma.c new file mode 100644 index 0000000000..4ba83dc63f --- /dev/null +++ b/mpfr/tests/tfma.c @@ -0,0 +1,802 @@ +/* Test file for mpfr_fma. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* When a * b is exact, the FMA is equivalent to the separate operations. */ +static void +test_exact (void) +{ + const char *val[] = + { "@NaN@", "-@Inf@", "-2", "-1", "-0", "0", "1", "2", "@Inf@" }; + int sv = sizeof (val) / sizeof (*val); + int i, j, k; + int rnd; + mpfr_t a, b, c, r1, r2; + + mpfr_inits2 (8, a, b, c, r1, r2, (mpfr_ptr) 0); + + for (i = 0; i < sv; i++) + for (j = 0; j < sv; j++) + for (k = 0; k < sv; k++) + RND_LOOP (rnd) + { + if (mpfr_set_str (a, val[i], 10, MPFR_RNDN) || + mpfr_set_str (b, val[j], 10, MPFR_RNDN) || + mpfr_set_str (c, val[k], 10, MPFR_RNDN) || + mpfr_mul (r1, a, b, (mpfr_rnd_t) rnd) || + mpfr_add (r1, r1, c, (mpfr_rnd_t) rnd)) + { + printf ("test_exact internal error for (%d,%d,%d,%d)\n", + i, j, k, rnd); + exit (1); + } + if (mpfr_fma (r2, a, b, c, (mpfr_rnd_t) rnd)) + { + printf ("test_exact(%d,%d,%d,%d): mpfr_fma should be exact\n", + i, j, k, rnd); + exit (1); + } + if (MPFR_IS_NAN (r1)) + { + if (MPFR_IS_NAN (r2)) + continue; + printf ("test_exact(%d,%d,%d,%d): mpfr_fma should be NaN\n", + i, j, k, rnd); + exit (1); + } + if (! mpfr_equal_p (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2)) + { + printf ("test_exact(%d,%d,%d,%d):\nexpected ", i, j, k, rnd); + mpfr_out_str (stdout, 10, 0, r1, MPFR_RNDN); + printf ("\n got "); + mpfr_out_str (stdout, 10, 0, r2, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + + mpfr_clears (a, b, c, r1, r2, (mpfr_ptr) 0); +} + +static void +test_overflow1 (void) +{ + mpfr_t x, y, z, r; + int inex; + + mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0); + MPFR_SET_POS (x); + mpfr_setmax (x, mpfr_get_emax ()); /* x = 2^emax - ulp */ + mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */ + mpfr_neg (z, x, MPFR_RNDN); /* z = -x = -(2^emax - ulp) */ + mpfr_clear_flags (); + /* The intermediate multiplication x * y overflows, but x * y + z = x + is representable. */ + inex = mpfr_fma (r, x, y, z, MPFR_RNDN); + if (inex || ! mpfr_equal_p (r, x)) + { + printf ("Error in test_overflow1\nexpected "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" with inex = 0\n got "); + mpfr_out_str (stdout, 2, 0, r, MPFR_RNDN); + printf (" with inex = %d\n", inex); + exit (1); + } + if (mpfr_overflow_p ()) + { + printf ("Error in test_overflow1: overflow flag set\n"); + exit (1); + } + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_overflow2 (void) +{ + mpfr_t x, y, z, r; + int i, inex, rnd, err = 0; + + mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0); + + MPFR_SET_POS (x); + mpfr_setmin (x, mpfr_get_emax ()); /* x = 0.1@emax */ + mpfr_set_si (y, -2, MPFR_RNDN); /* y = -2 */ + /* The intermediate multiplication x * y will overflow. */ + + for (i = -9; i <= 9; i++) + RND_LOOP (rnd) + { + int inf, overflow; + + inf = rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA; + overflow = inf || i <= 0; + + inex = mpfr_set_si_2exp (z, i, mpfr_get_emin (), MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + mpfr_clear_flags (); + /* One has: x * y = -1@emax exactly (but not representable). */ + inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd); + if (overflow ^ (mpfr_overflow_p () != 0)) + { + printf ("Error in test_overflow2 (i = %d, %s): wrong overflow" + " flag (should be %d)\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), overflow); + err = 1; + } + if (mpfr_nanflag_p ()) + { + printf ("Error in test_overflow2 (i = %d, %s): NaN flag should" + " not be set\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (mpfr_nan_p (r)) + { + printf ("Error in test_overflow2 (i = %d, %s): got NaN\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + else if (MPFR_SIGN (r) >= 0) + { + printf ("Error in test_overflow2 (i = %d, %s): wrong sign " + "(+ instead of -)\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + else if (inf && ! mpfr_inf_p (r)) + { + printf ("Error in test_overflow2 (i = %d, %s): expected -Inf," + " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_dump (r); + err = 1; + } + else if (!inf && (mpfr_inf_p (r) || + (mpfr_nextbelow (r), ! mpfr_inf_p (r)))) + { + printf ("Error in test_overflow2 (i = %d, %s): expected -MAX," + " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_dump (r); + err = 1; + } + if (inf ? inex >= 0 : inex <= 0) + { + printf ("Error in test_overflow2 (i = %d, %s): wrong inexact" + " flag (got %d)\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex); + err = 1; + } + + } + + if (err) + exit (1); + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_underflow1 (void) +{ + mpfr_t x, y, z, r; + int inex, signy, signz, rnd, err = 0; + + mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0); + + MPFR_SET_POS (x); + mpfr_setmin (x, mpfr_get_emin ()); /* x = 0.1@emin */ + + for (signy = -1; signy <= 1; signy += 2) + { + mpfr_set_si_2exp (y, signy, -1, MPFR_RNDN); /* |y| = 1/2 */ + for (signz = -3; signz <= 3; signz += 2) + { + RND_LOOP (rnd) + { + mpfr_set_si (z, signz, MPFR_RNDN); + if (ABS (signz) != 1) + mpfr_setmax (z, mpfr_get_emax ()); + /* |z| = 1 or 2^emax - ulp */ + mpfr_clear_flags (); + inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd); +#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " + if (mpfr_nanflag_p ()) + { + printf (ERRTU1 "NaN flag is set\n", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (signy < 0 && MPFR_IS_LIKE_RNDD(rnd, signz)) + mpfr_nextbelow (z); + if (signy > 0 && MPFR_IS_LIKE_RNDU(rnd, signz)) + mpfr_nextabove (z); + if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0)) + { + printf (ERRTU1 "wrong overflow flag\n", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (mpfr_underflow_p ()) + { + printf (ERRTU1 "underflow flag is set\n", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (r, z)) + { + printf (ERRTU1 "got ", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (r); + printf (" instead of "); + mpfr_print_binary (z); + printf ("\n"); + err = 1; + } + if (inex >= 0 && (rnd == MPFR_RNDD || + (rnd == MPFR_RNDZ && signz > 0) || + (rnd == MPFR_RNDN && signy > 0))) + { + printf (ERRTU1 "ternary value = %d instead of < 0\n", + signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + inex); + err = 1; + } + if (inex <= 0 && (rnd == MPFR_RNDU || + (rnd == MPFR_RNDZ && signz < 0) || + (rnd == MPFR_RNDN && signy < 0))) + { + printf (ERRTU1 "ternary value = %d instead of > 0\n", + signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + inex); + err = 1; + } + } + } + } + + if (err) + exit (1); + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_underflow2 (void) +{ + mpfr_t x, y, z, r; + int b, i, inex, same, err = 0; + + mpfr_inits2 (32, x, y, z, r, (mpfr_ptr) 0); + + mpfr_set_si_2exp (z, 1, mpfr_get_emin (), MPFR_RNDN); /* z = 2^emin */ + mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN); /* x = 2^emin */ + + for (b = 0; b <= 1; b++) + { + for (i = 15; i <= 17; i++) + { + mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), MPFR_RNDN); + /* z = 1.000...00b + * xy = 01111 + * or 10000 + * or 10001 + */ + mpfr_clear_flags (); + inex = mpfr_fma (r, x, y, z, MPFR_RNDN); +#define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " + if (__gmpfr_flags != MPFR_FLAGS_INEXACT) + { + printf (ERRTU2 "flags = %u instead of %u\n", b, i, + __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT); + err = 1; + } + same = i == 15 || (i == 16 && b == 0); + if (same ? (inex >= 0) : (inex <= 0)) + { + printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n", + b, i, inex, same ? '<' : '>'); + err = 1; + } + mpfr_set (y, z, MPFR_RNDN); + if (!same) + mpfr_nextabove (y); + if (! mpfr_equal_p (r, y)) + { + printf (ERRTU2 "expected ", b, i); + mpfr_dump (y); + printf (" got "); + mpfr_dump (r); + err = 1; + } + } + mpfr_nextabove (z); + } + + if (err) + exit (1); + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_underflow3 (int n) +{ + mpfr_t x, y, z, t1, t2; + int sign, k, s, rnd, inex1, inex2; + mpfr_exp_t e; + unsigned int flags1, flags2; + + mpfr_inits2 (4, x, z, t1, t2, (mpfr_ptr) 0); + mpfr_init2 (y, 6); + + e = mpfr_get_emin () - 1; + + for (sign = 1; sign >= -1; sign -= 2) + for (k = 1; k <= 7; k++) + for (s = -1; s <= 1; s++) + { + mpfr_set_si_2exp (x, sign, e, MPFR_RNDN); + mpfr_set_si_2exp (y, 8*k+s, -6, MPFR_RNDN); + mpfr_neg (z, x, MPFR_RNDN); + /* x = sign * 2^(emin-1) + y = (8 * k + s) * 2^(-6) = k / 8 + s * 2^(-6) + z = -x = -sign * 2^(emin-1) + FMA(x,y,z) = sign * ((k-8) * 2^(emin-4) + s * 2^(emin-7)) exactly. + Note: The purpose of the s * 2^(emin-7) term is to yield + double rounding when scaling for k = 4, s != 0, MPFR_RNDN. */ + + RND_LOOP (rnd) + { + mpfr_clear_flags (); + inex1 = mpfr_set_si_2exp (t1, sign * (8*k+s-64), e-6, + (mpfr_rnd_t) rnd); + flags1 = __gmpfr_flags; + + mpfr_clear_flags (); + inex2 = mpfr_fma (t2, x, y, z, (mpfr_rnd_t) rnd); + flags2 = __gmpfr_flags; + + if (! (mpfr_equal_p (t1, t2) && + SAME_SIGN (inex1, inex2) && + flags1 == flags2)) + { + printf ("Error in test_underflow3, n = %d, sign = %d," + " k = %d, s = %d, %s\n", n, sign, k, s, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Expected "); + mpfr_dump (t1); + printf (" with inex ~ %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (t2); + printf (" with inex ~ %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + } + + mpfr_clears (x, y, z, t1, t2, (mpfr_ptr) 0); +} + +static void +bug20101018 (void) +{ + mpfr_t x, y, z, t, u; + int i; + + mpfr_init2 (x, 64); + mpfr_init2 (y, 64); + mpfr_init2 (z, 64); + mpfr_init2 (t, 64); + mpfr_init2 (u, 64); + + mpfr_set_str (x, "0xf.fffffffffffffffp-14766", 16, MPFR_RNDN); + mpfr_set_str (y, "-0xf.fffffffffffffffp+317", 16, MPFR_RNDN); + mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN); + mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN); + i = mpfr_fma (u, x, y, z, MPFR_RNDN); + if (! mpfr_equal_p (u, t)) + { + printf ("Wrong result in bug20101018 (a)\n"); + printf ("Expected "); + mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (i <= 0) + { + printf ("Wrong ternary value in bug20101018 (a)\n"); + printf ("Expected > 0\n"); + printf ("Got %d\n", i); + exit (1); + } + + mpfr_set_str (x, "-0xf.fffffffffffffffp-11420", 16, MPFR_RNDN); + mpfr_set_str (y, "0xf.fffffffffffffffp+9863", 16, MPFR_RNDN); + mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN); + mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN); + i = mpfr_fma (u, x, y, z, MPFR_RNDN); + if (! mpfr_equal_p (u, t)) + { + printf ("Wrong result in bug20101018 (b)\n"); + printf ("Expected "); + mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (i <= 0) + { + printf ("Wrong ternary value in bug20101018 (b)\n"); + printf ("Expected > 0\n"); + printf ("Got %d\n", i); + exit (1); + } + + mpfr_set_str (x, "0xf.fffffffffffffffp-2125", 16, MPFR_RNDN); + mpfr_set_str (y, "-0xf.fffffffffffffffp-6000", 16, MPFR_RNDN); + mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN); + mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN); + i = mpfr_fma (u, x, y, z, MPFR_RNDN); + if (! mpfr_equal_p (u, t)) + { + printf ("Wrong result in bug20101018 (c)\n"); + printf ("Expected "); + mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (i <= 0) + { + printf ("Wrong ternary value in bug20101018 (c)\n"); + printf ("Expected > 0\n"); + printf ("Got %d\n", i); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + mpfr_clear (u); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, z, s; + mpfr_exp_t emin, emax; + + tests_start_mpfr (); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + bug20101018 (); + + mpfr_init (x); + mpfr_init (s); + mpfr_init (y); + mpfr_init (z); + + /* check special cases */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_prec (z, 2); + mpfr_set_prec (s, 2); + mpfr_set_str (x, "-0.75", 10, MPFR_RNDN); + mpfr_set_str (y, "0.5", 10, MPFR_RNDN); + mpfr_set_str (z, "0.375", 10, MPFR_RNDN); + mpfr_fma (s, x, y, z, MPFR_RNDU); /* result is 0 */ + if (mpfr_cmp_ui(s, 0)) + { + printf("Error: -0.75 * 0.5 + 0.375 should be equal to 0 for prec=2\n"); + exit(1); + } + + mpfr_set_prec (x, 27); + mpfr_set_prec (y, 27); + mpfr_set_prec (z, 27); + mpfr_set_prec (s, 27); + mpfr_set_str_binary (x, "1.11111111111111111111111111e-1"); + mpfr_set (y, x, MPFR_RNDN); + mpfr_set_str_binary (z, "-1.00011110100011001011001001e-1"); + if (mpfr_fma (s, x, y, z, MPFR_RNDN) >= 0) + { + printf ("Wrong inexact flag for x=y=1-2^(-27)\n"); + exit (1); + } + + mpfr_set_nan (x); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=NAN does not return NAN"); + exit (1); + } + + mpfr_set_nan (y); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p(s)) + { + printf ("evaluation of function in y=NAN does not return NAN"); + exit (1); + } + + mpfr_set_nan (z); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (x, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in z=NAN does not return NAN"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, 1); + mpfr_set_inf (z, 1); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("Error for (+inf) * (+inf) + (+inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_set_inf (y, -1); + mpfr_set_inf (z, 1); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("Error for (-inf) * (-inf) + (+inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, -1); + mpfr_set_inf (z, -1); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0) + { + printf ("Error for (+inf) * (-inf) + (-inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_set_inf (y, 1); + mpfr_set_inf (z, -1); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0) + { + printf ("Error for (-inf) * (+inf) + (-inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=INF y=0 does not return NAN"); + exit (1); + } + + mpfr_set_inf (y, 1); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=0 y=INF does not return NAN"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_urandomb (y, RANDS); /* always positive */ + mpfr_set_inf (z, -1); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=INF y>0 z=-INF does not return NAN"); + exit (1); + } + + mpfr_set_inf (y, 1); + mpfr_urandomb (x, RANDS); + mpfr_set_inf (z, -1); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x>0 y=INF z=-INF does not return NAN"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("evaluation of function in x=INF does not return INF"); + exit (1); + } + + mpfr_set_inf (y, 1); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("evaluation of function in y=INF does not return INF"); + exit (1); + } + + mpfr_set_inf (z, 1); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("evaluation of function in z=INF does not return INF"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (! mpfr_equal_p (s, z)) + { + printf ("evaluation of function in x=0 does not return z\n"); + exit (1); + } + + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fma (s, x, y, z, MPFR_RNDN); + if (! mpfr_equal_p (s, z)) + { + printf ("evaluation of function in y=0 does not return z\n"); + exit (1); + } + + { + mpfr_prec_t prec; + mpfr_t t, slong; + mpfr_rnd_t rnd; + int inexact, compare; + unsigned int n; + + mpfr_prec_t p0 = 2, p1 = 200; + unsigned int N = 200; + + mpfr_init (t); + mpfr_init (slong); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (s, prec); + mpfr_set_prec (t, prec); + + for (n = 0; n < N; n++) + { + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + + if (randlimb () % 2) + mpfr_neg (x, x, MPFR_RNDN); + if (randlimb () % 2) + mpfr_neg (y, y, MPFR_RNDN); + if (randlimb () % 2) + mpfr_neg (z, z, MPFR_RNDN); + + rnd = RND_RAND (); + mpfr_set_prec (slong, 2 * prec); + if (mpfr_mul (slong, x, y, rnd)) + { + printf ("x*y should be exact\n"); + exit (1); + } + compare = mpfr_add (t, slong, z, rnd); + inexact = mpfr_fma (s, x, y, z, rnd); + if (! mpfr_equal_p (s, t)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf (" y="); + mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN); + printf (" z="); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN); + puts (""); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf ("approx "); + mpfr_print_binary (slong); + puts (""); + exit (1); + } + if (! SAME_SIGN (inexact, compare)) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + } + mpfr_clear (t); + mpfr_clear (slong); + + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (s); + + test_exact (); + + test_overflow1 (); + test_overflow2 (); + test_underflow1 (); + test_underflow2 (); + test_underflow3 (1); + + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + test_overflow1 (); + test_overflow2 (); + test_underflow1 (); + test_underflow2 (); + test_underflow3 (2); + set_emin (emin); + set_emax (emax); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tfmod.c b/mpfr/tests/tfmod.c new file mode 100644 index 0000000000..659ce1c434 --- /dev/null +++ b/mpfr/tests/tfmod.c @@ -0,0 +1,437 @@ +/* tfmod -- test file for mpfr_fmod + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +#define TEST_FUNCTION mpfr_fmod +#define TWO_ARGS +#include "tgeneric.c" + +/* compute remainder as in definition: + r = x - n * y, where n = trunc(x/y). + warning: may change flags. */ +static int +slow_fmod (mpfr_ptr r, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd) +{ + mpfr_t q; + int inexact; + if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y))) + { + if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x) + || MPFR_IS_ZERO (y)) + { + MPFR_SET_NAN (r); + MPFR_RET_NAN; + } + else /* either y is Inf and x is 0 or non-special, + or x is 0 and y is non-special, + in both cases the quotient is zero. */ + return mpfr_set (r, x, rnd); + } + /* regular cases */ + /* if 2^(ex-1) <= |x| < 2^ex, and 2^(ey-1) <= |y| < 2^ey, + then |x/y| < 2^(ex-ey+1) */ + mpfr_init2 (q, + MAX (MPFR_PREC_MIN, mpfr_get_exp (x) - mpfr_get_exp (y) + 1)); + mpfr_div (q, x, y, MPFR_RNDZ); + mpfr_trunc (q, q); /* may change inexact flag */ + mpfr_prec_round (q, mpfr_get_prec (q) + mpfr_get_prec (y), MPFR_RNDZ); + inexact = mpfr_mul (q, q, y, MPFR_RNDZ); /* exact */ + inexact = mpfr_sub (r, x, q, rnd); + mpfr_clear (q); + return inexact; +} + +static void +test_failed (mpfr_t erem, mpfr_t grem, int eret, int gret, mpfr_t x, mpfr_t y, + mpfr_rnd_t rnd) +{ + printf ("error: mpfr_fmod (r, x, y, rnd)\n x = "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD); + printf ("\n y = "); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD); + printf ("\nrnd = %s", mpfr_print_rnd_mode (rnd)); + if (eret != gret) + printf ("\nexpected %s return value, got %d", + (eret < 0 ? "negative" : eret > 0 ? "positive" : "zero"), gret); + printf ("\n expected r = "); + mpfr_out_str (stdout, 10, 0, erem, MPFR_RNDD); + printf ("\n got r = "); + mpfr_out_str (stdout, 10, 0, grem, MPFR_RNDD); + putchar ('\n'); + + exit (1); +} + +static void +check (mpfr_t r0, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd) +{ + int inex0, inex1; + mpfr_t r1; + mpfr_init2 (r1, mpfr_get_prec (r0)); + + inex0 = mpfr_fmod (r0, x, y, rnd); + inex1 = slow_fmod (r1, x, y, rnd); + if (!mpfr_equal_p (r0, r1) || inex0 != inex1) + test_failed (r1, r0, inex1, inex0, x, y, rnd); + mpfr_clear (r1); +} + +static void +regular (void) +{ + mpfr_t x, y, r; + mpfr_inits (x, y, r, (mpfr_ptr) 0); + + /* remainder = 0 */ + mpfr_set_str (y, "FEDCBA987654321p-64", 16, MPFR_RNDN); + mpfr_pow_ui (x, y, 42, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + + /* x < y */ + mpfr_set_ui_2exp (x, 64723, -19, MPFR_RNDN); + mpfr_mul (x, x, y, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + + /* sign(x) = sign (r) */ + mpfr_set_ui (x, 123798, MPFR_RNDN); + mpfr_set_ui (y, 10, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + + /* huge difference between precisions */ + mpfr_set_prec (x, 314); + mpfr_set_prec (y, 8); + mpfr_set_prec (r, 123); + mpfr_const_pi (x, MPFR_RNDD); /* x = pi */ + mpfr_set_ui_2exp (y, 1, 3, MPFR_RNDD); /* y = 1/8 */ + check (r, x, y, MPFR_RNDD); + + mpfr_clears (x, y, r, (mpfr_ptr) 0); +} + +static void +special (void) +{ + int inexact; + mpfr_t x, y, r, t; + + mpfr_inits (x, y, r, t, (mpfr_ptr) 0); + + mpfr_set_nan (t); + + /* fmod (NaN, NaN) is NaN */ + mpfr_set_nan (x); + mpfr_set_nan (y); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (NaN, +0) is NaN */ + mpfr_set_ui (y, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+1, 0) is NaN */ + mpfr_set_ui (x, 1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (0, 0) is NaN */ + mpfr_set_ui (x, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, +0) is NaN */ + mpfr_set_inf (x, +1); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, +0) is NaN */ + mpfr_set_inf (x, -1); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, -0) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, +1) is NaN */ + mpfr_set_ui (y, +1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, +1) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, -inf) is NaN */ + mpfr_set_inf (y, -1); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, -inf) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, +inf) is NaN */ + mpfr_neg (y, y, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, +inf) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (x, +inf) = x, if x is finite */ + mpfr_set_ui (x, 1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, +inf) = +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-0, +inf) = -0 */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (x, -inf) = x, if x is finite */ + mpfr_set_inf (y, -1); + mpfr_set_ui (x, 1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, -inf) = +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-0, -inf) = -0 */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, +0) is NaN */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, -0) is NaN */ + mpfr_neg (y, y, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) + test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, +1) = +0 */ + mpfr_set_ui (y, 1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, -1) = +0 */ + mpfr_neg (y, y, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-0, -1) = -0 */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-0, +1) = -0 */ + mpfr_neg (y, y, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + + mpfr_set_prec (x, 380); + mpfr_set_prec (y, 385); + mpfr_set_str_binary (x, "0.11011010010110011101011000100100101100101011010001011100110001100101111001010100001011111110111100101110101010110011010101000100000100011101101100001011101110100111101111111010001001000010000110010110011100111000001110111010000100101001010111100100010001101001110100011110010000000001110001111001101100111011001000110110011100100011111110010100011001000001001011010111010000000000E0"); + mpfr_set_str_binary (y, "0.1100011000011101011010001100010111001110110111001101010010111100111100011010010011011101111101111001010111111110001001100001111101001000000010100101111001001110010110000111001000101010111001001000100101011111000010100110001111000110011011010101111101100110010101011010011101100001011101001000101111110110110110000001001101110111110110111110111111001001011110001110011111100000000000000E-1"); + mpfr_set_prec (r, 2); + inexact = mpfr_fmod (r, x, y, MPFR_RNDA); + mpfr_set_prec (t, 2); + mpfr_set_ui_2exp (t, 3, -5, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (r, 3, -5) || inexact <= 0) + test_failed (r, t, 1, inexact, x, y, MPFR_RNDA); + + mpfr_clears (x, y, r, t, (mpfr_ptr) 0); + return; +} + +/* bug reported by Eric Veach */ +static void +bug20090519 (void) +{ + mpfr_t x, y, r; + int inexact; + + mpfr_inits2 (100, x, y, r, (mpfr_ptr) 0); + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 3); + mpfr_set_prec (r, 3); + mpfr_set_si (x, 8, MPFR_RNDN); + mpfr_set_si (y, 7, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + + mpfr_set_prec (x, 10); + mpfr_set_prec (y, 10); + mpfr_set_prec (r, 10); + mpfr_set_ui_2exp (x, 3, 26, MPFR_RNDN); + mpfr_set_si (y, (1 << 9) - 1, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + + mpfr_set_prec (x, 100); + mpfr_set_prec (y, 100); + mpfr_set_prec (r, 100); + mpfr_set_str (x, "3.5", 10, MPFR_RNDN); + mpfr_set_str (y, "1.1", 10, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + /* double check, with a pre-computed value */ + { + mpfr_t er; + mpfr_init2 (er, 100); + mpfr_set_str (er, "CCCCCCCCCCCCCCCCCCCCCCCC8p-102", 16, MPFR_RNDN); + + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, er) || inexact != 0) + test_failed (er, r, 0, inexact, x, y, MPFR_RNDN); + + mpfr_clear (er); + } + + mpfr_set_si (x, 20, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, 1, MPFR_RNDN); /* exact */ + mpfr_sin (y, y, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + + mpfr_clears (x, y, r, (mpfr_ptr) 0); +} + +static void +bug20160217 (void) +{ + mpfr_t x, y, r; + int inexact, i; + mpfr_exp_t emin, emax; + + mpfr_inits2 (53, x, y, r, (mpfr_ptr) 0); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + for (i = 0; i <= 1; i++) + { + mpfr_set_zero (x, 1); + mpfr_nextabove (x); + mpfr_set_inf (y, 1); + mpfr_nextbelow (y); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_equal_p (r, x) || inexact != 0) + { + printf ("Error for mpfr_fmod (r, nextabove(0), nextbelow(+inf)," + " MPFR_RNDN)%s\n", i ? "extended exponent range" : ""); + printf ("Expected inex = 0, r = "); + mpfr_dump (x); + printf ("Got inex = %d, r = ", inexact); + mpfr_dump (r); + exit (1); + } + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + } + + set_emin (emin); + set_emax (emax); + + mpfr_clears (x, y, r, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + bug20090519 (); + bug20160217 (); + + test_generic (2, 100, 100); + + special (); + regular (); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tfms.c b/mpfr/tests/tfms.c new file mode 100644 index 0000000000..a7d4f3a787 --- /dev/null +++ b/mpfr/tests/tfms.c @@ -0,0 +1,644 @@ +/* Test file for mpfr_fms. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* When a * b is exact, the FMS is equivalent to the separate operations. */ +static void +test_exact (void) +{ + const char *val[] = + { "@NaN@", "-@Inf@", "-2", "-1", "-0", "0", "1", "2", "@Inf@" }; + int sv = sizeof (val) / sizeof (*val); + int i, j, k; + int rnd; + mpfr_t a, b, c, r1, r2; + + mpfr_inits2 (8, a, b, c, r1, r2, (mpfr_ptr) 0); + + for (i = 0; i < sv; i++) + for (j = 0; j < sv; j++) + for (k = 0; k < sv; k++) + RND_LOOP (rnd) + { + if (mpfr_set_str (a, val[i], 10, MPFR_RNDN) || + mpfr_set_str (b, val[j], 10, MPFR_RNDN) || + mpfr_set_str (c, val[k], 10, MPFR_RNDN) || + mpfr_mul (r1, a, b, (mpfr_rnd_t) rnd) || + mpfr_sub (r1, r1, c, (mpfr_rnd_t) rnd)) + { + printf ("test_exact internal error for (%d,%d,%d,%d)\n", + i, j, k, rnd); + exit (1); + } + if (mpfr_fms (r2, a, b, c, (mpfr_rnd_t) rnd)) + { + printf ("test_exact(%d,%d,%d,%d): mpfr_fms should be exact\n", + i, j, k, rnd); + exit (1); + } + if (MPFR_IS_NAN (r1)) + { + if (MPFR_IS_NAN (r2)) + continue; + printf ("test_exact(%d,%d,%d,%d): mpfr_fms should be NaN\n", + i, j, k, rnd); + exit (1); + } + if (mpfr_cmp (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2)) + { + printf ("test_exact(%d,%d,%d,%d):\nexpected ", i, j, k, rnd); + mpfr_out_str (stdout, 10, 0, r1, MPFR_RNDN); + printf ("\n got "); + mpfr_out_str (stdout, 10, 0, r2, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + + mpfr_clears (a, b, c, r1, r2, (mpfr_ptr) 0); +} + +static void +test_overflow1 (void) +{ + mpfr_t x, y, z, r; + int inex; + + mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0); + MPFR_SET_POS (x); + mpfr_setmax (x, mpfr_get_emax ()); /* x = 2^emax - ulp */ + mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */ + mpfr_set (z, x, MPFR_RNDN); /* z = x = 2^emax - ulp */ + mpfr_clear_flags (); + /* The intermediate multiplication x * y overflows, but x * y - z = x + is representable. */ + inex = mpfr_fms (r, x, y, z, MPFR_RNDN); + if (inex || ! mpfr_equal_p (r, x)) + { + printf ("Error in test_overflow1\nexpected "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" with inex = 0\n got "); + mpfr_out_str (stdout, 2, 0, r, MPFR_RNDN); + printf (" with inex = %d\n", inex); + exit (1); + } + if (mpfr_overflow_p ()) + { + printf ("Error in test_overflow1: overflow flag set\n"); + exit (1); + } + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_overflow2 (void) +{ + mpfr_t x, y, z, r; + int i, inex, rnd, err = 0; + + mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0); + + MPFR_SET_POS (x); + mpfr_setmin (x, mpfr_get_emax ()); /* x = 0.1@emax */ + mpfr_set_si (y, -2, MPFR_RNDN); /* y = -2 */ + /* The intermediate multiplication x * y will overflow. */ + + for (i = -9; i <= 9; i++) + RND_LOOP (rnd) + { + int inf, overflow; + + inf = rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA; + overflow = inf || i <= 0; + + inex = mpfr_set_si_2exp (z, -i, mpfr_get_emin (), MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + mpfr_clear_flags (); + /* One has: x * y = -1@emax exactly (but not representable). */ + inex = mpfr_fms (r, x, y, z, (mpfr_rnd_t) rnd); + if (overflow ^ (mpfr_overflow_p () != 0)) + { + printf ("Error in test_overflow2 (i = %d, %s): wrong overflow" + " flag (should be %d)\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), overflow); + err = 1; + } + if (mpfr_nanflag_p ()) + { + printf ("Error in test_overflow2 (i = %d, %s): NaN flag should" + " not be set\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (mpfr_nan_p (r)) + { + printf ("Error in test_overflow2 (i = %d, %s): got NaN\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + else if (MPFR_SIGN (r) >= 0) + { + printf ("Error in test_overflow2 (i = %d, %s): wrong sign " + "(+ instead of -)\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + else if (inf && ! mpfr_inf_p (r)) + { + printf ("Error in test_overflow2 (i = %d, %s): expected -Inf," + " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_dump (r); + err = 1; + } + else if (!inf && (mpfr_inf_p (r) || + (mpfr_nextbelow (r), ! mpfr_inf_p (r)))) + { + printf ("Error in test_overflow2 (i = %d, %s): expected -MAX," + " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_dump (r); + err = 1; + } + if (inf ? inex >= 0 : inex <= 0) + { + printf ("Error in test_overflow2 (i = %d, %s): wrong inexact" + " flag (got %d)\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex); + err = 1; + } + + } + + if (err) + exit (1); + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_underflow1 (void) +{ + mpfr_t x, y, z, r; + int inex, signy, signz, rnd, err = 0; + + mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0); + + MPFR_SET_POS (x); + mpfr_setmin (x, mpfr_get_emin ()); /* x = 0.1@emin */ + + for (signy = -1; signy <= 1; signy += 2) + { + mpfr_set_si_2exp (y, signy, -1, MPFR_RNDN); /* |y| = 1/2 */ + for (signz = -3; signz <= 3; signz += 2) + { + RND_LOOP (rnd) + { + mpfr_set_si (z, signz, MPFR_RNDN); + if (ABS (signz) != 1) + mpfr_setmax (z, mpfr_get_emax ()); + /* |z| = 1 or 2^emax - ulp */ + mpfr_clear_flags (); + inex = mpfr_fms (r, x, y, z, (mpfr_rnd_t) rnd); +#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " + if (mpfr_nanflag_p ()) + { + printf (ERRTU1 "NaN flag is set\n", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + mpfr_neg (z, z, MPFR_RNDN); + if (signy < 0 && MPFR_IS_LIKE_RNDD(rnd, -signz)) + mpfr_nextbelow (z); + if (signy > 0 && MPFR_IS_LIKE_RNDU(rnd, -signz)) + mpfr_nextabove (z); + if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0)) + { + printf (ERRTU1 "wrong overflow flag\n", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (mpfr_underflow_p ()) + { + printf (ERRTU1 "underflow flag is set\n", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (r, z)) + { + printf (ERRTU1 "got ", signy, signz, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (r); + printf (" instead of "); + mpfr_print_binary (z); + printf ("\n"); + err = 1; + } + if (inex >= 0 && (rnd == MPFR_RNDD || + (rnd == MPFR_RNDZ && signz < 0) || + (rnd == MPFR_RNDN && signy > 0))) + { + printf (ERRTU1 "ternary value = %d instead of < 0\n", + signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + inex); + err = 1; + } + if (inex <= 0 && (rnd == MPFR_RNDU || + (rnd == MPFR_RNDZ && signz > 0) || + (rnd == MPFR_RNDN && signy < 0))) + { + printf (ERRTU1 "ternary value = %d instead of > 0\n", + signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + inex); + err = 1; + } + } + } + } + + if (err) + exit (1); + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +static void +test_underflow2 (void) +{ + mpfr_t x, y, z, r; + int b, i, inex, same, err = 0; + + mpfr_inits2 (32, x, y, z, r, (mpfr_ptr) 0); + + mpfr_set_si_2exp (z, -1, mpfr_get_emin (), MPFR_RNDN); /* z = -2^emin */ + mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN); /* x = 2^emin */ + + for (b = 0; b <= 1; b++) + { + for (i = 15; i <= 17; i++) + { + mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), MPFR_RNDN); + /* z = -1.000...00b + * xy = 01111 + * or 10000 + * or 10001 + */ + mpfr_clear_flags (); + inex = mpfr_fms (r, x, y, z, MPFR_RNDN); +#define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " + if (__gmpfr_flags != MPFR_FLAGS_INEXACT) + { + printf (ERRTU2 "flags = %u instead of %u\n", b, i, + __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT); + err = 1; + } + same = i == 15 || (i == 16 && b == 0); + if (same ? (inex >= 0) : (inex <= 0)) + { + printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n", + b, i, inex, same ? '<' : '>'); + err = 1; + } + mpfr_neg (y, z, MPFR_RNDN); + if (!same) + mpfr_nextabove (y); + if (! mpfr_equal_p (r, y)) + { + printf (ERRTU2 "expected ", b, i); + mpfr_dump (y); + printf (" got "); + mpfr_dump (r); + err = 1; + } + } + mpfr_nextbelow (z); + } + + if (err) + exit (1); + mpfr_clears (x, y, z, r, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, z, s; + MPFR_SAVE_EXPO_DECL (expo); + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (s); + mpfr_init (y); + mpfr_init (z); + + /* check special cases */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_prec (z, 2); + mpfr_set_prec (s, 2); + mpfr_set_str (x, "-0.75", 10, MPFR_RNDN); + mpfr_set_str (y, "0.5", 10, MPFR_RNDN); + mpfr_set_str (z, "-0.375", 10, MPFR_RNDN); + mpfr_fms (s, x, y, z, MPFR_RNDU); /* result is 0 */ + if (mpfr_cmp_ui(s, 0)) + { + printf("Error: -0.75 * 0.5 - -0.375 should be equal to 0 for prec=2\n"); + exit(1); + } + + mpfr_set_prec (x, 27); + mpfr_set_prec (y, 27); + mpfr_set_prec (z, 27); + mpfr_set_prec (s, 27); + mpfr_set_str_binary (x, "1.11111111111111111111111111e-1"); + mpfr_set (y, x, MPFR_RNDN); + mpfr_set_str_binary (z, "1.00011110100011001011001001e-1"); + if (mpfr_fms (s, x, y, z, MPFR_RNDN) >= 0) + { + printf ("Wrong inexact flag for x=y=1-2^(-27)\n"); + exit (1); + } + + mpfr_set_nan (x); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=NAN does not return NAN"); + exit (1); + } + + mpfr_set_nan (y); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p(s)) + { + printf ("evaluation of function in y=NAN does not return NAN"); + exit (1); + } + + mpfr_set_nan (z); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (x, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in z=NAN does not return NAN"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, 1); + mpfr_set_inf (z, -1); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("Error for (+inf) * (+inf) - (-inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_set_inf (y, -1); + mpfr_set_inf (z, -1); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("Error for (-inf) * (-inf) - (-inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, -1); + mpfr_set_inf (z, 1); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0) + { + printf ("Error for (+inf) * (-inf) - (+inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_set_inf (y, 1); + mpfr_set_inf (z, 1); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0) + { + printf ("Error for (-inf) * (+inf) - (+inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=INF y=0 does not return NAN"); + exit (1); + } + + mpfr_set_inf (y, 1); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=0 y=INF does not return NAN"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_urandomb (y, RANDS); /* always positive */ + mpfr_set_inf (z, 1); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x=INF y>0 z=INF does not return NAN"); + exit (1); + } + + mpfr_set_inf (y, 1); + mpfr_urandomb (x, RANDS); + mpfr_set_inf (z, 1); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_nan_p (s)) + { + printf ("evaluation of function in x>0 y=INF z=INF does not return NAN"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("evaluation of function in x=INF does not return INF"); + exit (1); + } + + mpfr_set_inf (y, 1); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("evaluation of function in y=INF does not return INF"); + exit (1); + } + + mpfr_set_inf (z, -1); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0) + { + printf ("evaluation of function in z=-INF does not return INF"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + mpfr_neg (z, z, MPFR_RNDN); + if (mpfr_cmp (s, z)) + { + printf ("evaluation of function in x=0 does not return -z\n"); + exit (1); + } + + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (z, RANDS); + mpfr_fms (s, x, y, z, MPFR_RNDN); + mpfr_neg (z, z, MPFR_RNDN); + if (mpfr_cmp (s, z)) + { + printf ("evaluation of function in y=0 does not return -z\n"); + exit (1); + } + + { + mpfr_prec_t prec; + mpfr_t t, slong; + mpfr_rnd_t rnd; + int inexact, compare; + unsigned int n; + + mpfr_prec_t p0=2, p1=200; + unsigned int N=200; + + mpfr_init (t); + mpfr_init (slong); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (s, prec); + mpfr_set_prec (t, prec); + + for (n=0; n<N; n++) + { + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + + if (randlimb () % 2) + mpfr_neg (x, x, MPFR_RNDN); + if (randlimb () % 2) + mpfr_neg (y, y, MPFR_RNDN); + if (randlimb () % 2) + mpfr_neg (z, z, MPFR_RNDN); + + rnd = RND_RAND (); + mpfr_set_prec (slong, 2 * prec); + if (mpfr_mul (slong, x, y, rnd)) + { + printf ("x*y should be exact\n"); + exit (1); + } + compare = mpfr_sub (t, slong, z, rnd); + inexact = mpfr_fms (s, x, y, z, rnd); + if (mpfr_cmp (s, t)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf (" y="); + mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN); + printf (" z="); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN); + puts (""); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf ("approx "); + mpfr_print_binary (slong); + puts (""); + exit (1); + } + if (((inexact == 0) && (compare != 0)) || + ((inexact < 0) && (compare >= 0)) || + ((inexact > 0) && (compare <= 0))) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + } + mpfr_clear (t); + mpfr_clear (slong); + + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (s); + + test_exact (); + + MPFR_SAVE_EXPO_MARK (expo); + test_overflow1 (); + test_overflow2 (); + test_underflow1 (); + test_underflow2 (); + MPFR_SAVE_EXPO_FREE (expo); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tfprintf.c b/mpfr/tests/tfprintf.c new file mode 100644 index 0000000000..412ab4fd6f --- /dev/null +++ b/mpfr/tests/tfprintf.c @@ -0,0 +1,445 @@ +/* tfprintf.c -- test file for mpfr_fprintf and mpfr_vfprintf + +Copyright 2008-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_STDARG +#include <stdarg.h> + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> +#include <stddef.h> + +#include "mpfr-intmax.h" +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +#define QUOTE(X) NAME(X) +#define NAME(X) #X + +#define check_length(num_test, var, value, var_spec) \ + if ((var) != (value)) \ + { \ + printf ("Error in test #%d: mpfr_vfprintf printed %"QUOTE(var_spec) \ + " characters instead of %d\n", (num_test), (var), (value)); \ + exit (1); \ + } + +#define check_length_with_cmp(num_test, var, value, cmp, var_spec) \ + if (cmp != 0) \ + { \ + mpfr_printf ("Error in test #%d, mpfr_vfprintf printed %" \ + QUOTE(var_spec)" characters instead of %d\n", \ + (num_test), (var), (value)); \ + exit (1); \ + } + +/* limit for random precision in random() */ +const int prec_max_printf = 5000; + +static void +check (FILE *fout, const char *fmt, mpfr_t x) +{ + if (mpfr_fprintf (fout, fmt, x) == -1) + { + mpfr_printf ("Error in mpfr_fprintf(fout, \"%s\", %Re)\n", + fmt, x); + exit (1); + } + fputc ('\n', fout); +} + +static void +check_vfprintf (FILE *fout, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + if (mpfr_vfprintf (fout, fmt, ap) == -1) + { + mpfr_printf ("Error in mpfr_vfprintf(fout, \"%s\", ...)\n", fmt); + + va_end (ap); + exit (1); + } + + va_end (ap); + fputc ('\n', fout); +} + +static void +check_special (FILE *fout) +{ + mpfr_t x; + + mpfr_init (x); + + mpfr_set_inf (x, 1); + check (fout, "%Ra", x); + check (fout, "%Rb", x); + check (fout, "%Re", x); + check (fout, "%Rf", x); + check (fout, "%Rg", x); + check_vfprintf (fout, "%Ra", x); + check_vfprintf (fout, "%Rb", x); + check_vfprintf (fout, "%Re", x); + check_vfprintf (fout, "%Rf", x); + check_vfprintf (fout, "%Rg", x); + + mpfr_set_inf (x, -1); + check (fout, "%Ra", x); + check (fout, "%Rb", x); + check (fout, "%Re", x); + check (fout, "%Rf", x); + check (fout, "%Rg", x); + check_vfprintf (fout, "%Ra", x); + check_vfprintf (fout, "%Rb", x); + check_vfprintf (fout, "%Re", x); + check_vfprintf (fout, "%Rf", x); + check_vfprintf (fout, "%Rg", x); + + mpfr_set_nan (x); + check (fout, "%Ra", x); + check (fout, "%Rb", x); + check (fout, "%Re", x); + check (fout, "%Rf", x); + check (fout, "%Rg", x); + check_vfprintf (fout, "%Ra", x); + check_vfprintf (fout, "%Rb", x); + check_vfprintf (fout, "%Re", x); + check_vfprintf (fout, "%Rf", x); + check_vfprintf (fout, "%Rg", x); + + mpfr_clear (x); +} + +static void +check_mixed (FILE *fout) +{ + int ch = 'a'; +#ifndef NPRINTF_HH + signed char sch = -1; + unsigned char uch = 1; +#endif + short sh = -1; + unsigned short ush = 1; + int i = -1; + int j = 1; + unsigned int ui = 1; + long lo = -1; + unsigned long ulo = 1; + float f = -1.25; + double d = -1.25; +#if !defined(NPRINTF_T) || !defined(NPRINTF_L) + long double ld = -1.25; +#endif + +#ifndef NPRINTF_T + ptrdiff_t p = 1, saved_p; +#endif + size_t sz = 1; + + mpz_t mpz; + mpq_t mpq; + mpf_t mpf; + mpfr_rnd_t rnd = MPFR_RNDN; + + mp_size_t limb_size = 3; + mp_limb_t limb[3]; + + mpfr_t mpfr; + mpfr_prec_t prec = 53; + + mpz_init (mpz); + mpz_set_ui (mpz, ulo); + mpq_init (mpq); + mpq_set_si (mpq, lo, ulo); + mpf_init (mpf); + mpf_set_q (mpf, mpq); + + mpfr_init2 (mpfr, prec); + mpfr_set_f (mpfr, mpf, MPFR_RNDN); + + limb[0] = limb[1] = limb[2] = ~ (mp_limb_t) 0; + + check_vfprintf (fout, "a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j); + check_length (1, j, 22, d); + check_vfprintf (fout, "a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i, + lo, &ulo); + check_length (2, ulo, 36, lu); + check_vfprintf (fout, "a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush); + check_length (3, ush, 29, hu); + check_vfprintf (fout, "a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i); + check_length (4, i, 29, d); + check_vfprintf (fout, "a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, + &sz); + check_length (5, (unsigned long) sz, 34, lu); /* no format specifier "%zu" in C89 */ + check_vfprintf (fout, "a. %Pu, b. %c, c. %Zi%Zn", prec, ch, mpz, &mpz); + check_length_with_cmp (6, mpz, 17, mpz_cmp_ui (mpz, 17), Zi); + check_vfprintf (fout, "%% a. %#.0RNg, b. %Qx%Rn, c. %p", mpfr, mpq, &mpfr, + (void *) &i); + check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg); + +#ifndef NPRINTF_T + saved_p = p; + check_vfprintf (fout, "%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p); + if (p != 20) + mpfr_fprintf (stderr, "Error in test 8, got '%% a. %RNg, b. %Qx, c. %td'\n", mpfr, mpq, saved_p); + check_length (8, (long) p, 20, ld); /* no format specifier "%td" in C89 */ +#endif + +#ifndef NPRINTF_L + check_vfprintf (fout, "a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz); + check_length (9, (unsigned long) sz, 30, lu); /* no format specifier "%zu" in C89 */ +#endif + +#ifndef NPRINTF_HH + check_vfprintf (fout, "a. %hhi, b. %RA, c. %hhu%hhn", sch, mpfr, uch, &uch); + check_length (10, (unsigned int) uch, 22, u); /* no format specifier "%hhu" in C89 */ +#endif + +#if (__GNU_MP_VERSION * 10 + __GNU_MP_VERSION_MINOR) >= 42 + /* The 'M' specifier was added in gmp 4.2.0 */ + check_vfprintf (fout, "a. %Mx b. %Re%Mn", limb[0], mpfr, &limb[0]); + if (limb[0] != 14 + GMP_NUMB_BITS / 4 || limb[1] != ~ (mp_limb_t) 0 + || limb[2] != ~ (mp_limb_t) 0) + { + printf ("Error in test #11: mpfr_vfprintf did not print %d characters" + " as expected\n", 14 + (int) GMP_NUMB_BITS / 4); + exit (1); + } + + limb[0] = ~ (mp_limb_t) 0; + /* we tell vfprintf that limb array is 2 cells wide + and check it doesn't go through */ + check_vfprintf (fout, "a. %Re .b %Nx%Nn", mpfr, limb, limb_size, limb, + limb_size - 1); + if (limb[0] != 14 + 3 * GMP_NUMB_BITS / 4 || limb[1] != (mp_limb_t) 0 + || limb[2] != ~ (mp_limb_t) 0) + { + printf ("Error in test #12: mpfr_vfprintf did not print %d characters" + " as expected\n", 14 + (int) GMP_NUMB_BITS / 4); + exit (1); + } +#endif + +#if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL) + { + long long llo = -1; + unsigned long long ullo = 1; + + check_vfprintf (fout, "a. %Re, b. %llx%Qn", mpfr, ullo, &mpq); + check_length_with_cmp (21, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu); + check_vfprintf (fout, "a. %lli, b. %Rf%Fn", llo, mpfr, &mpf); + check_length_with_cmp (22, mpf, 19, mpf_cmp_ui (mpf, 19), Fg); + } +#endif + +#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J) + { + intmax_t im = -1; + uintmax_t uim = 1; + + check_vfprintf (fout, "a. %*RA, b. %ji%Qn", 10, mpfr, im, &mpq); + check_length_with_cmp (31, mpq, 20, mpq_cmp_ui (mpq, 20, 1), Qu); + check_vfprintf (fout, "a. %.*Re, b. %jx%Fn", 10, mpfr, uim, &mpf); + check_length_with_cmp (32, mpf, 25, mpf_cmp_ui (mpf, 25), Fg); + } +#endif + + mpfr_clear (mpfr); + mpf_clear (mpf); + mpq_clear (mpq); + mpz_clear (mpz); +} + +static void +check_random (FILE *fout, int nb_tests) +{ + int i; + mpfr_t x; + mpfr_rnd_t rnd; + char flag[] = + { + '-', + '+', + ' ', + '#', + '0', /* no ambiguity: first zeros are flag zero*/ + '\'' + }; + char specifier[] = + { + 'a', + 'b', + 'e', + 'f', + 'g' + }; + mpfr_exp_t old_emin, old_emax; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + mpfr_init (x); + + for (i = 0; i < nb_tests; ++i) + { + int ret; + int j, jmax; + int spec, prec; +#define FMT_SIZE 13 + char fmt[FMT_SIZE]; /* at most something like "%-+ #0'.*R*f" */ + char *ptr = fmt; + + tests_default_random (x, 256, MPFR_EMIN_MIN, MPFR_EMAX_MAX, 0); + rnd = RND_RAND (); + + spec = (int) (randlimb () % 5); + jmax = (spec == 3 || spec == 4) ? 6 : 5; /* ' flag only with %f or %g */ + /* advantage small precision */ + prec = (int) (randlimb () % ((randlimb () % 2) ? 10 : prec_max_printf)); + if (spec == 3 + && (mpfr_get_exp (x) > prec_max_printf + || mpfr_get_exp (x) < -prec_max_printf)) + /* change style 'f' to style 'e' when number x is large */ + --spec; + + *ptr++ = '%'; + for (j = 0; j < jmax; j++) + { + if (randlimb () % 3 == 0) + *ptr++ = flag[j]; + } + *ptr++ = '.'; + *ptr++ = '*'; + *ptr++ = 'R'; + *ptr++ = '*'; + *ptr++ = specifier[spec]; + *ptr = '\0'; + MPFR_ASSERTD (ptr - fmt < FMT_SIZE); + + mpfr_fprintf (fout, "mpfr_fprintf(fout, \"%s\", %d, %s, %Re)\n", + fmt, prec, mpfr_print_rnd_mode (rnd), x); + ret = mpfr_fprintf (fout, fmt, prec, rnd, x); + if (ret == -1) + { + if (spec == 3 + && (MPFR_GET_EXP (x) > INT_MAX || MPFR_GET_EXP (x) < -INT_MAX)) + /* normal failure: x is too large to be output with full precision */ + { + mpfr_fprintf (fout, "too large !"); + } + else + { + mpfr_printf ("Error in mpfr_fprintf(fout, \"%s\", %d, %s, %Re)\n", + fmt, prec, mpfr_print_rnd_mode (rnd), x); + exit (1); + } + } + mpfr_fprintf (fout, "\n"); + } + + mpfr_set_emin (old_emin); + mpfr_set_emax (old_emax); + + mpfr_clear (x); +} + +static void +bug_20090316 (FILE *fout) +{ + mpfr_t x; + + mpfr_init2 (x, 53); + + /* bug 20090316: fixed in r6112 */ + mpfr_set_ui_2exp (x, 0x60fa2916, -30, MPFR_RNDN); + check (fout, "%-#.4095RDg\n", x); + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + FILE *fout; + int N; + + tests_start_mpfr (); + + /* with no argument: prints to /dev/null, + tfprintf N: prints N tests to stdout */ + if (argc == 1) + { + N = 1000; + fout = fopen ("/dev/null", "w"); + /* If we failed to open this device, try with a dummy file */ + if (fout == NULL) + { + fout = fopen ("mpfrtest.txt", "w"); + + if (fout == NULL) + { + printf ("Can't open /dev/null or a temporary file\n"); + exit (1); + } + } + } + else + { + fout = stdout; + N = atoi (argv[1]); + } + + check_special (fout); + check_mixed (fout); + check_random (fout, N); + + bug_20090316 (fout); + + fclose (fout); + tests_end_mpfr (); + return 0; +} + +#else /* MPFR_VERSION */ + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif /* MPFR_VERSION */ + +#else /* HAVE_STDARG */ + +int +main (void) +{ + /* We have nothing to test. */ + return 77; +} + +#endif /* HAVE_STDARG */ diff --git a/mpfr/tests/tfrac.c b/mpfr/tests/tfrac.c new file mode 100644 index 0000000000..35f376b72a --- /dev/null +++ b/mpfr/tests/tfrac.c @@ -0,0 +1,301 @@ +/* Test file for mpfr_frac. + +Copyright 2002-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define PIP 70 +#define PFP 70 +#define PMAX (PIP+2*PFP) + +static void +check0 (mpfr_ptr ip, mpfr_ptr fp, mpfr_prec_t prec, mpfr_rnd_t rnd) +{ + mpfr_t sum, tmp, dst, fp2; + int inex1, inex2; + + mpfr_init2 (sum, PMAX); + mpfr_init2 (tmp, PMAX); + mpfr_init2 (dst, prec); + mpfr_init2 (fp2, prec); + + if (MPFR_SIGN (ip) != MPFR_SIGN (fp)) + { + printf ("Internal error (1)\n"); + exit (1); + } + if (mpfr_add (sum, ip, fp, MPFR_RNDZ)) + { + printf ("Wrong inexact flag in mpfr_add\n"); + exit (1); + } + if (MPFR_SIGN (sum) != MPFR_SIGN (fp)) + { + printf ("Internal error (2)\n"); + exit (1); + } + + inex1 = mpfr_frac (dst, sum, rnd); + inex2 = mpfr_set (fp2, fp, rnd); + if (inex1 != inex2) + { + printf ("Wrong inexact flag in mpfr_frac for\n"); + mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN); + printf ("\nGot %d instead of %d\n", inex1, inex2); + exit (1); + } + if (!mpfr_number_p (dst) || + MPFR_SIGN (dst) != MPFR_SIGN (fp2) || + mpfr_cmp (dst, fp2)) + { + printf ("Error in mpfr_frac (y, x, %s) with\nx = ", + mpfr_print_rnd_mode (rnd)); + mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, dst, MPFR_RNDN); + printf ("\ninstead of "); + mpfr_out_str (stdout, 2, 0, fp2, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + if (prec == PMAX) + { + inex1 = mpfr_frac (sum, sum, rnd); + if (inex1) + { + printf ("Wrong inexact flag in mpfr_frac\n"); + exit (1); + } + if (!mpfr_number_p (sum) || + MPFR_SIGN (sum) != MPFR_SIGN (fp) || + mpfr_cmp (sum, fp)) + { + printf ("Error in mpfr_frac (x, x, %s) with\nx = ", + mpfr_print_rnd_mode (rnd)); + mpfr_add (tmp, ip, fp, MPFR_RNDZ); + mpfr_out_str (stdout, 2, 0, tmp, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN); + printf ("\ninstead of "); + mpfr_out_str (stdout, 2, 0, fp, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + + mpfr_clear (fp2); + mpfr_clear (dst); + mpfr_clear (tmp); + mpfr_clear (sum); +} + +static void +check1 (mpfr_ptr ip, mpfr_ptr fp) +{ + int rnd; + + for (rnd = 0; rnd < MPFR_RND_MAX ; rnd++) + { + check0 (ip, fp, PMAX, (mpfr_rnd_t) rnd); + check0 (ip, fp, 70, (mpfr_rnd_t) rnd); + mpfr_neg (fp, fp, MPFR_RNDN); + mpfr_neg (ip, ip, MPFR_RNDN); + check0 (ip, fp, PMAX, (mpfr_rnd_t) rnd); + check0 (ip, fp, 70, (mpfr_rnd_t) rnd); + mpfr_neg (fp, fp, MPFR_RNDN); + mpfr_neg (ip, ip, MPFR_RNDN); + } +} + +static void +special (void) +{ + mpfr_t z, t; + + mpfr_init (z); + mpfr_init (t); + + mpfr_set_nan (z); + mpfr_frac (t, z, MPFR_RNDN); + if (!mpfr_nan_p (t)) + { + printf ("Error for frac(NaN)\n"); + exit (1); + } + + mpfr_set_prec (z, 6); + mpfr_set_prec (t, 3); + + mpfr_set_str_binary (z, "0.101101E3"); + mpfr_frac (t, z, MPFR_RNDN); + mpfr_set_str_binary (z, "0.101"); + if (mpfr_cmp (t, z)) + { + printf ("Error in frac(0.101101E3)\n"); + exit (1); + } + + mpfr_set_prec (z, 34); + mpfr_set_prec (t, 26); + mpfr_set_str_binary (z, "0.101101010000010011110011001101E9"); + mpfr_frac (t, z, MPFR_RNDN); + mpfr_set_str_binary (z, "0.000010011110011001101"); + if (mpfr_cmp (t, z)) + { + printf ("Error in frac(0.101101010000010011110011001101E9)\n"); + exit (1); + } + + mpfr_clear (z); + mpfr_clear (t); +} + +static void +bug20090918 (void) +{ + mpfr_t x, y, z; + mp_limb_t y0; + int inexy, inexz; + int r, i; + const char *s[] = { "61680.352935791015625", "61680.999999" }; + mpfr_exp_t emin; + + emin = mpfr_get_emin (); + mpfr_init2 (x, 32); + mpfr_init2 (y, 13); + + for (i = 0; i <= 9; i++) + { + mpfr_set_str (x, s[i & 1], 10, MPFR_RNDZ); + + RND_LOOP(r) + { + set_emin ((i >> 1) - 3); + inexy = mpfr_frac (y, x, (mpfr_rnd_t) r); + set_emin (emin); + y0 = MPFR_MANT(y)[0]; + while (y0 != 0 && (y0 >> 1) << 1 == y0) + y0 >>= 1; + if (y0 > 0x2000) + { + printf ("Error in bug20090918 (significand has more than" + " 13 bits), i = %d, %s.\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + mpfr_init2 (z, 32); + inexz = mpfr_frac (z, x, MPFR_RNDN); + MPFR_ASSERTN (inexz == 0); /* exact */ + inexz = mpfr_prec_round (z, 13, (mpfr_rnd_t) r); + set_emin ((i >> 1) - 3); + inexz = mpfr_check_range (z, inexz, (mpfr_rnd_t) r); + set_emin (emin); + if (mpfr_cmp0 (y, z) != 0) + { + printf ("Error in bug20090918, i = %d, %s.\n", i, + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + printf ("Expected "); + mpfr_dump (z); + printf ("Got "); + mpfr_dump (y); + exit (1); + } + if (! SAME_SIGN (inexy, inexz)) + { + printf ("Incorrect ternary value in bug20090918, i = %d, %s.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + printf ("Expected %d, got %d.\n", inexz, inexy); + exit (1); + } + mpfr_clear (z); + } + } + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_frac +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t ip, fp; + int ni, nf1, nf2; + + tests_start_mpfr (); + + special (); + + mpfr_init2 (ip, PIP); + mpfr_init2 (fp, PFP); + + for (ni = -1; ni < PIP; ni++) + { + if (ni <= 0) + { /* ni + 1 */ + mpfr_set_si (ip, ni, MPFR_RNDN); + mpfr_add_ui (ip, ip, 1, MPFR_RNDN); + } + else + { /* 2^ni + 1 */ + mpfr_set_ui (ip, 1, MPFR_RNDN); + mpfr_mul_2ui (ip, ip, ni, MPFR_RNDN); + mpfr_add_ui (ip, ip, 1, MPFR_RNDN); + } + + mpfr_set_ui (fp, 0, MPFR_RNDN); + check1 (ip, fp); + + for (nf1 = 1; nf1 < PFP; nf1++) + { + mpfr_set_ui (fp, 1, MPFR_RNDN); + mpfr_div_2ui (fp, fp, nf1, MPFR_RNDN); + check1 (ip, fp); + nf2 = 1 + (randlimb () % (PFP - 1)); + mpfr_set_ui (fp, 1, MPFR_RNDN); + mpfr_div_2ui (fp, fp, nf2, MPFR_RNDN); + mpfr_add_ui (fp, fp, 1, MPFR_RNDN); + mpfr_div_2ui (fp, fp, nf1, MPFR_RNDN); + check1 (ip, fp); + } + } + + mpfr_set_ui (ip, 1, MPFR_RNDN); + mpfr_div_ui (ip, ip, 0, MPFR_RNDN); + mpfr_set_ui (fp, 0, MPFR_RNDN); + check1 (ip, fp); /* test infinities */ + + mpfr_clear (ip); + mpfr_clear (fp); + + bug20090918 (); + + test_generic (2, 1000, 10); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tfrexp.c b/mpfr/tests/tfrexp.c new file mode 100644 index 0000000000..063be74a13 --- /dev/null +++ b/mpfr/tests/tfrexp.c @@ -0,0 +1,244 @@ +/* Test file for mpfr_frexp. + +Copyright 2011-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> /* for exit */ +#include "mpfr-test.h" + +static void +check_special (void) +{ + mpfr_t x, y; + int inex; + mpfr_exp_t exp; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + mpfr_set_nan (x); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + if (mpfr_nan_p (y) == 0 || inex != 0) + { + printf ("Error for mpfr_frexp(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + if (mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0 || inex != 0) + { + printf ("Error for mpfr_frexp(+Inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + if (mpfr_inf_p (y) == 0 || mpfr_sgn (y) >= 0 || inex != 0) + { + printf ("Error for mpfr_frexp(-Inf)\n"); + exit (1); + } + + mpfr_set_zero (x, 1); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + if (mpfr_zero_p (y) == 0 || mpfr_signbit (y) != 0 || inex != 0 || exp != 0) + { + printf ("Error for mpfr_frexp(+0)\n"); + exit (1); + } + + mpfr_set_zero (x, -1); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + if (mpfr_zero_p (y) == 0 || mpfr_signbit (y) == 0 || inex != 0 || exp != 0) + { + printf ("Error for mpfr_frexp(-0)\n"); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + /* 17 = 17/32*2^5 */ + if (mpfr_cmp_ui_2exp (y, 17, -5) != 0 || inex != 0 || exp != 5) + { + printf ("Error for mpfr_frexp(17)\n"); + exit (1); + } + + mpfr_set_si (x, -17, MPFR_RNDN); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + if (mpfr_cmp_si_2exp (y, -17, -5) != 0 || inex != 0 || exp != 5) + { + printf ("Error for mpfr_frexp(-17)\n"); + exit (1); + } + + /* now reduce the precision of y */ + mpfr_set_prec (y, 4); + mpfr_set_ui (x, 17, MPFR_RNDN); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDN); + /* 17 -> 16/32*2^5 */ + if (mpfr_cmp_ui_2exp (y, 16, -5) != 0 || inex >= 0 || exp != 5) + { + printf ("Error for mpfr_frexp(17) with prec=4, RNDN\n"); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDZ); + if (mpfr_cmp_ui_2exp (y, 16, -5) != 0 || inex >= 0 || exp != 5) + { + printf ("Error for mpfr_frexp(17) with prec=4, RNDZ\n"); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDD); + if (mpfr_cmp_ui_2exp (y, 16, -5) != 0 || inex >= 0 || exp != 5) + { + printf ("Error for mpfr_frexp(17) with prec=4, RNDD\n"); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + inex = mpfr_frexp (&exp, y, x, MPFR_RNDU); + if (mpfr_cmp_ui_2exp (y, 18, -5) != 0 || inex <= 0 || exp != 5) + { + printf ("Error for mpfr_frexp(17) with prec=4, RNDU\n"); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); +} + +static void check1 (void) +{ + mpfr_exp_t emin, emax, e; + mpfr_t x, y1, y2; + int r, neg, red; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + mpfr_init2 (x, 7); + mpfr_inits2 (4, y1, y2, (mpfr_ptr) 0); + + mpfr_set_ui_2exp (x, 1, -2, MPFR_RNDN); + while (mpfr_regular_p (x)) + { + /* Test the exponents up to 3 and with the maximum exponent + (to check potential intermediate overflow). */ + if (MPFR_GET_EXP (x) == 4) + mpfr_set_exp (x, MPFR_EMAX_MAX); + e = MPFR_GET_EXP (x); + for (neg = 0; neg < 2; neg++) + { + RND_LOOP (r) + { + int inex1, inex2; + mpfr_exp_t e1, e2; + unsigned int flags1, flags2; + + for (red = 0; red < 2; red++) + { + if (red) + { + /* e1: exponent of the rounded value of x. */ + MPFR_ASSERTN (e1 == e || e1 == e + 1); + set_emin (e); + set_emax (e); + mpfr_clear_flags (); + inex1 = e1 < 0 ? + mpfr_mul_2ui (y1, x, -e1, (mpfr_rnd_t) r) : + mpfr_div_2ui (y1, x, e1, (mpfr_rnd_t) r); + flags1 = __gmpfr_flags; + } + else + { + inex1 = mpfr_set (y1, x, (mpfr_rnd_t) r); + e1 = MPFR_IS_INF (y1) ? e + 1 : MPFR_GET_EXP (y1); + flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0; + } + mpfr_clear_flags (); + inex2 = mpfr_frexp (&e2, y2, x, (mpfr_rnd_t) r); + flags2 = __gmpfr_flags; + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + if ((!red || e == 0) && + (! mpfr_regular_p (y2) || MPFR_GET_EXP (y2) != 0)) + { + printf ("Error in check1 for %s, red = %d, x = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), red); + mpfr_dump (x); + printf ("Expected 1/2 <= |y| < 1, got y = "); + mpfr_dump (y2); + exit (1); + } + if (!red) + { + if (e2 > 0) + mpfr_mul_2ui (y2, y2, e2, MPFR_RNDN); + else if (e2 < 0) + mpfr_div_2ui (y2, y2, -e2, MPFR_RNDN); + } + if (! (SAME_SIGN (inex1, inex2) && + mpfr_equal_p (y1, y2) && + flags1 == flags2)) + { + printf ("Error in check1 for %s, red = %d, x = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), red); + mpfr_dump (x); + printf ("Expected y1 = "); + mpfr_dump (y1); + printf ("Got y2 = "); + mpfr_dump (y2); + printf ("Expected inex ~= %d, got %d\n", inex1, inex2); + printf ("Expected flags:"); + flags_out (flags1); + printf ("Got flags: "); + flags_out (flags2); + exit (1); + } + } + } + mpfr_neg (x, x, MPFR_RNDN); + } + mpfr_nextabove (x); + } + + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); + set_emin (emin); + set_emax (emax); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_special (); + check1 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tgamma.c b/mpfr/tests/tgamma.c new file mode 100644 index 0000000000..3f4cdba77b --- /dev/null +++ b/mpfr/tests/tgamma.c @@ -0,0 +1,1081 @@ +/* mpfr_tgamma -- test file for gamma function + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* Note: there could be an incorrect test about suspicious overflow + (MPFR_SUSPICIOUS_OVERFLOW) for x = 2^(-emax) = 0.5 * 2^(emin+1) in + RNDZ or RNDD, but this case is never tested in the generic tests. */ +#define TEST_FUNCTION mpfr_gamma +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for gamma(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for gamma(-Inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for gamma(+Inf)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for gamma(+0)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error for gamma(-0)\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error for gamma(1)\n"); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for gamma(-1)\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + +#define CHECK_X1 "1.0762904832837976166" +#define CHECK_Y1 "0.96134843256452096050" + + mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN); + if (mpfr_cmp (y, x)) + { + printf ("mpfr_lngamma("CHECK_X1") is wrong:\n" + "expected "); + mpfr_print_binary (x); putchar ('\n'); + printf ("got "); + mpfr_print_binary (y); putchar ('\n'); + exit (1); + } + +#define CHECK_X2 "9.23709516716202383435e-01" +#define CHECK_Y2 "1.0502315560291053398" + mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN); + if (mpfr_cmp (y, x)) + { + printf ("mpfr_lngamma("CHECK_X2") is wrong:\n" + "expected "); + mpfr_print_binary (x); putchar ('\n'); + printf ("got "); + mpfr_print_binary (y); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 8); + mpfr_set_prec (y, 175); + mpfr_set_ui (x, 33, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDU); + mpfr_set_prec (x, 175); + mpfr_set_str_binary (x, "0.110010101011010101101000010101010111000110011101001000101011000001100010111001101001011E118"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_gamma (1)\n"); + exit (1); + } + + mpfr_set_prec (x, 21); + mpfr_set_prec (y, 8); + mpfr_set_ui (y, 120, MPFR_RNDN); + mpfr_gamma (x, y, MPFR_RNDZ); + mpfr_set_prec (y, 21); + mpfr_set_str_binary (y, "0.101111101110100110110E654"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_gamma (120)\n"); + printf ("Expected "); mpfr_print_binary (y); puts (""); + printf ("Got "); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 206); + mpfr_set_str_binary (x, "0.110e10"); + inex = mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 206); + mpfr_set_str_binary (x, "0.110111100001000001101010010001000111000100000100111000010011100011011111001100011110101000111101101100110001001100110100001001111110000101010000100100011100010011101110000001000010001100010000101001111E6250"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_gamma (768)\n"); + exit (1); + } + if (inex <= 0) + { + printf ("Wrong flag for mpfr_gamma (768)\n"); + exit (1); + } + + /* worst case to exercise retry */ + mpfr_set_prec (x, 1000); + mpfr_set_prec (y, 869); + mpfr_const_pi (x, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + + mpfr_set_prec (x, 4); + mpfr_set_prec (y, 4); + mpfr_set_str_binary (x, "-0.1100E-66"); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.1011E67"); + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma(-0.1100E-66)\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_clear_inexflag (); + mpfr_gamma (y, x, MPFR_RNDN); + if (mpfr_inexflag_p ()) + { + printf ("Wrong inexact flag for gamma(2)\n"); + printf ("expected 0, got 1\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +special_overflow (void) +{ + mpfr_t x, y; + mpfr_exp_t emin, emax; + int inex; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + set_emin (-125); + set_emax (128); + + mpfr_init2 (x, 24); + mpfr_init2 (y, 24); + mpfr_set_str_binary (x, "0.101100100000000000110100E7"); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y)) + { + printf ("Overflow error.\n"); + mpfr_dump (y); + exit (1); + } + + /* problem mentioned by Kenneth Wilder, 18 Aug 2005 */ + mpfr_set_prec (x, 29); + mpfr_set_prec (y, 29); + mpfr_set_str (x, "-200000000.5", 10, MPFR_RNDN); /* exact */ + mpfr_gamma (y, x, MPFR_RNDN); + if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) + { + printf ("Error for gamma(-200000000.5)\n"); + printf ("expected -0"); + printf ("got "); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str (x, "-200000000.1", 10, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) + { + printf ("Error for gamma(-200000000.1), prec=53\n"); + printf ("expected -0"); + printf ("got "); + mpfr_dump (y); + exit (1); + } + + /* another problem mentioned by Kenneth Wilder, 29 Aug 2005 */ + mpfr_set_prec (x, 333); + mpfr_set_prec (y, 14); + mpfr_set_str (x, "-2.0000000000000000000000005", 10, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 14); + mpfr_set_str_binary (x, "-11010011110001E66"); + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma(-2.0000000000000000000000005)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + /* another tests from Kenneth Wilder, 31 Aug 2005 */ + set_emax (200); + set_emin (-200); + mpfr_set_prec (x, 38); + mpfr_set_prec (y, 54); + mpfr_set_str_binary (x, "0.11101111011100111101001001010110101001E-166"); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 54); + mpfr_set_str_binary (x, "0.100010001101100001110110001010111111010000100101011E167"); + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma (test 1)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + set_emax (1000); + set_emin (-2000); + mpfr_set_prec (x, 38); + mpfr_set_prec (y, 71); + mpfr_set_str_binary (x, "10101011011100001111111000010111110010E-1034"); + /* 184083777010*2^(-1034) */ + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 71); + mpfr_set_str_binary (x, "10111111001000011110010001000000000000110011110000000011101011111111100E926"); + /* 1762885132679550982140*2^926 */ + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma (test 2)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 38); + mpfr_set_prec (y, 88); + mpfr_set_str_binary (x, "10111100111001010000100001100100100101E-104"); + /* 202824096037*2^(-104) */ + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 88); + mpfr_set_str_binary (x, "1010110101111000111010111100010110101010100110111000001011000111000011101100001101110010E-21"); + /* 209715199999500283894743922*2^(-21) */ + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma (test 3)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 171); + mpfr_set_prec (y, 38); + mpfr_set_str (x, "-2993155353253689176481146537402947624254601559176535", 10, + MPFR_RNDN); + mpfr_div_2exp (x, x, 170, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 38); + mpfr_set_str (x, "201948391737", 10, MPFR_RNDN); + mpfr_mul_2exp (x, x, 92, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma (test 5)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + set_emin (-500000); + mpfr_set_prec (x, 337); + mpfr_set_prec (y, 38); + mpfr_set_str (x, "-30000.000000000000000000000000000000000000000000001", 10, + MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 38); + mpfr_set_str (x, "-3.623795987425E-121243", 10, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for gamma (test 7)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + /* was producing infinite loop */ + set_emin (emin); + mpfr_set_prec (x, 71); + mpfr_set_prec (y, 71); + mpfr_set_str (x, "-200000000.1", 10, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0)) + { + printf ("Error for gamma (test 8)\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + set_emax (1073741823); + mpfr_set_prec (x, 29); + mpfr_set_prec (y, 29); + mpfr_set_str (x, "423786866", 10, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for gamma(423786866)\n"); + exit (1); + } + + /* check exact result */ + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 3, MPFR_RNDN); + inex = mpfr_gamma (x, x, MPFR_RNDN); + if (inex != 0 || mpfr_cmp_ui (x, 2) != 0) + { + printf ("Error for gamma(3)\n"); + exit (1); + } + + mpfr_set_emax (1024); + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "101010110100110011111010000110001000111100000110101E-43"); + mpfr_gamma (x, x, MPFR_RNDU); + mpfr_set_str_binary (y, "110000011110001000111110110101011110000100001111111E971"); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for gamma(4)\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + + set_emin (emin); + set_emax (emax); + + /* bug found by Kevin Rauch, 26 Oct 2007 */ + mpfr_set_str (x, "1e19", 10, MPFR_RNDN); + inex = mpfr_gamma (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && inex > 0); + + mpfr_clear (y); + mpfr_clear (x); +} + +/* test gamma on some integral values (from Christopher Creutzig). */ +static void +gamma_integer (void) +{ + mpz_t n; + mpfr_t x, y; + unsigned int i; + + mpz_init (n); + mpfr_init2 (x, 149); + mpfr_init2 (y, 149); + + for (i = 0; i < 100; i++) + { + mpz_fac_ui (n, i); + mpfr_set_ui (x, i+1, MPFR_RNDN); + mpfr_gamma (y, x, MPFR_RNDN); + mpfr_set_z (x, n, MPFR_RNDN); + if (!mpfr_equal_p (x, y)) + { + printf ("Error for gamma(%u)\n", i+1); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + } + mpfr_clear (y); + mpfr_clear (x); + mpz_clear (n); +} + +/* bug found by Kevin Rauch */ +static void +test20071231 (void) +{ + mpfr_t x; + int inex; + mpfr_exp_t emin; + + emin = mpfr_get_emin (); + mpfr_set_emin (-1000000); + + mpfr_init2 (x, 21); + mpfr_set_str (x, "-1000001.5", 10, MPFR_RNDN); + inex = mpfr_gamma (x, x, MPFR_RNDN); + MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_POS(x) && inex < 0); + mpfr_clear (x); + + mpfr_set_emin (emin); + + mpfr_init2 (x, 53); + mpfr_set_str (x, "-1000000001.5", 10, MPFR_RNDN); + inex = mpfr_gamma (x, x, MPFR_RNDN); + MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_POS(x) && inex < 0); + mpfr_clear (x); +} + +/* bug found by Stathis in mpfr_gamma, only occurs on 32-bit machines; + the second test is for 64-bit machines. This bug reappeared due to + r8159. */ +static void +test20100709 (void) +{ + mpfr_t x, y, z; + int sign; + int inex; + mpfr_exp_t emin; + + mpfr_init2 (x, 100); + mpfr_init2 (y, 32); + mpfr_init2 (z, 32); + mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_nextabove (y); + mpfr_log (y, y, MPFR_RNDD); + mpfr_const_log2 (z, MPFR_RNDU); + mpfr_sub (y, y, z, MPFR_RNDD); /* log(MIN/2) = log(MIN) - log(2) */ + mpfr_lgamma (z, &sign, x, MPFR_RNDU); + MPFR_ASSERTN (sign == -1); + MPFR_ASSERTN (mpfr_less_p (z, y)); /* thus underflow */ + inex = mpfr_gamma (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0); + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + /* Similar test for 64-bit machines (also valid with a 32-bit exponent, + but will not trigger the bug). */ + emin = mpfr_get_emin (); + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_init2 (x, 100); + mpfr_init2 (y, 32); + mpfr_init2 (z, 32); + mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_nextabove (y); + mpfr_log (y, y, MPFR_RNDD); + mpfr_const_log2 (z, MPFR_RNDU); + mpfr_sub (y, y, z, MPFR_RNDD); /* log(MIN/2) = log(MIN) - log(2) */ + mpfr_lgamma (z, &sign, x, MPFR_RNDU); + MPFR_ASSERTN (sign == -1); + MPFR_ASSERTN (mpfr_less_p (z, y)); /* thus underflow */ + inex = mpfr_gamma (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0); + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_set_emin (emin); +} + +/* bug found by Giridhar Tammana */ +static void +test20120426 (void) +{ + mpfr_t xa, xb; + int i; + mpfr_exp_t emin; + + mpfr_init2 (xa, 53); + mpfr_init2 (xb, 53); + mpfr_set_d (xb, -168.5, MPFR_RNDN); + emin = mpfr_get_emin (); + mpfr_set_emin (-1073); + i = mpfr_gamma (xa, xb, MPFR_RNDN); + i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */ + mpfr_set_str (xb, "-9.5737343987585366746184749943e-304", 10, MPFR_RNDN); + if (!((i > 0) && (mpfr_cmp (xa, xb) == 0))) + { + printf ("Error in test20120426, i=%d\n", i); + printf ("expected "); + mpfr_print_binary (xb); putchar ('\n'); + printf ("got "); + mpfr_print_binary (xa); putchar ('\n'); + exit (1); + } + mpfr_set_emin (emin); + mpfr_clear (xa); + mpfr_clear (xb); +} + +static void +exprange (void) +{ + mpfr_exp_t emin, emax; + mpfr_t x, y, z; + int inex1, inex2; + unsigned int flags1, flags2; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init2 (x, 16); + mpfr_inits2 (8, y, z, (mpfr_ptr) 0); + + mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN); + mpfr_clear_flags (); + inex1 = mpfr_gamma (y, x, MPFR_RNDN); + flags1 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emin (0); + mpfr_clear_flags (); + inex2 = mpfr_gamma (z, x, MPFR_RNDN); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emin (emin); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test1)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + + mpfr_set_ui_2exp (x, 32769, -60, MPFR_RNDN); + mpfr_clear_flags (); + inex1 = mpfr_gamma (y, x, MPFR_RNDD); + flags1 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emax (45); + mpfr_clear_flags (); + inex2 = mpfr_gamma (z, x, MPFR_RNDD); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emax (emax); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test2)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + + mpfr_set_emax (44); + mpfr_clear_flags (); + inex1 = mpfr_check_range (y, inex1, MPFR_RNDD); + flags1 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_clear_flags (); + inex2 = mpfr_gamma (z, x, MPFR_RNDD); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emax (emax); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test3)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + + mpfr_set_ui_2exp (x, 1, -60, MPFR_RNDN); + mpfr_clear_flags (); + inex1 = mpfr_gamma (y, x, MPFR_RNDD); + flags1 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emax (60); + mpfr_clear_flags (); + inex2 = mpfr_gamma (z, x, MPFR_RNDD); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + mpfr_set_emax (emax); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test4)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + + MPFR_ASSERTN (MPFR_EMIN_MIN == - MPFR_EMAX_MAX); + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_set_emax (MPFR_EMAX_MAX); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_nextabove (x); /* x = 2^(emin - 1) */ + mpfr_set_inf (y, 1); + inex1 = 1; + flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW; + mpfr_clear_flags (); + /* MPFR_RNDU: overflow, infinity since 1/x = 2^(emax + 1) */ + inex2 = mpfr_gamma (z, x, MPFR_RNDU); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test5)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + mpfr_clear_flags (); + /* MPFR_RNDN: overflow, infinity since 1/x = 2^(emax + 1) */ + inex2 = mpfr_gamma (z, x, MPFR_RNDN); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test6)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + mpfr_nextbelow (y); + inex1 = -1; + mpfr_clear_flags (); + /* MPFR_RNDD: overflow, maxnum since 1/x = 2^(emax + 1) */ + inex2 = mpfr_gamma (z, x, MPFR_RNDD); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test7)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + mpfr_mul_2ui (x, x, 1, MPFR_RNDN); /* x = 2^emin */ + mpfr_set_inf (y, 1); + inex1 = 1; + flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW; + mpfr_clear_flags (); + /* MPFR_RNDU: overflow, infinity since 1/x = 2^emax */ + inex2 = mpfr_gamma (z, x, MPFR_RNDU); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test8)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + mpfr_clear_flags (); + /* MPFR_RNDN: overflow, infinity since 1/x = 2^emax */ + inex2 = mpfr_gamma (z, x, MPFR_RNDN); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test9)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + mpfr_nextbelow (y); + inex1 = -1; + flags1 = MPFR_FLAGS_INEXACT; + mpfr_clear_flags (); + /* MPFR_RNDD: no overflow, maxnum since 1/x = 2^emax and euler > 0 */ + inex2 = mpfr_gamma (z, x, MPFR_RNDD); + flags2 = __gmpfr_flags; + MPFR_ASSERTN (mpfr_inexflag_p ()); + if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z)) + { + printf ("Error in exprange (test10)\n"); + printf ("x = "); + mpfr_dump (x); + printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + mpfr_dump (y); + printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + mpfr_dump (z); + exit (1); + } + mpfr_set_emin (emin); + mpfr_set_emax (emax); + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static int +tiny_aux (int stop, mpfr_exp_t e) +{ + mpfr_t x, y, z; + int r, s, spm, inex, err = 0; + int expected_dir[2][5] = { { 1, -1, 1, -1, 1 }, { 1, 1, 1, -1, -1 } }; + mpfr_exp_t saved_emax; + + saved_emax = mpfr_get_emax (); + + mpfr_init2 (x, 32); + mpfr_inits2 (8, y, z, (mpfr_ptr) 0); + + mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN); + spm = 1; + for (s = 0; s < 2; s++) + { + RND_LOOP(r) + { + mpfr_rnd_t rr = (mpfr_rnd_t) r; + mpfr_exp_t exponent, emax; + + /* Exponent of the rounded value in unbounded exponent range. */ + exponent = expected_dir[s][r] < 0 && s == 0 ? - e : 1 - e; + + for (emax = exponent - 1; emax <= exponent; emax++) + { + unsigned int flags, expected_flags = MPFR_FLAGS_INEXACT; + int overflow, expected_inex = expected_dir[s][r]; + + if (emax > MPFR_EMAX_MAX) + break; + mpfr_set_emax (emax); + + mpfr_clear_flags (); + inex = mpfr_gamma (y, x, rr); + flags = __gmpfr_flags; + mpfr_clear_flags (); + mpfr_set_si_2exp (z, spm, - e, MPFR_RNDU); + overflow = mpfr_overflow_p (); + /* z is 1/x - euler rounded toward +inf */ + + if (overflow && rr == MPFR_RNDN && s == 1) + expected_inex = -1; + + if (expected_inex < 0) + mpfr_nextbelow (z); /* 1/x - euler rounded toward -inf */ + + if (exponent > emax) + expected_flags |= MPFR_FLAGS_OVERFLOW; + + if (!(mpfr_equal_p (y, z) && flags == expected_flags + && SAME_SIGN (inex, expected_inex))) + { + printf ("Error in tiny for s = %d, r = %s, emax = %" + MPFR_EXP_FSPEC "d%s\n on ", + s, mpfr_print_rnd_mode (rr), emax, + exponent > emax ? " (overflow)" : ""); + mpfr_dump (x); + printf (" expected inex = %2d, ", expected_inex); + mpfr_dump (z); + printf (" got inex = %2d, ", SIGN (inex)); + mpfr_dump (y); + printf (" expected flags = %u, got %u\n", + expected_flags, flags); + if (stop) + exit (1); + err = 1; + } + } + } + mpfr_neg (x, x, MPFR_RNDN); + spm = - spm; + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); + mpfr_set_emax (saved_emax); + return err; +} + +static void +tiny (int stop) +{ + mpfr_exp_t emin; + int err = 0; + + emin = mpfr_get_emin (); + + /* Note: in r7499, exponent -17 will select the generic code (in + tiny_aux, x has precision 32), while the other exponent values + will select special code for tiny values. */ + err |= tiny_aux (stop, -17); + err |= tiny_aux (stop, -999); + err |= tiny_aux (stop, mpfr_get_emin ()); + + if (emin != MPFR_EMIN_MIN) + { + mpfr_set_emin (MPFR_EMIN_MIN); + err |= tiny_aux (stop, MPFR_EMIN_MIN); + mpfr_set_emin (emin); + } + + if (err) + exit (1); +} + +/* Test mpfr_gamma in precision p1 by comparing it with exp(lgamma(x)) + computing with a working precision p2. Assume that x is not an + integer <= 2. */ +static void +exp_lgamma (mpfr_t x, mpfr_prec_t p1, mpfr_prec_t p2) +{ + mpfr_t yd, yu, zd, zu; + int inexd, inexu, sign; + int underflow = -1, overflow = -1; /* -1: we don't know */ + int got_underflow, got_overflow; + + if (mpfr_integer_p (x) && mpfr_cmp_si (x, 2) <= 0) + { + printf ("Warning! x is an integer <= 2 in exp_lgamma: "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + return; + } + mpfr_inits2 (p2, yd, yu, (mpfr_ptr) 0); + inexd = mpfr_lgamma (yd, &sign, x, MPFR_RNDD); + mpfr_set (yu, yd, MPFR_RNDN); /* exact */ + if (inexd) + mpfr_nextabove (yu); + mpfr_clear_flags (); + mpfr_exp (yd, yd, MPFR_RNDD); + if (! mpfr_underflow_p ()) + underflow = 0; + if (mpfr_overflow_p ()) + overflow = 1; + mpfr_clear_flags (); + mpfr_exp (yu, yu, MPFR_RNDU); + if (mpfr_underflow_p ()) + underflow = 1; + if (! mpfr_overflow_p ()) + overflow = 0; + if (sign < 0) + { + mpfr_neg (yd, yd, MPFR_RNDN); /* exact */ + mpfr_neg (yu, yu, MPFR_RNDN); /* exact */ + mpfr_swap (yd, yu); + } + /* yd < Gamma(x) < yu (strict inequalities since x != 1 and x != 2) */ + mpfr_inits2 (p1, zd, zu, (mpfr_ptr) 0); + mpfr_clear_flags (); + inexd = mpfr_gamma (zd, x, MPFR_RNDD); /* zd <= Gamma(x) < yu */ + got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p (); + got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p (); + if (! mpfr_less_p (zd, yu) || inexd > 0 || + got_underflow != underflow || + got_overflow != overflow) + { + printf ("Error in exp_lgamma on x = "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + printf ("yu = "); + mpfr_dump (yu); + printf ("zd = "); + mpfr_dump (zd); + printf ("got inexd = %d, expected <= 0\n", inexd); + printf ("got underflow = %d, expected %d\n", got_underflow, underflow); + printf ("got overflow = %d, expected %d\n", got_overflow, overflow); + exit (1); + } + mpfr_clear_flags (); + inexu = mpfr_gamma (zu, x, MPFR_RNDU); /* zu >= Gamma(x) > yd */ + got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p (); + got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p (); + if (! mpfr_greater_p (zu, yd) || inexu < 0 || + got_underflow != underflow || + got_overflow != overflow) + { + printf ("Error in exp_lgamma on x = "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + printf ("yd = "); + mpfr_dump (yd); + printf ("zu = "); + mpfr_dump (zu); + printf ("got inexu = %d, expected >= 0\n", inexu); + printf ("got underflow = %d, expected %d\n", got_underflow, underflow); + printf ("got overflow = %d, expected %d\n", got_overflow, overflow); + exit (1); + } + if (mpfr_equal_p (zd, zu)) + { + if (inexd != 0 || inexu != 0) + { + printf ("Error in exp_lgamma on x = "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + printf ("zd = zu, thus exact, but inexd = %d and inexu = %d\n", + inexd, inexu); + exit (1); + } + MPFR_ASSERTN (got_underflow == 0); + MPFR_ASSERTN (got_overflow == 0); + } + else if (inexd == 0 || inexu == 0) + { + printf ("Error in exp_lgamma on x = "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + printf ("zd != zu, thus inexact, but inexd = %d and inexu = %d\n", + inexd, inexu); + exit (1); + } + mpfr_clears (yd, yu, zd, zu, (mpfr_ptr) 0); +} + +static void +exp_lgamma_tests (void) +{ + mpfr_t x; + mpfr_exp_t emin, emax; + int i; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + mpfr_init2 (x, 96); + for (i = 3; i <= 8; i++) + { + mpfr_set_ui (x, i, MPFR_RNDN); + exp_lgamma (x, 53, 64); + mpfr_nextbelow (x); + exp_lgamma (x, 53, 64); + mpfr_nextabove (x); + mpfr_nextabove (x); + exp_lgamma (x, 53, 64); + } + mpfr_set_str (x, "1.7", 10, MPFR_RNDN); + exp_lgamma (x, 53, 64); + mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN); + exp_lgamma (x, 53, 64); + mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN); + exp_lgamma (x, 53, 64); + /* The following test gives a large positive result < +Inf */ + mpfr_set_str (x, "1.2b13fc45a92dea1@14", 16, MPFR_RNDN); + exp_lgamma (x, 53, 64); + /* Idem for a large negative result > -Inf */ + mpfr_set_str (x, "-1.2b13fc45a92de81@14", 16, MPFR_RNDN); + exp_lgamma (x, 53, 64); + /* The following two tests trigger an endless loop in r8186 + on 64-bit machines (64-bit exponent). The second one (due + to undetected overflow) is a direct consequence of the + first one, due to the call of Gamma(2-x) if x < 1. */ + mpfr_set_str (x, "1.2b13fc45a92dec8@14", 16, MPFR_RNDN); + exp_lgamma (x, 53, 64); + mpfr_set_str (x, "-1.2b13fc45a92dea8@14", 16, MPFR_RNDN); + exp_lgamma (x, 53, 64); + /* Similar tests (overflow threshold) for 32-bit machines. */ + mpfr_set_str (x, "2ab68d8.657542f855111c61", 16, MPFR_RNDN); + exp_lgamma (x, 12, 64); + mpfr_set_str (x, "-2ab68d6.657542f855111c61", 16, MPFR_RNDN); + exp_lgamma (x, 12, 64); + /* The following test is an overflow on 32-bit and 64-bit machines. + Revision r8189 fails on 64-bit machines as the flag is unset. */ + mpfr_set_str (x, "1.2b13fc45a92ded8@14", 16, MPFR_RNDN); + exp_lgamma (x, 53, 64); + /* On the following tests, with r8196, one gets an underflow on + 32-bit machines, while a normal result is expected (see FIXME + in gamma.c:382). */ + mpfr_set_str (x, "-2ab68d6.657542f855111c6104", 16, MPFR_RNDN); + exp_lgamma (x, 12, 64); /* failure on 32-bit machines */ + mpfr_set_str (x, "-12b13fc45a92deb.1c6c5bc964", 16, MPFR_RNDN); + exp_lgamma (x, 12, 64); /* failure on 64-bit machines */ + mpfr_clear (x); + + set_emin (emin); + set_emax (emax); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + special_overflow (); + exprange (); + tiny (argc == 1); + test_generic (2, 100, 2); + gamma_integer (); + test20071231 (); + test20100709 (); + test20120426 (); + exp_lgamma_tests (); + + data_check ("data/gamma", mpfr_gamma, "mpfr_gamma"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tgeneric.c b/mpfr/tests/tgeneric.c new file mode 100644 index 0000000000..6b1ef2f6e2 --- /dev/null +++ b/mpfr/tests/tgeneric.c @@ -0,0 +1,663 @@ +/* Generic test file for functions with one or two arguments (the second being + either mpfr_t or double or unsigned long). + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Define TWO_ARGS for two-argument functions like mpfr_pow. + Define DOUBLE_ARG1 or DOUBLE_ARG2 for function with a double operand in + first or second place like sub_d or d_sub. + Define ULONG_ARG1 or ULONG_ARG2 for function with an unsigned long + operand in first or second place like sub_ui or ui_sub. */ + +#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) || \ + defined(ULONG_ARG1) || defined(ULONG_ARG2) +#define TWO_ARGS_ALL +#endif + +#ifndef TEST_RANDOM_POS +/* For the random function: one number on two is negative. */ +#define TEST_RANDOM_POS 256 +#endif + +#ifndef TEST_RANDOM_POS2 +/* For the random function: one number on two is negative. */ +#define TEST_RANDOM_POS2 256 +#endif + +#ifndef TEST_RANDOM_EMIN +#define TEST_RANDOM_EMIN -256 +#endif + +#ifndef TEST_RANDOM_EMAX +#define TEST_RANDOM_EMAX 255 +#endif + +#ifndef TEST_RANDOM_ALWAYS_SCALE +#define TEST_RANDOM_ALWAYS_SCALE 0 +#endif + +/* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug, + then define TGENERIC_SO_TEST with an adequate test (possibly 0) to + omit this particular case. */ +#ifndef TGENERIC_SO_TEST +#define TGENERIC_SO_TEST 1 +#endif + +#define STR(F) #F +#define MAKE_STR(S) STR(S) + +/* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions + * with 2 arguments. See <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>. + */ +#define TGENERIC_FAIL(S, X, U) \ + do \ + { \ + printf ("tgeneric: %s\nx = ", (S)); \ + mpfr_dump (X);; \ + if ((void *) (U) != 0) \ + { \ + printf ("u = "); \ + mpfr_dump (U); \ + } \ + printf ("yprec = %u, rnd_mode = %s, inexact = %d\nflags =", \ + (unsigned int) yprec, mpfr_print_rnd_mode (rnd), \ + compare); \ + flags_out (flags); \ + exit (1); \ + } \ + while (0) + +#define TGENERIC_CHECK_AUX(S, EXPR, U) \ + do \ + if (!(EXPR)) \ + TGENERIC_FAIL (S " for " MAKE_STR(TEST_FUNCTION), x, U); \ + while (0) + +#undef TGENERIC_CHECK +#if defined(TWO_ARGS_ALL) +#define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u) +#else +#define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0) +#endif + +#ifdef DEBUG_TGENERIC +#define TGENERIC_IAUX(F,P,X,U) \ + do \ + { \ + printf ("tgeneric: testing function " STR(F) \ + ", %s, target prec = %lu\nx = ", \ + mpfr_print_rnd_mode (rnd), (unsigned long) (P)); \ + mpfr_dump (X); \ + if ((void *) (U) != 0) \ + { \ + printf ("u = "); \ + mpfr_dump (U); \ + } \ + } \ + while (0) +#undef TGENERIC_INFO +#if defined(TWO_ARGS_ALL) +#define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u) +#else +#define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0) +#endif +#endif /* DEBUG_TGENERIC */ + +/* For some functions (for example cos), the argument reduction is too + expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX + to some reasonable value before including tgeneric.c. */ +#ifndef REDUCE_EMAX +#define REDUCE_EMAX mpfr_get_emax () +#endif + +static void +test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax) +{ + mpfr_prec_t prec, xprec, yprec; + mpfr_t x, y, z, t, w; +#if defined(TWO_ARGS_ALL) + mpfr_t u; +#endif +#if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) + double d; +#endif +#if defined(ULONG_ARG1) || defined(ULONG_ARG2) + unsigned long i; +#endif + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + unsigned long ctrt = 0, ctrn = 0; + int test_of = 1, test_uf = 1; + mpfr_exp_t old_emin, old_emax; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0); +#if defined(TWO_ARGS_ALL) + mpfr_init2 (u, MPFR_PREC_MIN); +#endif + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + mpfr_set_prec (y, yprec); + mpfr_set_prec (w, yprec); + + /* Note: in precision p1, we test 4 special cases. */ + for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++) + { + int infinite_input = 0; + unsigned int flags; + mpfr_exp_t oemin, oemax; + + xprec = prec; + if (randlimb () & 1) + { + /* In half cases, modify the precision of the inputs: + If the base precision (for the result) is small, + take a larger input precision in general, else + take a smaller precision. */ + xprec *= (prec < 16 ? 256.0 : 1.0) * + (double) randlimb () / MP_LIMB_T_MAX; + if (xprec < MPFR_PREC_MIN) + xprec = MPFR_PREC_MIN; + } + mpfr_set_prec (x, xprec); +#if defined(TWO_ARGS) + mpfr_set_prec (u, xprec); +#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) + mpfr_set_prec (u, IEEE_DBL_MANT_DIG); +#elif defined(ULONG_ARG1) || defined(ULONG_ARG2) + mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT); +#endif + + if (n > 3 || prec < p1) + { +#if defined(RAND_FUNCTION) + RAND_FUNCTION (x); +#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) + RAND_FUNCTION (u); +#endif +#else /* ! defined(RAND_FUNCTION) */ + tests_default_random (x, TEST_RANDOM_POS, + TEST_RANDOM_EMIN, TEST_RANDOM_EMAX, + TEST_RANDOM_ALWAYS_SCALE); +#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) + tests_default_random (u, TEST_RANDOM_POS2, + TEST_RANDOM_EMIN, TEST_RANDOM_EMAX, + TEST_RANDOM_ALWAYS_SCALE); +#endif +#endif /* ! defined(RAND_FUNCTION) */ + } + else + { + /* Special cases tested in precision p1 if n <= 3. They are + useful really in the extended exponent range. */ +#if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO) + goto next_n; +#endif + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + if (n <= 1) + { + mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin ()); +#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) + mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN); + mpfr_set_exp (u, mpfr_get_emin ()); +#endif + } + else /* 2 <= n <= 3 */ + { + if (getenv ("MPFR_CHECK_MAX") == NULL) + goto next_n; + mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN); + mpfr_setmax (x, REDUCE_EMAX); +#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) + mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN); + mpfr_setmax (u, mpfr_get_emax ()); +#endif + } + } + +#if defined(ULONG_ARG1) || defined(ULONG_ARG2) + i = randlimb (); + inexact = mpfr_set_ui (u, i, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); +#endif + + /* Exponent range for the test. */ + oemin = mpfr_get_emin (); + oemax = mpfr_get_emax (); + + rnd = RND_RAND (); + mpfr_clear_flags (); +#ifdef DEBUG_TGENERIC + TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y)); +#endif +#if defined(TWO_ARGS) + compare = TEST_FUNCTION (y, x, u, rnd); +#elif defined(DOUBLE_ARG1) + d = mpfr_get_d (u, rnd); + compare = TEST_FUNCTION (y, d, x, rnd); + /* d can be infinite due to overflow in mpfr_get_d */ + infinite_input |= DOUBLE_ISINF (d); +#elif defined(DOUBLE_ARG2) + d = mpfr_get_d (u, rnd); + compare = TEST_FUNCTION (y, x, d, rnd); + /* d can be infinite due to overflow in mpfr_get_d */ + infinite_input |= DOUBLE_ISINF (d); +#elif defined(ULONG_ARG1) + compare = TEST_FUNCTION (y, i, x, rnd); +#elif defined(ULONG_ARG2) + compare = TEST_FUNCTION (y, x, i, rnd); +#else + compare = TEST_FUNCTION (y, x, rnd); +#endif + flags = __gmpfr_flags; + if (mpfr_get_emin () != oemin || + mpfr_get_emax () != oemax) + { + printf ("tgeneric: the exponent range has been modified" + " by the tested function!\n"); + exit (1); + } + TGENERIC_CHECK ("bad inexact flag", + (compare != 0) ^ (mpfr_inexflag_p () == 0)); + ctrt++; + + /* Tests in a reduced exponent range. */ + { + unsigned int oldflags = flags; + mpfr_exp_t e, emin, emax; + + /* Determine the smallest exponent range containing the + exponents of the mpfr_t inputs (x, and u if TWO_ARGS) + and output (y). */ + emin = MPFR_EMAX_MAX; + emax = MPFR_EMIN_MIN; + if (MPFR_IS_PURE_FP (x)) + { + e = MPFR_GET_EXP (x); + if (e < emin) + emin = e; + if (e > emax) + emax = e; + } +#if defined(TWO_ARGS) + if (MPFR_IS_PURE_FP (u)) + { + e = MPFR_GET_EXP (u); + if (e < emin) + emin = e; + if (e > emax) + emax = e; + } +#endif + if (MPFR_IS_PURE_FP (y)) + { + e = MPFR_GET_EXP (y); + if (test_of && e - 1 >= emax) + { + unsigned int ex_flags; + + mpfr_set_emax (e - 1); + mpfr_clear_flags (); +#if defined(TWO_ARGS) + inexact = TEST_FUNCTION (w, x, u, rnd); +#elif defined(DOUBLE_ARG1) + inexact = TEST_FUNCTION (w, d, x, rnd); +#elif defined(DOUBLE_ARG2) + inexact = TEST_FUNCTION (w, x, d, rnd); +#elif defined(ULONG_ARG1) + inexact = TEST_FUNCTION (w, i, x, rnd); +#elif defined(ULONG_ARG2) + inexact = TEST_FUNCTION (w, x, i, rnd); +#else + inexact = TEST_FUNCTION (w, x, rnd); +#endif + flags = __gmpfr_flags; + mpfr_set_emax (oemax); + ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION) + ", reduced exponent range [%" + MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC + "d] (overflow test) on:\n", + (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1); + printf ("x = "); + mpfr_dump (x); +#if defined(TWO_ARGS_ALL) + printf ("u = "); + mpfr_dump (u); +#endif + printf ("yprec = %u, rnd_mode = %s\n", + (unsigned int) yprec, + mpfr_print_rnd_mode (rnd)); + printf ("Expected flags ="); + flags_out (ex_flags); + printf (" got flags ="); + flags_out (flags); + printf ("inex = %d, w = ", inexact); + mpfr_dump (w); + exit (1); + } + test_of = 0; /* Overflow is tested only once. */ + } + if (test_uf && e + 1 <= emin) + { + unsigned int ex_flags; + + mpfr_set_emin (e + 1); + mpfr_clear_flags (); +#if defined(TWO_ARGS) + inexact = TEST_FUNCTION (w, x, u, rnd); +#elif defined(DOUBLE_ARG1) + inexact = TEST_FUNCTION (w, d, x, rnd); +#elif defined(DOUBLE_ARG2) + inexact = TEST_FUNCTION (w, x, d, rnd); +#elif defined(ULONG_ARG1) + inexact = TEST_FUNCTION (w, i, x, rnd); +#elif defined(ULONG_ARG2) + inexact = TEST_FUNCTION (w, x, i, rnd); +#else + inexact = TEST_FUNCTION (w, x, rnd); +#endif + flags = __gmpfr_flags; + mpfr_set_emin (oemin); + ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION) + ", reduced exponent range [%" + MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC + "d] (underflow test) on:\n", + (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax); + printf ("x = "); + mpfr_dump (x); +#if defined(TWO_ARGS_ALL) + printf ("u = "); + mpfr_dump (u); +#endif + printf ("yprec = %u, rnd_mode = %s\n", + (unsigned int) yprec, + mpfr_print_rnd_mode (rnd)); + printf ("Expected flags ="); + flags_out (ex_flags); + printf (" got flags ="); + flags_out (flags); + printf ("inex = %d, w = ", inexact); + mpfr_dump (w); + exit (1); + } + test_uf = 0; /* Underflow is tested only once. */ + } + if (e < emin) + emin = e; + if (e > emax) + emax = e; + } + if (emin > emax) + emin = emax; /* case where all values are singular */ + /* Consistency test in a reduced exponent range. Doing it + for the first 10 samples and for prec == p1 (which has + some special cases) should be sufficient. */ + if (ctrt <= 10 || prec == p1) + { + mpfr_set_emin (emin); + mpfr_set_emax (emax); +#ifdef DEBUG_TGENERIC + /* Useful information in case of assertion failure. */ + printf ("tgeneric: reduced exponent range [%" + MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n", + (mpfr_eexp_t) emin, (mpfr_eexp_t) emax); +#endif + mpfr_clear_flags (); +#if defined(TWO_ARGS) + inexact = TEST_FUNCTION (w, x, u, rnd); +#elif defined(DOUBLE_ARG1) + inexact = TEST_FUNCTION (w, d, x, rnd); +#elif defined(DOUBLE_ARG2) + inexact = TEST_FUNCTION (w, x, d, rnd); +#elif defined(ULONG_ARG1) + inexact = TEST_FUNCTION (w, i, x, rnd); +#elif defined(ULONG_ARG2) + inexact = TEST_FUNCTION (w, x, i, rnd); +#else + inexact = TEST_FUNCTION (w, x, rnd); +#endif + flags = __gmpfr_flags; + mpfr_set_emin (oemin); + mpfr_set_emax (oemax); + if (! (SAME_VAL (w, y) && + SAME_SIGN (inexact, compare) && + flags == oldflags)) + { + printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION) + ", reduced exponent range [%" + MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n", + (mpfr_eexp_t) emin, (mpfr_eexp_t) emax); + printf ("x = "); + mpfr_dump (x); +#if defined(TWO_ARGS_ALL) + printf ("u = "); + mpfr_dump (u); +#endif + printf ("yprec = %u, rnd_mode = %s\n", + (unsigned int) yprec, mpfr_print_rnd_mode (rnd)); + printf ("Expected:\n y = "); + mpfr_dump (y); + printf (" inex = %d, flags =", compare); + flags_out (oldflags); + printf ("Got:\n w = "); + mpfr_dump (w); + printf (" inex = %d, flags =", inexact); + flags_out (flags); + exit (1); + } + } + __gmpfr_flags = oldflags; /* restore the flags */ + } + + if (MPFR_IS_SINGULAR (y)) + { + if (MPFR_IS_NAN (y) || mpfr_nanflag_p ()) + TGENERIC_CHECK ("bad NaN flag", + MPFR_IS_NAN (y) && mpfr_nanflag_p ()); + else if (MPFR_IS_INF (y)) + { + TGENERIC_CHECK ("bad overflow flag", + (compare != 0) ^ (mpfr_overflow_p () == 0)); + TGENERIC_CHECK ("bad divide-by-zero flag", + (compare == 0 && !infinite_input) ^ + (mpfr_divby0_p () == 0)); + } + else if (MPFR_IS_ZERO (y)) + TGENERIC_CHECK ("bad underflow flag", + (compare != 0) ^ (mpfr_underflow_p () == 0)); + } + else if (mpfr_divby0_p ()) + { + TGENERIC_CHECK ("both overflow and divide-by-zero", + ! mpfr_overflow_p ()); + TGENERIC_CHECK ("both underflow and divide-by-zero", + ! mpfr_underflow_p ()); + TGENERIC_CHECK ("bad compare value (divide-by-zero)", + compare == 0); + } + else if (mpfr_overflow_p ()) + { + TGENERIC_CHECK ("both underflow and overflow", + ! mpfr_underflow_p ()); + TGENERIC_CHECK ("bad compare value (overflow)", compare != 0); + mpfr_nexttoinf (y); + TGENERIC_CHECK ("should have been max MPFR number (overflow)", + MPFR_IS_INF (y)); + } + else if (mpfr_underflow_p ()) + { + TGENERIC_CHECK ("bad compare value (underflow)", compare != 0); + mpfr_nexttozero (y); + TGENERIC_CHECK ("should have been min MPFR number (underflow)", + MPFR_IS_ZERO (y)); + } + else if (mpfr_can_round (y, yprec, rnd, rnd, prec)) + { + ctrn++; + mpfr_set (t, y, rnd); + /* Risk of failures are known when some flags are already set + before the function call. Do not set the erange flag, as + it will remain set after the function call and no checks + are performed in such a case (see the mpfr_erangeflag_p + test below). */ + if (randlimb () & 1) + __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE; +#ifdef DEBUG_TGENERIC + TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z)); +#endif + /* Let's increase the precision of the inputs in a random way. + In most cases, this doesn't make any difference, but for + the mpfr_fmod bug fixed in r6230, this triggers the bug. */ + mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15), + MPFR_RNDN); +#if defined(TWO_ARGS) + mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15), + MPFR_RNDN); + inexact = TEST_FUNCTION (z, x, u, rnd); +#elif defined(DOUBLE_ARG1) + inexact = TEST_FUNCTION (z, d, x, rnd); +#elif defined(DOUBLE_ARG2) + inexact = TEST_FUNCTION (z, x, d, rnd); +#elif defined(ULONG_ARG1) + inexact = TEST_FUNCTION (z, i, x, rnd); +#elif defined(ULONG_ARG2) + inexact = TEST_FUNCTION (z, x, i, rnd); +#else + inexact = TEST_FUNCTION (z, x, rnd); +#endif + if (mpfr_erangeflag_p ()) + goto next_n; + if (! mpfr_equal_p (t, z)) + { + printf ("tgeneric: results differ for " + MAKE_STR(TEST_FUNCTION) " on\n x = "); + mpfr_dump (x); +#if defined(TWO_ARGS_ALL) + printf (" u = "); + mpfr_dump (u); +#endif + printf (" prec = %u, rnd_mode = %s\n", + (unsigned int) prec, mpfr_print_rnd_mode (rnd)); + printf ("Got "); + mpfr_dump (z); + printf ("Expected "); + mpfr_dump (t); + printf ("Approx "); + mpfr_dump (y); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if (compare * compare2 >= 0) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (! SAME_SIGN (inexact, compare)) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d" + "\n", mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x = "); + mpfr_dump (x); +#if defined(TWO_ARGS_ALL) + printf ("u = "); + mpfr_dump (u); +#endif + printf ("y = "); + mpfr_dump (y); + printf ("t = "); + mpfr_dump (t); + exit (1); + } + } + else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL) + { + /* For developers only! */ + MPFR_ASSERTN (MPFR_IS_PURE_FP (y)); + mpfr_nexttoinf (y); + if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y)) + && !mpfr_overflow_p () && TGENERIC_SO_TEST) + { + printf ("Possible bug! |y| is the maximum finite number " + "and has been obtained when\nrounding toward zero" + " (%s). Thus there is a very probable overflow,\n" + "but the overflow flag is not set!\n", + mpfr_print_rnd_mode (rnd)); + printf ("x = "); + mpfr_dump (x); +#if defined(TWO_ARGS_ALL) + printf ("u = "); + mpfr_dump (u); +#endif + exit (1); + } + } + + next_n: + /* In case the exponent range has been changed by + tests_default_random() or for special values... */ + mpfr_set_emin (old_emin); + mpfr_set_emax (old_emax); + } + } + +#ifndef TGENERIC_NOWARNING + if (3 * ctrn < 2 * ctrt) + printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n", + ctrn, ctrt); +#endif + + mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0); +#if defined(TWO_ARGS_ALL) + mpfr_clear (u); +#endif +} + +#undef TEST_RANDOM_POS +#undef TEST_RANDOM_POS2 +#undef TEST_RANDOM_EMIN +#undef TEST_RANDOM_EMAX +#undef TEST_RANDOM_ALWAYS_SCALE +#undef RAND_FUNCTION +#undef TWO_ARGS +#undef TWO_ARGS_ALL +#undef DOUBLE_ARG1 +#undef DOUBLE_ARG2 +#undef ULONG_ARG1 +#undef ULONG_ARG2 +#undef TEST_FUNCTION +#undef test_generic diff --git a/mpfr/tests/tgeneric_ui.c b/mpfr/tests/tgeneric_ui.c new file mode 100644 index 0000000000..94658787d2 --- /dev/null +++ b/mpfr/tests/tgeneric_ui.c @@ -0,0 +1,137 @@ +/* Generic test file for functions with one mpfr_t argument and an integer. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* define INTEGER_TYPE to what we want */ +#ifndef INTEGER_TYPE +# define INTEGER_TYPE mp_limb_t +#endif +#ifndef RAND_FUNCTION +# define RAND_FUNCTION(x) mpfr_urandomb ((x), RANDS) +#endif +#ifndef INT_RAND_FUNCTION +# define INT_RAND_FUNCTION() (INTEGER_TYPE) randlimb () +#endif + +static void +test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N) +{ + mpfr_prec_t prec, yprec; + mpfr_t x, y, z, t; + INTEGER_TYPE u; + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n = 0; n <= N; n++) + { + if (n > 1 || prec < p1) + RAND_FUNCTION (x); + else + { + /* Special cases tested in precision p1 if n <= 1. */ + mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin ()); + } + if (n < 2 || n > 3 || prec < p1) + u = INT_RAND_FUNCTION (); + else + { + /* Special cases tested in precision p1 if n = 2 or 3. */ + if ((INTEGER_TYPE) -1 < 0) /* signed, type long assumed */ + u = n == 2 ? LONG_MIN : LONG_MAX; + else /* unsigned */ + u = n == 2 ? 0 : -1; + } + rnd = RND_RAND (); + mpfr_set_prec (y, yprec); + compare = TEST_FUNCTION (y, x, u, rnd); + if (mpfr_can_round (y, yprec, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = TEST_FUNCTION (z, x, u, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf ("\nu=%lu", (unsigned long) u); + printf (" prec=%lu rnd_mode=%s\n", + (unsigned long ) prec, mpfr_print_rnd_mode (rnd)); +#ifdef TEST_FUNCTION_NAME + printf ("Function: %s\n", TEST_FUNCTION_NAME); +#endif + printf ("got "); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + puts (""); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf ("approx "); + mpfr_print_binary (y); + puts (""); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if (compare * compare2 >= 0) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (! SAME_SIGN (inexact, compare)) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d" + "\n", mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x = "); mpfr_dump (x); + printf ("u = %lu\n", (unsigned long) u); + printf ("y = "); mpfr_dump (y); + printf ("t = "); mpfr_dump (t); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +#undef RAND_FUNCTION +#undef INTEGER_TYPE +#undef TEST_FUNCTION +#undef TEST_FUNCTION_NAME +#undef test_generic_ui +#undef INT_RAND_FUNCTION diff --git a/mpfr/tests/tget_d.c b/mpfr/tests/tget_d.c new file mode 100644 index 0000000000..ea3af8f7e3 --- /dev/null +++ b/mpfr/tests/tget_d.c @@ -0,0 +1,294 @@ +/* Test file for mpfr_get_d + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" +#include "ieee_floats.h" + +static int +check_denorms (void) +{ + mpfr_rnd_t rnd_mode; + mpfr_t x; + double d, d2, dd, f; + int fail = 0, k, n; + + mpfr_init2 (x, GMP_NUMB_BITS); + + rnd_mode = MPFR_RNDN; + for (k = -17; k <= 17; k += 2) + { + d = (double) k * DBL_MIN; /* k * 2^(-1022) */ + f = 1.0; + mpfr_set_si (x, k, MPFR_RNDN); + mpfr_div_2exp (x, x, 1022, MPFR_RNDN); /* k * 2^(-1022) */ + for (n = 0; n <= 58; n++) + { + d2 = d * f; + dd = mpfr_get_d (x, rnd_mode); + if (d2 != dd) /* should be k * 2^(-1022-n) for n < 53 */ + { + printf ("Wrong result for %d * 2^(%d), rnd_mode %d\n", + k, -1022-n, rnd_mode); + printf ("got %.20e instead of %.20e\n", dd, d2); + fail = 1; + } + f *= 0.5; + mpfr_div_2exp (x, x, 1, MPFR_RNDN); + } + } + + mpfr_set_str_binary (x, "1e-1074"); + dd = mpfr_get_d (x, MPFR_RNDA); + d2 = DBL_MIN; /* 2^(-1022) */ + for (k = 0; k < 52; k++) + d2 *= 0.5; /* 2^(-1074) */ + /* we first check that d2 is not zero (it could happen on a platform with + no subnormals) */ + if (d2 != 0.0 && dd != d2) + { + printf ("Error for x=1e-1074, RNDA\n"); + exit (1); + } + + mpfr_set_str_binary (x, "1e-1075"); + dd = mpfr_get_d (x, MPFR_RNDA); + if (d2 != 0.0 && dd != d2) + { + printf ("Error for x=1e-1075, RNDA\n"); + printf ("expected %.16e\n", d2); + printf ("got %.16e\n", dd); + exit (1); + } + + mpfr_clear (x); + return fail; +} + +static void +check_inf_nan (void) +{ + /* only if nans and infs are available */ +#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO) + mpfr_t x; + double d; + + mpfr_init2 (x, 123); + + mpfr_set_inf (x, 1); + d = mpfr_get_d (x, MPFR_RNDZ); + MPFR_ASSERTN (d > 0); + MPFR_ASSERTN (DOUBLE_ISINF (d)); + + mpfr_set_inf (x, -1); + d = mpfr_get_d (x, MPFR_RNDZ); + MPFR_ASSERTN (d < 0); + MPFR_ASSERTN (DOUBLE_ISINF (d)); + + mpfr_set_nan (x); + d = mpfr_get_d (x, MPFR_RNDZ); + MPFR_ASSERTN (DOUBLE_ISNAN (d)); + + mpfr_clear (x); +#endif +} + +static void +check_max (void) +{ + double d, e; + mpfr_t u; + + d = 1.0; + while (d < (DBL_MAX / 2.0)) + d += d; + mpfr_init (u); + if (mpfr_set_d (u, d, MPFR_RNDN) == 0) + { + /* If setting is exact */ + e = (mpfr_get_d1) (u); + if (e != d) + { + printf ("get_d(set_d)(1): %1.20e != %1.20e\n", d, e); + exit (1); + } + } + + mpfr_set_str_binary (u, "-1E1024"); + d = mpfr_get_d (u, MPFR_RNDZ); + MPFR_ASSERTN(d == -DBL_MAX); + d = mpfr_get_d (u, MPFR_RNDU); + MPFR_ASSERTN(d == -DBL_MAX); +#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO) + d = mpfr_get_d (u, MPFR_RNDN); + MPFR_ASSERTN(DOUBLE_ISINF(d) && d < 0.0); + d = mpfr_get_d (u, MPFR_RNDD); + MPFR_ASSERTN(DOUBLE_ISINF(d) && d < 0.0); +#endif + + mpfr_set_str_binary (u, "1E1024"); + d = mpfr_get_d (u, MPFR_RNDZ); + MPFR_ASSERTN(d == DBL_MAX); + d = mpfr_get_d (u, MPFR_RNDD); + MPFR_ASSERTN(d == DBL_MAX); +#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO) + d = mpfr_get_d (u, MPFR_RNDN); + MPFR_ASSERTN(DOUBLE_ISINF(d) && d > 0.0); + d = mpfr_get_d (u, MPFR_RNDU); + MPFR_ASSERTN(DOUBLE_ISINF(d) && d > 0.0); +#endif + + mpfr_clear (u); +} + +static void +check_min(void) +{ + double d, e; + mpfr_t u; + + d = 1.0; while (d > (DBL_MIN * 2.0)) d /= 2.0; + mpfr_init(u); + if (mpfr_set_d(u, d, MPFR_RNDN) == 0) + { + /* If setting is exact */ + e = mpfr_get_d1(u); + if (e != d) + { + printf("get_d(set_d)(2): %1.20e != %1.20e\n", d, e); + exit(1); + } + } + mpfr_clear(u); +} + +static void +check_get_d_2exp_inf_nan (void) +{ +#if !defined(MPFR_ERRDIVZERO) + + double var_d; + long exp; + mpfr_t var; + + mpfr_init2 (var, MPFR_PREC_MIN); + + mpfr_set_nan (var); + var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN); + if (!DOUBLE_ISNAN (var_d)) + { + printf ("mpfr_get_d_2exp with a NAN mpfr value returned a wrong value :\n" + " waiting for %g got %g\n", MPFR_DBL_NAN, var_d); + exit (1); + } + + mpfr_set_zero (var, 1); + var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN); + if ((exp != 0) || (var_d != 0.0)) + { + printf ("mpfr_get_d_2exp with a +0.0 mpfr value returned a wrong value :\n" + " double waiting for 0.0 got %g\n exp waiting for 0 got %ld\n", + var_d, exp); + exit (1); + } + + mpfr_set_zero (var, -1); + var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN); + if ((exp != 0) || (var_d != DBL_NEG_ZERO)) + { + printf ("mpfr_get_d_2exp with a +0.0 mpfr value returned a wrong value :\n" + " double waiting for %g got %g\n exp waiting for 0 got %ld\n", + DBL_NEG_ZERO, var_d, exp); + exit (1); + } + + mpfr_set_inf (var, 1); + var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN); + if (var_d != MPFR_DBL_INFP) + { + printf ("mpfr_get_d_2exp with a +Inf mpfr value returned a wrong value :\n" + " waiting for %g got %g\n", MPFR_DBL_INFP, var_d); + exit (1); + } + + mpfr_set_inf (var, -1); + var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN); + if (var_d != MPFR_DBL_INFM) + { + printf ("mpfr_get_d_2exp with a -Inf mpfr value returned a wrong value :\n" + " waiting for %g got %g\n", MPFR_DBL_INFM, var_d); + exit (1); + } + + mpfr_clear (var); + +#endif +} + +int +main (void) +{ + tests_start_mpfr (); + mpfr_test_init (); + +#ifndef MPFR_DOUBLE_SPEC + printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n" + "that you do not have a conforming C implementation and problems\n" + "may occur with conversions between MPFR numbers and standard\n" + "floating-point types. Please contact the MPFR team.\n"); +#elif MPFR_DOUBLE_SPEC == 0 + /* + printf ("The type 'double' of your C implementation does not seem to\n" + "correspond to the IEEE-754 double precision. Though code has\n" + "been written to support such implementations, tests have been\n" + "done only on IEEE-754 double-precision implementations and\n" + "conversions between MPFR numbers and standard floating-point\n" + "types may be inaccurate. You may wish to contact the MPFR team\n" + "for further testing.\n"); + */ + printf ("The type 'double' of your C implementation does not seem to\n" + "correspond to the IEEE-754 double precision. Such particular\n" + "implementations are not supported yet, and conversions between\n" + "MPFR numbers and standard floating-point types may be very\n" + "inaccurate.\n"); + printf ("FLT_RADIX = %ld\n", (long) FLT_RADIX); + printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG); + printf ("DBL_MIN_EXP = %ld\n", (long) DBL_MIN_EXP); + printf ("DBL_MAX_EXP = %ld\n", (long) DBL_MAX_EXP); +#endif + + if (check_denorms ()) + exit (1); + + check_inf_nan (); + check_min(); + check_max(); + + check_get_d_2exp_inf_nan (); + + tests_end_mpfr (); + return 0; +} + diff --git a/mpfr/tests/tget_d_2exp.c b/mpfr/tests/tget_d_2exp.c new file mode 100644 index 0000000000..610513e817 --- /dev/null +++ b/mpfr/tests/tget_d_2exp.c @@ -0,0 +1,121 @@ +/* Test mpfr_get_d_2exp. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + + +/* Check that hardware rounding doesn't make mpfr_get_d_2exp return a value + outside its defined range. */ +static void +check_round (void) +{ + static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 }; + mpfr_t f; + double got; + long got_exp; + int i, rnd_mode, neg; + + mpfr_init2 (f, 1024L); + + for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX ; rnd_mode++) + { + for (i = 0; i < (int) numberof (data); i++) + { + mpfr_set_ui (f, 1L, MPFR_RNDZ); + mpfr_mul_2exp (f, f, data[i], MPFR_RNDZ); + mpfr_sub_ui (f, f, 1L, MPFR_RNDZ); + + for (neg = 0; neg <= 1; neg++) + { + got = mpfr_get_d_2exp (&got_exp, f, (mpfr_rnd_t) rnd_mode); + + if (neg == 0 + ? (got < 0.5 || got >= 1.0) + : (got <= -1.0 || got > -0.5)) + { + printf ("mpfr_get_d_2exp wrong on 2**%lu-1\n", data[i]); + printf ("result out of range, expect 0.5 <= got < 1.0\n"); + printf (" rnd_mode = %d\n", rnd_mode); + printf (" data[i] = %lu\n", data[i]); + printf (" f "); + mpfr_out_str (stdout, 2, 0, f, MPFR_RNDN); + printf ("\n"); + d_trace (" got ", got); + printf (" got exp %ld\n", got_exp); + exit(1); + } + + mpfr_neg (f, f, MPFR_RNDZ); + } + } + } + + mpfr_clear (f); +} + + +static void +check_inf_nan (void) +{ + /* only if nans and infs are available */ +#if _GMP_IEEE_FLOATS + mpfr_t x; + double d; + long exp; + + mpfr_init2 (x, 123); + + mpfr_set_inf (x, 1); + d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ); + MPFR_ASSERTN (d > 0); + MPFR_ASSERTN (DOUBLE_ISINF (d)); + + mpfr_set_inf (x, -1); + d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ); + MPFR_ASSERTN (d < 0); + MPFR_ASSERTN (DOUBLE_ISINF (d)); + + mpfr_set_nan (x); + d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ); + MPFR_ASSERTN (DOUBLE_ISNAN (d)); + + mpfr_clear (x); +#endif +} + + +int +main (void) +{ + tests_start_mpfr (); + mpfr_test_init (); + + check_round (); + check_inf_nan (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tget_f.c b/mpfr/tests/tget_f.c new file mode 100644 index 0000000000..fbf7ee59e2 --- /dev/null +++ b/mpfr/tests/tget_f.c @@ -0,0 +1,390 @@ +/* Test file for mpfr_get_f. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +/* Test that there is no lost of accuracy when converting a mpfr_t number + into a mpf_t number (test with various precisions and exponents). */ +static void +prec_test (void) +{ + int px, py; + + for (py = 3; py <= 136; py++) + { + mpfr_t y1, y2, y3; + + mpfr_init2 (y1, py); + mpfr_init2 (y2, py); + mpfr_init2 (y3, py); + + for (px = 32; px <= 160; px += 32) + { + mpf_t x1, x2, x3; + int e; + + mpf_init (x1); + mpf_init (x2); + mpf_init (x3); + mpfr_set_ui_2exp (y1, 1, py - 1, MPFR_RNDN); + mpfr_get_f (x1, y1, MPFR_RNDN); /* exact (power of 2) */ + mpf_set (x2, x1); + mpfr_set (y2, y1, MPFR_RNDN); + + for (e = py - 2; e >= 0; e--) + { + int inex; + mpf_div_2exp (x2, x2, 1); + mpf_add (x1, x1, x2); + mpfr_div_2exp (y2, y2, 1, MPFR_RNDN); + inex = mpfr_add (y1, y1, y2, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_set_f (y3, x1, MPFR_RNDN); + if (! mpfr_equal_p (y1, y3)) + break; + inex = mpfr_get_f (x3, y3, MPFR_RNDN); + if (mpf_cmp (x1, x3) != 0) + { + printf ("Error in prec_test (px = %d, py = %d, e = %d)\n", + px, py, e); + printf ("x1 = "); + mpf_out_str (stdout, 16, 0, x1); + printf ("\nx2 = "); + mpf_out_str (stdout, 16, 0, x2); + printf ("\n"); + exit (1); + } + if (inex != 0) + { + printf ("Error in prec_test (px = %d, py = %d, e = %d)\n", + px, py, e); + printf ("wrong ternary value got: %+d, expected: 0\n", + inex); + exit (1); + } + } + + mpf_clear (x1); + mpf_clear (x2); + mpf_clear (x3); + } + + mpfr_clear (y1); + mpfr_clear (y2); + mpfr_clear (y3); + } +} + +static void +special_test (void) +{ + int inex; + mpf_t x; + mpfr_t y; + + mpfr_init (y); + mpf_init (x); + + mpfr_set_nan (y); + mpfr_clear_flags (); + mpfr_get_f (x, y, MPFR_RNDN); + if (! mpfr_erangeflag_p ()) + { + printf ("Error: mpfr_get_f(NaN) should raise erange flag\n"); + exit (1); + } + + mpfr_set_inf (y, +1); + mpfr_clear_flags (); + inex = mpfr_get_f (x, y, MPFR_RNDN); + if (inex >= 0) + { + printf ("Error: mpfr_get_f(+Inf) should return a negative ternary" + "value\n"); + exit (1); + } + if (! mpfr_erangeflag_p ()) + { + printf ("Error: mpfr_get_f(+Inf) should raise erange flag\n"); + exit (1); + } + + mpfr_set_inf (y, -1); + mpfr_clear_flags (); + inex = mpfr_get_f (x, y, MPFR_RNDN); + if (inex <= 0) + { + printf ("Error: mpfr_get_f(-Inf) should return a positive ternary" + "value\n"); + exit (1); + } + if (! mpfr_erangeflag_p ()) + { + printf ("Error: mpfr_get_f(-Inf) should raise erange flag\n"); + exit (1); + } + + mpfr_set_ui (y, 0, MPFR_RNDN); + if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, 0)) + { + printf ("Error: mpfr_get_f(+0) fails\n"); + exit (1); + } + + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_neg (y, y, MPFR_RNDN); + if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, 0)) + { + printf ("Error: mpfr_get_f(-0) fails\n"); + exit (1); + } + + mpfr_clear (y); + mpf_clear (x); +} + +static void +ternary_test (void) +{ + int prec; + int rnd; + int inex, expected_inex; + mpf_t x; + mpfr_t y; + + mpf_init2 (x, 256); + mpfr_init2 (y, 256); + + for (prec = 2; prec <= 256; prec++) + { + + mpf_set_prec (x, prec); + mpfr_set_prec (y, PREC (x) * GMP_NUMB_BITS + 1); + + /* y == 1 */ + mpfr_set_ui_2exp (y, 1, prec, MPFR_RNDN); + + RND_LOOP (rnd) + { + inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd); + + if (inex != 0 || mpfr_cmp_f (y, x) !=0) + { + printf ("Error in mpfr_get_f (x, y, %s)\nx = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpf_out_str (stdout, 2, 0, x); + printf ("\ny = "); + mpfr_dump (y); + if (inex != 0) + printf ("got ternary value = %+d, expected: 0\n", inex); + + exit (1); + } + } + + /* y == 1 + epsilon */ + mpfr_nextbelow (y); + + RND_LOOP (rnd) + { + switch (rnd) + { + case MPFR_RNDU: case MPFR_RNDA: + case MPFR_RNDN: + expected_inex = +1; + break; + default : + expected_inex = -1; + } + + inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd); + + if (! SAME_SIGN (expected_inex, inex) + || SAME_SIGN (expected_inex, mpfr_cmp_f (y, x))) + { + printf ("Error in mpfr_get_f (x, y, %s)\nx = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpf_out_str (stdout, 2, 0, x); + printf ("\ny = "); + mpfr_dump (y); + if (! SAME_SIGN (expected_inex, inex)) + printf ("got ternary value = %+d, expected: %+d\n", + inex, expected_inex); + + exit (1); + } + } + + /* y == positive random float */ + mpfr_random2 (y, MPFR_LIMB_SIZE (y), 1024, RANDS); + + RND_LOOP (rnd) + { + inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd); + + if (! SAME_SIGN (inex, -mpfr_cmp_f (y, x))) + { + printf ("Error in mpfr_get_f (x, y, %s)\nx = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpf_out_str (stdout, 2, 0, x); + printf ("\ny = "); + mpfr_dump (y); + printf ("got ternary value = %+d, expected: %+d\n", + inex, -mpfr_cmp_f (y, x)); + + exit (1); + } + } + } + + mpf_clear (x); + mpfr_clear (y); +} + +int +main (void) +{ + mpf_t x; + mpfr_t y, z; + unsigned long i; + mpfr_exp_t e; + int inex; + + tests_start_mpfr (); + + mpfr_init (y); + mpfr_init (z); + mpf_init (x); + + i = 1; + while (i) + { + mpfr_set_ui (y, i, MPFR_RNDN); + if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, i)) + { + printf ("Error: mpfr_get_f(%lu) fails\n", i); + exit (1); + } + if (i <= - (unsigned long) LONG_MIN) + { + long j = i < - (unsigned long) LONG_MIN ? - (long) i : LONG_MIN; + mpfr_set_si (y, j, MPFR_RNDN); + if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_si (x, j)) + { + printf ("Error: mpfr_get_f(-%lu) fails\n", i); + exit (1); + } + } + i *= 2; + } + + /* same tests, but with a larger precision for y, which requires to + round it */ + mpfr_set_prec (y, 100); + i = 1; + while (i) + { + mpfr_set_ui (y, i, MPFR_RNDN); + inex = mpfr_get_f (x, y, MPFR_RNDN); + if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x)) || mpf_cmp_ui (x, i)) + { + printf ("Error: mpfr_get_f(%lu) fails\n", i); + exit (1); + } + mpfr_set_si (y, (signed long) -i, MPFR_RNDN); + inex = mpfr_get_f (x, y, MPFR_RNDN); + if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x)) + || mpf_cmp_si (x, (signed long) -i)) + { + printf ("Error: mpfr_get_f(-%lu) fails\n", i); + exit (1); + } + i *= 2; + } + + /* bug reported by Jim White */ + for (e = 0; e <= 2 * GMP_NUMB_BITS; e++) + { + /* test with 2^(-e) */ + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_div_2exp (y, y, e, MPFR_RNDN); + inex = mpfr_get_f (x, y, MPFR_RNDN); + mpf_mul_2exp (x, x, e); + if (inex != 0 || mpf_cmp_ui (x, 1) != 0) + { + printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n"); + printf ("y="); + mpfr_dump (y); + printf ("x="); + mpf_div_2exp (x, x, e); + mpf_out_str (stdout, 2, 0, x); + exit (1); + } + + /* test with 2^(e) */ + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_mul_2exp (y, y, e, MPFR_RNDN); + inex = mpfr_get_f (x, y, MPFR_RNDN); + mpf_div_2exp (x, x, e); + if (inex != 0 || mpf_cmp_ui (x, 1) != 0) + { + printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n"); + printf ("y="); + mpfr_dump (y); + printf ("x="); + mpf_mul_2exp (x, x, e); + mpf_out_str (stdout, 2, 0, x); + exit (1); + } + } + + /* Bug reported by Yury Lukach on 2006-04-05 */ + mpfr_set_prec (y, 32); + mpfr_set_prec (z, 32); + mpf_set_prec (x, 32); + mpfr_set_ui_2exp (y, 0xc1234567, -30, MPFR_RNDN); + mpfr_get_f (x, y, MPFR_RNDN); + inex = mpfr_set_f (z, x, MPFR_RNDN); + if (inex != 0 || ! mpfr_equal_p (y, z)) + { + printf ("Error in mpfr_get_f:\n inex = %d, y = ", inex); + mpfr_dump (z); + printf ("Expected:\n inex = 0, y = "); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (z); + mpf_clear (x); + + special_test (); + prec_test (); + ternary_test (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tget_flt.c b/mpfr/tests/tget_flt.c new file mode 100644 index 0000000000..fbf8cc7341 --- /dev/null +++ b/mpfr/tests/tget_flt.c @@ -0,0 +1,399 @@ +/* Test file for mpfr_get_flt and mpfr_set_flt + +Copyright 2009-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <float.h> /* for FLT_MIN */ +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x, y; + float f, g; + int i; +#if !defined(MPFR_ERRDIVZERO) + float infp; +#endif + + tests_start_mpfr (); + +#if !defined(MPFR_ERRDIVZERO) + /* The definition of DBL_POS_INF involves a division by 0. This makes + "clang -O2 -fsanitize=undefined -fno-sanitize-recover" fail. */ + infp = (float) DBL_POS_INF; + if (infp * 0.5 != infp) + { + fprintf (stderr, "Error, FLT_MAX + FLT_MAX does not yield INFP\n"); + fprintf (stderr, "(this is probably a compiler bug, please report)\n"); + exit (1); + } +#endif + + mpfr_init2 (x, 24); + mpfr_init2 (y, 24); + +#if !defined(MPFR_ERRDIVZERO) + mpfr_set_nan (x); + f = mpfr_get_flt (x, MPFR_RNDN); + if (! DOUBLE_ISNAN (f)) + { + printf ("Error for mpfr_get_flt(NaN)\n"); + printf ("got f=%f\n", f); + exit (1); + } + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_nan_p (x) == 0) + { + printf ("Error for mpfr_set_flt(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) < 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(+Inf)):\n"); + printf ("f=%f, expected -Inf\n", f); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_set_inf (x, -1); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) > 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(-Inf)):\n"); + printf ("f=%f, expected -Inf\n", f); + printf ("got "); mpfr_dump (x); + exit (1); + } +#endif + + mpfr_set_ui (x, 0, MPFR_RNDN); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) < 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(+0))\n"); + exit (1); + } + +#ifdef HAVE_SIGNEDZ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) > 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(-0))\n"); + exit (1); + } +#endif /* HAVE_SIGNEDZ */ + + mpfr_set_ui (x, 17, MPFR_RNDN); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_cmp_ui (x, 17) != 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(17))\n"); + printf ("expected 17\n"); + printf ("got "); + mpfr_dump (x); + exit (1); + } + + mpfr_set_si (x, -42, MPFR_RNDN); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (x, f, MPFR_RNDN); + if (mpfr_cmp_si (x, -42) != 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(-42))\n"); + printf ("expected -42\n"); + printf ("got "); + mpfr_dump (x); + exit (1); + } + + mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN); + for (i = -126; i < 128; i++) + { + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_set_flt (y, f, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + mpfr_mul_2exp (x, x, 1, MPFR_RNDN); + } + + mpfr_set_prec (x, 53); + mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN); + for (i = -126; i < 128; i++) + { + mpfr_nextbelow (x); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_nextabove (x); + mpfr_set_flt (y, f, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + mpfr_mul_2exp (x, x, 1, MPFR_RNDN); + } + + mpfr_set_prec (x, 53); + mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN); + for (i = -126; i < 128; i++) + { + mpfr_nextabove (x); + f = mpfr_get_flt (x, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_set_flt (y, f, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n"); + printf ("expected "); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + mpfr_mul_2exp (x, x, 1, MPFR_RNDN); + } + +#ifdef HAVE_DENORMS + mpfr_set_si_2exp (x, 1, -150, MPFR_RNDN); + g = 0.0; + f = mpfr_get_flt (x, MPFR_RNDN); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-150),RNDN)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDZ); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-150),RNDZ)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDD); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-150),RNDD)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + g = FLT_MIN * FLT_EPSILON; + f = mpfr_get_flt (x, MPFR_RNDU); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-150),RNDU)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDA); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-150),RNDA)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + + mpfr_set_si_2exp (x, 1, -151, MPFR_RNDN); + g = 0.0; + f = mpfr_get_flt (x, MPFR_RNDN); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-151),RNDN)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDZ); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-151),RNDZ)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDD); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-151),RNDD)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + g = FLT_MIN * FLT_EPSILON; + f = mpfr_get_flt (x, MPFR_RNDU); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-151),RNDU)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDA); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-151),RNDA)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + + mpfr_set_si_2exp (x, 1, -149, MPFR_RNDN); + g = FLT_MIN * FLT_EPSILON; + f = mpfr_get_flt (x, MPFR_RNDN); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-149),RNDN)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDZ); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-149),RNDZ)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDD); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-149),RNDD)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDU); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-149),RNDU)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDA); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^(-149),RNDA)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } +#endif + + mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN); + g = FLT_MAX; + f = mpfr_get_flt (x, MPFR_RNDZ); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128,RNDZ)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDD); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128,RNDD)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } +#if !defined(MPFR_ERRDIVZERO) + f = mpfr_get_flt (x, MPFR_RNDN); /* 2^128 rounds to itself with extended + exponent range, we should get +Inf */ + g = infp; + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128,RNDN)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDU); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128,RNDU)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDA); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128,RNDA)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } +#endif + + /* corner case: take x with 25 bits just below 2^128 */ + mpfr_set_prec (x, 25); + mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN); + mpfr_nextbelow (x); + g = FLT_MAX; + f = mpfr_get_flt (x, MPFR_RNDZ); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDZ)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDD); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDD)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } +#if !defined(MPFR_ERRDIVZERO) + f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule), + thus we should get +Inf */ + g = infp; + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDN)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDU); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDU)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } + f = mpfr_get_flt (x, MPFR_RNDA); + if (f != g) + { + printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDA)\n"); + printf ("expected %.8e, got %.8e\n", g, f); + exit (1); + } +#endif + + mpfr_clear (x); + mpfr_clear (y); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tget_ld_2exp.c b/mpfr/tests/tget_ld_2exp.c new file mode 100644 index 0000000000..6f18b11216 --- /dev/null +++ b/mpfr/tests/tget_ld_2exp.c @@ -0,0 +1,145 @@ +/* Test mpfr_get_ld_2exp. + +Copyright 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +/* Check that hardware rounding doesn't make mpfr_get_ld_2exp return a value + outside its defined range. */ +static void +check_round (void) +{ + static const unsigned long data[] = {1, 32, 53, 54, 63, 64, 65, 127, 128, 256, 512 }; + mpfr_t f; + long double got; + long got_exp; + int i, rnd_mode, neg; + + mpfr_init2 (f, 1024L); + + for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX ; rnd_mode++) + { + for (i = 0; i < (int) numberof (data); i++) + { + mpfr_set_ui (f, 1L, MPFR_RNDZ); + mpfr_mul_2exp (f, f, data[i], MPFR_RNDZ); + mpfr_sub_ui (f, f, 1L, MPFR_RNDZ); + + for (neg = 0; neg <= 1; neg++) + { + got = mpfr_get_ld_2exp (&got_exp, f, (mpfr_rnd_t) rnd_mode); + + if (neg == 0 + ? (got < 0.5 || got >= 1.0) + : (got <= -1.0 || got > -0.5)) + { + printf ("mpfr_get_ld_2exp wrong on 2**%lu-1\n", data[i]); + printf ("result out of range, expect 0.5 <= got < 1.0\n"); + printf (" rnd_mode = %d\n", rnd_mode); + printf (" data[i] = %lu\n", data[i]); + printf (" f "); + mpfr_out_str (stdout, 2, 0, f, MPFR_RNDN); + printf ("\n"); + d_trace (" got ", got); + printf (" got exp %ld\n", got_exp); + exit(1); + } + + mpfr_neg (f, f, MPFR_RNDZ); + } + } + } + + mpfr_clear (f); +} + + +static void +check_inf_nan (void) +{ + /* only if nans and infs are available */ +#if _GMP_IEEE_FLOATS + mpfr_t x; + double d; + long exp; + + mpfr_init2 (x, 123); + + mpfr_set_inf (x, 1); + d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ); + MPFR_ASSERTN (d > 0); + MPFR_ASSERTN (DOUBLE_ISINF (d)); + + mpfr_set_inf (x, -1); + d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ); + MPFR_ASSERTN (d < 0); + MPFR_ASSERTN (DOUBLE_ISINF (d)); + + mpfr_set_nan (x); + d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ); + MPFR_ASSERTN (DOUBLE_ISNAN (d)); + + mpfr_clear (x); +#endif +} + +static void +bug20090520 (void) +{ + mpfr_t x; + long double d, e; + int i; + + mpfr_init (x); + mpfr_set_ui (x, 1, MPFR_RNDN); + d = 1.0; + mpfr_div_2exp (x, x, 16383, MPFR_RNDN); + for (i = 0; i < 16383; i++) + d *= 0.5; + e = mpfr_get_ld (x, MPFR_RNDN); + if (e != d) + { + printf ("mpfr_get_ld(1e-16383) failed\n"); + printf ("expected %.20Le\n", d); + printf ("got %.20Le\n", e); + exit (1); + } + mpfr_clear (x); +} + +int +main (void) +{ + tests_start_mpfr (); + mpfr_test_init (); + + bug20090520 (); + + check_round (); + check_inf_nan (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tget_set_d64.c b/mpfr/tests/tget_set_d64.c new file mode 100644 index 0000000000..117ce3fc59 --- /dev/null +++ b/mpfr/tests/tget_set_d64.c @@ -0,0 +1,349 @@ +/* Test file for mpfr_get_decimal64 and mpfr_set_decimal64. + +Copyright 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef MPFR_WANT_DECIMAL_FLOATS + +#include <stdlib.h> /* for exit */ +#include "mpfr-test.h" + +#ifndef DEC64_MAX +# define DEC64_MAX 9.999999999999999E384dd +#endif + +/* #define DEBUG */ + +static void +print_decimal64 (_Decimal64 d) +{ + union ieee_double_extract x; + union ieee_double_decimal64 y; + unsigned int Gh, i; + + y.d64 = d; + x.d = y.d; + Gh = x.s.exp >> 6; + printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1, + (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1); + printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1, + (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1, + x.s.exp & 1); + for (i = 20; i > 0; i--) + printf ("%d", (x.s.manh >> (i - 1)) & 1); + for (i = 32; i > 0; i--) + printf ("%d", (x.s.manl >> (i - 1)) & 1); + printf ("|\n"); +} + +static void +check_inf_nan (void) +{ + mpfr_t x, y; + _Decimal64 d; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + mpfr_set_nan (x); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 1, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_nan_p (x)); + + mpfr_set_inf (x, 1); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 1, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) > 0); + + mpfr_set_inf (x, -1); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 1, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0); + + mpfr_set_ui (x, 0, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 1, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) > 0); + + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_neg (x, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 1, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) < 0); + + mpfr_set_ui (x, 1, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_ui (x, 1) == 0); + + mpfr_set_si (x, -1, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0); + + mpfr_set_ui (x, 2, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_ui (x, 2) == 0); + + mpfr_set_ui (x, 99, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp_ui (x, 99) == 0); + + mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ); + mpfr_set (y, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + /* smallest normal number */ + mpfr_set_str (x, "1E-383", 10, MPFR_RNDU); + mpfr_set (y, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDU); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + /* smallest subnormal number */ + mpfr_set_str (x, "1E-398", 10, MPFR_RNDU); + mpfr_set (y, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDU); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + /* subnormal number with exponent change when we round back + from 16 digits to 1 digit */ + mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN); + d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */ + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDD); + mpfr_set_str (y, "1E-397", 10, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + /* largest number */ + mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); + mpfr_set (y, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDU); + MPFR_ASSERTN (d == DEC64_MAX); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ); + mpfr_set (y, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDA); + MPFR_ASSERTN (d == -DEC64_MAX); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + /* largest number */ + mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDZ); + mpfr_set_decimal64 (y, d, MPFR_RNDU); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_random (void) +{ + mpfr_t x, y; + _Decimal64 d; + int i; + + mpfr_init2 (x, 49); + mpfr_init2 (y, 49); + + for (i = 0; i < 100000; i++) + { + mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */ + /* the normal decimal64 range contains [2^(-1272), 2^1278] */ + mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN); + if (mpfr_get_exp (x) <= -1272) + mpfr_mul_2exp (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + mpfr_set_decimal64 (y, d, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("x="); mpfr_dump (x); + printf ("d="); print_decimal64 (d); + printf ("y="); mpfr_dump (y); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (y); +} + +/* check with native decimal formats */ +static void +check_native (void) +{ + mpfr_t x; + _Decimal64 d; + + mpfr_init2 (x, 53); + + /* check important constants are correctly converted */ + mpfr_set_ui (x, 17, MPFR_RNDN); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + MPFR_ASSERTN(d == 17.0dd); + + mpfr_set_ui (x, 42, MPFR_RNDN); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + MPFR_ASSERTN(d == 42.0dd); + + mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0); + + mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0); + + mpfr_clear (x); +} + +static void +check_overflow (void) +{ + mpfr_t x; + int err = 0, neg, rnd; + + mpfr_init2 (x, 96); + for (neg = 0; neg < 2; neg++) + RND_LOOP (rnd) + { + _Decimal64 d, e; + mpfr_rnd_t r = (mpfr_rnd_t) rnd; + int sign = neg ? -1 : 1; + + e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX; + /* This tests the binary exponent e > 1279 case of get_d64.c */ + mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN); + d = mpfr_get_decimal64 (x, r); + if (d != e) + { + printf ("Error 1 in check_overflow for %s, %s\n", + neg ? "negative" : "positive", + mpfr_print_rnd_mode (r)); + err = 1; + } + /* This tests the decimal exponent e > 385 case of get_d64.c */ + mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN); + d = mpfr_get_decimal64 (x, r); + if (d != e) + { + printf ("Error 2 in check_overflow for %s, %s\n", + neg ? "negative" : "positive", + mpfr_print_rnd_mode (r)); + err = 1; + } + /* This tests the last else (-382 <= e <= 385) of get_d64.c */ + mpfr_set_decimal64 (x, e, MPFR_RNDA); + d = mpfr_get_decimal64 (x, r); + if (d != e) + { + printf ("Error 3 in check_overflow for %s, %s\n", + neg ? "negative" : "positive", + mpfr_print_rnd_mode (r)); + err = 1; + } + } + mpfr_clear (x); + if (err) + exit (1); +} + +static void +check_tiny (void) +{ + mpfr_t x; + _Decimal64 d; + + /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round + to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between + 0 and 1E-398 is not a representable binary number, so that there + are no tests for it. */ + mpfr_init2 (x, 128); + mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + MPFR_ASSERTN (d == 1.0E-398dd); + mpfr_neg (x, x, MPFR_RNDN); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + MPFR_ASSERTN (d == -1.0E-398dd); + mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + MPFR_ASSERTN (d == 1.0E-398dd); + mpfr_neg (x, x, MPFR_RNDN); + d = mpfr_get_decimal64 (x, MPFR_RNDN); + MPFR_ASSERTN (d == -1.0E-398dd); + mpfr_clear (x); +} + +int +main (void) +{ + tests_start_mpfr (); + mpfr_test_init (); + +#ifdef DEBUG +#ifdef DPD_FORMAT + printf ("Using DPD format\n"); +#else + printf ("Using BID format\n"); +#endif +#endif + check_inf_nan (); + check_random (); + check_native (); + check_overflow (); + check_tiny (); + + tests_end_mpfr (); + return 0; +} + +#else /* MPFR_WANT_DECIMAL_FLOATS */ + +int +main (void) +{ + return 77; +} + +#endif /* MPFR_WANT_DECIMAL_FLOATS */ diff --git a/mpfr/tests/tget_sj.c b/mpfr/tests/tget_sj.c new file mode 100644 index 0000000000..f69863e3d0 --- /dev/null +++ b/mpfr/tests/tget_sj.c @@ -0,0 +1,281 @@ +/* Test file for mpfr_get_sj and mpfr_get_uj. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" /* for a build within gmp */ +#endif + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-intmax.h" +#include "mpfr-test.h" + +#ifndef _MPFR_H_HAVE_INTMAX_T + +int +main (void) +{ + return 77; +} + +#else + +static void +check_sj (intmax_t s, mpfr_ptr x) +{ + mpfr_t y; + int i; + + mpfr_init2 (y, MPFR_PREC (x)); + + for (i = -1; i <= 1; i++) + { + int rnd; + + mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); + mpfr_add (y, y, x, MPFR_RNDN); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + intmax_t r; + + if (rnd == MPFR_RNDZ && i < 0 && s >= 0) + continue; + if (rnd == MPFR_RNDZ && i > 0 && s <= 0) + continue; + if (rnd == MPFR_RNDD && i < 0) + continue; + if (rnd == MPFR_RNDU && i > 0) + continue; + if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || + (MPFR_IS_NEG(y) && i < 0))) + continue; + /* rint (y) == x == s */ + r = mpfr_get_sj (y, (mpfr_rnd_t) rnd); + if (r != s) + { + printf ("Error in check_sj for y = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Got %jd instead of %jd.\n", r, s); + exit (1); + } + } + } + + mpfr_clear (y); +} + +static void +check_uj (uintmax_t u, mpfr_ptr x) +{ + mpfr_t y; + int i; + + mpfr_init2 (y, MPFR_PREC (x)); + + for (i = -1; i <= 1; i++) + { + int rnd; + + mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); + mpfr_add (y, y, x, MPFR_RNDN); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + uintmax_t r; + + if (rnd == MPFR_RNDZ && i < 0) + continue; + if (rnd == MPFR_RNDD && i < 0) + continue; + if (rnd == MPFR_RNDU && i > 0) + continue; + if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || + (MPFR_IS_NEG(y) && i < 0))) + continue; + /* rint (y) == x == u */ + r = mpfr_get_uj (y, (mpfr_rnd_t) rnd); + if (r != u) + { + printf ("Error in check_uj for y = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Got %ju instead of %ju.\n", r, u); + exit (1); + } + } + } + + mpfr_clear (y); +} + +static void +check_erange (void) +{ + mpfr_t x; + uintmax_t dl; + intmax_t d; + + /* Test for ERANGE flag + correct behaviour if overflow */ + + mpfr_init2 (x, 256); + mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); + mpfr_clear_erangeflag (); + dl = mpfr_get_uj (x, MPFR_RNDN); + if (dl != MPFR_UINTMAX_MAX || mpfr_erangeflag_p ()) + { + printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (1)\n"); + exit (1); + } + mpfr_add_ui (x, x, 1, MPFR_RNDN); + dl = mpfr_get_uj (x, MPFR_RNDN); + if (dl != MPFR_UINTMAX_MAX || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (2)\n"); + exit (1); + } + mpfr_set_sj (x, -1, MPFR_RNDN); + mpfr_clear_erangeflag (); + dl = mpfr_get_uj (x, MPFR_RNDN); + if (dl != 0 || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_uj + ERANGE + -1 \n"); + exit (1); + } + mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN); + mpfr_clear_erangeflag (); + d = mpfr_get_sj (x, MPFR_RNDN); + if (d != MPFR_INTMAX_MAX || mpfr_erangeflag_p ()) + { + printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (1)\n"); + exit (1); + } + mpfr_add_ui (x, x, 1, MPFR_RNDN); + d = mpfr_get_sj (x, MPFR_RNDN); + if (d != MPFR_INTMAX_MAX || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (2)\n"); + exit (1); + } + mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN); + mpfr_clear_erangeflag (); + d = mpfr_get_sj (x, MPFR_RNDN); + if (d != MPFR_INTMAX_MIN || mpfr_erangeflag_p ()) + { + printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (1)\n"); + exit (1); + } + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + d = mpfr_get_sj (x, MPFR_RNDN); + if (d != MPFR_INTMAX_MIN || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (2)\n"); + exit (1); + } + + mpfr_set_nan (x); + mpfr_clear_erangeflag (); + d = mpfr_get_uj (x, MPFR_RNDN); + if (d != 0 || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_uj + NaN\n"); + exit (1); + } + mpfr_clear_erangeflag (); + d = mpfr_get_sj (x, MPFR_RNDN); + if (d != 0 || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_sj + NaN\n"); + exit (1); + } + + mpfr_clear (x); +} + +int +main (void) +{ + mpfr_prec_t prec; + mpfr_t x, y; + intmax_t s; + uintmax_t u; + + tests_start_mpfr (); + + for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++) + { } + + mpfr_init2 (x, prec + 4); + mpfr_init2 (y, prec + 4); + + mpfr_set_ui (x, 0, MPFR_RNDN); + check_sj (0, x); + check_uj (0, x); + + mpfr_set_ui (x, 1, MPFR_RNDN); + check_sj (1, x); + check_uj (1, x); + + mpfr_neg (x, x, MPFR_RNDN); + check_sj (-1, x); + + mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN); + mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */ + + mpfr_div_ui (y, x, 2, MPFR_RNDZ); + mpfr_trunc (y, y); /* INTMAX_MAX */ + for (s = MPFR_INTMAX_MAX; s != 0; s /= 17) + { + check_sj (s, y); + mpfr_div_ui (y, y, 17, MPFR_RNDZ); + mpfr_trunc (y, y); + } + + mpfr_div_ui (y, x, 2, MPFR_RNDZ); + mpfr_trunc (y, y); /* INTMAX_MAX */ + mpfr_neg (y, y, MPFR_RNDN); + if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0) + mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */ + for (s = MPFR_INTMAX_MIN; s != 0; s /= 17) + { + check_sj (s, y); + mpfr_div_ui (y, y, 17, MPFR_RNDZ); + mpfr_trunc (y, y); + } + + for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17) + { + check_uj (u, x); + mpfr_div_ui (x, x, 17, MPFR_RNDZ); + mpfr_trunc (x, x); + } + + mpfr_clear (x); + mpfr_clear (y); + + check_erange (); + + tests_end_mpfr (); + return 0; +} + +#endif diff --git a/mpfr/tests/tget_str.c b/mpfr/tests/tget_str.c new file mode 100644 index 0000000000..9b64356ce4 --- /dev/null +++ b/mpfr/tests/tget_str.c @@ -0,0 +1,1268 @@ +/* Test file for mpfr_get_str. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check3 (const char *d, mpfr_rnd_t rnd, const char *res) +{ + mpfr_t x; + char *str; + mpfr_exp_t e; + + mpfr_init2 (x, 53); + mpfr_set_str (x, d, 10, rnd); + str = mpfr_get_str (NULL, &e, 10, 5, x, rnd); + if (strcmp (str, res)) + { + printf ("Error in mpfr_get_str for x=%s\n", d); + printf ("got %s instead of %s\n", str, res); + exit (1); + } + mpfr_clear (x); + mpfr_free_str (str); +} + +static void +check_small (void) +{ + mpfr_t x; + char *s; + mpfr_exp_t e; + mpfr_prec_t p; + + mpfr_init (x); + + mpfr_set_prec (x, 20); + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_nexttozero (x); + s = mpfr_get_str (NULL, &e, 4, 2, x, MPFR_RNDU); + if (strcmp (s, "20") || (e != 1)) + { + printf ("Error in mpfr_get_str: 2- rounded up with 2 digits" + " in base 4\n"); + exit (1); + } + mpfr_free_str (s); + + /* check n_digits=0 */ + mpfr_set_prec (x, 5); + mpfr_set_ui (x, 17, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 3, 0, x, MPFR_RNDN); + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 36, 0, x, MPFR_RNDN); + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 62, 0, x, MPFR_RNDN); + mpfr_free_str (s); + + mpfr_set_prec (x, 64); + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_div_2exp (x, x, 63, MPFR_RNDN); /* x = -2^(-63) */ + mpfr_add_ui (x, x, 1, MPFR_RNDN); /* x = 1 - 2^(-63) */ + mpfr_mul_2exp (x, x, 32, MPFR_RNDN); /* x = 2^32 - 2^(-31) */ + s = mpfr_get_str (NULL, &e, 3, 21, x, MPFR_RNDU); + if (strcmp (s, "102002022201221111211") || (e != 21)) + { + printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with" + " 21 digits in base 3\n"); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 3, 20, x, MPFR_RNDU); + if (strcmp (s, "10200202220122111122") || (e != 21)) + { + printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with" + " 20 digits in base 3\n"); + exit (1); + } + mpfr_free_str (s); + + /* check corner case ret!=0, j0!=0 in mpfr_get_str_aux */ + mpfr_set_prec (x, 100); + mpfr_set_str_binary (x, "0.1001011111010001101110010101010101111001010111111101101101100110100011110110000101110110001011110000E-9"); + s = mpfr_get_str (NULL, &e, 3, 2, x, MPFR_RNDU); + if (strcmp (s, "22") || (e != -6)) + { + printf ("Error in mpfr_get_str: 100-bit number rounded up with" + " 2 digits in base 3\n"); + exit (1); + } + mpfr_free_str (s); + + /* check corner case exact=0 in mpfr_get_str_aux */ + mpfr_set_prec (x, 100); + mpfr_set_str_binary (x, "0.1001001111101101111000101000110111111010101100000110010001111111011001101011101100001100110000000000E8"); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDZ); + if (strcmp (s, "14") || (e != 3)) + { + printf ("Error in mpfr_get_str: 100-bit number rounded to zero with" + " 2 digits in base 10\n"); + exit (1); + } + mpfr_free_str (s); + + for (p=4; p<=200; p++) + { + mpfr_set_prec (x, p); + mpfr_set_str (x, "6.5", 10, MPFR_RNDN); + + s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN); + if (strcmp (s, "10") || (e != 2)) + { + printf ("Error in mpfr_get_str: 6.5 rounded to nearest with" + " 2 digits in base 6\n"); + exit (1); + } + mpfr_free_str (s); + + mpfr_nexttoinf (x); + s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN); + if (strcmp (s, "11") || (e != 2)) + { + printf ("Error in mpfr_get_str: 6.5+ rounded to nearest with" + " 2 digits in base 6\ngot %se%d instead of 11e2\n", + s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str (x, "6.5", 10, MPFR_RNDN); + mpfr_nexttozero (x); + s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN); + if (strcmp (s, "10") || (e != 2)) + { + printf ("Error in mpfr_get_str: 6.5- rounded to nearest with" + " 2 digits in base 6\n"); + exit (1); + } + mpfr_free_str (s); + } + + mpfr_set_prec (x, 3); + mpfr_set_ui (x, 7, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 2, 2, x, MPFR_RNDU); + if (strcmp (s, "10") || (e != 4)) + { + printf ("Error in mpfr_get_str: 7 rounded up with 2 bits should" + " give 0.10e3 instead of 0.%s*2^%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* problem found by Fabrice Rouillier */ + mpfr_set_prec (x, 63); + mpfr_set_str (x, "5e14", 10, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU); + mpfr_free_str (s); + + /* bug found by Johan Vervloet */ + mpfr_set_prec (x, 6); + mpfr_set_str (x, "688.0", 10, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 2, 4, x, MPFR_RNDU); + if (strcmp (s, "1011") || (e != 10)) + { + printf ("Error in mpfr_get_str: 688 printed up to 4 bits should" + " give 1.011e9\ninstead of "); + mpfr_out_str (stdout, 2, 4, x, MPFR_RNDU); + puts (""); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 38); + mpfr_set_str_binary (x, "1.0001110111110100011010100010010100110e-6"); + s = mpfr_get_str (NULL, &e, 8, 10, x, MPFR_RNDU); + if (strcmp (s, "1073721522") || (e != -1)) + { + printf ("Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 53); + mpfr_set_str_binary (x, "0.11010111011101100010000100010101110001000000010111001E454"); + s = mpfr_get_str (NULL, &e, 19, 12, x, MPFR_RNDU); + if (strcmp (s, "b1cgfa4gha0h") || (e != 107)) + { + printf ("Error in mpfr_get_str (4): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 145); + mpfr_set_str_binary (x, "-0.1000110011000001011000010101101010110110101100101110100011111100011110011001001001010000100001000011000011000000010111011001000111101001110100110e6"); + s = mpfr_get_str (NULL, &e, 4, 53, x, MPFR_RNDU); + if (strcmp (s, "-20303001120111222312230232203330132121021100201003003") || (e != 3)) + { + printf ("Error in mpfr_get_str (5): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 45); + mpfr_set_str_binary (x, "-0.00100111010110010001011001110111010001010010010"); + s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN); + if (strcmp (s, "-4tchctq54") || (e != 0)) + { + printf ("Error in mpfr_get_str (6): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* worst case found by Vincent Lefe`vre */ + mpfr_set_prec (x, 53); + mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E164"); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN); + if (strcmp (s, "13076622631878654") || (e != 66)) + { + printf ("Error in mpfr_get_str (7): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10000001001001001100011101010011011011111000011000100E93"); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU); + if (strcmp (s, "46") || e != 44) + { + printf ("Error in mpfr_get_str (8): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10010001111100000111001111010101001010000010111010101E55"); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN); + if (strcmp (s, "19") || e != 33) + { + printf ("Error in mpfr_get_str (9): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "11011001010010111110010101101100111110111000010110110E44"); + s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDN); + if (strcmp (s, "135") || e != 30) + { + printf ("Error in mpfr_get_str (10): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "11101111101000001011100001111000011111101111011001100E72"); + s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDN); + if (strcmp (s, "3981") || e != 38) + { + printf ("Error in mpfr_get_str (11): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10011001001100100010111100001101110101001001111110000E46"); + s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDN); + if (strcmp (s, "37930") || e != 30) + { + printf ("Error in mpfr_get_str (12): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10001100110111001011011110011011011101100011010001011E-72"); + s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDN); + if (strcmp (s, "104950") || e != -5) + { + printf ("Error in mpfr_get_str (13): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "10100100001011001000011001101101000110100110000010111E89"); + s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN); + if (strcmp (s, "3575392") || e != 43) + { + printf ("Error in mpfr_get_str (14): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "11000011011110110010100110001010000001010011001011001E-73"); + s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN); + if (strcmp (s, "72822386") || e != -6) + { + printf ("Error in mpfr_get_str (15): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "10101010001101000111001100001000100011100010010001010E78"); + s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN); + if (strcmp (s, "180992873") || e != 40) + { + printf ("Error in mpfr_get_str (16): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "10110111001000100000001101111001100101101110011011101E91"); + s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDN); + if (strcmp (s, "1595312255") || e != 44) + { + printf ("Error in mpfr_get_str (17): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E93"); + s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDN); + if (strcmp (s, "54835744350") || e != 44) + { + printf ("Error in mpfr_get_str (18): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E92"); + s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDN); + if (strcmp (s, "274178721752") || e != 44) + { + printf ("Error in mpfr_get_str (19): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E91"); + s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDN); + if (strcmp (s, "1370893608762") || e != 44) + { + printf ("Error in mpfr_get_str (20): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "10010011010110011100010010100101100011101000011111111E92"); + s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN); + if (strcmp (s, "25672105101864") || e != 44) + { + printf ("Error in mpfr_get_str (21): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "100110111110110001000101110100100101101000011111001E87"); + s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN); + if (strcmp (s, "212231308858721") || e != 42) + { + printf ("Error in mpfr_get_str (22): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10111010110000111000101100101111001011011100101001111E-128"); + s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN); + if (strcmp (s, "193109287087290") || e != -22) + { + printf ("Error in mpfr_get_str (22b): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "10001101101011010001111110000111010111010000110101010E80"); + s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN); + if (strcmp (s, "6026241735727920") || e != 40) + { + printf ("Error in mpfr_get_str (23): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "100010001011101001110101000110011001001000110001001E-81"); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN); + if (strcmp (s, "49741483709103481") || e != -9) + { + printf ("Error in mpfr_get_str (24): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "11000100001001001110111010011001111001001010110101111E-101"); + s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN); + if (strcmp (s, "2722049") || e != -14) + { + printf ("Error in mpfr_get_str (25): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-135"); + s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN); + if (strcmp (s, "20138772") || e != -24) + { + printf ("Error in mpfr_get_str (26): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-136"); + s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN); + if (strcmp (s, "100693858") || e != -24) + { + printf ("Error in mpfr_get_str (27): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10001000001110010110001011111011111011011010000110001E-110"); + s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN); + if (strcmp (s, "36923634350619") || e != -17) + { + printf ("Error in mpfr_get_str (28): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "11001100010111000111100010000110011101110001000101111E-87"); + s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN); + if (strcmp (s, "4646636036100804") || e != -10) + { + printf ("Error in mpfr_get_str (29): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "10011111001111110100001001010111111011010101111111000E-99"); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN); + if (strcmp (s, "88399901882446712") || e != -14) + { + printf ("Error in mpfr_get_str (30): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 8116315218207718*2^(-293) ~ 0.5100000000000000000015*10^(-72) */ + mpfr_set_str_binary (x, "11100110101011011111011100101011101110110001111100110E-293"); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU); + if (strcmp (s, "52") || e != -72) + { + printf ("Error in mpfr_get_str (31u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD); + if (strcmp (s, "51") || e != -72) + { + printf ("Error in mpfr_get_str (31d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 6712731423444934*2^536 ~ .151000000000000000000067*10^178 */ + mpfr_set_str_binary (x, "10111110110010011000110010011111101111000111111000110E536"); + s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDU); + if (strcmp (s, "152") || e != 178) + { + printf ("Error in mpfr_get_str (32u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDD); + if (strcmp (s, "151") || e != 178) + { + printf ("Error in mpfr_get_str (32d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 3356365711722467*2^540 ~ .120800000000000000000054*10^179 */ + mpfr_set_str_binary (x, "1011111011001001100011001001111110111100011111100011E540"); + s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDU); + if (strcmp (s, "1209") || e != 179) + { + printf ("Error in mpfr_get_str (33u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDD); + if (strcmp (s, "1208") || e != 179) + { + printf ("Error in mpfr_get_str (33d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 6475049196144587*2^100 ~ .8208099999999999999999988*10^46 */ + mpfr_set_str_binary (x, "10111000000010000010111011111001111010100011111001011E100"); + s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDU); + if (strcmp (s, "82081") || e != 46) + { + printf ("Error in mpfr_get_str (34u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDD); + if (strcmp (s, "82080") || e != 46) + { + printf ("Error in mpfr_get_str (34d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 6722280709661868*2^364 ~ .25260100000000000000000012*10^126 */ + mpfr_set_str_binary (x, "10111111000011110000011110001110001111010010010101100E364"); + s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDU); + if (strcmp (s, "252602") || e != 126) + { + printf ("Error in mpfr_get_str (35u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDD); + if (strcmp (s, "252601") || e != 126) + { + printf ("Error in mpfr_get_str (35d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 5381065484265332*2^(-455) ~ .578389299999999999999999982*10^(-121) */ + mpfr_set_str_binary (x, "10011000111100000110011110000101100111110011101110100E-455"); + s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDU); + if (strcmp (s, "5783893") || e != -121) + { + printf ("Error in mpfr_get_str (36u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDD); + if (strcmp (s, "5783892") || e != -121) + { + printf ("Error in mpfr_get_str (36d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 8369123604277281*2^(-852) ~ .27869147000000000000000000056*10^(-240) */ + mpfr_set_str_binary (x, "11101101110111010110001101111100000111010100000100001E-852"); + s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDU); + if (strcmp (s, "27869148") || e != -240) + { + printf ("Error in mpfr_get_str (37u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDD); + if (strcmp (s, "27869147") || e != -240) + { + printf ("Error in mpfr_get_str (37d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 7976538478610756*2^377 ~ .245540326999999999999999999982*10^130 */ + mpfr_set_str_binary (x, "11100010101101001111010010110100011100000100101000100E377"); + s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDU); + if (strcmp (s, "245540327") || e != 130) + { + printf ("Error in mpfr_get_str (38u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDD); + if (strcmp (s, "245540326") || e != 130) + { + printf ("Error in mpfr_get_str (38d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 8942832835564782*2^(-382) ~ .9078555839000000000000000000038*10^(-99) */ + mpfr_set_str_binary (x, "11111110001010111010110000110011100110001010011101110E-382"); + s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDU); + if (strcmp (s, "9078555840") || e != -99) + { + printf ("Error in mpfr_get_str (39u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDD); + if (strcmp (s, "9078555839") || e != -99) + { + printf ("Error in mpfr_get_str (39d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 4471416417782391*2^(-380) ~ .18157111678000000000000000000077*10^(-98) */ + mpfr_set_str_binary (x, "1111111000101011101011000011001110011000101001110111E-380"); + s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDU); + if (strcmp (s, "18157111679") || e != -98) + { + printf ("Error in mpfr_get_str (40u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDD); + if (strcmp (s, "18157111678") || e != -98) + { + printf ("Error in mpfr_get_str (40d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 7225450889282194*2^711 ~ .778380362292999999999999999999971*10^230 */ + mpfr_set_str_binary (x, "11001101010111000001001100001100110010000001010010010E711"); + s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDU); + if (strcmp (s, "778380362293") || e != 230) + { + printf ("Error in mpfr_get_str (41u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDD); + if (strcmp (s, "778380362292") || e != 230) + { + printf ("Error in mpfr_get_str (41d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 3612725444641097*2^713 ~ .1556760724585999999999999999999942*10^231 */ + mpfr_set_str_binary (x, "1100110101011100000100110000110011001000000101001001E713"); + s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDU); + if (strcmp (s, "1556760724586") || e != 231) + { + printf ("Error in mpfr_get_str (42u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDD); + if (strcmp (s, "1556760724585") || e != 231) + { + printf ("Error in mpfr_get_str (42d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 6965949469487146*2^(-248) ~ .15400733123779000000000000000000016*10^(-58) */ + mpfr_set_str_binary (x, "11000101111110111111001111111101001101111000000101010E-248"); + s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDU); + if (strcmp (s, "15400733123780") || e != -58) + { + printf ("Error in mpfr_get_str (43u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDD); + if (strcmp (s, "15400733123779") || e != -58) + { + printf ("Error in mpfr_get_str (43d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 3482974734743573*2^(-244) ~ .12320586499023200000000000000000013*10^(-57) */ + mpfr_set_str_binary (x, "1100010111111011111100111111110100110111100000010101E-244"); + s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDU); + if (strcmp (s, "123205864990233") || e != -57) + { + printf ("Error in mpfr_get_str (44u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDD); + if (strcmp (s, "123205864990232") || e != -57) + { + printf ("Error in mpfr_get_str (44d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 7542952370752766*2^(-919) ~ .170206189963739699999999999999999974*10^(-260) */ + mpfr_set_str_binary (x, "11010110011000100011001110100100111011100110011111110E-919"); + s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDU); + if (strcmp (s, "1702061899637397") || e != -260) + { + printf ("Error in mpfr_get_str (45u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDD); + if (strcmp (s, "1702061899637396") || e != -260) + { + printf ("Error in mpfr_get_str (45d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + /* 5592117679628511*2^165 ~ .26153245263757307000000000000000000074*10^66 */ + mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E165"); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDU); + if (strcmp (s, "26153245263757308") || e != 66) + { + printf ("Error in mpfr_get_str (46u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDD); + if (strcmp (s, "26153245263757307") || e != 66) + { + printf ("Error in mpfr_get_str (46d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "11010010110111100001011010000110010000100001011011101E1223"); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN); + if (strcmp (s, "10716284017294180") || e != 385) + { + printf ("Error in mpfr_get_str (47n): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU); + if (strcmp (s, "107162840172941805") || e != 385) + { + printf ("Error in mpfr_get_str (47u): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD); + if (strcmp (s, "107162840172941804") || e != 385) + { + printf ("Error in mpfr_get_str (47d): s=%s e=%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_str_binary (x, "11111101111011000001010100001101101000010010001111E122620"); + s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN); + if (strcmp (s, "22183435284042374") || e != 36928) + { + printf ("Error in mpfr_get_str (48n): s=%s e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU); + if (strcmp (s, "221834352840423736") || e != 36928) + { + printf ("Error in mpfr_get_str (48u): s=%s e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD); + if (strcmp (s, "221834352840423735") || e != 36928) + { + printf ("Error in mpfr_get_str (48d): s=%s e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 45); + mpfr_set_str_binary (x, "1E45"); + s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN); + mpfr_free_str (s); + + mpfr_set_prec (x, 7); + mpfr_set_str_binary (x, "0.1010101E10"); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU); + mpfr_free_str (s); + + /* checks rounding of negative numbers */ + mpfr_set_prec (x, 7); + mpfr_set_str (x, "-11.5", 10, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD); + if (strcmp (s, "-12")) + { + printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDD\n" + "got %s instead of -12\n", s); + exit (1); + } + mpfr_free_str (s); + + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU); + if (strcmp (s, "-11")) + { + printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDU\n"); + exit (1); + } + mpfr_free_str (s); + + /* bug found by Jean-Pierre Merlet, produced error in mpfr_get_str */ + mpfr_set_prec (x, 128); + mpfr_set_str_binary (x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3"); + s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDU); + mpfr_free_str (s); + + mpfr_set_prec (x, 381); + mpfr_set_str_binary (x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010"); + s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDD); + if (e != 0) + { + printf ("Error in mpfr_get_str for x=0.999999..., exponent is %d" + " instead of 0\n", (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 5); + mpfr_set_str_binary (x, "1101.1"); /* 13.5, or (16)_7 + 1/2 */ + s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN); + /* we are in the tie case: both surrounding numbers are (16)_7 and + (20)_7: since (16)_7 = 13 is odd and (20)_7 = 14 is even, + we should have s = "20" and e = 2 */ + if (e != 2 || strcmp (s, "20")) + { + printf ("Error in mpfr_get_str for x=13.5, base 7\n"); + printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + /* try the same example, with input just below or above 13.5 */ + mpfr_set_prec (x, 1000); + mpfr_set_str_binary (x, "1101.1"); + mpfr_nextabove (x); + s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN); + if (e != 2 || strcmp (s, "20")) + { + printf ("Error in mpfr_get_str for x=13.5+tiny, base 7\n"); + printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "1101.1"); + mpfr_nextbelow (x); + s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN); + if (e != 2 || strcmp (s, "16")) + { + printf ("Error in mpfr_get_str for x=13.5-tiny, base 7\n"); + printf ("Expected s=16, e=2, got s=%s, e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_prec (x, 7); + mpfr_set_str_binary (x, "110000.1"); /* 48.5, or (66)_7 + 1/2 */ + s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN); + /* we are in the tie case: both surrounding numbers are (66)_7 and + (100)_7: since (66)_7 = 48 is even and (100)_7 is odd, + we should hase s = "66" and e = 2 */ + if (e != 2 || strcmp (s, "66")) + { + printf ("Error in mpfr_get_str for x=48.5, base 7\n"); + printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + /* try the same example, with input just below or above 48.5 */ + mpfr_set_prec (x, 1000); + mpfr_set_str_binary (x, "110000.1"); + mpfr_nextabove (x); + s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN); + if (e != 3 || strcmp (s, "10")) + { + printf ("Error in mpfr_get_str for x=48.5+tiny, base 7\n"); + printf ("Expected s=10, e=3, got s=%s, e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + mpfr_set_str_binary (x, "110000.1"); + mpfr_nextbelow (x); + s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN); + if (e != 2 || strcmp (s, "66")) + { + printf ("Error in mpfr_get_str for x=48.5-tiny, base 7\n"); + printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_clear (x); +} + +/* bugs found by Alain Delplanque */ +static void +check_large (void) +{ + mpfr_t x; + char *s, s1[7]; + const char xm[] = { '1', '1', '9', '1', '3', '2', '9', '3', '7', '3', + '5', '8', '4', '4', '5', '4', '9', '0', '2', '9', + '6', '3', '4', '4', '6', '9', '9', '1', '9', '5', + '5', '7', '2', '0', '1', '7', '5', '2', '8', '6', + '1', '2', '5', '2', '5', '2', '7', '4', '0', '2', + '7', '9', '1', '1', '7', '4', '5', '6', '7', '5', + '9', '3', '1', '4', '2', '5', '5', '6', '6', '6', + '1', '6', '4', '3', '8', '1', '2', '8', '7', '6', + '2', '9', '2', '0', '8', '8', '9', '4', '3', '9', + '6', '2', '8', '4', '1', '1', '8', '1', '0', '6', + '2', '3', '7', '6', '3', '8', '1', '5', '1', '7', + '3', '4', '6', '1', '2', '4', '0', '1', '3', '0', + '8', '4', '1', '3', '9', '3', '2', '0', '1', '6', + '3', '6', '7', '1', '5', '1', '7', '5', '0', '1', + '9', '8', '4', '0', '8', '2', '7', '9', '1', '3', + '2', '2', '8', '3', '4', '1', '6', '2', '3', '9', + '6', '2', '0', '7', '3', '5', '5', '5', '3', '4', + '2', '1', '7', '0', '9', '7', '6', '2', '1', '0', + '3', '3', '5', '4', '7', '6', '0', '9', '7', '6', + '9', '3', '5', '1', '7', '8', '6', '8', '8', '2', + '8', '1', '4', '3', '7', '4', '3', '3', '2', '4', + '1', '5', '4', '7', '8', '1', '1', '4', '2', '1', + '2', '4', '2', '7', '6', '5', '9', '5', '4', '5', + '2', '6', '7', '3', '0', '3', '4', '0', '6', '9', + '1', '8', '9', '9', '9', '8', '0', '5', '7', '0', + '9', '3', '8', '7', '6', '2', '4', '6', '1', '6', + '7', '2', '0', '3', '5', '9', '3', '5', '8', '8', + '9', '7', '7', '9', '2', '7', '0', '8', '1', '6', + '8', '7', '4', '8', '5', '3', '0', '8', '4', '3', + '5', '6', '5', '1', '6', '6', '0', '9', '7', '9', + '8', '9', '2', '7', '2', '6', '8', '5', '9', '4', + '5', '8', '1', '3', '7', '2', '9', '3', '8', '3', + '7', '9', '1', '7', '9', '9', '7', '7', '2', '8', + '4', '6', '5', '5', '7', '3', '3', '8', '3', '6', + '6', '9', '7', '1', '4', '3', '3', '7', '1', '4', + '9', '4', '1', '2', '4', '9', '5', '1', '4', '7', + '2', '6', '4', '4', '8', '0', '6', '2', '6', '0', + '6', '9', '8', '1', '1', '7', '9', '9', '3', '9', + '3', '8', '4', '7', '3', '1', '9', '0', '2', '3', + '5', '3', '5', '4', '2', '1', '1', '7', '6', '7', + '4', '3', '2', '2', '0', '6', '5', '9', '9', '3', + '2', '6', '7', '1', '2', '0', '0', '3', '7', '3', + '8', '7', '4', '3', '3', '3', '3', '3', '2', '3', + '8', '2', '8', '6', '3', '1', '5', '5', '2', '2', + '5', '9', '3', '3', '7', '0', '6', '2', '8', '1', + '0', '3', '6', '7', '6', '9', '6', '5', '9', '0', + '6', '6', '6', '3', '6', '9', '9', '3', '8', '7', + '6', '5', '4', '5', '3', '5', '9', '4', '0', '0', + '7', '5', '8', '5', '4', '1', '4', '3', '1', '5', + '7', '6', '6', '3', '4', '4', '5', '0', '8', '7', + '5', '7', '5', '0', '1', '0', '1', '8', '4', '7', + '3', '1', '9', '9', '2', '7', '1', '1', '1', '2', + '3', '9', '9', '6', '5', '9', '2', '3', '2', '8', + '1', '5', '5', '1', '2', '6', '4', '9', '6', '6', + '4', '5', '1', '1', '6', '0', '0', '3', '2', '8', + '4', '8', '7', '1', '4', '9', '6', '8', '1', '6', + '5', '9', '8', '3', '4', '2', '9', '7', '0', '1', + '9', '2', '6', '6', '9', '1', '3', '5', '9', '3', + '2', '9', '6', '2', '3', '0', '6', '0', '1', '1', + '6', '5', '1', '7', '9', '0', '7', '5', '8', '6', + '8', '4', '2', '1', '0', '3', '8', '6', '6', '4', + '4', '9', '9', '7', '5', '8', '1', '7', '5', '7', + '9', '6', '6', '8', '8', '5', '8', '6', '7', '4', + '0', '7', '2', '0', '2', '9', '9', '4', '4', '1', + '9', '5', '8', '6', '5', '0', '6', '7', '4', '2', + '7', '3', '2', '3', '2', '7', '0', '2', '1', '3', + '0', '5', '9', '0', '3', '9', '1', '4', '5', '3', + '7', '2', '7', '0', '8', '5', '5', '4', '6', '1', + '1', '0', '0', '9', '2', '0', '4', '1', '6', '6', + '4', '6', '9', '1', '3', '2', '8', '5', '0', '3', + '3', '8', '9', '8', '7', '8', '5', '9', '5', '5', + '9', '1', '9', '3', '6', '5', '4', '1', '7', '4', + '0', '2', '4', '7', '2', '9', '7', '1', '2', '4', + '5', '8', '1', '4', '4', '6', '1', '8', '5', '8', + '7', '6', '9', '7', '2', '1', '2', '0', '8', '9', + '5', '9', '5', '5', '3', '8', '1', '2', '5', '4', + '3', '0', '7', '6', '5', '1', '7', '8', '2', '0', + '0', '7', '6', '7', '4', '8', '1', '0', '6', '3', + '2', '3', '0', '5', '2', '5', '0', '1', '1', '4', + '3', '8', '4', '5', '2', '3', '9', '5', '0', '9', + '8', '2', '6', '4', '7', '4', '8', '0', '1', '1', + '7', '1', '5', '4', '9', '0', '9', '2', '2', '3', + '8', '1', '6', '9', '0', '4', '6', '4', '5', '4', + '6', '3', '8', '7', '3', '6', '1', '7', '2', '3', + '4', '5', '5', '2', '0', '2', '5', '8', '1', '4', + '9', '3', '0', '7', '4', '1', '6', '8', '7', '8', + '2', '6', '2', '5', '1', '0', '7', '4', '7', '3', + '6', '6', '4', '5', '6', '6', '6', '6', '8', '5', + '1', '3', '5', '7', '1', '6', '2', '0', '9', '2', + '3', '2', '6', '0', '7', '9', '8', '1', '6', '2', + '0', '3', '8', '8', '0', '2', '8', '7', '7', '5', + '9', '3', '1', '0', '6', '7', '5', '7', '3', '1', + '2', '7', '7', '2', '0', '0', '4', '1', '2', '8', + '2', '0', '8', '4', '0', '5', '0', '5', '0', '1', + '9', '3', '3', '6', '3', '6', '9', '6', '2', '8', + '2', '9', '7', '5', '3', '8', '8', '9', '1', '1', + '4', '5', '7', '7', '5', '6', '0', '2', '7', '9', + '7', '2', '1', '7', '4', '3', '0', '3', '6', '7', + '3', '7', '2', '2', '7', '5', '6', '2', '3', '1', + '2', '1', '3', '1', '4', '2', '6', '9', '2', '3', + '\0' }; + mpfr_exp_t e; + + mpfr_init2 (x, 3322); + mpfr_set_str (x, xm, 10, MPFR_RNDN); + mpfr_div_2exp (x, x, 4343, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN); + if (s[999] != '1') /* s must be 5.04383...689071e-309 */ + { + printf ("Error in check_large: expected '689071', got '%s'\n", + s + 994); + exit (1); + } + mpfr_free_str (s); + + mpfr_mul_2exp (x, x, 4343, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN); + if (strcmp (s, "12") || (e != 1000)) + { + printf ("Error in check_large: expected 0.12e1000\n"); + printf ("got %se%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + + mpfr_set_nan (x); + s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN); + if (strcmp (s, "@NaN@")) + { + printf ("Error for NaN\n"); + exit (1); + } + mpfr_free_str (s); + + mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN); + + mpfr_set_inf (x, 1); + s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN); + if (strcmp (s, "@Inf@")) + { + printf ("Error for Inf\n"); + exit (1); + } + mpfr_free_str (s); + + mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN); + + mpfr_set_inf (x, -1); + s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN); + if (strcmp (s, "-@Inf@")) + { + printf ("Error for -Inf\n"); + exit (1); + } + mpfr_free_str (s); + + mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN); + + mpfr_set_ui (x, 0, MPFR_RNDN); + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN); + if (e != 0 || strcmp (s, "00")) + { + printf ("Error for 0.0\n"); + exit (1); + } + mpfr_free_str (s); + mpfr_get_str (s1, &e, 10, 2, x, MPFR_RNDN); + + mpfr_neg (x, x, MPFR_RNDN); /* -0.0 */ + s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN); + if (e != 0 || strcmp (s, "-00")) + { + printf ("Error for -0.0\ngot %se%d\n", s, (int) e); + exit (1); + } + mpfr_free_str (s); + mpfr_get_str (s1, &e, 10, 2, x, MPFR_RNDN); + + mpfr_clear (x); +} + +#define MAX_DIGITS 100 + +static void +check_special (int b, mpfr_prec_t p) +{ + mpfr_t x; + int i, j; + char s[MAX_DIGITS + 2], s2[MAX_DIGITS + 2], c; + mpfr_exp_t e; + int r; + size_t m; + + /* check for invalid base */ + if (mpfr_get_str (s, &e, 1, 10, x, MPFR_RNDN) != NULL) + { + printf ("Error: mpfr_get_str should not accept base = 1\n"); + exit (1); + } + if (mpfr_get_str (s, &e, 63, 10, x, MPFR_RNDN) != NULL) + { + printf ("Error: mpfr_get_str should not accept base = 63\n"); + exit (1); + } + + s2[0] = '1'; + for (i=1; i<MAX_DIGITS+2; i++) + s2[i] = '0'; + + mpfr_init2 (x, p); + mpfr_set_ui (x, 1, MPFR_RNDN); + for (i=1; i<MAX_DIGITS && mpfr_mul_ui (x, x, b, MPFR_RNDN) == 0; i++) + { + /* x = b^i (exact) */ + for (r = 0; r < MPFR_RND_MAX; r++) + for (m= (i<3)? 2 : i-1 ; (int) m <= i+1 ; m++) + { + mpfr_get_str (s, &e, b, m, x, (mpfr_rnd_t) r); + /* s should be 1 followed by (m-1) zeros, and e should be i+1 */ + if ((e != i+1) || strncmp (s, s2, m) != 0) + { + printf ("Error in mpfr_get_str for %d^%d\n", b, i); + exit (1); + } + } + if (mpfr_sub_ui (x, x, 1, MPFR_RNDN) != 0) + break; + /* now x = b^i-1 (exact) */ + for (r = 0; r < MPFR_RND_MAX; r++) + if (i >= 2) + { + mpfr_get_str (s, &e, b, i, x, (mpfr_rnd_t) r); + /* should be i times (b-1) */ + c = (b <= 10) ? '0' + b - 1 : 'a' + (b - 11); + for (j=0; (j < i) && (s[j] == c); j++); + if ((j < i) || (e != i)) + { + printf ("Error in mpfr_get_str for %d^%d-1\n", b, i); + printf ("got 0.%s*2^%d\n", s, (int) e); + exit (1); + } + } + if (i >= 3) + { + mpfr_get_str (s, &e, b, i - 1, x, MPFR_RNDU); + /* should be b^i */ + if ((e != i+1) || strncmp (s, s2, i - 1) != 0) + { + printf ("Error in mpfr_get_str for %d^%d-1\n", b, i); + printf ("got 0.%s*2^%d\n", s, (int) e); + exit (1); + } + } + + mpfr_add_ui (x, x, 1, MPFR_RNDN); + } + mpfr_clear (x); +} + +static void +check_bug_base2k (void) +{ + /* + * -2.63b22b55697e800000000000@130 + * +-0.1001100011101100100010101101010101011010010111111010000000000000000000000000+00000000000000000000001E522 + */ + mpfr_t xx, yy, zz; + char *s; + mpfr_exp_t e; + + mpfr_init2 (xx, 107); + mpfr_init2 (yy, 79); + mpfr_init2 (zz, 99); + + mpfr_set_str (xx, "-1.90e8c3e525d7c0000000000000@-18", 16, MPFR_RNDN); + mpfr_set_str (yy, "-2.63b22b55697e8000000@130", 16, MPFR_RNDN); + mpfr_add (zz, xx, yy, MPFR_RNDD); + s = mpfr_get_str (NULL, &e, 16, 0, zz, MPFR_RNDN); + if (strcmp (s, "-263b22b55697e8000000000008")) + { + printf ("Error for get_str base 16\n" + "Got %s expected -263b22b55697e8000000000008\n", s); + exit (1); + } + mpfr_free_str (s); + mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); +} + +static void +check_reduced_exprange (void) +{ + mpfr_t x; + char *s; + mpfr_exp_t emax, e; + + emax = mpfr_get_emax (); + mpfr_init2 (x, 8); + mpfr_set_str (x, "0.11111111E0", 2, MPFR_RNDN); + set_emax (0); + s = mpfr_get_str (NULL, &e, 16, 0, x, MPFR_RNDN); + set_emax (emax); + if (strcmp (s, "ff0")) + { + printf ("Error for mpfr_get_str on 0.11111111E0 in base 16:\n" + "Got \"%s\" instead of \"ff0\".\n", s); + exit (1); + } + mpfr_free_str (s); + mpfr_clear (x); +} + +#define ITER 1000 + +int +main (int argc, char *argv[]) +{ + int b; + mpfr_t x; + mpfr_rnd_t r; + char s[MAX_DIGITS + 2]; + mpfr_exp_t e, f; + size_t m; + mpfr_prec_t p; + int i; + + tests_start_mpfr (); + + check_small (); + + check_special (2, 2); + for (i = 0; i < ITER; i++) + { + p = 2 + (randlimb () % (MAX_DIGITS - 1)); + b = 2 + (randlimb () % 35); + check_special (b, p); + } + + mpfr_init2 (x, MAX_DIGITS); + for (i = 0; i < ITER; i++) + { + m = 2 + (randlimb () % (MAX_DIGITS - 1)); + mpfr_urandomb (x, RANDS); + e = (mpfr_exp_t) (randlimb () % 21) - 10; + mpfr_set_exp (x, (e == -10) ? mpfr_get_emin () : + ((e == 10) ? mpfr_get_emax () : e)); + b = 2 + (randlimb () % 35); + r = RND_RAND (); + mpfr_get_str (s, &f, b, m, x, r); + } + mpfr_clear (x); + + check_large (); + check3 ("4.059650008e-83", MPFR_RNDN, "40597"); + check3 ("-6.606499965302424244461355e233", MPFR_RNDN, "-66065"); + check3 ("-7.4", MPFR_RNDN, "-74000"); + check3 ("0.997", MPFR_RNDN, "99700"); + check3 ("-4.53063926135729747564e-308", MPFR_RNDN, "-45306"); + check3 ("2.14478198760196000000e+16", MPFR_RNDN, "21448"); + check3 ("7.02293374921793516813e-84", MPFR_RNDN, "70229"); + + check3 ("-6.7274500420134077e-87", MPFR_RNDN, "-67275"); + check3 ("-6.7274500420134077e-87", MPFR_RNDZ, "-67274"); + check3 ("-6.7274500420134077e-87", MPFR_RNDU, "-67274"); + check3 ("-6.7274500420134077e-87", MPFR_RNDD, "-67275"); + check3 ("-6.7274500420134077e-87", MPFR_RNDA, "-67275"); + + check3 ("6.7274500420134077e-87", MPFR_RNDN, "67275"); + check3 ("6.7274500420134077e-87", MPFR_RNDZ, "67274"); + check3 ("6.7274500420134077e-87", MPFR_RNDU, "67275"); + check3 ("6.7274500420134077e-87", MPFR_RNDD, "67274"); + check3 ("6.7274500420134077e-87", MPFR_RNDA, "67275"); + + check_bug_base2k (); + check_reduced_exprange (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tget_z.c b/mpfr/tests/tget_z.c new file mode 100644 index 0000000000..ff6bda41b8 --- /dev/null +++ b/mpfr/tests/tget_z.c @@ -0,0 +1,201 @@ +/* Test file for mpz_set_fr / mpfr_get_z. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check_diff (void) +{ + int inex; + mpfr_t x; + mpz_t z; + mpfr_exp_t emin; + + mpz_init (z); + mpfr_init2 (x, 2); + + mpfr_set_ui (x, 2047, MPFR_RNDU); + mpz_set_fr (z, x, MPFR_RNDN); + if (mpz_cmp_ui (z, 2048) != 0) + { + printf ("get_z RU 2048 failed\n"); + exit (1); + } + + mpfr_set_prec (x, 6); + mpfr_set_str (x, "17.5", 10, MPFR_RNDN); + inex = mpfr_get_z (z, x, MPFR_RNDN); + if (inex <= 0 || mpz_cmp_ui (z, 18) != 0) + { + printf ("get_z RN 17.5 failed\n"); + exit (1); + } + + /* save default emin */ + emin = mpfr_get_emin ();; + + mpfr_set_emin (17); + mpfr_set_ui (x, 0, MPFR_RNDN); + inex = mpfr_get_z (z, x, MPFR_RNDN); + if (inex != 0 || mpz_cmp_ui (z, 0) != 0) + { + printf ("get_z 0 failed\n"); + exit (1); + } + + /* restore default emin */ + mpfr_set_emin (emin); + + mpfr_clear (x); + mpz_clear (z); +} + +static void +check_one (mpz_ptr z) +{ + int inex; + int sh, neg; + mpfr_t f; + mpz_t got; + + mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) ); + mpz_init (got); + + for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++) + { + for (neg = 0; neg <= 1; neg++) + { + mpz_neg (z, z); + mpfr_set_z (f, z, MPFR_RNDN); + + if (sh < 0) + { + mpz_tdiv_q_2exp (z, z, -sh); + mpfr_div_2exp (f, f, -sh, MPFR_RNDN); + } + else + { + mpz_mul_2exp (z, z, sh); + mpfr_mul_2exp (f, f, sh, MPFR_RNDN); + } + + inex = mpfr_get_z (got, f, MPFR_RNDZ); + + if (mpz_cmp (got, z) != 0) + { + printf ("Wrong result for shift=%d\n", sh); + printf (" f "); mpfr_dump (f); + printf (" got "); mpz_dump (got); + printf (" want "); mpz_dump (z); + exit (1); + } + if (! SAME_SIGN (inex, - mpfr_cmp_z (f, z))) + { + printf ("Wrong inexact value for shift=%d\n", sh); + printf (" f "); mpfr_dump (f); + printf (" got %+d\n", inex); + printf (" want %+d\n", -mpfr_cmp_z (f, z)); + exit (1); + } + } + } + + mpfr_clear (f); + mpz_clear (got); +} + +static void +check (void) +{ + mpz_t z; + + mpz_init (z); + + mpz_set_ui (z, 0L); + check_one (z); + + mpz_set_si (z, 123L); + check_one (z); + + mpz_rrandomb (z, RANDS, 2*GMP_NUMB_BITS); + check_one (z); + + mpz_rrandomb (z, RANDS, 5*GMP_NUMB_BITS); + check_one (z); + + mpz_clear (z); +} + +static void +special (void) +{ + int inex; + mpfr_t x; + mpz_t z; + int i; + mpfr_exp_t e; + + mpfr_init2 (x, 2); + mpz_init (z); + + for (i = -1; i <= 1; i++) + { + if (i != 0) + mpfr_set_nan (x); + else + mpfr_set_inf (x, i); + mpfr_clear_flags (); + inex = mpfr_get_z (z, x, MPFR_RNDN); + if (!mpfr_erangeflag_p () || inex != 0 || mpz_cmp_ui (z, 0) != 0) + { + printf ("special() failed on mpfr_get_z for i = %d\n", i); + exit (1); + } + mpfr_clear_flags (); + e = mpfr_get_z_2exp (z, x); + if (!mpfr_erangeflag_p () || e != __gmpfr_emin || + mpz_cmp_ui (z, 0) != 0) + { + printf ("special() failed on mpfr_get_z_2exp for i = %d\n", i); + exit (1); + } + } + + mpfr_clear (x); + mpz_clear (z); +} + +int +main (void) +{ + tests_start_mpfr (); + + check (); + check_diff (); + special (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tgmpop.c b/mpfr/tests/tgmpop.c new file mode 100644 index 0000000000..f099895be6 --- /dev/null +++ b/mpfr/tests/tgmpop.c @@ -0,0 +1,1265 @@ +/* Test file for mpfr_add_[q,z], mpfr_sub_[q,z], mpfr_div_[q,z], + mpfr_mul_[q,z], mpfr_cmp_[f,q,z] + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include "mpfr-test.h" + +#define CHECK_FOR(str, cond) \ + if ((cond) == 0) { \ + printf ("Special case error %s. Ternary value = %d, flags = %u\n", \ + str, res, __gmpfr_flags); \ + printf ("Got "); mpfr_dump (y); \ + printf ("X = "); mpfr_dump (x); \ + printf ("Q = "); mpz_dump (mpq_numref(q)); \ + printf (" /"); mpz_dump (mpq_denref(q)); \ + exit (1); \ + } + +#define CHECK_FORZ(str, cond) \ + if ((cond) == 0) { \ + printf ("Special case error %s. Ternary value = %d, flags = %u\n", \ + str, res, __gmpfr_flags); \ + printf ("Got "); mpfr_dump (y); \ + printf ("X = "); mpfr_dump (x); \ + printf ("Z = "); mpz_dump (z); \ + exit (1); \ + } + +static void +special (void) +{ + mpfr_t x, y; + mpq_t q; + mpz_t z; + int res = 0; + + mpfr_init (x); + mpfr_init (y); + mpq_init (q); + mpz_init (z); + + /* cancellation in mpfr_add_q */ + mpfr_set_prec (x, 60); + mpfr_set_prec (y, 20); + mpz_set_str (mpq_numref (q), "-187207494", 10); + mpz_set_str (mpq_denref (q), "5721", 10); + mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44"); + mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0); + + mpfr_set_prec (x, 19); + mpfr_set_str_binary (x, "0.1011110101110011100E0"); + mpz_set_str (mpq_numref (q), "187207494", 10); + mpz_set_str (mpq_denref (q), "5721", 10); + mpfr_set_prec (y, 29); + mpfr_add_q (y, x, q, MPFR_RNDD); + mpfr_set_prec (x, 29); + mpfr_set_str_binary (x, "11111111101001110011010001001E-14"); + CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0); + + /* Inf */ + mpfr_set_inf (x, 1); + mpz_set_str (mpq_numref (q), "395877315", 10); + mpz_set_str (mpq_denref (q), "3508975966", 10); + mpfr_set_prec (y, 118); + mpfr_add_q (y, x, q, MPFR_RNDU); + CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0); + mpfr_sub_q (y, x, q, MPFR_RNDU); + CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0); + + /* Nan */ + MPFR_SET_NAN (x); + mpfr_add_q (y, x, q, MPFR_RNDU); + CHECK_FOR ("nan", mpfr_nan_p (y)); + mpfr_sub_q (y, x, q, MPFR_RNDU); + CHECK_FOR ("nan", mpfr_nan_p (y)); + + /* Exact value */ + mpfr_set_prec (x, 60); + mpfr_set_prec (y, 60); + mpfr_set_str1 (x, "0.5"); + mpz_set_str (mpq_numref (q), "3", 10); + mpz_set_str (mpq_denref (q), "2", 10); + res = mpfr_add_q (y, x, q, MPFR_RNDU); + CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0); + res = mpfr_sub_q (y, x, q, MPFR_RNDU); + CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0); + + /* Inf Rationnal */ + mpq_set_ui (q, 1, 0); + mpfr_set_str1 (x, "0.5"); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0); + mpq_set_si (q, -1, 0); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0); + res = mpfr_div_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_SIGN (y) < 0 && res == 0); + mpq_set_ui (q, 1, 0); + mpfr_set_inf (x, 1); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("+Inf + +Inf", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("+Inf - +Inf", MPFR_IS_NAN (y) && res == 0); + mpfr_set_inf (x, -1); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("-Inf + +Inf", MPFR_IS_NAN (y) && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("-Inf - +Inf", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0); + mpq_set_si (q, -1, 0); + mpfr_set_inf (x, 1); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("+Inf + -Inf", MPFR_IS_NAN (y) && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("+Inf - -Inf", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0); + mpfr_set_inf (x, -1); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("-Inf + -Inf", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("-Inf - -Inf", MPFR_IS_NAN (y) && res == 0); + + /* 0 */ + mpq_set_ui (q, 0, 1); + mpfr_set_ui (x, 42, MPFR_RNDN); + res = mpfr_add_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0); + res = mpfr_sub_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0); + res = mpfr_mul_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_SIGN (y) > 0 && res == 0); + mpfr_clear_flags (); + res = mpfr_div_q (y, x, q, MPFR_RNDN); + CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0 + && mpfr_divby0_p ()); + mpz_set_ui (z, 0); + mpfr_clear_flags (); + res = mpfr_div_z (y, x, z, MPFR_RNDN); + CHECK_FORZ ("42/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0 + && mpfr_divby0_p ()); + + mpz_clear (z); + mpq_clear (q); + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_for_zero (void) +{ + /* Check that 0 is unsigned! */ + mpq_t q; + mpz_t z; + mpfr_t x; + int r; + mpfr_sign_t i; + + mpfr_init (x); + mpz_init (z); + mpq_init (q); + + mpz_set_ui (z, 0); + mpq_set_ui (q, 0, 1); + + MPFR_SET_ZERO (x); + RND_LOOP (r) + { + for (i = MPFR_SIGN_NEG ; i <= MPFR_SIGN_POS ; + i+=MPFR_SIGN_POS-MPFR_SIGN_NEG) + { + MPFR_SET_SIGN(x, i); + mpfr_add_z (x, x, z, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) + { + printf("GMP Zero errors for add_z & rnd=%s & s=%d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); + mpfr_dump (x); + exit (1); + } + mpfr_sub_z (x, x, z, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) + { + printf("GMP Zero errors for sub_z & rnd=%s & s=%d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); + mpfr_dump (x); + exit (1); + } + mpfr_mul_z (x, x, z, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) + { + printf("GMP Zero errors for mul_z & rnd=%s & s=%d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); + mpfr_dump (x); + exit (1); + } + mpfr_add_q (x, x, q, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) + { + printf("GMP Zero errors for add_q & rnd=%s & s=%d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); + mpfr_dump (x); + exit (1); + } + mpfr_sub_q (x, x, q, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) + { + printf("GMP Zero errors for sub_q & rnd=%s & s=%d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); + mpfr_dump (x); + exit (1); + } + } + } + + mpq_clear (q); + mpz_clear (z); + mpfr_clear (x); +} + +static void +test_cmp_z (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) +{ + mpfr_t x, z; + mpz_t y; + mpfr_prec_t p; + int res1, res2; + int n; + + mpfr_init (x); + mpfr_init2 (z, MPFR_PREC_MIN); + mpz_init (y); + + /* check the erange flag when x is NaN */ + mpfr_set_nan (x); + mpz_set_ui (y, 17); + mpfr_clear_erangeflag (); + res1 = mpfr_cmp_z (x, y); + if (res1 != 0 || mpfr_erangeflag_p () == 0) + { + printf ("Error for mpfr_cmp_z (NaN, 17)\n"); + printf ("Return value: expected 0, got %d\n", res1); + printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ()); + exit (1); + } + + for(p=pmin ; p < pmax ; p++) + { + mpfr_set_prec (x, p); + for ( n = 0; n < nmax ; n++) + { + mpfr_urandomb (x, RANDS); + mpz_urandomb (y, RANDS, 1024); + if (!MPFR_IS_SINGULAR (x)) + { + mpfr_sub_z (z, x, y, MPFR_RNDN); + res1 = mpfr_sgn (z); + res2 = mpfr_cmp_z (x, y); + if (res1 != res2) + { + printf("Error for mpfr_cmp_z: res=%d sub_z gives %d\n", + res2, res1); + exit (1); + } + } + } + } + mpz_clear (y); + mpfr_clear (x); + mpfr_clear (z); +} + +static void +test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) +{ + mpfr_t x, z; + mpq_t y; + mpfr_prec_t p; + int res1, res2; + int n; + + mpfr_init (x); + mpfr_init2 (z, MPFR_PREC_MIN); + mpq_init (y); + + /* check the erange flag when x is NaN */ + mpfr_set_nan (x); + mpq_set_ui (y, 17, 1); + mpfr_clear_erangeflag (); + res1 = mpfr_cmp_q (x, y); + if (res1 != 0 || mpfr_erangeflag_p () == 0) + { + printf ("Error for mpfr_cmp_q (NaN, 17)\n"); + printf ("Return value: expected 0, got %d\n", res1); + printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ()); + exit (1); + } + + for(p=pmin ; p < pmax ; p++) + { + mpfr_set_prec (x, p); + for (n = 0 ; n < nmax ; n++) + { + mpfr_urandomb (x, RANDS); + mpq_set_ui (y, randlimb (), randlimb() ); + if (!MPFR_IS_SINGULAR (x)) + { + mpfr_sub_q (z, x, y, MPFR_RNDN); + res1 = mpfr_sgn (z); + res2 = mpfr_cmp_q (x, y); + if (res1 != res2) + { + printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n", + res2, res1); + exit (1); + } + } + } + } + mpq_clear (y); + mpfr_clear (x); + mpfr_clear (z); +} + +static void +test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) +{ + mpfr_t x, z; + mpf_t y; + mpfr_prec_t p; + int res1, res2; + int n; + + mpfr_init (x); + mpfr_init2 (z, pmax+GMP_NUMB_BITS); + mpf_init2 (y, MPFR_PREC_MIN); + + /* check the erange flag when x is NaN */ + mpfr_set_nan (x); + mpf_set_ui (y, 17); + mpfr_clear_erangeflag (); + res1 = mpfr_cmp_f (x, y); + if (res1 != 0 || mpfr_erangeflag_p () == 0) + { + printf ("Error for mpfr_cmp_f (NaN, 17)\n"); + printf ("Return value: expected 0, got %d\n", res1); + printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ()); + exit (1); + } + + for(p=pmin ; p < pmax ; p+=3) + { + mpfr_set_prec (x, p); + mpf_set_prec (y, p); + for ( n = 0; n < nmax ; n++) + { + mpfr_urandomb (x, RANDS); + mpf_urandomb (y, RANDS, p); + if (!MPFR_IS_SINGULAR (x)) + { + mpfr_set_f (z, y, MPFR_RNDN); + mpfr_sub (z, x, z, MPFR_RNDN); + res1 = mpfr_sgn (z); + res2 = mpfr_cmp_f (x, y); + if (res1 != res2) + { + printf("Error for mpfr_cmp_f: res=%d sub gives %d\n", + res2, res1); + exit (1); + } + } + } + } + mpf_clear (y); + mpfr_clear (x); + mpfr_clear (z); +} + +static void +test_specialz (int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t), + void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr), + const char *op) +{ + mpfr_t x1, x2; + mpz_t z1, z2; + int res; + + mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0); + mpz_init (z1); mpz_init(z2); + mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */ + mpz_add_ui (z1, z1, 1); + mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */ + mpz_add_ui (z2, z2, 1); + + res = mpfr_set_z(x1, z1, MPFR_RNDN); + if (res) + { + printf("Specialz %s: set_z1 error\n", op); + exit(1); + } + mpfr_set_z (x2, z2, MPFR_RNDN); + if (res) + { + printf("Specialz %s: set_z2 error\n", op); + exit(1); + } + + /* (19!+1) * (20!+1) fits in a 128 bits number */ + res = mpfr_func(x1, x1, z2, MPFR_RNDN); + if (res) + { + printf("Specialz %s: wrong inexact flag.\n", op); + exit(1); + } + mpz_func(z1, z1, z2); + res = mpfr_set_z (x2, z1, MPFR_RNDN); + if (res) + { + printf("Specialz %s: set_z2 error\n", op); + exit(1); + } + if (mpfr_cmp(x1, x2)) + { + printf("Specialz %s: results differ.\nx1=", op); + mpfr_print_binary(x1); + printf("\nx2="); + mpfr_print_binary(x2); + printf ("\nZ2="); + mpz_out_str (stdout, 2, z1); + putchar('\n'); + exit(1); + } + + mpz_set_ui (z1, 1); + mpz_set_ui (z2, 0); + mpfr_set_ui (x1, 1, MPFR_RNDN); + mpz_func (z1, z1, z2); + res = mpfr_func(x1, x1, z2, MPFR_RNDN); + mpfr_set_z (x2, z1, MPFR_RNDN); + if (mpfr_cmp(x1, x2)) + { + printf("Specialz %s: results differ(2).\nx1=", op); + mpfr_print_binary(x1); + printf("\nx2="); + mpfr_print_binary(x2); + putchar('\n'); + exit(1); + } + + mpz_clear (z1); mpz_clear(z2); + mpfr_clears (x1, x2, (mpfr_ptr) 0); +} + +static void +test_special2z (int (*mpfr_func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t), + void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr), + const char *op) +{ + mpfr_t x1, x2; + mpz_t z1, z2; + int res; + + mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0); + mpz_init (z1); mpz_init(z2); + mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */ + mpz_add_ui (z1, z1, 1); + mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */ + mpz_add_ui (z2, z2, 1); + + res = mpfr_set_z(x1, z1, MPFR_RNDN); + if (res) + { + printf("Special2z %s: set_z1 error\n", op); + exit(1); + } + mpfr_set_z (x2, z2, MPFR_RNDN); + if (res) + { + printf("Special2z %s: set_z2 error\n", op); + exit(1); + } + + /* (19!+1) * (20!+1) fits in a 128 bits number */ + res = mpfr_func(x1, z1, x2, MPFR_RNDN); + if (res) + { + printf("Special2z %s: wrong inexact flag.\n", op); + exit(1); + } + mpz_func(z1, z1, z2); + res = mpfr_set_z (x2, z1, MPFR_RNDN); + if (res) + { + printf("Special2z %s: set_z2 error\n", op); + exit(1); + } + if (mpfr_cmp(x1, x2)) + { + printf("Special2z %s: results differ.\nx1=", op); + mpfr_print_binary(x1); + printf("\nx2="); + mpfr_print_binary(x2); + printf ("\nZ2="); + mpz_out_str (stdout, 2, z1); + putchar('\n'); + exit(1); + } + + mpz_set_ui (z1, 0); + mpz_set_ui (z2, 1); + mpfr_set_ui (x2, 1, MPFR_RNDN); + res = mpfr_func(x1, z1, x2, MPFR_RNDN); + mpz_func (z1, z1, z2); + mpfr_set_z (x2, z1, MPFR_RNDN); + if (mpfr_cmp(x1, x2)) + { + printf("Special2z %s: results differ(2).\nx1=", op); + mpfr_print_binary(x1); + printf("\nx2="); + mpfr_print_binary(x2); + putchar('\n'); + exit(1); + } + + mpz_clear (z1); mpz_clear(z2); + mpfr_clears (x1, x2, (mpfr_ptr) 0); +} + +static void +test_genericz (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, + int (*func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t), + const char *op) +{ + mpfr_prec_t prec; + mpfr_t arg1, dst_big, dst_small, tmp; + mpz_t arg2; + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + + mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); + mpz_init (arg2); + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (arg1, prec); + mpfr_set_prec (tmp, prec); + mpfr_set_prec (dst_small, prec); + + for (n=0; n<N; n++) + { + mpfr_urandomb (arg1, RANDS); + mpz_urandomb (arg2, RANDS, 1024); + rnd = RND_RAND (); + mpfr_set_prec (dst_big, 2*prec); + compare = func(dst_big, arg1, arg2, rnd); + if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec)) + { + mpfr_set (tmp, dst_big, rnd); + inexact = func(dst_small, arg1, arg2, rnd); + if (mpfr_cmp (tmp, dst_small)) + { + printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n" + "arg1=", + (unsigned) prec, mpfr_print_rnd_mode (rnd), op); + mpfr_print_binary (arg1); + printf("\narg2="); + mpz_out_str (stdout, 10, arg2); + printf ("\ngot "); + mpfr_dump (dst_small); + printf ("expected "); + mpfr_dump (tmp); + printf ("approx "); + mpfr_dump (dst_big); + exit (1); + } + compare2 = mpfr_cmp (tmp, dst_big); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if (compare * compare2 >= 0) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + printf ("Wrong inexact flag for rnd=%s and %s_z:\n" + "expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), op, compare, inexact); + printf ("\narg1="); mpfr_print_binary (arg1); + printf ("\narg2="); mpz_out_str(stdout, 2, arg2); + printf ("\ndstl="); mpfr_print_binary (dst_big); + printf ("\ndsts="); mpfr_print_binary (dst_small); + printf ("\ntmp ="); mpfr_dump (tmp); + exit (1); + } + } + } + } + + mpz_clear (arg2); + mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); +} + +static void +test_generic2z (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, + int (*func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t), + const char *op) +{ + mpfr_prec_t prec; + mpfr_t arg1, dst_big, dst_small, tmp; + mpz_t arg2; + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + + mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); + mpz_init (arg2); + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (arg1, prec); + mpfr_set_prec (tmp, prec); + mpfr_set_prec (dst_small, prec); + + for (n=0; n<N; n++) + { + mpfr_urandomb (arg1, RANDS); + mpz_urandomb (arg2, RANDS, 1024); + rnd = RND_RAND (); + mpfr_set_prec (dst_big, 2*prec); + compare = func(dst_big, arg2, arg1, rnd); + if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec)) + { + mpfr_set (tmp, dst_big, rnd); + inexact = func(dst_small, arg2, arg1, rnd); + if (mpfr_cmp (tmp, dst_small)) + { + printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n" + "arg1=", + (unsigned) prec, mpfr_print_rnd_mode (rnd), op); + mpfr_print_binary (arg1); + printf("\narg2="); + mpz_out_str (stdout, 10, arg2); + printf ("\ngot "); + mpfr_dump (dst_small); + printf ("expected "); + mpfr_dump (tmp); + printf ("approx "); + mpfr_dump (dst_big); + exit (1); + } + compare2 = mpfr_cmp (tmp, dst_big); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if (compare * compare2 >= 0) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + printf ("Wrong inexact flag for rnd=%s and %s_z:\n" + "expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), op, compare, inexact); + printf ("\narg1="); mpfr_print_binary (arg1); + printf ("\narg2="); mpz_out_str(stdout, 2, arg2); + printf ("\ndstl="); mpfr_print_binary (dst_big); + printf ("\ndsts="); mpfr_print_binary (dst_small); + printf ("\ntmp ="); mpfr_dump (tmp); + exit (1); + } + } + } + } + + mpz_clear (arg2); + mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); +} + +static void +test_genericq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, + int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t), + const char *op) +{ + mpfr_prec_t prec; + mpfr_t arg1, dst_big, dst_small, tmp; + mpq_t arg2; + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + + mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); + mpq_init (arg2); + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (arg1, prec); + mpfr_set_prec (tmp, prec); + mpfr_set_prec (dst_small, prec); + + for (n=0; n<N; n++) + { + mpfr_urandomb (arg1, RANDS); + mpq_set_ui (arg2, randlimb (), randlimb() ); + mpq_canonicalize (arg2); + rnd = RND_RAND (); + mpfr_set_prec (dst_big, prec+10); + compare = func(dst_big, arg1, arg2, rnd); + if (mpfr_can_round (dst_big, prec+10, rnd, rnd, prec)) + { + mpfr_set (tmp, dst_big, rnd); + inexact = func(dst_small, arg1, arg2, rnd); + if (mpfr_cmp (tmp, dst_small)) + { + printf ("Results differ for prec=%u rnd_mode=%s and %s_q:\n" + "arg1=", + (unsigned) prec, mpfr_print_rnd_mode (rnd), op); + mpfr_print_binary (arg1); + printf("\narg2="); + mpq_out_str(stdout, 2, arg2); + printf ("\ngot "); + mpfr_print_binary (dst_small); + printf ("\nexpected "); + mpfr_print_binary (tmp); + printf ("\napprox "); + mpfr_print_binary (dst_big); + putchar('\n'); + exit (1); + } + compare2 = mpfr_cmp (tmp, dst_big); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if (compare * compare2 >= 0) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + printf ("Wrong inexact flag for rnd=%s and %s_q:\n" + "expected %d, got %d", + mpfr_print_rnd_mode (rnd), op, compare, inexact); + printf ("\narg1="); mpfr_print_binary (arg1); + printf ("\narg2="); mpq_out_str(stdout, 2, arg2); + printf ("\ndstl="); mpfr_print_binary (dst_big); + printf ("\ndsts="); mpfr_print_binary (dst_small); + printf ("\ntmp ="); mpfr_print_binary (tmp); + putchar('\n'); + exit (1); + } + } + } + } + + mpq_clear (arg2); + mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); +} + +static void +test_specialq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, + int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t), + void (*mpq_func)(mpq_ptr, mpq_srcptr, mpq_srcptr), + const char *op) +{ + mpfr_t fra, frb, frq; + mpq_t q1, q2, qr; + unsigned int n; + mpfr_prec_t prec; + + for (prec = p0 ; prec < p1 ; prec++) + { + mpfr_inits2 (prec, fra, frb, frq, (mpfr_ptr) 0); + mpq_init (q1); mpq_init(q2); mpq_init (qr); + + for( n = 0 ; n < N ; n++) + { + mpq_set_ui(q1, randlimb(), randlimb() ); + mpq_set_ui(q2, randlimb(), randlimb() ); + mpq_canonicalize (q1); + mpq_canonicalize (q2); + mpq_func (qr, q1, q2); + mpfr_set_q (fra, q1, MPFR_RNDD); + mpfr_func (fra, fra, q2, MPFR_RNDD); + mpfr_set_q (frb, q1, MPFR_RNDU); + mpfr_func (frb, frb, q2, MPFR_RNDU); + mpfr_set_q (frq, qr, MPFR_RNDN); + /* We should have fra <= qr <= frb */ + if ( (mpfr_cmp(fra, frq) > 0) || (mpfr_cmp (frq, frb) > 0)) + { + printf("Range error for prec=%lu and %s", + (unsigned long) prec, op); + printf ("\nq1="); mpq_out_str(stdout, 2, q1); + printf ("\nq2="); mpq_out_str(stdout, 2, q2); + printf ("\nfr_dn="); mpfr_print_binary (fra); + printf ("\nfr_q ="); mpfr_print_binary (frq); + printf ("\nfr_up="); mpfr_print_binary (frb); + putchar('\n'); + exit (1); + } + } + + mpq_clear (q1); mpq_clear (q2); mpq_clear (qr); + mpfr_clears (fra, frb, frq, (mpfr_ptr) 0); + } +} + +static void +bug_mul_q_20100810 (void) +{ + mpfr_t x; + mpfr_t y; + mpq_t q; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpq_init (q); + + /* mpfr_mul_q: the inexact value must be set in case of overflow */ + mpq_set_ui (q, 4096, 3); + mpfr_set_inf (x, +1); + mpfr_nextbelow (x); + inexact = mpfr_mul_q (y, x, q, MPFR_RNDU); + + if (inexact <= 0) + { + printf ("Overflow error in mpfr_mul_q. "); + printf ("Wrong inexact flag: got %d, should be positive.\n", inexact); + + exit (1); + } + if (!mpfr_inf_p (y)) + { + printf ("Overflow error in mpfr_mul_q (y, x, q, MPFR_RNDD). "); + printf ("\nx = "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD); + printf ("\nq = "); + mpq_out_str (stdout, 10, q); + printf ("\ny = "); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD); + printf (" (should be +infinity)\n"); + + exit (1); + } + + mpq_clear (q); + mpfr_clear (y); + mpfr_clear (x); +} + +static void +bug_div_q_20100810 (void) +{ + mpfr_t x; + mpfr_t y; + mpq_t q; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpq_init (q); + + /* mpfr_div_q: the inexact value must be set in case of overflow */ + mpq_set_ui (q, 3, 4096); + mpfr_set_inf (x, +1); + mpfr_nextbelow (x); + inexact = mpfr_div_q (y, x, q, MPFR_RNDU); + + if (inexact <= 0) + { + printf ("Overflow error in mpfr_div_q. "); + printf ("Wrong inexact flag: got %d, should be positive.\n", inexact); + + exit (1); + } + if (!mpfr_inf_p (y)) + { + printf ("Overflow error in mpfr_div_q (y, x, q, MPFR_RNDD). "); + printf ("\nx = "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD); + printf ("\nq = "); + mpq_out_str (stdout, 10, q); + printf ("\ny = "); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD); + printf (" (should be +infinity)\n"); + + exit (1); + } + + mpq_clear (q); + mpfr_clear (y); + mpfr_clear (x); +} + +static void +bug_mul_div_q_20100818 (void) +{ + mpq_t qa, qb; + mpfr_t x1, x2, y1, y2, y3; + mpfr_exp_t emin, emax, e; + int inex; + int rnd; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + mpq_init (qa); + mpq_init (qb); + mpfr_inits2 (32, x1, x2, y1, y2, y3, (mpfr_ptr) 0); + + mpq_set_ui (qa, 3, 17); + mpq_set_ui (qb, 17, 3); + inex = mpfr_set_ui (x1, 7, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + e = MPFR_EMAX_MAX - 3; + inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */ + MPFR_ASSERTN (inex == 0); + + RND_LOOP(rnd) + { + mpfr_mul_q (y1, x1, qa, (mpfr_rnd_t) rnd); + mpfr_div_q (y3, x1, qb, (mpfr_rnd_t) rnd); + MPFR_ASSERTN (mpfr_equal_p (y1, y3)); + inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */ + MPFR_ASSERTN (inex == 0); + mpfr_mul_q (y2, x2, qa, (mpfr_rnd_t) rnd); + if (! mpfr_equal_p (y2, y3)) + { + printf ("Error 1 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); + printf ("Expected "); mpfr_dump (y3); + printf ("Got "); mpfr_dump (y2); + exit (1); + } + mpfr_div_q (y2, x2, qb, (mpfr_rnd_t) rnd); + if (! mpfr_equal_p (y2, y3)) + { + printf ("Error 2 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); + printf ("Expected "); mpfr_dump (y3); + printf ("Got "); mpfr_dump (y2); + exit (1); + } + } + + e = MPFR_EMIN_MIN; + inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */ + MPFR_ASSERTN (inex == 0); + + RND_LOOP(rnd) + { + mpfr_div_q (y1, x1, qa, (mpfr_rnd_t) rnd); + mpfr_mul_q (y3, x1, qb, (mpfr_rnd_t) rnd); + MPFR_ASSERTN (mpfr_equal_p (y1, y3)); + inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */ + MPFR_ASSERTN (inex == 0); + mpfr_div_q (y2, x2, qa, (mpfr_rnd_t) rnd); + if (! mpfr_equal_p (y2, y3)) + { + printf ("Error 3 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); + printf ("Expected "); mpfr_dump (y3); + printf ("Got "); mpfr_dump (y2); + exit (1); + } + mpfr_mul_q (y2, x2, qb, (mpfr_rnd_t) rnd); + if (! mpfr_equal_p (y2, y3)) + { + printf ("Error 4 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd); + printf ("Expected "); mpfr_dump (y3); + printf ("Got "); mpfr_dump (y2); + exit (1); + } + } + + mpq_clear (qa); + mpq_clear (qb); + mpfr_clears (x1, x2, y1, y2, y3, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +static void +reduced_expo_range (void) +{ + mpfr_t x; + mpz_t z; + mpq_t q; + mpfr_exp_t emin; + int inex; + + emin = mpfr_get_emin (); + set_emin (4); + + mpfr_init2 (x, 32); + + mpz_init (z); + mpfr_clear_flags (); + inex = mpfr_set_ui (x, 17, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + mpz_set_ui (z, 3); + inex = mpfr_mul_z (x, x, z, MPFR_RNDN); + if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 51) != 0) + { + printf ("Error 1 in reduce_expo_range: expected 51 with inex = 0," + " got\n"); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("with inex = %d\n", inex); + exit (1); + } + inex = mpfr_div_z (x, x, z, MPFR_RNDN); + if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0) + { + printf ("Error 2 in reduce_expo_range: expected 17 with inex = 0," + " got\n"); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("with inex = %d\n", inex); + exit (1); + } + inex = mpfr_add_z (x, x, z, MPFR_RNDN); + if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 20) != 0) + { + printf ("Error 3 in reduce_expo_range: expected 20 with inex = 0," + " got\n"); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("with inex = %d\n", inex); + exit (1); + } + inex = mpfr_sub_z (x, x, z, MPFR_RNDN); + if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0) + { + printf ("Error 4 in reduce_expo_range: expected 17 with inex = 0," + " got\n"); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("with inex = %d\n", inex); + exit (1); + } + MPFR_ASSERTN (__gmpfr_flags == 0); + if (mpfr_cmp_z (x, z) <= 0) + { + printf ("Error 5 in reduce_expo_range: expected a positive value.\n"); + exit (1); + } + mpz_clear (z); + + mpq_init (q); + mpq_set_ui (q, 1, 1); + mpfr_set_ui (x, 16, MPFR_RNDN); + inex = mpfr_add_q (x, x, q, MPFR_RNDN); + if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0) + { + printf ("Error in reduce_expo_range for 16 + 1/1," + " got inex = %d and\nx = ", inex); + mpfr_dump (x); + exit (1); + } + inex = mpfr_sub_q (x, x, q, MPFR_RNDN); + if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 16) != 0) + { + printf ("Error in reduce_expo_range for 17 - 1/1," + " got inex = %d and\nx = ", inex); + mpfr_dump (x); + exit (1); + } + mpq_clear (q); + + mpfr_clear (x); + + set_emin (emin); +} + +static void +addsubq_overflow_aux (mpfr_exp_t e) +{ + mpfr_t x, y; + mpq_t q; + mpfr_exp_t emax; + int inex; + int rnd; + int sign, sub; + + MPFR_ASSERTN (e <= LONG_MAX); + emax = mpfr_get_emax (); + set_emax (e); + mpfr_inits2 (16, x, y, (mpfr_ptr) 0); + mpq_init (q); + + mpfr_set_inf (x, 1); + mpfr_nextbelow (x); + mpq_set_ui (q, 1, 1); + + for (sign = 0; sign <= 1; sign++) + { + for (sub = 0; sub <= 1; sub++) + { + RND_LOOP(rnd) + { + unsigned int flags, ex_flags; + int inf; + + inf = rnd == MPFR_RNDA || + rnd == (sign ? MPFR_RNDD : MPFR_RNDU); + ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0); + mpfr_clear_flags (); + inex = sub ? + mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) : + mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd); + flags = __gmpfr_flags; + if (inex == 0 || flags != ex_flags || + (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y))) + { + printf ("Error in addsubq_overflow_aux(%ld)," + " sign = %d, %s\n", (long) e, sign, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Got inex = %d, y = ", inex); + mpfr_dump (y); + printf ("Expected flags:"); + flags_out (ex_flags); + printf ("Got flags: "); + flags_out (flags); + exit (1); + } + } + mpq_neg (q, q); + } + mpfr_neg (x, x, MPFR_RNDN); + mpq_neg (q, q); + } + + mpq_clear (q); + mpfr_clears (x, y, (mpfr_ptr) 0); + set_emax (emax); +} + +static void +addsubq_overflow (void) +{ + addsubq_overflow_aux (4913); + addsubq_overflow_aux (MPFR_EMAX_MAX); +} + +static void +coverage_mpfr_mul_q_20110218 (void) +{ + mpfr_t cmp, res, op1; + mpq_t op2; + int status; + + mpfr_init2 (cmp, MPFR_PREC_MIN); + mpfr_init2 (res, MPFR_PREC_MIN); + mpfr_init_set_si (op1, 1, MPFR_RNDN); + + mpq_init (op2); + mpq_set_si (op2, 0, 0); + mpz_set_si (mpq_denref (op2), 0); + + status = mpfr_mul_q (res, op1, op2, MPFR_RNDN); + + if ((status != 0) || (mpfr_cmp (cmp, res) != 0)) + { + printf ("Results differ %d.\nres=", status); + mpfr_print_binary (res); + printf ("\ncmp="); + mpfr_print_binary (cmp); + putchar ('\n'); + exit (1); + } + + mpfr_set_si (op1, 1, MPFR_RNDN); + mpq_set_si (op2, -1, 0); + + status = mpfr_mul_q (res, op1, op2, MPFR_RNDN); + + mpfr_set_inf (cmp, -1); + if ((status != 0) || (mpfr_cmp(res, cmp) != 0)) + { + printf ("mpfr_mul_q 1 * (-1/0) returned a wrong value :\n waiting for "); + mpfr_print_binary (cmp); + printf (" got "); + mpfr_print_binary (res); + printf ("\n trinary value is %d\n", status); + exit (1); + } + + mpq_clear (op2); + mpfr_clear (op1); + mpfr_clear (res); + mpfr_clear (cmp); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_specialz (mpfr_add_z, mpz_add, "add"); + test_specialz (mpfr_sub_z, mpz_sub, "sub"); + test_specialz (mpfr_mul_z, mpz_mul, "mul"); + test_genericz (2, 100, 100, mpfr_add_z, "add"); + test_genericz (2, 100, 100, mpfr_sub_z, "sub"); + test_genericz (2, 100, 100, mpfr_mul_z, "mul"); + test_genericz (2, 100, 100, mpfr_div_z, "div"); + test_special2z (mpfr_z_sub, mpz_sub, "sub"); + test_generic2z (2, 100, 100, mpfr_z_sub, "sub"); + + test_genericq (2, 100, 100, mpfr_add_q, "add"); + test_genericq (2, 100, 100, mpfr_sub_q, "sub"); + test_genericq (2, 100, 100, mpfr_mul_q, "mul"); + test_genericq (2, 100, 100, mpfr_div_q, "div"); + test_specialq (2, 100, 100, mpfr_mul_q, mpq_mul, "mul"); + test_specialq (2, 100, 100, mpfr_div_q, mpq_div, "div"); + test_specialq (2, 100, 100, mpfr_add_q, mpq_add, "add"); + test_specialq (2, 100, 100, mpfr_sub_q, mpq_sub, "sub"); + + test_cmp_z (2, 100, 100); + test_cmp_q (2, 100, 100); + test_cmp_f (2, 100, 100); + + check_for_zero (); + + bug_mul_q_20100810 (); + bug_div_q_20100810 (); + bug_mul_div_q_20100818 (); + reduced_expo_range (); + addsubq_overflow (); + + coverage_mpfr_mul_q_20110218 (); + + tests_end_mpfr (); + return 0; +} + diff --git a/mpfr/tests/tgrandom.c b/mpfr/tests/tgrandom.c new file mode 100644 index 0000000000..ed1c1a3a75 --- /dev/null +++ b/mpfr/tests/tgrandom.c @@ -0,0 +1,135 @@ +/* Test file for mpfr_grandom + +Copyright 2011-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +test_special (mpfr_prec_t p) +{ + mpfr_t x; + int inexact; + + mpfr_init2 (x, p); + + inexact = mpfr_grandom (x, NULL, RANDS, MPFR_RNDN); + if ((inexact & 3) == 0) + { + printf ("Error: mpfr_grandom() returns a zero ternary value.\n"); + exit (1); + } + if ((inexact & (3 << 2)) != 0) + { + printf ("Error: the second ternary value of mpfr_grandom(x, NULL, ...)" + " must be 0.\n"); + exit (1); + } + + mpfr_clear(x); +} + + +static void +test_grandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd, + int verbose) +{ + mpfr_t *t; + mpfr_t av, va, tmp; + int i, inexact; + + nbtests = (nbtests & 1) ? (nbtests + 1) : nbtests; + t = (mpfr_t *) tests_allocate (nbtests * sizeof (mpfr_t)); + + for (i = 0; i < nbtests; ++i) + mpfr_init2 (t[i], prec); + + for (i = 0; i < nbtests; i += 2) + { + inexact = mpfr_grandom (t[i], t[i + 1], RANDS, MPFR_RNDN); + if ((inexact & 3) == 0 || (inexact & (3 << 2)) == 0) + { + /* one call in the loop pretended to return an exact number! */ + printf ("Error: mpfr_grandom() returns a zero ternary value.\n"); + exit (1); + } + } + +#ifdef HAVE_STDARG + if (verbose) + { + mpfr_init2 (av, prec); + mpfr_init2 (va, prec); + mpfr_init2 (tmp, prec); + + mpfr_set_ui (av, 0, MPFR_RNDN); + mpfr_set_ui (va, 0, MPFR_RNDN); + for (i = 0; i < nbtests; ++i) + { + mpfr_add (av, av, t[i], MPFR_RNDN); + mpfr_sqr (tmp, t[i], MPFR_RNDN); + mpfr_add (va, va, tmp, MPFR_RNDN); + } + mpfr_div_ui (av, av, nbtests, MPFR_RNDN); + mpfr_div_ui (va, va, nbtests, MPFR_RNDN); + mpfr_sqr (tmp, av, MPFR_RNDN); + mpfr_sub (va, va, av, MPFR_RNDN); + + mpfr_printf ("Average = %.5Rf\nVariance = %.5Rf\n", av, va); + mpfr_clear (av); + mpfr_clear (va); + mpfr_clear (tmp); + } +#endif /* HAVE_STDARG */ + + for (i = 0; i < nbtests; ++i) + mpfr_clear (t[i]); + tests_free (t, nbtests * sizeof (mpfr_t)); + return; +} + + +int +main (int argc, char *argv[]) +{ + long nbtests; + int verbose; + tests_start_mpfr (); + + verbose = 0; + nbtests = 10; + if (argc > 1) + { + long a = atol (argv[1]); + verbose = 1; + if (a != 0) + nbtests = a; + } + + test_grandom (nbtests, 420, MPFR_RNDN, verbose); + test_special (2); + test_special (42000); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/thyperbolic.c b/mpfr/tests/thyperbolic.c new file mode 100644 index 0000000000..3857bfd11b --- /dev/null +++ b/mpfr/tests/thyperbolic.c @@ -0,0 +1,385 @@ +/* Test file for hyperbolic function : mpfr_cosh, mpfr_sinh, mpfr_tanh, mpfr_acosh, mpfr_asinh, mpfr_atanh. + +Copyright 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <stdio.h> + +#include "mpfr-test.h" + +static int +check_NAN (void) +{ + mpfr_t t, ch,sh,th,ach,ash,ath; + int tester; + int fail = 0; + + mpfr_init2(t,200); + mpfr_init2(ch,200); + mpfr_init2(sh,200); + mpfr_init2(th,200); + mpfr_init2(ach,200); + mpfr_init2(ash,200); + mpfr_init2(ath,200); + + MPFR_SET_NAN(t); + + /******cosh********/ + + tester=mpfr_cosh(ch,t,MPFR_RNDD); + if (!MPFR_IS_NAN(ch) || tester!=0) + { + printf("cosh NAN \n"); + fail = 1; + goto clean_up; + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,MPFR_RNDD); + if (!MPFR_IS_NAN(sh) || tester!=0) + { + printf("sinh NAN \n"); + fail = 1; + goto clean_up; + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,MPFR_RNDD); + if (!MPFR_IS_NAN(th) || tester!=0) + { + printf("tanh NAN \n"); + fail = 1; + goto clean_up; + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,MPFR_RNDD); + if (!MPFR_IS_NAN(ach) || tester!=0) + { + printf("acosh NAN \n"); + fail = 1; + goto clean_up; + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,MPFR_RNDD); + if (!MPFR_IS_NAN(ash) || tester!=0) + { + printf("asinh NAN \n"); + fail = 1; + goto clean_up; + } + + /******atanh********/ + + tester=mpfr_atanh(ath,t,MPFR_RNDD); + if (!MPFR_IS_NAN(ath) || tester!=0) + { + printf("atanh NAN \n"); + fail = 1; + goto clean_up; + } + + clean_up: + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + return fail; +} + +static int +check_zero (void) +{ + mpfr_t t, ch,sh,th,ach,ash,ath; + int tester; + int fail = 0; + + mpfr_init2(t,200); + mpfr_init2(ch,200); + mpfr_init2(sh,200); + mpfr_init2(th,200); + mpfr_init2(ach,200); + mpfr_init2(ash,200); + mpfr_init2(ath,200); + + mpfr_set_ui(t,0,MPFR_RNDD); + + /******cosh********/ + + tester = mpfr_cosh (ch, t, MPFR_RNDD); + if (mpfr_cmp_ui(ch, 1) || tester) + { + printf("cosh(0) \n"); + fail = 1; + goto clean_up; + } + + /******sinh********/ + + tester = mpfr_sinh (sh, t, MPFR_RNDD); + if (!MPFR_IS_ZERO(sh) || tester) + { + printf("sinh(0) \n"); + fail = 1; + goto clean_up; + } + + /******tanh********/ + + tester = mpfr_tanh (th, t, MPFR_RNDD); + if (!MPFR_IS_ZERO(th) || tester) + { + printf("tanh(0) \n"); + fail = 1; + goto clean_up; + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,MPFR_RNDD); + if (!MPFR_IS_NAN(ach) || tester) + { + printf("acosh(0) \n"); + fail = 1; + goto clean_up; + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,MPFR_RNDD); + if (!MPFR_IS_ZERO(ash) || tester) + { + printf("asinh(0) \n"); + fail = 1; + goto clean_up; + } + + /******atanh********/ + + tester=mpfr_atanh(ath,t,MPFR_RNDD); + if (!MPFR_IS_ZERO(ath) || tester) + { + printf("atanh(0) \n"); + fail = 1; + goto clean_up; + } + + clean_up: + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + return fail; +} + +static int +check_INF (void) +{ + mpfr_t t, ch, sh, th, ach, ash, ath; + int tester; + int fail = 0; + + mpfr_init2 (t, 200); + mpfr_init2 (ch, 200); + mpfr_init2 (sh, 200); + mpfr_init2 (th, 200); + mpfr_init2 (ach, 200); + mpfr_init2 (ash, 200); + mpfr_init2 (ath, 200); + + MPFR_SET_INF(t); + + if(MPFR_SIGN(t)<0) + MPFR_CHANGE_SIGN(t); + + /******cosh********/ + + tester = mpfr_cosh(ch,t,MPFR_RNDD); + if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester!=0) + { + printf("cosh(INF) \n"); + fail = 1; + goto clean_up; + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,MPFR_RNDD); + if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) < 0 || tester!=0) + { + printf("sinh(INF) \n"); + fail = 1; + goto clean_up; + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,MPFR_RNDD); + if (mpfr_cmp_ui(th,1) != 0 || tester!=0) + { + printf("tanh(INF) \n"); + fail = 1; + goto clean_up; + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,MPFR_RNDD); + if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || tester!=0) + { + printf("acosh(INF) \n"); + fail = 1; + goto clean_up; + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,MPFR_RNDD); + if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) < 0 || tester!=0) + { + printf("asinh(INF) \n"); + fail = 1; + goto clean_up; + } + + /******atanh********/ + + tester = mpfr_atanh (ath, t, MPFR_RNDD); + if (!MPFR_IS_NAN(ath) || tester != 0) + { + printf("atanh(INF) \n"); + fail = 1; + goto clean_up; + } + + MPFR_CHANGE_SIGN(t); + + /******cosh********/ + + tester=mpfr_cosh(ch,t,MPFR_RNDD); + if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester!=0) + { + printf("cosh(-INF) \n"); + fail = 1; + goto clean_up; + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,MPFR_RNDD); + if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) > 0 || tester!=0) + { + printf("sinh(-INF) \n"); + fail = 1; + goto clean_up; + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,MPFR_RNDD); + if (!mpfr_cmp_ui(th,-1) || tester!=0) + { + printf("tanh(-INF) \n"); + fail = 1; + goto clean_up; + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,MPFR_RNDD); + if (!MPFR_IS_NAN(ach) || tester!=0) + { + printf("acosh(-INF) \n"); + fail = 1; + goto clean_up; + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,MPFR_RNDD); + if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) > 0 || tester!=0) + { + printf("asinh(-INF) \n"); + fail = 1; + goto clean_up; + } + + /******atanh********/ + + tester = mpfr_atanh (ath, t, MPFR_RNDD); + if (!MPFR_IS_NAN(ath) || tester != 0) + { + printf("atanh(-INF) \n"); + fail = 1; + goto clean_up; + } + + clean_up: + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + return fail; +} + +int +main(void) +{ + tests_start_mpfr (); + + if (check_zero ()) + { + printf ("Error in evaluation at 0\n"); + exit (1); + } + + if (check_INF ()) + { + printf ("Error in evaluation of INF\n"); + exit (1); + } + + if (check_NAN ()) + { + printf ("Error in evaluation of NAN\n"); + exit (1); + } + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/thypot.c b/mpfr/tests/thypot.c new file mode 100644 index 0000000000..f942ea7225 --- /dev/null +++ b/mpfr/tests/thypot.c @@ -0,0 +1,331 @@ +/* Test file for mpfr_hypot. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* Non-zero when extended exponent range */ +static int ext = 0; + +static void +special (void) +{ + mpfr_t x, y, z; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + mpfr_set_nan (x); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_hypot (z, x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (z)); + mpfr_hypot (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (z)); + mpfr_hypot (z, y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (z)); + + mpfr_set_inf (x, 1); + mpfr_set_inf (y, -1); + mpfr_hypot (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); + + mpfr_set_inf (x, -1); + mpfr_set_nan (y); + mpfr_hypot (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); + + mpfr_set_nan (x); + mpfr_set_inf (y, -1); + mpfr_hypot (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +test_large (void) +{ + mpfr_t x, y, z, t; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + mpfr_set_ui (x, 21, MPFR_RNDN); + mpfr_set_ui (y, 28, MPFR_RNDN); + mpfr_set_ui (z, 35, MPFR_RNDN); + + mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); + mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); + mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); + + mpfr_hypot (t, x, y, MPFR_RNDN); + if (mpfr_cmp (z, t)) + { + printf ("Error in test_large: got\n"); + mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); + printf ("\ninstead of\n"); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (t, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021"); + mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021"); + mpfr_hypot (t, x, y, MPFR_RNDN); + mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020"); + if (mpfr_cmp (z, t)) + { + printf ("Error in test_large: got\n"); + mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); + printf ("\ninstead of\n"); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 240); + mpfr_set_prec (y, 22); + mpfr_set_prec (z, 2); + mpfr_set_prec (t, 2); + mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7"); + mpfr_set_str_binary (y, "0.1111000010000011000111E-10"); + mpfr_hypot (t, x, y, MPFR_RNDN); + mpfr_set_str_binary (z, "0.11E-7"); + if (mpfr_cmp (z, t)) + { + printf ("Error in test_large: got\n"); + mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); + printf ("\ninstead of\n"); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +static void +test_small (void) +{ + mpfr_t x, y, z1, z2; + int inex1, inex2; + unsigned int flags; + + /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */ + mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0); + mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN); + mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN); + mpfr_set_ui (z1, 2, MPFR_RNDN); + inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN); + inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN); + MPFR_ASSERTN (inex2 == 0); + mpfr_clear_flags (); + inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN); + flags = __gmpfr_flags; + if (mpfr_cmp (z1, z2) != 0) + { + printf ("Error in test_small%s\nExpected ", + ext ? ", extended exponent range" : ""); + mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (! SAME_SIGN (inex1, inex2)) + { + printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n", + ext ? ", extended exponent range" : "", inex1, inex2); + exit (1); + } + if (flags != MPFR_FLAGS_INEXACT) + { + printf ("Bad flags in test_small%s\nExpected %u, got %u\n", + ext ? ", extended exponent range" : "", + (unsigned int) MPFR_FLAGS_INEXACT, flags); + exit (1); + } + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); +} + +static void +test_large_small (void) +{ + mpfr_t x, y, z; + int inexact, inex2, r; + + mpfr_init2 (x, 3); + mpfr_init2 (y, 2); + mpfr_init2 (z, 2); + + mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN); + inexact = mpfr_hypot (z, x, y, MPFR_RNDN); + if (inexact >= 0 || mpfr_cmp (x, z)) + { + printf ("Error 1 in test_large_small%s\n", + ext ? ", extended exponent range" : ""); + exit (1); + } + + mpfr_mul_ui (x, x, 5, MPFR_RNDN); + inexact = mpfr_hypot (z, x, y, MPFR_RNDN); + if (mpfr_cmp (x, z) >= 0) + { + printf ("Error 2 in test_large_small%s\n", + ext ? ", extended exponent range" : ""); + printf ("x = "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + printf ("y = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + printf ("z = "); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf (" (in precision 2) instead of\n "); + mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU); + printf ("\n"); + exit (1); + } + + RND_LOOP(r) + { + mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN); + inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r); + inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r); + if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2)) + { + printf ("Error 3 in test_large_small, %s%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), + ext ? ", extended exponent range" : ""); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (", inex = %d\n", inex2); + printf ("Got "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (", inex = %d\n", inexact); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_overflow (void) +{ + mpfr_t x, y; + int inex, r; + + mpfr_inits2 (8, x, y, (mpfr_ptr) 0); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_setmax (x, mpfr_get_emax ()); + + RND_LOOP(r) + { + mpfr_clear_overflow (); + inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r); + if (!mpfr_overflow_p ()) + { + printf ("No overflow in check_overflow for %s%s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), + ext ? ", extended exponent range" : ""); + exit (1); + } + MPFR_ASSERTN (MPFR_IS_POS (y)); + if (r == MPFR_RNDZ || r == MPFR_RNDD) + { + MPFR_ASSERTN (inex < 0); + MPFR_ASSERTN (!mpfr_inf_p (y)); + mpfr_nexttoinf (y); + } + else + { + MPFR_ASSERTN (inex > 0); + } + MPFR_ASSERTN (mpfr_inf_p (y)); + } + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +#define TWO_ARGS +#define TEST_FUNCTION mpfr_hypot +#include "tgeneric.c" + +static void +alltst (void) +{ + mpfr_exp_t emin, emax; + + ext = 0; + test_small (); + test_large_small (); + check_overflow (); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + if (mpfr_get_emin () != emin || mpfr_get_emax () != emax) + { + ext = 1; + test_small (); + test_large_small (); + check_overflow (); + set_emin (emin); + set_emax (emax); + } +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_large (); + alltst (); + + test_generic (2, 100, 10); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tinits.c b/mpfr/tests/tinits.c new file mode 100644 index 0000000000..daeb4edd03 --- /dev/null +++ b/mpfr/tests/tinits.c @@ -0,0 +1,62 @@ +/* Test file for mpfr_init2, mpfr_inits, mpfr_inits2 and mpfr_clears. + +Copyright 2003, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t a, b, c; + long large_prec; + + tests_start_mpfr (); + + mpfr_inits (a, b, c, (mpfr_ptr) 0); + mpfr_clears (a, b, c, (mpfr_ptr) 0); + mpfr_inits2 (200, a, b, c, (mpfr_ptr) 0); + mpfr_clears (a, b, c, (mpfr_ptr) 0); + + /* test for precision 2^31-1, see + https://gforge.inria.fr/tracker/index.php?func=detail&aid=13918 */ + large_prec = 2147483647; + if (getenv ("MPFR_CHECK_LARGEMEM") != NULL) + { + /* We assume that the precision won't be increased internally. */ + if (large_prec > MPFR_PREC_MAX) + large_prec = MPFR_PREC_MAX; + mpfr_inits2 (large_prec, a, b, (mpfr_ptr) 0); + mpfr_set_ui (a, 17, MPFR_RNDN); + mpfr_set (b, a, MPFR_RNDN); + if (mpfr_get_ui (a, MPFR_RNDN) != 17) + { + printf ("Error in mpfr_init2 with precision 2^31-1\n"); + exit (1); + } + mpfr_clears (a, b, (mpfr_ptr) 0); + } + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tinp_str.c b/mpfr/tests/tinp_str.c new file mode 100644 index 0000000000..9f3a80259a --- /dev/null +++ b/mpfr/tests/tinp_str.c @@ -0,0 +1,94 @@ +/* Test file for mpfr_inp_str. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + mpfr_t y; + FILE *f; + int i; + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 15); + f = src_fopen ("inp_str.data", "r"); + if (f == NULL) + { + printf ("Error, can't open inp_str.data\n"); + exit (1); + } + i = mpfr_inp_str (x, f, 10, MPFR_RNDN); + if (i == 0 || mpfr_cmp_ui (x, 31415)) + { + printf ("Error in reading 1st line from file inp_str.data (%d)\n", i); + mpfr_dump (x); + exit (1); + } + getc (f); + i = mpfr_inp_str (x, f, 10, MPFR_RNDN); + if ((i == 0) || mpfr_cmp_ui (x, 31416)) + { + printf ("Error in reading 2nd line from file inp_str.data (%d)\n", i); + mpfr_dump (x); + exit (1); + } + getc (f); + i = mpfr_inp_str (x, f, 10, MPFR_RNDN); + if (i != 0) + { + printf ("Error in reading 3rd line from file inp_str.data (%d)\n", i); + mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str (y, "1.0010010100001110100101001110011010111011100001110010e226", + 2, MPFR_RNDN); + for (i = 2; i < 63; i++) + { + getc (f); + if (mpfr_inp_str (x, f, i, MPFR_RNDN) == 0 || !mpfr_equal_p (x, y)) + { + printf ("Error in reading %dth line from file inp_str.data\n", i+2); + mpfr_dump (x); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); + } + + fclose (f); + + mpfr_clear (x); + mpfr_clear (y); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tinternals.c b/mpfr/tests/tinternals.c new file mode 100644 index 0000000000..a746e2ef9a --- /dev/null +++ b/mpfr/tests/tinternals.c @@ -0,0 +1,161 @@ +/* tinternals -- Test for internals. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#define MPFR_NEED_LONGLONG_H +#include "mpfr-test.h" + +static void +test_int_ceil_log2 (void) +{ + int i; + int val[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; + + for (i = 1; i < 17; i++) + { + if (MPFR_INT_CEIL_LOG2 (i) != val[i-1]) + { + printf ("Error 1 in test_int_ceil_log2 for i = %d\n", i); + exit (1); + } + if (MPFR_INT_CEIL_LOG2 (i) != __gmpfr_int_ceil_log2 (i)) + { + printf ("Error 2 in test_int_ceil_log2 for i = %d\n", i); + exit (1); + } + } +} + +static void +test_round_near_x (void) +{ + mpfr_t x, y, z, eps; + mpfr_exp_t e; + int failures = 0, mx, neg, err, dir, r, inex, inex2; + char buffer[7], *p; + + mpfr_inits (x, y, z, eps, (mpfr_ptr) 0); + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 3); + mpfr_set_prec (z, 3); + mpfr_set_prec (eps, 2); + mpfr_set_ui_2exp (eps, 1, -32, MPFR_RNDN); + + for (mx = 16; mx < 32; mx++) + { + mpfr_set_ui_2exp (x, mx, -2, MPFR_RNDN); + for (p = buffer, neg = 0; + neg <= 1; + mpfr_neg (x, x, MPFR_RNDN), p++, neg++) + for (err = 2; err <= 6; err++) + for (dir = 0; dir <= 1; dir++) + RND_LOOP(r) + { + inex = mpfr_round_near_x (y, x, err, dir, (mpfr_rnd_t) r); + + if (inex == 0 && err < 6) + { + /* The test is more restrictive than necessary. + So, no failure in this case. */ + continue; + } + + inex2 = ((dir ^ neg) ? mpfr_add : mpfr_sub) + (z, x, eps, (mpfr_rnd_t) r); + if (inex * inex2 <= 0) + printf ("Bad return value (%d instead of %d) for:\n", + inex, inex2); + else if (mpfr_equal_p (y, z)) + continue; /* correct inex and y */ + else + { + printf ("Bad MPFR value (should have got "); + mpfr_out_str (stdout, 2, 3, z, MPFR_RNDZ); + printf (") for:\n"); + } + + if (!mpfr_get_str (buffer, &e, 2, 5, x, MPFR_RNDZ) || e != 3) + { + printf ("mpfr_get_str failed in test_round_near_x\n"); + exit (1); + } + printf ("x = %c%c%c%c.%c%c, ", neg ? '-' : '+', + p[0], p[1], p[2], p[3], p[4]); + printf ("err = %d, dir = %d, r = %s --> inex = %2d", + err, dir, mpfr_print_rnd_mode ((mpfr_rnd_t) r), inex); + if (inex != 0) + { + printf (", y = "); + mpfr_out_str (stdout, 2, 3, y, MPFR_RNDZ); + } + printf ("\n"); + if (inex == 0) + printf ("Rounding was possible!\n"); + if (++failures == 10) /* show at most 10 failures */ + exit (1); + } + } + + if (failures) + exit (1); + + mpfr_clears (x, y, z, eps, (mpfr_ptr) 0); +} + +static void +test_set_prec_raw (void) +{ + mpfr_t x; + int i; + + mpfr_init2 (x, 53); + for (i = 2; i < 11; i++) + { + mpfr_set_prec_raw (x, i); + if (MPFR_PREC (x) != i) + { + printf ("[ERROR]: mpfr_set_prec_raw %d\n", i); + exit (1); + } + } + mpfr_clear (x); +} + +int +main (int argc, char **argv) +{ + tests_start_mpfr (); + + /* The tested function and macro exist in MPFR 2.2.0, but with a + different (incorrect, but with no effect in 2.2.0) behavior. */ +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0) + test_int_ceil_log2 (); +#endif + + test_round_near_x (); + test_set_prec_raw (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tisnan.c b/mpfr/tests/tisnan.c new file mode 100644 index 0000000000..096f2521b1 --- /dev/null +++ b/mpfr/tests/tisnan.c @@ -0,0 +1,212 @@ +/* Test file for mpfr_nan_p, mpfr_inf_p, mpfr_number_p, mpfr_zero_p and + mpfr_regular_p. + +Copyright 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x; + + tests_start_mpfr (); + + mpfr_init (x); + + /* check +infinity gives non-zero for mpfr_inf_p only */ + mpfr_set_ui (x, 1L, MPFR_RNDZ); + mpfr_div_ui (x, x, 0L, MPFR_RNDZ); + if (mpfr_nan_p (x) || (mpfr_nan_p) (x) ) + { + printf ("Error: mpfr_nan_p(+Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) == 0) + { + printf ("Error: mpfr_inf_p(+Inf) gives zero\n"); + exit (1); + } + if (mpfr_number_p (x) || (mpfr_number_p) (x) ) + { + printf ("Error: mpfr_number_p(+Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_zero_p (x) || (mpfr_zero_p) (x) ) + { + printf ("Error: mpfr_zero_p(+Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + { + printf ("Error: mpfr_regular_p(+Inf) gives non-zero\n"); + exit (1); + } + + /* same for -Inf */ + mpfr_neg (x, x, MPFR_RNDN); + if (mpfr_nan_p (x) || (mpfr_nan_p(x))) + { + printf ("Error: mpfr_nan_p(-Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) == 0) + { + printf ("Error: mpfr_inf_p(-Inf) gives zero\n"); + exit (1); + } + if (mpfr_number_p (x) || (mpfr_number_p)(x) ) + { + printf ("Error: mpfr_number_p(-Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_zero_p (x) || (mpfr_zero_p)(x) ) + { + printf ("Error: mpfr_zero_p(-Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + { + printf ("Error: mpfr_regular_p(-Inf) gives non-zero\n"); + exit (1); + } + + /* same for NaN */ + mpfr_sub (x, x, x, MPFR_RNDN); + if (mpfr_nan_p (x) == 0) + { + printf ("Error: mpfr_nan_p(NaN) gives zero\n"); + exit (1); + } + if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + { + printf ("Error: mpfr_inf_p(NaN) gives non-zero\n"); + exit (1); + } + if (mpfr_number_p (x) || (mpfr_number_p) (x) ) + { + printf ("Error: mpfr_number_p(NaN) gives non-zero\n"); + exit (1); + } + if (mpfr_zero_p (x) || (mpfr_zero_p)(x) ) + { + printf ("Error: mpfr_number_p(NaN) gives non-zero\n"); + exit (1); + } + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + { + printf ("Error: mpfr_regular_p(NaN) gives non-zero\n"); + exit (1); + } + + /* same for a regular number */ + mpfr_set_ui (x, 1, MPFR_RNDN); + if (mpfr_nan_p (x) || (mpfr_nan_p)(x)) + { + printf ("Error: mpfr_nan_p(1) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + { + printf ("Error: mpfr_inf_p(1) gives non-zero\n"); + exit (1); + } + if (mpfr_number_p (x) == 0) + { + printf ("Error: mpfr_number_p(1) gives zero\n"); + exit (1); + } + if (mpfr_zero_p (x) || (mpfr_zero_p) (x) ) + { + printf ("Error: mpfr_zero_p(1) gives non-zero\n"); + exit (1); + } + if (mpfr_regular_p (x) == 0 || (mpfr_regular_p) (x) == 0) + { + printf ("Error: mpfr_regular_p(1) gives zero\n"); + exit (1); + } + + /* Same for +0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + if (mpfr_nan_p (x) || (mpfr_nan_p)(x)) + { + printf ("Error: mpfr_nan_p(+0) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + { + printf ("Error: mpfr_inf_p(+0) gives non-zero\n"); + exit (1); + } + if (mpfr_number_p (x) == 0) + { + printf ("Error: mpfr_number_p(+0) gives zero\n"); + exit (1); + } + if (mpfr_zero_p (x) == 0 ) + { + printf ("Error: mpfr_zero_p(+0) gives zero\n"); + exit (1); + } + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + { + printf ("Error: mpfr_regular_p(+0) gives non-zero\n"); + exit (1); + } + + /* Same for -0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + if (mpfr_nan_p (x) || (mpfr_nan_p)(x)) + { + printf ("Error: mpfr_nan_p(-0) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + { + printf ("Error: mpfr_inf_p(-0) gives non-zero\n"); + exit (1); + } + if (mpfr_number_p (x) == 0) + { + printf ("Error: mpfr_number_p(-0) gives zero\n"); + exit (1); + } + if (mpfr_zero_p (x) == 0 ) + { + printf ("Error: mpfr_zero_p(-0) gives zero\n"); + exit (1); + } + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + { + printf ("Error: mpfr_regular_p(-0) gives non-zero\n"); + exit (1); + } + + mpfr_clear (x); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tisqrt.c b/mpfr/tests/tisqrt.c new file mode 100644 index 0000000000..9716a6d50d --- /dev/null +++ b/mpfr/tests/tisqrt.c @@ -0,0 +1,94 @@ +/* Test file for __gmpfr_isqrt and __gmpfr_cuberoot internal functions. + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +tst_isqrt (unsigned long n, unsigned long r) +{ + unsigned long i; + + i = __gmpfr_isqrt (n); + if (i != r) + { + printf ("Error in __gmpfr_isqrt (%lu): got %lu instead of %lu\n", + n, i, r); + exit (1); + } +} + +static void +tst_icbrt (unsigned long n, unsigned long r) +{ + unsigned long i; + + i = __gmpfr_cuberoot (n); + if (i != r) + { + printf ("Error in __gmpfr_cuberoot (%lu): got %lu instead of %lu\n", + n, i, r); + exit (1); + } +} + +int +main (void) +{ + unsigned long c, i; + + tests_start_mpfr (); + + tst_isqrt (0, 0); + tst_isqrt (1, 1); + tst_isqrt (2, 1); + for (i = 2; i <= 65535; i++) + { + tst_isqrt (i * i - 1, i - 1); + tst_isqrt (i * i, i); + } + tst_isqrt (4294967295UL, 65535); + + tst_icbrt (0, 0); + tst_icbrt (1, 1); + tst_icbrt (2, 1); + tst_icbrt (3, 1); + for (i = 2; i <= 1625; i++) + { + c = i * i * i; + tst_icbrt (c - 4, i - 1); + tst_icbrt (c - 3, i - 1); + tst_icbrt (c - 2, i - 1); + tst_icbrt (c - 1, i - 1); + tst_icbrt (c, i); + tst_icbrt (c + 1, i); + tst_icbrt (c + 2, i); + tst_icbrt (c + 3, i); + tst_icbrt (c + 4, i); + } + tst_icbrt (4294967295UL, 1625); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tj0.c b/mpfr/tests/tj0.c new file mode 100644 index 0000000000..0ce289afaa --- /dev/null +++ b/mpfr/tests/tj0.c @@ -0,0 +1,147 @@ +/* tj0 -- test file for the Bessel function of first kind (order 0) + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_j0 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS) +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + int inex; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + /* special values */ + mpfr_set_nan (x); + mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_inf (x, -1); /* -Inf */ + mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ + mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(+0)=1 */ + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(-0)=1 */ + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_j0 (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_j0 for x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_j0 (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_j0 for x=-1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + /* Bug reported on 2007-07-03 by Sisyphus (assertion failed in r4619) */ + mpfr_set_si (x, 70000, MPFR_RNDN); + mpfr_j0 (y, x, MPFR_RNDN); + + /* Bug reported by Kevin Rauch on 27 Oct 2007 */ + mpfr_set_prec (x, 7); + mpfr_set_prec (y, 7); + mpfr_set_si (x, -100, MPFR_RNDN); + mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_ui_2exp (y, 41, -11) == 0); + + /* Bug reported by Fredrik Johansson on 19 Jan 2016 */ + mpfr_set_prec (x, 53); + mpfr_set_str (x, "0x4.3328p+0", 0, MPFR_RNDN); + mpfr_set_prec (y, 2); + mpfr_j0 (y, x, MPFR_RNDD); + /* y should be -0.5 */ + MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_si_2exp (y, -1, -1) == 0); + mpfr_set_prec (y, 3); + mpfr_j0 (y, x, MPFR_RNDD); + /* y should be -0.4375 */ + MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_si_2exp (y, -7, -4) == 0); + + /* Case for which s = 0 in mpfr_jn */ + mpfr_set_prec (x, 44); + mpfr_set_prec (y, 44); + mpfr_set_si (x, 2, MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_j0 (y, x, MPFR_RNDN); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_INEXACT); + mpfr_set_str (x, "0x.e5439fd9267p-2", 0, MPFR_RNDN); + if (! mpfr_equal_p (y, x)) + { + printf ("Error on 2:\n"); + printf ("Expected "); + mpfr_dump (x); + printf ("Got "); + mpfr_dump (y); + exit (1); + } + if (inex >= 0) + { + printf ("Bad ternary value on 2: expected negative, got %d\n", inex); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + + test_generic (2, 100, 10); + + data_check ("data/j0", mpfr_j0, "mpfr_j0"); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tj1.c b/mpfr/tests/tj1.c new file mode 100644 index 0000000000..fe5bb8d670 --- /dev/null +++ b/mpfr/tests/tj1.c @@ -0,0 +1,88 @@ +/* tj1 -- test file for the Bessel function of first kind (order 1) + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_j1 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS) +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + /* special values */ + mpfr_set_nan (x); + mpfr_j1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_j1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_inf (x, -1); /* -Inf */ + mpfr_j1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ + mpfr_j1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j1(+0)=+0 */ + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_j1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j1(-0)=-0 */ + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_j1 (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.0111000010100111001001111011101001011100001100011011"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_j1 for x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + + test_generic (2, 100, 10); + + data_check ("data/j1", mpfr_j1, "mpfr_j1"); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tjn.c b/mpfr/tests/tjn.c new file mode 100644 index 0000000000..3fe28ef0cc --- /dev/null +++ b/mpfr/tests/tjn.c @@ -0,0 +1,307 @@ +/* tjn -- test file for the Bessel function of first kind + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> /* for LONG_MAX */ + +#include "mpfr-test.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + long n; + + if (argc > 1) + { + mpfr_init2 (x, atoi (argv[1])); + mpfr_set_str (x, argv[3], 10, MPFR_RNDN); + mpfr_jn (x, atoi (argv[2]), x, MPFR_RNDN); + mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN); + printf ("\n"); + mpfr_clear (x); + return 0; + } + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + /* special values */ + mpfr_set_nan (x); + mpfr_jn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_jn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_inf (x, -1); /* -Inf */ + mpfr_jn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ + mpfr_jn (y, 0, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(+0)=1 */ + mpfr_jn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j17(+0)=+0 */ + mpfr_jn (y, -17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j-17(+0)=-0 */ + mpfr_jn (y, 42, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j42(+0)=+0 */ + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_jn (y, 0, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(-0)=1 */ + mpfr_jn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j17(-0)=-0 */ + mpfr_jn (y, -17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j-17(-0)=+0 */ + mpfr_jn (y, 42, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j42(-0)=+0 */ + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_jn (y, 0, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=0, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_jn (y, 0, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=0, x=-1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_jn (y, 1, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.0111000010100111001001111011101001011100001100011011"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=1, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_jn (y, 17, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100011111001010101001001001000110110000010001011E-65"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=17, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_jn (y, 42, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=42, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_jn (y, -42, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=-42, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_jn (y, 42, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=42, x=-1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_jn (y, -42, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=-42, x=-1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 4, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.0001110001011001100010100111100111100000111110111011111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=4, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 16, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.0011101111100111101111010100000111111001111001001010011"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=16, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 256, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.11111101111100110000000010111101101011101011110001011E-894"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=256, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 65536, x, MPFR_RNDN); + mpfr_set_str_binary (x, "100010010010011010110101100001000100011100010111011E-751747"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=65536, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 131072, x, MPFR_RNDN); + mpfr_set_str_binary (x, "1000001001110011111001110110000010011010000001001101E-1634508"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=131072, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 262144, x, MPFR_RNDN); + mpfr_set_str_binary (x, "1010011011000100111011001011110001000010000010111111E-3531100"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=262144, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, 524288, x, MPFR_RNDN); + mpfr_set_str_binary (x, "110000001010001111011011000011001011010100010001011E-7586426"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=524288, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + n = LONG_MAX; + /* ensures n is odd */ + if (n % 2 == 0) + n --; + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, n, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=%ld, x=17, rnd=MPFR_RNDN\n", n); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -17, MPFR_RNDN); + mpfr_jn (y, n, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=%ld, x=-17, rnd=MPFR_RNDN\n", n); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_jn (y, -n, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=%ld, x=17, rnd=MPFR_RNDN\n", -n); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -17, MPFR_RNDN); + mpfr_jn (y, -n, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_jn for n=%ld, x=-17, rnd=MPFR_RNDN\n", -n); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tl2b.c b/mpfr/tests/tl2b.c new file mode 100644 index 0000000000..e385443108 --- /dev/null +++ b/mpfr/tests/tl2b.c @@ -0,0 +1,174 @@ +/* Test file for l2b constants. + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Execute this program with an argument to generate code that initializes + the l2b constants. */ + +#include <stdio.h> +#include <stdlib.h> +#include "mpfr-test.h" + +/* Must be a multiple of 4 */ +static const int bits2use[] = {16, 32, 64, 96, 128, 256}; +#define size_of_bits2use ((sizeof bits2use) / sizeof bits2use[0]) + +static __mpfr_struct l2b[BASE_MAX-1][2]; + +static void +print_mpfr (mpfr_srcptr x, const char *name) +{ + unsigned char temp[16]; /* buffer for the base-256 string */ + unsigned char *ptr; /* pointer to its first non-zero byte */ + int size; /* size of the string */ + int i; /* bits2use index */ + int j; /* output limb index */ + int k; /* byte index (in output limb) */ + int r; /* digit index, relative to ptr */ + + if (printf ("#if 0\n") < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } + for (i = 0; i < size_of_bits2use; i++) + { + if (printf ("#elif GMP_NUMB_BITS == %d\n" + "const mp_limb_t %s__tab[] = { 0x", bits2use[i], name) < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } + size = mpn_get_str (temp, 256, MPFR_MANT (x), MPFR_LIMB_SIZE (x)); + MPFR_ASSERTN (size <= 16); + ptr = temp; + /* Skip leading zeros. */ + while (*ptr == 0) + { + ptr++; + size--; + MPFR_ASSERTN (size > 0); + } + MPFR_ASSERTN (*ptr >= 128); + for (j = (MPFR_PREC (x) - 1) / bits2use[i]; j >= 0; j--) + { + r = j * (bits2use[i] / 8); + for (k = 0; k < bits2use[i] / 8; k++) + if (printf ("%02x", r < size ? ptr[r++] : 0) < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } + if (printf (j == 0 ? " };\n" : ", 0x") < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } + } + } + if (printf ("#endif\n\n") < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } +} + +static void +compute_l2b (int output) +{ + mpfr_ptr p; + mpfr_srcptr t; + int beta, i; + int error = 0; + char buffer[30]; + + for (beta = 2; beta <= BASE_MAX; beta++) + { + for (i = 0; i < 2; i++) + { + p = &l2b[beta-2][i]; + + /* Compute the value */ + if (i == 0) + { + /* 23-bit upper approximation to log(b)/log(2) */ + mpfr_init2 (p, 23); + mpfr_set_ui (p, beta, MPFR_RNDU); + mpfr_log2 (p, p, MPFR_RNDU); + } + else + { + /* 76-bit upper approximation to log(2)/log(b) */ + mpfr_init2 (p, 77); + mpfr_set_ui (p, beta, MPFR_RNDD); + mpfr_log2 (p, p, MPFR_RNDD); + mpfr_ui_div (p, 1, p, MPFR_RNDU); + } + + sprintf (buffer, "mpfr_l2b_%d_%d", beta, i); + if (output) + print_mpfr (p, buffer); + + /* Check the value */ + t = &__gmpfr_l2b[beta-2][i]; + if (t == NULL || MPFR_PREC (t) == 0 || !mpfr_equal_p (p, t)) + { + if (!output) + { + error = 1; + printf ("Error for constant %s\n", buffer); + } + } + + if (!output) + mpfr_clear (p); + } + } + + if (output) + { + if (printf ("const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2] = {\n") + < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } + for (beta = 2; beta <= BASE_MAX; beta++) + { + for (i = 0; i < 2; i++) + { + p = &l2b[beta-2][i]; + if (printf (" %c {%3d,%2d,%3ld, (mp_limb_t *) " + "mpfr_l2b_%d_%d__tab }%s\n", i == 0 ? '{' : ' ', + (int) MPFR_PREC (p), MPFR_SIGN (p), + (long) MPFR_GET_EXP (p), beta, i, + i == 0 ? "," : beta < BASE_MAX ? " }," : " } };") + < 0) + { fprintf (stderr, "Error in printf\n"); exit (1); } + mpfr_clear (p); + } + } + } + + /* If there was an error, the test fails. */ + if (error) + exit (1); +} + +int +main (int argc, char *argv[]) +{ + if (argc != 1) + { + /* Generate code that initializes the l2b constants. */ + compute_l2b (1); + } + else + { + /* Check the l2b constants. */ + tests_start_mpfr (); + compute_l2b (0); + tests_end_mpfr (); + } + return 0; +} diff --git a/mpfr/tests/tlgamma.c b/mpfr/tests/tlgamma.c new file mode 100644 index 0000000000..d2f0f53517 --- /dev/null +++ b/mpfr/tests/tlgamma.c @@ -0,0 +1,403 @@ +/* mpfr_tlgamma -- test file for lgamma function + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static int +mpfr_lgamma_nosign (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) +{ + int inex, sign; + + inex = mpfr_lgamma (y, &sign, x, rnd); + if (!MPFR_IS_SINGULAR (y)) + { + MPFR_ASSERTN (sign == 1 || sign == -1); + if (sign == -1 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ)) + { + mpfr_neg (y, y, MPFR_RNDN); + inex = -inex; + /* This is a way to check with the generic tests, that the value + returned in the sign variable is consistent, but warning! The + tested function depends on the rounding mode: it is + * lgamma(x) = log(|Gamma(x)|) in MPFR_RNDD and MPFR_RNDU; + * lgamma(x) * sign(Gamma(x)) in MPFR_RNDN and MPFR_RNDZ. */ + } + } + + return inex; +} + +#define TEST_FUNCTION mpfr_lgamma_nosign +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int inex; + int sign; + mpfr_exp_t emin, emax; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for lgamma(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for lgamma(-Inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1) + { + printf ("Error for lgamma(+Inf)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1) + { + printf ("Error for lgamma(+0)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != -1) + { + printf ("Error for lgamma(-0)\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1) + { + printf ("Error for lgamma(1)\n"); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error for lgamma(-1)\n"); + exit (1); + } + + mpfr_set_ui (x, 2, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1) + { + printf ("Error for lgamma(2)\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + +#define CHECK_X1 "1.0762904832837976166" +#define CHECK_Y1 "-0.039418362817587634939" + + mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN); + if (mpfr_equal_p (y, x) == 0 || sign != 1) + { + printf ("mpfr_lgamma("CHECK_X1") is wrong:\n" + "expected "); + mpfr_print_binary (x); putchar ('\n'); + printf ("got "); + mpfr_print_binary (y); putchar ('\n'); + exit (1); + } + +#define CHECK_X2 "9.23709516716202383435e-01" +#define CHECK_Y2 "0.049010669407893718563" + mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN); + if (mpfr_equal_p (y, x) == 0 || sign != 1) + { + printf ("mpfr_lgamma("CHECK_X2") is wrong:\n" + "expected "); + mpfr_print_binary (x); putchar ('\n'); + printf ("got "); + mpfr_print_binary (y); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 8); + mpfr_set_prec (y, 175); + mpfr_set_ui (x, 33, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDU); + mpfr_set_prec (x, 175); + mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7"); + if (mpfr_equal_p (x, y) == 0 || sign != 1) + { + printf ("Error in mpfr_lgamma (1)\n"); + exit (1); + } + + mpfr_set_prec (x, 21); + mpfr_set_prec (y, 8); + mpfr_set_ui (y, 120, MPFR_RNDN); + sign = -17; + mpfr_lgamma (x, &sign, y, MPFR_RNDZ); + mpfr_set_prec (y, 21); + mpfr_set_str_binary (y, "0.111000101000001100101E9"); + if (mpfr_equal_p (x, y) == 0 || sign != 1) + { + printf ("Error in mpfr_lgamma (120)\n"); + printf ("Expected "); mpfr_print_binary (y); puts (""); + printf ("Got "); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 206); + mpfr_set_str_binary (x, "0.110e10"); + sign = -17; + inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_prec (x, 206); + mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13"); + if (mpfr_equal_p (x, y) == 0 || sign != 1) + { + printf ("Error in mpfr_lgamma (768)\n"); + exit (1); + } + if (inex >= 0) + { + printf ("Wrong flag for mpfr_lgamma (768)\n"); + exit (1); + } + + mpfr_set_prec (x, 4); + mpfr_set_prec (y, 4); + mpfr_set_str_binary (x, "0.1100E-66"); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100E6"); + if (mpfr_equal_p (x, y) == 0 || sign != 1) + { + printf ("Error for lgamma(0.1100E-66)\n"); + printf ("Expected "); + mpfr_dump (x); + printf ("Got "); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 256); + mpfr_set_prec (y, 32); + mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN); + mpfr_add_ui (x, x, 1, MPFR_RNDN); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_prec (x, 32); + mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207"); + if (mpfr_equal_p (x, y) == 0 || sign != 1) + { + printf ("Error for lgamma(-2^199+0.5)\n"); + printf ("Got "); + mpfr_dump (y); + printf ("instead of "); + mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 256); + mpfr_set_prec (y, 32); + mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN); + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + sign = -17; + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_prec (x, 32); + mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207"); + if (mpfr_equal_p (x, y) == 0 || sign != -1) + { + printf ("Error for lgamma(-2^199-0.5)\n"); + printf ("Got "); + mpfr_dump (y); + printf ("with sign %d instead of ", sign); + mpfr_dump (x); + printf ("with sign -1.\n"); + exit (1); + } + + mpfr_set_prec (x, 10); + mpfr_set_prec (y, 10); + mpfr_set_str_binary (x, "-0.1101111000E-3"); + inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, "10.01001011"); + if (mpfr_equal_p (x, y) == 0 || sign != -1 || inex >= 0) + { + printf ("Error for lgamma(-0.1101111000E-3)\n"); + printf ("Got "); + mpfr_dump (y); + printf ("instead of "); + mpfr_dump (x); + printf ("with sign %d instead of -1 (inex=%d).\n", sign, inex); + exit (1); + } + + mpfr_set_prec (x, 18); + mpfr_set_prec (y, 28); + mpfr_set_str_binary (x, "-1.10001101010001101e-196"); + inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_prec (x, 28); + mpfr_set_str_binary (x, "0.100001110110101011011010011E8"); + MPFR_ASSERTN (mpfr_equal_p (x, y) && inex < 0); + + /* values reported by Kaveh Ghazi on 14 Jul 2007, where mpfr_lgamma() + takes forever */ +#define VAL1 "-0.11100001001010110111001010001001001011110100110000110E-55" +#define OUT1 "100110.01000000010111001110110101110101001001100110111" +#define VAL2 "-0.11100001001010110111001010001001001011110011111111100E-55" +#define OUT2 "100110.0100000001011100111011010111010100100110011111" +#define VAL3 "-0.11100001001010110111001010001001001001110101101010100E-55" +#define OUT3 "100110.01000000010111001110110101110101001011110111011" +#define VAL4 "-0.10001111110110110100100100000000001111110001001001011E-57" +#define OUT4 "101000.0001010111110011101101000101111111010001100011" +#define VAL5 "-0.10001111110110110100100100000000001111011111100001000E-57" +#define OUT5 "101000.00010101111100111011010001011111110100111000001" +#define VAL6 "-0.10001111110110110100100100000000001111011101100011001E-57" +#define OUT6 "101000.0001010111110011101101000101111111010011101111" + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_str_binary (x, VAL1); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, OUT1); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p(x, y)); + + mpfr_set_str_binary (x, VAL2); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, OUT2); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); + + mpfr_set_str_binary (x, VAL3); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, OUT3); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); + + mpfr_set_str_binary (x, VAL4); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, OUT4); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); + + mpfr_set_str_binary (x, VAL5); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, OUT5); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); + + mpfr_set_str_binary (x, VAL6); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, OUT6); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); + + /* further test from Kaveh Ghazi */ + mpfr_set_str_binary (x, "-0.10011010101001010010001110010111010111011101010111001E-53"); + mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, "100101.00111101101010000000101010111010001111001101111"); + MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y)); + + /* bug found by Kevin Rauch on 26 Oct 2007 */ + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + mpfr_set_emin (-1000000000); + mpfr_set_emax (1000000000); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_lgamma (x, &sign, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_get_emin () == -1000000000); + MPFR_ASSERTN(mpfr_get_emax () == 1000000000); + mpfr_set_emin (emin); + mpfr_set_emax (emax); + + /* two other bugs reported by Kevin Rauch on 27 Oct 2007 */ + mpfr_set_prec (x, 128); + mpfr_set_prec (y, 128); + mpfr_set_str_binary (x, "0.11000110011110111111110010100110000000000000000000000000000000000000000000000000000000000000000001000011000110100100110111101010E-765689"); + inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_str_binary (x, "10000001100100101111011011010000111010001001110000111010011000101001011111011111110011011010110100101111110111001001010100011101E-108"); + MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0); + + mpfr_set_prec (x, 128); + mpfr_set_prec (y, 256); + mpfr_set_str_binary (x, "0.1011111111111111100000111011111E-31871"); + inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN); + mpfr_set_prec (x, 256); + mpfr_set_str (x, "AC9729B83707E6797612D0D76DAF42B1240A677FF1B6E3783FD4E53037143B1P-237", 16, MPFR_RNDN); + MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +static int +mpfr_lgamma1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r) +{ + int sign; + + return mpfr_lgamma (y, &sign, x, r); +} + +int +main (void) +{ + tests_start_mpfr (); + + special (); + test_generic (2, 100, 2); + + data_check ("data/lgamma", mpfr_lgamma1, "mpfr_lgamma"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tli2.c b/mpfr/tests/tli2.c new file mode 100644 index 0000000000..f388cd14e1 --- /dev/null +++ b/mpfr/tests/tli2.c @@ -0,0 +1,208 @@ +/* mpfr_tli2 -- test file for dilogarithm function + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +#define TEST_FUNCTION mpfr_li2 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_li2 (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for li2(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_li2 (y, x, MPFR_RNDN); + if (!MPFR_IS_INF (y) || MPFR_IS_POS (y)) + { + printf ("Error for li2(-Inf)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_li2 (y, x, MPFR_RNDN); + if (!MPFR_IS_INF (y) || MPFR_IS_POS (y)) + { + printf ("Error for li2(+Inf)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_li2 (y, x, MPFR_RNDN); + if (!MPFR_IS_ZERO (y) || MPFR_IS_NEG (y)) + { + printf ("Error for li2(+0)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_li2 (y, x, MPFR_RNDN); + if (!MPFR_IS_ZERO (y) || MPFR_IS_POS (y)) + { + printf ("Error for li2(-0)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +normal (void) +{ + int inexact; + mpfr_t x, y; + mpfr_init (x); + mpfr_init (y); + + /* x1 = 2^-3 */ + mpfr_set_str (x, "1p-3", 2, MPFR_RNDD); + mpfr_li2 (x, x, MPFR_RNDN); + if (mpfr_cmp_str (x, "0x1087a7a9e42141p-55", 16, MPFR_RNDN) != 0) + { + printf ("Error for li2(x1)\n"); + exit (1); + } + + /* check MPFR_FAST_COMPUTE_IF_SMALL_INPUT */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 20); + mpfr_set_ui_2exp (x, 1, -21, MPFR_RNDN); + mpfr_li2 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + mpfr_set_si_2exp (x, -1, -21, MPFR_RNDN); + mpfr_li2 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + /* worst case */ + /* x2 = 0x7F18EA6537E00E983196CDDC6EFAC57Fp-129 + Li2(x2) = 2^-2 + 2^-6 + 2^-120 */ + mpfr_set_prec (x, 128); + mpfr_set_str (x, "7F18EA6537E00E983196CDDC6EFAC57Fp-129", 16, MPFR_RNDN); + + /* round to nearest mode and 4 bits of precision, + it should be rounded to 2^-2 + 2^-5 and */ + mpfr_set_prec (y, 4); + inexact = mpfr_li2 (y, x, MPFR_RNDN); + if (inexact != 1 || mpfr_cmp_str (y, "0.1001p-1", 2, MPFR_RNDN) != 0) + { + printf ("Error for li2(x2, RNDN)\n"); + exit (1); + } + + /* round toward zero mode and 5 bits of precision, + it should be rounded to 2^-2 + 2^-6 */ + mpfr_set_prec (y, 5); + inexact = mpfr_li2 (y, x, MPFR_RNDZ); + if (inexact != -1 || mpfr_cmp_str (y, "0.10001p-1", 2, MPFR_RNDN) != 0) + { + printf ("Error for li2(x2, RNDZ)\n"); + exit (1); + } + + /* round away from zero mode and 5 bits of precision, + it should be rounded to 2^-2 + 2^-5 */ + inexact = mpfr_li2 (y, x, MPFR_RNDU); + if (inexact != 1 || mpfr_cmp_str (y, "0.10010p-1", 2, MPFR_RNDN) != 0) + { + printf ("Error for li2(x2, RNDU)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +bug20091013 (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init2 (x, 17); + mpfr_init2 (y, 2); + mpfr_set_str_binary (x, "0.10000000000000000E-16"); + inex = mpfr_li2 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (y, 1, -17) != 0) + { + printf ("Error in bug20091013()\n"); + printf ("expected 2^(-17)\n"); + printf ("got "); + mpfr_dump (y); + exit (1); + } + if (inex >= 0) + { + printf ("Error in bug20091013()\n"); + printf ("expected negative ternary value, got %d\n", inex); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + bug20091013 (); + + special (); + + normal (); + + test_generic (2, 100, 2); + + data_check ("data/li2", mpfr_li2, "mpfr_li2"); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tlngamma.c b/mpfr/tests/tlngamma.c new file mode 100644 index 0000000000..d2b4986df2 --- /dev/null +++ b/mpfr/tests/tlngamma.c @@ -0,0 +1,268 @@ +/* mpfr_tlngamma -- test file for lngamma function + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_lngamma +#define TEST_RANDOM_POS 16 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int i, inex; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for lngamma(NaN)\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || __gmpfr_flags != 0) + { + printf ("Error for lngamma(+Inf)\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || __gmpfr_flags != 0) + { + printf ("Error for lngamma(-Inf)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || + __gmpfr_flags != MPFR_FLAGS_DIVBY0) + { + printf ("Error for lngamma(+0)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || + __gmpfr_flags != MPFR_FLAGS_DIVBY0) + { + printf ("Error for lngamma(-0)\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_lngamma (y, x, MPFR_RNDN); + if (mpfr_cmp_ui0 (y, 0) || MPFR_IS_NEG (y)) + { + printf ("Error for lngamma(1)\n"); + exit (1); + } + + for (i = 1; i <= 5; i++) + { + int c; + + mpfr_set_si (x, -i, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || + __gmpfr_flags != MPFR_FLAGS_DIVBY0) + { + printf ("Error for lngamma(-%d)\n", i); + exit (1); + } + if (i & 1) + { + mpfr_nextabove (x); + c = '+'; + } + else + { + mpfr_nextbelow (x); + c = '-'; + } + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for lngamma(-%d%cepsilon)\n", i, c); + exit (1); + } + } + + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_lngamma (y, x, MPFR_RNDN); + if (mpfr_cmp_ui0 (y, 0) || MPFR_IS_NEG (y)) + { + printf ("Error for lngamma(2)\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + +#define CHECK_X1 "1.0762904832837976166" +#define CHECK_Y1 "-0.039418362817587634939" + + mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN); + mpfr_lngamma (y, x, MPFR_RNDN); + mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN); + if (MPFR_IS_NAN (y) || mpfr_cmp (y, x)) + { + printf ("mpfr_lngamma("CHECK_X1") is wrong:\n" + "expected "); + mpfr_print_binary (x); putchar ('\n'); + printf ("got "); + mpfr_print_binary (y); putchar ('\n'); + exit (1); + } + +#define CHECK_X2 "9.23709516716202383435e-01" +#define CHECK_Y2 "0.049010669407893718563" + mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN); + mpfr_lngamma (y, x, MPFR_RNDN); + mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN); + if (mpfr_cmp0 (y, x)) + { + printf ("mpfr_lngamma("CHECK_X2") is wrong:\n" + "expected "); + mpfr_print_binary (x); putchar ('\n'); + printf ("got "); + mpfr_print_binary (y); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 8); + mpfr_set_prec (y, 175); + mpfr_set_ui (x, 33, MPFR_RNDN); + mpfr_lngamma (y, x, MPFR_RNDU); + mpfr_set_prec (x, 175); + mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7"); + if (mpfr_cmp0 (x, y)) + { + printf ("Error in mpfr_lngamma (1)\n"); + exit (1); + } + + mpfr_set_prec (x, 21); + mpfr_set_prec (y, 8); + mpfr_set_ui (y, 120, MPFR_RNDN); + mpfr_lngamma (x, y, MPFR_RNDZ); + mpfr_set_prec (y, 21); + mpfr_set_str_binary (y, "0.111000101000001100101E9"); + if (mpfr_cmp0 (x, y)) + { + printf ("Error in mpfr_lngamma (120)\n"); + printf ("Expected "); mpfr_print_binary (y); puts (""); + printf ("Got "); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 206); + mpfr_set_str_binary (x, "0.110e10"); + inex = mpfr_lngamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 206); + mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13"); + if (mpfr_cmp0 (x, y)) + { + printf ("Error in mpfr_lngamma (768)\n"); + exit (1); + } + if (inex >= 0) + { + printf ("Wrong flag for mpfr_lngamma (768)\n"); + exit (1); + } + + mpfr_set_prec (x, 4); + mpfr_set_prec (y, 4); + mpfr_set_str_binary (x, "0.1100E-66"); + mpfr_lngamma (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1100E6"); + if (mpfr_cmp0 (x, y)) + { + printf ("Error for lngamma(0.1100E-66)\n"); + exit (1); + } + + mpfr_set_prec (x, 256); + mpfr_set_prec (y, 32); + mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN); + mpfr_add_ui (x, x, 1, MPFR_RNDN); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + mpfr_lngamma (y, x, MPFR_RNDN); + mpfr_set_prec (x, 32); + mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207"); + if (mpfr_cmp0 (x, y)) + { + printf ("Error for lngamma(-2^199+0.5)\n"); + printf ("Got "); + mpfr_dump (y); + printf ("instead of "); + mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 256); + mpfr_set_prec (y, 32); + mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN); + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + mpfr_lngamma (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error for lngamma(-2^199-0.5)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (void) +{ + tests_start_mpfr (); + + special (); + test_generic (2, 100, 2); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tlog.c b/mpfr/tests/tlog.c new file mode 100644 index 0000000000..0d2bef92fb --- /dev/null +++ b/mpfr/tests/tlog.c @@ -0,0 +1,361 @@ +/* Test file for mpfr_log. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_log (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_log (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_log mpfr_log +#endif + +static void +check2 (const char *as, mpfr_rnd_t rnd_mode, const char *res1s) +{ + mpfr_t ta, tres; + + mpfr_inits2 (53, ta, tres, (mpfr_ptr) 0); + mpfr_set_str1 (ta, as); + test_log (tres, ta, rnd_mode); + + if (mpfr_cmp_str1 (tres, res1s)) + { + printf ("mpfr_log failed for a=%s, rnd_mode=%s\n", + as, mpfr_print_rnd_mode (rnd_mode)); + printf ("correct result is %s\n mpfr_log gives ", + res1s); + mpfr_out_str(stdout, 10, 0, tres, MPFR_RNDN); + exit (1); + } + mpfr_clears (ta, tres, (mpfr_ptr) 0); +} + +static void +check3 (double d, unsigned long prec, mpfr_rnd_t rnd) +{ + mpfr_t x, y; + + mpfr_init2 (x, prec); + mpfr_init2 (y, prec); + mpfr_set_d (x, d, rnd); + test_log (y, x, rnd); + mpfr_out_str (stdout, 10, 0, y, rnd); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); +} + +/* examples from Jean-Michel Muller and Vincent Lefevre + Cf http://www.ens-lyon.fr/~jmmuller/Intro-to-TMD.htm +*/ + +static void +check_worst_cases (void) +{ + check2("1.00089971802309629645", MPFR_RNDD, "8.99313519443722736088e-04"); + check2("1.00089971802309629645", MPFR_RNDN, "8.99313519443722844508e-04"); + check2("1.00089971802309629645", MPFR_RNDU, "8.99313519443722844508e-04"); + + check2("1.01979300812244555452", MPFR_RNDD, "1.95996734891603630047e-02"); + check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02"); + check2("1.01979300812244555452", MPFR_RNDU, "1.95996734891603664741e-02"); + + check2("1.02900871924604464525", MPFR_RNDD, "2.85959303301472726744e-02"); + check2("1.02900871924604464525", MPFR_RNDN, "2.85959303301472761438e-02"); + check2("1.02900871924604464525", MPFR_RNDU, "2.85959303301472761438e-02"); + + check2("1.27832870030418943585", MPFR_RNDD, "2.45553521871417795852e-01"); + check2("1.27832870030418943585", MPFR_RNDN, "2.45553521871417823608e-01"); + check2("1.27832870030418943585", MPFR_RNDU, "2.45553521871417823608e-01"); + + check2("1.31706530746788241792", MPFR_RNDD, "2.75406009586277422674e-01"); + check2("1.31706530746788241792", MPFR_RNDN, "2.75406009586277478185e-01"); + check2("1.31706530746788241792", MPFR_RNDU, "2.75406009586277478185e-01"); + + check2("1.47116981099449883885", MPFR_RNDD, "3.86057874110010412760e-01"); + check2("1.47116981099449883885", MPFR_RNDN, "3.86057874110010412760e-01"); + check2("1.47116981099449883885", MPFR_RNDU, "3.86057874110010468272e-01"); + + check2("1.58405446812987782401", MPFR_RNDD, "4.59987679246663727639e-01"); + check2("1.58405446812987782401", MPFR_RNDN, "4.59987679246663783150e-01"); + check2("1.58405446812987782401", MPFR_RNDU, "4.59987679246663783150e-01"); + + check2("1.67192331263391547047", MPFR_RNDD, "5.13974647961076613889e-01"); + check2("1.67192331263391547047", MPFR_RNDN, "5.13974647961076724911e-01"); + check2("1.67192331263391547047", MPFR_RNDU, "5.13974647961076724911e-01"); + + check2("1.71101198068990645318", MPFR_RNDD, "5.37084997042120315669e-01"); + check2("1.71101198068990645318", MPFR_RNDN, "5.37084997042120315669e-01"); + check2("1.71101198068990645318", MPFR_RNDU, "5.37084997042120426691e-01"); + + check2("1.72634853551388700588", MPFR_RNDD, "5.46008504786553605648e-01"); + check2("1.72634853551388700588", MPFR_RNDN, "5.46008504786553716670e-01"); + check2("1.72634853551388700588", MPFR_RNDU, "5.46008504786553716670e-01"); + + check2("2.00028876593004323325", MPFR_RNDD, "6.93291553102749702475e-01"); + check2("2.00028876593004323325", MPFR_RNDN, "6.93291553102749813497e-01"); + check2("2.00028876593004323325", MPFR_RNDU, "6.93291553102749813497e-01"); + + check2("6.27593230200363105808", MPFR_RNDD, "1.83672204800630312072"); + check2("6.27593230200363105808", MPFR_RNDN, "1.83672204800630334276"); + check2("6.27593230200363105808", MPFR_RNDU, "1.83672204800630334276"); + + check2("7.47216682321367997588", MPFR_RNDD, "2.01118502712453661729"); + check2("7.47216682321367997588", MPFR_RNDN, "2.01118502712453706138"); + check2("7.47216682321367997588", MPFR_RNDU, "2.01118502712453706138"); + + check2("9.34589857718275318632", MPFR_RNDD, "2.23493759221664944903"); + check2("9.34589857718275318632", MPFR_RNDN, "2.23493759221664989312"); + check2("9.34589857718275318632", MPFR_RNDU, "2.23493759221664989312"); + + check2("10.6856587560831854944", MPFR_RNDD, "2.36890253928838445674"); + check2("10.6856587560831854944", MPFR_RNDN, "2.36890253928838445674"); + check2("10.6856587560831854944", MPFR_RNDU, "2.36890253928838490083"); + + check2("12.4646345033981766903", MPFR_RNDD, "2.52289539471636015122"); + check2("12.4646345033981766903", MPFR_RNDN, "2.52289539471636015122"); + check2("12.4646345033981766903", MPFR_RNDU, "2.52289539471636059531"); + + check2("17.0953275851761752335", MPFR_RNDD, "2.83880518553861849185"); + check2("17.0953275851761752335", MPFR_RNDN, "2.83880518553861893594"); + check2("17.0953275851761752335", MPFR_RNDU, "2.83880518553861893594"); + + check2("19.8509496207496916043", MPFR_RNDD, "2.98825184582516722998"); + check2("19.8509496207496916043", MPFR_RNDN, "2.98825184582516722998"); + check2("19.8509496207496916043", MPFR_RNDU, "2.98825184582516767406"); + + check2("23.9512076062771335216", MPFR_RNDD, "3.17601874455977206679"); + check2("23.9512076062771335216", MPFR_RNDN, "3.17601874455977206679"); + check2("23.9512076062771335216", MPFR_RNDU, "3.17601874455977251088"); + + check2("428.315247165198229595", MPFR_RNDD, "6.05985948325268264369"); + check2("428.315247165198229595", MPFR_RNDN, "6.05985948325268353187"); + check2("428.315247165198229595", MPFR_RNDU, "6.05985948325268353187"); +} + +static void +special (void) +{ + mpfr_t x, y; + int inex; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + /* Check special case: An overflow in const_pi could occurs! */ + set_emin (-125); + set_emax (128); + mpfr_set_prec (y, 24*2); + mpfr_set_prec (x, 24); + mpfr_set_str_binary (x, "0.111110101010101011110101E0"); + test_log (y, x, MPFR_RNDN); + set_emin (emin); + set_emax (emax); + + mpfr_set_prec (y, 53); + mpfr_set_prec (x, 53); + mpfr_set_ui (x, 3, MPFR_RNDD); + test_log (y, x, MPFR_RNDD); + if (mpfr_cmp_str1 (y, "1.09861228866810956")) + { + printf ("Error in mpfr_log(3) for MPFR_RNDD\n"); + exit (1); + } + + /* check large precision */ + mpfr_set_prec (x, 3322); + mpfr_set_prec (y, 3322); + mpfr_set_ui (x, 3, MPFR_RNDN); + mpfr_sqrt (x, x, MPFR_RNDN); + test_log (y, x, MPFR_RNDN); + + /* negative argument */ + mpfr_set_si (x, -1, MPFR_RNDN); + test_log (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + /* infinite loop when */ + set_emax (128); + mpfr_set_prec (x, 251); + mpfr_set_prec (y, 251); + mpfr_set_str_binary (x, "0.10010111000000000001101E8"); + /* x = 4947981/32768, log(x) ~ 5.017282... */ + test_log (y, x, MPFR_RNDN); + + set_emax (emax); + + mpfr_set_ui (x, 0, MPFR_RNDN); + inex = test_log (y, x, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) < 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + inex = test_log (y, x, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) < 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +x_near_one (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 16); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextbelow (x); + inex = mpfr_log (y, x, MPFR_RNDD); + if (mpfr_cmp_str (y, "-0.1000000000000001E-31", 2, MPFR_RNDN) + || inex >= 0) + { + printf ("Failure in x_near_one, got inex = %d and\ny = ", inex); + mpfr_dump (y); + } + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION test_log +#define TEST_RANDOM_POS 8 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + if (argc==4) + { /* tlog x prec rnd */ + check3 (atof(argv[1]), atoi(argv[2]), (mpfr_rnd_t) atoi(argv[3])); + goto done; + } + + special (); + check_worst_cases(); + + check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02"); + check2("10.0",MPFR_RNDU,"2.30258509299404590110e+00"); + check2("6.0",MPFR_RNDU,"1.79175946922805517936"); + check2("1.0",MPFR_RNDZ,"0.0"); + check2("62.0",MPFR_RNDU,"4.12713438504509166905"); + check2("0.5",MPFR_RNDZ,"-6.93147180559945286226e-01"); + check2("3.0",MPFR_RNDZ,"1.09861228866810956006e+00"); + check2("234375765.0",MPFR_RNDU,"1.92724362186836231104e+01"); + check2("8.0",MPFR_RNDZ,"2.07944154167983574765e+00"); + check2("44.0",MPFR_RNDU,"3.78418963391826146392e+00"); + check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02"); + + /* bugs found by Vincent Lefe`vre */ + check2("0.99999599881598921769", MPFR_RNDN, "-0.0000040011920155404072924737977900999652547398000024259090423583984375"); + check2("9.99995576063808955247e-01",MPFR_RNDZ,"-4.42394597667932383816e-06"); + check2("9.99993687357856209097e-01",MPFR_RNDN,"-6.31266206860017342601e-06"); + check2("9.99995223520736886691e-01",MPFR_RNDN,"-4.77649067052670982220e-06"); + check2("9.99993025794720935551e-01",MPFR_RNDN,"-6.97422959894716163837e-06"); + check2("9.99987549017837484833e-01",MPFR_RNDN,"-1.24510596766369924330e-05"); + check2("9.99985901426543311032e-01",MPFR_RNDN,"-1.40986728425098585229e-05"); + check2("9.99986053947420794330e-01",MPFR_RNDN, "-0.000013946149826301084938555592540598837558718514628708362579345703125"); + check2("9.99971938247442126979e-01",MPFR_RNDN,"-2.80621462962173414790e-05"); + + /* other bugs found by Vincent Lefe`vre */ + check2("1.18615436389927785905e+77",MPFR_RNDN,"1.77469768607706015473e+02"); + check2("9.48868723578399476187e+77",MPFR_RNDZ,"1.79549152432275803903e+02"); + check2("2.31822210096938820854e+89",MPFR_RNDN,"2.05770873832573869322e+02"); + + /* further bugs found by Vincent Lefe`vre */ + check2("9.99999989485669482647e-01",MPFR_RNDZ,"-1.05143305726283042331e-08"); + check2("9.99999989237970177136e-01",MPFR_RNDZ,"-1.07620298807745377934e-08"); + check2("9.99999989239339082125e-01",MPFR_RNDN,"-1.07606609757704445430e-08"); + + check2("7.3890560989306504",MPFR_RNDU,"2.0000000000000004"); /* exp(2.0) */ + check2("7.3890560989306495",MPFR_RNDU,"2.0"); /* exp(2.0) */ + check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01"); + check2("6.18784121531737948160e+19",MPFR_RNDZ,"4.55717030391710693493e+01"); + check2("1.02560267603047283735e+00",MPFR_RNDD,"2.52804164149448735987e-02"); + check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01"); + check2("1.42470900831881198052e+49",MPFR_RNDZ,"113.180637144887668910087086260318756103515625"); + + check2("1.08013816255293777466e+11",MPFR_RNDN,"2.54055249841782604392e+01"); + check2("6.72783635300509015581e-37",MPFR_RNDU,"-8.32893948416799503320e+01"); + check2("2.25904918906057891180e-52",MPFR_RNDU,"-1.18919480823735682406e+02"); + check2("1.48901209246462951085e+00",MPFR_RNDD,"3.98112874867437460668e-01"); + check2("1.70322470467612341327e-01",MPFR_RNDN,"-1.77006175364294615626"); + check2("1.94572026316065240791e+01",MPFR_RNDD,"2.96821731676437838842"); + check2("4.01419512207026418764e+04",MPFR_RNDD,"1.06001772315501128218e+01"); + check2("9.47077365236487591672e-04",MPFR_RNDZ,"-6.96212977303956748187e+00"); + check2("3.95906157687589643802e-109",MPFR_RNDD,"-2.49605768114704119399e+02"); + check2("2.73874914516503004113e-02",MPFR_RNDD,"-3.59766888618655977794e+00"); + check2("9.18989072589566467669e-17",MPFR_RNDZ,"-3.69258425351464083519e+01"); + check2("7706036453608191045959753324430048151991964994788917248.0",MPFR_RNDZ,"126.3815989984199177342816255986690521240234375"); + check2("1.74827399630587801934e-23",MPFR_RNDZ,"-5.24008281254547156891e+01"); + check2("4.35302958401482307665e+22",MPFR_RNDD,"5.21277441046519527390e+01"); + check2("9.70791868689332915209e+00",MPFR_RNDD,"2.27294191194272210410e+00"); + check2("2.22183639799464011100e-01",MPFR_RNDN,"-1.50425103275253957413e+00"); + check2("2.27313466156682375540e+00",MPFR_RNDD,"8.21159787095675608448e-01"); + check2("6.58057413965851156767e-01",MPFR_RNDZ,"-4.18463096196088235600e-01"); + check2 ("7.34302197248998461006e+43",MPFR_RNDZ,"101.0049094695131799426235374994575977325439453125"); + check2("6.09969788341579732815e+00",MPFR_RNDD,"1.80823924264386204363e+00"); + + x_near_one (); + + test_generic (2, 100, 40); + + data_check ("data/log", mpfr_log, "mpfr_log"); + bad_cases (mpfr_log, mpfr_exp, "mpfr_log", 256, -30, 30, 4, 128, 800, 50); + + done: + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tlog10.c b/mpfr/tests/tlog10.c new file mode 100644 index 0000000000..f46394ae7a --- /dev/null +++ b/mpfr/tests/tlog10.c @@ -0,0 +1,122 @@ +/* Test file for mpfr_log10. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_log10 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_log10 (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_log10 mpfr_log10 +#endif + +#define TEST_FUNCTION test_log10 +#define TEST_RANDOM_POS 8 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + unsigned int n; + int inex; + + tests_start_mpfr (); + + test_generic (2, 100, 20); + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + /* check NaN */ + mpfr_set_nan (x); + inex = test_log10 (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0); + + /* check Inf */ + mpfr_set_inf (x, -1); + inex = test_log10 (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0); + + mpfr_set_inf (x, 1); + inex = test_log10 (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0 && inex == 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + inex = test_log10 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + inex = test_log10 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); + + /* check negative argument */ + mpfr_set_si (x, -1, MPFR_RNDN); + inex = test_log10 (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0); + + /* check log10(1) = 0 */ + mpfr_set_ui (x, 1, MPFR_RNDN); + inex = test_log10 (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y) && inex == 0); + + /* check log10(10^n)=n */ + mpfr_set_ui (x, 1, MPFR_RNDN); + for (n = 1; n <= 15; n++) + { + mpfr_mul_ui (x, x, 10, MPFR_RNDN); /* x = 10^n */ + inex = test_log10 (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, n)) + { + printf ("log10(10^n) <> n for n=%u\n", n); + exit (1); + } + MPFR_ASSERTN (inex == 0); + } + + mpfr_clear (x); + mpfr_clear (y); + + data_check ("data/log10", mpfr_log10, "mpfr_log10"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tlog1p.c b/mpfr/tests/tlog1p.c new file mode 100644 index 0000000000..beac2459e5 --- /dev/null +++ b/mpfr/tests/tlog1p.c @@ -0,0 +1,150 @@ +/* Test file for mpfr_log1p. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_log1p (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_log1p (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_log1p mpfr_log1p +#endif + +#define TEST_FUNCTION test_log1p +#define TEST_RANDOM_EMAX 80 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x; + int inex; + + mpfr_init (x); + + mpfr_set_nan (x); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) > 0 && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x) && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG (x) && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + mpfr_set_si (x, -2, MPFR_RNDN); + mpfr_clear_flags (); + inex = test_log1p (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + mpfr_clear (x); +} + +static void +other (void) +{ + mpfr_t x, y; + + /* Bug reported by Guillaume Melquiond on 2006-08-14. */ + mpfr_init2 (x, 53); + mpfr_set_str (x, "-1.5e4f72873ed9a@-100", 16, MPFR_RNDN); + mpfr_init2 (y, 57); + mpfr_log1p (y, x, MPFR_RNDU); + if (mpfr_cmp (x, y) != 0) + { + printf ("Error in tlog1p for x = "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf (", rnd = MPFR_RNDU\nExpected "); + mpfr_out_str (stdout, 16, 15, x, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 16, 15, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); + return; +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + other (); + + test_generic (2, 100, 50); + + data_check ("data/log1p", mpfr_log1p, "mpfr_log1p"); + bad_cases (mpfr_log1p, mpfr_expm1, "mpfr_log1p", 256, -64, 40, + 4, 128, 800, 40); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tlog2.c b/mpfr/tests/tlog2.c new file mode 100644 index 0000000000..5a4b1d1ce3 --- /dev/null +++ b/mpfr/tests/tlog2.c @@ -0,0 +1,84 @@ +/* Test file for mpfr_log2. + +Copyright 2001-2002, 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_log2 +#define TEST_RANDOM_POS 8 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x; + int inex; + + mpfr_init (x); + + mpfr_set_nan (x); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0); + + mpfr_set_inf (x, -1); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0); + + mpfr_set_inf (x, 1); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) > 0 && inex == 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0); + + mpfr_set_si (x, -1, MPFR_RNDN); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0); + + mpfr_set_si (x, 1, MPFR_RNDN); + inex = mpfr_log2 (x, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x) && inex == 0); + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 30); + + data_check ("data/log2", mpfr_log2, "mpfr_log2"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tmin_prec.c b/mpfr/tests/tmin_prec.c new file mode 100644 index 0000000000..f5909260a2 --- /dev/null +++ b/mpfr/tests/tmin_prec.c @@ -0,0 +1,102 @@ +/* Test file for mpfr_min_prec. + +Copyright 2009-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + mpfr_prec_t ret; + unsigned long i; + + tests_start_mpfr (); + + mpfr_init2 (x, 53); + + /* Check special values */ + mpfr_set_nan (x); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 0); + + mpfr_set_inf (x, 1); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 0); + + mpfr_set_inf (x, -1); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 0); + + /* Some constants */ + + mpfr_set_ui (x, 1, MPFR_RNDN); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 1); + + mpfr_set_ui (x, 17, MPFR_RNDN); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 5); + + mpfr_set_ui (x, 42, MPFR_RNDN); + ret = mpfr_min_prec (x); + MPFR_ASSERTN (ret == 5); + + mpfr_set_prec (x, 256); + for (i = 0; i <= 255; i++) + { + mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN); + mpfr_add_ui (x, x, 1, MPFR_RNDN); + ret = mpfr_min_prec (x); + if (ret != i + 1) + { + printf ("Error for x = 2^%lu + 1\n", i); + printf ("Expected %lu, got %lu\n", i + 1, (unsigned long) ret); + exit (1); + } + } + + for (i = MPFR_PREC_MIN; i <= 255; i++) + { + mpfr_set_prec (x, i); + mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN); + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + ret = mpfr_min_prec (x); + if (ret != i) + { + printf ("Error for x = 2^%lu - 1\n", i); + printf ("Expected %lu, got %lu\n", i, (unsigned long) ret); + exit (1); + } + } + + mpfr_clear (x); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tminmax.c b/mpfr/tests/tminmax.c new file mode 100644 index 0000000000..61194a10d7 --- /dev/null +++ b/mpfr/tests/tminmax.c @@ -0,0 +1,171 @@ +/* Test file for mpfr_min & mpfr_max. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x, y, z; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + /* case x=NaN && y=NAN */ + mpfr_set_nan (x); + mpfr_set_nan (y); + mpfr_min (z, x, y, MPFR_RNDN); + if (!mpfr_nan_p (z)) + { + printf ("Error in mpfr_min (NaN, NaN)\n"); + exit (1); + } + mpfr_max (z, x, y, MPFR_RNDN); + if (!mpfr_nan_p (z)) + { + printf ("Error in mpfr_max (NaN, NaN)\n"); + exit (1); + } + /* case x=NaN */ + mpfr_set_nan (x); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_min (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0)) + { + printf ("Error in mpfr_min (NaN, 0)\n"); + exit (1); + } + mpfr_min (z, y, x, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0)) + { + printf ("Error in mpfr_min (0, NaN)\n"); + exit (1); + } + mpfr_max (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0)) + { + printf ("Error in mpfr_max (NaN, 0)\n"); + exit (1); + } + mpfr_max (z, y, x, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0)) + { + printf ("Error in mpfr_max (0, NaN)\n"); + exit (1); + } + /* Case x=0+ and x=0- */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); MPFR_SET_NEG(y); + mpfr_max (z, x, y, MPFR_RNDN); + if (!MPFR_IS_ZERO(z) || MPFR_IS_NEG(z)) + { + printf ("Error in mpfr_max (0+, 0-)\n"); + exit (1); + } + mpfr_min (z, x, y, MPFR_RNDN); + if (!MPFR_IS_ZERO(z) || MPFR_IS_POS(z)) + { + printf ("Error in mpfr_min (0+, 0-)\n"); + exit (1); + } + /* Case x=0- and y=0+ */ + mpfr_set_ui (x, 0, MPFR_RNDN); MPFR_SET_NEG(x); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_max (z, x, y, MPFR_RNDN); + if (!MPFR_IS_ZERO(z) || MPFR_IS_NEG(z)) + { + printf ("Error in mpfr_max (0+, 0-)\n"); + exit (1); + } + mpfr_min (z, x, y, MPFR_RNDN); + if (!MPFR_IS_ZERO(z) || MPFR_IS_POS(z)) + { + printf ("Error in mpfr_min (0+, 0-)\n"); + exit (1); + } + + /* case x=+Inf */ + mpfr_set_inf (x, 1); + mpfr_set_si (y, -12, MPFR_RNDN); + mpfr_min (z, x, y, MPFR_RNDN); + if ( mpfr_cmp_si (z, -12) ) + { + printf ("Error in mpfr_min (+Inf, -12)\n"); + exit (1); + } + mpfr_max (z, x, y, MPFR_RNDN); + if ( !MPFR_IS_INF(z) || MPFR_IS_NEG(z) ) + { + printf ("Error in mpfr_max (+Inf, 12)\n"); + exit (1); + } + /* case x=-Inf */ + mpfr_set_inf (x, -1); + mpfr_set_ui (y, 12, MPFR_RNDN); + mpfr_max (z, x, y, MPFR_RNDN); + if ( mpfr_cmp_ui (z, 12) ) + { + printf ("Error in mpfr_max (-Inf, 12)\n"); + exit (1); + } + mpfr_min (z, x, y, MPFR_RNDN); + if ( !MPFR_IS_INF(z) || MPFR_IS_POS(z) ) + { + printf ("Error in mpfr_min (-Inf, 12)\n"); + exit (1); + } + + /* case x=17 and y=42 */ + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_set_ui (y, 42, MPFR_RNDN); + mpfr_max (z, x, y, MPFR_RNDN); + if ( mpfr_cmp_ui (z, 42) ) + { + printf ("Error in mpfr_max (17, 42)\n"); + exit (1); + } + mpfr_max (z, y, x, MPFR_RNDN); + if ( mpfr_cmp_ui (z, 42) ) + { + printf ("Error in mpfr_max (42, 17)\n"); + exit (1); + } + mpfr_min (z, y, x, MPFR_RNDN); + if ( mpfr_cmp_ui (z, 17) ) + { + printf ("Error in mpfr_min (42, 17)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tmodf.c b/mpfr/tests/tmodf.c new file mode 100644 index 0000000000..b05de0c9da --- /dev/null +++ b/mpfr/tests/tmodf.c @@ -0,0 +1,236 @@ +/* Test file for mpfr_modf. + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check (const char *xis, const char *xfs, const char *xs, + mpfr_prec_t xip, mpfr_prec_t xfp, mpfr_prec_t xp, + int expected_return, mpfr_rnd_t rnd_mode) +{ + int inexact; + mpfr_t xi, xf, x; + + mpfr_init2 (xi, xip); + mpfr_init2 (xf, xfp); + mpfr_init2 (x, xp); + mpfr_set_str1 (x, xs); + inexact = mpfr_modf (xi, xf, x, rnd_mode); + if (mpfr_cmp_str1 (xi, xis)) + { + printf ("mpfr_modf failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode(rnd_mode)); + printf ("got integer value: "); + mpfr_out_str (stdout, 10, 0, xi, MPFR_RNDN); + printf ("\nexpected %s\n", xis); + exit (1); + } + if (mpfr_cmp_str1 (xf, xfs)) + { + printf ("mpfr_modf failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode(rnd_mode)); + printf ("got fractional value: "); + mpfr_out_str (stdout, 10, 0, xf, MPFR_RNDN); + printf ("\nexpected %s\n", xfs); + exit (1); + } + if (inexact != expected_return) + { + printf ("mpfr_modf failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode(rnd_mode)); + printf ("got return value: %d, expected %d\n", inexact, expected_return); + exit (1); + } + mpfr_clears (xi, xf, x, (mpfr_ptr) 0); +} + +static void +check_nans (void) +{ + mpfr_t x, xi, xf; + + mpfr_init2 (x, 123); + mpfr_init2 (xi, 123); + mpfr_init2 (xf, 123); + + /* nan */ + mpfr_set_nan (x); + mpfr_modf (xi, xf, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (xi)); + MPFR_ASSERTN (mpfr_nan_p (xf)); + + /* +inf */ + mpfr_set_inf (x, 1); + mpfr_modf (xi, xf, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (xi)); + MPFR_ASSERTN (mpfr_sgn (xi) > 0); + MPFR_ASSERTN (mpfr_zero_p (xf)); + + /* -inf */ + mpfr_set_inf (x, -1); + mpfr_modf (xi ,xf, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (xi)); + MPFR_ASSERTN (mpfr_sgn (xi) < 0); + MPFR_ASSERTN (mpfr_zero_p (xf)); + + mpfr_clear (x); + mpfr_clear (xi); + mpfr_clear (xf); +} + +static void +check_special_exprange (void) +{ + int inexact, ov; + unsigned int eflags, gflags; + mpfr_t xi, xf, x; + mpfr_exp_t emax; + + emax = mpfr_get_emax (); + mpfr_init2 (xi, 7); + mpfr_init2 (xf, 7); + mpfr_init2 (x, 8); + + mpfr_set_str (x, "0.11111111", 2, MPFR_RNDN); + for (ov = 0; ov <= 1; ov++) + { + const char *s = ov ? "@Inf@" : "1"; + + if (ov) + set_emax (0); + mpfr_clear_flags (); + inexact = mpfr_modf (xi, xf, x, MPFR_RNDN); + gflags = __gmpfr_flags; + set_emax (emax); + if (MPFR_NOTZERO (xi) || MPFR_IS_NEG (xi) || + mpfr_cmp_str1 (xf, s) != 0) + { + printf ("Error in check_special_exprange (ov = %d):" + " expected 0 and %s, got\n", ov, s); + mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN); + printf (" and "); + mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (inexact != 4) + { + printf ("Bad inexact value in check_special_exprange (ov = %d):" + " expected 4, got %d\n", ov, inexact); + exit (1); + } + eflags = MPFR_FLAGS_INEXACT | (ov ? MPFR_FLAGS_OVERFLOW : 0); + if (gflags != eflags) + { + printf ("Bad flags in check_special_exprange (ov = %d):" + " expected %u, got %u\n", ov, eflags, gflags); + exit (1); + } + } + + /* Test if an overflow occurs in mpfr_set for ope >= opq. */ + mpfr_set_emax (MPFR_EMAX_MAX); + mpfr_set_inf (x, 1); + mpfr_nextbelow (x); + mpfr_clear_flags (); + inexact = mpfr_modf (xi, xf, x, MPFR_RNDN); + gflags = __gmpfr_flags; + if (mpfr_cmp_str1 (xi, "@Inf@") != 0 || + MPFR_NOTZERO (xf) || MPFR_IS_NEG (xf)) + { + printf ("Error in check_special_exprange:" + " expected 0 and @Inf@, got\n"); + mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN); + printf (" and "); + mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN); + printf ("\n"); + exit (1); + } + if (inexact != 1) + { + printf ("Bad inexact value in check_special_exprange:" + " expected 1, got %d\n", inexact); + exit (1); + } + eflags = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW; + if (gflags != eflags) + { + printf ("Bad flags in check_special_exprange:" + " expected %u, got %u\n", eflags, gflags); + exit (1); + } + set_emax (emax); + + /* Test if an underflow occurs in the general case. TODO */ + + mpfr_clears (xi, xf, x, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_nans (); + + /* integer part is exact, frac. part is exact: return value should be 0 */ + check ("61680","3.52935791015625e-1", "61680.352935791015625", + 53, 53, 53, 0, MPFR_RNDZ); + /* integer part is rounded up, fractional part is rounded up: return value + should be 1+4*1=5 */ + check ("-53968","-3.529052734375e-1", "-53970.352935791015625", + 13, 13, 53, 5, MPFR_RNDZ); + /* integer part is rounded down, fractional part is rounded down: + return value should be 2+4*2=10 */ + check ("61632","3.525390625e-1", "61648.352935791015625", + 10, 10, 53, 10, MPFR_RNDZ); + check ("61680", "0", "61680", 53, 53, 53, 0, MPFR_RNDZ); + /* integer part is rounded up, fractional part is exact: 1 */ + check ("-53968","0", "-53970", 13, 13, 53, 1, MPFR_RNDZ); + /* integer part is rounded up, fractional part is exact: 1 */ + check ("-43392","0", "-43399", 13, 13, 53, 1, MPFR_RNDU); + /* integer part is rounded down, fractional part is exact: 2 */ + check ("-52720","0", "-52719", 13, 13, 53, 2, MPFR_RNDD); + /* integer part is rounded down, fractional part is exact: 2 */ + check ("61632", "0", "61648", 10, 10, 53, 2, MPFR_RNDZ); + + check_special_exprange (); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tmul.c b/mpfr/tests/tmul.c new file mode 100644 index 0000000000..4aaff8e979 --- /dev/null +++ b/mpfr/tests/tmul.c @@ -0,0 +1,697 @@ +/* Test file for mpfr_mul. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c); + if (ok) + { + mpfr_print_raw (b); + printf (" "); + mpfr_print_raw (c); + } + res = mpfr_mul (a, b, c, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_mul mpfr_mul +#endif + +/* checks that xs * ys gives the expected result res */ +static void +check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, + unsigned int px, unsigned int py, unsigned int pz, const char *res) +{ + mpfr_t xx, yy, zz; + + mpfr_init2 (xx, px); + mpfr_init2 (yy, py); + mpfr_init2 (zz, pz); + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_mul(zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, res) ) + { + printf ("(1)mpfr_mul failed for x=%s y=%s with rnd=%s\n", + xs, ys, mpfr_print_rnd_mode (rnd_mode)); + printf ("correct is %s, mpfr_mul gives ", res); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + /* + printf("\nBinary forms:\nxx="); + mpfr_print_binary (xx); + printf("\nyy="); + mpfr_print_binary (yy); + printf("\nzz="); + mpfr_print_binary(zz); + printf("\nre="); + mpfr_set_str1 (zz, res); + mpfr_print_binary(zz); + putchar('\n');*/ + exit (1); + } + mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); +} + +static void +check53 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, yy, zz; + + mpfr_inits2 (53, xx, yy, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_mul (zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, zs) ) + { + printf ("(2) mpfr_mul failed for x=%s y=%s with rnd=%s\n", + xs, ys, mpfr_print_rnd_mode(rnd_mode)); + printf ("correct result is %s,\n mpfr_mul gives ", zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + /* + printf("\nBinary forms:\nxx="); + mpfr_print_binary (xx); + printf("\nyy="); + mpfr_print_binary (yy); + printf("\nzz="); + mpfr_print_binary(zz); + printf("\nre="); + mpfr_set_str1 (zz, zs); + mpfr_print_binary(zz); + putchar('\n'); */ + exit (1); + } + mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); +} + +/* checks that x*y gives the right result with 24 bits of precision */ +static void +check24 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, yy, zz; + + mpfr_inits2 (24, xx, yy, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_mul (zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, zs) ) + { + printf ("(3) mpfr_mul failed for x=%s y=%s with " + "rnd=%s\n", xs, ys, mpfr_print_rnd_mode(rnd_mode)); + printf ("correct result is gives %s, mpfr_mul gives ", zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + putchar('\n'); + exit (1); + } + mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); +} + +/* the following examples come from the paper "Number-theoretic Test + Generation for Directed Rounding" from Michael Parks, Table 1 */ +static void +check_float (void) +{ + check24("8388609.0", "8388609.0", MPFR_RNDN, "70368760954880.0"); + check24("16777213.0", "8388609.0", MPFR_RNDN, "140737479966720.0"); + check24("8388611.0", "8388609.0", MPFR_RNDN, "70368777732096.0"); + check24("12582911.0", "8388610.0", MPFR_RNDN, "105553133043712.0"); + check24("12582914.0", "8388610.0", MPFR_RNDN, "105553158209536.0"); + check24("13981013.0", "8388611.0", MPFR_RNDN, "117281279442944.0"); + check24("11184811.0", "8388611.0", MPFR_RNDN, "93825028587520.0"); + check24("11184810.0", "8388611.0", MPFR_RNDN, "93825020198912.0"); + check24("13981014.0", "8388611.0", MPFR_RNDN, "117281287831552.0"); + + check24("8388609.0", "8388609.0", MPFR_RNDZ, "70368760954880.0"); + check24("16777213.0", "8388609.0", MPFR_RNDZ, "140737471578112.0"); + check24("8388611.0", "8388609.0", MPFR_RNDZ, "70368777732096.0"); + check24("12582911.0", "8388610.0", MPFR_RNDZ, "105553124655104.0"); + check24("12582914.0", "8388610.0", MPFR_RNDZ, "105553158209536.0"); + check24("13981013.0", "8388611.0", MPFR_RNDZ, "117281271054336.0"); + check24("11184811.0", "8388611.0", MPFR_RNDZ, "93825028587520.0"); + check24("11184810.0", "8388611.0", MPFR_RNDZ, "93825011810304.0"); + check24("13981014.0", "8388611.0", MPFR_RNDZ, "117281287831552.0"); + + check24("8388609.0", "8388609.0", MPFR_RNDU, "70368769343488.0"); + check24("16777213.0", "8388609.0", MPFR_RNDU, "140737479966720.0"); + check24("8388611.0", "8388609.0", MPFR_RNDU, "70368786120704.0"); + check24("12582911.0", "8388610.0", MPFR_RNDU, "105553133043712.0"); + check24("12582914.0", "8388610.0", MPFR_RNDU, "105553166598144.0"); + check24("13981013.0", "8388611.0", MPFR_RNDU, "117281279442944.0"); + check24("11184811.0", "8388611.0", MPFR_RNDU, "93825036976128.0"); + check24("11184810.0", "8388611.0", MPFR_RNDU, "93825020198912.0"); + check24("13981014.0", "8388611.0", MPFR_RNDU, "117281296220160.0"); + + check24("8388609.0", "8388609.0", MPFR_RNDD, "70368760954880.0"); + check24("16777213.0", "8388609.0", MPFR_RNDD, "140737471578112.0"); + check24("8388611.0", "8388609.0", MPFR_RNDD, "70368777732096.0"); + check24("12582911.0", "8388610.0", MPFR_RNDD, "105553124655104.0"); + check24("12582914.0", "8388610.0", MPFR_RNDD, "105553158209536.0"); + check24("13981013.0", "8388611.0", MPFR_RNDD, "117281271054336.0"); + check24("11184811.0", "8388611.0", MPFR_RNDD, "93825028587520.0"); + check24("11184810.0", "8388611.0", MPFR_RNDD, "93825011810304.0"); + check24("13981014.0", "8388611.0", MPFR_RNDD, "117281287831552.0"); +} + +/* check sign of result */ +static void +check_sign (void) +{ + mpfr_t a, b; + + mpfr_init2 (a, 53); + mpfr_init2 (b, 53); + mpfr_set_si (a, -1, MPFR_RNDN); + mpfr_set_ui (b, 2, MPFR_RNDN); + test_mul(a, b, b, MPFR_RNDN); + if (mpfr_cmp_ui (a, 4) ) + { + printf ("2.0*2.0 gives \n"); + mpfr_out_str(stdout, 10, 0, a, MPFR_RNDN); + putchar('\n'); + exit (1); + } + mpfr_clear(a); mpfr_clear(b); +} + +/* checks that the inexact return value is correct */ +static void +check_exact (void) +{ + mpfr_t a, b, c, d; + mpfr_prec_t prec; + int i, inexact; + mpfr_rnd_t rnd; + + mpfr_init (a); + mpfr_init (b); + mpfr_init (c); + mpfr_init (d); + + mpfr_set_prec (a, 17); + mpfr_set_prec (b, 17); + mpfr_set_prec (c, 32); + mpfr_set_str_binary (a, "1.1000111011000100e-1"); + mpfr_set_str_binary (b, "1.0010001111100111e-1"); + if (test_mul (c, a, b, MPFR_RNDZ)) + { + printf ("wrong return value (1)\n"); + exit (1); + } + + for (prec = 2; prec < 100; prec++) + { + mpfr_set_prec (a, prec); + mpfr_set_prec (b, prec); + mpfr_set_prec (c, 2 * prec - 2); + mpfr_set_prec (d, 2 * prec); + for (i = 0; i < 1000; i++) + { + mpfr_urandomb (a, RANDS); + mpfr_urandomb (b, RANDS); + rnd = RND_RAND (); + inexact = test_mul (c, a, b, rnd); + if (test_mul (d, a, b, rnd)) /* should be always exact */ + { + printf ("unexpected inexact return value\n"); + exit (1); + } + if ((inexact == 0) && mpfr_cmp (c, d)) + { + printf ("inexact=0 but results differ\n"); + exit (1); + } + else if (inexact && (mpfr_cmp (c, d) == 0)) + { + printf ("inexact!=0 but results agree\n"); + printf ("prec=%u rnd=%s a=", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + mpfr_out_str (stdout, 2, 0, a, rnd); + printf ("\nb="); + mpfr_out_str (stdout, 2, 0, b, rnd); + printf ("\nc="); + mpfr_out_str (stdout, 2, 0, c, rnd); + printf ("\nd="); + mpfr_out_str (stdout, 2, 0, d, rnd); + printf ("\n"); + exit (1); + } + } + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpfr_clear (d); +} + +static void +check_max(void) +{ + mpfr_t xx, yy, zz; + mpfr_exp_t emin; + + mpfr_init2(xx, 4); + mpfr_init2(yy, 4); + mpfr_init2(zz, 4); + mpfr_set_str1 (xx, "0.68750"); + mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN); + mpfr_set_str1 (yy, "0.68750"); + mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN); + mpfr_clear_flags(); + test_mul(zz, xx, yy, MPFR_RNDU); + if (!(mpfr_overflow_p() && MPFR_IS_INF(zz))) + { + printf("check_max failed (should be an overflow)\n"); + exit(1); + } + + mpfr_clear_flags(); + test_mul(zz, xx, yy, MPFR_RNDD); + if (mpfr_overflow_p() || MPFR_IS_INF(zz)) + { + printf("check_max failed (should NOT be an overflow)\n"); + exit(1); + } + mpfr_set_str1 (xx, "0.93750"); + mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN); + if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz))) + { + printf("check_max failed (internal error)\n"); + exit(1); + } + if (mpfr_cmp(xx, zz) != 0) + { + printf("check_max failed: got "); + mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); + printf(" instead of "); + mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ); + printf("\n"); + exit(1); + } + + /* check underflow */ + emin = mpfr_get_emin (); + set_emin (0); + mpfr_set_str_binary (xx, "0.1E0"); + mpfr_set_str_binary (yy, "0.1E0"); + test_mul (zz, xx, yy, MPFR_RNDN); + /* exact result is 0.1E-1, which should round to 0 */ + MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz)); + set_emin (emin); + + /* coverage test for mpfr_powerof2_raw */ + emin = mpfr_get_emin (); + set_emin (0); + mpfr_set_prec (xx, mp_bits_per_limb + 1); + mpfr_set_str_binary (xx, "0.1E0"); + mpfr_nextabove (xx); + mpfr_set_str_binary (yy, "0.1E0"); + test_mul (zz, xx, yy, MPFR_RNDN); + /* exact result is just above 0.1E-1, which should round to minfloat */ + MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0); + set_emin (emin); + + mpfr_clear(xx); + mpfr_clear(yy); + mpfr_clear(zz); +} + +static void +check_min(void) +{ + mpfr_t xx, yy, zz; + + mpfr_init2(xx, 4); + mpfr_init2(yy, 4); + mpfr_init2(zz, 3); + mpfr_set_str1(xx, "0.9375"); + mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, MPFR_RNDN); + mpfr_set_str1(yy, "0.9375"); + mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, MPFR_RNDN); + test_mul(zz, xx, yy, MPFR_RNDD); + if (mpfr_sgn(zz) != 0) + { + printf("check_min failed: got "); + mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); + printf(" instead of 0\n"); + exit(1); + } + + test_mul(zz, xx, yy, MPFR_RNDU); + mpfr_set_str1 (xx, "0.5"); + mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, MPFR_RNDN); + if (mpfr_sgn(xx) <= 0) + { + printf("check_min failed (internal error)\n"); + exit(1); + } + if (mpfr_cmp(xx, zz) != 0) + { + printf("check_min failed: got "); + mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); + printf(" instead of "); + mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ); + printf("\n"); + exit(1); + } + + mpfr_clear(xx); + mpfr_clear(yy); + mpfr_clear(zz); +} + +static void +check_nans (void) +{ + mpfr_t p, x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + mpfr_init2 (p, 123L); + + /* nan * 0 == nan */ + mpfr_set_nan (x); + mpfr_set_ui (y, 0L, MPFR_RNDN); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (p)); + + /* 1 * nan == nan */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_nan (y); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (p)); + + /* 0 * +inf == nan */ + mpfr_set_ui (x, 0L, MPFR_RNDN); + mpfr_set_nan (y); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (p)); + + /* +1 * +inf == +inf */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_inf (y, 1); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (p)); + MPFR_ASSERTN (mpfr_sgn (p) > 0); + + /* -1 * +inf == -inf */ + mpfr_set_si (x, -1L, MPFR_RNDN); + mpfr_set_inf (y, 1); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (p)); + MPFR_ASSERTN (mpfr_sgn (p) < 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (p); +} + +#define BUFSIZE 1552 + +static void +get_string (char *s, FILE *fp) +{ + int c, n = BUFSIZE; + + while ((c = getc (fp)) != '\n') + { + if (c == EOF) + { + printf ("Error in get_string: end of file\n"); + exit (1); + } + *(unsigned char *)s++ = c; + if (--n == 0) + { + printf ("Error in get_string: buffer is too small\n"); + exit (1); + } + } + *s = '\0'; +} + +static void +check_regression (void) +{ + mpfr_t x, y, z; + int i; + FILE *fp; + char s[BUFSIZE]; + + mpfr_inits2 (6177, x, y, z, (mpfr_ptr) 0); + /* we read long strings from a file since ISO C90 does not support strings of + length > 509 */ + fp = src_fopen ("tmul.dat", "r"); + if (fp == NULL) + { + fprintf (stderr, "Error, cannot open tmul.dat in srcdir\n"); + exit (1); + } + get_string (s, fp); + mpfr_set_str (y, s, 16, MPFR_RNDN); + get_string (s, fp); + mpfr_set_str (z, s, 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDN); + get_string (s, fp); + if (mpfr_cmp_str (x, s, 16, MPFR_RNDN) != 0 || i != -1) + { + printf ("Regression test 1 failed (i=%d, expected -1)\nx=", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + fclose (fp); + + mpfr_set_prec (x, 606); + mpfr_set_prec (y, 606); + mpfr_set_prec (z, 606); + + mpfr_set_str (y, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN); + mpfr_set_str (z, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDU); + mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff25b5df87f00a5953eb0e6cac9b3d27cc5a64c@-1", 16, MPFR_RNDN); + if (mpfr_cmp (x, y) || i <= 0) + { + printf ("Regression test (2) failed! (i=%d - Expected 1)\n", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 184); + mpfr_set_prec (y, 92); + mpfr_set_prec (z, 1023); + + mpfr_set_str (y, "6.9b8c8498882770d8038c3b0@-1", 16, MPFR_RNDN); + mpfr_set_str (z, "7.44e24b986e7fb296f1e936ce749fec3504cbf0d5ba769466b1c9f1578115efd5d29b4c79271191a920a99280c714d3a657ad6e3afbab77ffce9d697e9bb9110e26d676069afcea8b69f1d1541f2365042d80a97c21dcccd8ace4f1bb58b49922003e738e6f37bb82ef653cb2e87f763974e6ae50ae54e7724c38b80653e3289@255", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDU); + mpfr_set_prec (y, 184); + mpfr_set_str (y, "3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255", + 16, MPFR_RNDN); + if (mpfr_cmp (x, y) || i <= 0) + { + printf ("Regression test (4) failed! (i=%d - expected 1)\n", i); + printf ("Ref: 3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255\n" + "Got: "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 908); + mpfr_set_prec (y, 908); + mpfr_set_prec (z, 908); + mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42" +"e6e9a327230345ea6@-1", 16, MPFR_RNDN); + mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42" + "e6e9a327230345ea6@-1", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDU); + mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffff337d23f07d8de1da5147a85c" +"dd3464e46068bd4d@-1", 16, MPFR_RNDN); + if (mpfr_cmp (x, y) || i <= 0) + { + printf ("Regression test (5) failed! (i=%d - expected 1)\n", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + + mpfr_set_prec (x, 50); + mpfr_set_prec (y, 40); + mpfr_set_prec (z, 53); + mpfr_set_str (y, "4.1ffffffff8", 16, MPFR_RNDN); + mpfr_set_str (z, "4.2000000ffe0000@-4", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDN); + if (mpfr_cmp_str (x, "1.104000041d6c0@-3", 16, MPFR_RNDN) != 0 + || i <= 0) + { + printf ("Regression test (6) failed! (i=%d - expected 1)\nx=", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\nMore prec="); + mpfr_set_prec (x, 93); + mpfr_mul (x, y, z, MPFR_RNDN); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 439); + mpfr_set_prec (y, 393); + mpfr_set_str (y, "-1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d" + "4c76273644a29410f31c6809bbdf2a33679a748636600", + 16, MPFR_RNDN); + i = mpfr_mul (x, y, y, MPFR_RNDU); + if (mpfr_cmp_str (x, "2.77a79937c8bbcb495b89b36602306b1c2159a8ff834288a19a08" + "84094f1cda3dc426da61174c4544a173de83c2500f8bfea2e0569e3698", + 16, MPFR_RNDN) != 0 + || i <= 0) + { + printf ("Regression test (7) failed! (i=%d - expected 1)\nx=", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 1023); + mpfr_set_prec (y, 1023); + mpfr_set_prec (z, 511); + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_set_ui (y, 42, MPFR_RNDN); + i = mpfr_mul (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 17*42) != 0 || i != 0) + { + printf ("Regression test (8) failed! (i=%d - expected 0)\nz=", i); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION test_mul +#define TWO_ARGS +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) +#include "tgeneric.c" + +/* multiplies x by 53-bit approximation of Pi */ +static int +mpfr_mulpi (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r) +{ + mpfr_t z; + int inex; + + mpfr_init2 (z, 53); + mpfr_set_str_binary (z, "11.001001000011111101101010100010001000010110100011"); + inex = mpfr_mul (y, x, z, r); + mpfr_clear (z); + return inex; +} + +static void +valgrind20110503 (void) +{ + mpfr_t a, b, c; + + mpfr_init2 (a, 2); + mpfr_init2 (b, 2005); + mpfr_init2 (c, 2); + + mpfr_set_ui (b, 5, MPFR_RNDN); + mpfr_nextabove (b); + mpfr_set_ui (c, 1, MPFR_RNDN); + mpfr_mul (a, b, c, MPFR_RNDZ); + /* After the call to mpfr_mulhigh_n, valgrind complains: + Conditional jump or move depends on uninitialised value(s) */ + + mpfr_clears (a, b, c, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_nans (); + check_exact (); + check_float (); + + check53("6.9314718055994530941514e-1", "0.0", MPFR_RNDZ, "0.0"); + check53("0.0", "6.9314718055994530941514e-1", MPFR_RNDZ, "0.0"); + check_sign(); + check53("-4.165000000e4", "-0.00004801920768307322868063274915", MPFR_RNDN, + "2.0"); + check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165", + MPFR_RNDZ, "-1.8251348697787782844e-172"); + check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165", + MPFR_RNDA, "-1.8251348697787786e-172"); + check53("0.31869277231188065", "0.88642843322303122", MPFR_RNDZ, + "2.8249833483992453642e-1"); + check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDU, + 28, 45, 2, "0.375"); + check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDA, + 28, 45, 2, "0.375"); + check("2.63978122803639081440e-01", "6.8378615379333496093e-1", MPFR_RNDN, + 34, 23, 31, "0.180504585267044603"); + check("1.0", "0.11835170935876249132", MPFR_RNDU, 6, 41, 36, + "0.1183517093595583"); + check53("67108865.0", "134217729.0", MPFR_RNDN, "9.007199456067584e15"); + check("1.37399642157394197284e-01", "2.28877275604219221350e-01", MPFR_RNDN, + 49, 15, 32, "0.0314472340833162888"); + check("4.03160720978664954828e-01", "5.854828e-1" + /*"5.85483042917246621073e-01"*/, MPFR_RNDZ, + 51, 22, 32, "0.2360436821472831"); + check("3.90798504668055102229e-14", "9.85394674650308388664e-04", MPFR_RNDN, + 46, 22, 12, "0.385027296503914762e-16"); + check("4.58687081072827851358e-01", "2.20543551472118792844e-01", MPFR_RNDN, + 49, 3, 2, "0.09375"); + check_max(); + check_min(); + + check_regression (); + test_generic (2, 500, 100); + + data_check ("data/mulpi", mpfr_mulpi, "mpfr_mulpi"); + + valgrind20110503 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tmul.dat b/mpfr/tests/tmul.dat new file mode 100644 index 0000000000..3551efe5a9 --- /dev/null +++ b/mpfr/tests/tmul.dat @@ -0,0 +1,3 @@ +5.17cc1b727220a94fe13abe8fa9a6ee06db14acc9e21c820ff28b1d5ef5de2b0db92371d2126e9700324977504e8c90e7f0ef58e5894d39f74411afa975da24274ce38135a2fbf209cc8eb1cc1a99cfa4e422fc5defc941d8ffc4bffef02cc07f79788c5ad05368fb69b3f6793e584dba7a31fb34f2ff516ba93dd63f5f2f8bd9e839cfbc529497535fdafd88fc6ae842b0198237e3db5d5f867de104d7a1b0ed4f1c8b0af730d8432ccc2af8a50342046ffec4026b9939883030aab6539d464b0713de04635a3e20ce1b3e6ee74049541ace23b45cb0e536ed7a268ab8c829f52ff83829fbf19f419616f27cc193edde19e9377b58f2f7c4f9d0f9ae5793f8ec3f890c83e3e12357d376abb9698219d8ae30a5ace8ce1e16256a0a6962e8006233ec316b8f1cd634d803119be695a4bd3da6aaa9bfb1f6b8c0851fe3b26954eb255ebb87c3e31abd83d738a8bab24e06ceb1d9c4253e591923bc56b11aa2d5c8f800d8578efe70cff98cfb50f3330abcca3fdd66c3fbf5bb29144f419305ff366e277849b366a1faeebef0b6f1dac494def14116974431426ac711965630b718465bef028600bd38ef9adf00c1a099731094180a441adc77abfd856f9748f21a52469b3886c6ed5212fd76730b55214055a4ce9f953033fbbae41e151c41e30bc39c52d4657deebb7b1d316e5dffa77c0c6b3e09322e52a9b6ce569541446b0e13be4890a13024da309622ce22262e448d926f98b8056a1ea72a494886afefe5f00664a0f7767387a9f09c078f661f3d9947c63ca02c99f38e0d9849779a285ce09443d9055cfda9761492397993db6aa864853b90ff3b5cb6598a50b3cf13ca0c4effa4bca744273714b98ccb5f6c41b2faf877eddda4d24365233a13938992ec6dc0acf84f2de1298c69cba7b8e0298008606b40425ac77164855238173ba126b5ed33efbb92437778b4fd34a477b48da28a9e8f9056799cc103f25fab431d92f9f6e81aea03fc4c294a92ae0321b886c369924193aa62dea38a7372a22e08485b4fa956ab30a4e8393a8022eed9dda62bb750bfcc3beb5a4dd138e94b4cb000000000@1535 +3.243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be5466cf34e90c6cc0ac29b7c97c50dd3f84d5b5b54709179216d5d98979fb1bd1310ba698dfb5ac2ffd72dbd01adfb7b8e1afed6a267e96ba7c9045f12c7f9924a19947b3916cf70801f2e2858efc16636920d871574e69a458fea3f4933d7e0d95748f728eb658718bcd5882154aee7b54a41dc25a59b59c30d5392af26013c5d1b023286085f0ca417918b8db38ef8e79dcb0603a180e6c9e0e8bb01e8a3ed71577c1bd314b2778af2fda55605c60e65525f3aa55ab945748986263e8144055ca396a2aab10b6b4cc5c341141e8cea15486af7c72e993b3ee1411636fbc2a2ba9c55d741831f6ce5c3e169b87931eafd6ba336c24cf5c7a325381289586773b8f48986b4bb9afc4bfe81b6628219361d809ccfb21a991487cac605dec8032ef845d5de98575b1dc262302eb651b8823893e81d396acc50f6d6ff383f442392e0b4482a484200469c8f04a9e1f9b5e21c66842f6e96c9a670c9c61abd388f06a51a0d2d8542f68960fa728ab5133a36eef0b6c137a3be4ba3bf0507efb2a98a1f1651d39af017666ca593e82430e888cee8619456f9fb47d84a5c33b8b5ebee06f75d885c12073401a449f56c16aa64ed3aa62363f77061bfedf72429b023d37d0d724d00a1248db0fead349f1c09b075372c980991b7b25d479d8f6e8def7e3fe501ab6794c3b976ce0bd04c006bac1a94fb6409f60c45e5c9ec2196a246368fb6faf3e6c53b51339b2eb3b52ec6f6dfc511f9b30952ccc814544af5ebd09bee3d004de334afd660f2807192e4bb3c0cba85745c8740fd20b5f39b9d3fbdb5579c0bd1a60320ad6a100c6402c7279679f25fefb1fa3cc8ea5e9f8db3222f83c7516dffd616b152f501ec8ad0552ab323db5fafd23876053317b483e00df829e5c57bbca6f8ca01a87562edf1769dbd542a8f6287effc3ac6732c68c4f5573695b27b0bbca58c8e1ffa35db8f011a010fa3d98fd2183b84afcb56c2dd1d35b9a53e479b6f84565d28e49bc4bfb9790e1ddf2daa4cb7e3362fb1342 +f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef09109690@1535 diff --git a/mpfr/tests/tmul_2exp.c b/mpfr/tests/tmul_2exp.c new file mode 100644 index 0000000000..b498a6de52 --- /dev/null +++ b/mpfr/tests/tmul_2exp.c @@ -0,0 +1,419 @@ +/* Test file for mpfr_{mul,div}_2{ui,si}. + +Copyright 1999, 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static const char * const val[] = { + "1.0001@100","4.0004000000000@102", "4.0004000000000@97", + "1.ABF012345@-100","6.afc048d140000@-98","6.afc048d140000@-103", + "F.FFFFFFFFF@10000","3.fffffffffc000@10003","3.fffffffffc000@9998", + "1.23456789ABCDEF@42","4.8d159e26af37c@44","4.8d159e26af37c@39", + "17@42","5.c000000000000@45","5.c000000000000@40", + "42@-17","1.0800000000000@-13","1.0800000000000@-18" +}; + +static int +test_mul (int i, int div, mpfr_ptr y, mpfr_srcptr x, + unsigned long int n, mpfr_rnd_t r) +{ + return + i == 0 ? (div ? mpfr_div_2ui : mpfr_mul_2ui) (y, x, n, r) : + i == 1 ? (div ? mpfr_div_2si : mpfr_mul_2si) (y, x, n, r) : + i == 2 ? (div ? mpfr_mul_2si : mpfr_div_2si) (y, x, -n, r) : + (exit (1), 0); +} + +static void +underflow (mpfr_exp_t e) +{ + mpfr_t x, y, z1, z2; + mpfr_exp_t emin; + int i, k, s; + int prec; + int rnd; + int div; + int inex1, inex2; + unsigned int flags1, flags2; + + /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e) with + * emin = e, x = s * (1 + i/16), i in { -1, 0, 1 }, s in { -1, 1 }, and + * k = 1 to 4, by comparing the result with the one of a simple division. + */ + emin = mpfr_get_emin (); + set_emin (e); + mpfr_inits2 (8, x, y, (mpfr_ptr) 0); + for (i = 15; i <= 17; i++) + for (s = 1; s >= -1; s -= 2) + { + inex1 = mpfr_set_si_2exp (x, s * i, -4, MPFR_RNDN); + MPFR_ASSERTN (inex1 == 0); + for (prec = 6; prec >= 3; prec -= 3) + { + mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0); + RND_LOOP (rnd) + for (k = 1; k <= 4; k++) + { + /* The following one is assumed to be correct. */ + inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN); + MPFR_ASSERTN (inex1 == 0); + inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN); + MPFR_ASSERTN (inex1 == 0); + mpfr_clear_flags (); + /* Do not use mpfr_div_ui to avoid the optimization + by mpfr_div_2si. */ + inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd); + flags1 = __gmpfr_flags; + + for (div = 0; div <= 2; div++) + { + mpfr_clear_flags (); + inex2 = + div == 0 ? + mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : + div == 1 ? + mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) : + mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd); + flags2 = __gmpfr_flags; + if (flags1 == flags2 && SAME_SIGN (inex1, inex2) && + mpfr_equal_p (z1, z2)) + continue; + printf ("Error in underflow("); + if (e == MPFR_EMIN_MIN) + printf ("MPFR_EMIN_MIN"); + else if (e == emin) + printf ("default emin"); + else if (e >= LONG_MIN) + printf ("%ld", (long) e); + else + printf ("<LONG_MIN"); + printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d," + " %s\n", div == 0 ? "mul_2si" : div == 1 ? + "div_2si" : "div_2ui", s * i, prec, k, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Expected "); + mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN); + printf (", inex = %d, flags = %u\n", + SIGN (inex1), flags1); + printf ("Got "); + mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN); + printf (", inex = %d, flags = %u\n", + SIGN (inex2), flags2); + exit (1); + } /* div */ + } /* k */ + mpfr_clears (z1, z2, (mpfr_ptr) 0); + } /* prec */ + } /* i */ + mpfr_clears (x, y, (mpfr_ptr) 0); + set_emin (emin); +} + +static void +underflow0 (void) +{ + underflow (-256); + if (mpfr_get_emin () != MPFR_EMIN_MIN) + underflow (mpfr_get_emin ()); + underflow (MPFR_EMIN_MIN); +} + +static void +large (mpfr_exp_t e) +{ + mpfr_t x, y, z; + mpfr_exp_t emax; + int inex; + unsigned int flags; + + emax = mpfr_get_emax (); + set_emax (e); + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + mpfr_init2 (z, 4); + + mpfr_set_inf (x, 1); + mpfr_nextbelow (x); + + mpfr_mul_2si (y, x, -1, MPFR_RNDU); + mpfr_prec_round (y, 4, MPFR_RNDU); + + mpfr_clear_flags (); + inex = mpfr_mul_2si (z, x, -1, MPFR_RNDU); + flags = __gmpfr_flags; + + if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) + { + printf ("Error in large("); + if (e == MPFR_EMAX_MAX) + printf ("MPFR_EMAX_MAX"); + else if (e == emax) + printf ("default emax"); + else if (e <= LONG_MAX) + printf ("%ld", (long) e); + else + printf (">LONG_MAX"); + printf (") for mpfr_mul_2si\n"); + printf ("Expected inex > 0, flags = %u,\n y = ", + (unsigned int) MPFR_FLAGS_INEXACT); + mpfr_dump (y); + printf ("Got inex = %d, flags = %u,\n y = ", + inex, flags); + mpfr_dump (z); + exit (1); + } + + mpfr_clear_flags (); + inex = mpfr_div_2si (z, x, 1, MPFR_RNDU); + flags = __gmpfr_flags; + + if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) + { + printf ("Error in large("); + if (e == MPFR_EMAX_MAX) + printf ("MPFR_EMAX_MAX"); + else if (e == emax) + printf ("default emax"); + else if (e <= LONG_MAX) + printf ("%ld", (long) e); + else + printf (">LONG_MAX"); + printf (") for mpfr_div_2si\n"); + printf ("Expected inex > 0, flags = %u,\n y = ", + (unsigned int) MPFR_FLAGS_INEXACT); + mpfr_dump (y); + printf ("Got inex = %d, flags = %u,\n y = ", + inex, flags); + mpfr_dump (z); + exit (1); + } + + mpfr_clear_flags (); + inex = mpfr_div_2ui (z, x, 1, MPFR_RNDU); + flags = __gmpfr_flags; + + if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) + { + printf ("Error in large("); + if (e == MPFR_EMAX_MAX) + printf ("MPFR_EMAX_MAX"); + else if (e == emax) + printf ("default emax"); + else if (e <= LONG_MAX) + printf ("%ld", (long) e); + else + printf (">LONG_MAX"); + printf (") for mpfr_div_2ui\n"); + printf ("Expected inex > 0, flags = %u,\n y = ", + (unsigned int) MPFR_FLAGS_INEXACT); + mpfr_dump (y); + printf ("Got inex = %d, flags = %u,\n y = ", + inex, flags); + mpfr_dump (z); + exit (1); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); + set_emax (emax); +} + +static void +large0 (void) +{ + large (256); + if (mpfr_get_emax () != MPFR_EMAX_MAX) + large (mpfr_get_emax ()); + large (MPFR_EMAX_MAX); +} + +/* Cases where the function overflows on n = 0 when rounding is like + away from zero. */ +static void +overflow0 (mpfr_exp_t emax) +{ + mpfr_exp_t old_emax; + mpfr_t x, y1, y2; + int neg, r, op; + static char *sop[4] = { "mul_2ui", "mul_2si", "div_2ui", "div_2si" }; + + old_emax = mpfr_get_emax (); + set_emax (emax); + + mpfr_init2 (x, 8); + mpfr_inits2 (6, y1, y2, (mpfr_ptr) 0); + + mpfr_set_inf (x, 1); + mpfr_nextbelow (x); + + for (neg = 0; neg <= 1; neg++) + { + RND_LOOP (r) + { + int inex1, inex2; + unsigned int flags1, flags2; + + /* Even if there isn't an overflow (rounding ~ toward zero), + the result is the same as the one of an overflow. */ + inex1 = mpfr_overflow (y1, (mpfr_rnd_t) r, neg ? -1 : 1); + flags1 = MPFR_FLAGS_INEXACT; + if (mpfr_inf_p (y1)) + flags1 |= MPFR_FLAGS_OVERFLOW; + for (op = 0; op < 4; op++) + { + mpfr_clear_flags (); + inex2 = + op == 0 ? mpfr_mul_2ui (y2, x, 0, (mpfr_rnd_t) r) : + op == 1 ? mpfr_mul_2si (y2, x, 0, (mpfr_rnd_t) r) : + op == 2 ? mpfr_div_2ui (y2, x, 0, (mpfr_rnd_t) r) : + op == 3 ? mpfr_div_2si (y2, x, 0, (mpfr_rnd_t) r) : + (MPFR_ASSERTN (0), 0); + flags2 = __gmpfr_flags; + if (!(mpfr_equal_p (y1, y2) && + SAME_SIGN (inex1, inex2) && + flags1 == flags2)) + { + printf ("Error in overflow0 for %s, mpfr_%s, emax = %" + MPFR_EXP_FSPEC "d,\nx = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), sop[op], + (mpfr_eexp_t) emax); + mpfr_dump (x); + printf ("Expected "); + mpfr_dump (y1); + printf (" with inex = %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (y2); + printf (" with inex = %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + } + mpfr_neg (x, x, MPFR_RNDN); + } + + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); + set_emax (old_emax); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t w,z; + unsigned long k; + int i; + + tests_start_mpfr (); + + mpfr_inits2 (53, w, z, (mpfr_ptr) 0); + + for (i = 0; i < 3; i++) + { + mpfr_set_inf (w, 1); + test_mul (i, 0, w, w, 10, MPFR_RNDZ); + if (!MPFR_IS_INF(w)) + { + printf ("Result is not Inf (i = %d)\n", i); + exit (1); + } + + mpfr_set_nan (w); + test_mul (i, 0, w, w, 10, MPFR_RNDZ); + if (!MPFR_IS_NAN(w)) + { + printf ("Result is not NaN (i = %d)\n", i); + exit (1); + } + + for (k = 0 ; k < numberof(val) ; k+=3) + { + mpfr_set_str (w, val[k], 16, MPFR_RNDN); + test_mul (i, 0, z, w, 10, MPFR_RNDZ); + if (mpfr_cmp_str (z, val[k+1], 16, MPFR_RNDN)) + { + printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]); + printf ("Expected: %s\n" + "Got : ", val[k+1]); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + test_mul (i, 1, z, w, 10, MPFR_RNDZ); + if (mpfr_cmp_str (z, val[k+2], 16, MPFR_RNDN)) + { + printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]); + printf ("Expected: %s\n" + "Got : ", val[k+2]); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + } + + mpfr_set_inf (w, 1); + mpfr_nextbelow (w); + test_mul (i, 0, w, w, 1, MPFR_RNDN); + if (!mpfr_inf_p (w)) + { + printf ("Overflow error (i = %d)!\n", i); + exit (1); + } + mpfr_set_ui (w, 0, MPFR_RNDN); + mpfr_nextabove (w); + test_mul (i, 1, w, w, 1, MPFR_RNDN); + if (mpfr_cmp_ui (w, 0)) + { + printf ("Underflow error (i = %d)!\n", i); + exit (1); + } + } + + if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1) + { + unsigned long lmp1 = (unsigned long) LONG_MAX + 1; + + mpfr_set_ui (w, 1, MPFR_RNDN); + mpfr_mul_2ui (w, w, LONG_MAX/2, MPFR_RNDZ); + mpfr_div_2ui (w, w, lmp1, MPFR_RNDZ); + mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, MPFR_RNDZ); + if (!mpfr_cmp_ui (w, 1)) + { + printf ("Underflow LONG_MAX error!\n"); + exit (1); + } + } + + mpfr_clears (w, z, (mpfr_ptr) 0); + + underflow0 (); + large0 (); + + if (mpfr_get_emax () != MPFR_EMAX_MAX) + overflow0 (mpfr_get_emax ()); + overflow0 (MPFR_EMAX_MAX); + overflow0 (-1); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tmul_d.c b/mpfr/tests/tmul_d.c new file mode 100644 index 0000000000..ce126ba5e7 --- /dev/null +++ b/mpfr/tests/tmul_d.c @@ -0,0 +1,136 @@ +/* Test file for mpfr_mul_d + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check_nans (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + /* nan * 1.0 is nan */ + mpfr_set_nan (x); + mpfr_clear_flags(); + inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf * 1.0 == +inf */ + mpfr_set_inf (x, 1); + mpfr_clear_flags(); + inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* +inf * 0.0 is nan */ + mpfr_clear_flags(); + inexact = mpfr_mul_d (y, x, 0.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* -inf * 1.0 == -inf */ + mpfr_set_inf (x, -1); + mpfr_clear_flags(); + inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_mul_d +#define DOUBLE_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z; + double d; + int inexact; + + tests_start_mpfr (); + + /* check with enough precision */ + mpfr_init2 (x, IEEE_DBL_MANT_DIG); + mpfr_init2 (y, IEEE_DBL_MANT_DIG); + mpfr_init2 (z, IEEE_DBL_MANT_DIG); + + mpfr_set_str (y, "4096", 10, MPFR_RNDN); + d = 0.125; + mpfr_clear_flags (); + inexact = mpfr_mul_d (x, y, d, MPFR_RNDN); + if (inexact != 0) + { + printf ("Inexact flag error in mpfr_mul_d\n"); + exit (1); + } + mpfr_set_str (z, "512", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_mul_d ("); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + check_nans (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tmul_ui.c b/mpfr/tests/tmul_ui.c new file mode 100644 index 0000000000..4baf1abe12 --- /dev/null +++ b/mpfr/tests/tmul_ui.c @@ -0,0 +1,282 @@ +/* Test file for mpfr_mul_ui. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check_inexact (mpfr_prec_t p) +{ + mpfr_t x, y, z; + unsigned long u; + mpfr_prec_t q; + int inexact, cmp; + int rnd; + + mpfr_init2 (x, p); + mpfr_init (y); + mpfr_init2 (z, p + mp_bits_per_limb); + mpfr_urandomb (x, RANDS); + u = randlimb (); + if (mpfr_mul_ui (z, x, u, MPFR_RNDN)) + { + printf ("Error: result should be exact\n"); + exit (1); + } + + for (q = 2; q <= p; q++) + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + mpfr_set_prec (y, q); + inexact = mpfr_mul_ui (y, x, u, (mpfr_rnd_t) rnd); + cmp = mpfr_cmp (y, z); + if (((inexact == 0) && (cmp != 0)) || + ((inexact < 0) && (cmp >= 0)) || + ((inexact > 0) && (cmp <= 0))) + { + printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n", + (unsigned int) p, (unsigned int) q, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + exit (1); + } + } + + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 1, MPFR_RNDN); + if (mpfr_mul_ui (x, x, 5, MPFR_RNDZ) == 0) + { + printf ("mul_ui(1, 5) cannot be exact with prec=2\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +#define TEST_FUNCTION mpfr_mul_ui +#define ULONG_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + unsigned int xprec, yprec, i; + mpfr_prec_t p; + mpfr_exp_t emax; + + tests_start_mpfr (); + + for (p=2; p<100; p++) + for (i=1; i<50; i++) + check_inexact (p); + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + /* checks that result is normalized */ + mpfr_set_str (y, "6.93147180559945286227e-01", 10, MPFR_RNDZ); + mpfr_mul_ui (x, y, 1, MPFR_RNDZ); + if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0) + { + printf ("Error in mpfr_mul_ui: result not normalized\n"); + exit (1); + } + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_mul_ui: 1*y != y\n"); + printf ("y= "); mpfr_print_binary (y); puts (""); + printf ("1*y="); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_mul_ui (x, x, 3, MPFR_RNDU); + if (!mpfr_inf_p (x) || (mpfr_sgn (x) <= 0)) + { + printf ("Error in mpfr_mul_ui: +Inf*3 does not give +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_mul_ui (x, x, 3, MPFR_RNDU); + if (!mpfr_inf_p (x) || (mpfr_sgn (x) >= 0)) + { + printf ("Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n"); + exit (1); + } + + mpfr_set_nan (x); + mpfr_mul_ui (x, x, 3, MPFR_RNDU); + if (!mpfr_nan_p(x)) + { + printf ("Error in mpfr_mul_ui: NaN*3 does not give NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_mul_ui (x, x, 0, MPFR_RNDU); + MPFR_ASSERTN(mpfr_nan_p (x)); + + mpfr_set_ui (x, 1, MPFR_RNDU); + mpfr_mul_ui (x, x, 0, MPFR_RNDU); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + + emax = mpfr_get_emax (); + set_emax (0); + mpfr_set_str_binary (x, "0.1E0"); + mpfr_mul_ui (x, x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x)); + set_emax (emax); + + mpfr_set_str (x, /*1.0/3.0*/ + "0.333333333333333333333333333333333", 10, MPFR_RNDZ); + mpfr_mul_ui (x, x, 3, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n"); + exit (1); + } + + /* checks sign is correct */ + mpfr_set_si (x, -2, MPFR_RNDZ); + mpfr_set_si (y, 3, MPFR_RNDZ); + mpfr_mul_ui(x, y, 4, MPFR_RNDZ); + if (mpfr_cmp_ui(x, 0) <= 0) + { + printf("Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n"); + mpfr_print_binary(x); puts (""); + printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0)); + exit(1); + } + + mpfr_set_prec (x, 9); + mpfr_set_prec (y, 9); + mpfr_set_str_binary (y, "0.100001111E9"); /* 271 */ + mpfr_mul_ui (x, y, 1335, MPFR_RNDN); + mpfr_set_str_binary (y, "0.101100001E19"); /* 361472 */ + if (mpfr_cmp (x, y)) + { + printf ("Error in mul_ui for 1335*(0.100001111E9)\n"); + printf ("got "); mpfr_print_binary (x); puts (""); + exit(1); + } + + mpfr_set_prec(y, 100); + mpfr_set_prec(x, 100); + /* y = 1199781142214086656 */ + mpfr_set_str_binary(y, "0.1000010100110011110101001011110010101111000100001E61"); + mpfr_mul_ui(x, y, 121, MPFR_RNDD); + /* 121*y = 145173518207904485376, representable exactly */ + mpfr_set_str_binary(y, "0.1111101111010101111111100011010010111010111110110011001E67"); + if (mpfr_cmp(x, y)) + { + printf("Error for 121*y: expected result is:\n"); + mpfr_print_binary(y); puts (""); + } + + mpfr_set_prec (x, 32); + mpfr_set_str_binary (x, "0.10000000000000000000000000000000E1"); + mpfr_set_prec (y, 93); + mpfr_mul_ui (y, x, 1, MPFR_RNDN); + + mpfr_set_prec (x, 287); + mpfr_set_str_binary (x, "0.1111E7"); + mpfr_set_prec (y, 289); + mpfr_mul_ui (y, x, 6, MPFR_RNDN); + mpfr_set_str_binary (x, "0.101101E10"); + if (mpfr_cmp (x, y)) + { + printf ("Error for 6 * 120\n"); + exit (1); + } + + mpfr_set_prec (x, 68); + mpfr_set_prec (y, 64); + mpfr_set_str (x, "2143861251406875.0", 10, MPFR_RNDN); + mpfr_mul_ui (y, x, 23, MPFR_RNDN); + mpfr_set_str_binary (x, "10101111001011100001100110101111110001010010011001101101.0"); + if (mpfr_cmp (x, y)) + { + printf ("Error for 23 * 2143861251406875.0\n"); + printf ("expected "); mpfr_print_binary (x); puts (""); + printf ("got "); mpfr_print_binary (y); puts (""); + exit (1); + } + + + for (xprec = 53; xprec <= 128; xprec++) + { + mpfr_set_prec (x, xprec); + mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2"); + for (yprec = 53; yprec <= 128; yprec++) + { + mpfr_set_prec (y, yprec); + mpfr_mul_ui (y, x, 1, MPFR_RNDN); + if (mpfr_cmp(x,y)) + { + printf ("multiplication by 1.0 fails for xprec=%u, yprec=%u\n", + xprec, yprec); + printf ("expected "); mpfr_print_binary (x); puts (""); + printf ("got "); mpfr_print_binary (y); puts (""); + exit (1); + } + } + } + + mpfr_set_prec (x, 128); + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_mul_ui (x, x, ULONG_HIGHBIT, MPFR_RNDN); + mpfr_set_prec (y, 128); + mpfr_set_ui (y, ULONG_HIGHBIT, MPFR_RNDN); + mpfr_mul_ui (y, y, 17, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for 17 * ULONG_HIGHBIT\n"); + exit (1); + } + + /* Check regression */ + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 96); + mpfr_set_ui (x, 1742175942, MPFR_RNDN); + mpfr_mul_ui (y, x, 59, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.10111111011101010101000110111101000100000000000000" + "0000000000000000000000000000000000000000000000E37", + 2, MPFR_RNDN)) + { + printf ("Regression tested failed for x=1742175942 * 59\n"); + exit (1); + } + + mpfr_clear(x); + mpfr_clear(y); + + test_generic (2, 500, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tnext.c b/mpfr/tests/tnext.c new file mode 100644 index 0000000000..1c0393ec7e --- /dev/null +++ b/mpfr/tests/tnext.c @@ -0,0 +1,168 @@ +/* Test file for mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward. + +Copyright 2003-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* Generic tests for mpfr_nextabove and mpfr_nextbelow */ +static void +generic_abovebelow (void) +{ + int i; + + for (i = 0; i < 20000; i++) + { + mpfr_t x, y, z, t; + mpfr_prec_t prec; + int neg, below; + + prec = (randlimb () % 300) + MPFR_PREC_MIN; + mpfr_inits2 (prec, x, y, z, (mpfr_ptr) 0); + mpfr_init2 (t, 3); + + /* special tests (executed once is enough) */ + if (i == 0) + { + mpfr_set_nan (x); + mpfr_nextabove (x); + MPFR_ASSERTN(mpfr_nan_p (x)); + mpfr_nextbelow (x); + MPFR_ASSERTN(mpfr_nan_p (x)); + mpfr_nexttoward (x, y); + MPFR_ASSERTN(mpfr_nan_p (x)); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_nexttoward (y, x); + MPFR_ASSERTN(mpfr_nan_p (y)); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_nexttoward (x, y); + MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0); + } + + do + mpfr_urandomb (x, RANDS); + while (mpfr_cmp_ui (x, 0) == 0); + neg = randlimb () & 1; + if (neg) + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set (y, x, MPFR_RNDN); + below = randlimb () & 1; + if (below) + mpfr_nextbelow (y); + else + mpfr_nextabove (y); + mpfr_set_si (t, below ? -5 : 5, MPFR_RNDN); + mpfr_mul_2si (t, t, (mpfr_get_exp) (x) - prec - 3, MPFR_RNDN); + /* t = (1/2 + 1/8) ulp(x) */ + mpfr_add (z, x, t, MPFR_RNDN); + if (!mpfr_number_p (y) || mpfr_cmp (y, z) != 0) + { + printf ("Error in mpfr_next%s for\n", + below ? "below" : "above"); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (", got\n"); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" instead of\n"); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, t, (mpfr_ptr) 0); + } +} + +static void +inverse_test (void) +{ + static const char *tests[] = { "0", "1", "2", "3.1", "Inf" }; + int i, neg, below; + mpfr_prec_t prec; + + for (i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i++) + for (neg = 0; neg <= 1; neg++) + for (below = 0; below <= 1; below++) + for (prec = MPFR_PREC_MIN; prec < 200; prec += 3) + { + mpfr_t x, y; + int sign; + + mpfr_inits2 (prec, x, y, (mpfr_ptr) 0); + mpfr_set_str (x, tests[i], 10, MPFR_RNDN); + if (neg) + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set (y, x, MPFR_RNDN); + if (below) + mpfr_nextbelow (y); + else + mpfr_nextabove (y); + sign = MPFR_SIGN (y); + if (!(neg == below && mpfr_inf_p (x))) /* then x = y */ + { + if (mpfr_cmp (x, y) == 0) + { + printf ("Error in inverse_test for %s, neg = %d," + " below = %d, prec = %d: x = y", tests[i], + neg, below, (int) prec); + printf ("\nx = "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ny = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_nexttoward (y, x); + if (mpfr_cmp_ui (y, 0) == 0 && MPFR_SIGN (y) != sign) + { + printf ("Sign error in inverse_test for %s, neg = %d," + " below = %d, prec = %d\n", tests[i], neg, + below, (int) prec); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + if (mpfr_cmp (x, y) != 0) + { + printf ("Error in inverse_test for %s, neg = %d, below = %d," + " prec = %d", tests[i], neg, below, (int) prec); + printf ("\nx = "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ny = "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, (mpfr_ptr) 0); + } +} + +int +main (void) +{ + tests_start_mpfr (); + generic_abovebelow (); + inverse_test (); + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tout_str.c b/mpfr/tests/tout_str.c new file mode 100644 index 0000000000..992c655fd6 --- /dev/null +++ b/mpfr/tests/tout_str.c @@ -0,0 +1,171 @@ +/* Test file for mpfr_out_str. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <float.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +FILE *fout; + +#define check(d,r,b) check4(d,r,b,53) + +static void +check4 (double d, mpfr_rnd_t rnd, int base, int prec) +{ + mpfr_t x; + + mpfr_init2 (x, prec); + mpfr_set_d (x, d, 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); +} + +static void +special (void) +{ + mpfr_t x; + unsigned int n; + + mpfr_init (x); + + mpfr_set_nan (x); + n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); + if (n != 5) + { + printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u " + "characters instead of 5.\n", n); + exit (1); + } + + mpfr_set_inf (x, 1); + n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); + if (n != 5) + { + printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u " + "characters instead of 5.\n", n); + exit (1); + } + + mpfr_set_inf (x, -1); + n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); + if (n != 6) + { + printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u " + "characters instead of 6.\n", n); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); + if (n != 1) + { + printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u " + "characters instead of 1.\n", n); + exit (1); + } + + mpfr_neg (x, x, MPFR_RNDN); + n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); + if (n != 2) + { + printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u " + "characters instead of 2.\n", n); + exit (1); + } + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + int i, N=10000, p; + mpfr_rnd_t rnd; + double d; + + tests_start_mpfr (); + + /* with no argument: prints to /dev/null, + tout_str N: prints N tests to stdout */ + if (argc == 1) + { + fout = fopen ("/dev/null", "w"); + /* If we failed to open this device, try with a dummy file */ + if (fout == NULL) + fout = fopen ("mpfrtest.txt", "w"); + } + else + { + fout = stdout; + N = atoi (argv[1]); + } + + if (fout == NULL) + { + printf ("Can't open /dev/null or stdout\n"); + exit (1); + } + + special (); + + check (-1.37247529013405550000e+15, MPFR_RNDN, 7); + check (-1.5674376729569697500e+15, MPFR_RNDN, 19); + check (-5.71262771772792640000e-79, MPFR_RNDU, 16); + check (DBL_NEG_ZERO, MPFR_RNDU, 7); + check (-4.5306392613572974756e-308, MPFR_RNDN, 8); + check (-6.7265890111403371523e-165, MPFR_RNDN, 4); + check (-1.3242553591261807653e+156, MPFR_RNDN, 16); + check (-6.606499965302424244461355e233, MPFR_RNDN, 10); + check4 (1.0, MPFR_RNDN, 10, 120); + check (1.0, MPFR_RNDU, 10); + check (4.059650008e-83, MPFR_RNDN, 10); + check (-7.4, MPFR_RNDN, 10); + check (0.997, MPFR_RNDN, 10); + check (-4.53063926135729747564e-308, MPFR_RNDN, 10); + check (2.14478198760196000000e+16, MPFR_RNDN, 10); + check (7.02293374921793516813e-84, MPFR_RNDN, 10); + + /* random tests */ + for (i=0;i<N;i++) + { + do + { + d = DBL_RAND (); + } +#ifdef HAVE_DENORMS + while (0); +#else + while (ABS(d) < DBL_MIN); +#endif + rnd = RND_RAND (); + p = 2 + randlimb () % 61; + check (d, rnd, p); + } + + fclose (fout); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/toutimpl.c b/mpfr/tests/toutimpl.c new file mode 100644 index 0000000000..a30dde4b62 --- /dev/null +++ b/mpfr/tests/toutimpl.c @@ -0,0 +1,122 @@ +/* Test file for internal debugging-out functions: + mpfr_dump, mpfr_print_binary, mpfr_print_rnd_mode. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include "mpfr-test.h" + +/* We output stdout to a file to check if it is correct + Is it a good idea? + We can't use tmpname since it is insecure */ +#define FILE_NAME "dummy.tmp" + +static const char Buffer[] = +"@NaN@\n" +"-@Inf@\n" +"-0\n" +"0.10101010101011111001000110001100010000100000000000000E32\n"; + +int +main (void) +{ + mpfr_t x; + FILE *f; + int i; + + tests_start_mpfr (); + + /* Check RND_MODE */ + if (strcmp (mpfr_print_rnd_mode(MPFR_RNDN), "MPFR_RNDN")) + { + printf ("Error for printing MPFR_RNDN\n"); + exit (1); + } + if (strcmp (mpfr_print_rnd_mode(MPFR_RNDU), "MPFR_RNDU")) + { + printf ("Error for printing MPFR_RNDU\n"); + exit (1); + } + if (strcmp (mpfr_print_rnd_mode(MPFR_RNDD), "MPFR_RNDD")) + { + printf ("Error for printing MPFR_RNDD\n"); + exit (1); + } + if (strcmp (mpfr_print_rnd_mode(MPFR_RNDZ), "MPFR_RNDZ")) + { + printf ("Error for printing MPFR_RNDZ\n"); + exit (1); + } + if (mpfr_print_rnd_mode ((mpfr_rnd_t) -1) != NULL || + mpfr_print_rnd_mode (MPFR_RND_MAX) != NULL) + { + printf ("Error for illegal rounding mode values.\n"); + exit (1); + } + + /* Reopen stdout to a file. All errors will be put to stderr + Can't use tmpname since it is unsecure */ + if (freopen (FILE_NAME, "w", stdout) == NULL) + { + printf ("Error can't redirect stdout\n"); + exit (1); + } + mpfr_init (x); + mpfr_set_nan (x); + mpfr_dump (x); + mpfr_set_inf (x, -1); + mpfr_dump (x); + MPFR_SET_ZERO (x); MPFR_SET_NEG (x); + mpfr_dump (x); + mpfr_set_str_binary (x, "0.101010101010111110010001100011000100001E32"); + mpfr_dump (x); + mpfr_print_mant_binary ("x=",MPFR_MANT(x), MPFR_PREC(x)); + + + mpfr_clear (x); + fclose (stdout); + /* Open it and check for it */ + f = fopen (FILE_NAME, "r"); + if (f == NULL) + { + fprintf (stderr, "Can't reopen file!\n"); + exit (1); + } + for(i = 0 ; i < sizeof(Buffer)-1 ; i++) + { + if (feof (f)) + { + fprintf (stderr, "Error EOF\n"); + exit (1); + } + if (Buffer[i] != fgetc (f)) + { + fprintf (stderr, "Character mismatch for i=%d / %lu\n", + i, (unsigned long) sizeof(Buffer)); + exit (1); + } + } + fclose (f); + + remove (FILE_NAME); + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tpow.c b/mpfr/tests/tpow.c new file mode 100644 index 0000000000..927f098ee5 --- /dev/null +++ b/mpfr/tests/tpow.c @@ -0,0 +1,1588 @@ +/* Test file for mpfr_pow, mpfr_pow_ui and mpfr_pow_si. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> +#include <math.h> +#include <limits.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_pow (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c) + && mpfr_get_prec (a) >= 53; + if (ok) + { + mpfr_print_raw (b); + printf (" "); + mpfr_print_raw (c); + } + res = mpfr_pow (a, b, c, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_pow mpfr_pow +#endif + +#define TEST_FUNCTION test_pow +#define TWO_ARGS +#define TEST_RANDOM_POS 16 +#define TGENERIC_NOWARNING 1 +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_pow_ui +#define INTEGER_TYPE unsigned long +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric_ui.c" + +#define TEST_FUNCTION mpfr_pow_si +#define INTEGER_TYPE long +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#define test_generic_ui test_generic_si +#include "tgeneric_ui.c" + +static void +check_pow_ui (void) +{ + mpfr_t a, b; + unsigned long n; + int res; + + mpfr_init2 (a, 53); + mpfr_init2 (b, 53); + + /* check in-place operations */ + mpfr_set_str (b, "0.6926773", 10, MPFR_RNDN); + mpfr_pow_ui (a, b, 10, MPFR_RNDN); + mpfr_pow_ui (b, b, 10, MPFR_RNDN); + if (mpfr_cmp (a, b)) + { + printf ("Error for mpfr_pow_ui (b, b, ...)\n"); + exit (1); + } + + /* check large exponents */ + mpfr_set_ui (b, 1, MPFR_RNDN); + mpfr_pow_ui (a, b, 4294967295UL, MPFR_RNDN); + + mpfr_set_inf (a, -1); + mpfr_pow_ui (a, a, 4049053855UL, MPFR_RNDN); + if (!mpfr_inf_p (a) || (mpfr_sgn (a) >= 0)) + { + printf ("Error for (-Inf)^4049053855\n"); + exit (1); + } + + mpfr_set_inf (a, -1); + mpfr_pow_ui (a, a, (unsigned long) 30002752, MPFR_RNDN); + if (!mpfr_inf_p (a) || (mpfr_sgn (a) <= 0)) + { + printf ("Error for (-Inf)^30002752\n"); + exit (1); + } + + /* Check underflow */ + mpfr_set_str_binary (a, "1E-1"); + res = mpfr_pow_ui (a, a, -mpfr_get_emin (), MPFR_RNDN); + if (MPFR_GET_EXP (a) != mpfr_get_emin () + 1) + { + printf ("Error for (1e-1)^MPFR_EMAX_MAX\n"); + mpfr_dump (a); + exit (1); + } + + mpfr_set_str_binary (a, "1E-10"); + res = mpfr_pow_ui (a, a, -mpfr_get_emin (), MPFR_RNDZ); + if (!MPFR_IS_ZERO (a)) + { + printf ("Error for (1e-10)^MPFR_EMAX_MAX\n"); + mpfr_dump (a); + exit (1); + } + + /* Check overflow */ + mpfr_set_str_binary (a, "1E10"); + res = mpfr_pow_ui (a, a, ULONG_MAX, MPFR_RNDN); + if (!MPFR_IS_INF (a) || MPFR_SIGN (a) < 0) + { + printf ("Error for (1e10)^ULONG_MAX\n"); + exit (1); + } + + /* Bug in pow_ui.c from r3214 to r5107: if x = y (same mpfr_t argument), + the input argument is negative, n is odd, an overflow or underflow + occurs, and the temporary result res is positive, then the result + gets a wrong sign (positive instead of negative). */ + mpfr_set_str_binary (a, "-1E10"); + n = (ULONG_MAX ^ (ULONG_MAX >> 1)) + 1; + res = mpfr_pow_ui (a, a, n, MPFR_RNDN); + if (!MPFR_IS_INF (a) || MPFR_SIGN (a) > 0) + { + printf ("Error for (-1e10)^%lu, expected -Inf,\ngot ", n); + mpfr_dump (a); + exit (1); + } + + /* Check 0 */ + MPFR_SET_ZERO (a); + MPFR_SET_POS (a); + mpfr_set_si (b, -1, MPFR_RNDN); + res = mpfr_pow_ui (b, a, 1, MPFR_RNDN); + if (res != 0 || MPFR_IS_NEG (b)) + { + printf ("Error for (0+)^1\n"); + exit (1); + } + MPFR_SET_ZERO (a); + MPFR_SET_NEG (a); + mpfr_set_ui (b, 1, MPFR_RNDN); + res = mpfr_pow_ui (b, a, 5, MPFR_RNDN); + if (res != 0 || MPFR_IS_POS (b)) + { + printf ("Error for (0-)^5\n"); + exit (1); + } + MPFR_SET_ZERO (a); + MPFR_SET_NEG (a); + mpfr_set_si (b, -1, MPFR_RNDN); + res = mpfr_pow_ui (b, a, 6, MPFR_RNDN); + if (res != 0 || MPFR_IS_NEG (b)) + { + printf ("Error for (0-)^6\n"); + exit (1); + } + + mpfr_set_prec (a, 122); + mpfr_set_prec (b, 122); + mpfr_set_str_binary (a, "0.10000010010000111101001110100101101010011110011100001111000001001101000110011001001001001011001011010110110110101000111011E1"); + mpfr_set_str_binary (b, "0.11111111100101001001000001000001100011100000001110111111100011111000111011100111111111110100011000111011000100100011001011E51290375"); + mpfr_pow_ui (a, a, 2026876995UL, MPFR_RNDU); + if (mpfr_cmp (a, b) != 0) + { + printf ("Error for x^2026876995\n"); + exit (1); + } + + mpfr_set_prec (a, 29); + mpfr_set_prec (b, 29); + mpfr_set_str_binary (a, "1.0000000000000000000000001111"); + mpfr_set_str_binary (b, "1.1001101111001100111001010111e165"); + mpfr_pow_ui (a, a, 2055225053, MPFR_RNDZ); + if (mpfr_cmp (a, b) != 0) + { + printf ("Error for x^2055225053\n"); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + /* worst case found by Vincent Lefevre, 25 Nov 2006 */ + mpfr_set_prec (a, 53); + mpfr_set_prec (b, 53); + mpfr_set_str_binary (a, "1.0000010110000100001000101101101001011101101011010111"); + mpfr_set_str_binary (b, "1.0000110111101111011010110100001100010000001010110100E1"); + mpfr_pow_ui (a, a, 35, MPFR_RNDN); + if (mpfr_cmp (a, b) != 0) + { + printf ("Error in mpfr_pow_ui for worst case (1)\n"); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN); + printf ("\n"); + exit (1); + } + /* worst cases found on 2006-11-26 */ + mpfr_set_str_binary (a, "1.0110100111010001101001010111001110010100111111000011"); + mpfr_set_str_binary (b, "1.1111010011101110001111010110000101110000110110101100E17"); + mpfr_pow_ui (a, a, 36, MPFR_RNDD); + if (mpfr_cmp (a, b) != 0) + { + printf ("Error in mpfr_pow_ui for worst case (2)\n"); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_set_str_binary (a, "1.1001010100001110000110111111100011011101110011000100"); + mpfr_set_str_binary (b, "1.1100011101101101100010110001000001110001111110010001E23"); + mpfr_pow_ui (a, a, 36, MPFR_RNDU); + if (mpfr_cmp (a, b) != 0) + { + printf ("Error in mpfr_pow_ui for worst case (3)\n"); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear (a); + mpfr_clear (b); +} + +static void +check_pow_si (void) +{ + mpfr_t x; + + mpfr_init (x); + + mpfr_set_nan (x); + mpfr_pow_si (x, x, -1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x)); + + mpfr_set_inf (x, 1); + mpfr_pow_si (x, x, -1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + + mpfr_set_inf (x, -1); + mpfr_pow_si (x, x, -1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x)); + + mpfr_set_inf (x, -1); + mpfr_pow_si (x, x, -2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_pow_si (x, x, -1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_pow_si (x, x, -1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_pow_si (x, x, -2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + + mpfr_set_si (x, 2, MPFR_RNDN); + mpfr_pow_si (x, x, LONG_MAX, MPFR_RNDN); /* 2^LONG_MAX */ + if (LONG_MAX > mpfr_get_emax () - 1) /* LONG_MAX + 1 > emax */ + { + MPFR_ASSERTN (mpfr_inf_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, (mpfr_exp_t) LONG_MAX)); + } + + mpfr_set_si (x, 2, MPFR_RNDN); + mpfr_pow_si (x, x, LONG_MIN, MPFR_RNDN); /* 2^LONG_MIN */ + if (LONG_MIN + 1 < mpfr_get_emin ()) + { + MPFR_ASSERTN (mpfr_zero_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, (mpfr_exp_t) LONG_MIN)); + } + + mpfr_set_si (x, 2, MPFR_RNDN); + mpfr_pow_si (x, x, LONG_MIN + 1, MPFR_RNDN); /* 2^(LONG_MIN+1) */ + if (mpfr_nan_p (x)) + { + printf ("Error in pow_si(2, LONG_MIN+1): got NaN\n"); + exit (1); + } + if (LONG_MIN + 2 < mpfr_get_emin ()) + { + MPFR_ASSERTN (mpfr_zero_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, (mpfr_exp_t) (LONG_MIN + 1))); + } + + mpfr_set_si_2exp (x, 1, -1, MPFR_RNDN); /* 0.5 */ + mpfr_pow_si (x, x, LONG_MIN, MPFR_RNDN); /* 2^(-LONG_MIN) */ + if (LONG_MIN < 1 - mpfr_get_emax ()) /* 1 - LONG_MIN > emax */ + { + MPFR_ASSERTN (mpfr_inf_p (x)); + } + else + { + MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 2, (mpfr_exp_t) - (LONG_MIN + 1))); + } + + mpfr_clear (x); +} + +static void +check_special_pow_si (void) +{ + mpfr_t a, b; + mpfr_exp_t emin; + + mpfr_init (a); + mpfr_init (b); + mpfr_set_str (a, "2E100000000", 10, MPFR_RNDN); + mpfr_set_si (b, -10, MPFR_RNDN); + test_pow (b, a, b, MPFR_RNDN); + if (!MPFR_IS_ZERO(b)) + { + printf("Pow(2E10000000, -10) failed\n"); + mpfr_dump (a); + mpfr_dump (b); + exit(1); + } + + emin = mpfr_get_emin (); + mpfr_set_emin (-10); + mpfr_set_si (a, -2, MPFR_RNDN); + mpfr_pow_si (b, a, -10000, MPFR_RNDN); + if (!MPFR_IS_ZERO (b)) + { + printf ("Pow_so (1, -10000) doesn't underflow if emin=-10.\n"); + mpfr_dump (a); + mpfr_dump (b); + exit (1); + } + mpfr_set_emin (emin); + mpfr_clear (a); + mpfr_clear (b); +} + +static void +pow_si_long_min (void) +{ + mpfr_t x, y, z; + int inex; + + mpfr_inits2 (sizeof(long) * CHAR_BIT + 32, x, y, z, (mpfr_ptr) 0); + mpfr_set_si_2exp (x, 3, -1, MPFR_RNDN); /* 1.5 */ + + inex = mpfr_set_si (y, LONG_MIN, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_nextbelow (y); + mpfr_pow (y, x, y, MPFR_RNDD); + + inex = mpfr_set_si (z, LONG_MIN, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_nextabove (z); + mpfr_pow (z, x, z, MPFR_RNDU); + + mpfr_pow_si (x, x, LONG_MIN, MPFR_RNDN); /* 1.5^LONG_MIN */ + if (mpfr_cmp (x, y) < 0 || mpfr_cmp (x, z) > 0) + { + printf ("Error in pow_si_long_min\n"); + exit (1); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static void +check_inexact (mpfr_prec_t p) +{ + mpfr_t x, y, z, t; + unsigned long u; + mpfr_prec_t q; + int inexact, cmp; + int rnd; + + mpfr_init2 (x, p); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + mpfr_urandomb (x, RANDS); + u = randlimb () % 2; + for (q = 2; q <= p; q++) + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + mpfr_set_prec (y, q); + mpfr_set_prec (z, q + 10); + mpfr_set_prec (t, q); + inexact = mpfr_pow_ui (y, x, u, (mpfr_rnd_t) rnd); + cmp = mpfr_pow_ui (z, x, u, (mpfr_rnd_t) rnd); + if (mpfr_can_round (z, q + 10, (mpfr_rnd_t) rnd, (mpfr_rnd_t) rnd, q)) + { + cmp = mpfr_set (t, z, (mpfr_rnd_t) rnd) || cmp; + if (mpfr_cmp (y, t)) + { + printf ("results differ for u=%lu rnd=%s\n", + u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + printf ("t="); mpfr_print_binary (t); puts (""); + printf ("z="); mpfr_print_binary (z); puts (""); + exit (1); + } + if (((inexact == 0) && (cmp != 0)) || + ((inexact != 0) && (cmp == 0))) + { + printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n", + (unsigned int) p, (unsigned int) q, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("u=%lu x=", u); mpfr_print_binary (x); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + exit (1); + } + } + } + + /* check exact power */ + mpfr_set_prec (x, p); + mpfr_set_prec (y, p); + mpfr_set_prec (z, p); + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_set_str (y, "0.5", 10, MPFR_RNDN); + test_pow (z, x, y, MPFR_RNDZ); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +static void +special (void) +{ + mpfr_t x, y, z, t; + mpfr_exp_t emin, emax; + int inex; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_init2 (z, 53); + mpfr_init2 (t, 2); + + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_pow_si (x, x, -2, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (x, 1, -2)) + { + printf ("Error in pow_si(x,x,-2) for x=2\n"); + exit (1); + } + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_set_si (y, -2, MPFR_RNDN); + test_pow (x, x, y, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (x, 1, -2)) + { + printf ("Error in pow(x,x,y) for x=2, y=-2\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_str_binary (x, "1.0e-1"); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (y, "0.11010110011100101010110011001010100111000001000101110E-1"); + mpfr_set_prec (z, 2); + test_pow (z, x, y, MPFR_RNDZ); + mpfr_set_str_binary (x, "1.0e-1"); + if (mpfr_cmp (x, z)) + { + printf ("Error in mpfr_pow (1)\n"); + exit (1); + } + + mpfr_set_prec (x, 64); + mpfr_set_prec (y, 64); + mpfr_set_prec (z, 64); + mpfr_set_prec (t, 64); + mpfr_set_str_binary (x, "0.111011000111100000111010000101010100110011010000011"); + mpfr_set_str_binary (y, "0.111110010100110000011101100011010111000010000100101"); + mpfr_set_str_binary (t, "0.1110110011110110001000110100100001001111010011111000010000011001"); + + test_pow (z, x, y, MPFR_RNDN); + if (mpfr_cmp (z, t)) + { + printf ("Error in mpfr_pow for prec=64, rnd=MPFR_RNDN\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_prec (z, 53); + mpfr_set_str (x, "5.68824667828621954868e-01", 10, MPFR_RNDN); + mpfr_set_str (y, "9.03327850535952658895e-01", 10, MPFR_RNDN); + test_pow (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_str1 (z, "0.60071044650456473235")) + { + printf ("Error in mpfr_pow for prec=53, rnd=MPFR_RNDZ\n"); + exit (1); + } + + mpfr_set_prec (t, 2); + mpfr_set_prec (x, 30); + mpfr_set_prec (y, 30); + mpfr_set_prec (z, 30); + mpfr_set_str (x, "1.00000000001010111110001111011e1", 2, MPFR_RNDN); + mpfr_set_str (t, "-0.5", 10, MPFR_RNDN); + test_pow (z, x, t, MPFR_RNDN); + mpfr_set_str (y, "1.01101001111010101110000101111e-1", 2, MPFR_RNDN); + if (mpfr_cmp (z, y)) + { + printf ("Error in mpfr_pow for prec=30, rnd=MPFR_RNDN\n"); + exit (1); + } + + mpfr_set_prec (x, 21); + mpfr_set_prec (y, 21); + mpfr_set_prec (z, 21); + mpfr_set_str (x, "1.11111100100001100101", 2, MPFR_RNDN); + test_pow (z, x, t, MPFR_RNDZ); + mpfr_set_str (y, "1.01101011010001100000e-1", 2, MPFR_RNDN); + if (mpfr_cmp (z, y)) + { + printf ("Error in mpfr_pow for prec=21, rnd=MPFR_RNDZ\n"); + printf ("Expected "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\nGot "); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + /* From http://www.terra.es/personal9/ismaeljc/hall.htm */ + mpfr_set_prec (x, 113); + mpfr_set_prec (y, 2); + mpfr_set_prec (z, 169); + mpfr_set_str1 (x, "6078673043126084065007902175846955"); + mpfr_set_ui_2exp (y, 3, -1, MPFR_RNDN); + test_pow (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264144")) + { + printf ("Error in mpfr_pow for 6078673043126084065007902175846955"); + printf ("^(3/2), MPFR_RNDZ\nExpected "); + printf ("4.73928882491000966028828671876527456070714790264144e50"); + printf ("\nGot "); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + test_pow (z, x, y, MPFR_RNDU); + if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264145")) + { + printf ("Error in mpfr_pow for 6078673043126084065007902175846955"); + printf ("^(3/2), MPFR_RNDU\nExpected "); + printf ("4.73928882491000966028828671876527456070714790264145e50"); + printf ("\nGot "); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_set_prec (y, 2); + mpfr_set_str_binary (y, "1E10"); + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z)); + mpfr_set_inf (x, -1); + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z)); + mpfr_set_prec (y, 10); + mpfr_set_str_binary (y, "1.000000001E9"); + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_NEG(z)); + mpfr_set_str_binary (y, "1.000000001E8"); + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z)); + + mpfr_set_inf (x, -1); + mpfr_set_prec (y, 2 * mp_bits_per_limb); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_mul_2exp (y, y, mp_bits_per_limb - 1, MPFR_RNDN); + /* y = 2^(mp_bits_per_limb - 1) */ + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z)); + mpfr_nextabove (y); + test_pow (z, x, y, MPFR_RNDN); + /* y = 2^(mp_bits_per_limb - 1) + epsilon */ + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z)); + mpfr_nextbelow (y); + mpfr_div_2exp (y, y, 1, MPFR_RNDN); + mpfr_nextabove (y); + test_pow (z, x, y, MPFR_RNDN); + /* y = 2^(mp_bits_per_limb - 2) + epsilon */ + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z)); + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_set_prec (y, 2); + mpfr_set_str_binary (y, "1E10"); + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0); + + /* Check (-0)^(17.0001) */ + mpfr_set_prec (x, 6); + mpfr_set_prec (y, 640); + MPFR_SET_ZERO (x); MPFR_SET_NEG (x); + mpfr_set_ui (y, 17, MPFR_RNDN); mpfr_nextabove (y); + test_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z)); + + /* Bugs reported by Kevin Rauch on 29 Oct 2007 */ + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + mpfr_set_emin (-1000000); + mpfr_set_emax ( 1000000); + mpfr_set_prec (x, 64); + mpfr_set_prec (y, 64); + mpfr_set_prec (z, 64); + mpfr_set_str (x, "-0.5", 10, MPFR_RNDN); + mpfr_set_str (y, "-0.ffffffffffffffff", 16, MPFR_RNDN); + mpfr_set_exp (y, mpfr_get_emax ()); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + /* (-0.5)^(-n) = 1/2^n for n even */ + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS (z) && inex > 0); + + /* (-1)^(-n) = 1 for n even */ + mpfr_set_str (x, "-1", 10, MPFR_RNDN); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0 && inex == 0); + + /* (-1)^n = 1 for n even */ + mpfr_set_str (x, "-1", 10, MPFR_RNDN); + mpfr_neg (y, y, MPFR_RNDN); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0 && inex == 0); + + /* (-1.5)^n = +Inf for n even */ + mpfr_set_str (x, "-1.5", 10, MPFR_RNDN); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS (z) && inex > 0); + + /* (-n)^1.5 = NaN for n even */ + mpfr_neg (y, y, MPFR_RNDN); + mpfr_set_str (x, "1.5", 10, MPFR_RNDN); + inex = mpfr_pow (z, y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (z)); + + /* x^(-1.5) = NaN for x small < 0 */ + mpfr_set_str (x, "-0.8", 16, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin ()); + mpfr_set_str (y, "-1.5", 10, MPFR_RNDN); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (z)); + + mpfr_set_emin (emin); + mpfr_set_emax (emax); + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +static void +particular_cases (void) +{ + mpfr_t t[11], r, r2; + mpz_t z; + long si; + + static const char *name[11] = { + "NaN", "+inf", "-inf", "+0", "-0", "+1", "-1", "+2", "-2", "+0.5", "-0.5"}; + int i, j; + int error = 0; + + mpz_init (z); + + for (i = 0; i < 11; i++) + mpfr_init2 (t[i], 2); + mpfr_init2 (r, 6); + mpfr_init2 (r2, 6); + + mpfr_set_nan (t[0]); + mpfr_set_inf (t[1], 1); + mpfr_set_ui (t[3], 0, MPFR_RNDN); + mpfr_set_ui (t[5], 1, MPFR_RNDN); + mpfr_set_ui (t[7], 2, MPFR_RNDN); + mpfr_div_2ui (t[9], t[5], 1, MPFR_RNDN); + for (i = 1; i < 11; i += 2) + mpfr_neg (t[i+1], t[i], MPFR_RNDN); + + for (i = 0; i < 11; i++) + for (j = 0; j < 11; j++) + { + double d; + int p; + static const int q[11][11] = { + /* NaN +inf -inf +0 -0 +1 -1 +2 -2 +0.5 -0.5 */ + /* NaN */ { 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0 }, + /* +inf */ { 0, 1, 2, 128, 128, 1, 2, 1, 2, 1, 2 }, + /* -inf */ { 0, 1, 2, 128, 128, -1, -2, 1, 2, 1, 2 }, + /* +0 */ { 0, 2, 1, 128, 128, 2, 1, 2, 1, 2, 1 }, + /* -0 */ { 0, 2, 1, 128, 128, -2, -1, 2, 1, 2, 1 }, + /* +1 */ {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, + /* -1 */ { 0, 128, 128, 128, 128,-128,-128, 128, 128, 0, 0 }, + /* +2 */ { 0, 1, 2, 128, 128, 256, 64, 512, 32, 180, 90 }, + /* -2 */ { 0, 1, 2, 128, 128,-256, -64, 512, 32, 0, 0 }, + /* +0.5 */ { 0, 2, 1, 128, 128, 64, 256, 32, 512, 90, 180 }, + /* -0.5 */ { 0, 2, 1, 128, 128, -64,-256, 32, 512, 0, 0 } + }; + /* This define is used to make the following table readable */ +#define N MPFR_FLAGS_NAN +#define I MPFR_FLAGS_INEXACT +#define D MPFR_FLAGS_DIVBY0 + static const unsigned int f[11][11] = { + /* NaN +inf -inf +0 -0 +1 -1 +2 -2 +0.5 -0.5 */ + /* NaN */ { N, N, N, 0, 0, N, N, N, N, N, N }, + /* +inf */ { N, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* -inf */ { N, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* +0 */ { N, 0, 0, 0, 0, 0, D, 0, D, 0, D }, + /* -0 */ { N, 0, 0, 0, 0, 0, D, 0, D, 0, D }, + /* +1 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* -1 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, N, N }, + /* +2 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, I, I }, + /* -2 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, N, N }, + /* +0.5 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, I, I }, + /* -0.5 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, N, N } + }; +#undef N +#undef I +#undef D + mpfr_clear_flags (); + test_pow (r, t[i], t[j], MPFR_RNDN); + p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 : + mpfr_cmp_ui (r, 0) == 0 ? 2 : + (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0)); + if (p != 0 && MPFR_IS_NEG (r)) + p = -p; + if (p != q[i][j]) + { + printf ("Error in mpfr_pow for (%s)^(%s) (%d,%d):\n" + "got %d instead of %d\n", + name[i], name[j], i, j, p, q[i][j]); + mpfr_dump (r); + error = 1; + } + if (__gmpfr_flags != f[i][j]) + { + printf ("Error in mpfr_pow for (%s)^(%s) (%d,%d):\n" + "Flags = %u instead of expected %u\n", + name[i], name[j], i, j, __gmpfr_flags, f[i][j]); + mpfr_dump (r); + error = 1; + } + /* Perform the same tests with pow_z & pow_si & pow_ui + if t[j] is an integer */ + if (mpfr_integer_p (t[j])) + { + /* mpfr_pow_z */ + mpfr_clear_flags (); + mpfr_get_z (z, t[j], MPFR_RNDN); + mpfr_pow_z (r, t[i], z, MPFR_RNDN); + p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 : + mpfr_cmp_ui (r, 0) == 0 ? 2 : + (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0)); + if (p != 0 && MPFR_IS_NEG (r)) + p = -p; + if (p != q[i][j]) + { + printf ("Error in mpfr_pow_z for (%s)^(%s) (%d,%d):\n" + "got %d instead of %d\n", + name[i], name[j], i, j, p, q[i][j]); + mpfr_dump (r); + error = 1; + } + if (__gmpfr_flags != f[i][j]) + { + printf ("Error in mpfr_pow_z for (%s)^(%s) (%d,%d):\n" + "Flags = %u instead of expected %u\n", + name[i], name[j], i, j, __gmpfr_flags, f[i][j]); + mpfr_dump (r); + error = 1; + } + /* mpfr_pow_si */ + mpfr_clear_flags (); + si = mpfr_get_si (t[j], MPFR_RNDN); + mpfr_pow_si (r, t[i], si, MPFR_RNDN); + p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 : + mpfr_cmp_ui (r, 0) == 0 ? 2 : + (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0)); + if (p != 0 && MPFR_IS_NEG (r)) + p = -p; + if (p != q[i][j]) + { + printf ("Error in mpfr_pow_si for (%s)^(%s) (%d,%d):\n" + "got %d instead of %d\n", + name[i], name[j], i, j, p, q[i][j]); + mpfr_dump (r); + error = 1; + } + if (__gmpfr_flags != f[i][j]) + { + printf ("Error in mpfr_pow_si for (%s)^(%s) (%d,%d):\n" + "Flags = %u instead of expected %u\n", + name[i], name[j], i, j, __gmpfr_flags, f[i][j]); + mpfr_dump (r); + error = 1; + } + /* if si >= 0, test mpfr_pow_ui */ + if (si >= 0) + { + mpfr_clear_flags (); + mpfr_pow_ui (r, t[i], si, MPFR_RNDN); + p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 : + mpfr_cmp_ui (r, 0) == 0 ? 2 : + (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0)); + if (p != 0 && MPFR_IS_NEG (r)) + p = -p; + if (p != q[i][j]) + { + printf ("Error in mpfr_pow_ui for (%s)^(%s) (%d,%d):\n" + "got %d instead of %d\n", + name[i], name[j], i, j, p, q[i][j]); + mpfr_dump (r); + error = 1; + } + if (__gmpfr_flags != f[i][j]) + { + printf ("Error in mpfr_pow_ui for (%s)^(%s) (%d,%d):\n" + "Flags = %u instead of expected %u\n", + name[i], name[j], i, j, __gmpfr_flags, f[i][j]); + mpfr_dump (r); + error = 1; + } + } + } /* integer_p */ + /* Perform the same tests with mpfr_ui_pow */ + if (mpfr_integer_p (t[i]) && MPFR_IS_POS (t[i])) + { + /* mpfr_ui_pow */ + mpfr_clear_flags (); + si = mpfr_get_si (t[i], MPFR_RNDN); + mpfr_ui_pow (r, si, t[j], MPFR_RNDN); + p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 : + mpfr_cmp_ui (r, 0) == 0 ? 2 : + (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0)); + if (p != 0 && MPFR_IS_NEG (r)) + p = -p; + if (p != q[i][j]) + { + printf ("Error in mpfr_ui_pow for (%s)^(%s) (%d,%d):\n" + "got %d instead of %d\n", + name[i], name[j], i, j, p, q[i][j]); + mpfr_dump (r); + error = 1; + } + if (__gmpfr_flags != f[i][j]) + { + printf ("Error in mpfr_ui_pow for (%s)^(%s) (%d,%d):\n" + "Flags = %u instead of expected %u\n", + name[i], name[j], i, j, __gmpfr_flags, f[i][j]); + mpfr_dump (r); + error = 1; + } + } + } + + for (i = 0; i < 11; i++) + mpfr_clear (t[i]); + mpfr_clear (r); + mpfr_clear (r2); + mpz_clear (z); + + if (error) + exit (1); +} + +static void +underflows (void) +{ + mpfr_t x, y, z; + int err = 0; + int inexact; + int i; + mpfr_exp_t emin; + + mpfr_init2 (x, 64); + mpfr_init2 (y, 64); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin()); + + for (i = 3; i < 10; i++) + { + mpfr_set_ui (y, i, MPFR_RNDN); + mpfr_div_2ui (y, y, 1, MPFR_RNDN); + test_pow (y, x, y, MPFR_RNDN); + if (!MPFR_IS_FP(y) || mpfr_cmp_ui (y, 0)) + { + printf ("Error in mpfr_pow for "); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" ^ (%d/2)\nGot ", i); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" instead of 0.\n"); + exit (1); + } + } + + mpfr_init2 (z, 55); + mpfr_set_str (x, "0.110011010011101001110001110100010000110111101E0", + 2, MPFR_RNDN); + mpfr_set_str (y, "0.101110010011111001011010100011011100111110011E40", + 2, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_pow (z, x, y, MPFR_RNDU); + if (!mpfr_underflow_p ()) + { + printf ("Underflow flag is not set for special underflow test.\n"); + err = 1; + } + if (inexact <= 0) + { + printf ("Ternary value is wrong for special underflow test.\n"); + err = 1; + } + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_nextabove (x); + if (mpfr_cmp (x, z) != 0) + { + printf ("Wrong value for special underflow test.\nGot "); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf ("\ninstead of "); + mpfr_out_str (stdout, 2, 2, x, MPFR_RNDN); + printf ("\n"); + err = 1; + } + if (err) + exit (1); + + /* MPFR currently (2006-08-19) segfaults on the following code (and + possibly makes other programs crash due to the lack of memory), + because y is converted into an mpz_t, and the required precision + is too high. */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_prec (z, 12); + mpfr_set_ui_2exp (x, 3, -2, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, mpfr_get_emax () - 1, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_pow (z, x, y, MPFR_RNDN); + if (!mpfr_underflow_p () || MPFR_NOTZERO (z)) + { + printf ("Underflow test with large y fails.\n"); + exit (1); + } + + emin = mpfr_get_emin (); + mpfr_set_emin (-256); + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_prec (z, 12); + mpfr_set_ui_2exp (x, 3, -2, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, 38, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_pow (z, x, y, MPFR_RNDN); + if (!mpfr_underflow_p () || MPFR_NOTZERO (z) || inexact >= 0) + { + printf ("Bad underflow detection for 0.75^(2^38). Obtained:\n" + "Underflow flag... %-3s (should be 'yes')\n" + "Zero result...... %-3s (should be 'yes')\n" + "Inexact value.... %-3d (should be negative)\n", + mpfr_underflow_p () ? "yes" : "no", + MPFR_IS_ZERO (z) ? "yes" : "no", inexact); + exit (1); + } + mpfr_set_emin (emin); + + emin = mpfr_get_emin (); + mpfr_set_emin (-256); + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 40); + mpfr_set_prec (z, 12); + mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN); + mpfr_set_si_2exp (y, -1, 38, MPFR_RNDN); + for (i = 0; i < 4; i++) + { + if (i == 2) + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inexact = mpfr_pow (z, x, y, MPFR_RNDN); + if (!mpfr_underflow_p () || MPFR_NOTZERO (z) || + (i == 3 ? (inexact <= 0) : (inexact >= 0))) + { + printf ("Bad underflow detection for ("); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (")^(-2^38-%d). Obtained:\n" + "Overflow flag.... %-3s (should be 'no')\n" + "Underflow flag... %-3s (should be 'yes')\n" + "Zero result...... %-3s (should be 'yes')\n" + "Inexact value.... %-3d (should be %s)\n", i, + mpfr_overflow_p () ? "yes" : "no", + mpfr_underflow_p () ? "yes" : "no", + MPFR_IS_ZERO (z) ? "yes" : "no", inexact, + i == 3 ? "positive" : "negative"); + exit (1); + } + inexact = mpfr_sub_ui (y, y, 1, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + } + mpfr_set_emin (emin); + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static void +overflows (void) +{ + mpfr_t a, b; + + /* bug found by Ming J. Tsai <mingjt@delvron.us>, 4 Oct 2003 */ + + mpfr_init_set_str (a, "5.1e32", 10, MPFR_RNDN); + mpfr_init (b); + + test_pow (b, a, a, MPFR_RNDN); + if (!(mpfr_inf_p (b) && mpfr_sgn (b) > 0)) + { + printf ("Error for a^a for a=5.1e32\n"); + printf ("Expected +Inf, got "); + mpfr_out_str (stdout, 10, 0, b, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear(a); + mpfr_clear(b); +} + +static void +overflows2 (void) +{ + mpfr_t x, y, z; + mpfr_exp_t emin, emax; + int e; + + /* x^y in reduced exponent range, where x = 2^b and y is not an integer + (so that mpfr_pow_z is not used). */ + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (-128); + + mpfr_inits2 (16, x, y, z, (mpfr_ptr) 0); + + mpfr_set_si_2exp (x, 1, -64, MPFR_RNDN); /* 2^(-64) */ + mpfr_set_si_2exp (y, -1, -1, MPFR_RNDN); /* -0.5 */ + for (e = 2; e <= 32; e += 17) + { + set_emax (e); + mpfr_clear_flags (); + mpfr_pow (z, x, y, MPFR_RNDN); + if (MPFR_IS_NEG (z) || ! mpfr_inf_p (z)) + { + printf ("Error in overflows2 (e = %d): expected +Inf, got ", e); + mpfr_dump (z); + exit (1); + } + if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)) + { + printf ("Error in overflows2 (e = %d): bad flags (%u)\n", + e, __gmpfr_flags); + exit (1); + } + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +static void +overflows3 (void) +{ + /* x^y where x = 2^b, y is not an integer (so that mpfr_pow_z is not used) + and b * y = emax in the extended exponent range. If emax is divisible + by 3, we choose x = 2^(-2*emax/3) and y = -3/2. + Test also with nextbelow(x). */ + + if (MPFR_EMAX_MAX % 3 == 0) + { + mpfr_t x, y, z, t; + mpfr_exp_t emin, emax; + unsigned int flags; + int i; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + mpfr_inits2 (16, x, y, z, t, (mpfr_ptr) 0); + + mpfr_set_si_2exp (x, 1, -2 * (MPFR_EMAX_MAX / 3), MPFR_RNDN); + for (i = 0; i <= 1; i++) + { + mpfr_set_si_2exp (y, -3, -1, MPFR_RNDN); + mpfr_clear_flags (); + mpfr_pow (z, x, y, MPFR_RNDN); + if (MPFR_IS_NEG (z) || ! mpfr_inf_p (z)) + { + printf ("Error in overflows3 (RNDN, i = %d): expected +Inf," + " got ", i); + mpfr_dump (z); + exit (1); + } + if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)) + { + printf ("Error in overflows3 (RNDN, i = %d): bad flags (%u)\n", + i, __gmpfr_flags); + exit (1); + } + + mpfr_clear_flags (); + mpfr_pow (z, x, y, MPFR_RNDZ); + flags = __gmpfr_flags; + mpfr_set (t, z, MPFR_RNDN); + mpfr_nextabove (t); + if (MPFR_IS_NEG (z) || mpfr_inf_p (z) || ! mpfr_inf_p (t)) + { + printf ("Error in overflows3 (RNDZ, i = %d):\nexpected ", i); + mpfr_set_inf (t, 1); + mpfr_nextbelow (t); + mpfr_dump (t); + printf ("got "); + mpfr_dump (z); + exit (1); + } + if (flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)) + { + printf ("Error in overflows3 (RNDZ, i = %d): bad flags (%u)\n", + i, flags); + exit (1); + } + mpfr_nextbelow (x); + } + + mpfr_clears (x, y, z, t, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); + } +} + +static void +x_near_one (void) +{ + mpfr_t x, y, z; + int inex; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 4); + mpfr_init2 (z, 33); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_set_ui_2exp (y, 11, -2, MPFR_RNDN); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + if (mpfr_cmp_str (z, "0.111111111111111111111111111111011E0", 2, MPFR_RNDN) + || inex <= 0) + { + printf ("Failure in x_near_one, got inex = %d and\nz = ", inex); + mpfr_dump (z); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static int +mpfr_pow275 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r) +{ + mpfr_t z; + int inex; + + mpfr_init2 (z, 4); + mpfr_set_ui_2exp (z, 11, -2, MPFR_RNDN); + inex = mpfr_pow (y, x, z, MPFR_RNDN); + mpfr_clear (z); + return inex; +} + +/* Bug found by Kevin P. Rauch */ +static void +bug20071103 (void) +{ + mpfr_t x, y, z; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + mpfr_set_emin (-1000000); + mpfr_set_emax ( 1000000); + + mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0); + mpfr_set_si_2exp (x, -3, -1, MPFR_RNDN); /* x = -1.5 */ + mpfr_set_str (y, "-0.ffffffffffffffff", 16, MPFR_RNDN); + mpfr_set_exp (y, mpfr_get_emax ()); + mpfr_clear_flags (); + mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (z) && MPFR_SIGN (z) > 0 && + __gmpfr_flags == (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT)); + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +/* Bug found by Kevin P. Rauch */ +static void +bug20071104 (void) +{ + mpfr_t x, y, z; + mpfr_exp_t emin, emax; + int inex; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + mpfr_set_emin (-1000000); + mpfr_set_emax ( 1000000); + + mpfr_inits2 (20, x, y, z, (mpfr_ptr) 0); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_nextbelow (x); /* x = -2^(emin-1) */ + mpfr_set_si (y, -2, MPFR_RNDN); /* y = -2 */ + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, MPFR_RNDN); + if (! mpfr_inf_p (z) || MPFR_SIGN (z) < 0) + { + printf ("Error in bug20071104: expected +Inf, got "); + mpfr_dump (z); + exit (1); + } + if (inex <= 0) + { + printf ("Error in bug20071104: bad ternary value (%d)\n", inex); + exit (1); + } + if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)) + { + printf ("Error in bug20071104: bad flags (%u)\n", __gmpfr_flags); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +/* Bug found by Kevin P. Rauch */ +static void +bug20071127 (void) +{ + mpfr_t x, y, z; + int i, tern; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + mpfr_set_emin (-1000000); + mpfr_set_emax ( 1000000); + + mpfr_init2 (x, 128); + mpfr_init2 (y, 128); + mpfr_init2 (z, 128); + + mpfr_set_str (x, "0.80000000000000000000000000000001", 16, MPFR_RNDN); + + for (i = 1; i < 9; i *= 2) + { + mpfr_set_str (y, "8000000000000000", 16, MPFR_RNDN); + mpfr_add_si (y, y, i, MPFR_RNDN); + tern = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (z) && MPFR_IS_POS (z) && tern < 0); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + mpfr_set_emin (emin); + mpfr_set_emax (emax); +} + +/* Bug found by Kevin P. Rauch */ +static void +bug20071128 (void) +{ + mpfr_t max_val, x, y, z; + int i, tern; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + mpfr_set_emin (-1000000); + mpfr_set_emax ( 1000000); + + mpfr_init2 (max_val, 64); + mpfr_init2 (x, 64); + mpfr_init2 (y, 64); + mpfr_init2 (z, 64); + + mpfr_set_str (max_val, "0.ffffffffffffffff", 16, MPFR_RNDN); + mpfr_set_exp (max_val, mpfr_get_emax ()); + + mpfr_neg (x, max_val, MPFR_RNDN); + + /* on 64-bit machines */ + for (i = 41; i < 45; i++) + { + mpfr_set_si_2exp (y, -1, i, MPFR_RNDN); + mpfr_add_si (y, y, 1, MPFR_RNDN); + tern = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (z) && MPFR_IS_NEG (z) && tern > 0); + } + + /* on 32-bit machines */ + for (i = 9; i < 13; i++) + { + mpfr_set_si_2exp (y, -1, i, MPFR_RNDN); + mpfr_add_si (y, y, 1, MPFR_RNDN); + tern = mpfr_pow (z, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_zero_p (z) && MPFR_SIGN(z) < 0); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (max_val); + + mpfr_set_emin (emin); + mpfr_set_emax (emax); +} + +/* Bug found by Kevin P. Rauch */ +static void +bug20071218 (void) +{ + mpfr_t x, y, z, t; + int tern; + + mpfr_inits2 (64, x, y, z, t, (mpfr_ptr) 0); + mpfr_set_str (x, "0x.80000000000002P-1023", 0, MPFR_RNDN); + mpfr_set_str (y, "100000.000000002", 16, MPFR_RNDN); + mpfr_set_ui (t, 0, MPFR_RNDN); + mpfr_nextabove (t); + tern = mpfr_pow (z, x, y, MPFR_RNDN); + if (mpfr_cmp0 (z, t) != 0) + { + printf ("Error in bug20071218 (1): Expected\n"); + mpfr_dump (t); + printf ("Got\n"); + mpfr_dump (z); + exit (1); + } + if (tern <= 0) + { + printf ("Error in bug20071218 (1): bad ternary value" + " (%d instead of positive)\n", tern); + exit (1); + } + mpfr_mul_2ui (y, y, 32, MPFR_RNDN); + tern = mpfr_pow (z, x, y, MPFR_RNDN); + if (MPFR_NOTZERO (z) || MPFR_IS_NEG (z)) + { + printf ("Error in bug20071218 (2): expected 0, got\n"); + mpfr_dump (z); + exit (1); + } + if (tern >= 0) + { + printf ("Error in bug20071218 (2): bad ternary value" + " (%d instead of negative)\n", tern); + exit (1); + } + mpfr_clears (x, y, z, t, (mpfr_ptr) 0); +} + +/* With revision 5429, this gives: + * pow.c:43: assertion failed: !mpfr_integer_p (y) + * This is fixed in revision 5432. + */ +static void +bug20080721 (void) +{ + mpfr_t x, y, z, t[2]; + int inex; + int rnd; + int err = 0; + + /* Note: input values have been chosen in a way to select the + * general case. If mpfr_pow is modified, in particular line + * if (y_is_integer && (MPFR_GET_EXP (y) <= 256)) + * make sure that this test still does what we want. + */ + mpfr_inits2 (4913, x, y, (mpfr_ptr) 0); + mpfr_inits2 (8, z, t[0], t[1], (mpfr_ptr) 0); + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_set_ui_2exp (y, 1, mpfr_get_prec (y) - 1, MPFR_RNDN); + inex = mpfr_add_ui (y, y, 1, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_set_str_binary (t[0], "-0.10101101e2"); + mpfr_set_str_binary (t[1], "-0.10101110e2"); + RND_LOOP (rnd) + { + int i, inex0; + + i = (rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA); + inex0 = i ? -1 : 1; + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); + if (__gmpfr_flags != MPFR_FLAGS_INEXACT || ! SAME_SIGN (inex, inex0) + || MPFR_IS_NAN (z) || mpfr_cmp (z, t[i]) != 0) + { + unsigned int flags = __gmpfr_flags; + + printf ("Error in bug20080721 with %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("expected "); + mpfr_out_str (stdout, 2, 0, t[i], MPFR_RNDN); + printf (", inex = %d, flags = %u\n", inex0, + (unsigned int) MPFR_FLAGS_INEXACT); + printf ("got "); + mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf (", inex = %d, flags = %u\n", inex, flags); + err = 1; + } + } + mpfr_clears (x, y, z, t[0], t[1], (mpfr_ptr) 0); + if (err) + exit (1); +} + +/* The following test fails in r5552 (32-bit and 64-bit). This is due to: + * mpfr_log (t, absx, MPFR_RNDU); + * mpfr_mul (t, y, t, MPFR_RNDU); + * in pow.c, that is supposed to compute an upper bound on exp(y*ln|x|), + * but this is incorrect if y is negative. + */ +static void +bug20080820 (void) +{ + mpfr_exp_t emin; + mpfr_t x, y, z1, z2; + + emin = mpfr_get_emin (); + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_init2 (x, 80); + mpfr_init2 (y, sizeof (mpfr_exp_t) * CHAR_BIT + 32); + mpfr_init2 (z1, 2); + mpfr_init2 (z2, 80); + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_set_exp_t (y, mpfr_get_emin () - 2, MPFR_RNDN); + mpfr_nextabove (y); + mpfr_pow (z1, x, y, MPFR_RNDN); + mpfr_pow (z2, x, y, MPFR_RNDN); + /* As x > 0, the rounded value of x^y to nearest in precision p is equal + to 0 iff x^y <= 2^(emin - 2). In particular, this does not depend on + the precision p. Hence the following test. */ + if (MPFR_IS_ZERO (z1) && MPFR_NOTZERO (z2)) + { + printf ("Error in bug20080820\n"); + exit (1); + } + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); + set_emin (emin); +} + +static void +bug20110320 (void) +{ + mpfr_exp_t emin; + mpfr_t x, y, z1, z2; + int inex; + unsigned int flags; + + emin = mpfr_get_emin (); + mpfr_set_emin (11); + mpfr_inits2 (2, x, y, z1, z2, (mpfr_ptr) 0); + mpfr_set_ui_2exp (x, 1, 215, MPFR_RNDN); + mpfr_set_ui (y, 1024, MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_pow (z1, x, y, MPFR_RNDN); + flags = __gmpfr_flags; + mpfr_set_ui_2exp (z2, 1, 215*1024, MPFR_RNDN); + if (inex != 0 || flags != 0 || ! mpfr_equal_p (z1, z2)) + { + printf ("Error in bug20110320\n"); + printf ("Expected inex = 0, flags = 0, z = "); + mpfr_dump (z2); + printf ("Got inex = %d, flags = %u, z = ", inex, flags); + mpfr_dump (z1); + exit (1); + } + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); + set_emin (emin); +} + +int +main (int argc, char **argv) +{ + mpfr_prec_t p; + + tests_start_mpfr (); + + bug20071127 (); + special (); + particular_cases (); + check_pow_ui (); + check_pow_si (); + check_special_pow_si (); + pow_si_long_min (); + for (p = 2; p < 100; p++) + check_inexact (p); + underflows (); + overflows (); + overflows2 (); + overflows3 (); + x_near_one (); + bug20071103 (); + bug20071104 (); + bug20071128 (); + bug20071218 (); + bug20080721 (); + bug20080820 (); + bug20110320 (); + + test_generic (2, 100, 100); + test_generic_ui (2, 100, 100); + test_generic_si (2, 100, 100); + + data_check ("data/pow275", mpfr_pow275, "mpfr_pow275"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tpow3.c b/mpfr/tests/tpow3.c new file mode 100644 index 0000000000..58e3136757 --- /dev/null +++ b/mpfr/tests/tpow3.c @@ -0,0 +1,126 @@ +/* Test file for mpfr_pow. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> + +#include "mpfr-test.h" + + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, z; + + mpfr_prec_t prec, yprec; + mpfr_t t, s; + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n, err; + + mpfr_prec_t p0=2, p1=100; + unsigned int N=25; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init2 (y,sizeof(unsigned long int)*CHAR_BIT); + mpfr_init (z); + + mpfr_init (s); + mpfr_init (t); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (s, sizeof(unsigned long int)*CHAR_BIT); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n=0; n<N; n++) + { + mpfr_urandomb (x, RANDS); + mpfr_urandomb (s, RANDS); + if (randlimb () % 2) + mpfr_neg (s, s, MPFR_RNDN); + rnd = RND_RAND (); + mpfr_set_prec (y, yprec); + compare = mpfr_pow (y, x, s, rnd); + err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = mpfr_pow (z, x, s, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x^y with x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf (" y="); + mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + puts (""); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf ("approx "); + mpfr_print_binary (y); + puts (""); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if ((rnd != MPFR_RNDN) && (compare * compare2 >= 0)) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d" + "\n", mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + printf ("t="); mpfr_print_binary (t); puts (""); + exit (1); + } + } + } + } + + mpfr_clear (s); + mpfr_clear (t); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tpow_all.c b/mpfr/tests/tpow_all.c new file mode 100644 index 0000000000..588184d260 --- /dev/null +++ b/mpfr/tests/tpow_all.c @@ -0,0 +1,781 @@ +/* Test file for the various power functions + +Copyright 2008-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Note: some tests of the other tpow* test files could be moved there. + The main goal of this test file is to test _all_ the power functions + on special values, to make sure that they are consistent and give the + expected result, in particular because such special cases are handled + in different ways in each function. */ + +/* Execute with at least an argument to report all the errors found by + comparisons. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +/* Behavior of cmpres (called by test_others): + * 0: stop as soon as an error is found. + * 1: report all errors found by test_others. + * -1: the 1 is changed to this value as soon as an error has been found. + */ +static int all_cmpres_errors; + +/* Non-zero when extended exponent range */ +static int ext = 0; + +static const char *val[] = + { "min", "min+", "max", "@NaN@", "-@Inf@", "-4", "-3", "-2", "-1.5", + "-1", "-0.5", "-0", "0", "0.5", "1", "1.5", "2", "3", "4", "@Inf@" }; + +static void +err (const char *s, int i, int j, int rnd, mpfr_srcptr z, int inex) +{ + puts (s); + if (ext) + puts ("extended exponent range"); + printf ("x = %s, y = %s, %s\n", val[i], val[j], + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("z = "); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ninex = %d\n", inex); + exit (1); +} + +/* Arguments: + * spx: non-zero if px is a stringm zero if px is a MPFR number. + * px: value of x (string or MPFR number). + * sy: value of y (string). + * rnd: rounding mode. + * z1: expected result (null pointer if unknown pure FP value). + * inex1: expected ternary value (if z1 is not a null pointer). + * z2: computed result. + * inex2: computed ternary value. + * flags1: expected flags (computed flags in __gmpfr_flags). + * s1, s2: strings about the context. + */ +static void +cmpres (int spx, const void *px, const char *sy, mpfr_rnd_t rnd, + mpfr_srcptr z1, int inex1, mpfr_srcptr z2, int inex2, + unsigned int flags1, const char *s1, const char *s2) +{ + unsigned int flags2 = __gmpfr_flags; + + if (flags1 == flags2) + { + /* Note: the test on the sign of z1 and z2 is needed + in case they are both zeros. */ + if (z1 == NULL) + { + if (MPFR_IS_PURE_FP (z2)) + return; + } + else if (SAME_SIGN (inex1, inex2) && + ((MPFR_IS_NAN (z1) && MPFR_IS_NAN (z2)) || + ((MPFR_IS_NEG (z1) ^ MPFR_IS_NEG (z2)) == 0 && + mpfr_equal_p (z1, z2)))) + return; + } + + printf ("Error in %s\nwith %s%s\nx = ", s1, s2, + ext ? ", extended exponent range" : ""); + if (spx) + printf ("%s, ", (char *) px); + else + { + mpfr_out_str (stdout, 16, 0, (mpfr_ptr) px, MPFR_RNDN); + puts (","); + } + printf ("y = %s, %s\n", sy, mpfr_print_rnd_mode (rnd)); + printf ("Expected "); + if (z1 == NULL) + { + printf ("pure FP value, flags ="); + flags_out (flags1); + } + else + { + mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN); + printf (", inex = %d,\n flags =", SIGN (inex1)); + flags_out (flags1); + } + printf ("Got "); + mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN); + printf (", inex = %d,\n flags =", SIGN (inex2)); + flags_out (flags2); + if (all_cmpres_errors != 0) + all_cmpres_errors = -1; + else + exit (1); +} + +static int +is_odd (mpfr_srcptr x) +{ + /* works only with the values from val[] */ + return mpfr_integer_p (x) && mpfr_fits_slong_p (x, MPFR_RNDN) && + (mpfr_get_si (x, MPFR_RNDN) & 1); +} + +/* Compare the result (z1,inex1) of mpfr_pow with all flags cleared + with those of mpfr_pow with all flags set and of the other power + functions. Arguments x and y are the input values; sx and sy are + their string representations (sx may be null); rnd contains the + rounding mode; s is a string containing the function that called + test_others. */ +static void +test_others (const void *sx, const char *sy, mpfr_rnd_t rnd, + mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z1, + int inex1, unsigned int flags, const char *s) +{ + mpfr_t z2; + int inex2; + int spx = sx != NULL; + + if (!spx) + sx = x; + + mpfr_init2 (z2, mpfr_get_prec (z1)); + + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow (z2, x, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_pow, flags set"); + + /* If y is an integer that fits in an unsigned long and is not -0, + we can test mpfr_pow_ui. */ + if (MPFR_IS_POS (y) && mpfr_integer_p (y) && + mpfr_fits_ulong_p (y, MPFR_RNDN)) + { + unsigned long yy = mpfr_get_ui (y, MPFR_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_pow_ui (z2, x, yy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_pow_ui, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow_ui (z2, x, yy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_pow_ui, flags set"); + + /* If x is an integer that fits in an unsigned long and is not -0, + we can also test mpfr_ui_pow_ui. */ + if (MPFR_IS_POS (x) && mpfr_integer_p (x) && + mpfr_fits_ulong_p (x, MPFR_RNDN)) + { + unsigned long xx = mpfr_get_ui (x, MPFR_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_ui_pow_ui, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_ui_pow_ui, flags set"); + } + } + + /* If y is an integer but not -0 and not huge, we can test mpfr_pow_z, + and possibly mpfr_pow_si (and possibly mpfr_ui_div). */ + if (MPFR_IS_ZERO (y) ? MPFR_IS_POS (y) : + (mpfr_integer_p (y) && MPFR_GET_EXP (y) < 256)) + { + mpz_t yyy; + + /* If y fits in a long, we can test mpfr_pow_si. */ + if (mpfr_fits_slong_p (y, MPFR_RNDN)) + { + long yy = mpfr_get_si (y, MPFR_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_pow_si (z2, x, yy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_pow_si, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow_si (z2, x, yy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_pow_si, flags set"); + + /* If y = -1, we can test mpfr_ui_div. */ + if (yy == -1) + { + mpfr_clear_flags (); + inex2 = mpfr_ui_div (z2, 1, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_ui_div, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_ui_div (z2, 1, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_ui_div, flags set"); + } + + /* If y = 2, we can test mpfr_sqr. */ + if (yy == 2) + { + mpfr_clear_flags (); + inex2 = mpfr_sqr (z2, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_sqr, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_sqr (z2, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_sqr, flags set"); + } + } + + /* Test mpfr_pow_z. */ + mpz_init (yyy); + mpfr_get_z (yyy, y, MPFR_RNDN); + mpfr_clear_flags (); + inex2 = mpfr_pow_z (z2, x, yyy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_pow_z, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow_z (z2, x, yyy, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_pow_z, flags set"); + mpz_clear (yyy); + } + + /* If y = 0.5, we can test mpfr_sqrt, except if x is -0 or -Inf (because + the rule for mpfr_pow on these special values is different). */ + if (MPFR_IS_PURE_FP (y) && mpfr_cmp_str1 (y, "0.5") == 0 && + ! ((MPFR_IS_ZERO (x) || MPFR_IS_INF (x)) && MPFR_IS_NEG (x))) + { + mpfr_clear_flags (); + inex2 = mpfr_sqrt (z2, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_sqrt, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_sqrt (z2, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_sqrt, flags set"); + } + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + /* If y = -0.5, we can test mpfr_rec_sqrt, except if x = -Inf + (because the rule for mpfr_pow on -Inf is different). */ + if (MPFR_IS_PURE_FP (y) && mpfr_cmp_str1 (y, "-0.5") == 0 && + ! (MPFR_IS_INF (x) && MPFR_IS_NEG (x))) + { + mpfr_clear_flags (); + inex2 = mpfr_rec_sqrt (z2, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_rec_sqrt, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_rec_sqrt (z2, x, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_rec_sqrt, flags set"); + } +#endif + + /* If x is an integer that fits in an unsigned long and is not -0, + we can test mpfr_ui_pow. */ + if (MPFR_IS_POS (x) && mpfr_integer_p (x) && + mpfr_fits_ulong_p (x, MPFR_RNDN)) + { + unsigned long xx = mpfr_get_ui (x, MPFR_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_ui_pow (z2, xx, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_ui_pow, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_ui_pow (z2, xx, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_ui_pow, flags set"); + + /* If x = 2, we can test mpfr_exp2. */ + if (xx == 2) + { + mpfr_clear_flags (); + inex2 = mpfr_exp2 (z2, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_exp2, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_exp2 (z2, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_exp2, flags set"); + } + + /* If x = 10, we can test mpfr_exp10. */ + if (xx == 10) + { + mpfr_clear_flags (); + inex2 = mpfr_exp10 (z2, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags, + s, "mpfr_exp10, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_exp10 (z2, y, rnd); + cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL, + s, "mpfr_exp10, flags set"); + } + } + + mpfr_clear (z2); +} + +static int +my_setstr (mpfr_ptr t, const char *s) +{ + if (strcmp (s, "min") == 0) + { + mpfr_setmin (t, mpfr_get_emin ()); + MPFR_SET_POS (t); + return 0; + } + if (strcmp (s, "min+") == 0) + { + mpfr_setmin (t, mpfr_get_emin ()); + MPFR_SET_POS (t); + mpfr_nextabove (t); + return 0; + } + if (strcmp (s, "max") == 0) + { + mpfr_setmax (t, mpfr_get_emax ()); + MPFR_SET_POS (t); + return 0; + } + return mpfr_set_str (t, s, 10, MPFR_RNDN); +} + +static void +tst (void) +{ + int sv = sizeof (val) / sizeof (*val); + int i, j; + int rnd; + mpfr_t x, y, z, tmp; + + mpfr_inits2 (53, x, y, z, tmp, (mpfr_ptr) 0); + + for (i = 0; i < sv; i++) + for (j = 0; j < sv; j++) + RND_LOOP (rnd) + { + int exact, inex; + unsigned int flags; + + if (my_setstr (x, val[i]) || my_setstr (y, val[j])) + { + printf ("internal error for (%d,%d,%d)\n", i, j, rnd); + exit (1); + } + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); + flags = __gmpfr_flags; + if (! MPFR_IS_NAN (z) && mpfr_nanflag_p ()) + err ("got NaN flag without NaN value", i, j, rnd, z, inex); + if (MPFR_IS_NAN (z) && ! mpfr_nanflag_p ()) + err ("got NaN value without NaN flag", i, j, rnd, z, inex); + if (inex != 0 && ! mpfr_inexflag_p ()) + err ("got non-zero ternary value without inexact flag", + i, j, rnd, z, inex); + if (inex == 0 && mpfr_inexflag_p ()) + err ("got null ternary value with inexact flag", + i, j, rnd, z, inex); + if (i >= 3 && j >= 3) + { + if (mpfr_underflow_p ()) + err ("got underflow", i, j, rnd, z, inex); + if (mpfr_overflow_p ()) + err ("got overflow", i, j, rnd, z, inex); + exact = MPFR_IS_SINGULAR (z) || + (mpfr_mul_2ui (tmp, z, 16, MPFR_RNDN), mpfr_integer_p (tmp)); + if (exact && inex != 0) + err ("got exact value with ternary flag different from 0", + i, j, rnd, z, inex); + if (! exact && inex == 0) + err ("got inexact value with ternary flag equal to 0", + i, j, rnd, z, inex); + } + if (MPFR_IS_ZERO (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y)) + { + if (MPFR_IS_NEG (y) && ! MPFR_IS_INF (z)) + err ("expected an infinity", i, j, rnd, z, inex); + if (MPFR_IS_POS (y) && ! MPFR_IS_ZERO (z)) + err ("expected a zero", i, j, rnd, z, inex); + if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z)) + err ("wrong sign", i, j, rnd, z, inex); + } + if (! MPFR_IS_NAN (x) && mpfr_cmp_si (x, -1) == 0) + { + /* x = -1 */ + if (! (MPFR_IS_INF (y) || mpfr_integer_p (y)) && + ! MPFR_IS_NAN (z)) + err ("expected NaN", i, j, rnd, z, inex); + if ((MPFR_IS_INF (y) || (mpfr_integer_p (y) && ! is_odd (y))) + && ! mpfr_equal_p (z, __gmpfr_one)) + err ("expected 1", i, j, rnd, z, inex); + if (is_odd (y) && + (MPFR_IS_NAN (z) || mpfr_cmp_si (z, -1) != 0)) + err ("expected -1", i, j, rnd, z, inex); + } + if ((mpfr_equal_p (x, __gmpfr_one) || MPFR_IS_ZERO (y)) && + ! mpfr_equal_p (z, __gmpfr_one)) + err ("expected 1", i, j, rnd, z, inex); + if (MPFR_IS_PURE_FP (x) && MPFR_IS_NEG (x) && + MPFR_IS_FP (y) && ! mpfr_integer_p (y) && + ! MPFR_IS_NAN (z)) + err ("expected NaN", i, j, rnd, z, inex); + if (MPFR_IS_INF (y) && MPFR_NOTZERO (x)) + { + int cmpabs1 = mpfr_cmpabs (x, __gmpfr_one); + + if ((MPFR_IS_NEG (y) ? (cmpabs1 < 0) : (cmpabs1 > 0)) && + ! (MPFR_IS_POS (z) && MPFR_IS_INF (z))) + err ("expected +Inf", i, j, rnd, z, inex); + if ((MPFR_IS_NEG (y) ? (cmpabs1 > 0) : (cmpabs1 < 0)) && + ! (MPFR_IS_POS (z) && MPFR_IS_ZERO (z))) + err ("expected +0", i, j, rnd, z, inex); + } + if (MPFR_IS_INF (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y)) + { + if (MPFR_IS_POS (y) && ! MPFR_IS_INF (z)) + err ("expected an infinity", i, j, rnd, z, inex); + if (MPFR_IS_NEG (y) && ! MPFR_IS_ZERO (z)) + err ("expected a zero", i, j, rnd, z, inex); + if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z)) + err ("wrong sign", i, j, rnd, z, inex); + } + test_others (val[i], val[j], (mpfr_rnd_t) rnd, x, y, z, inex, flags, + "tst"); + } + mpfr_clears (x, y, z, tmp, (mpfr_ptr) 0); +} + +static void +underflow_up1 (void) +{ + mpfr_t delta, x, y, z, z0; + mpfr_exp_t n; + int inex; + int rnd; + int i; + + n = mpfr_get_emin (); + if (n < LONG_MIN) + return; + + mpfr_init2 (delta, 2); + inex = mpfr_set_ui_2exp (delta, 1, -2, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + mpfr_init2 (x, 8); + inex = mpfr_set_ui (x, 2, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + mpfr_init2 (y, sizeof (long) * CHAR_BIT + 4); + inex = mpfr_set_si (y, n, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + mpfr_init2 (z0, 2); + mpfr_set_ui (z0, 0, MPFR_RNDN); + + mpfr_init2 (z, 32); + + for (i = 0; i <= 12; i++) + { + unsigned int flags = 0; + char sy[16]; + + /* Test 2^(emin - i/4). + * --> Underflow iff i > 4. + * --> Zero in MPFR_RNDN iff i >= 8. + */ + + if (i != 0 && i != 4) + flags |= MPFR_FLAGS_INEXACT; + if (i > 4) + flags |= MPFR_FLAGS_UNDERFLOW; + + sprintf (sy, "emin - %d/4", i); + + RND_LOOP (rnd) + { + int zero; + + zero = (i > 4 && (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)) || + (i >= 8 && rnd == MPFR_RNDN); + + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); + cmpres (1, "2", sy, (mpfr_rnd_t) rnd, zero ? z0 : (mpfr_ptr) NULL, + -1, z, inex, flags, "underflow_up1", "mpfr_pow"); + test_others ("2", sy, (mpfr_rnd_t) rnd, x, y, z, inex, flags, + "underflow_up1"); + } + + inex = mpfr_sub (y, y, delta, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + } + + mpfr_clears (delta, x, y, z, z0, (mpfr_ptr) 0); +} + +/* With pow.c r5497, the following test fails on a 64-bit Linux machine + * due to a double-rounding problem when rescaling the result: + * Error with underflow_up2 and extended exponent range + * x = 7.fffffffffffffff0@-1, + * y = 4611686018427387904, MPFR_RNDN + * Expected 1.0000000000000000@-1152921504606846976, inex = 1, flags = 9 + * Got 0, inex = -1, flags = 9 + * With pow_ui.c r5423, the following test fails on a 64-bit Linux machine + * as underflows and overflows are not handled correctly (the approximation + * error is ignored): + * Error with mpfr_pow_ui, flags cleared + * x = 7.fffffffffffffff0@-1, + * y = 4611686018427387904, MPFR_RNDN + * Expected 1.0000000000000000@-1152921504606846976, inex = 1, flags = 9 + * Got 0, inex = -1, flags = 9 + */ +static void +underflow_up2 (void) +{ + mpfr_t x, y, z, z0, eps; + mpfr_exp_t n; + int inex; + int rnd; + + n = 1 - mpfr_get_emin (); + MPFR_ASSERTN (n > 1); + if (n > ULONG_MAX) + return; + + mpfr_init2 (eps, 2); + mpfr_set_ui_2exp (eps, 1, -1, MPFR_RNDN); /* 1/2 */ + mpfr_div_ui (eps, eps, n, MPFR_RNDZ); /* 1/(2n) rounded toward zero */ + + mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 1); + inex = mpfr_ui_sub (x, 1, eps, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); /* since n < 2^(size_of_long_in_bits) */ + inex = mpfr_div_2ui (x, x, 1, MPFR_RNDN); /* 1/2 - eps/2 exactly */ + MPFR_ASSERTN (inex == 0); + + mpfr_init2 (y, sizeof (unsigned long) * CHAR_BIT); + inex = mpfr_set_ui (y, n, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + + /* 0 < eps < 1 / (2n), thus (1 - eps)^n > 1/2, + and 1/2 (1/2)^n < (1/2 - eps/2)^n < (1/2)^n. */ + mpfr_inits2 (64, z, z0, (mpfr_ptr) 0); + RND_LOOP (rnd) + { + unsigned int ufinex = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; + int expected_inex; + char sy[256]; + + mpfr_set_ui (z0, 0, MPFR_RNDN); + expected_inex = rnd == MPFR_RNDN || rnd == MPFR_RNDU || rnd == MPFR_RNDA ? + (mpfr_nextabove (z0), 1) : -1; + sprintf (sy, "%lu", (unsigned long) n); + + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); + cmpres (0, x, sy, (mpfr_rnd_t) rnd, z0, expected_inex, z, inex, ufinex, + "underflow_up2", "mpfr_pow"); + test_others (NULL, sy, (mpfr_rnd_t) rnd, x, y, z, inex, ufinex, + "underflow_up2"); + } + + mpfr_clears (x, y, z, z0, eps, (mpfr_ptr) 0); +} + +static void +underflow_up3 (void) +{ + mpfr_t x, y, z, z0; + int inex; + int rnd; + int i; + + mpfr_init2 (x, 64); + mpfr_init2 (y, sizeof (mpfr_exp_t) * CHAR_BIT); + mpfr_init2 (z, 32); + mpfr_init2 (z0, 2); + + inex = mpfr_set_exp_t (y, mpfr_get_emin () - 2, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + unsigned int ufinex = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; + int expected_inex; + + mpfr_set_ui (x, 2, MPFR_RNDN); + if (i < 0) + mpfr_nextbelow (x); + if (i > 0) + mpfr_nextabove (x); + /* x = 2 + i * eps, y = emin - 2, x^y ~= 2^(emin - 2) */ + + expected_inex = rnd == MPFR_RNDU || rnd == MPFR_RNDA + || (rnd == MPFR_RNDN && i < 0) ? 1 : -1; + + mpfr_set_ui (z0, 0, MPFR_RNDN); + if (expected_inex > 0) + mpfr_nextabove (z0); + + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); + cmpres (0, x, "emin - 2", (mpfr_rnd_t) rnd, z0, expected_inex, z, inex, + ufinex, "underflow_up3", "mpfr_pow"); + test_others (NULL, "emin - 2", (mpfr_rnd_t) rnd, x, y, z, inex, ufinex, + "underflow_up3"); + } + + mpfr_clears (x, y, z, z0, (mpfr_ptr) 0); +} + +static void +underflow_up (void) +{ + underflow_up1 (); + underflow_up2 (); + underflow_up3 (); +} + +static void +overflow_inv (void) +{ + mpfr_t x, y, z; + int precx; + int s, t; + int inex; + int rnd; + + mpfr_init2 (y, 2); + mpfr_init2 (z, 8); + + mpfr_set_si (y, -1, MPFR_RNDN); + for (precx = 10; precx <= 100; precx += 90) + { + const char *sp = precx == 10 ? + "overflow_inv (precx = 10)" : "overflow_inv (precx = 100)"; + + mpfr_init2 (x, precx); + for (s = -1; s <= 1; s += 2) + { + inex = mpfr_set_si_2exp (x, s, - mpfr_get_emax (), MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + for (t = 0; t <= 5; t++) + { + /* If precx = 10: + * x = s * 2^(-emax) * (1 + t * 2^(-9)), so that + * 1/x = s * 2^emax * (1 - t * 2^(-9) + eps) with eps > 0. + * Values of (1/x) / 2^emax and overflow condition for x > 0: + * t = 0: 1 o: always + * t = 1: 0.11111111 100000000011... o: MPFR_RNDN and MPFR_RNDU + * t = 2: 0.11111111 000000001111... o: MPFR_RNDU + * t = 3: 0.11111110 100000100011... o: never + * + * If precx = 100: + * t = 0: always overflow + * t > 0: overflow for MPFR_RNDN and MPFR_RNDU. + */ + RND_LOOP (rnd) + { + int inf, overflow; + mpfr_rnd_t rnd2; + + if (rnd == MPFR_RNDA) + rnd2 = s < 0 ? MPFR_RNDD : MPFR_RNDU; + else + rnd2 = (mpfr_rnd_t) rnd; + + overflow = t == 0 || + ((mpfr_rnd_t) rnd == MPFR_RNDN && + (precx > 10 || t == 1)) || + (rnd2 == (s < 0 ? MPFR_RNDD : MPFR_RNDU) && + (precx > 10 || t <= 2)); + inf = overflow && + ((mpfr_rnd_t) rnd == MPFR_RNDN || + rnd2 == (s < 0 ? MPFR_RNDD : MPFR_RNDU)); + mpfr_clear_flags (); + inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); + if (overflow ^ !! mpfr_overflow_p ()) + { + printf ("Bad overflow flag in %s\nfor mpfr_pow%s\n" + "s = %d, t = %d, %s\n", sp, + ext ? ", extended exponent range" : "", + s, t, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + exit (1); + } + if (overflow && (inf ^ !! MPFR_IS_INF (z))) + { + printf ("Bad value in %s\nfor mpfr_pow%s\n" + "s = %d, t = %d, %s\nGot ", sp, + ext ? ", extended exponent range" : "", + s, t, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + printf (" instead of %s value.\n", + inf ? "infinite" : "finite"); + exit (1); + } + test_others (NULL, "-1", (mpfr_rnd_t) rnd, x, y, z, + inex, __gmpfr_flags, sp); + } /* RND_LOOP */ + mpfr_nexttoinf (x); + } /* for (t = ...) */ + } /* for (s = ...) */ + mpfr_clear (x); + } /* for (precx = ...) */ + + mpfr_clears (y, z, (mpfr_ptr) 0); +} + +static void +alltst (void) +{ + mpfr_exp_t emin, emax; + + ext = 0; + tst (); + underflow_up (); + overflow_inv (); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + if (mpfr_get_emin () != emin || mpfr_get_emax () != emax) + { + ext = 1; + tst (); + underflow_up (); + overflow_inv (); + set_emin (emin); + set_emax (emax); + } +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + all_cmpres_errors = argc > 1; + alltst (); + tests_end_mpfr (); + return all_cmpres_errors < 0; +} diff --git a/mpfr/tests/tpow_z.c b/mpfr/tests/tpow_z.c new file mode 100644 index 0000000000..0acb9c0ca5 --- /dev/null +++ b/mpfr/tests/tpow_z.c @@ -0,0 +1,379 @@ +/* Test file for mpfr_pow_z -- power function x^z with z a MPZ + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <float.h> +#include <math.h> + +#include "mpfr-test.h" + +#define ERROR(str) do { printf("Error for "str"\n"); exit (1); } while (0) + +static void +check_special (void) +{ + mpfr_t x, y; + mpz_t z; + int res; + + mpfr_init (x); + mpfr_init (y); + mpz_init (z); + + /* x^0 = 1 except for NAN */ + mpfr_set_ui (x, 23, MPFR_RNDN); + mpz_set_ui (z, 0); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (y, 1) != 0) + ERROR ("23^0"); + mpfr_set_nan (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_nan_p (y) || mpfr_cmp_si (y, 1) != 0) + ERROR ("NAN^0"); + mpfr_set_inf (x, 1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (y, 1) != 0) + ERROR ("INF^0"); + + /* sINF^N = INF if s==1 or n even if N > 0*/ + mpz_set_ui (z, 42); + mpfr_set_inf (x, 1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) + ERROR ("INF^42"); + mpfr_set_inf (x, -1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) + ERROR ("-INF^42"); + mpz_set_ui (z, 17); + mpfr_set_inf (x, 1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) + ERROR ("INF^17"); + mpfr_set_inf (x, -1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) >= 0) + ERROR ("-INF^17"); + + mpz_set_si (z, -42); + mpfr_set_inf (x, 1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("INF^-42"); + mpfr_set_inf (x, -1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("-INF^-42"); + mpz_set_si (z, -17); + mpfr_set_inf (x, 1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("INF^-17"); + mpfr_set_inf (x, -1); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) >= 0) + ERROR ("-INF^-17"); + + /* s0^N = +0 if s==+ or n even if N > 0*/ + mpz_set_ui (z, 42); + MPFR_SET_ZERO (x); MPFR_SET_POS (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("+0^42"); + MPFR_SET_NEG (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("-0^42"); + mpz_set_ui (z, 17); + MPFR_SET_POS (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("+0^17"); + MPFR_SET_NEG (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) >= 0) + ERROR ("-0^17"); + + mpz_set_si (z, -42); + MPFR_SET_ZERO (x); MPFR_SET_POS (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("+0^-42"); + MPFR_SET_NEG (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("-0^-42"); + mpz_set_si (z, -17); + MPFR_SET_POS (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0) + ERROR ("+0^-17"); + MPFR_SET_NEG (x); + res = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) >= 0) + ERROR ("-0^-17"); + + mpz_clear (z); + mpfr_clear (y); + mpfr_clear (x); +} + +static void +check_integer (mpfr_prec_t begin, mpfr_prec_t end, unsigned long max) +{ + mpfr_t x, y1, y2; + mpz_t z; + unsigned long i, n; + mpfr_prec_t p; + int res1, res2; + mpfr_rnd_t rnd; + + mpfr_inits2 (begin, x, y1, y2, (mpfr_ptr) 0); + mpz_init (z); + for (p = begin ; p < end ; p+=4) + { + mpfr_set_prec (x, p); + mpfr_set_prec (y1, p); + mpfr_set_prec (y2, p); + for (i = 0 ; i < max ; i++) + { + mpz_urandomb (z, RANDS, GMP_NUMB_BITS); + if ((i & 1) != 0) + mpz_neg (z, z); + mpfr_urandomb (x, RANDS); + mpfr_mul_2ui (x, x, 1, MPFR_RNDN); /* 0 <= x < 2 */ + rnd = RND_RAND (); + if (mpz_fits_slong_p (z)) + { + n = mpz_get_si (z); + /* printf ("New test for x=%ld\nCheck Pow_si\n", n); */ + res1 = mpfr_pow_si (y1, x, n, rnd); + /* printf ("Check pow_z\n"); */ + res2 = mpfr_pow_z (y2, x, z, rnd); + if (mpfr_cmp (y1, y2) != 0) + { + printf ("Error for p = %lu, z = %lu, rnd = %s and x = ", + (unsigned long) p, n, mpfr_print_rnd_mode (rnd)); + mpfr_dump (x); + printf ("Ypowsi = "); mpfr_dump (y1); + printf ("Ypowz = "); mpfr_dump (y2); + exit (1); + } + if (res1 != res2) + { + printf ("Wrong inexact flags for p = %lu, z = %lu, rnd = %s" + " and x = ", (unsigned long) p, n, + mpfr_print_rnd_mode (rnd)); + mpfr_dump (x); + printf ("Ypowsi(inex = %2d) = ", res1); mpfr_dump (y1); + printf ("Ypowz (inex = %2d) = ", res2); mpfr_dump (y2); + exit (1); + } + } + } /* for i */ + } /* for p */ + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); + mpz_clear (z); +} + +static void +check_regression (void) +{ + mpfr_t x, y; + mpz_t z; + int res1, res2; + + mpz_init_set_ui (z, 2026876995); + mpfr_init2 (x, 122); + mpfr_init2 (y, 122); + + mpfr_set_str_binary (x, "0.10000010010000111101001110100101101010011110011100001111000001001101000110011001001001001011001011010110110110101000111011E1"); + res1 = mpfr_pow_z (y, x, z, MPFR_RNDU); + res2 = mpfr_pow_ui (x, x, 2026876995UL, MPFR_RNDU); + if (mpfr_cmp (x, y) || res1 != res2) + { + printf ("Regression (1) tested failed (%d=?%d)\n",res1, res2); + printf ("pow_ui: "); mpfr_dump (x); + printf ("pow_z: "); mpfr_dump (y); + + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpz_clear (z); +} + +/* Bug found by Kevin P. Rauch */ +static void +bug20071104 (void) +{ + mpfr_t x, y; + mpz_t z; + int inex; + + mpz_init_set_si (z, -2); + mpfr_inits2 (20, x, y, (mpfr_ptr) 0); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_nextbelow (x); /* x = -2^(emin-1) */ + mpfr_clear_flags (); + inex = mpfr_pow_z (y, x, z, MPFR_RNDN); + if (! mpfr_inf_p (y) || MPFR_SIGN (y) < 0) + { + printf ("Error in bug20071104: expected +Inf, got "); + mpfr_dump (y); + exit (1); + } + if (inex <= 0) + { + printf ("Error in bug20071104: bad ternary value (%d)\n", inex); + exit (1); + } + if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT)) + { + printf ("Error in bug20071104: bad flags (%u)\n", __gmpfr_flags); + exit (1); + } + mpfr_clears (x, y, (mpfr_ptr) 0); + mpz_clear (z); +} + +static void +check_overflow (void) +{ + mpfr_t a; + mpz_t z; + unsigned long n; + int res; + + mpfr_init2 (a, 53); + + mpfr_set_str_binary (a, "1E10"); + mpz_init_set_ui (z, ULONG_MAX); + res = mpfr_pow_z (a, a, z, MPFR_RNDN); + if (! MPFR_IS_INF (a) || MPFR_SIGN (a) < 0 || res <= 0) + { + printf ("Error for (1e10)^ULONG_MAX, expected +Inf,\ngot "); + mpfr_dump (a); + exit (1); + } + + /* Bug in pow_z.c up to r5109: if x = y (same mpfr_t argument), the + input argument is negative and not a power of two, z is positive + and odd, an overflow or underflow occurs, and the temporary result + res is positive, then the result gets a wrong sign (positive + instead of negative). */ + mpfr_set_str_binary (a, "-1.1E10"); + n = (ULONG_MAX ^ (ULONG_MAX >> 1)) + 1; + mpz_set_ui (z, n); + res = mpfr_pow_z (a, a, z, MPFR_RNDN); + if (! MPFR_IS_INF (a) || MPFR_SIGN (a) > 0 || res >= 0) + { + printf ("Error for (-1e10)^%lu, expected -Inf,\ngot ", n); + mpfr_dump (a); + exit (1); + } + + mpfr_clear (a); + mpz_clear (z); +} + +/* bug reported by Carl Witty (32-bit architecture) */ +static void +bug20080223 (void) +{ + mpfr_t a, exp, answer; + + mpfr_init2 (a, 53); + mpfr_init2 (exp, 53); + mpfr_init2 (answer, 53); + + mpfr_set_si (exp, -1073741824, MPFR_RNDN); + + mpfr_set_str (a, "1.999999999", 10, MPFR_RNDN); + /* a = 562949953139837/2^48 */ + mpfr_pow (answer, a, exp, MPFR_RNDN); + mpfr_set_str_binary (a, "0.110110101111011001110000111111100011101000111011101E-1073741823"); + MPFR_ASSERTN(mpfr_cmp0 (answer, a) == 0); + + mpfr_clear (a); + mpfr_clear (exp); + mpfr_clear (answer); +} + +static void +bug20080904 (void) +{ + mpz_t exp; + mpfr_t a, answer; + mpfr_exp_t emin_default; + + mpz_init (exp); + mpfr_init2 (a, 70); + mpfr_init2 (answer, 70); + + emin_default = mpfr_get_emin (); + mpfr_set_emin (MPFR_EMIN_MIN); + + mpz_set_str (exp, "-4eb92f8c7b7bf81e", 16); + mpfr_set_str_binary (a, "1.110000101110100110100011111000011110111101000011111001111001010011100"); + + mpfr_pow_z (answer, a, exp, MPFR_RNDN); + /* The correct result is near 2^(-2^62), so it underflows when + MPFR_EMIN_MIN > -2^62 (i.e. with 32 and 64 bits machines). */ + mpfr_set_str (a, "AA500C0D7A69275DBp-4632850503556296886", 16, MPFR_RNDN); + if (! mpfr_equal_p (answer, a)) + { + printf ("Error in bug20080904:\n"); + printf ("Expected "); + mpfr_out_str (stdout, 16, 0, a, MPFR_RNDN); + putchar ('\n'); + printf ("Got "); + mpfr_out_str (stdout, 16, 0, answer, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + + mpfr_set_emin (emin_default); + + mpz_clear (exp); + mpfr_clear (a); + mpfr_clear (answer); +} + +int +main (void) +{ + tests_start_mpfr (); + + check_special (); + + check_integer (2, 163, 100); + check_regression (); + bug20071104 (); + bug20080223 (); + bug20080904 (); + check_overflow (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tprintf.c b/mpfr/tests/tprintf.c new file mode 100644 index 0000000000..1c4961bf4e --- /dev/null +++ b/mpfr/tests/tprintf.c @@ -0,0 +1,505 @@ +/* tprintf.c -- test file for mpfr_printf and mpfr_vprintf + +Copyright 2008-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if HAVE_STDARG +#include <stdarg.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> + +#include "mpfr-intmax.h" +#include "mpfr-test.h" +#define STDOUT_FILENO 1 + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +#define QUOTE(X) NAME(X) +#define NAME(X) #X + +/* unlike other tests, we print out errors to stderr because stdout might be + redirected */ +#define check_length(num_test, var, value, var_spec) \ + if ((var) != (value)) \ + { \ + fprintf (stderr, "Error in test #%d: mpfr_printf printed %" \ + QUOTE(var_spec)" characters instead of %d\n", \ + (num_test), (var), (value)); \ + exit (1); \ + } + +#define check_length_with_cmp(num_test, var, value, cmp, var_spec) \ + if (cmp != 0) \ + { \ + mpfr_fprintf (stderr, "Error in test #%d, mpfr_printf printed %" \ + QUOTE(var_spec)" characters instead of %d\n", \ + (num_test), (var), (value)); \ + exit (1); \ + } + +/* limit for random precision in random() */ +const int prec_max_printf = 5000; +/* boolean: is stdout redirected to a file ? */ +int stdout_redirect; + +static void +check (const char *fmt, mpfr_t x) +{ + if (mpfr_printf (fmt, x) == -1) + { + fprintf (stderr, "Error in mpfr_printf(\"%s\", ...)\n", fmt); + + exit (1); + } + putchar ('\n'); +} + +static void +check_vprintf (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + if (mpfr_vprintf (fmt, ap) == -1) + { + fprintf (stderr, "Error in mpfr_vprintf(\"%s\", ...)\n", fmt); + + va_end (ap); + exit (1); + } + putchar ('\n'); + va_end (ap); +} + +static void +check_vprintf_failure (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + if (mpfr_vprintf (fmt, ap) != -1) + { + putchar ('\n'); + fprintf (stderr, "Error in mpfr_vprintf(\"%s\", ...)\n", fmt); + + va_end (ap); + exit (1); + } + putchar ('\n'); + va_end (ap); +} + +static void +check_invalid_format (void) +{ + int i = 0; + + /* format in disorder */ + check_vprintf_failure ("blah %l2.1d blah", i); + check_vprintf_failure ("blah %2.1#d blah", i); + + /* incomplete format */ + check_vprintf_failure ("%", i); + check_vprintf_failure ("% (missing conversion specifier)", i); + check_vprintf_failure ("missing conversion specifier %h", i); + check_vprintf_failure ("this should fail %.l because of missing conversion specifier " + "(or doubling %%)", i); + check_vprintf_failure ("%L", i); + check_vprintf_failure ("%hh. ", i); + check_vprintf_failure ("blah %j."); + check_vprintf_failure ("%ll blah"); + check_vprintf_failure ("blah%t blah"); + check_vprintf_failure ("%z "); + check_vprintf_failure ("%F (missing conversion specifier)"); + check_vprintf_failure ("%Q (missing conversion specifier)"); + check_vprintf_failure ("%M (missing conversion specifier)"); + check_vprintf_failure ("%N (missing conversion specifier)"); + check_vprintf_failure ("%Z (missing conversion specifier)"); + check_vprintf_failure ("%R (missing conversion specifier)"); + check_vprintf_failure ("%R"); + check_vprintf_failure ("%P (missing conversion specifier)"); + + /* conversion specifier with wrong length specifier */ + check_vprintf_failure ("%ha", i); + check_vprintf_failure ("%hhe", i); + check_vprintf_failure ("%jf", i); + check_vprintf_failure ("%lg", i); + check_vprintf_failure ("%tA", i); + check_vprintf_failure ("%zE", i); + check_vprintf_failure ("%Ld", i); + check_vprintf_failure ("%Qf", i); + check_vprintf_failure ("%MG", i); + check_vprintf_failure ("%Na", i); + check_vprintf_failure ("%ZE", i); + check_vprintf_failure ("%PG", i); + check_vprintf_failure ("%Fu", i); + check_vprintf_failure ("%Rx", i); +} + +static void +check_long_string (void) +{ + /* this test is VERY expensive both in time (~1 min on core2 @ 2.40GHz) and + in memory (~2.5 GB) */ + mpfr_t x; + + mpfr_init2 (x, INT_MAX); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextabove (x); + + check_vprintf_failure ("%Rb", x); + check_vprintf_failure ("%RA %RA %Ra %Ra", x, x, x, x); + + mpfr_clear (x); +} + +static void +check_special (void) +{ + mpfr_t x; + + mpfr_init (x); + + mpfr_set_inf (x, 1); + check ("%Ra", x); + check ("%Rb", x); + check ("%Re", x); + check ("%Rf", x); + check ("%Rg", x); + check_vprintf ("%Ra", x); + check_vprintf ("%Rb", x); + check_vprintf ("%Re", x); + check_vprintf ("%Rf", x); + check_vprintf ("%Rg", x); + + mpfr_set_inf (x, -1); + check ("%Ra", x); + check ("%Rb", x); + check ("%Re", x); + check ("%Rf", x); + check ("%Rg", x); + check_vprintf ("%Ra", x); + check_vprintf ("%Rb", x); + check_vprintf ("%Re", x); + check_vprintf ("%Rf", x); + check_vprintf ("%Rg", x); + + mpfr_set_nan (x); + check ("%Ra", x); + check ("%Rb", x); + check ("%Re", x); + check ("%Rf", x); + check ("%Rg", x); + check_vprintf ("%Ra", x); + check_vprintf ("%Rb", x); + check_vprintf ("%Re", x); + check_vprintf ("%Rf", x); + check_vprintf ("%Rg", x); + + mpfr_clear (x); +} + +static void +check_mixed (void) +{ + int ch = 'a'; +#ifndef NPRINTF_HH + signed char sch = -1; + unsigned char uch = 1; +#endif + short sh = -1; + unsigned short ush = 1; + int i = -1; + int j = 1; + unsigned int ui = 1; + long lo = -1; + unsigned long ulo = 1; + float f = -1.25; + double d = -1.25; +#if !defined(NPRINTF_T) || !defined(NPRINTF_L) + long double ld = -1.25; +#endif + +#ifndef NPRINTF_T + ptrdiff_t p = 1, saved_p; +#endif + size_t sz = 1; + + mpz_t mpz; + mpq_t mpq; + mpf_t mpf; + mpfr_rnd_t rnd = MPFR_RNDN; + + mpfr_t mpfr; + mpfr_prec_t prec; + + mpz_init (mpz); + mpz_set_ui (mpz, ulo); + mpq_init (mpq); + mpq_set_si (mpq, lo, ulo); + mpf_init (mpf); + mpf_set_q (mpf, mpq); + mpfr_init (mpfr); + mpfr_set_f (mpfr, mpf, MPFR_RNDN); + prec = mpfr_get_prec (mpfr); + + check_vprintf ("a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j); + check_length (1, j, 22, d); + check_vprintf ("a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i, lo, &ulo); + check_length (2, ulo, 36, lu); + check_vprintf ("a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush); + check_length (3, ush, 29, hu); + check_vprintf ("a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i); + check_length (4, i, 29, d); + check_vprintf ("a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, &sz); + check_length (5, (unsigned long) sz, 34, lu); /* no format specifier '%zu' in C89 */ + check_vprintf ("a. %Pu, b. %c, c. %RUG, d. %Zi%Zn", prec, ch, mpfr, mpz, &mpz); + check_length_with_cmp (6, mpz, 24, mpz_cmp_ui (mpz, 24), Zi); + check_vprintf ("%% a. %#.0RNg, b. %Qx%Rn c. %p", + mpfr, mpq, &mpfr, (void *) &i); + check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg); + +#ifndef NPRINTF_T + saved_p = p; + check_vprintf ("%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p); + if (p != 20) + mpfr_fprintf (stderr, "Error in test 8, got '%% a. %RNg, b. %Qx, c. %td'\n", mpfr, mpq, saved_p); + check_length (8, (long) p, 20, ld); /* no format specifier '%td' in C89 */ +#endif + +#ifndef NPRINTF_L + check_vprintf ("a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz); + check_length (9, (unsigned long) sz, 30, lu); /* no format specifier '%zu' in C89 */ +#endif + +#ifndef NPRINTF_HH + check_vprintf ("a. %hhi, b. %Ra, c. %hhu%hhn", sch, mpfr, uch, &uch); + check_length (10, (unsigned int) uch, 22, u); /* no format specifier '%hhu' in C89 */ +#endif + +#if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL) + { + long long llo = -1; + unsigned long long ullo = 1; + + check_vprintf ("a. %Re, b. %llx%Qn", mpfr, ullo, &mpq); + check_length_with_cmp (11, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu); + check_vprintf ("a. %lli, b. %Rf%lln", llo, mpfr, &ullo); + check_length (12, ullo, 19, llu); + } +#endif + +#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J) + { + intmax_t im = -1; + uintmax_t uim = 1; + + check_vprintf ("a. %*RA, b. %ji%Fn", 10, mpfr, im, &mpf); + check_length_with_cmp (31, mpf, 20, mpf_cmp_ui (mpf, 20), Fg); + check_vprintf ("a. %.*Re, b. %jx%jn", 10, mpfr, uim, &im); + check_length (32, (long) im, 25, li); /* no format specifier "%ji" in C89 */ + } +#endif + + mpfr_clear (mpfr); + mpf_clear (mpf); + mpq_clear (mpq); + mpz_clear (mpz); +} + +static void +check_random (int nb_tests) +{ + int i; + mpfr_t x; + mpfr_rnd_t rnd; + char flag[] = + { + '-', + '+', + ' ', + '#', + '0', /* no ambiguity: first zeros are flag zero*/ + '\'' + }; + char specifier[] = + { + 'a', + 'b', + 'e', + 'f', + 'g' + }; + mpfr_exp_t old_emin, old_emax; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + mpfr_init (x); + + for (i = 0; i < nb_tests; ++i) + { + int ret; + int j, jmax; + int spec, prec; +#define FMT_SIZE 13 + char fmt[FMT_SIZE]; /* at most something like "%-+ #0'.*R*f" */ + char *ptr = fmt; + + tests_default_random (x, 256, MPFR_EMIN_MIN, MPFR_EMAX_MAX, 0); + rnd = (mpfr_rnd_t) RND_RAND (); + + spec = (int) (randlimb () % 5); + jmax = (spec == 3 || spec == 4) ? 6 : 5; /* ' flag only with %f or %g */ + /* advantage small precision */ + prec = (randlimb () % 2) ? 10 : prec_max_printf; + prec = (int) (randlimb () % prec); + if (spec == 3 + && (mpfr_get_exp (x) > prec_max_printf + || mpfr_get_exp (x) < -prec_max_printf)) + /* change style 'f' to style 'e' when number x is very large or very + small*/ + --spec; + + *ptr++ = '%'; + for (j = 0; j < jmax; j++) + { + if (randlimb () % 3 == 0) + *ptr++ = flag[j]; + } + *ptr++ = '.'; + *ptr++ = '*'; + *ptr++ = 'R'; + *ptr++ = '*'; + *ptr++ = specifier[spec]; + *ptr = '\0'; + MPFR_ASSERTD (ptr - fmt < FMT_SIZE); + + mpfr_printf ("mpfr_printf(\"%s\", %d, %s, %Re)\n", fmt, prec, + mpfr_print_rnd_mode (rnd), x); + ret = mpfr_printf (fmt, prec, rnd, x); + if (ret == -1) + { + if (spec == 3 + && (MPFR_GET_EXP (x) > INT_MAX || MPFR_GET_EXP (x) < -INT_MAX)) + /* normal failure: x is too large to be output with full precision */ + { + mpfr_printf ("too large !"); + } + else + { + printf ("Error in mpfr_printf(\"%s\", %d, %s, ...)", + fmt, prec, mpfr_print_rnd_mode (rnd)); + + if (stdout_redirect) + { + if ((fflush (stdout) == EOF) || (fclose (stdout) == -1)) + { + perror ("check_random"); + exit (1); + } + } + exit (1); + } + } + putchar ('\n'); + } + + mpfr_set_emin (old_emin); + mpfr_set_emax (old_emax); + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + int N; + + tests_start_mpfr (); + + /* with no argument: prints to /dev/null, + tprintf N: prints N tests to stdout */ + if (argc == 1) + { + N = 1000; + stdout_redirect = 1; + if (freopen ("/dev/null", "w", stdout) == NULL) + { + /* We failed to open this device, try with a dummy file */ + if (freopen ("mpfrtest.txt", "w", stdout) == NULL) + { + /* Output the error message to stderr since it is not + a message about a wrong result in MPFR. Anyway the + stdandard output may have changed. */ + fprintf (stderr, "Can't open /dev/null or a temporary file\n"); + exit (1); + } + } + } + else + { + stdout_redirect = 0; + N = atoi (argv[1]); + } + + check_invalid_format (); + check_special (); + check_mixed (); + + /* expensive tests */ + if (getenv ("MPFR_CHECK_LARGEMEM") != NULL) + check_long_string(); + + check_random (N); + + if (stdout_redirect) + { + if ((fflush (stdout) == EOF) || (fclose (stdout) == -1)) + perror ("main"); + } + tests_end_mpfr (); + return 0; +} + +#else /* MPFR_VERSION */ + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif /* MPFR_VERSION */ + +#else /* HAVE_STDARG */ + +int +main (void) +{ + /* We have nothing to test. */ + return 77; +} + +#endif /* HAVE_STDARG */ diff --git a/mpfr/tests/trandom.c b/mpfr/tests/trandom.c new file mode 100644 index 0000000000..8c66785a78 --- /dev/null +++ b/mpfr/tests/trandom.c @@ -0,0 +1,217 @@ +/* Test file for mpfr_urandomb + +Copyright 1999-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +test_urandomb (long nbtests, mpfr_prec_t prec, int verbose) +{ + mpfr_t x; + int *tab, size_tab, k, sh, xn; + double d, av = 0, var = 0, chi2 = 0, th; + mpfr_exp_t emin; + + size_tab = (nbtests >= 1000 ? nbtests / 50 : 20); + tab = (int *) calloc (size_tab, sizeof(int)); + if (tab == NULL) + { + fprintf (stderr, "trandom: can't allocate memory in test_urandomb\n"); + exit (1); + } + + mpfr_init2 (x, prec); + xn = 1 + (prec - 1) / mp_bits_per_limb; + sh = xn * mp_bits_per_limb - prec; + + for (k = 0; k < nbtests; k++) + { + mpfr_urandomb (x, RANDS); + /* check that lower bits are zero */ + if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh)) + { + printf ("Error: mpfr_urandomb() returns invalid numbers:\n"); + mpfr_print_binary (x); puts (""); + exit (1); + } + d = mpfr_get_d1 (x); av += d; var += d*d; + tab[(int)(size_tab * d)]++; + } + + /* coverage test */ + emin = mpfr_get_emin (); + set_emin (1); /* the generated number in [0,1[ is not in the exponent + range, except if it is zero */ + k = mpfr_urandomb (x, RANDS); + if (MPFR_IS_ZERO(x) == 0 && (k == 0 || mpfr_nan_p (x) == 0)) + { + printf ("Error in mpfr_urandomb, expected NaN, got "); + mpfr_dump (x); + exit (1); + } + set_emin (emin); + + mpfr_clear (x); + if (!verbose) + { + free(tab); + return; + } + + av /= nbtests; + var = (var / nbtests) - av * av; + + th = (double)nbtests / size_tab; + printf("Average = %.5f\nVariance = %.5f\n", av, var); + printf("Repartition for urandomb. Each integer should be close to %d.\n", + (int)th); + + for (k = 0; k < size_tab; k++) + { + chi2 += (tab[k] - th) * (tab[k] - th) / th; + printf("%d ", tab[k]); + if (((k+1) & 7) == 0) + printf("\n"); + } + + printf("\nChi2 statistics value (with %d degrees of freedom) : %.5f\n\n", + size_tab - 1, chi2); + + free(tab); + return; +} + +/* Problem reported by Carl Witty: check mpfr_urandomb give similar results + on 32-bit and 64-bit machines. + We assume the default GMP random generator does not depend on the machine + word size, not on the GMP version. +*/ +static void +bug20100914 (void) +{ + mpfr_t x; + gmp_randstate_t s; + +#if __MPFR_GMP(4,2,0) +# define C1 "0.895943" +# define C2 "0.848824" +#else +# define C1 "0.479652" +# define C2 "0.648529" +#endif + + gmp_randinit_default (s); + gmp_randseed_ui (s, 42); + mpfr_init2 (x, 17); + mpfr_urandomb (x, s); + if (mpfr_cmp_str1 (x, C1) != 0) + { + printf ("Error in bug20100914, expected " C1 ", got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_urandomb (x, s); + if (mpfr_cmp_str1 (x, C2) != 0) + { + printf ("Error in bug20100914, expected " C2 ", got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clear (x); + gmp_randclear (s); +} + +int +main (int argc, char *argv[]) +{ + long nbtests; + mpfr_prec_t prec; + int verbose = 0; + + tests_start_mpfr (); + + if (argc > 1) + verbose = 1; + + nbtests = 10000; + if (argc > 1) + { + long a = atol(argv[1]); + if (a != 0) + nbtests = a; + } + + if (argc <= 2) + prec = 1000; + else + prec = atol(argv[2]); + + test_urandomb (nbtests, prec, verbose); + + if (argc == 1) /* check also small precision */ + { + test_urandomb (nbtests, 2, 0); + } + + bug20100914 (); + +#if __MPFR_GMP(4,2,0) + /* Get a non-zero fixed-point number whose first 32 bits are 0 with the + default GMP PRNG. This corresponds to the case cnt == 0 && k != 0 in + src/urandomb.c with the 32-bit ABI. */ + { + gmp_randstate_t s; + mpfr_t x; + char *str = "0.1010111100000000000000000000000000000000E-32"; + int k; + + gmp_randinit_default (s); + gmp_randseed_ui (s, 4518); + mpfr_init2 (x, 40); + + for (k = 0; k < 575123; k++) + { + mpfr_urandomb (x, s); + MPFR_ASSERTN (MPFR_IS_FP (x)); + } + + if (mpfr_cmp_str (x, str, 2, MPFR_RNDN) != 0) + { + printf ("Error in test_urandomb:\n"); + printf ("Expected %s\n", str); + printf ("Got "); + mpfr_dump (x); + exit (1); + } + + mpfr_clear (x); + gmp_randclear (s); + } +#endif + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/trec_sqrt.c b/mpfr/tests/trec_sqrt.c new file mode 100644 index 0000000000..da49c40a19 --- /dev/null +++ b/mpfr/tests/trec_sqrt.c @@ -0,0 +1,210 @@ +/* Test file for mpfr_rec_sqrt. + +Copyright 2008-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +#define TEST_FUNCTION mpfr_rec_sqrt +#define TEST_RANDOM_POS 8 /* 8/512 = 1/64 of the tested numbers are negative */ +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init (x); + mpfr_init (y); + + /* rec_sqrt(NaN) = NaN */ + mpfr_set_nan (x); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0); + + /* rec_sqrt(+Inf) = +0 */ + mpfr_set_inf (x, 1); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_zero_p (x) && MPFR_IS_POS(x) && inex == 0); + + /* rec_sqrt(-Inf) = NaN */ + mpfr_set_inf (x, -1); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0); + + /* rec_sqrt(+0) = +Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x) && inex == 0); + + /* rec_sqrt(-0) = +Inf */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x) && inex == 0); + + /* rec_sqrt(-1) = NaN */ + mpfr_set_si (x, -1, MPFR_RNDN); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0); + + /* rec_sqrt(1) = 1 */ + mpfr_set_ui (x, 1, MPFR_RNDN); + inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); + MPFR_ASSERTN((mpfr_cmp_ui (x, 1) == 0) && (inex == 0)); + + mpfr_set_prec (x, 23); + mpfr_set_prec (y, 33); + mpfr_set_str_binary (x, "1.0001110110101001010100e-1"); + inex = mpfr_rec_sqrt (y, x, MPFR_RNDU); + mpfr_set_prec (x, 33); + mpfr_set_str_binary (x, "1.01010110101110100100100101011"); + MPFR_ASSERTN (inex > 0 && mpfr_cmp (x, y) == 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +/* Worst case incorrectly rounded in r5573, found with the bad_cases test */ +static void +bad_case1 (void) +{ + mpfr_t x, y, z; + + mpfr_init2 (x, 72); + mpfr_inits2 (6, y, z, (mpfr_ptr) 0); + mpfr_set_str (x, "1.08310518720928b30e@-120", 16, MPFR_RNDN); + mpfr_set_str (z, "f.8@59", 16, MPFR_RNDN); + /* z = rec_sqrt(x) rounded on 6 bits toward 0, the exact value + being ~= f.bffffffffffffffffa11@59. */ + mpfr_rec_sqrt (y, x, MPFR_RNDZ); + if (mpfr_cmp0 (y, z) != 0) + { + printf ("Error in bad_case1\nexpected "); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static int +pm2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) +{ + return mpfr_pow_si (y, x, -2, rnd_mode); +} + +/* exercises corner cases with inputs around 1 or 2 */ +static void +bad_case2 (void) +{ + mpfr_t r, u; + mpfr_prec_t pr, pu; + int rnd; + + for (pr = MPFR_PREC_MIN; pr <= 192; pr++) + for (pu = MPFR_PREC_MIN; pu <= 192; pu++) + { + mpfr_init2 (r, pr); + mpfr_init2 (u, pu); + + mpfr_set_ui (u, 1, MPFR_RNDN); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_nextbelow (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_nextbelow (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_set_ui (u, 1, MPFR_RNDN); + mpfr_nextabove (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_nextabove (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_set_ui (u, 2, MPFR_RNDN); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_nextbelow (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_nextbelow (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_set_ui (u, 2, MPFR_RNDN); + mpfr_nextabove (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_nextabove (u); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); + + mpfr_clear (r); + mpfr_clear (u); + } +} + +int +main (void) +{ + tests_start_mpfr (); + + special (); + bad_case1 (); + bad_case2 (); + test_generic (2, 300, 15); + + data_check ("data/rec_sqrt", mpfr_rec_sqrt, "mpfr_rec_sqrt"); + bad_cases (mpfr_rec_sqrt, pm2, "mpfr_rec_sqrt", 8, -256, 255, 4, 128, + 800, 50); + + tests_end_mpfr (); + return 0; +} + +#else /* MPFR_VERSION */ + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif /* MPFR_VERSION */ diff --git a/mpfr/tests/tremquo.c b/mpfr/tests/tremquo.c new file mode 100644 index 0000000000..73f3debc60 --- /dev/null +++ b/mpfr/tests/tremquo.c @@ -0,0 +1,301 @@ +/* tremquo -- test file for mpfr_remquo and mpfr_remainder + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +bug20090227 (void) +{ + mpfr_t x, y, r1, r2; + + mpfr_init2 (x, 118); + mpfr_init2 (y, 181); + mpfr_init2 (r1, 140); + mpfr_init2 (r2, 140); + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_set_str_binary (y, "1.100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001000100010100110011111010"); + mpfr_remainder (r1, x, y, MPFR_RNDU); + /* since the quotient is -1, r1 is the rounding of x+y */ + mpfr_add (r2, x, y, MPFR_RNDU); + if (mpfr_cmp (r1, r2)) + { + printf ("Error in mpfr_remainder (bug20090227)\n"); + printf ("Expected "); + mpfr_dump (r2); + printf ("Got "); + mpfr_dump (r1); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (r1); + mpfr_clear (r2); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, r; + long q[1]; + int inex; + + if (argc == 3) /* usage: tremquo x y (rnd=MPFR_RNDN implicit) */ + { + mpfr_init2 (x, GMP_NUMB_BITS); + mpfr_init2 (y, GMP_NUMB_BITS); + mpfr_init2 (r, GMP_NUMB_BITS); + mpfr_set_str (x, argv[1], 10, MPFR_RNDN); + mpfr_set_str (y, argv[2], 10, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + printf ("r="); + mpfr_out_str (stdout, 10, 0, r, MPFR_RNDN); + printf (" q=%ld\n", q[0]); + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (r); + return 0; + } + + tests_start_mpfr (); + + bug20090227 (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (r); + + /* special values */ + mpfr_set_nan (x); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (r)); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_nan (y); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (r)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (r)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (r)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_set_inf (y, 1); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (r)); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_inf (y, 1); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r)); + MPFR_ASSERTN (q[0] == (long) 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_set_inf (y, 1); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r)); + MPFR_ASSERTN (q[0] == (long) 0); + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_set_inf (y, 1); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp (r, x) == 0); + MPFR_ASSERTN (q[0] == (long) 0); + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (r)); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_ui (y, 17, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r)); + MPFR_ASSERTN (q[0] == (long) 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set_ui (y, 17, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r)); + MPFR_ASSERTN (q[0] == (long) 0); + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + /* check four possible sign combinations */ + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_set_ui (y, 17, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0); + MPFR_ASSERTN (q[0] == (long) 2); + mpfr_set_si (x, -42, MPFR_RNDN); + mpfr_set_ui (y, 17, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0); + MPFR_ASSERTN (q[0] == (long) -2); + mpfr_set_si (x, -42, MPFR_RNDN); + mpfr_set_si (y, -17, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0); + MPFR_ASSERTN (q[0] == (long) 2); + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_set_si (y, -17, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0); + MPFR_ASSERTN (q[0] == (long) -2); + + mpfr_set_prec (x, 100); + mpfr_set_prec (y, 50); + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_nextabove (x); /* 42 + 2^(-94) */ + mpfr_set_ui (y, 21, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -94) == 0); + MPFR_ASSERTN (q[0] == (long) 2); + + mpfr_set_prec (x, 50); + mpfr_set_prec (y, 100); + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_nextabove (x); /* 42 + 2^(-44) */ + mpfr_set_ui (y, 21, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -44) == 0); + MPFR_ASSERTN (q[0] == (long) 2); + + mpfr_set_prec (x, 100); + mpfr_set_prec (y, 50); + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_set_ui (y, 21, MPFR_RNDN); + mpfr_nextabove (y); /* 21 + 2^(-45) */ + mpfr_remquo (r, q, x, y, MPFR_RNDN); + /* r should be 42 - 2*(21 + 2^(-45)) = -2^(-44) */ + MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -44) == 0); + MPFR_ASSERTN (q[0] == (long) 2); + + mpfr_set_prec (x, 50); + mpfr_set_prec (y, 100); + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_set_ui (y, 21, MPFR_RNDN); + mpfr_nextabove (y); /* 21 + 2^(-95) */ + mpfr_remquo (r, q, x, y, MPFR_RNDN); + /* r should be 42 - 2*(21 + 2^(-95)) = -2^(-94) */ + MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -94) == 0); + MPFR_ASSERTN (q[0] == (long) 2); + + /* exercise large quotient */ + mpfr_set_ui_2exp (x, 1, 65, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + /* quotient is 2^65 */ + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0); + MPFR_ASSERTN (q[0] % 1073741824L == 0L); + + /* another large quotient */ + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 65); + mpfr_const_pi (x, MPFR_RNDN); + mpfr_mul_2exp (x, x, 63, MPFR_RNDN); + mpfr_const_log2 (y, MPFR_RNDN); + mpfr_set_prec (r, 10); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + /* q should be 41803643793084085130, r should be 605/2048 */ + MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 605, -11) == 0); + MPFR_ASSERTN ((q[0] > 0) && ((q[0] % 1073741824L) == 733836170L)); + + /* check cases where quotient is 1.5 +/- eps */ + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 65); + mpfr_set_prec (r, 63); + mpfr_set_ui (x, 3, MPFR_RNDN); + mpfr_set_ui (y, 2, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + /* x/y = 1.5, quotient should be 2 (even rule), remainder should be -1 */ + MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0); + MPFR_ASSERTN (q[0] == 2L); + mpfr_set_ui (x, 3, MPFR_RNDN); + mpfr_nextabove (x); /* 3 + 2^(-63) */ + mpfr_set_ui (y, 2, MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + /* x/y = 1.5 + 2^(-64), quo should be 2, r should be -1 + 2^(-63) */ + MPFR_ASSERTN (mpfr_add_ui (r, r, 1, MPFR_RNDN) == 0); + MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -63) == 0); + MPFR_ASSERTN (q[0] == 2L); + mpfr_set_ui (x, 3, MPFR_RNDN); + mpfr_set_ui (y, 2, MPFR_RNDN); + mpfr_nextabove (y); /* 2 + 2^(-63) */ + mpfr_remquo (r, q, x, y, MPFR_RNDN); + /* x/y = 1.5 - eps, quo should be 1, r should be 1 - 2^(-63) */ + MPFR_ASSERTN (mpfr_sub_ui (r, r, 1, MPFR_RNDN) == 0); + MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -63) == 0); + MPFR_ASSERTN (q[0] == 1L); + + /* bug founds by Kaveh Ghazi, 3 May 2007 */ + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_set_ui (y, 3, MPFR_RNDN); + mpfr_remainder (r, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0); + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_remainder (r, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0 && MPFR_SIGN (r) < 0); + + /* check argument reuse */ + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_remainder (x, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si (x, 0) == 0 && MPFR_SIGN (x) < 0); + + mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN); + mpfr_remquo (r, q, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (r) && MPFR_SIGN (r) > 0); + MPFR_ASSERTN (q[0] == 0); + + mpfr_set_prec (x, 380); + mpfr_set_prec (y, 385); + mpfr_set_str_binary (x, "0.11011010010110011101011000100100101100101011010001011100110001100101111001010100001011111110111100101110101010110011010101000100000100011101101100001011101110100111101111111010001001000010000110010110011100111000001110111010000100101001010111100100010001101001110100011110010000000001110001111001101100111011001000110110011100100011111110010100011001000001001011010111010000000000E-2"); + mpfr_set_str_binary (y, "0.1100011000011101011010001100010111001110110111001101010010111100111100011010010011011101111101111001010111111110001001100001111101001000000010100101111001001110010110000111001000101010111001001000100101011111000010100110001111000110011011010101111101100110010101011010011101100001011101001000101111110110110110000001001101110111110110111110111111001001011110001110011111100000000000000E-1"); + mpfr_set_prec (r, 2); + inex = mpfr_remainder (r, x, y, MPFR_RNDA); + MPFR_ASSERTN(mpfr_cmp_si_2exp (r, -3, -4) == 0); + MPFR_ASSERTN(inex < 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (r); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/trint.c b/mpfr/tests/trint.c new file mode 100644 index 0000000000..aca47416d7 --- /dev/null +++ b/mpfr/tests/trint.c @@ -0,0 +1,630 @@ +/* Test file for mpfr_rint, mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round, + mpfr_rint_trunc, mpfr_rint_floor, mpfr_rint_ceil, mpfr_rint_round. + +Copyright 2002-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +#if __MPFR_STDC (199901L) +# include <math.h> +#endif + +static void +special (void) +{ + mpfr_t x, y; + mpfr_exp_t emax; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0); + + mpfr_set_inf (x, -1); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG(y)); + + /* coverage test */ + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_mul_2exp (x, x, mp_bits_per_limb, MPFR_RNDN); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + /* another coverage test */ + emax = mpfr_get_emax (); + set_emax (1); + mpfr_set_prec (x, 3); + mpfr_set_str_binary (x, "1.11E0"); + mpfr_set_prec (y, 2); + mpfr_rint (y, x, MPFR_RNDU); /* x rounds to 1.0E1=0.1E2 which overflows */ + MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0); + set_emax (emax); + + /* yet another */ + mpfr_set_prec (x, 97); + mpfr_set_prec (y, 96); + mpfr_set_str_binary (x, "-0.1011111001101111000111011100011100000110110110110000000111010001000101001111101010101011010111100E97"); + mpfr_rint (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "0.10101100000000101001010101111111000000011111010000010E-1"); + mpfr_rint (y, x, MPFR_RNDU); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); + mpfr_rint (y, x, MPFR_RNDD); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y)); + + mpfr_set_prec (x, 36); + mpfr_set_prec (y, 2); + mpfr_set_str_binary (x, "-11000110101010111111110111001.0000100"); + mpfr_rint (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-11E27"); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + mpfr_set_prec (x, 39); + mpfr_set_prec (y, 29); + mpfr_set_str_binary (x, "-0.100010110100011010001111001001001100111E39"); + mpfr_rint (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.10001011010001101000111100101E39"); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + mpfr_set_prec (x, 46); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "-0.1011100110100101000001011111101011001001101001E32"); + mpfr_rint (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.10111001101001010000010111111011E32"); + MPFR_ASSERTN(mpfr_cmp (y, x) == 0); + + /* coverage test for mpfr_round */ + mpfr_set_prec (x, 3); + mpfr_set_str_binary (x, "1.01E1"); /* 2.5 */ + mpfr_set_prec (y, 2); + mpfr_round (y, x); + /* since mpfr_round breaks ties away, should give 3 and not 2 as with + the "round to even" rule */ + MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0); + /* same test for the function */ + (mpfr_round) (y, x); + MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0); + + mpfr_set_prec (x, 6); + mpfr_set_prec (y, 3); + mpfr_set_str_binary (x, "110.111"); + mpfr_round (y, x); + if (mpfr_cmp_ui (y, 7)) + { + printf ("Error in round(110.111)\n"); + exit (1); + } + + /* Bug found by Mark J Watkins */ + mpfr_set_prec (x, 84); + mpfr_set_str_binary (x, + "0.110011010010001000000111101101001111111100101110010000000000000" \ + "000000000000000000000E32"); + mpfr_round (x, x); + if (mpfr_cmp_str (x, "0.1100110100100010000001111011010100000000000000" \ + "00000000000000000000000000000000000000E32", 2, MPFR_RNDN)) + { + printf ("Rounding error when dest=src\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +#define BASIC_TEST(F,J) \ + do \ + { \ + int red; \ + for (red = 0; red <= 1; red++) \ + { \ + int inex1, inex2; \ + unsigned int ex_flags, flags; \ + \ + if (red) \ + { \ + set_emin (e); \ + set_emax (e); \ + } \ + \ + mpfr_clear_flags (); \ + inex1 = mpfr_set_si (y, J, (mpfr_rnd_t) r); \ + ex_flags = __gmpfr_flags; \ + mpfr_clear_flags (); \ + inex2 = mpfr_rint_##F (z, x, (mpfr_rnd_t) r); \ + flags = __gmpfr_flags; \ + if (! (mpfr_equal_p (y, z) && \ + SAME_SIGN (inex1, inex2) && \ + flags == ex_flags)) \ + { \ + printf ("Basic test failed on mpfr_rint_" #F \ + ", prec = %d, i = %d, %s\n", prec, s * i, \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \ + printf ("i.e. x = "); \ + mpfr_dump (x); \ + if (red) \ + printf ("with emin = emax = %d\n", e); \ + printf ("Expected "); \ + mpfr_dump (y); \ + printf ("with inex = %d (or equivalent)\n", inex1); \ + printf (" flags:"); \ + flags_out (ex_flags); \ + printf ("Got "); \ + mpfr_dump (z); \ + printf ("with inex = %d (or equivalent)\n", inex2); \ + printf (" flags:"); \ + flags_out (flags); \ + exit (1); \ + } \ + } \ + set_emin (emin); \ + set_emax (emax); \ + } \ + while (0) + +#define BASIC_TEST2(F,J,INEX) \ + do \ + { \ + int red; \ + for (red = 0; red <= 1; red++) \ + { \ + int inex; \ + unsigned int ex_flags, flags; \ + \ + if (red) \ + { \ + set_emin (e); \ + set_emax (e); \ + } \ + \ + mpfr_clear_flags (); \ + inex = mpfr_set_si (y, J, MPFR_RNDN); \ + MPFR_ASSERTN (inex == 0 || mpfr_overflow_p ()); \ + ex_flags = __gmpfr_flags; \ + mpfr_clear_flags (); \ + inex = mpfr_##F (z, x); \ + if (inex != 0) \ + ex_flags |= MPFR_FLAGS_INEXACT; \ + flags = __gmpfr_flags; \ + if (! (mpfr_equal_p (y, z) && \ + inex == (INEX) && \ + flags == ex_flags)) \ + { \ + printf ("Basic test failed on mpfr_" #F \ + ", prec = %d, i = %d\n", prec, s * i); \ + printf ("i.e. x = "); \ + mpfr_dump (x); \ + if (red) \ + printf ("with emin = emax = %d\n", e); \ + printf ("Expected "); \ + mpfr_dump (y); \ + printf ("with inex = %d\n", (INEX)); \ + printf (" flags:"); \ + flags_out (ex_flags); \ + printf ("Got "); \ + mpfr_dump (z); \ + printf ("with inex = %d\n", inex); \ + printf (" flags:"); \ + flags_out (flags); \ + exit (1); \ + } \ + } \ + set_emin (emin); \ + set_emax (emax); \ + } \ + while (0) + +/* Test mpfr_rint_* on i/4 with |i| between 1 and 72. */ +static void +basic_tests (void) +{ + mpfr_t x, y, z; + int prec, s, i, r; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init2 (x, 16); + for (prec = 2; prec <= 7; prec++) + { + mpfr_inits2 (prec, y, z, (mpfr_ptr) 0); + for (s = 1; s >= -1; s -= 2) + for (i = 1; i <= 72; i++) + { + int k, t, u, v, f, e; + + for (t = i/4, k = 0; t >= 1 << prec; t >>= 1, k++) + ; + t <<= k; + for (u = (i+3)/4, k = 0; u >= 1 << prec; u = (u+1)/2, k++) + ; + u <<= k; + v = i < (t+u) << 1 ? t : u; + f = t == u ? 0 : i % 4 == 0 ? 1 : 2; + + mpfr_set_si_2exp (x, s * i, -2, MPFR_RNDN); + e = mpfr_get_exp (x); + RND_LOOP(r) + { + BASIC_TEST (trunc, s * (i/4)); + BASIC_TEST (floor, s > 0 ? i/4 : - ((i+3)/4)); + BASIC_TEST (ceil, s > 0 ? (i+3)/4 : - (i/4)); + BASIC_TEST (round, s * ((i+2)/4)); + } + BASIC_TEST2 (trunc, s * t, - s * f); + BASIC_TEST2 (floor, s > 0 ? t : - u, - f); + BASIC_TEST2 (ceil, s > 0 ? u : - t, f); + BASIC_TEST2 (round, s * v, v == t ? - s * f : s * f); + } + mpfr_clears (y, z, (mpfr_ptr) 0); + } + mpfr_clear (x); +} + +#if __MPFR_STDC (199901L) + +static void +test_fct (double (*f)(double), int (*g)(), char *s, mpfr_rnd_t r) +{ + double d, y; + mpfr_t dd, yy; + + mpfr_init2 (dd, 53); + mpfr_init2 (yy, 53); + for (d = -5.0; d <= 5.0; d += 0.25) + { + mpfr_set_d (dd, d, r); + y = (*f)(d); + if (g == &mpfr_rint) + mpfr_rint (yy, dd, r); + else + (*g)(yy, dd); + mpfr_set_d (dd, y, r); + if (mpfr_cmp (yy, dd)) + { + printf ("test_against_libc: incorrect result for %s, rnd = %s," + " d = %g\ngot ", s, mpfr_print_rnd_mode (r), d); + mpfr_out_str (stdout, 10, 0, yy, MPFR_RNDN); + printf (" instead of %g\n", y); + exit (1); + } + } + mpfr_clear (dd); + mpfr_clear (yy); +} + +#define TEST_FCT(F) test_fct (&F, &mpfr_##F, #F, r) + +static void +test_against_libc (void) +{ + mpfr_rnd_t r = MPFR_RNDN; + + (void) r; /* avoid a warning by using r */ +#if HAVE_ROUND + TEST_FCT (round); +#endif +#if HAVE_TRUNC + TEST_FCT (trunc); +#endif +#if HAVE_FLOOR + TEST_FCT (floor); +#endif +#if HAVE_CEIL + TEST_FCT (ceil); +#endif +#if HAVE_NEARBYINT + for (r = 0; r < MPFR_RND_MAX ; r++) + if (mpfr_set_machine_rnd_mode (r) == 0) + test_fct (&nearbyint, &mpfr_rint, "rint", r); +#endif +} + +#endif + +static void +err (const char *str, mp_size_t s, mpfr_t x, mpfr_t y, mpfr_prec_t p, + mpfr_rnd_t r, int trint, int inexact) +{ + printf ("Error: %s\ns = %u, p = %u, r = %s, trint = %d, inexact = %d\nx = ", + str, (unsigned int) s, (unsigned int) p, mpfr_print_rnd_mode (r), + trint, inexact); + mpfr_print_binary (x); + printf ("\ny = "); + mpfr_print_binary (y); + printf ("\n"); + exit (1); +} + +static void +coverage_03032011 (void) +{ + mpfr_t in, out, cmp; + int status; + int precIn; + char strData[(GMP_NUMB_BITS * 4)+256]; + + precIn = GMP_NUMB_BITS * 4; + + mpfr_init2 (in, precIn); + mpfr_init2 (out, GMP_NUMB_BITS); + mpfr_init2 (cmp, GMP_NUMB_BITS); + + /* cmp = "0.1EprecIn+2" */ + /* The buffer size is sufficient, as precIn is small in practice. */ + sprintf (strData, "0.1E%d", precIn+2); + mpfr_set_str_binary (cmp, strData); + + /* in = "0.10...01EprecIn+2" use all (precIn) significand bits */ + memset ((void *)strData, '0', precIn+2); + strData[1] = '.'; + strData[2] = '1'; + sprintf (&strData[precIn+1], "1E%d", precIn+2); + mpfr_set_str_binary (in, strData); + + status = mpfr_rint (out, in, MPFR_RNDN); + if ((mpfr_cmp (out, cmp) != 0) || (status >= 0)) + { + printf("mpfr_rint error :\n status is %d instead of 0\n", status); + printf(" out value is "); + mpfr_dump(out); + printf(" instead of "); + mpfr_dump(cmp); + exit (1); + } + + mpfr_clear (cmp); + mpfr_clear (out); + + mpfr_init2 (out, GMP_NUMB_BITS); + mpfr_init2 (cmp, GMP_NUMB_BITS); + + /* cmp = "0.10...01EprecIn+2" use all (GMP_NUMB_BITS) significand bits */ + strcpy (&strData[GMP_NUMB_BITS+1], &strData[precIn+1]); + mpfr_set_str_binary (cmp, strData); + + (MPFR_MANT(in))[2] = MPFR_LIMB_HIGHBIT; + status = mpfr_rint (out, in, MPFR_RNDN); + + if ((mpfr_cmp (out, cmp) != 0) || (status <= 0)) + { + printf("mpfr_rint error :\n status is %d instead of 0\n", status); + printf(" out value is\n"); + mpfr_dump(out); + printf(" instead of\n"); + mpfr_dump(cmp); + exit (1); + } + + mpfr_clear (cmp); + mpfr_clear (out); + mpfr_clear (in); +} + +#define TEST_FUNCTION mpfr_rint_trunc +#define TEST_RANDOM_EMIN -20 +#define TEST_RANDOM_ALWAYS_SCALE 1 +#define test_generic test_generic_trunc +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_rint_floor +#define TEST_RANDOM_EMIN -20 +#define TEST_RANDOM_ALWAYS_SCALE 1 +#define test_generic test_generic_floor +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_rint_ceil +#define TEST_RANDOM_EMIN -20 +#define TEST_RANDOM_ALWAYS_SCALE 1 +#define test_generic test_generic_ceil +#include "tgeneric.c" + +#define TEST_FUNCTION mpfr_rint_round +#define TEST_RANDOM_EMIN -20 +#define TEST_RANDOM_ALWAYS_SCALE 1 +#define test_generic test_generic_round +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mp_size_t s; + mpz_t z; + mpfr_prec_t p; + mpfr_t x, y, t, u, v; + int r; + int inexact, sign_t; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + mpz_init (z); + mpfr_init (t); + mpfr_init (u); + mpfr_init (v); + mpz_set_ui (z, 1); + for (s = 2; s < 100; s++) + { + /* z has exactly s bits */ + + mpz_mul_2exp (z, z, 1); + if (randlimb () % 2) + mpz_add_ui (z, z, 1); + mpfr_set_prec (x, s); + mpfr_set_prec (t, s); + mpfr_set_prec (u, s); + if (mpfr_set_z (x, z, MPFR_RNDN)) + { + printf ("Error: mpfr_set_z should be exact (s = %u)\n", + (unsigned int) s); + exit (1); + } + if (randlimb () % 2) + mpfr_neg (x, x, MPFR_RNDN); + if (randlimb () % 2) + mpfr_div_2ui (x, x, randlimb () % s, MPFR_RNDN); + for (p = 2; p < 100; p++) + { + int trint; + mpfr_set_prec (y, p); + mpfr_set_prec (v, p); + for (r = 0; r < MPFR_RND_MAX ; r++) + for (trint = 0; trint < 3; trint++) + { + if (trint == 2) + inexact = mpfr_rint (y, x, (mpfr_rnd_t) r); + else if (r == MPFR_RNDN) + inexact = mpfr_round (y, x); + else if (r == MPFR_RNDZ) + inexact = (trint ? mpfr_trunc (y, x) : + mpfr_rint_trunc (y, x, MPFR_RNDZ)); + else if (r == MPFR_RNDU) + inexact = (trint ? mpfr_ceil (y, x) : + mpfr_rint_ceil (y, x, MPFR_RNDU)); + else /* r = MPFR_RNDD */ + inexact = (trint ? mpfr_floor (y, x) : + mpfr_rint_floor (y, x, MPFR_RNDD)); + if (mpfr_sub (t, y, x, MPFR_RNDN)) + err ("subtraction 1 should be exact", + s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + sign_t = mpfr_cmp_ui (t, 0); + if (trint != 0 && + (((inexact == 0) && (sign_t != 0)) || + ((inexact < 0) && (sign_t >= 0)) || + ((inexact > 0) && (sign_t <= 0)))) + err ("wrong inexact flag", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + if (inexact == 0) + continue; /* end of the test for exact results */ + + if (((r == MPFR_RNDD || (r == MPFR_RNDZ && MPFR_SIGN (x) > 0)) + && inexact > 0) || + ((r == MPFR_RNDU || (r == MPFR_RNDZ && MPFR_SIGN (x) < 0)) + && inexact < 0)) + err ("wrong rounding direction", + s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + if (inexact < 0) + { + mpfr_add_ui (v, y, 1, MPFR_RNDU); + if (mpfr_cmp (v, x) <= 0) + err ("representable integer between x and its " + "rounded value", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + } + else + { + mpfr_sub_ui (v, y, 1, MPFR_RNDD); + if (mpfr_cmp (v, x) >= 0) + err ("representable integer between x and its " + "rounded value", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + } + if (r == MPFR_RNDN) + { + int cmp; + if (mpfr_sub (u, v, x, MPFR_RNDN)) + err ("subtraction 2 should be exact", + s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + cmp = mpfr_cmp_abs (t, u); + if (cmp > 0) + err ("faithful rounding, but not the nearest integer", + s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + if (cmp < 0) + continue; + /* |t| = |u|: x is the middle of two consecutive + representable integers. */ + if (trint == 2) + { + /* halfway case for mpfr_rint in MPFR_RNDN rounding + mode: round to an even integer or significand. */ + mpfr_div_2ui (y, y, 1, MPFR_RNDZ); + if (!mpfr_integer_p (y)) + err ("halfway case for mpfr_rint, result isn't an" + " even integer", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + /* If floor(x) and ceil(x) aren't both representable + integers, the significand must be even. */ + mpfr_sub (v, v, y, MPFR_RNDN); + mpfr_abs (v, v, MPFR_RNDN); + if (mpfr_cmp_ui (v, 1) != 0) + { + mpfr_div_2si (y, y, MPFR_EXP (y) - MPFR_PREC (y) + + 1, MPFR_RNDN); + if (!mpfr_integer_p (y)) + err ("halfway case for mpfr_rint, significand isn't" + " even", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + } + } + else + { /* halfway case for mpfr_round: x must have been + rounded away from zero. */ + if ((MPFR_SIGN (x) > 0 && inexact < 0) || + (MPFR_SIGN (x) < 0 && inexact > 0)) + err ("halfway case for mpfr_round, bad rounding" + " direction", s, x, y, p, (mpfr_rnd_t) r, trint, inexact); + } + } + } + } + } + mpfr_clear (x); + mpfr_clear (y); + mpz_clear (z); + mpfr_clear (t); + mpfr_clear (u); + mpfr_clear (v); + + special (); + basic_tests (); + coverage_03032011 (); + + test_generic_trunc (2, 300, 20); + test_generic_floor (2, 300, 20); + test_generic_ceil (2, 300, 20); + test_generic_round (2, 300, 20); + +#if __MPFR_STDC (199901L) + if (argc > 1 && strcmp (argv[1], "-s") == 0) + test_against_libc (); +#endif + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/troot.c b/mpfr/tests/troot.c new file mode 100644 index 0000000000..ae1af0026e --- /dev/null +++ b/mpfr/tests/troot.c @@ -0,0 +1,489 @@ +/* Test file for mpfr_root. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define DEFN(N) \ + static int root##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \ + { return mpfr_root (y, x, N, rnd); } \ + static int pow##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \ + { return mpfr_pow_ui (y, x, N, rnd); } + +DEFN(2) +DEFN(3) +DEFN(4) +DEFN(5) +DEFN(17) +DEFN(120) + +static void +special (void) +{ + mpfr_t x, y; + int i; + + mpfr_init (x); + mpfr_init (y); + + /* root(NaN) = NaN */ + mpfr_set_nan (x); + mpfr_root (y, x, 17, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: root(NaN,17) <> NaN\n"); + exit (1); + } + + /* root(+Inf) = +Inf */ + mpfr_set_inf (x, 1); + mpfr_root (y, x, 42, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: root(+Inf,42) <> +Inf\n"); + exit (1); + } + + /* root(-Inf, 17) = -Inf */ + mpfr_set_inf (x, -1); + mpfr_root (y, x, 17, MPFR_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error: root(-Inf,17) <> -Inf\n"); + exit (1); + } + /* root(-Inf, 42) = NaN */ + mpfr_set_inf (x, -1); + mpfr_root (y, x, 42, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: root(-Inf,42) <> -Inf\n"); + exit (1); + } + + /* root(+/-0, k) = +/-0 for k > 0 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_root (y, x, 17, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: root(+0,17) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_root (y, x, 42, MPFR_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: root(-0,42) <> -0\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_str (x, "8.39005285514734966412e-01", 10, MPFR_RNDN); + mpfr_root (x, x, 3, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01")) + { + printf ("Error in root3 (1)\n"); + printf ("expected 9.43166207799662426048e-01\n"); + printf ("got "); + mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "0.10000100001100101001001001011001"); + mpfr_root (x, x, 3, MPFR_RNDN); + mpfr_set_str_binary (y, "0.11001101011000100111000111111001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in root3 (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "-0.1100001110110000010101011001011"); + mpfr_root (x, x, 3, MPFR_RNDD); + mpfr_set_str_binary (y, "-0.11101010000100100101000101011001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in root3 (3)\n"); + exit (1); + } + + mpfr_set_prec (x, 82); + mpfr_set_prec (y, 27); + mpfr_set_str_binary (x, "0.1010001111011101011011000111001011001101100011110110010011011011011010011001100101e-7"); + mpfr_root (y, x, 3, MPFR_RNDD); + mpfr_set_str_binary (x, "0.101011110001110001000100011E-2"); + if (mpfr_cmp (x, y)) + { + printf ("Error in root3 (4)\n"); + exit (1); + } + + mpfr_set_prec (x, 204); + mpfr_set_prec (y, 38); + mpfr_set_str_binary (x, "0.101000000001101000000001100111111011111001110110100001111000100110100111001101100111110001110001011011010110010011100101111001111100001010010100111011101100000011011000101100010000000011000101001010001001E-5"); + mpfr_root (y, x, 3, MPFR_RNDD); + mpfr_set_str_binary (x, "0.10001001111010011011101000010110110010E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error in root3 (5)\n"); + exit (1); + } + + /* Worst case found on 2006-11-25 */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "1.0100001101101101001100110001001000000101001101100011E28"); + mpfr_root (y, x, 35, MPFR_RNDN); + mpfr_set_str_binary (x, "1.1100000010110101100011101011000010100001101100100011E0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_root (y, x, 35, MPFR_RNDN) for\n" + "x = 1.0100001101101101001100110001001000000101001101100011E28\n" + "Expected "); + mpfr_dump (x); + printf ("Got "); + mpfr_dump (y); + exit (1); + } + /* Worst cases found on 2006-11-26 */ + mpfr_set_str_binary (x, "1.1111010011101110001111010110000101110000110110101100E17"); + mpfr_root (y, x, 36, MPFR_RNDD); + mpfr_set_str_binary (x, "1.0110100111010001101001010111001110010100111111000010E0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_root (y, x, 36, MPFR_RNDD) for\n" + "x = 1.1111010011101110001111010110000101110000110110101100E17\n" + "Expected "); + mpfr_dump (x); + printf ("Got "); + mpfr_dump (y); + exit (1); + } + mpfr_set_str_binary (x, "1.1100011101101101100010110001000001110001111110010000E23"); + mpfr_root (y, x, 36, MPFR_RNDU); + mpfr_set_str_binary (x, "1.1001010100001110000110111111100011011101110011000100E0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_root (y, x, 36, MPFR_RNDU) for\n" + "x = 1.1100011101101101100010110001000001110001111110010000E23\n" + "Expected "); + mpfr_dump (x); + printf ("Got "); + mpfr_dump (y); + exit (1); + } + + /* Check for k = 1 */ + mpfr_set_ui (x, 17, MPFR_RNDN); + i = mpfr_root (y, x, 1, MPFR_RNDN); + if (mpfr_cmp_ui (x, 17) || i != 0) + { + printf ("Error in root for 17^(1/1)\n"); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + i = mpfr_root (y, x, 0, MPFR_RNDN); + if (!MPFR_IS_NAN (y) || i != 0) + { + printf ("Error in root for (+0)^(1/0)\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + i = mpfr_root (y, x, 0, MPFR_RNDN); + if (!MPFR_IS_NAN (y) || i != 0) + { + printf ("Error in root for (-0)^(1/0)\n"); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + i = mpfr_root (y, x, 0, MPFR_RNDN); + if (!MPFR_IS_NAN (y) || i != 0) + { + printf ("Error in root for 1^(1/0)\n"); + exit (1); + } + + /* Check for k==2 */ + mpfr_set_si (x, -17, MPFR_RNDD); + i = mpfr_root (y, x, 2, MPFR_RNDN); + if (!MPFR_IS_NAN (y) || i != 0) + { + printf ("Error in root for (-17)^(1/2)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +/* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=812779 + * https://bugzilla.gnome.org/show_bug.cgi?id=756960 + * is a GNOME Calculator bug (mpfr_root applied on a negative integer, + * which is converted to an unsigned integer), but the strange result + * is also due to a bug in MPFR. + */ +static void +bigint (void) +{ + mpfr_t x, y; + + mpfr_inits2 (64, x, y, (mpfr_ptr) 0); + + mpfr_set_ui (x, 10, MPFR_RNDN); + if (sizeof (unsigned long) * CHAR_BIT == 64) + { + mpfr_root (x, x, ULONG_MAX, MPFR_RNDN); + mpfr_set_ui_2exp (y, 1, -63, MPFR_RNDN); + mpfr_add_ui (y, y, 1, MPFR_RNDN); + if (! mpfr_equal_p (x, y)) + { + printf ("Error in bigint for ULONG_MAX\n"); + printf ("Expected "); + mpfr_dump (y); + printf ("Got "); + mpfr_dump (x); + exit (1); + } + } + + mpfr_set_ui (x, 10, MPFR_RNDN); + mpfr_root (x, x, 1234567890, MPFR_RNDN); + mpfr_set_str_binary (y, + "1.00000000000000000000000000001000000000101011000101000110010001"); + if (! mpfr_equal_p (x, y)) + { + printf ("Error in bigint for 1234567890\n"); + printf ("Expected "); + mpfr_dump (y); + printf ("Got "); + mpfr_dump (x); + exit (1); + } + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION mpfr_root +#define INTEGER_TYPE unsigned long +#define INT_RAND_FUNCTION() \ + (INTEGER_TYPE) (randlimb () & 1 ? randlimb () : randlimb () % 3 + 2) +#include "tgeneric_ui.c" + +static void +exact_powers (unsigned long bmax, unsigned long kmax) +{ + long b, k; + mpz_t z; + mpfr_t x, y; + int inex, neg; + + mpz_init (z); + for (b = 2; b <= bmax; b++) + for (k = 1; k <= kmax; k++) + { + mpz_ui_pow_ui (z, b, k); + mpfr_init2 (x, mpz_sizeinbase (z, 2)); + mpfr_set_ui (x, b, MPFR_RNDN); + mpfr_pow_ui (x, x, k, MPFR_RNDN); + mpz_set_ui (z, b); + mpfr_init2 (y, mpz_sizeinbase (z, 2)); + for (neg = 0; neg <= 1; neg++) + { + inex = mpfr_root (y, x, k, MPFR_RNDN); + if (inex != 0) + { + printf ("Error in exact_powers, b=%ld, k=%ld\n", b, k); + printf ("Expected inex=0, got %d\n", inex); + exit (1); + } + if (neg && (k & 1) == 0) + { + if (!MPFR_IS_NAN (y)) + { + printf ("Error in exact_powers, b=%ld, k=%ld\n", b, k); + printf ("Expected y=NaN\n"); + printf ("Got "); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + else if (MPFR_IS_NAN (y) || mpfr_cmp_si (y, b) != 0) + { + printf ("Error in exact_powers, b=%ld, k=%ld\n", b, k); + printf ("Expected y=%ld\n", b); + printf ("Got "); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + b = -b; + } + mpfr_clear (x); + mpfr_clear (y); + } + mpz_clear (z); +} + +/* Compare root(x,2^h) with pow(x,2^(-h)). */ +static void +cmp_pow (void) +{ + mpfr_t x, y1, y2; + int h; + + mpfr_inits2 (128, x, y1, y2, (mpfr_ptr) 0); + + for (h = 1; h < sizeof (unsigned long) * CHAR_BIT; h++) + { + unsigned long k = (unsigned long) 1 << h; + int i; + + for (i = 0; i < 10; i++) + { + mpfr_rnd_t rnd; + unsigned int flags1, flags2; + int inex1, inex2; + + tests_default_random (x, 0, __gmpfr_emin, __gmpfr_emax, 1); + rnd = RND_RAND (); + mpfr_set_ui_2exp (y1, 1, -h, MPFR_RNDN); + mpfr_clear_flags (); + inex1 = mpfr_pow (y1, x, y1, rnd); + flags1 = __gmpfr_flags; + mpfr_clear_flags (); + inex2 = mpfr_root (y2, x, k, rnd); + flags2 = __gmpfr_flags; + if (!(mpfr_equal_p (y1, y2) && SAME_SIGN (inex1, inex2) && + flags1 == flags2)) + { + printf ("Error in cmp_pow on h=%d, i=%d, rnd=%s\n", + h, i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("x = "); + mpfr_dump (x); + printf ("pow = "); + mpfr_dump (y1); + printf ("with inex = %d, flags =", inex1); + flags_out (flags1); + printf ("root = "); + mpfr_dump (y2); + printf ("with inex = %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + } + + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); +} + +int +main (void) +{ + mpfr_t x; + int r; + mpfr_prec_t p; + unsigned long k; + + tests_start_mpfr (); + + exact_powers (3, 1000); + special (); + bigint (); + cmp_pow (); + + mpfr_init (x); + + for (p = 2; p < 100; p++) + { + mpfr_set_prec (x, p); + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_set_ui (x, 1, MPFR_RNDN); + k = 2 + randlimb () % 4; /* 2 <= k <= 5 */ + mpfr_root (x, x, k, (mpfr_rnd_t) r); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_root(%lu) for x=1, rnd=%s\ngot ", + k, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_set_si (x, -1, MPFR_RNDN); + if (k % 2) + { + mpfr_root (x, x, k, (mpfr_rnd_t) r); + if (mpfr_cmp_si (x, -1)) + { + printf ("Error in mpfr_root(%lu) for x=-1, rnd=%s\ngot ", + k, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + + if (p >= 5) + { + int i; + for (i = -12; i <= 12; i++) + { + mpfr_set_ui (x, 27, MPFR_RNDN); + mpfr_mul_2si (x, x, 3*i, MPFR_RNDN); + mpfr_root (x, x, 3, MPFR_RNDN); + if (mpfr_cmp_si_2exp (x, 3, i)) + { + printf ("Error in mpfr_root(3) for " + "x = 27.0 * 2^(%d), rnd=%s\ngot ", + 3*i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\ninstead of 3 * 2^(%d)\n", i); + exit (1); + } + } + } + } + } + mpfr_clear (x); + + test_generic_ui (2, 200, 30); + + bad_cases (root2, pow2, "mpfr_root[2]", 8, -256, 255, 4, 128, 800, 40); + bad_cases (root3, pow3, "mpfr_root[3]", 8, -256, 255, 4, 128, 800, 40); + bad_cases (root4, pow4, "mpfr_root[4]", 8, -256, 255, 4, 128, 800, 40); + bad_cases (root5, pow5, "mpfr_root[5]", 8, -256, 255, 4, 128, 800, 40); + bad_cases (root17, pow17, "mpfr_root[17]", 8, -256, 255, 4, 128, 800, 40); + bad_cases (root120, pow120, "mpfr_root[120]", 8, -256, 255, 4, 128, 800, 40); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tround_prec.c b/mpfr/tests/tround_prec.c new file mode 100644 index 0000000000..f6936d7811 --- /dev/null +++ b/mpfr/tests/tround_prec.c @@ -0,0 +1,124 @@ +/* Test file for mpfr_prec_round. + +Copyright 1999-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x; + mpfr_exp_t emax; + + tests_start_mpfr (); + + mpfr_init (x); + + mpfr_set_nan (x); + mpfr_prec_round (x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x)); + + mpfr_set_inf (x, 1); + mpfr_prec_round (x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + + mpfr_set_inf (x, -1); + mpfr_prec_round (x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_prec_round (x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_prec_round (x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x)); + + emax = mpfr_get_emax (); + set_emax (0); + mpfr_set_prec (x, 3); + mpfr_set_str_binary (x, "0.111"); + mpfr_prec_round (x, 2, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + set_emax (emax); + + mpfr_set_prec (x, mp_bits_per_limb + 2); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0); + + mpfr_set_prec (x, 3); + mpfr_set_ui (x, 5, MPFR_RNDN); + mpfr_prec_round (x, 2, MPFR_RNDN); + if (mpfr_cmp_ui(x, 4)) + { + printf ("Error in tround: got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (" instead of 4\n"); + exit (1); + } + + /* check case when reallocation is needed */ + mpfr_set_prec (x, 3); + mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */ + mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN); + if (mpfr_cmp_ui(x, 5)) + { + printf ("Error in tround: got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (" instead of 5\n"); + exit (1); + } + + mpfr_clear(x); + mpfr_init2 (x, 3); + mpfr_set_si (x, -5, MPFR_RNDN); /* exact */ + mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN); + if (mpfr_cmp_si(x, -5)) + { + printf ("Error in tround: got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (" instead of -5\n"); + exit (1); + } + + /* check case when new precision needs less limbs */ + mpfr_set_prec (x, mp_bits_per_limb + 1); + mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */ + mpfr_prec_round (x, 3, MPFR_RNDN); /* exact */ + if (mpfr_cmp_ui(x, 5)) + { + printf ("Error in tround: got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (" instead of 5\n"); + exit (1); + } + + mpfr_clear(x); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsec.c b/mpfr/tests/tsec.c new file mode 100644 index 0000000000..16951860d9 --- /dev/null +++ b/mpfr/tests/tsec.c @@ -0,0 +1,172 @@ +/* Test file for mpfr_sec. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_sec +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_sec (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sec(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_sec (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sec(Inf) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_sec (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sec(-Inf) != NaN\n"); + exit (1); + } + + /* sec(+/-0) = 1 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_sec (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: sec(+0) != 1\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_sec (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: sec(-0) != 1\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +overflowed_sec0 (void) +{ + mpfr_t x, y; + int emax, i, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (emax); /* 1 is not representable. */ + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_sec (x, x, (mpfr_rnd_t) rnd); + if (! mpfr_overflow_p ()) + { + printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" + " The overflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_specials (); + + test_generic (2, 200, 10); + overflowed_sec0 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsech.c b/mpfr/tests/tsech.c new file mode 100644 index 0000000000..d52c8f3edd --- /dev/null +++ b/mpfr/tests/tsech.c @@ -0,0 +1,190 @@ +/* Test file for mpfr_sech. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_sech +#define TEST_RANDOM_EMIN -64 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +check_specials (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_sech (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sech(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_sech (y, x, MPFR_RNDN); + if (! (MPFR_IS_ZERO (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error: sech(+Inf) != +0\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_sech (y, x, MPFR_RNDN); + if (! (MPFR_IS_ZERO (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error: sech(-Inf) != +0\n"); + exit (1); + } + + /* sec(+/-0) = 1 */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_sech (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: sech(+0) != 1\n"); + exit (1); + } + mpfr_neg (x, x, MPFR_RNDN); + mpfr_sech (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: sech(-0) != 1\n"); + exit (1); + } + + /* check huge x */ + mpfr_set_str (x, "8e8", 10, MPFR_RNDN); + mpfr_sech (y, x, MPFR_RNDN); + if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error: sech(8e8) != +0\n"); + exit (1); + } + mpfr_set_str (x, "-8e8", 10, MPFR_RNDN); + mpfr_sech (y, x, MPFR_RNDN); + if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error: sech(-8e8) != +0\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +overflowed_sech0 (void) +{ + mpfr_t x, y; + int emax, i, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); + mpfr_nextbelow (y); + set_emax (emax); /* 1 is not representable. */ + /* and if emax < 0, 1 - eps is not representable either. */ + for (i = -1; i <= 1; i++) + RND_LOOP (rnd) + { + mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_sech (x, x, (mpfr_rnd_t) rnd); + if ((i == 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && + ! mpfr_overflow_p ()) + { + printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n" + " The overflow flag is not set.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex >= 0) + { + printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n" + " The inexact value must be negative.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (x, y)) + { + printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex <= 0) + { + printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n" + " The inexact value must be positive.\n", + i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) + { + printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n" + " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_specials (); + test_generic (2, 200, 10); + overflowed_sech0 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset.c b/mpfr/tests/tset.c new file mode 100644 index 0000000000..eec197af06 --- /dev/null +++ b/mpfr/tests/tset.c @@ -0,0 +1,209 @@ +/* Test file for mpfr_set. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int error; + +#define PRINT_ERROR_IF(condition, text) \ + do { \ + if (condition) \ + { \ + printf ("%s", text); \ + error = 1; \ + } \ + } while (0) + + +/* Maybe better create its own test file ? */ +static void +check_neg_special (void) +{ + mpfr_t x; + mpfr_init (x); + MPFR_SET_NAN (x); + mpfr_clear_nanflag (); + mpfr_neg (x, x, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_nanflag_p (), + "ERROR: neg (NaN) doesn't set Nan flag.\n"); + mpfr_clear (x); +} + +static void +check_special (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_inf (x, 1); + PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0, + "ERROR: mpfr_set_inf failed to set variable to +infinity.\n"); + inexact = mpfr_set (y, x, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || inexact != 0, + "ERROR: mpfr_set failed to set variable to +infinity.\n"); + + inexact = mpfr_set_ui (y, 0, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) < 0 || inexact != 0, + "ERROR: mpfr_set_ui failed to set variable to +0.\n"); + + mpfr_set_inf (x, -1); + PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0, + "ERROR: mpfr_set_inf failed to set variable to -infinity.\n"); + inexact = mpfr_set (y, x, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) > 0 || inexact != 0, + "ERROR: mpfr_set failed to set variable to -infinity.\n"); + + mpfr_set_zero (x, 1); + PRINT_ERROR_IF (!mpfr_zero_p (x) || mpfr_sgn (x) < 0, + "ERROR: mpfr_set_zero failed to set variable to +0.\n"); + inexact = mpfr_set (y, x, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) < 0 || inexact != 0, + "ERROR: mpfr_set failed to set variable to +0.\n"); + + mpfr_set_zero (x, -1); + PRINT_ERROR_IF (!mpfr_zero_p (x) || mpfr_sgn (x) > 0, + "ERROR: mpfr_set_zero failed to set variable to -0.\n"); + inexact = mpfr_set (y, x, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) > 0 || inexact != 0, + "ERROR: mpfr_set failed to set variable to -0.\n"); + + mpfr_set_nan (x); + PRINT_ERROR_IF (!mpfr_nan_p (x), + "ERROR: mpfr_set_nan failed to set variable to NaN.\n"); + inexact = mpfr_set (y, x, MPFR_RNDN); + PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0, + "ERROR: mpfr_set failed to set variable to NaN.\n"); + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_ternary_value (void) +{ + int p, q, rnd; + int inexact, cmp; + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + for (p=2; p<500; p++) + { + mpfr_set_prec (x, p); + mpfr_urandomb (x, RANDS); + if (randlimb () % 2) + mpfr_neg (x, x, MPFR_RNDN); + for (q=2; q<2*p; q++) + { + mpfr_set_prec (y, q); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd); + cmp = mpfr_cmp (y, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong ternary value in mpfr_set: expected %d," + " got %d\n", cmp, inexact); + exit (1); + } + } + } + } + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_set +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z, u; + int inexact; + mpfr_exp_t emax; + + tests_start_mpfr (); + + /* Default : no error */ + error = 0; + + /* check prototypes of mpfr_init_set_* */ + inexact = mpfr_init_set_si (x, -1, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + inexact = mpfr_init_set (y, x, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + + emax = mpfr_get_emax (); + set_emax (0); + mpfr_set_prec (x, 3); + mpfr_set_str_binary (x, "0.111"); + mpfr_set_prec (y, 2); + mpfr_set (y, x, MPFR_RNDU); + if (!(MPFR_IS_INF (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx="); + mpfr_dump (x); + printf ("y="); + mpfr_dump (y); + exit (1); + } + + set_emax (emax); + + mpfr_set_prec (y, 11); + mpfr_set_str_binary (y, "0.11111111100E-8"); + mpfr_set_prec (x, 2); + mpfr_set (x, y, MPFR_RNDN); + mpfr_set_str_binary (y, "1.0E-8"); + if (mpfr_cmp (x, y)) + { + printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); + + check_ternary_value (); + check_special (); + check_neg_special (); + + test_generic (2, 1000, 10); + + tests_end_mpfr (); + return error; +} diff --git a/mpfr/tests/tset_d.c b/mpfr/tests/tset_d.c new file mode 100644 index 0000000000..df57beaaa2 --- /dev/null +++ b/mpfr/tests/tset_d.c @@ -0,0 +1,227 @@ +/* Test file for mpfr_set_d and mpfr_get_d. + +Copyright 1999-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, z; + unsigned long k, n; + volatile double d; + double dd; + + tests_start_mpfr (); + mpfr_test_init (); + +#ifndef MPFR_DOUBLE_SPEC + printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n" + "that you do not have a conforming C implementation and problems\n" + "may occur with conversions between MPFR numbers and standard\n" + "floating-point types. Please contact the MPFR team.\n"); +#elif MPFR_DOUBLE_SPEC == 0 + /* + printf ("The type 'double' of your C implementation does not seem to\n" + "correspond to the IEEE-754 double precision. Though code has\n" + "been written to support such implementations, tests have been\n" + "done only on IEEE-754 double-precision implementations and\n" + "conversions between MPFR numbers and standard floating-point\n" + "types may be inaccurate. You may wish to contact the MPFR team\n" + "for further testing.\n"); + */ + printf ("The type 'double' of your C implementation does not seem to\n" + "correspond to the IEEE-754 double precision. Such particular\n" + "implementations are not supported yet, and conversions between\n" + "MPFR numbers and standard floating-point types may be very\n" + "inaccurate.\n"); + printf ("FLT_RADIX = %ld\n", (long) FLT_RADIX); + printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG); + printf ("DBL_MIN_EXP = %ld\n", (long) DBL_MIN_EXP); + printf ("DBL_MAX_EXP = %ld\n", (long) DBL_MAX_EXP); +#endif + + mpfr_init (x); + +#if !defined(MPFR_ERRDIVZERO) + mpfr_set_nan (x); + d = mpfr_get_d (x, MPFR_RNDN); + if (! DOUBLE_ISNAN (d)) + { + printf ("ERROR for NAN (1)\n"); +#ifdef MPFR_NANISNAN + printf ("The reason is that NAN == NAN. Please look at the configure " + "output\nand Section \"In case of problem\" of the INSTALL " + "file.\n"); +#endif + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_d (x, d, MPFR_RNDN); + if (! mpfr_nan_p (x)) + { + printf ("ERROR for NAN (2)\n"); +#ifdef MPFR_NANISNAN + printf ("The reason is that NAN == NAN. Please look at the configure " + "output\nand Section \"In case of problem\" of the INSTALL " + "file.\n"); +#endif + exit (1); + } +#endif /* MPFR_ERRDIVZERO */ + +#ifdef HAVE_SIGNEDZ + d = 0.0; + mpfr_set_d (x, d, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + d = -d; + mpfr_set_d (x, d, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x)) + { + printf ("Error in mpfr_set_d on -0\n"); + exit (1); + } +#endif /* HAVE_SIGNEDZ */ + +#if !defined(MPFR_ERRDIVZERO) + mpfr_set_inf (x, 1); + d = mpfr_get_d (x, MPFR_RNDN); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_d (x, d, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + + mpfr_set_inf (x, -1); + d = mpfr_get_d (x, MPFR_RNDN); + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_set_d (x, d, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); +#endif /* MPFR_ERRDIVZERO */ + + mpfr_set_prec (x, 2); + + /* checks that subnormals are not flushed to zero */ + d = DBL_MIN; /* 2^(-1022) */ + for (n=0; n<52; n++, d /= 2.0) + if (d != 0.0) /* should be 2^(-1022-n) */ + { + mpfr_set_d (x, d, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (x, 1, -1022-n)) + { + printf ("Wrong result for d=2^(%ld), ", -1022-n); + printf ("got "); + mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN); + printf ("\n"); + mpfr_print_binary (x); + puts (""); + exit (1); + } + } + + /* checks that rounds to nearest sets the last + bit to zero in case of equal distance */ + mpfr_set_d (x, 5.0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 4)) + { + printf ("Error in tset_d: expected 4.0, got "); + mpfr_print_binary (x); putchar('\n'); + exit (1); + } + mpfr_set_d (x, -5.0, MPFR_RNDN); + if (mpfr_cmp_si (x, -4)) + { + printf ("Error in tset_d: expected -4.0, got "); + mpfr_print_binary (x); putchar('\n'); + exit (1); + } + + mpfr_set_d (x, 9.84891017624509146344e-01, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in tset_d: expected 1.0, got "); + mpfr_print_binary (x); putchar('\n'); + exit (1); + } + + mpfr_init2 (z, 32); + mpfr_set_d (z, 1.0, (mpfr_rnd_t) 0); + if (mpfr_cmp_ui (z, 1)) + { + mpfr_print_binary (z); puts (""); + printf ("Error: 1.0 != 1.0\n"); + exit (1); + } + mpfr_set_prec (x, 53); + mpfr_init2 (y, 53); + mpfr_set_d (x, d=-1.08007920352320089721e+150, (mpfr_rnd_t) 0); + if (mpfr_get_d1 (x) != d) + { + mpfr_print_binary (x); puts (""); + printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n", + d, mpfr_get_d1 (x)); + exit (1); + } + + mpfr_set_d (x, 8.06294740693074521573e-310, (mpfr_rnd_t) 0); + d = -6.72658901114033715233e-165; + mpfr_set_d (x, d, (mpfr_rnd_t) 0); + if (d != mpfr_get_d1 (x)) + { + mpfr_print_binary (x); + puts (""); + printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n", + d, mpfr_get_d1 (x)); + exit (1); + } + + n = (argc==1) ? 500000 : atoi(argv[1]); + for (k = 1; k <= n; k++) + { + do + { + d = DBL_RAND (); + } +#ifdef HAVE_DENORMS + while (0); +#else + while (ABS(d) < DBL_MIN); +#endif + mpfr_set_d (x, d, (mpfr_rnd_t) 0); + dd = mpfr_get_d1 (x); + if (d != dd && !(Isnan(d) && Isnan(dd))) + { + printf ("Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d1 (x)); + mpfr_print_binary (x); + puts (""); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset_exp.c b/mpfr/tests/tset_exp.c new file mode 100644 index 0000000000..bdd043a7b1 --- /dev/null +++ b/mpfr/tests/tset_exp.c @@ -0,0 +1,67 @@ +/* Test file for mpfr_set_exp. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + int ret; + mpfr_exp_t emin, emax; + + tests_start_mpfr (); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init (x); + + mpfr_set_ui (x, 1, MPFR_RNDN); + ret = mpfr_set_exp (x, 2); + MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui (x, 2) == 0); + + set_emin (-1); + ret = mpfr_set_exp (x, -1); + MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui_2exp (x, 1, -2) == 0); + + set_emax (1); + ret = mpfr_set_exp (x, 1); + MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui (x, 1) == 0); + + ret = mpfr_set_exp (x, -2); + MPFR_ASSERTN(ret != 0 && mpfr_cmp_ui (x, 1) == 0); + + ret = mpfr_set_exp (x, 2); + MPFR_ASSERTN(ret != 0 && mpfr_cmp_ui (x, 1) == 0); + + mpfr_clear (x); + + set_emin (emin); + set_emax (emax); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset_f.c b/mpfr/tests/tset_f.c new file mode 100644 index 0000000000..e4670d2bfb --- /dev/null +++ b/mpfr/tests/tset_f.c @@ -0,0 +1,207 @@ +/* Test file for mpfr_set_f. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> /* for ULONG_MAX */ + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x, u; + mpf_t y, z; + mpfr_exp_t emax; + unsigned long k, pr; + int r, inexact; + + tests_start_mpfr (); + + mpf_init (y); + mpf_init (z); + + mpf_set_d (y, 0.0); + + /* check prototype of mpfr_init_set_f */ + mpfr_init_set_f (x, y, MPFR_RNDN); + mpfr_set_prec (x, 100); + mpfr_set_f (x, y, MPFR_RNDN); + + mpf_urandomb (y, RANDS, 10 * GMP_NUMB_BITS); + mpfr_set_f (x, y, RND_RAND ()); + + /* bug found by Jean-Pierre Merlet */ + mpfr_set_prec (x, 256); + mpf_set_prec (y, 256); + mpfr_init2 (u, 256); + mpfr_set_str (u, + "7.f10872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872b020c498@2", + 16, MPFR_RNDN); + mpf_set_str (y, "2033033E-3", 10); /* avoid 2033.033 which is + locale-sensitive */ + mpfr_set_f (x, y, MPFR_RNDN); + if (mpfr_cmp (x, u)) + { + printf ("mpfr_set_f failed for y=2033033E-3\n"); + exit (1); + } + mpf_set_str (y, "-2033033E-3", 10); /* avoid -2033.033 which is + locale-sensitive */ + mpfr_set_f (x, y, MPFR_RNDN); + mpfr_neg (u, u, MPFR_RNDN); + if (mpfr_cmp (x, u)) + { + printf ("mpfr_set_f failed for y=-2033033E-3\n"); + exit (1); + } + + mpf_set_prec (y, 300); + mpf_set_str (y, "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", -2); + mpf_mul_2exp (y, y, 600); + mpfr_set_prec (x, 300); + mpfr_set_f (x, y, MPFR_RNDN); + if (mpfr_check (x) == 0) + { + printf ("Error in mpfr_set_f: corrupted result\n"); + mpfr_dump (x); + exit (1); + } + MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, 901) == 0); + + /* random values */ + for (k = 1; k <= 1000; k++) + { + pr = 2 + (randlimb () & 255); + mpf_set_prec (z, pr); + mpf_urandomb (z, RANDS, z->_mp_prec); + mpfr_set_prec (u, ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS)); + mpfr_set_f (u, z, MPFR_RNDN); + if (mpfr_cmp_f (u , z) != 0) + { + printf ("Error in mpfr_set_f:\n"); + printf ("mpf (precision=%lu)=", pr); + mpf_out_str (stdout, 16, 0, z); + printf ("\nmpfr(precision=%lu)=", + ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS)); + mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + mpfr_set_prec (x, pr); + mpfr_set_f (x, z, MPFR_RNDN); + mpfr_sub (u, u, x, MPFR_RNDN); + mpfr_abs (u, u, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (u, 1, -pr - 1) > 0) + { + printf ("Error in mpfr_set_f: precision=%lu\n", pr); + printf ("mpf ="); + mpf_out_str (stdout, 16, 0, z); + printf ("\nmpfr="); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + } + + /* Check for +0 */ + mpfr_set_prec (x, 53); + mpf_set_prec (y, 53); + mpf_set_ui (y, 0); + for (r = 0 ; r < MPFR_RND_MAX ; r++) + { + int i; + for (i = -1; i <= 1; i++) + { + if (i) + mpfr_set_si (x, i, MPFR_RNDN); + inexact = mpfr_set_f (x, y, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact) + { + printf ("mpfr_set_f(x,0) failed for %s, i = %d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); + exit (1); + } + } + } + + /* coverage test */ + mpf_set_prec (y, 2); + mpfr_set_prec (x, 3 * mp_bits_per_limb); + mpf_set_ui (y, 1); + for (r = 0; r < mp_bits_per_limb; r++) + { + mpfr_urandomb (x, RANDS); /* to fill low limbs with random data */ + inexact = mpfr_set_f (x, y, MPFR_RNDN); + MPFR_ASSERTN(inexact == 0 && mpfr_cmp_ui_2exp (x, 1, r) == 0); + mpf_mul_2exp (y, y, 1); + } + + mpf_set_ui (y, 1); + mpf_mul_2exp (y, y, ULONG_MAX); + mpfr_set_f (x, y, MPFR_RNDN); + mpfr_set_ui (u, 1, MPFR_RNDN); + mpfr_mul_2ui (u, u, ULONG_MAX, MPFR_RNDN); + if (!mpfr_equal_p (x, u)) + { + printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^ULONG_MAX\n"); + exit (1); + } + + emax = mpfr_get_emax (); + + /* For mpf_mul_2exp, emax must fit in an unsigned long! */ + if (emax >= 0 && emax <= ULONG_MAX) + { + mpf_set_ui (y, 1); + mpf_mul_2exp (y, y, emax); + mpfr_set_f (x, y, MPFR_RNDN); + mpfr_set_ui_2exp (u, 1, emax, MPFR_RNDN); + if (!mpfr_equal_p (x, u)) + { + printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^emax\n"); + exit (1); + } + } + + /* For mpf_mul_2exp, emax - 1 must fit in an unsigned long! */ + if (emax >= 1 && emax - 1 <= ULONG_MAX) + { + mpf_set_ui (y, 1); + mpf_mul_2exp (y, y, emax - 1); + mpfr_set_f (x, y, MPFR_RNDN); + mpfr_set_ui_2exp (u, 1, emax - 1, MPFR_RNDN); + if (!mpfr_equal_p (x, u)) + { + printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^(emax-1)\n"); + exit (1); + } + } + + mpfr_clear (x); + mpfr_clear (u); + mpf_clear (y); + mpf_clear (z); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset_ld.c b/mpfr/tests/tset_ld.c new file mode 100644 index 0000000000..6e2b931f57 --- /dev/null +++ b/mpfr/tests/tset_ld.c @@ -0,0 +1,315 @@ +/* Test file for mpfr_set_ld and mpfr_get_ld. + +Copyright 2002-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> +#include <limits.h> +#ifdef WITH_FPU_CONTROL +#include <fpu_control.h> +#endif + +#include "mpfr-test.h" + +static void +check_gcc33_bug (void) +{ + volatile long double x; + x = (long double) 9007199254740992.0 + 1.0; + if (x != 0.0) + return; /* OK */ + printf + ("Detected optimization bug of gcc 3.3 on Alpha concerning long double\n" + "comparisons; set_ld tests might fail (set_ld won't work correctly).\n" + "See http://gcc.gnu.org/ml/gcc-bugs/2003-10/msg00853.html for more\n" + "information.\n"); +} + +static int +Isnan_ld (long double d) +{ + /* Do not convert d to double as this can give an overflow, which + may confuse compilers without IEEE 754 support (such as clang + -fsanitize=undefined), or trigger a trap if enabled. + The DOUBLE_ISNAN macro should work fine on long double. */ + if (DOUBLE_ISNAN (d)) + return 1; + LONGDOUBLE_NAN_ACTION (d, goto yes); + return 0; + yes: + return 1; +} + +/* checks that a long double converted to a mpfr (with precision >=113), + then converted back to a long double gives the initial value, + or in other words mpfr_get_ld(mpfr_set_ld(d)) = d. +*/ +static void +check_set_get (long double d, mpfr_t x) +{ + int r; + long double e; + int inex; + + for (r = 0; r < MPFR_RND_MAX; r++) + { + inex = mpfr_set_ld (x, d, (mpfr_rnd_t) r); + if (inex != 0) + { + mpfr_exp_t emin, emax; + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + printf ("Error: mpfr_set_ld should be exact\n"); + printf ("d=%1.30Le inex=%d\n", d, inex); + if (emin >= LONG_MIN) + printf ("emin=%ld\n", (long) emin); + if (emax <= LONG_MAX) + printf ("emax=%ld\n", (long) emax); + mpfr_dump (x); + exit (1); + } + e = mpfr_get_ld (x, (mpfr_rnd_t) r); + if ((Isnan_ld(d) && ! Isnan_ld(e)) || + (Isnan_ld(e) && ! Isnan_ld(d)) || + (e != d && !(Isnan_ld(e) && Isnan_ld(d)))) + { + printf ("Error: mpfr_get_ld o mpfr_set_ld <> Id\n"); + printf (" r=%d\n", r); + printf (" d=%1.30Le get_ld(set_ld(d))=%1.30Le\n", d, e); + ld_trace (" d", d); + printf (" x="); mpfr_out_str (NULL, 16, 0, x, MPFR_RNDN); + printf ("\n"); + ld_trace (" e", e); +#ifdef MPFR_NANISNAN + if (Isnan_ld(d) || Isnan_ld(e)) + printf ("The reason is that NAN == NAN. Please look at the " + "configure output\nand Section \"In case of problem\" " + "of the INSTALL file.\n"); +#endif + exit (1); + } + } +} + +static void +test_small (void) +{ + mpfr_t x, y, z; + long double d; + + mpfr_init2 (x, 64); + mpfr_init2 (y, 64); + mpfr_init2 (z, 64); + + /* x = 11906603631607553907/2^(16381+64) */ + mpfr_set_str (x, "0.1010010100111100110000001110101101000111010110000001111101110011E-16381", 2, MPFR_RNDN); + d = mpfr_get_ld (x, MPFR_RNDN); /* infinite loop? */ + mpfr_set_ld (y, d, MPFR_RNDN); + mpfr_sub (z, x, y, MPFR_RNDN); + mpfr_abs (z, z, MPFR_RNDN); + mpfr_clear_erangeflag (); + /* If long double = double, d should be equal to 0; + in this case, everything is OK. */ + if (d != 0 && (mpfr_cmp_str (z, "1E-16434", 2, MPFR_RNDN) > 0 || + mpfr_erangeflag_p ())) + { + printf ("Error with x = "); + mpfr_out_str (NULL, 10, 21, x, MPFR_RNDN); + printf (" = "); + mpfr_out_str (NULL, 16, 0, x, MPFR_RNDN); + printf ("\n -> d = %.21Lg", d); + printf ("\n -> y = "); + mpfr_out_str (NULL, 10, 21, y, MPFR_RNDN); + printf (" = "); + mpfr_out_str (NULL, 16, 0, y, MPFR_RNDN); + printf ("\n -> |x-y| = "); + mpfr_out_str (NULL, 16, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +test_fixed_bugs (void) +{ + mpfr_t x; + long double l, m; + + /* bug found by Steve Kargl (2009-03-14) */ + mpfr_init2 (x, 64); + mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN); + mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */ + + /* bug reported by Jakub Jelinek (2010-10-17) + https://gforge.inria.fr/tracker/?func=detail&aid=11300 */ + mpfr_set_prec (x, MPFR_LDBL_MANT_DIG); + /* l = 0x1.23456789abcdef0123456789abcdp-914L; */ + l = 8.215640181713713164092636634579e-276; + mpfr_set_ld (x, l, MPFR_RNDN); + m = mpfr_get_ld (x, MPFR_RNDN); + if (m != l) + { + printf ("Error in get_ld o set_ld for l=%Le\n", l); + printf ("Got m=%Le instead of l\n", m); + exit (1); + } + + /* another similar test which failed with extended double precision and the + generic code for mpfr_set_ld */ + /* l = 0x1.23456789abcdef0123456789abcdp-968L; */ + l = 4.560596445887084662336528403703e-292; + mpfr_set_ld (x, l, MPFR_RNDN); + m = mpfr_get_ld (x, MPFR_RNDN); + if (m != l) + { + printf ("Error in get_ld o set_ld for l=%Le\n", l); + printf ("Got m=%Le instead of l\n", m); + exit (1); + } + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + long double d, e; + mpfr_t x; + int i; + mpfr_exp_t emax; +#ifdef WITH_FPU_CONTROL + fpu_control_t cw; + + if (argc > 1) + { + cw = strtol(argv[1], NULL, 0); + printf ("FPU control word: 0x%x\n", (unsigned int) cw); + _FPU_SETCW (cw); + } +#endif + + check_gcc33_bug (); + test_fixed_bugs (); + + tests_start_mpfr (); + mpfr_test_init (); + + mpfr_init2 (x, MPFR_LDBL_MANT_DIG); + +#if !defined(MPFR_ERRDIVZERO) + /* check NaN */ + mpfr_set_nan (x); + d = mpfr_get_ld (x, MPFR_RNDN); + check_set_get (d, x); +#endif + + /* check +0.0 and -0.0 */ + d = 0.0; + check_set_get (d, x); + d = DBL_NEG_ZERO; + check_set_get (d, x); + + /* check that the sign of -0.0 is set */ + mpfr_set_ld (x, DBL_NEG_ZERO, MPFR_RNDN); + if (MPFR_SIGN(x) > 0) + { + printf ("Error: sign of -0.0 is not set correctly\n"); +#if _GMP_IEEE_FLOATS + exit (1); + /* Non IEEE doesn't support negative zero yet */ +#endif + } + +#if !defined(MPFR_ERRDIVZERO) + /* check +Inf */ + mpfr_set_inf (x, 1); + d = mpfr_get_ld (x, MPFR_RNDN); + check_set_get (d, x); + + /* check -Inf */ + mpfr_set_inf (x, -1); + d = mpfr_get_ld (x, MPFR_RNDN); + check_set_get (d, x); +#endif + + /* check the largest power of two */ + d = 1.0; while (d < LDBL_MAX / 2.0) d += d; + check_set_get (d, x); + check_set_get (-d, x); + + /* check largest long double */ + d = LDBL_MAX; + check_set_get (d, x); + check_set_get (-d, x); + + /* check the smallest power of two */ + d = 1.0; + while ((e = d / 2.0) != (long double) 0.0 && e != d) + d = e; + check_set_get (d, x); + check_set_get (-d, x); + + /* check largest 2^(2^k) that is representable as a long double */ + d = (LDBL_MAX / 2) + (LDBL_MAX / 4 * LDBL_EPSILON); + check_set_get (d, x); + + /* check that 2^i, 2^i+1 and 2^i-1 are correctly converted */ + d = 1.0; + for (i = 1; i < MPFR_LDBL_MANT_DIG; i++) + { + d = 2.0 * d; /* d = 2^i */ + check_set_get (d, x); + check_set_get (d + 1.0, x); + check_set_get (d - 1.0, x); + } + + for (i = 0; i < 10000; i++) + { + mpfr_urandomb (x, RANDS); + d = mpfr_get_ld (x, MPFR_RNDN); + check_set_get (d, x); + } + + /* check with reduced emax to exercise overflow */ + emax = mpfr_get_emax (); + mpfr_set_prec (x, 2); + set_emax (1); + mpfr_set_ld (x, (long double) 2.0, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + for (d = (long double) 2.0, i = 0; i < 13; i++, d *= d); + /* now d = 2^8192 */ + mpfr_set_ld (x, d, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + set_emax (emax); + + mpfr_clear (x); + + test_small (); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tset_q.c b/mpfr/tests/tset_q.c new file mode 100644 index 0000000000..776c550d14 --- /dev/null +++ b/mpfr/tests/tset_q.c @@ -0,0 +1,186 @@ +/* Test file for mpfr_set_q. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check (long int n, long int d, mpfr_rnd_t rnd, const char *ys) +{ + mpq_t q; + mpfr_t x, t; + int inexact, compare; + unsigned int flags, ex_flags; + + mpfr_init2 (x, 53); + mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb); + mpq_init (q); + mpq_set_si (q, n, d); + mpfr_clear_flags (); + inexact = mpfr_set_q (x, q, rnd); + flags = __gmpfr_flags; + + /* check values */ + if (mpfr_cmp_str1 (x, ys)) + { + printf ("Error for q = %ld/%ld and rnd = %s\n", n, d, + mpfr_print_rnd_mode (rnd)); + printf ("correct result is %s, mpfr_set_q gives ", ys); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + + /* check inexact flag */ + if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd)) + { + printf ("t <- x * d should be exact\n"); + exit (1); + } + compare = mpfr_cmp_si (t, n); + if (! SAME_SIGN (inexact, compare)) + { + printf ("Wrong ternary value for q = %ld/%ld and rnd = %s:\n" + "expected %d or equivalent, got %d\n", + n, d, mpfr_print_rnd_mode (rnd), compare, inexact); + exit (1); + } + + ex_flags = compare == 0 ? 0 : MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("Wrong flags for q = %ld/%ld and rnd = %s:\n", + n, d, mpfr_print_rnd_mode (rnd)); + printf ("Expected flags:"); + flags_out (ex_flags); + printf ("Got flags: "); + flags_out (flags); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (t); + mpq_clear (q); +} + +static void +check0 (void) +{ + mpq_t y; + mpfr_t x; + int inexact; + int r; + + /* Check for +0 */ + mpfr_init (x); + mpq_init (y); + mpq_set_si (y, 0, 1); + for (r = 0; r < MPFR_RND_MAX; r++) + { + mpfr_clear_flags (); + inexact = mpfr_set_q (x, y, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact || + __gmpfr_flags != 0) + { + printf("mpfr_set_q(x,0) failed for %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit(1); + } + } + mpfr_clear (x); + mpq_clear (y); +} + +static void +check_nan_inf_mpq (void) +{ + mpfr_t mpfr_value, mpfr_cmp; + mpq_t mpq_value; + int status; + + mpfr_init2 (mpfr_value, MPFR_PREC_MIN); + mpq_init (mpq_value); + mpq_set_si (mpq_value, 0, 0); + mpz_set_si (mpq_denref (mpq_value), 0); + + status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN); + + if ((status != 0) || (!MPFR_IS_NAN (mpfr_value))) + { + mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN); + mpfr_set_nan (mpfr_cmp); + printf ("mpfr_set_q with a NAN mpq value returned a wrong value :\n" + " waiting for "); + mpfr_print_binary (mpfr_cmp); + printf (" got "); + mpfr_print_binary (mpfr_value); + printf ("\n trinary value is %d\n", status); + exit (1); + } + + mpq_set_si (mpq_value, -1, 0); + mpz_set_si (mpq_denref (mpq_value), 0); + + status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN); + + if ((status != 0) || (!MPFR_IS_INF (mpfr_value)) || + (MPFR_SIGN(mpfr_value) != mpq_sgn(mpq_value))) + { + mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN); + mpfr_set_inf (mpfr_cmp, -1); + printf ("mpfr_set_q with a -INF mpq value returned a wrong value :\n" + " waiting for "); + mpfr_print_binary (mpfr_cmp); + printf (" got "); + mpfr_print_binary (mpfr_value); + printf ("\n trinary value is %d\n", status); + exit (1); + } + + mpq_clear (mpq_value); + mpfr_clear (mpfr_value); +} + +int +main (void) +{ + tests_start_mpfr (); + + check(-1647229822, 40619231, MPFR_RNDZ, "-4.055295438754120596e1"); + check(-148939696, 1673285490, MPFR_RNDZ, "-8.9010331404953485501e-2"); + check(-441322590, 273662545, MPFR_RNDZ, "-1.6126525096812205362"); + check(-1631156895, 1677687197, MPFR_RNDU, "-9.722652100563177191e-1"); + check(2141332571, 3117601, MPFR_RNDZ, "6.8685267004982347316e2"); + check(75504803, 400207282, MPFR_RNDU, "1.8866424074712365155e-1"); + check(643562308, 23100894, MPFR_RNDD, "2.7858762002890447462e1"); + check(632549085, 1831935802, MPFR_RNDN, "3.4528998467600230393e-1"); + check (1, 1, MPFR_RNDN, "1.0"); + + check0(); + + check_nan_inf_mpq (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset_si.c b/mpfr/tests/tset_si.c new file mode 100644 index 0000000000..d77e9981ef --- /dev/null +++ b/mpfr/tests/tset_si.c @@ -0,0 +1,464 @@ +/* Test file for mpfr_set_si and mpfr_set_ui. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +#define ERROR(str) {printf("Error for "str"\n"); exit(1);} + +static void +test_2exp (void) +{ + mpfr_t x; + int res; + + mpfr_init2 (x, 32); + + mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN); + if (mpfr_cmp_ui(x, 1)) + ERROR("(1U,0)"); + + mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN); + if (mpfr_cmp_ui(x, 1)) + ERROR("(1024U,-10)"); + + mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN); + if (mpfr_cmp_ui(x, 1024*1024)) + ERROR("(1024U,+10)"); + + mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN); + if (mpfr_cmp_si(x, -1024)) + ERROR("(1M,-10)"); + + mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN); + if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN)) + ERROR("(x92345678U,+16)"); + + mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN); + if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN)) + ERROR("(-x1ABCDEF0,-256)"); + + mpfr_set_prec (x, 2); + res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1<<13) || res <= 0) + ERROR ("Prec 2 + si_2exp"); + + res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU); + if (mpfr_cmp_ui (x, 1<<13) || res <= 0) + ERROR ("Prec 2 + ui_2exp"); + + mpfr_clear_flags (); + mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN); + if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) + ERROR ("mpfr_set_ui_2exp and overflow (bad result)"); + if (!mpfr_overflow_p ()) + ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)"); + + mpfr_clear_flags (); + mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN); + if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) + ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)"); + if (!mpfr_overflow_p ()) + ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)"); + + mpfr_clear_flags (); + mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN); + if (!mpfr_inf_p (x) || MPFR_IS_POS (x)) + ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)"); + if (!mpfr_overflow_p ()) + ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)"); + + mpfr_clear (x); +} + +static void +test_macros (void) +{ + mpfr_t x[3]; + mpfr_ptr p; + int r; + + mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0); + p = x[0]; + r = 0; + mpfr_set_ui (p++, 0, (mpfr_rnd_t) r++); + if (p != x[1] || r != 1) + { + printf ("Error in mpfr_set_ui macro: p - x[0] = %d (expecting 1), " + "r = %d (expecting 1)\n", (int) (p - x[0]), r); + exit (1); + } + p = x[0]; + r = 0; + mpfr_set_si (p++, 0, (mpfr_rnd_t) r++); + if (p != x[1] || r != 1) + { + printf ("Error in mpfr_set_si macro: p - x[0] = %d (expecting 1), " + "r = %d (expecting 1)\n", (int) (p - x[0]), r); + exit (1); + } + mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0); +} + +static void +test_macros_keyword (void) +{ + mpfr_t x; + unsigned long i; + + mpfr_init2 (x, 64); +#define MKN 0x1000000 +#define long short + mpfr_set_ui (x, MKN, MPFR_RNDN); +#undef long + i = mpfr_get_ui (x, MPFR_RNDN); + if (i != MKN) + { + printf ("Error in test_macros_keyword: expected 0x%lx, got 0x%lx.\n", + (unsigned long) MKN, i); + exit (1); + } + mpfr_clear (x); +} + +/* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to + have all tests examine the bits in mpfr_t for what should come out. */ + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + long k, z, d, N; + unsigned long zl, dl; + int inex; + int r; + mpfr_exp_t emin, emax; + int flag; + + tests_start_mpfr (); + + mpfr_init2 (x, 100); + + N = (argc==1) ? 100000 : atol (argv[1]); + + for (k = 1; k <= N; k++) + { + z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2; + inex = mpfr_set_si (x, z, MPFR_RNDZ); + d = mpfr_get_si (x, MPFR_RNDZ); + if (d != z) + { + printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d); + exit (1); + } + if (inex) + { + printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n", + z, inex); + exit (1); + } + } + + for (k = 1; k <= N; k++) + { + zl = randlimb (); + inex = mpfr_set_ui (x, zl, MPFR_RNDZ); + dl = mpfr_get_ui (x, MPFR_RNDZ); + if (dl != zl) + { + printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl); + exit (1); + } + if (inex) + { + printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n", + zl, inex); + exit (1); + } + } + + mpfr_set_prec (x, 2); + if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0) + { + printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0) + { + printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n"); + exit (1); + } + + mpfr_set_prec (x, 3); + inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */ + if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1)) + || inex >= 0) + { + printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n"); + mpfr_print_binary (x); + puts (""); + exit (1); + } + inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */ + if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1)) + || inex >= 0) + { + printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n"); + mpfr_print_binary (x); + puts (""); + exit (1); + } + + mpfr_set_prec (x, 2); + inex = mpfr_set_si (x, 33096, MPFR_RNDU); + if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0) + { + printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n", + mpfr_get_si (x, MPFR_RNDZ), inex); + exit (1); + } + inex = mpfr_set_ui (x, 33096, MPFR_RNDU); + if (mpfr_get_si (x, MPFR_RNDZ) != 49152) + { + printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n", + mpfr_get_si (x, MPFR_RNDZ), inex); + exit (1); + } + /* Also test the mpfr_set_ui function (instead of macro). */ + inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU); + if (mpfr_get_si (x, MPFR_RNDZ) != 49152) + { + printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n", + mpfr_get_si (x, MPFR_RNDZ), inex); + exit (1); + } + + for (r = 0 ; r < MPFR_RND_MAX ; r++) + { + mpfr_set_si (x, -1, (mpfr_rnd_t) r); + mpfr_set_ui (x, 0, (mpfr_rnd_t) r); + if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0) + { + printf ("mpfr_set_ui (x, 0) gives -0 for %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + + mpfr_set_si (x, -1, (mpfr_rnd_t) r); + mpfr_set_si (x, 0, (mpfr_rnd_t) r); + if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0) + { + printf ("mpfr_set_si (x, 0) gives -0 for %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + + /* check potential bug in case mp_limb_t is unsigned */ + emax = mpfr_get_emax (); + set_emax (0); + mpfr_set_si (x, -1, MPFR_RNDN); + if (mpfr_sgn (x) >= 0) + { + printf ("mpfr_set_si (x, -1) fails\n"); + exit (1); + } + set_emax (emax); + + emax = mpfr_get_emax (); + set_emax (5); + mpfr_set_prec (x, 2); + mpfr_set_si (x, -31, MPFR_RNDN); + if (mpfr_sgn (x) >= 0) + { + printf ("mpfr_set_si (x, -31) fails\n"); + exit (1); + } + set_emax (emax); + + /* test for get_ui */ + mpfr_set_ui (x, 0, MPFR_RNDN); + MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0); + mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU); + mpfr_nextabove (x); + mpfr_get_ui (x, MPFR_RNDU); + + /* another test for get_ui */ + mpfr_set_prec (x, 10); + mpfr_set_str_binary (x, "10.101"); + dl = mpfr_get_ui (x, MPFR_RNDN); + MPFR_ASSERTN (dl == 3); + + mpfr_set_str_binary (x, "-1.0"); + mpfr_get_ui (x, MPFR_RNDN); + + mpfr_set_str_binary (x, "0.1"); + dl = mpfr_get_ui (x, MPFR_RNDN); + MPFR_ASSERTN (dl == 0); + dl = mpfr_get_ui (x, MPFR_RNDZ); + MPFR_ASSERTN (dl == 0); + dl = mpfr_get_ui (x, MPFR_RNDD); + MPFR_ASSERTN (dl == 0); + dl = mpfr_get_ui (x, MPFR_RNDU); + MPFR_ASSERTN (dl == 1); + + /* coverage tests */ + mpfr_set_prec (x, 2); + mpfr_set_si (x, -7, MPFR_RNDD); + MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0); + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 7, MPFR_RNDU); + MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0); + emax = mpfr_get_emax (); + set_emax (3); + mpfr_set_ui (x, 7, MPFR_RNDU); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + set_emax (1); + MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) ); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + set_emax (emax); + mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN); + MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0); + MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0); + + /* Test for ERANGE flag + correct behaviour if overflow */ + mpfr_set_prec (x, 256); + mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN); + mpfr_clear_erangeflag (); + dl = mpfr_get_ui (x, MPFR_RNDN); + if (dl != ULONG_MAX || mpfr_erangeflag_p ()) + { + printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n"); + exit (1); + } + mpfr_add_ui (x, x, 1, MPFR_RNDN); + dl = mpfr_get_ui (x, MPFR_RNDN); + if (dl != ULONG_MAX || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n"); + exit (1); + } + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_clear_erangeflag (); + dl = mpfr_get_ui (x, MPFR_RNDN); + if (dl != 0 || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_ui + ERANGE + -1 \n"); + exit (1); + } + mpfr_set_si (x, LONG_MAX, MPFR_RNDN); + mpfr_clear_erangeflag (); + d = mpfr_get_si (x, MPFR_RNDN); + if (d != LONG_MAX || mpfr_erangeflag_p ()) + { + printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d); + exit (1); + } + mpfr_add_ui (x, x, 1, MPFR_RNDN); + d = mpfr_get_si (x, MPFR_RNDN); + if (d != LONG_MAX || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n"); + exit (1); + } + mpfr_set_si (x, LONG_MIN, MPFR_RNDN); + mpfr_clear_erangeflag (); + d = mpfr_get_si (x, MPFR_RNDN); + if (d != LONG_MIN || mpfr_erangeflag_p ()) + { + printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n"); + exit (1); + } + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + d = mpfr_get_si (x, MPFR_RNDN); + if (d != LONG_MIN || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n"); + exit (1); + } + + mpfr_set_nan (x); + mpfr_clear_erangeflag (); + d = mpfr_get_ui (x, MPFR_RNDN); + if (d != 0 || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_ui + NaN\n"); + exit (1); + } + mpfr_clear_erangeflag (); + d = mpfr_get_si (x, MPFR_RNDN); + if (d != 0 || !mpfr_erangeflag_p ()) + { + printf ("ERROR for get_si + NaN\n"); + exit (1); + } + + emin = mpfr_get_emin (); + mpfr_set_prec (x, 2); + + mpfr_set_emin (4); + mpfr_clear_flags (); + mpfr_set_ui (x, 7, MPFR_RNDU); + flag = mpfr_underflow_p (); + mpfr_set_emin (emin); + if (mpfr_cmp_ui (x, 8) != 0) + { + printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n"); + exit (1); + } + if (flag) + { + printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow " + "with prec = 2, emin = 4\n"); + exit (1); + } + + mpfr_set_emin (4); + mpfr_clear_flags (); + mpfr_set_si (x, -7, MPFR_RNDD); + flag = mpfr_underflow_p (); + mpfr_set_emin (emin); + if (mpfr_cmp_si (x, -8) != 0) + { + printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n"); + exit (1); + } + if (flag) + { + printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow " + "with prec = 2, emin = 4\n"); + exit (1); + } + + mpfr_clear (x); + + test_2exp (); + test_macros (); + test_macros_keyword (); + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset_sj.c b/mpfr/tests/tset_sj.c new file mode 100644 index 0000000000..ac103b3b85 --- /dev/null +++ b/mpfr/tests/tset_sj.c @@ -0,0 +1,195 @@ +/* Test file for + mpfr_set_sj, mpfr_set_uj, mpfr_set_sj_2exp and mpfr_set_uj_2exp. + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" /* for a build within gmp */ +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-intmax.h" +#include "mpfr-test.h" + +#ifndef _MPFR_H_HAVE_INTMAX_T + +int +main (void) +{ + return 77; +} + +#else + +#define ERROR(str) {printf("Error for "str"\n"); exit(1);} + +static int +inexact_sign (int x) +{ + return (x < 0) ? -1 : (x > 0); +} + +static void +check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N) +{ + mpfr_t x, y; + mpfr_prec_t p; + int inex1, inex2, n; + mp_limb_t limb; + + mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0); + + for ( p = pmin ; p < pmax ; p++) + { + mpfr_set_prec (x, p); + mpfr_set_prec (y, p); + for (n = 0 ; n < N ; n++) + { + /* mp_limb_t may be unsigned long long */ + limb = (unsigned long) randlimb (); + inex1 = mpfr_set_uj (x, limb, MPFR_RNDN); + inex2 = mpfr_set_ui (y, limb, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n", + (unsigned long) limb, (unsigned long) p); + printf ("X="); mpfr_dump (x); + printf ("Y="); mpfr_dump (y); + exit (1); + } + if (inexact_sign (inex1) != inexact_sign (inex2)) + { + printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n" + "Inexact1= %d Inexact2= %d\n", + (unsigned long) limb, (unsigned long) p, inex1, inex2); + exit (1); + } + } + } + /* Special case */ + mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT); + inex1 = mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); + if (inex1 != 0 || mpfr_sgn(x) <= 0) + ERROR ("inexact / UINTMAX_MAX"); + inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN); + if (inex1 != 0 || !mpfr_powerof2_raw (x) + || MPFR_EXP (x) != (sizeof(uintmax_t)*CHAR_BIT+1) ) + ERROR ("power of 2"); + mpfr_set_uj (x, 0, MPFR_RNDN); + if (!MPFR_IS_ZERO (x)) + ERROR ("Setting 0"); + + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +static void +check_set_uj_2exp (void) +{ + mpfr_t x; + int inex; + + mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT); + + inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN); + if (inex || mpfr_cmp_ui(x, 1)) + ERROR("(1U,0)"); + + inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN); + if (inex || mpfr_cmp_ui(x, 1)) + ERROR("(1024U,-10)"); + + inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN); + if (inex || mpfr_cmp_ui(x, 1024L * 1024L)) + ERROR("(1024U,+10)"); + + inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, 1000, MPFR_RNDN); + inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN); + inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN); + if (inex || !mpfr_powerof2_raw (x) + || MPFR_EXP (x) != (sizeof(uintmax_t)*CHAR_BIT+1) ) + ERROR("(UINTMAX_MAX)"); + + inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN); + if (inex == 0 || !mpfr_inf_p (x)) + ERROR ("Overflow"); + + inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN); + if (inex == 0 || !MPFR_IS_ZERO (x)) + ERROR ("Underflow"); + + mpfr_clear (x); +} + +static void +check_set_sj (void) +{ + mpfr_t x; + int inex; + + mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1); + + inex = mpfr_set_sj (x, -MPFR_INTMAX_MAX, MPFR_RNDN); + inex |= mpfr_add_si (x, x, -1, MPFR_RNDN); + if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x) + || MPFR_EXP (x) != (sizeof(intmax_t)*CHAR_BIT) ) + ERROR("set_sj (-INTMAX_MAX)"); + + inex = mpfr_set_sj (x, 1742, MPFR_RNDN); + if (inex || mpfr_cmp_ui (x, 1742)) + ERROR ("set_sj (1742)"); + + mpfr_clear (x); +} + +static void +check_set_sj_2exp (void) +{ + mpfr_t x; + int inex; + + mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1); + + inex = mpfr_set_sj_2exp (x, MPFR_INTMAX_MIN, 1000, MPFR_RNDN); + if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x) + || MPFR_EXP (x) != (sizeof(intmax_t)*CHAR_BIT+1000) ) + ERROR("set_sj_2exp (INTMAX_MIN)"); + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_set_uj (2, 128, 50); + check_set_uj_2exp (); + check_set_sj (); + check_set_sj_2exp (); + + tests_end_mpfr (); + return 0; +} + +#endif diff --git a/mpfr/tests/tset_str.c b/mpfr/tests/tset_str.c new file mode 100644 index 0000000000..b5883cd72e --- /dev/null +++ b/mpfr/tests/tset_str.c @@ -0,0 +1,870 @@ +/* Test file for mpfr_set_str. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +#define N 30000 + +#define CHECK53(y, s, r, x, t, n) \ + mpfr_set_str (y, s, 10, r); \ + mpfr_set_str_binary (x, t); \ + if (mpfr_cmp (x, y)) \ + { \ + printf ("Error in mpfr_set_str (%d):\n", n); \ + mpfr_print_binary (x); \ + puts (""); \ + mpfr_print_binary (y); \ + puts (""); \ + mpfr_clear (x); \ + mpfr_clear (y); \ + exit (1); \ + } + +static void +check_underflow (void) +{ + mpfr_t a; + mpfr_exp_t emin, emax; + int res; + + mpfr_init (a); + + /* Check underflow */ + emin = mpfr_get_emin (); + set_emin (-20); + res = mpfr_set_str (a, "0.00000000001", 10, MPFR_RNDZ); + if (!MPFR_IS_ZERO (a)) + { + printf("ERROR for mpfr_set_str (a, \"0.00000000001\", 10, MPFR_RNDN)\n" + " with emin=-20\n" + "res=%d\n", res); + mpfr_dump (a); + exit (1); + } + set_emin (emin); + + /* check overflow */ + emax = mpfr_get_emax (); + set_emax (1073741823); /* 2^30-1 */ + mpfr_set_str (a, "2E1000000000", 10, MPFR_RNDN); + if (!mpfr_inf_p (a) || mpfr_sgn (a) < 0) + { + printf("ERROR for mpfr_set_str (a, \"2E1000000000\", 10, MPFR_RNDN);\n"); + exit (1); + } + set_emax (emax); + + mpfr_clear (a); +} + +/* Bug found by Christoph Lauter. */ +static void +bug20081028 (void) +{ + mpfr_t x; + const char *s = "0.10000000000000000000000000000001E1"; + + mpfr_init2 (x, 32); + mpfr_set_str (x, "1.00000000000000000006", 10, MPFR_RNDU); + if (! mpfr_greater_p (x, __gmpfr_one)) + { + printf ("Error in bug20081028:\nExpected %s\nGot ", s); + mpfr_dump (x); + exit (1); + } + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + unsigned long k, bd, nc, i; + char *str, *str2; + mpfr_exp_t e; + int base, logbase, prec, baseprec, ret, obase; + + tests_start_mpfr (); + + if (argc >= 2) /* tset_str <string> [<prec>] [<ibase>] [<obase>] */ + { + prec = (argc >= 3) ? atoi (argv[2]) : 53; + base = (argc >= 4) ? atoi (argv[3]) : 2; + obase = (argc >= 5) ? atoi (argv[4]) : 10; + mpfr_init2 (x, prec); + mpfr_set_str (x, argv[1], base, MPFR_RNDN); + mpfr_out_str (stdout, obase, 0, x, MPFR_RNDN); + puts (""); + mpfr_clear (x); + return 0; + } + + mpfr_init2 (x, 2); + + nc = (argc > 1) ? atoi(argv[1]) : 53; + if (nc < 100) + nc = 100; + + bd = randlimb () & 8; + + str2 = str = (char*) tests_allocate (nc); + + if (bd) + { + for(k = 1; k <= bd; k++) + *(str2++) = (randlimb () & 1) + '0'; + } + else + *(str2++) = '0'; + + *(str2++) = '.'; + + for (k = 1; k < nc - 17 - bd; k++) + *(str2++) = '0' + (char) (randlimb () & 1); + + *(str2++) = 'e'; + sprintf (str2, "%d", (int) (randlimb () & INT_MAX) + INT_MIN/2); + + mpfr_set_prec (x, nc + 10); + mpfr_set_str_binary (x, str); + + mpfr_set_prec (x, 54); + mpfr_set_str_binary (x, "0.100100100110110101001010010101111000001011100100101010E-529"); + mpfr_init2 (y, 54); + mpfr_set_str (y, "4.936a52bc17254@-133", 16, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (1a):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str_binary (x, "0.111111101101110010111010100110000111011001010100001101E-529"); + mpfr_set_str (y, "0.fedcba98765434P-529", 16, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (1b):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + tests_free (str, nc); + + mpfr_set_prec (x, 53); + mpfr_set_str_binary (x, "+110101100.01010000101101000000100111001000101011101110E00"); + + mpfr_set_str_binary (x, "1.0"); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_set_str_binary for s=1.0\n"); + mpfr_clear(x); + mpfr_clear(y); + exit(1); + } + + mpfr_set_str_binary (x, "+0000"); + mpfr_set_str_binary (x, "+0000E0"); + mpfr_set_str_binary (x, "0000E0"); + if (mpfr_cmp_ui (x, 0)) + { + printf ("Error in mpfr_set_str_binary for s=0.0\n"); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (x, "+243495834958.53452345E1", 10, MPFR_RNDN); + mpfr_set_str (x, "9007199254740993", 10, MPFR_RNDN); + mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDU); + mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDD); + mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDZ); + + /* check a random number printed and read is not modified */ + prec = 53; + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + for (i=0;i<N;i++) + { + mpfr_rnd_t rnd; + + mpfr_urandomb (x, RANDS); + rnd = RND_RAND (); + logbase = (randlimb () % 5) + 1; + base = 1 << logbase; + /* Warning: the number of bits needed to print exactly a number of + 'prec' bits in base 2^logbase may be greater than ceil(prec/logbase), + for example 0.11E-1 in base 2 cannot be written exactly with only + one digit in base 4 */ + if (base == 2) + baseprec = prec; + else + baseprec = 1 + (prec - 2 + logbase) / logbase; + str = mpfr_get_str (NULL, &e, base, baseprec, x, rnd); + mpfr_set_str (y, str, base, rnd); + MPFR_EXP(y) += logbase * (e - strlen (str)); + if (mpfr_cmp (x, y)) + { + printf ("mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n", + mpfr_print_rnd_mode (rnd)); + printf ("x="); + mpfr_print_binary (x); + puts (""); + printf ("s=%s, exp=%d, base=%d\n", str, (int) e, base); + printf ("y="); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + mpfr_free_str (str); + } + + for (i = 2; i <= 62; i++) + { + if (mpfr_set_str (x, "@NaN@(garbage)", i, MPFR_RNDN) != 0 || + !mpfr_nan_p(x)) + { + printf ("mpfr_set_str failed on @NaN@(garbage)\n"); + exit (1); + } + + /* + if (mpfr_set_str (x, "@Inf@garbage", i, MPFR_RNDN) != 0 || + !mpfr_inf_p(x) || MPFR_SIGN(x) < 0) + { + printf ("mpfr_set_str failed on @Inf@garbage\n"); + exit (1); + } + + if (mpfr_set_str (x, "-@Inf@garbage", i, MPFR_RNDN) != 0 || + !mpfr_inf_p(x) || MPFR_SIGN(x) > 0) + { + printf ("mpfr_set_str failed on -@Inf@garbage\n"); + exit (1); + } + + if (mpfr_set_str (x, "+@Inf@garbage", i, MPFR_RNDN) != 0 || + !mpfr_inf_p(x) || MPFR_SIGN(x) < 0) + { + printf ("mpfr_set_str failed on +@Inf@garbage\n"); + exit (1); + } + */ + + if (i > 16) + continue; + + if (mpfr_set_str (x, "NaN", i, MPFR_RNDN) != 0 || + !mpfr_nan_p(x)) + { + printf ("mpfr_set_str failed on NaN\n"); + exit (1); + } + + if (mpfr_set_str (x, "Inf", i, MPFR_RNDN) != 0 || + !mpfr_inf_p(x) || MPFR_SIGN(x) < 0) + { + printf ("mpfr_set_str failed on Inf\n"); + exit (1); + } + + if (mpfr_set_str (x, "-Inf", i, MPFR_RNDN) != 0 || + !mpfr_inf_p(x) || MPFR_SIGN(x) > 0) + { + printf ("mpfr_set_str failed on -Inf\n"); + exit (1); + } + + if (mpfr_set_str (x, "+Inf", i, MPFR_RNDN) != 0 || + !mpfr_inf_p(x) || MPFR_SIGN(x) < 0) + { + printf ("mpfr_set_str failed on +Inf\n"); + exit (1); + } + } + + /* check that mpfr_set_str works for uppercase letters too */ + mpfr_set_prec (x, 10); + mpfr_set_str (x, "B", 16, MPFR_RNDN); + if (mpfr_cmp_ui (x, 11) != 0) + { + printf ("mpfr_set_str does not work for uppercase letters\n"); + exit (1); + } + + /* start of tests added by Alain Delplanque */ + + /* in this example an overflow can occur */ + mpfr_set_prec (x, 64); + mpfr_set_prec (y, 64); + mpfr_set_str_binary (x, "1.0E-532"); + mpfr_set_str (y, "0.71128279983522479470@-160", 10, MPFR_RNDU); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (2):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + /* in this example, I think there was a pb in the old function : + result of mpfr_set_str_old for the same number , but with more + precision is: 1.111111111110000000000000000111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100111000100001100000010101100111010e184 + this result is the same as mpfr_set_str */ + mpfr_set_prec (x, 64); + mpfr_set_prec (y, 64); + mpfr_set_str_binary (x, "1.111111111110000000000000000111111111111111111111111110000000001E184"); + mpfr_set_str (y, "0.jo08hg31hc5mmpj5mjjmgn55p2h35g@39", 27, MPFR_RNDU); + /* y = 49027884868983130654865109690613178467841148597221480052 */ + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (3):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + /* not exact rounding in mpfr_set_str + same number with more precision is : 1.111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011011111101000001101110110010101101000010100110011101110010001110e195 + this result is the same as mpfr_set_str */ + /* problem was : can_round was call with MPFR_RNDN round mode, + so can_round use an error : 1/2 * 2^err * ulp(y) + instead of 2^err * ulp(y) + I have increase err by 1 */ + mpfr_set_prec (x, 64); /* it was round down instead of up */ + mpfr_set_prec (y, 64); + mpfr_set_str_binary (x, "1.111111111111111111111111111000000000000000000000000000000000001e195"); + mpfr_set_str (y, "0.6e23ekb6acgh96abk10b6c9f2ka16i@45", 21, MPFR_RNDU); + /* y = 100433627392042473064661483711179345482301462325708736552078 */ + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (4):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + /* may be an error in mpfr_set_str_old + with more precision : 1.111111100000001111110000000000011111011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110111101010001110111011000010111001011100110110e180 */ + mpfr_set_prec (x, 64); /* it was round down instead of up */ + mpfr_set_prec (y, 64); + mpfr_set_str_binary (x, "1.111111100000001111110000000000011111011111111111111111111111111e180"); + mpfr_set_str (y, "0.10j8j2k82ehahha56390df0a1de030@41", 23, MPFR_RNDZ); + /* y = 3053110535624388280648330929253842828159081875986159414 */ + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (5):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_prec (x, 64); + mpfr_set_prec (y, 64); + mpfr_set_str (y, "0.jrchfhpp9en7hidqm9bmcofid9q3jg@39", 28, MPFR_RNDU); + /* y = 196159429139499688661464718784226062699788036696626429952 */ + mpfr_set_str_binary (x, "0.1111111111111111111111111111111000000000000011100000001111100001E187"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (6):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_prec (x, 64); + mpfr_set_prec (y, 64); + mpfr_set_str (y, "0.h148m5ld5cf8gk1kd70b6ege92g6ba@47", 24, MPFR_RNDZ); + /* y = 52652933527468502324759448399183654588831274530295083078827114496 */ + mpfr_set_str_binary (x, "0.1111111111111100000000001000000000000000000011111111111111101111E215"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (7):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + /* worst cases for rounding to nearest in double precision */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_str (y, "5e125", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10111101000101110110011000100000101001010000000111111E418"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (8):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "69e267", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10000101101111100101101100000110010011001010011011010E894"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (9):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "623e100", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10110010000001010011000101111001110101000001111011111E342"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (10):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "3571e263", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10110001001100100010011000110000111010100000110101010E886"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (11):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "75569e-254", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10101101001000110001011011001000111000110101010110011E-827"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (12):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "920657e-23", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10101001110101001100110000101110110111101111001101100E-56"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (13):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "9210917e80", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.11101101000100011001000110100011111100110000000110010E289"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (14):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "87575437e-309", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.11110000001110011001000000110000000100000010101101100E-1000"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (15):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "245540327e122", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E434"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (16):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "491080654e122", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E435"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (17):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (y, "83356057653e193", 10, MPFR_RNDN); + mpfr_set_str_binary (x, "0.10101010001001110011011011010111011100010101000011000E678"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_str (18):\n"); + mpfr_print_binary (x); + puts (""); + mpfr_print_binary (y); + puts (""); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + CHECK53(y, "83356057653e193", MPFR_RNDN, x, + "0.10101010001001110011011011010111011100010101000011000E678", + 18); + + CHECK53(y, "619534293513e124", MPFR_RNDN, x, + "0.10001000011000010000000110000001111111110000011110001e452", + 19); + + CHECK53(y, "3142213164987e-294", MPFR_RNDN, x, + "0.11101001101000000100111011111101111001010001001101111e-935", + 20); + + CHECK53(y, "36167929443327e-159", MPFR_RNDN, x, + "0.11100111001110111110000101011001100110010100011111100e-483", + 21); + + CHECK53(y, "904198236083175e-161", MPFR_RNDN, x, + "0.11100111001110111110000101011001100110010100011111100e-485", + 22); + + CHECK53(y, "3743626360493413e-165", MPFR_RNDN, x, + "0.11000100000100011101001010111101011011011111011111001e-496", + 23); + + CHECK53(y, "94080055902682397e-242", MPFR_RNDN, x, + "0.10110010010011000000111100011100111100110011011001010e-747", + 24); + + CHECK53(y, "7e-303", MPFR_RNDD, x, + "0.10011001100111001000100110001110001000110111110001011e-1003", + 25); + CHECK53(y, "7e-303", MPFR_RNDU, x, + "0.10011001100111001000100110001110001000110111110001100e-1003", + 26); + + CHECK53(y, "93e-234", MPFR_RNDD, x, + "0.10010011110110010111001001111001000010000000001110101E-770", + 27); + CHECK53(y, "93e-234", MPFR_RNDU, x, + "0.10010011110110010111001001111001000010000000001110110E-770", + 28); + + CHECK53(y, "755e174", MPFR_RNDD, x, + "0.10111110110010011000110010011111101111000111111000101E588", + 29); + CHECK53(y, "755e174", MPFR_RNDU, x, + "0.10111110110010011000110010011111101111000111111000110E588", + 30); + + CHECK53(y, "8699e-276", MPFR_RNDD, x, + "0.10010110100101101111100100100011011101100110100101100E-903", + 31); + CHECK53(y, "8699e-276", MPFR_RNDU, x, + "0.10010110100101101111100100100011011101100110100101101E-903", + 32); + + CHECK53(y, "82081e41", MPFR_RNDD, x, + "0.10111000000010000010111011111001111010100011111001011E153", + 33); + CHECK53(y, "82081e41", MPFR_RNDU, x, + "0.10111000000010000010111011111001111010100011111001100E153", + 34); + + CHECK53(y, "584169e229", MPFR_RNDD, x, + "0.11101011001010111000001011001110111000111100110101010E780", + 35); + CHECK53(y, "584169e229", MPFR_RNDU, x, + "0.11101011001010111000001011001110111000111100110101011E780", + 36); + + CHECK53(y, "5783893e-128", MPFR_RNDD, x, + "0.10011000111100000110011110000101100111110011101110100E-402", + 37); + CHECK53(y, "5783893e-128", MPFR_RNDU, x, + "0.10011000111100000110011110000101100111110011101110101E-402", + 38); + + CHECK53(y, "87575437e-310", MPFR_RNDD, x, + "0.11000000001011100000110011110011010000000010001010110E-1003", + 39); + CHECK53(y, "87575437e-310", MPFR_RNDU, x, + "0.11000000001011100000110011110011010000000010001010111E-1003", + 40); + + CHECK53(y, "245540327e121", MPFR_RNDD, x, + "0.11100010101101001111010010110100011100000100101000100E430", + 41); + CHECK53(y, "245540327e121", MPFR_RNDU, x, + "0.11100010101101001111010010110100011100000100101000101E430", + 42); + + CHECK53(y, "9078555839e-109", MPFR_RNDD, x, + "0.11111110001010111010110000110011100110001010011101101E-329", + 43); + CHECK53(y, "9078555839e-109", MPFR_RNDU, x, + "0.11111110001010111010110000110011100110001010011101110E-329", + 44); + + CHECK53(y, "42333842451e201", MPFR_RNDD, x, + "0.10000000110001001101000100110110111110101011101011111E704", + 45); + CHECK53(y, "42333842451e201", MPFR_RNDU, x, + "0.10000000110001001101000100110110111110101011101100000E704", + 46); + + CHECK53(y, "778380362293e218", MPFR_RNDD, x, + "0.11001101010111000001001100001100110010000001010010010E764", + 47); + CHECK53(y, "778380362293e218", MPFR_RNDU, x, + "0.11001101010111000001001100001100110010000001010010011E764", + 48); + + CHECK53(y, "7812878489261e-179", MPFR_RNDD, x, + "0.10010011011011010111001111011101111101101101001110100E-551", + 49); + CHECK53(y, "7812878489261e-179", MPFR_RNDU, x, + "0.10010011011011010111001111011101111101101101001110101E-551", + 50); + + CHECK53(y, "77003665618895e-73", MPFR_RNDD, x, + "0.11000101111110111111001111111101001101111000000101001E-196", + 51); + CHECK53(y, "77003665618895e-73", MPFR_RNDU, x, + "0.11000101111110111111001111111101001101111000000101010E-196", + 52); + + CHECK53(y, "834735494917063e-300", MPFR_RNDD, x, + "0.11111110001101100001001101111100010011001110111010001E-947", + 53); + CHECK53(y, "834735494917063e-300", MPFR_RNDU, x, + "0.11111110001101100001001101111100010011001110111010010E-947", + 54); + + CHECK53(y, "6182410494241627e-119", MPFR_RNDD, x, + "0.10001101110010110010001011000010001000101110100000111E-342", + 55); + CHECK53(y, "6182410494241627e-119", MPFR_RNDU, x, + "0.10001101110010110010001011000010001000101110100001000E-342", + 56); + + CHECK53(y, "26153245263757307e49", MPFR_RNDD, x, + "0.10011110111100000000001011011110101100010000011011110E218", + 57); + CHECK53(y, "26153245263757307e49", MPFR_RNDU, x, + "0.10011110111100000000001011011110101100010000011011111E218", + 58); + + /* to check this problem : I convert limb (10--0 or 101--1) into base b + with more than mp_bits_per_limb digits, + so when convert into base 2 I should have + the limb that I have choose */ + /* this use mpfr_get_str */ + { + size_t nb_digit = mp_bits_per_limb; + mp_limb_t check_limb[2] = {MPFR_LIMB_HIGHBIT, ~(MPFR_LIMB_HIGHBIT >> 1)}; + int base[3] = {10, 16, 19}; + mpfr_rnd_t rnd[3] = {MPFR_RNDU, MPFR_RNDN, MPFR_RNDD}; + int cbase, climb, crnd; + char *str; + + mpfr_set_prec (x, mp_bits_per_limb); /* x and y have only one limb */ + mpfr_set_prec (y, mp_bits_per_limb); + + str = (char *) tests_allocate (N + 20); + + mpfr_set_ui (x, 1, MPFR_RNDN); /* ensures that x is not NaN or Inf */ + for (; nb_digit < N; nb_digit *= 10) + for (cbase = 0; cbase < 3; cbase++) + for (climb = 0; climb < 2; climb++) + for (crnd = 0; crnd < 3; crnd++) + { + char *str1; + mpfr_exp_t exp; + + *(MPFR_MANT(x)) = check_limb[climb]; + MPFR_EXP(x) = 0; + + mpfr_get_str (str + 2, &exp, base[cbase], + nb_digit, x, rnd[crnd]); + str[0] = '-'; + str[(str[2] == '-')] = '0'; + str[(str[2] == '-') + 1] = '.'; + + for (str1 = str; *str1 != 0; str1++) + ; + sprintf (str1, "@%i", (int) exp); + + mpfr_set_str (y, str, base[cbase], rnd[2 - crnd]); + + if (mpfr_cmp (x, y) != 0) + { + printf ("Error in mpfr_set_str for nb_digit=%u, base=%d, " + "rnd=%s:\n", (unsigned int) nb_digit, base[cbase], + mpfr_print_rnd_mode (rnd[crnd])); + printf ("instead of: "); + mpfr_print_binary (x); + puts (""); + printf ("return : "); + mpfr_print_binary (y); + puts (""); + exit (1); + } + } + + tests_free (str, N + 20); + } + + /* end of tests added by Alain Delplanque */ + + /* check that flags are correctly cleared */ + mpfr_set_nan (x); + mpfr_set_str (x, "+0.0", 10, MPFR_RNDN); + if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) < 0) + { + printf ("x <- +0.0 failed after x=NaN\n"); + exit (1); + } + mpfr_set_str (x, "-0.0", 10, MPFR_RNDN); + if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) > 0) + { + printf ("x <- -0.0 failed after x=NaN\n"); + exit (1); + } + + /* check invalid input */ + ret = mpfr_set_str (x, "1E10toto", 10, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + ret = mpfr_set_str (x, "1p10toto", 16, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + ret = mpfr_set_str (x, "", 16, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + ret = mpfr_set_str (x, "+", 16, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + ret = mpfr_set_str (x, "-", 16, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + ret = mpfr_set_str (x, "this_is_an_invalid_number_in_base_36", 36, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + ret = mpfr_set_str (x, "1.2.3", 10, MPFR_RNDN); + MPFR_ASSERTN (ret == -1); + mpfr_set_prec (x, 135); + ret = mpfr_set_str (x, "thisisavalidnumberinbase36", 36, MPFR_RNDN); + mpfr_set_prec (y, 135); + mpfr_set_str (y, "23833565676460972739462619524519814462546", 10, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp (x, y) == 0 && ret == 0); + + /* coverage test for set_str_binary */ + mpfr_set_str_binary (x, "NaN"); + MPFR_ASSERTN(mpfr_nan_p (x)); + mpfr_set_str_binary (x, "Inf"); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + mpfr_set_str_binary (x, "+Inf"); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + mpfr_set_str_binary (x, "-Inf"); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); + mpfr_set_prec (x, 3); + mpfr_set_str_binary (x, "0.01E2"); + MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0); + mpfr_set_str_binary (x, "-0.01E2"); + MPFR_ASSERTN(mpfr_cmp_si (x, -1) == 0); + + mpfr_clear (x); + mpfr_clear (y); + + check_underflow (); + bug20081028 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tset_z.c b/mpfr/tests/tset_z.c new file mode 100644 index 0000000000..321566fe95 --- /dev/null +++ b/mpfr/tests/tset_z.c @@ -0,0 +1,142 @@ +/* Test file for mpfr_set_z. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +static void check0(void) +{ + mpz_t y; + mpfr_t x; + int inexact, r; + + /* Check for +0 */ + mpfr_init (x); + mpz_init (y); + mpz_set_si (y, 0); + for(r = 0; r < MPFR_RND_MAX; r++) + { + inexact = mpfr_set_z (x, y, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact) + { + printf("mpfr_set_z(x,0) failed for %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit(1); + } + } + mpfr_clear(x); + mpz_clear(y); +} + +/* FIXME: It'd be better to examine the actual data in an mpfr_t to see that + it's as expected. Comparing mpfr_set_z with mpfr_cmp or against + mpfr_get_si is a rather indirect test of a low level routine. */ + +static void +check (long i, mpfr_rnd_t rnd) +{ + mpfr_t f; + mpz_t z; + + mpfr_init2 (f, 8 * sizeof(long)); + mpz_init (z); + mpz_set_ui (z, i); + mpfr_set_z (f, z, rnd); + if (mpfr_get_si (f, MPFR_RNDZ) != i) + { + printf ("Error in mpfr_set_z for i=%ld rnd_mode=%d\n", i, rnd); + exit (1); + } + mpfr_clear (f); + mpz_clear (z); +} + +static void +check_large (void) +{ + mpz_t z; + mpfr_t x, y; + mpfr_exp_t emax, emin; + + mpz_init (z); + mpfr_init2 (x, 160); + mpfr_init2 (y, 160); + + mpz_set_str (z, "77031627725494291259359895954016675357279104942148788042", 10); + mpfr_set_z (x, z, MPFR_RNDN); + mpfr_set_str_binary (y, "0.1100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001001E186"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_set_z on large input\n"); + exit (1); + } + + /* check overflow */ + emax = mpfr_get_emax (); + set_emax (2); + mpz_set_str (z, "7", 10); + mpfr_set_z (x, z, MPFR_RNDU); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + set_emax (3); + mpfr_set_prec (x, 2); + mpz_set_str (z, "7", 10); + mpfr_set_z (x, z, MPFR_RNDU); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + set_emax (emax); + + /* check underflow */ + emin = mpfr_get_emin (); + set_emin (3); + mpz_set_str (z, "1", 10); + mpfr_set_z (x, z, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + set_emin (2); + mpfr_set_z (x, z, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); + set_emin (emin); + + mpz_clear (z); + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + long j; + + tests_start_mpfr (); + + check_large (); + check (0, MPFR_RNDN); + for (j = 0; j < 200000; j++) + check (randlimb () & LONG_MAX, RND_RAND ()); + check0 (); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tset_z_exp.c b/mpfr/tests/tset_z_exp.c new file mode 100644 index 0000000000..05e5461a57 --- /dev/null +++ b/mpfr/tests/tset_z_exp.c @@ -0,0 +1,132 @@ +/* Test file for mpfr_set_z_2exp. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +static mpfr_exp_t +randexp (void) +{ + return (mpfr_exp_t) (randlimb () % (__gmpfr_emax - __gmpfr_emin)) + + __gmpfr_emin; +} + +static void +check0 (void) +{ + mpz_t y; + mpfr_t x; + int inexact, r; + mpfr_exp_t e; + + /* Check for +0 */ + mpfr_init (x); + mpz_init (y); + mpz_set_si (y, 0); + for (r = 0; r < MPFR_RND_MAX; r++) + { + e = randexp (); + inexact = mpfr_set_z_2exp (x, y, e, (mpfr_rnd_t) r); + if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact) + { + printf ("mpfr_set_z_2exp(x,0,e) failed for e="); + if (e < LONG_MIN) + printf ("(<LONG_MIN)"); + else if (e > LONG_MAX) + printf ("(>LONG_MAX)"); + else + printf ("%ld", (long) e); + printf (", rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + exit (1); + } + } + mpfr_clear(x); + mpz_clear(y); +} + +/* FIXME: It'd be better to examine the actual data in an mpfr_t to see that + it's as expected. Comparing mpfr_set_z with mpfr_cmp or against + mpfr_get_si is a rather indirect test of a low level routine. */ + +static void +check (long i, mpfr_rnd_t rnd) +{ + mpfr_t f; + mpz_t z; + mpfr_exp_t e; + int inex; + + /* using CHAR_BIT * sizeof(long) bits of precision ensures that + mpfr_set_z_2exp is exact below */ + mpfr_init2 (f, CHAR_BIT * sizeof(long)); + mpz_init (z); + mpz_set_ui (z, i); + /* the following loop ensures that no overflow occurs */ + do + e = randexp (); + while (e > mpfr_get_emax () - CHAR_BIT * sizeof(long)); + inex = mpfr_set_z_2exp (f, z, e, rnd); + if (inex != 0) + { + printf ("Error in mpfr_set_z_2exp for i=%ld, e=%ld," + " wrong ternary value\n", i, (long) e); + printf ("expected 0, got %d\n", inex); + exit (1); + } + mpfr_div_2si (f, f, e, rnd); + if (mpfr_get_si (f, MPFR_RNDZ) != i) + { + printf ("Error in mpfr_set_z_2exp for i=%ld e=", i); + if (e < LONG_MIN) + printf ("(<LONG_MIN)"); + else if (e > LONG_MAX) + printf ("(>LONG_MAX)"); + else + printf ("%ld", (long) e); + printf (" rnd_mode=%d\n", rnd); + printf ("expected %ld\n", i); + printf ("got "); mpfr_dump (f); + exit (1); + } + mpfr_clear (f); + mpz_clear (z); +} + +int +main (int argc, char *argv[]) +{ + long j; + + tests_start_mpfr (); + + check (0, MPFR_RNDN); + for (j = 0; j < 200000; j++) + check (randlimb () & LONG_MAX, RND_RAND ()); + check0 (); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tsgn.c b/mpfr/tests/tsgn.c new file mode 100644 index 0000000000..b7d208b57b --- /dev/null +++ b/mpfr/tests/tsgn.c @@ -0,0 +1,131 @@ +/* tsgn -- Test for the sign of a floating point number. + +Copyright 2003, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check_special (void) +{ + mpfr_t x; + int ret = 0; + + mpfr_init (x); + MPFR_SET_ZERO (x); + if ((mpfr_sgn) (x) != 0 || mpfr_sgn (x) != 0) + { + printf("Sgn error for 0.\n"); + ret = 1; + } + MPFR_SET_INF (x); + MPFR_SET_POS (x); + if ((mpfr_sgn) (x) != 1 || mpfr_sgn (x) != 1) + { + printf("Sgn error for +Inf.\n"); + ret = 1; + } + MPFR_SET_INF (x); + MPFR_SET_NEG (x); + if ((mpfr_sgn) (x) != -1 || mpfr_sgn (x) != -1) + { + printf("Sgn error for -Inf.\n"); + ret = 1; + } + MPFR_SET_NAN (x); + mpfr_clear_flags (); + if ((mpfr_sgn) (x) != 0 || !mpfr_erangeflag_p ()) + { + printf("Sgn error for NaN.\n"); + ret = 1; + } + mpfr_clear_flags (); + if (mpfr_sgn (x) != 0 || !mpfr_erangeflag_p ()) + { + printf("Sgn error for NaN.\n"); + ret = 1; + } + mpfr_clear (x); + if (ret) + exit (ret); +} + +static void +check_sgn(void) +{ + mpfr_t x; + int i, s1, s2; + + mpfr_init(x); + for(i = 0 ; i < 100 ; i++) + { + mpfr_urandomb (x, RANDS); + if (i&1) + { + MPFR_SET_POS(x); + s2 = 1; + } + else + { + MPFR_SET_NEG(x); + s2 = -1; + } + s1 = mpfr_sgn(x); + if (s1 < -1 || s1 > 1) + { + printf("Error for sgn: out of range.\n"); + goto lexit; + } + else if (MPFR_IS_NAN(x) || MPFR_IS_ZERO(x)) + { + if (s1 != 0) + { + printf("Error for sgn: Nan or Zero should return 0.\n"); + goto lexit; + } + } + else if (s1 != s2) + { + printf("Error for sgn. Return %d instead of %d.\n", s1, s2); + goto lexit; + } + } + mpfr_clear(x); + return; + + lexit: + mpfr_clear(x); + exit(1); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_special (); + check_sgn (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsi_op.c b/mpfr/tests/tsi_op.c new file mode 100644 index 0000000000..5a84c64126 --- /dev/null +++ b/mpfr/tests/tsi_op.c @@ -0,0 +1,146 @@ +/* Test file for mpfr_add_si, mpfr_sub_si, mpfr_si_sub, mpfr_mul_si, + mpfr_div_si, mpfr_si_div + +Copyright 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define ERROR1(s, i, z, exp) \ +{\ + printf("Error for "s" and i=%d\n", i);\ + printf("Expected %s\n", exp);\ + printf("Got "); mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);\ + putchar ('\n');\ + exit(1);\ +} + +const struct { + const char * op1; + long int op2; + const char * res_add; + const char * res_sub; + const char * res_mul; + const char * res_div; +} tab[] = { + {"10", 0x1, "11", "0F", "10", "10"}, + {"1", -1, "0", "2", "-1", "-1"}, + {"17.42", -0x17, "0.42", "2E.42", "-216.ee", "-1.02de9bd37a6f4"}, + {"-1024.0", -0x16, "-103A", "-100E", "16318", "bb.d1745d1745d0"} +}; + +static void +check_invert (void) +{ + mpfr_t x; + mpfr_init2 (x, MPFR_PREC_MIN); + + mpfr_set_ui (x, 0xC, MPFR_RNDN); + mpfr_si_sub (x, -1, x, MPFR_RNDD); /* -0001 - 1100 = - 1101 --> -1 0000 */ + if (mpfr_cmp_si (x, -0x10) ) + { + printf ("Special rounding error\n"); + exit (1); + } + mpfr_clear (x); +} + +#define TEST_FUNCTION mpfr_add_si +#define TEST_FUNCTION_NAME "mpfr_add_si" +#define INTEGER_TYPE long +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#define test_generic_ui test_generic_add_si +#include "tgeneric_ui.c" + +#define TEST_FUNCTION mpfr_sub_si +#define TEST_FUNCTION_NAME "mpfr_sub_si" +#define INTEGER_TYPE long +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#define test_generic_ui test_generic_sub_si +#include "tgeneric_ui.c" + +#define TEST_FUNCTION mpfr_mul_si +#define TEST_FUNCTION_NAME "mpfr_mul_si" +#define INTEGER_TYPE long +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#define test_generic_ui test_generic_mul_si +#include "tgeneric_ui.c" + +#define TEST_FUNCTION mpfr_div_si +#define TEST_FUNCTION_NAME "mpfr_div_si" +#define INTEGER_TYPE long +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#define test_generic_ui test_generic_div_si +#include "tgeneric_ui.c" + + +int +main (int argc, char *argv[]) +{ + mpfr_t x, z; + int y; + int i; + + tests_start_mpfr (); + mpfr_inits2 (53, x, z, (mpfr_ptr) 0); + for(i = 0 ; i < numberof (tab) ; i++) + { + mpfr_set_str (x, tab[i].op1, 16, MPFR_RNDN); + y = tab[i].op2; + mpfr_add_si (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_str (z, tab[i].res_add, 16, MPFR_RNDN)) + ERROR1("add_si", i, z, tab[i].res_add); + mpfr_sub_si (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_str (z, tab[i].res_sub, 16, MPFR_RNDN)) + ERROR1("sub_si", i, z, tab[i].res_sub); + mpfr_si_sub (z, y, x, MPFR_RNDZ); + mpfr_neg (z, z, MPFR_RNDZ); + if (mpfr_cmp_str (z, tab[i].res_sub, 16, MPFR_RNDN)) + ERROR1("si_sub", i, z, tab[i].res_sub); + mpfr_mul_si (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_str (z, tab[i].res_mul, 16, MPFR_RNDN)) + ERROR1("mul_si", i, z, tab[i].res_mul); + mpfr_div_si (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_str (z, tab[i].res_div, 16, MPFR_RNDN)) + ERROR1("div_si", i, z, tab[i].res_div); + } + mpfr_set_str1 (x, "1"); + mpfr_si_div (z, 1024, x, MPFR_RNDN); + if (mpfr_cmp_str1 (z, "1024")) + ERROR1("si_div", i, z, "1024"); + mpfr_si_div (z, -1024, x, MPFR_RNDN); + if (mpfr_cmp_str1 (z, "-1024")) + ERROR1("si_div", i, z, "-1024"); + + mpfr_clears (x, z, (mpfr_ptr) 0); + + check_invert (); + + test_generic_add_si (2, 200, 17); + test_generic_sub_si (2, 200, 17); + test_generic_mul_si (2, 200, 17); + test_generic_div_si (2, 200, 17); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsin.c b/mpfr/tests/tsin.c new file mode 100644 index 0000000000..7afa57c26c --- /dev/null +++ b/mpfr/tests/tsin.c @@ -0,0 +1,378 @@ +/* Test file for mpfr_sin. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_sin (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_sin (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_sin mpfr_sin +#endif + +static void +check53 (const char *xs, const char *sin_xs, mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, s; + + mpfr_init2 (xx, 53); + mpfr_init2 (s, 53); + mpfr_set_str1 (xx, xs); /* should be exact */ + test_sin (s, xx, rnd_mode); + if (mpfr_cmp_str1 (s, sin_xs)) + { + printf ("mpfr_sin failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode (rnd_mode)); + printf ("mpfr_sin gives sin(x)="); + mpfr_out_str (stdout, 10, 0, s, MPFR_RNDN); + printf (", expected %s\n", sin_xs); + exit (1); + } + mpfr_clear (xx); + mpfr_clear (s); +} + +static void +check53b (const char *xs, const char *sin_xs, mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, s; + + mpfr_init2 (xx, 53); + mpfr_init2 (s, 53); + mpfr_set_str (xx, xs, 2, MPFR_RNDN); /* should be exact */ + test_sin (s, xx, rnd_mode); + if (mpfr_cmp_str (s, sin_xs, 2, MPFR_RNDN)) + { + printf ("mpfr_sin failed in rounding mode %s for\n x = %s\n", + mpfr_print_rnd_mode (rnd_mode), xs); + printf (" got "); + mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN); + printf ("\nexpected %s\n", sin_xs); + exit (1); + } + mpfr_clear (xx); + mpfr_clear (s); +} + +static void +test_sign (void) +{ + mpfr_t pid, piu, x, y; + int p, k; + + mpfr_init2 (pid, 4096); + mpfr_const_pi (pid, MPFR_RNDD); + mpfr_init2 (piu, 4096); + mpfr_const_pi (piu, MPFR_RNDU); + mpfr_init (x); + mpfr_init2 (y, 2); + for (p = 8; p <= 128; p++) + for (k = 2; k <= 6; k += 2) + { + mpfr_set_prec (x, p); + mpfr_mul_ui (x, pid, k, MPFR_RNDD); + test_sin (y, x, MPFR_RNDN); + if (MPFR_SIGN(y) > 0) + { + printf ("Error in test_sign for sin(%dpi-epsilon), prec = %d" + " for argument.\nResult should have been negative.\n", + k, p); + exit (1); + } + mpfr_mul_ui (x, piu, k, MPFR_RNDU); + test_sin (y, x, MPFR_RNDN); + if (MPFR_SIGN(y) < 0) + { + printf ("Error in test_sign for sin(%dpi+epsilon), prec = %d" + " for argument.\nResult should have been positive.\n", + k, p); + exit (1); + } + } + + /* worst case on 53 bits */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str (x, "6134899525417045", 10, MPFR_RNDN); + test_sin (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "11011010111101011110111100010101010101110000000001011E-106"); + MPFR_ASSERTN(mpfr_cmp (x, y) == 0); + + /* Bug on Special cases */ + mpfr_set_str_binary (x, "0.100011011010111101E-32"); + test_sin (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.10001101101011110100000000000000000000000000000000000E-32", 2, MPFR_RNDN)) + { + printf("sin special 97 error:\nx="); + mpfr_dump (x); printf("y="); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "1.1001001000011111101101010100010001000010110100010011"); + mpfr_set_str_binary (y, "1.1111111111111111111111111111111111111111111111111111e-1"); + test_sin (x, x, MPFR_RNDZ); + MPFR_ASSERTN(mpfr_cmp (x, y) == 0); + + mpfr_clear (pid); + mpfr_clear (piu); + mpfr_clear (x); + mpfr_clear (y); +} + +static void +check_nans (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + test_sin (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sin(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + test_sin (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sin(Inf) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + test_sin (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: sin(-Inf) != NaN\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION test_sin +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +const char xs[] = "0.111011111110110000111000001100000111110E-1"; + +static void +check_regression (void) +{ + mpfr_t x, y; + mpfr_prec_t p; + int i; + + p = strlen (xs) - 2 - 3; + mpfr_inits2 (p, x, y, (mpfr_ptr) 0); + + mpfr_set_str (x, xs, 2, MPFR_RNDN); + i = mpfr_sin (y, x, MPFR_RNDN); + if (i >= 0 + || mpfr_cmp_str (y, "0.111001110011110011110001010110011101110E-1", + 2, MPFR_RNDN)) + { + printf ("Regression test failed (1) i=%d\ny=", i); + mpfr_dump (y); + exit (1); + } + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +/* Test provided by Christopher Creutzig, 2007-05-21. */ +static void +check_tiny (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin ()); + mpfr_sin (y, x, MPFR_RNDD); + if (mpfr_cmp (x, y) < 0) + { + printf ("Error in check_tiny: got sin(x) > x for x = 2^(emin-1)\n"); + exit (1); + } + + mpfr_sin (y, x, MPFR_RNDU); + mpfr_mul_2ui (y, y, 1, MPFR_RNDU); + if (mpfr_cmp (x, y) > 0) + { + printf ("Error in check_tiny: got sin(x) < x/2 for x = 2^(emin-1)\n"); + exit (1); + } + + mpfr_neg (x, x, MPFR_RNDN); + mpfr_sin (y, x, MPFR_RNDU); + if (mpfr_cmp (x, y) > 0) + { + printf ("Error in check_tiny: got sin(x) < x for x = -2^(emin-1)\n"); + exit (1); + } + + mpfr_sin (y, x, MPFR_RNDD); + mpfr_mul_2ui (y, y, 1, MPFR_RNDD); + if (mpfr_cmp (x, y) < 0) + { + printf ("Error in check_tiny: got sin(x) > x/2 for x = -2^(emin-1)\n"); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, c, s, c2, s2; + + tests_start_mpfr (); + + check_regression (); + check_nans (); + + /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */ + check53 ("4.984987858808754279e-1", "4.781075595393330379e-1", MPFR_RNDN); + check53 ("4.984987858808754279e-1", "4.781075595393329824e-1", MPFR_RNDD); + check53 ("4.984987858808754279e-1", "4.781075595393329824e-1", MPFR_RNDZ); + check53 ("4.984987858808754279e-1", "4.781075595393330379e-1", MPFR_RNDU); + check53 ("1.00031274099908640274", "8.416399183372403892e-1", MPFR_RNDN); + check53 ("1.00229256850978698523", "8.427074524447979442e-1", MPFR_RNDZ); + check53 ("1.00288304857059840103", "8.430252033025980029e-1", MPFR_RNDZ); + check53 ("1.00591265847407274059", "8.446508805292128885e-1", MPFR_RNDN); + + /* Other worst cases showing a bug introduced on 2005-01-29 in rev 3248 */ + check53b ("1.0111001111010111010111111000010011010001110001111011e-21", + "1.0111001111010111010111111000010011010001101001110001e-21", + MPFR_RNDU); + check53b ("1.1011101111111010000001010111000010000111100100101101", + "1.1111100100101100001111100000110011110011010001010101e-1", + MPFR_RNDU); + + mpfr_init2 (x, 2); + + mpfr_set_str (x, "0.5", 10, MPFR_RNDN); + test_sin (x, x, MPFR_RNDD); + if (mpfr_cmp_ui_2exp (x, 3, -3)) /* x != 0.375 = 3/8 */ + { + printf ("mpfr_sin(0.5, MPFR_RNDD) failed with precision=2\n"); + exit (1); + } + + /* bug found by Kevin Ryde */ + mpfr_const_pi (x, MPFR_RNDN); + mpfr_mul_ui (x, x, 3L, MPFR_RNDN); + mpfr_div_ui (x, x, 2L, MPFR_RNDN); + test_sin (x, x, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) >= 0) + { + printf ("Error: wrong sign for sin(3*Pi/2)\n"); + exit (1); + } + + /* Can fail on an assert */ + mpfr_set_prec (x, 53); + mpfr_set_str (x, "77291789194529019661184401408", 10, MPFR_RNDN); + mpfr_init2 (c, 4); mpfr_init2 (s, 42); + mpfr_init2 (c2, 4); mpfr_init2 (s2, 42); + + test_sin (s, x, MPFR_RNDN); + mpfr_cos (c, x, MPFR_RNDN); + mpfr_sin_cos (s2, c2, x, MPFR_RNDN); + if (mpfr_cmp (c2, c)) + { + printf("cos differs for x=77291789194529019661184401408"); + exit (1); + } + if (mpfr_cmp (s2, s)) + { + printf("sin differs for x=77291789194529019661184401408"); + exit (1); + } + + mpfr_set_str_binary (x, "1.1001001000011111101101010100010001000010110100010011"); + test_sin (x, x, MPFR_RNDZ); + if (mpfr_cmp_str (x, "1.1111111111111111111111111111111111111111111111111111e-1", 2, MPFR_RNDN)) + { + printf ("Error for x= 1.1001001000011111101101010100010001000010110100010011\nGot "); + mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (s, 9); + mpfr_set_prec (x, 190); + mpfr_const_pi (x, MPFR_RNDN); + mpfr_sin (s, x, MPFR_RNDZ); + if (mpfr_cmp_str (s, "0.100000101e-196", 2, MPFR_RNDN)) + { + printf ("Error for x ~= pi\n"); + mpfr_dump (s); + exit (1); + } + + mpfr_clear (s2); + mpfr_clear (c2); + mpfr_clear (s); + mpfr_clear (c); + mpfr_clear (x); + + test_generic (2, 100, 15); + test_generic (MPFR_SINCOS_THRESHOLD-1, MPFR_SINCOS_THRESHOLD+1, 2); + test_sign (); + check_tiny (); + + data_check ("data/sin", mpfr_sin, "mpfr_sin"); + bad_cases (mpfr_sin, mpfr_asin, "mpfr_sin", 256, -40, 0, 4, 128, 800, 50); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsin_cos.c b/mpfr/tests/tsin_cos.c new file mode 100644 index 0000000000..d475596500 --- /dev/null +++ b/mpfr/tests/tsin_cos.c @@ -0,0 +1,725 @@ +/* Test file for mpfr_sin_cos. + +Copyright 2000-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +large_test (char *X, int prec, int N) +{ + int i; + mpfr_t x, s, c; + + mpfr_init2 (x, prec); + mpfr_init2 (s, prec); + mpfr_init2 (c, prec); + mpfr_set_str (x, X, 10, MPFR_RNDN); + + for (i = 0; i < N; i++) + mpfr_sin_cos (s, c, x, MPFR_RNDN); + + mpfr_clear (x); + mpfr_clear (s); + mpfr_clear (c); +} + +static void +check53 (const char *xs, const char *sin_xs, const char *cos_xs, + mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, s, c; + + mpfr_inits2 (53, xx, s, c, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); /* should be exact */ + mpfr_sin_cos (s, c, xx, rnd_mode); + if (mpfr_cmp_str1 (s, sin_xs)) + { + printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode (rnd_mode)); + printf ("mpfr_sin_cos gives sin(x)="); + mpfr_out_str(stdout, 10, 0, s, MPFR_RNDN); + printf(", expected %s\n", sin_xs); + exit (1); + } + if (mpfr_cmp_str1 (c, cos_xs)) + { + printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode (rnd_mode)); + printf ("mpfr_sin_cos gives cos(x)="); + mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN); + printf(", expected %s\n", cos_xs); + exit (1); + } + mpfr_clears (xx, s, c, (mpfr_ptr) 0); +} + +static void +check53sin (const char *xs, const char *sin_xs, mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, s, c; + + mpfr_inits2 (53, xx, s, c, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); /* should be exact */ + mpfr_sin_cos (s, c, xx, rnd_mode); + if (mpfr_cmp_str1 (s, sin_xs)) + { + printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode (rnd_mode)); + printf ("mpfr_sin_cos gives sin(x)="); + mpfr_out_str(stdout, 10, 0, s, MPFR_RNDN); + printf(", expected %s\n", sin_xs); + exit (1); + } + mpfr_clears (xx, s, c, (mpfr_ptr) 0); +} + +static void +check53cos (const char *xs, const char *cos_xs, mpfr_rnd_t rnd_mode) +{ + mpfr_t xx, c, s; + + mpfr_inits2 (53, xx, s, c, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); /* should be exact */ + mpfr_sin_cos (s, c, xx, rnd_mode); + if (mpfr_cmp_str1 (c, cos_xs)) + { + printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n", + xs, mpfr_print_rnd_mode (rnd_mode)); + printf ("mpfr_sin_cos gives cos(x)="); + mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN); + printf(", expected %s\n", cos_xs); + exit (1); + } + mpfr_clears (xx, s, c, (mpfr_ptr) 0); +} + +static void +check_nans (void) +{ + mpfr_t x, s, c; + + mpfr_init2 (x, 123L); + mpfr_init2 (s, 123L); + mpfr_init2 (c, 123L); + + /* sin(NaN)==NaN, cos(NaN)==NaN */ + mpfr_set_nan (x); + mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (s)); + MPFR_ASSERTN (mpfr_nan_p (c)); + + /* sin(+Inf)==NaN, cos(+Inf)==NaN */ + mpfr_set_inf (x, 1); + mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (s)); + MPFR_ASSERTN (mpfr_nan_p (c)); + + /* sin(-Inf)==NaN, cos(-Inf)==NaN */ + mpfr_set_inf (x, -1); + mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (s)); + MPFR_ASSERTN (mpfr_nan_p (c)); + + /* check zero */ + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (s, 0) == 0 && MPFR_IS_POS (s)); + MPFR_ASSERTN (mpfr_cmp_ui (c, 1) == 0); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_ui (s, 0) == 0 && MPFR_IS_NEG (s)); + MPFR_ASSERTN (mpfr_cmp_ui (c, 1) == 0); + + /* coverage test */ + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 4, MPFR_RNDN); + mpfr_set_prec (s, 2); + mpfr_set_prec (c, 2); + mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_cmp_si_2exp (s, -3, -2) == 0); + MPFR_ASSERTN (mpfr_cmp_si_2exp (c, -3, -2) == 0); + + mpfr_clear (x); + mpfr_clear (s); + mpfr_clear (c); +} + +static void +overflowed_sin_cos0 (void) +{ + mpfr_t x, y, z; + int emax, inex, rnd, err = 0; + mpfr_exp_t old_emax; + + old_emax = mpfr_get_emax (); + + mpfr_init2 (x, 8); + mpfr_init2 (y, 8); + mpfr_init2 (z, 8); + + for (emax = -1; emax <= 0; emax++) + { + mpfr_set_ui_2exp (z, 1, emax, MPFR_RNDN); + mpfr_nextbelow (z); + set_emax (emax); /* 1 is not representable. */ + /* and if emax < 0, 1 - eps is not representable either. */ + RND_LOOP (rnd) + { + mpfr_set_si (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_clear_flags (); + inex = mpfr_sin_cos (x, y, x, (mpfr_rnd_t) rnd); + if (! mpfr_overflow_p ()) + { + printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" + " The overflow flag is not set.\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_zero_p (x) && MPFR_SIGN (x) < 0)) + { + printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" + " Got sin = ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (x); + printf (" instead of -0.\n"); + err = 1; + } + if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + { + if (inex == 0) + { + printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" + " The inexact value must be non-zero.\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! mpfr_equal_p (y, z)) + { + printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" + " Got cos = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (y); + printf (" instead of 0.11111111E%d.\n", emax); + err = 1; + } + } + else + { + if (inex == 0) + { + printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" + " The inexact value must be non-zero.\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + err = 1; + } + if (! (mpfr_inf_p (y) && MPFR_SIGN (y) > 0)) + { + printf ("Error in overflowed_sin_cos0 (rnd = %s):\n" + " Got cos = ", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + mpfr_print_binary (y); + printf (" instead of +Inf.\n"); + err = 1; + } + } + } + set_emax (old_emax); + } + + if (err) + exit (1); + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +tiny (void) +{ + mpfr_t x, s, c; + int i, inex; + + mpfr_inits2 (64, x, s, c, (mpfr_ptr) 0); + + for (i = -1; i <= 1; i += 2) + { + mpfr_set_si (x, i, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin ()); + inex = mpfr_sin_cos (s, c, x, MPFR_RNDN); + MPFR_ASSERTN (inex != 0); + MPFR_ASSERTN (mpfr_equal_p (s, x)); + MPFR_ASSERTN (!mpfr_nan_p (c) && mpfr_cmp_ui (c, 1) == 0); + } + + mpfr_clears (x, s, c, (mpfr_ptr) 0); +} + +/* bug found in nightly tests */ +static void +test20071214 (void) +{ + mpfr_t a, b; + int inex; + + mpfr_init2 (a, 4); + mpfr_init2 (b, 4); + + mpfr_set_ui_2exp (a, 3, -4, MPFR_RNDN); + inex = mpfr_sin_cos (a, b, a, MPFR_RNDD); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 11, -6) == 0); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (b, 15, -4) == 0); + MPFR_ASSERTN(inex == 10); + + mpfr_set_ui_2exp (a, 3, -4, MPFR_RNDN); + inex = mpfr_sin_cos (a, b, a, MPFR_RNDU); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 3, -4) == 0); + MPFR_ASSERTN(mpfr_cmp_ui (b, 1) == 0); + MPFR_ASSERTN(inex == 5); + + mpfr_set_ui_2exp (a, 3, -4, MPFR_RNDN); + inex = mpfr_sin_cos (a, b, a, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 3, -4) == 0); + MPFR_ASSERTN(mpfr_cmp_ui (b, 1) == 0); + MPFR_ASSERTN(inex == 5); + + mpfr_clear (a); + mpfr_clear (b); +} + +/* check that mpfr_sin_cos and test_mpfr_sincos_fast agree */ +static void +test_mpfr_sincos_fast (void) +{ + mpfr_t x, y, z, yref, zref, h; + mpfr_prec_t p = 1000; + int i, inex, inexref; + mpfr_rnd_t r; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, p); + mpfr_init2 (yref, p); + mpfr_init2 (zref, p); + mpfr_init2 (h, p); + mpfr_set_ui (x, 0, MPFR_RNDN); + /* we generate a random value x, compute sin(x) and cos(x) with both + mpfr_sin_cos and mpfr_sincos_fast, and check the values and the flags + agree */ + for (i = 0; i < 100; i++) + { + mpfr_urandomb (h, RANDS); + mpfr_add (x, x, h, MPFR_RNDN); + r = RND_RAND (); + inexref = mpfr_sin_cos (yref, zref, x, r); + inex = mpfr_sincos_fast (y, z, x, r); + if (mpfr_cmp (y, yref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n"); + printf ("x="); mpfr_dump (x); + printf ("rnd=%s\n", mpfr_print_rnd_mode (r)); + printf ("yref="); mpfr_dump (yref); + printf ("y="); mpfr_dump (y); + exit (1); + } + if (mpfr_cmp (z, zref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n"); + printf ("x="); mpfr_dump (x); + printf ("rnd=%s\n", mpfr_print_rnd_mode (r)); + printf ("zref="); mpfr_dump (zref); + printf ("z="); mpfr_dump (z); + exit (1); + } + if (inex != inexref) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n"); + printf ("x="); mpfr_dump (x); + printf ("rnd=%s\n", mpfr_print_rnd_mode (r)); + printf ("inexref=%d inex=%d\n", inexref, inex); + exit (1); + } + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (yref); + mpfr_clear (zref); + mpfr_clear (h); +} + +static void +bug20091007 (void) +{ + mpfr_t x, y, z, yref, zref; + mpfr_prec_t p = 1000; + int inex, inexref; + mpfr_rnd_t r = MPFR_RNDZ; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, p); + mpfr_init2 (yref, p); + mpfr_init2 (zref, p); + + mpfr_set_str (x, "1.9ecdc22ba77a5ab2560f7e84289e2a328906f47377ea3fd4c82d1bb2f13ee05c032cffc1933eadab7b0a5498e03e3bd0508968e59c25829d97a0b54f20cd4662c8dfffa54e714de41fc8ee3e0e0b244d110a194db05b70022b7d77f88955d415b09f17dd404576098dc51a583a3e49c35839551646e880c7eb790a01a4@1", 16, MPFR_RNDN); + inexref = mpfr_sin_cos (yref, zref, x, r); + inex = mpfr_sincos_fast (y, z, x, r); + + if (mpfr_cmp (y, yref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091007)\n"); + printf ("yref="); mpfr_dump (yref); + printf ("y="); mpfr_dump (y); + exit (1); + } + if (mpfr_cmp (z, zref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091007)\n"); + printf ("zref="); mpfr_dump (zref); + printf ("z="); mpfr_dump (z); + exit (1); + } + if (inex != inexref) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091007)\n"); + printf ("inexref=%d inex=%d\n", inexref, inex); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (yref); + mpfr_clear (zref); +} + +/* Note: with the sin_cos.c code before r6507, the disagreement occurs + only on the return ("inexact") value, which is new in r6444. */ +static void +bug20091008 (void) +{ + mpfr_t x, y, z, yref, zref; + mpfr_prec_t p = 1000; + int inex, inexref; + mpfr_rnd_t r = MPFR_RNDN; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, p); + mpfr_init2 (yref, p); + mpfr_init2 (zref, p); + + mpfr_set_str (x, "c.91813724e28ef6a711d33e6505984699daef7fe93636c1ed5d0168bc96989cc6802f7f9e405c902ec62fb90cd39c9d21084c8ad8b5af4c4aa87bf402e2e4a78e6fe1ffeb6dbbbdbbc2983c196c518966ccc1e094ed39ee77984ef2428069d65de37928e75247edbe7007245e682616b5ebbf05f2fdefc74ad192024f10", 16, MPFR_RNDN); + inexref = mpfr_sin_cos (yref, zref, x, r); + inex = mpfr_sincos_fast (y, z, x, r); + + if (mpfr_cmp (y, yref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091008)\n"); + printf ("yref="); mpfr_dump (yref); + printf ("y="); mpfr_dump (y); + exit (1); + } + if (mpfr_cmp (z, zref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091008)\n"); + printf ("zref="); mpfr_dump (zref); + printf ("z="); mpfr_dump (z); + exit (1); + } + /* sin(x) is rounded up, cos(x) is rounded up too, thus we should get 5 + for the return value */ + if (inex != inexref) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091008)\n"); + printf ("inexref=%d inex=%d (5 expected)\n", inexref, inex); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (yref); + mpfr_clear (zref); +} + +static void +bug20091013 (void) +{ + mpfr_t x, y, z, yref, zref; + mpfr_prec_t p = 1000; + int inex, inexref; + mpfr_rnd_t r = MPFR_RNDN; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, p); + mpfr_init2 (yref, p); + mpfr_init2 (zref, p); + + mpfr_set_str (x, "3.240ff3fdcb1ee7cd667b96287593ae24e20fb63ed7c2d5bf4bd0f2cc5509283b04e7628e66382605f14ed5967cef15296041539a1bdaa626c777c7fbb6f2068414759b78cee14f37848689b3a170f583656be4e0837f464d8210556a3a822d4ecfdd59f4e0d5fdb76bf7e15b8a57234e2160b98e14c17bbdf27c4643b8@1", 16, MPFR_RNDN); + inexref = mpfr_sin_cos (yref, zref, x, r); + inex = mpfr_sincos_fast (y, z, x, r); + + if (mpfr_cmp (y, yref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091013)\n"); + printf ("yref="); mpfr_dump (yref); + printf ("y="); mpfr_dump (y); + exit (1); + } + if (mpfr_cmp (z, zref)) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091013)\n"); + printf ("zref="); mpfr_dump (zref); + printf ("z="); mpfr_dump (z); + exit (1); + } + /* sin(x) is rounded down and cos(x) is rounded down, thus we should get + 2+4*2 = 10 as return value */ + if (inex != inexref) + { + printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091013)\n"); + printf ("inexref=%d inex=%d (10 expected)\n", inexref, inex); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (yref); + mpfr_clear (zref); +} + +/* Bug reported by Laurent Fousse for the 2.4 branch. + No problem in the trunk. + https://sympa.inria.fr/sympa/arc/mpfr/2009-11/msg00044.html */ +static void +bug20091122 (void) +{ + mpfr_t x, y, z, yref, zref; + mpfr_prec_t p = 3; + mpfr_rnd_t r = MPFR_RNDN; + + mpfr_init2 (x, 5); + mpfr_init2 (y, p); + mpfr_init2 (z, p); + mpfr_init2 (yref, p); + mpfr_init2 (zref, p); + + mpfr_set_str (x, "0.11111E49", 2, MPFR_RNDN); + mpfr_sin_cos (yref, zref, x, r); + + mpfr_sin (y, x, r); + mpfr_cos (z, x, r); + + if (! mpfr_equal_p (y, yref)) + { + printf ("mpfr_sin_cos and mpfr_sin disagree (bug20091122)\n"); + printf ("yref = "); mpfr_dump (yref); + printf ("y = "); mpfr_dump (y); + exit (1); + } + if (! mpfr_equal_p (z, zref)) + { + printf ("mpfr_sin_cos and mpfr_cos disagree (bug20091122)\n"); + printf ("zref = "); mpfr_dump (zref); + printf ("z = "); mpfr_dump (z); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (yref); + mpfr_clear (zref); +} + +static void +consistency (void) +{ + mpfr_t x, s1, s2, c1, c2; + mpfr_exp_t emin, emax; + mpfr_rnd_t rnd; + unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref; + int inex_sin, is, inex_cos, ic, inex, inex_ref; + int i; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + for (i = 0; i <= 10000; i++) + { + mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8)); + mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2, + (mpfr_ptr) 0); + if (i < 8 * MPFR_RND_MAX) + { + int j = i / MPFR_RND_MAX; + if (j & 1) + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_set_si (x, (j & 2) ? 1 : -1, MPFR_RNDN); + mpfr_set_exp (x, mpfr_get_emin ()); + rnd = (mpfr_rnd_t) (i % MPFR_RND_MAX); + flags_before = 0; + if (j & 4) + mpfr_set_emax (-17); + } + else + { + tests_default_random (x, 256, -5, 50, 0); + rnd = RND_RAND (); + flags_before = (randlimb () & 1) ? + (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) : + (unsigned int) 0; + } + __gmpfr_flags = flags_before; + inex_sin = mpfr_sin (s1, x, rnd); + is = inex_sin < 0 ? 2 : inex_sin > 0 ? 1 : 0; + flags_sin = __gmpfr_flags; + __gmpfr_flags = flags_before; + inex_cos = mpfr_cos (c1, x, rnd); + ic = inex_cos < 0 ? 2 : inex_cos > 0 ? 1 : 0; + flags_cos = __gmpfr_flags; + __gmpfr_flags = flags_before; + inex = mpfr_sin_cos (s2, c2, x, rnd); + flags = __gmpfr_flags; + inex_ref = is + 4 * ic; + flags_ref = flags_sin | flags_cos; + if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) || + inex != inex_ref || flags != flags_ref) + { + printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s," + " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i); + mpfr_dump (x); + printf ("s1 = "); + mpfr_dump (s1); + printf ("s2 = "); + mpfr_dump (s2); + printf ("c1 = "); + mpfr_dump (c1); + printf ("c2 = "); + mpfr_dump (c2); + printf ("inex_sin = %d (s = %d), inex_cos = %d (c = %d), " + "inex = %d (expected %d)\n", + inex_sin, is, inex_cos, ic, inex, inex_ref); + printf ("flags_sin = 0x%x, flags_cos = 0x%x, " + "flags = 0x%x (expected 0x%x)\n", + flags_sin, flags_cos, flags, flags_ref); + exit (1); + } + mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0); + mpfr_set_emin (emin); + mpfr_set_emax (emax); + } +} + +static void +coverage_01032011 (void) +{ + mpfr_t val, cval, sval, svalf; + int status_f, status; + + mpfr_init2 (val, MPFR_PREC_MIN); + mpfr_init2 (cval, MPFR_PREC_MIN); + mpfr_init2 (sval, MPFR_PREC_MIN); + mpfr_init2 (svalf, MPFR_PREC_MIN); + + mpfr_set_str1 (val, "-0.7"); + + status_f = mpfr_sincos_fast (svalf, NULL, val, MPFR_RNDN); + status = mpfr_sin_cos (sval, cval, val, MPFR_RNDN); + if (! mpfr_equal_p (svalf, sval) || SIGN (status_f) != SIGN (status)) + { + printf ("mpfr_sincos_fast differ from mpfr_sin_cos result:\n" + " sin fast is "); + mpfr_dump (svalf); + printf (" sin is "); + mpfr_dump (sval); + printf ("status_f = %d, status = %d\n", status_f, status); + exit (1); + } + + mpfr_clears(val, cval, sval, svalf, (mpfr_ptr) 0); +} + +/* tsin_cos prec [N] performs N tests with prec bits */ +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + if (argc > 1) + { + if (argc != 3 && argc != 4) + { + fprintf (stderr, "Usage: tsin_cos x prec [n]\n"); + exit (1); + } + large_test (argv[1], atoi (argv[2]), (argc > 3) ? atoi (argv[3]) : 1); + goto end; + } + + bug20091013 (); + bug20091008 (); + bug20091007 (); + bug20091122 (); + consistency (); + + test_mpfr_sincos_fast (); + + check_nans (); + + /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */ + check53 ("4.984987858808754279e-1", "4.781075595393330379e-1", + "8.783012931285841817e-1", MPFR_RNDN); + check53 ("4.984987858808754279e-1", "4.781075595393329824e-1", + "8.783012931285840707e-1", MPFR_RNDD); + check53 ("4.984987858808754279e-1", "4.781075595393329824e-1", + "8.783012931285840707e-1", MPFR_RNDZ); + check53 ("4.984987858808754279e-1", "4.781075595393330379e-1", + "8.783012931285841817e-1", MPFR_RNDU); + check53 ("1.00031274099908640274", "8.416399183372403892e-1", + "0.540039116973283217504", MPFR_RNDN); + check53 ("1.00229256850978698523", "8.427074524447979442e-1", + "0.538371757797526551137", MPFR_RNDZ); + check53 ("1.00288304857059840103", "8.430252033025980029e-1", + "0.537874062022526966409", MPFR_RNDZ); + check53 ("1.00591265847407274059", "8.446508805292128885e-1", + "0.53531755997839769456", MPFR_RNDN); + + /* check one argument only */ + check53sin ("1.00591265847407274059", "8.446508805292128885e-1", MPFR_RNDN); + check53cos ("1.00591265847407274059", "0.53531755997839769456", MPFR_RNDN); + + overflowed_sin_cos0 (); + tiny (); + test20071214 (); + + coverage_01032011 (); + + end: + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsinh.c b/mpfr/tests/tsinh.c new file mode 100644 index 0000000000..cd336eb956 --- /dev/null +++ b/mpfr/tests/tsinh.c @@ -0,0 +1,109 @@ +/* Test file for mpfr_sinh. + +Copyright 2001-2002, 2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_sinh +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x; + int i; + + mpfr_init (x); + + mpfr_set_nan (x); + mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x)); + + mpfr_set_inf (x, 1); + mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0); + mpfr_set_inf (x, -1); + mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0); + + mpfr_set_prec (x, 10); + mpfr_set_str_binary (x, "-0.1001011001"); + mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_si_2exp (x, -159, -8) == 0); + + /* corner case */ + mpfr_set_prec (x, 2); + mpfr_set_str_binary (x, "1E-6"); + mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -6) == 0); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "1E1000000000"); + i = mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0); + MPFR_ASSERTN (mpfr_overflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1E1000000000"); + i = mpfr_sinh (x, x, MPFR_RNDN); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) < 0); + MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == -1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1E1000000000"); + i = mpfr_sinh (x, x, MPFR_RNDD); + MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) < 0); + MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == -1); + + mpfr_clear_flags (); + mpfr_set_str_binary (x, "-1E1000000000"); + i = mpfr_sinh (x, x, MPFR_RNDU); + MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) < 0); + MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ()); + MPFR_ASSERTN (i == 1); + + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 100); + + data_check ("data/sinh", mpfr_sinh, "mpfr_sinh"); + bad_cases (mpfr_sinh, mpfr_asinh, "mpfr_sinh", 256, -256, 255, + 4, 128, 800, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsinh_cosh.c b/mpfr/tests/tsinh_cosh.c new file mode 100644 index 0000000000..f5b1d0cff8 --- /dev/null +++ b/mpfr/tests/tsinh_cosh.c @@ -0,0 +1,143 @@ +/* Test file for mpfr_sinh_cosh. + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +failed (mpfr_t x, mpfr_t esh, mpfr_t gsh, mpfr_t ech, mpfr_t gch) +{ + printf ("error : mpfr_sinh_cosh (x) x = "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD); + printf ("\nsinh(x) expected "); + mpfr_out_str (stdout, 10, 0, esh, MPFR_RNDD); + printf ("\n got "); + mpfr_out_str (stdout, 10, 0, gsh, MPFR_RNDD); + printf ("\ncosh(x) expected "); + mpfr_out_str (stdout, 10, 0, ech, MPFR_RNDD); + printf ("\n got "); + mpfr_out_str (stdout, 10, 0, gch, MPFR_RNDD); + putchar ('\n'); + + mpfr_clears (x, esh, gsh, ech, gch, (mpfr_ptr) 0); + exit (1); +} + +/* check against sinh, cosh */ +static void +check (mpfr_t x, mpfr_rnd_t rnd) +{ + mpfr_t s, c, sx, cx; + int isc, is, ic; + + mpfr_inits2 (MPFR_PREC(x), s, c, sx, cx, (mpfr_ptr) 0); + + isc = mpfr_sinh_cosh (sx, cx, x, rnd); + is = mpfr_sinh (s, x, rnd); + ic = mpfr_cosh (c, x, rnd); + + if (!mpfr_equal_p (s, sx) || !mpfr_equal_p (c, cx)) + failed (x, s, sx, c, cx); + MPFR_ASSERTN (isc = is || ic); + + mpfr_clears (s, c, sx, cx, (mpfr_ptr) 0); +} + +static void +check_nans (void) +{ + mpfr_t x, sh, ch; + + mpfr_init2 (x, 123); + mpfr_init2 (sh, 123); + mpfr_init2 (ch, 123); + + /* nan */ + mpfr_set_nan (x); + mpfr_sinh_cosh (sh, ch, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (sh)); + MPFR_ASSERTN (mpfr_nan_p (ch)); + + /* +inf */ + mpfr_set_inf (x, 1); + mpfr_sinh_cosh (sh, ch, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (sh)); + MPFR_ASSERTN (mpfr_sgn (sh) > 0); + MPFR_ASSERTN (mpfr_inf_p (ch)); + MPFR_ASSERTN (mpfr_sgn (ch) > 0); + + /* -inf */ + mpfr_set_inf (x, -1); + mpfr_sinh_cosh (sh, ch, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (sh)); + MPFR_ASSERTN (mpfr_sgn (sh) < 0); + MPFR_ASSERTN (mpfr_inf_p (ch)); + MPFR_ASSERTN (mpfr_sgn (ch) > 0); + + mpfr_clear (x); + mpfr_clear (sh); + mpfr_clear (ch); +} + +int +main (int argc, char *argv[]) +{ + int i; + mpfr_t x; + + tests_start_mpfr (); + + check_nans (); + + /* check against values given by sinh(x), cosh(x) */ + mpfr_init2 (x, 53); + mpfr_set_str (x, "FEDCBA987654321p-48", 16, MPFR_RNDN); + for (i = 0; i < 10; ++i) + { + /* x = i - x / 2 : boggle sign and bits */ + mpfr_ui_sub (x, i, x, MPFR_RNDD); + mpfr_div_2ui (x, x, 2, MPFR_RNDD); + + check (x, MPFR_RNDN); + check (x, MPFR_RNDU); + check (x, MPFR_RNDD); + } + mpfr_clear (x); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tsprintf.c b/mpfr/tests/tsprintf.c new file mode 100644 index 0000000000..42778b8fe7 --- /dev/null +++ b/mpfr/tests/tsprintf.c @@ -0,0 +1,1315 @@ +/* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf, + and mpfr_vsnprintf + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_STDARG +#include <stdarg.h> + +#include <stdlib.h> +#include <float.h> + +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +const int prec_max_printf = 5000; /* limit for random precision in + random_double() */ +#define BUF_SIZE 65536 + +const char pinf_str[] = "inf"; +const char pinf_uc_str[] = "INF"; +const char minf_str[] = "-inf"; +const char minf_uc_str[] = "-INF"; +const char nan_str[] = "nan"; +const char nan_uc_str[] = "NAN"; + +/* 1. compare expected string with the string BUFFER returned by + mpfr_sprintf(buffer, fmt, x) + 2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */ +static int +check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) +{ + int n0, n1, p; + char buffer[BUF_SIZE]; + + /* test mpfr_sprintf */ + n0 = mpfr_sprintf (buffer, fmt, x); + if (strcmp (buffer, expected) != 0) + { + printf ("Error in mpfr_sprintf (s, \"%s\", x);\n", fmt); + printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer); + + exit (1); + } + + /* test mpfr_snprintf */ + p = (int) (randlimb () % n0); + if (p == 0 && (randlimb () & 1) == 0) + { + n1 = mpfr_snprintf (NULL, 0, fmt, x); + } + else + { + buffer[p] = 17; + n1 = mpfr_snprintf (buffer, p, fmt, x); + if (buffer[p] != 17) + { + printf ("Buffer overflow in mpfr_snprintf for p = %d!\n", p); + exit (1); + } + } + if (n0 != n1) + { + printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n", + p, fmt); + printf ("expected: %d\ngot: %d\n", n0, n1); + exit (1); + } + if ((p > 1 && strncmp (expected, buffer, p-1) != 0) + || (p == 1 && buffer[0] != '\0')) + { + char part_expected[BUF_SIZE]; + strncpy (part_expected, expected, p); + part_expected[p-1] = '\0'; + printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); + printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); + exit (1); + } + return n0; +} + +/* 1. compare expected string with the string BUFFER returned by + mpfr_vsprintf(buffer, fmt, ...) + 2. then, test mpfr_vsnprintf. */ +static int +check_vsprintf (const char *expected, const char *fmt, ...) +{ + int n0, n1, p; + char buffer[BUF_SIZE]; + va_list ap0, ap1; + va_start (ap0, fmt); + va_start (ap1, fmt); + + n0 = mpfr_vsprintf (buffer, fmt, ap0); + if (strcmp (buffer, expected) != 0) + { + printf ("Error in mpfr_vsprintf (s, \"%s\", ...);\n", fmt); + printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer); + + va_end (ap0); + va_end (ap1); + exit (1); + } + va_end (ap0); + + /* test mpfr_snprintf */ + p = (int) (randlimb () % n0); + if (p == 0 && (randlimb () & 1) == 0) + { + n1 = mpfr_vsnprintf (NULL, 0, fmt, ap1); + } + else + { + buffer[p] = 17; + n1 = mpfr_vsnprintf (buffer, p, fmt, ap1); + if (buffer[p] != 17) + { + printf ("Buffer overflow in mpfr_vsnprintf for p = %d!\n", p); + exit (1); + } + } + if (n0 != n1) + { + printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...) return value\n", + p, fmt); + printf ("expected: %d\ngot: %d\n", n0, n1); + + va_end (ap1); + exit (1); + } + if ((p > 1 && strncmp (expected, buffer, p-1) != 0) + || (p == 1 && buffer[0] != '\0')) + { + char part_expected[BUF_SIZE]; + strncpy (part_expected, expected, p); + part_expected[p-1] = '\0'; + printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); + printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); + + va_end (ap1); + exit (1); + } + + va_end (ap1); + return n0; +} + +static void +native_types (void) +{ + int c = 'a'; + int i = -1; + unsigned int ui = 1; + double d = -1.25; + char s[] = "test"; + + char buf[255]; + + sprintf (buf, "%c", c); + check_vsprintf (buf, "%c", c); + + sprintf (buf, "%d", i); + check_vsprintf (buf, "%d", i); + + sprintf (buf, "%e", d); + check_vsprintf (buf, "%e", d); + + sprintf (buf, "%f", d); + check_vsprintf (buf, "%f", d); + + sprintf (buf, "%i", i); + check_vsprintf (buf, "%i", i); + + sprintf (buf, "%g", d); + check_vsprintf (buf, "%g", d); + + sprintf (buf, "%o", i); + check_vsprintf (buf, "%o", i); + + sprintf (buf, "%s", s); + check_vsprintf (buf, "%s", s); + + sprintf (buf, "--%s++", ""); + check_vsprintf (buf, "--%s++", ""); + + sprintf (buf, "%u", ui); + check_vsprintf (buf, "%u", ui); + + sprintf (buf, "%x", ui); + check_vsprintf (buf, "%x", ui); +} + +static int +decimal (void) +{ + mpfr_prec_t p = 128; + mpfr_t x; + mpfr_t z; + mpfr_init (z); + mpfr_init2 (x, p); + + /* specifier 'P' for precision */ + check_vsprintf ("128", "%Pu", p); + check_vsprintf ("00128", "%.5Pu", p); + + /* special numbers */ + mpfr_set_inf (x, 1); + check_sprintf (pinf_str, "%Re", x); + check_sprintf (pinf_str, "%RUe", x); + check_sprintf (pinf_uc_str, "%RE", x); + check_sprintf (pinf_uc_str, "%RDE", x); + check_sprintf (pinf_str, "%Rf", x); + check_sprintf (pinf_str, "%RYf", x); + check_sprintf (pinf_uc_str, "%RF", x); + check_sprintf (pinf_uc_str, "%RZF", x); + check_sprintf (pinf_str, "%Rg", x); + check_sprintf (pinf_str, "%RNg", x); + check_sprintf (pinf_uc_str, "%RG", x); + check_sprintf (pinf_uc_str, "%RUG", x); + check_sprintf (" inf", "%010Re", x); + check_sprintf (" inf", "%010RDe", x); + + mpfr_set_inf (x, -1); + check_sprintf (minf_str, "%Re", x); + check_sprintf (minf_str, "%RYe", x); + check_sprintf (minf_uc_str, "%RE", x); + check_sprintf (minf_uc_str, "%RZE", x); + check_sprintf (minf_str, "%Rf", x); + check_sprintf (minf_str, "%RNf", x); + check_sprintf (minf_uc_str, "%RF", x); + check_sprintf (minf_uc_str, "%RUF", x); + check_sprintf (minf_str, "%Rg", x); + check_sprintf (minf_str, "%RDg", x); + check_sprintf (minf_uc_str, "%RG", x); + check_sprintf (minf_uc_str, "%RYG", x); + check_sprintf (" -inf", "%010Re", x); + check_sprintf (" -inf", "%010RZe", x); + + mpfr_set_nan (x); + check_sprintf (nan_str, "%Re", x); + check_sprintf (nan_str, "%RNe", x); + check_sprintf (nan_uc_str, "%RE", x); + check_sprintf (nan_uc_str, "%RUE", x); + check_sprintf (nan_str, "%Rf", x); + check_sprintf (nan_str, "%RDf", x); + check_sprintf (nan_uc_str, "%RF", x); + check_sprintf (nan_uc_str, "%RYF", x); + check_sprintf (nan_str, "%Rg", x); + check_sprintf (nan_str, "%RZg", x); + check_sprintf (nan_uc_str, "%RG", x); + check_sprintf (nan_uc_str, "%RNG", x); + check_sprintf (" nan", "%010Re", x); + + /* positive numbers */ + mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); + mpfr_set_ui (z, 0, MPFR_RNDD); + + /* simplest case right justified */ + check_sprintf (" 1.899347461279296875e+07", "%30Re", x); + check_sprintf (" 2e+07", "%30.0Re", x); + check_sprintf (" 18993474.612793", "%30Rf", x); + check_sprintf (" 18993474.6127930", "%30.7Rf", x); + check_sprintf (" 1.89935e+07", "%30Rg", x); + check_sprintf (" 2e+07", "%30.0Rg", x); + check_sprintf (" 18993474.61279296875", "%30.19Rg", x); + check_sprintf (" 0e+00", "%30.0Re", z); + check_sprintf (" 0", "%30.0Rf", z); + check_sprintf (" 0.0000", "%30.4Rf", z); + check_sprintf (" 0", "%30.0Rg", z); + check_sprintf (" 0", "%30.4Rg", z); + /* sign or space, pad with leading zeros */ + check_sprintf (" 000001.899347461279296875E+07", "% 030RE", x); + check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x); + check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x); + check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z); + check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z); + /* sign + or -, left justified */ + check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", x); + check_sprintf ("+2e+07 ", "%+-30.0Re", x); + check_sprintf ("+0e+00 ", "%+-30.0Re", z); + check_sprintf ("+0 ", "%+-30.0Rf", z); + /* decimal point, left justified, precision and rounding parameter */ + check_vsprintf ("1.9E+07 ", "%#-10.*R*E", 1, MPFR_RNDN, x); + check_vsprintf ("2.E+07 ", "%#*.*R*E", -10, 0, MPFR_RNDN, x); + check_vsprintf ("2.E+07 ", "%#-10.*R*G", 0, MPFR_RNDN, x); + check_vsprintf ("0.E+00 ", "%#-10.*R*E", 0, MPFR_RNDN, z); + check_vsprintf ("0. ", "%#-10.*R*F", 0, MPFR_RNDN, z); + check_vsprintf ("0. ", "%#-10.*R*G", 0, MPFR_RNDN, z); + /* sign or space */ + check_sprintf (" 1.899e+07", "% .3RNe", x); + check_sprintf (" 2e+07", "% .0RNe", x); + /* sign + or -, decimal point, pad with leading zeros */ + check_sprintf ("+0001.8E+07", "%0+#11.1RZE", x); + check_sprintf ("+00001.E+07", "%0+#11.0RZE", x); + check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z); + check_sprintf ("+00000000.0", "%0+#11.1RZF", z); + /* pad with leading zero */ + check_sprintf ("0000001.899347461279296875e+07", "%030RDe", x); + check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x); + /* sign or space, decimal point, left justified */ + check_sprintf (" 1.8E+07 ", "%- #11.1RDE", x); + check_sprintf (" 1.E+07 ", "%- #11.0RDE", x); + + /* negative numbers */ + mpfr_mul_si (x, x, -1, MPFR_RNDD); + mpfr_mul_si (z, z, -1, MPFR_RNDD); + + /* sign + or - */ + check_sprintf (" -1.8e+07", "%+10.1RUe", x); + check_sprintf (" -1e+07", "%+10.0RUe", x); + check_sprintf (" -0e+00", "%+10.0RUe", z); + check_sprintf (" -0", "%+10.0RUf", z); + + + /* neighborhood of 1 */ + mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN); + check_sprintf ("9.9993896484375E-01 ", "%-20RE", x); + check_sprintf ("9.9993896484375E-01 ", "%-20.RE", x); + check_sprintf ("1E+00 ", "%-20.0RE", x); + check_sprintf ("1.0E+00 ", "%-20.1RE", x); + check_sprintf ("1.00E+00 ", "%-20.2RE", x); + check_sprintf ("9.999E-01 ", "%-20.3RE", x); + check_sprintf ("9.9994E-01 ", "%-20.4RE", x); + check_sprintf ("0.999939 ", "%-20RF", x); + check_sprintf ("0.999939 ", "%-20.RF", x); + check_sprintf ("1 ", "%-20.0RF", x); + check_sprintf ("1.0 ", "%-20.1RF", x); + check_sprintf ("1.00 ", "%-20.2RF", x); + check_sprintf ("1.000 ", "%-20.3RF", x); + check_sprintf ("0.9999 ", "%-20.4RF", x); + check_sprintf ("0.999939 ", "%-#20RF", x); + check_sprintf ("0.999939 ", "%-#20.RF", x); + check_sprintf ("1. ", "%-#20.0RF", x); + check_sprintf ("1.0 ", "%-#20.1RF", x); + check_sprintf ("1.00 ", "%-#20.2RF", x); + check_sprintf ("1.000 ", "%-#20.3RF", x); + check_sprintf ("0.9999 ", "%-#20.4RF", x); + check_sprintf ("1 ", "%-20.0RG", x); + check_sprintf ("1 ", "%-20.1RG", x); + check_sprintf ("1 ", "%-20.2RG", x); + check_sprintf ("1 ", "%-20.3RG", x); + check_sprintf ("0.9999 ", "%-20.4RG", x); + check_sprintf ("0.999939 ", "%-#20RG", x); + check_sprintf ("0.999939 ", "%-#20.RG", x); + check_sprintf ("1. ", "%-#20.0RG", x); + check_sprintf ("1. ", "%-#20.1RG", x); + check_sprintf ("1.0 ", "%-#20.2RG", x); + check_sprintf ("1.00 ", "%-#20.3RG", x); + check_sprintf ("0.9999 ", "%-#20.4RG", x); + + /* multiple of 10 */ + mpfr_set_str (x, "1e17", 10, MPFR_RNDN); + check_sprintf ("1e+17", "%Re", x); + check_sprintf ("1.000e+17", "%.3Re", x); + check_sprintf ("100000000000000000", "%.0Rf", x); + check_sprintf ("100000000000000000.0", "%.1Rf", x); + check_sprintf ("100000000000000000.000000", "%'Rf", x); + check_sprintf ("100000000000000000.0", "%'.1Rf", x); + + mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */ + check_sprintf ("1e-17", "%Re", x); + check_sprintf ("0.000000", "%Rf", x); + check_sprintf ("1e-17", "%Rg", x); + check_sprintf ("0.0", "%.1RDf", x); + check_sprintf ("0.0", "%.1RZf", x); + check_sprintf ("0.1", "%.1RUf", x); + check_sprintf ("0.1", "%.1RYf", x); + check_sprintf ("0", "%.0RDf", x); + check_sprintf ("0", "%.0RZf", x); + check_sprintf ("1", "%.0RUf", x); + check_sprintf ("1", "%.0RYf", x); + + /* multiple of 10 with 'g' style */ + mpfr_set_str (x, "10", 10, MPFR_RNDN); + check_sprintf ("10", "%Rg", x); + check_sprintf ("1e+01", "%.0Rg", x); + check_sprintf ("1e+01", "%.1Rg", x); + check_sprintf ("10", "%.2Rg", x); + + mpfr_ui_div (x, 1, x, MPFR_RNDN); + check_sprintf ("0.1", "%Rg", x); + check_sprintf ("0.1", "%.0Rg", x); + check_sprintf ("0.1", "%.1Rg", x); + + mpfr_set_str (x, "1000", 10, MPFR_RNDN); + check_sprintf ("1000", "%Rg", x); + check_sprintf ("1e+03", "%.0Rg", x); + check_sprintf ("1e+03", "%.3Rg", x); + check_sprintf ("1000", "%.4Rg", x); + + mpfr_ui_div (x, 1, x, MPFR_RNDN); + check_sprintf ("0.001", "%Rg", x); + check_sprintf ("0.001", "%.0Rg", x); + check_sprintf ("0.001", "%.1Rg", x); + + mpfr_set_str (x, "100000", 10, MPFR_RNDN); + check_sprintf ("100000", "%Rg", x); + check_sprintf ("1e+05", "%.0Rg", x); + check_sprintf ("1e+05", "%.5Rg", x); + check_sprintf ("100000", "%.6Rg", x); + + mpfr_ui_div (x, 1, x, MPFR_RNDN); + check_sprintf ("1e-05", "%Rg", x); + check_sprintf ("1e-05", "%.0Rg", x); + check_sprintf ("1e-05", "%.1Rg", x); + + /* check rounding mode */ + mpfr_set_str (x, "0.0076", 10, MPFR_RNDN); + check_sprintf ("0.007", "%.3RDF", x); + check_sprintf ("0.007", "%.3RZF", x); + check_sprintf ("0.008", "%.3RF", x); + check_sprintf ("0.008", "%.3RUF", x); + check_sprintf ("0.008", "%.3RYF", x); + check_vsprintf ("0.008", "%.3R*F", MPFR_RNDA, x); + + /* check limit between %f-style and %g-style */ + mpfr_set_str (x, "0.0000999", 10, MPFR_RNDN); + check_sprintf ("0.0001", "%.0Rg", x); + check_sprintf ("9e-05", "%.0RDg", x); + check_sprintf ("0.0001", "%.1Rg", x); + check_sprintf ("0.0001", "%.2Rg", x); + check_sprintf ("9.99e-05", "%.3Rg", x); + + /* trailing zeros */ + mpfr_set_si_2exp (x, -1, -15, MPFR_RNDN); /* x=-2^-15 */ + check_sprintf ("-3.0517578125e-05", "%.30Rg", x); + check_sprintf ("-3.051757812500000000000000000000e-05", "%.30Re", x); + check_sprintf ("-3.05175781250000000000000000000e-05", "%#.30Rg", x); + check_sprintf ("-0.000030517578125000000000000000", "%.30Rf", x); + + /* bug 20081023 */ + check_sprintf ("-3.0517578125e-05", "%.30Rg", x); + mpfr_set_str (x, "1.9999", 10, MPFR_RNDN); + check_sprintf ("1.999900 ", "%-#10.7RG", x); + check_sprintf ("1.9999 ", "%-10.7RG", x); + mpfr_set_ui (x, 1, MPFR_RNDN); + check_sprintf ("1.", "%#.1Rg", x); + check_sprintf ("1. ", "%-#5.1Rg", x); + check_sprintf (" 1.0", "%#5.2Rg", x); + check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x); + check_sprintf ("1", "%.30Rg", x); + mpfr_set_ui (x, 0, MPFR_RNDN); + check_sprintf ("0.", "%#.1Rg", x); + check_sprintf ("0. ", "%-#5.1Rg", x); + check_sprintf (" 0.0", "%#5.2Rg", x); + check_sprintf ("0.00000000000000000000000000000", "%#.30Rg", x); + check_sprintf ("0", "%.30Rg", x); + + /* following tests with precision 53 bits */ + mpfr_set_prec (x, 53); + + /* Exponent zero has a plus sign */ + mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10, + MPFR_RNDN); + check_sprintf ("-1.0e+00", "%- #0.1Re", x); + + /* Decimal point and no figure after it with '#' flag and 'G' style */ + mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN); + check_sprintf ("-1.", "%- #0.1RG", x); + + /* precision zero */ + mpfr_set_d (x, 9.5, MPFR_RNDN); + check_sprintf ("9", "%.0RDf", x); + check_sprintf ("10", "%.0RUf", x); + + mpfr_set_d (x, 19.5, MPFR_RNDN); + check_sprintf ("19", "%.0RDf", x); + check_sprintf ("20", "%.0RUf", x); + + mpfr_set_d (x, 99.5, MPFR_RNDN); + check_sprintf ("99", "%.0RDf", x); + check_sprintf ("100", "%.0RUf", x); + + mpfr_set_d (x, -9.5, MPFR_RNDN); + check_sprintf ("-10", "%.0RDf", x); + check_sprintf ("-10", "%.0RYf", x); + check_sprintf ("-10", "%.0Rf", x); + check_sprintf ("-1e+01", "%.0Re", x); + check_sprintf ("-1e+01", "%.0Rg", x); + mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN); + check_sprintf ("0", "%.0Rf", x); + check_sprintf ("5e-01", "%.0Re", x); + check_sprintf ("0.5", "%.0Rg", x); + mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN); + check_sprintf ("2", "%.0Rf", x); + mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN); + check_sprintf ("2", "%.0Rf", x); + mpfr_set_ui (x, 0x1f, MPFR_RNDN); + check_sprintf ("0x1p+5", "%.0Ra", x); + mpfr_set_ui (x, 3, MPFR_RNDN); + check_sprintf ("1p+2", "%.0Rb", x); + + /* round to next ten power with %f but not with %g */ + mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN); + check_sprintf ("-0.1", "%.1Rf", x); + check_sprintf ("-0.0", "%.1RZf", x); + check_sprintf ("-0.07", "%.1Rg", x); + check_sprintf ("-0.06", "%.1RZg", x); + + /* round to next ten power and do not remove trailing zeros */ + mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN); + check_sprintf ("0.1", "%#.1Rg", x); + check_sprintf ("0.10", "%#.2Rg", x); + check_sprintf ("0.099", "%#.2RZg", x); + + /* Halfway cases */ + mpfr_set_str (x, "1.5", 10, MPFR_RNDN); + check_sprintf ("2e+00", "%.0Re", x); + mpfr_set_str (x, "2.5", 10, MPFR_RNDN); + check_sprintf ("2e+00", "%.0Re", x); + mpfr_set_str (x, "9.5", 10, MPFR_RNDN); + check_sprintf ("1e+01", "%.0Re", x); + mpfr_set_str (x, "1.25", 10, MPFR_RNDN); + check_sprintf ("1.2e+00", "%.1Re", x); + mpfr_set_str (x, "1.75", 10, MPFR_RNDN); + check_sprintf ("1.8e+00", "%.1Re", x); + mpfr_set_str (x, "-0.5", 10, MPFR_RNDN); + check_sprintf ("-0", "%.0Rf", x); + mpfr_set_str (x, "1.25", 10, MPFR_RNDN); + check_sprintf ("1.2", "%.1Rf", x); + mpfr_set_str (x, "1.75", 10, MPFR_RNDN); + check_sprintf ("1.8", "%.1Rf", x); + mpfr_set_str (x, "1.5", 10, MPFR_RNDN); + check_sprintf ("2", "%.1Rg", x); + mpfr_set_str (x, "2.5", 10, MPFR_RNDN); + check_sprintf ("2", "%.1Rg", x); + mpfr_set_str (x, "9.25", 10, MPFR_RNDN); + check_sprintf ("9.2", "%.2Rg", x); + mpfr_set_str (x, "9.75", 10, MPFR_RNDN); + check_sprintf ("9.8", "%.2Rg", x); + + /* assertion failure in r6320 */ + mpfr_set_str (x, "-9.996", 10, MPFR_RNDN); + check_sprintf ("-10.0", "%.1Rf", x); + + mpfr_clears (x, z, (mpfr_ptr) 0); + return 0; +} + +static int +hexadecimal (void) +{ + mpfr_t x, z; + mpfr_inits2 (64, x, z, (mpfr_ptr) 0); + + /* special */ + mpfr_set_inf (x, 1); + check_sprintf (pinf_str, "%Ra", x); + check_sprintf (pinf_str, "%RUa", x); + check_sprintf (pinf_str, "%RDa", x); + check_sprintf (pinf_uc_str, "%RA", x); + check_sprintf (pinf_uc_str, "%RYA", x); + check_sprintf (pinf_uc_str, "%RZA", x); + check_sprintf (pinf_uc_str, "%RNA", x); + + mpfr_set_inf (x, -1); + check_sprintf (minf_str, "%Ra", x); + check_sprintf (minf_str, "%RYa", x); + check_sprintf (minf_str, "%RZa", x); + check_sprintf (minf_str, "%RNa", x); + check_sprintf (minf_uc_str, "%RA", x); + check_sprintf (minf_uc_str, "%RUA", x); + check_sprintf (minf_uc_str, "%RDA", x); + + mpfr_set_nan (x); + check_sprintf (nan_str, "%Ra", x); + check_sprintf (nan_uc_str, "%RA", x); + + /* regular numbers */ + mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN); + mpfr_set_ui (z, 0, MPFR_RNDZ); + + /* simplest case right justified */ + check_sprintf (" 0xf.edcba987654321p+24", "%25Ra", x); + check_sprintf (" 0xf.edcba987654321p+24", "%25RUa", x); + check_sprintf (" 0xf.edcba987654321p+24", "%25RDa", x); + check_sprintf (" 0xf.edcba987654321p+24", "%25RYa", x); + check_sprintf (" 0xf.edcba987654321p+24", "%25RZa", x); + check_sprintf (" 0xf.edcba987654321p+24", "%25RNa", x); + check_sprintf (" 0x1p+28", "%25.0Ra", x); + check_sprintf (" 0x0p+0", "%25.0Ra", z); + /* sign or space, pad with leading zeros */ + check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x); + check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x); + check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z); + /* sign + or -, left justified */ + check_sprintf ("+0xf.edcba987654321p+24 ", "%+-25Ra", x); + check_sprintf ("+0x1p+28 ", "%+-25.0Ra", x); + check_sprintf ("+0x0p+0 ", "%+-25.0Ra", z); + /* decimal point, left justified, precision and rounding parameter */ + check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x); + check_vsprintf ("0X1.P+28 ", "%#-10.*R*A", 0, MPFR_RNDN, x); + check_vsprintf ("0X0.P+0 ", "%#-10.*R*A", 0, MPFR_RNDN, z); + /* sign or space */ + check_sprintf (" 0xf.eddp+24", "% .3RNa", x); + check_sprintf (" 0x1p+28", "% .0RNa", x); + /* sign + or -, decimal point, pad with leading zeros */ + check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x); + check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x); + check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z); + /* pad with leading zero */ + check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x); + check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x); + /* sign or space, decimal point, left justified */ + check_sprintf (" 0XF.EP+24 " , "%- #11.1RDA", x); + check_sprintf (" 0XF.P+24 " , "%- #11.0RDA", x); + + mpfr_mul_si (x, x, -1, MPFR_RNDD); + mpfr_mul_si (z, z, -1, MPFR_RNDD); + + /* sign + or - */ + check_sprintf ("-0xf.ep+24", "%+10.1RUa", x); + check_sprintf (" -0xfp+24", "%+10.0RUa", x); + check_sprintf (" -0x0p+0", "%+10.0RUa", z); + + /* rounding bit is zero */ + mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN); + check_sprintf ("0XFP+0", "%.0RNA", x); + /* tie case in round to nearest mode */ + mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN); + check_sprintf ("0x9.p-1", "%#.0RNa", x); + mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN); + check_sprintf ("-0xap-1", "%.0RNa", x); + /* trailing zeros in fractional part */ + check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x); + /* rounding bit is one and the first non zero bit is far away */ + mpfr_set_prec (x, 1024); + mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN); + mpfr_nextabove (x); + check_sprintf ("0XFP+0", "%.0RNA", x); + + /* with more than one limb */ + mpfr_set_prec (x, 300); + mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffff", 16, MPFR_RNDN); + check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x); + check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x); + check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x); + check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x); + check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x); + check_sprintf ("0x1.0000000000000000000000000000000000000000p+4", + "%.40RNa", x); + check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0", + "%.40RZa", x); + check_sprintf ("0x1.0000000000000000000000000000000000000000p+4", + "%.40RYa", x); + check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0", + "%.40RDa", x); + check_sprintf ("0x1.0000000000000000000000000000000000000000p+4", + "%.40RUa", x); + + mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffff", 16, MPFR_RNDN); + check_sprintf ("0XFP+0", "%.0RNA", x); + check_sprintf ("0XFP+0", "%.0RZA", x); + check_sprintf ("0X1P+4", "%.0RYA", x); + check_sprintf ("0XFP+0", "%.0RDA", x); + check_sprintf ("0X1P+4", "%.0RUA", x); + check_sprintf ("0XF.8P+0", "%.1RNA", x); + check_sprintf ("0XF.7P+0", "%.1RZA", x); + check_sprintf ("0XF.8P+0", "%.1RYA", x); + check_sprintf ("0XF.7P+0", "%.1RDA", x); + check_sprintf ("0XF.8P+0", "%.1RUA", x); + + /* do not round up to the next power of the base */ + mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff" + "ffffffffffffffffff", 16, MPFR_RNDN); + check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0", + "%.40RNa", x); + check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0", + "%.40RZa", x); + check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0", + "%.40RYa", x); + check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0", + "%.40RDa", x); + check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0", + "%.40RUa", x); + + mpfr_clears (x, z, (mpfr_ptr) 0); + return 0; +} + +static int +binary (void) +{ + mpfr_t x; + mpfr_t z; + mpfr_inits2 (64, x, z, (mpfr_ptr) 0); + + /* special */ + mpfr_set_inf (x, 1); + check_sprintf (pinf_str, "%Rb", x); + + mpfr_set_inf (x, -1); + check_sprintf (minf_str, "%Rb", x); + + mpfr_set_nan (x); + check_sprintf (nan_str, "%Rb", x); + + /* regular numbers */ + mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN); + mpfr_set_ui (z, 0, MPFR_RNDN); + + /* simplest case: right justified */ + check_sprintf (" 1.1100101011001101p+9", "%25Rb", x); + check_sprintf (" 0p+0", "%25Rb", z); + /* sign or space, pad with leading zeros */ + check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x); + check_sprintf (" 000000000000000000000p+0", "% 025Rb", z); + /* sign + or -, left justified */ + check_sprintf ("+1.1100101011001101p+9 ", "%+-25Rb", x); + check_sprintf ("+0p+0 ", "%+-25Rb", z); + /* sign or space */ + check_sprintf (" 1.110p+9", "% .3RNb", x); + check_sprintf (" 1.1101p+9", "% .4RNb", x); + check_sprintf (" 0.0000p+0", "% .4RNb", z); + /* sign + or -, decimal point, pad with leading zeros */ + check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x); + check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x); + check_sprintf ("+000000.p+0", "%0+#11.0RNb", z); + /* pad with leading zero */ + check_sprintf ("00001.1100101011001101p+9", "%025RDb", x); + /* sign or space, decimal point (unused), left justified */ + check_sprintf (" 1.1p+9 ", "%- #11.1RDb", x); + check_sprintf (" 1.p+9 ", "%- #11.0RDb", x); + check_sprintf (" 1.p+10 ", "%- #11.0RUb", x); + check_sprintf (" 1.p+9 ", "%- #11.0RZb", x); + check_sprintf (" 1.p+10 ", "%- #11.0RYb", x); + check_sprintf (" 1.p+10 ", "%- #11.0RNb", x); + + mpfr_mul_si (x, x, -1, MPFR_RNDD); + mpfr_mul_si (z, z, -1, MPFR_RNDD); + + /* sign + or - */ + check_sprintf (" -1.1p+9", "%+10.1RUb", x); + check_sprintf (" -0.0p+0", "%+10.1RUb", z); + + /* precision 0 */ + check_sprintf ("-1p+10", "%.0RNb", x); + check_sprintf ("-1p+10", "%.0RDb", x); + check_sprintf ("-1p+9", "%.0RUb", x); + check_sprintf ("-1p+9", "%.0RZb", x); + check_sprintf ("-1p+10", "%.0RYb", x); + /* round to next base power */ + check_sprintf ("-1.0p+10", "%.1RNb", x); + check_sprintf ("-1.0p+10", "%.1RDb", x); + check_sprintf ("-1.0p+10", "%.1RYb", x); + /* do not round to next base power */ + check_sprintf ("-1.1p+9", "%.1RUb", x); + check_sprintf ("-1.1p+9", "%.1RZb", x); + /* rounding bit is zero */ + check_sprintf ("-1.11p+9", "%.2RNb", x); + /* tie case in round to nearest mode */ + check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x); + /* trailing zeros in fractional part */ + check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x); + + mpfr_clears (x, z, (mpfr_ptr) 0); + return 0; +} + +static int +mixed (void) +{ + int n1; + int n2; + int i = 121; +#ifndef NPRINTF_L + long double d = 1. / 31.; +#endif + mpf_t mpf; + mpq_t mpq; + mpz_t mpz; + mpfr_t x; + mpfr_rnd_t rnd; + + mpf_init (mpf); + mpf_set_ui (mpf, 40); + mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */ + mpq_init (mpq); + mpq_set_ui (mpq, 123456, 4567890); + mpz_init (mpz); + mpz_fib_ui (mpz, 64); + mpfr_init (x); + mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN); + rnd = MPFR_RNDD; + + check_vsprintf ("121%", "%i%%", i); + check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x); + check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x); + check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd, + x); + check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i); + check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq); + n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", "%i, %.*Rf, %Ff%n", + i, 12, x, mpf, &n2); + if (n1 != n2) + { + printf ("error in number of characters written by mpfr_vsprintf\n"); + printf ("expected: %d\n", n2); + printf (" got: %d\n", n1); + exit (1); + } + +#ifndef NPRINTF_L + check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258", + "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d); +#endif + + mpf_clear (mpf); + mpq_clear (mpq); + mpz_clear (mpz); + mpfr_clear (x); + return 0; +} + +#if MPFR_LCONV_DPTS + +/* Check with locale "da_DK". On most platforms, decimal point is ',' + and thousands separator is '.'; the test is not performed if this + is not the case or if the locale doesn't exist. */ +static int +locale_da_DK (void) +{ + mpfr_prec_t p = 128; + mpfr_t x; + + if (setlocale (LC_ALL, "da_DK") == 0 || + localeconv()->decimal_point[0] != ',' || + localeconv()->thousands_sep[0] != '.') + return 0; + + mpfr_init2 (x, p); + + /* positive numbers */ + mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); + + /* simplest case right justified with thousands separator */ + check_sprintf (" 1,899347461279296875e+07", "%'30Re", x); + check_sprintf (" 1,89935e+07", "%'30Rg", x); + check_sprintf (" 18.993.474,61279296875", "%'30.19Rg", x); + check_sprintf (" 18.993.474,612793", "%'30Rf", x); + + /* sign or space, pad, thousands separator with leading zeros */ + check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", x); + check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x); + check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x); + check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x); + + mpfr_set_ui (x, 50, MPFR_RNDN); + mpfr_exp10 (x, x, MPFR_RNDN); + check_sprintf ("100000000000000000000000000000000000000000000000000", "%.0Rf", + x); + check_sprintf + ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,", + "%'#.0Rf", x); + check_sprintf + ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,0000", + "%'.4Rf", x); + + mpfr_clear (x); + return 0; +} + +#endif /* MPFR_LCONV_DPTS */ + +/* check concordance between mpfr_asprintf result with a regular mpfr float + and with a regular double float */ +static int +random_double (void) +{ + mpfr_t x; /* random regular mpfr float */ + double y; /* regular double float (equal to x) */ + + char flag[] = + { + '-', + '+', + ' ', + '#', + '0', /* no ambiguity: first zeros are flag zero*/ + '\'' + }; + /* no 'a': mpfr and glibc do not have the same semantic */ + char specifier[] = + { + 'e', + 'f', + 'g', + 'E', + 'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for + regular numbers */ + 'G', + }; + int spec; /* random index in specifier[] */ + int prec; /* random value for precision field */ + + /* in the format string for mpfr_t variable, the maximum length is + reached by something like "%-+ #0'.*Rf", that is 12 characters. */ +#define FMT_MPFR_SIZE 12 + char fmt_mpfr[FMT_MPFR_SIZE]; + char *ptr_mpfr; + + /* in the format string for double variable, the maximum length is + reached by something like "%-+ #0'.*f", that is 11 characters. */ +#define FMT_SIZE 11 + char fmt[FMT_SIZE]; + char *ptr; + + int xi; + char *xs; + int yi; + char *ys; + + int i, j, jmax; + + mpfr_init2 (x, MPFR_LDBL_MANT_DIG); + + for (i = 0; i < 1000; ++i) + { + /* 1. random double */ + do + { + y = DBL_RAND (); + } +#ifdef HAVE_DENORMS + while (0); +#else + while (ABS(y) < DBL_MIN); +#endif + + if (randlimb () % 2 == 0) + y = -y; + + mpfr_set_d (x, y, MPFR_RNDN); + if (y != mpfr_get_d (x, MPFR_RNDN)) + /* conversion error: skip this one */ + continue; + + /* 2. build random format strings fmt_mpfr and fmt */ + ptr_mpfr = fmt_mpfr; + ptr = fmt; + *ptr_mpfr++ = *ptr++ = '%'; + /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */ + spec = (int) (randlimb() % 6); + /* random flags, but no ' flag with %e */ + jmax = (spec == 0 || spec == 3) ? 5 : 6; + for (j = 0; j < jmax; j++) + { + if (randlimb() % 3 == 0) + *ptr_mpfr++ = *ptr++ = flag[j]; + } + *ptr_mpfr++ = *ptr++ = '.'; + *ptr_mpfr++ = *ptr++ = '*'; + *ptr_mpfr++ = 'R'; + *ptr_mpfr++ = *ptr++ = specifier[spec]; + *ptr_mpfr = *ptr = '\0'; + MPFR_ASSERTN (ptr - fmt < FMT_SIZE); + MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE); + + /* advantage small precision */ + if (randlimb() % 2 == 0) + prec = (int) (randlimb() % 10); + else + prec = (int) (randlimb() % prec_max_printf); + + /* 3. calls and checks */ + /* the double float case is handled by the libc asprintf through + gmp_asprintf */ + xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x); + yi = mpfr_asprintf (&ys, fmt, prec, y); + + /* test if XS and YS differ, beware that ISO C99 doesn't specify + the sign of a zero exponent (the C99 rationale says: "The sign + of a zero exponent in %e format is unspecified. The committee + knows of different implementations and choose not to require + implementations to document their behaviour in this case + (by making this be implementation defined behaviour). Most + implementations use a "+" sign, e.g., 1.2e+00; but there is at + least one implementation that uses the sign of the unlimited + precision result, e.g., the 0.987 would be 9.87e-01, so could + end up as 1e-00 after rounding to one digit of precision."), + while mpfr always uses '+' */ + if (xi != yi + || ((strcmp (xs, ys) != 0) + && (spec == 1 || spec == 4 + || ((strstr (xs, "e+00") == NULL + || strstr (ys, "e-00") == NULL) + && (strstr (xs, "E+00") == NULL + || strstr (ys, "E-00") == NULL))))) + { + mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n", + fmt_mpfr, prec, x); + printf ("expected: %s\n", ys); + printf (" got: %s\n", xs); + printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec); + + exit (1); + } + + mpfr_free_str (xs); + mpfr_free_str (ys); + } + + mpfr_clear (x); + return 0; +} + +static void +bug20080610 (void) +{ + /* bug on icc found on June 10, 2008 */ + /* this is not a bug but a different implementation choice: ISO C99 doesn't + specify the sign of a zero exponent (see note in random_double above). */ + mpfr_t x; + double y; + int xi; + char *xs; + int yi; + char *ys; + + mpfr_init2 (x, MPFR_LDBL_MANT_DIG); + + y = -9.95645044213728791504536275169812142849e-01; + mpfr_set_d (x, y, MPFR_RNDN); + + xi = mpfr_asprintf (&xs, "%- #0.*Re", 1, x); + yi = mpfr_asprintf (&ys, "%- #0.*e", 1, y); + + if (xi != yi || strcmp (xs, ys) != 0) + { + printf ("Error in bug20080610\n"); + printf ("expected: %s\n", ys); + printf (" got: %s\n", xs); + printf ("xi=%d yi=%d\n", xi, yi); + + exit (1); + } + + mpfr_free_str (xs); + mpfr_free_str (ys); + mpfr_clear (x); +} + +static void +bug20081214 (void) +{ + /* problem with glibc 2.3.6, December 14, 2008: + the system asprintf outputs "-1.0" instead of "-1.". */ + mpfr_t x; + double y; + int xi; + char *xs; + int yi; + char *ys; + + mpfr_init2 (x, MPFR_LDBL_MANT_DIG); + + y = -9.90597761233942053494e-01; + mpfr_set_d (x, y, MPFR_RNDN); + + xi = mpfr_asprintf (&xs, "%- #0.*RG", 1, x); + yi = mpfr_asprintf (&ys, "%- #0.*G", 1, y); + + if (xi != yi || strcmp (xs, ys) != 0) + { + mpfr_printf ("Error in bug20081214\n" + "mpfr_asprintf(\"%- #0.*Re\", 1, %Re)\n", x); + printf ("expected: %s\n", ys); + printf (" got: %s\n", xs); + printf ("xi=%d yi=%d\n", xi, yi); + + exit (1); + } + + mpfr_free_str (xs); + mpfr_free_str (ys); + mpfr_clear (x); +} + +static void +bug20111102 (void) +{ + mpfr_t t; + char s[100]; + + mpfr_init2 (t, 84); + mpfr_set_str (t, "999.99999999999999999999", 10, MPFR_RNDN); + mpfr_sprintf (s, "%.20RNg", t); + if (strcmp (s, "1000") != 0) + { + printf ("Error in bug20111102, expected 1000, got %s\n", s); + exit (1); + } + mpfr_clear (t); +} + +/* In particular, the following test makes sure that the rounding + * for %Ra and %Rb is not done on the MPFR number itself (as it + * would overflow). Note: it has been reported on comp.std.c that + * some C libraries behave differently on %a, but this is a bug. + */ +static void +check_emax_aux (mpfr_exp_t e) +{ + mpfr_t x; + char *s1, s2[256]; + int i; + mpfr_exp_t emax; + + MPFR_ASSERTN (e <= LONG_MAX); + emax = mpfr_get_emax (); + set_emax (e); + + mpfr_init2 (x, 16); + + mpfr_set_inf (x, 1); + mpfr_nextbelow (x); + + i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x); + MPFR_ASSERTN (i > 0); + + mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3); + + if (strcmp (s1, s2) != 0) + { + printf ("Error in check_emax_aux for emax = "); + if (e > LONG_MAX) + printf ("(>LONG_MAX)\n"); + else + printf ("%ld\n", (long) e); + printf ("Expected %s\n", s2); + printf ("Got %s\n", s1); + exit (1); + } + + mpfr_free_str (s1); + + i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x); + MPFR_ASSERTN (i > 0); + + mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e); + + if (strcmp (s1, s2) != 0) + { + printf ("Error in check_emax_aux for emax = "); + if (e > LONG_MAX) + printf ("(>LONG_MAX)\n"); + else + printf ("%ld\n", (long) e); + printf ("Expected %s\n", s2); + printf ("Got %s\n", s1); + exit (1); + } + + mpfr_free_str (s1); + + mpfr_clear (x); + set_emax (emax); +} + +static void +check_emax (void) +{ + check_emax_aux (15); + check_emax_aux (MPFR_EMAX_MAX); +} + +static void +check_emin_aux (mpfr_exp_t e) +{ + mpfr_t x; + char *s1, s2[256]; + int i; + mpfr_exp_t emin; + mpz_t ee; + + MPFR_ASSERTN (e >= LONG_MIN); + emin = mpfr_get_emin (); + set_emin (e); + + mpfr_init2 (x, 16); + mpz_init (ee); + + mpfr_setmin (x, e); + mpz_set_si (ee, e); + mpz_sub_ui (ee, ee, 1); + + i = mpfr_asprintf (&s1, "%Ra", x); + MPFR_ASSERTN (i > 0); + + gmp_snprintf (s2, 256, "0x1p%Zd", ee); + + if (strcmp (s1, s2) != 0) + { + printf ("Error in check_emin_aux for emin = %ld\n", (long) e); + printf ("Expected %s\n", s2); + printf ("Got %s\n", s1); + exit (1); + } + + mpfr_free_str (s1); + + i = mpfr_asprintf (&s1, "%Rb", x); + MPFR_ASSERTN (i > 0); + + gmp_snprintf (s2, 256, "1p%Zd", ee); + + if (strcmp (s1, s2) != 0) + { + printf ("Error in check_emin_aux for emin = %ld\n", (long) e); + printf ("Expected %s\n", s2); + printf ("Got %s\n", s1); + exit (1); + } + + mpfr_free_str (s1); + + mpfr_clear (x); + mpz_clear (ee); + set_emin (emin); +} + +static void +check_emin (void) +{ + check_emin_aux (-15); + check_emin_aux (mpfr_get_emin ()); + check_emin_aux (MPFR_EMIN_MIN); +} + +int +main (int argc, char **argv) +{ + char *locale; + + tests_start_mpfr (); + +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) + /* currently, we just check with 'C' locale */ + locale = setlocale (LC_ALL, "C"); +#endif + + bug20111102 (); + native_types (); + hexadecimal (); + binary (); + decimal (); + mixed (); + check_emax (); + check_emin (); + +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) +#if MPFR_LCONV_DPTS + locale_da_DK (); + /* Avoid a warning by doing the setlocale outside of this #if */ +#endif + setlocale (LC_ALL, locale); +#endif + + if (getenv ("MPFR_CHECK_LIBC_PRINTF")) + { + /* check against libc */ + random_double (); + bug20081214 (); + bug20080610 (); + } + + tests_end_mpfr (); + return 0; +} + +#else /* MPFR_VERSION */ + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif /* MPFR_VERSION */ + +#else /* HAVE_STDARG */ + +int +main (void) +{ + /* We have nothing to test. */ + return 77; +} + +#endif /* HAVE_STDARG */ diff --git a/mpfr/tests/tsqr.c b/mpfr/tests/tsqr.c new file mode 100644 index 0000000000..ab8674bec9 --- /dev/null +++ b/mpfr/tests/tsqr.c @@ -0,0 +1,178 @@ +/* Test file for mpfr_sqr. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_sqr +#include "tgeneric.c" + +static int +inexact_sign (int x) +{ + return (x < 0) ? -1 : (x > 0); +} + +static void +error1 (mpfr_rnd_t rnd, mpfr_prec_t prec, + mpfr_t in, mpfr_t outmul, mpfr_t outsqr) +{ + printf("ERROR: for %s and prec=%lu\nINPUT=", mpfr_print_rnd_mode(rnd), + (unsigned long) prec); + mpfr_dump(in); + printf("OutputMul="); mpfr_dump(outmul); + printf("OutputSqr="); mpfr_dump(outsqr); + exit(1); +} + +static void +error2 (mpfr_rnd_t rnd, mpfr_prec_t prec, mpfr_t in, mpfr_t out, + int inexactmul, int inexactsqr) +{ + printf("ERROR: for %s and prec=%lu\nINPUT=", mpfr_print_rnd_mode(rnd), + (unsigned long) prec); + mpfr_dump(in); + printf("Output="); mpfr_dump(out); + printf("InexactMul= %d InexactSqr= %d\n", inexactmul, inexactsqr); + exit(1); +} + +static void +check_random (mpfr_prec_t p) +{ + mpfr_t x,y,z; + int r; + int i, inexact1, inexact2; + + mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0); + for(i = 0 ; i < 500 ; i++) + { + mpfr_urandomb (x, RANDS); + if (MPFR_IS_PURE_FP(x)) + for (r = 0 ; r < MPFR_RND_MAX ; r++) + { + inexact1 = mpfr_mul (y, x, x, (mpfr_rnd_t) r); + inexact2 = mpfr_sqr (z, x, (mpfr_rnd_t) r); + if (mpfr_cmp (y, z)) + error1 ((mpfr_rnd_t) r,p,x,y,z); + if (inexact_sign (inexact1) != inexact_sign (inexact2)) + error2 ((mpfr_rnd_t) r,p,x,y,inexact1,inexact2); + } + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +static void +check_special (void) +{ + mpfr_t x, y; + mpfr_exp_t emin; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_sqr (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); + mpfr_sqr (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0); + + mpfr_set_inf (x, -1); + mpfr_sqr (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0); + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_sqr (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (y)); + + emin = mpfr_get_emin (); + mpfr_set_emin (0); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + MPFR_ASSERTN (!mpfr_zero_p (x)); + mpfr_sqr (y, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_zero_p (y)); + mpfr_set_emin (emin); + + mpfr_clear (y); + mpfr_clear (x); +} + +/* Test of a bug seen with GCC 4.5.2 and GMP 5.0.1 on m68k (m68000 target). + https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00003.html + https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00041.html +*/ +static void +check_mpn_sqr (void) +{ +#if GMP_NUMB_BITS == 32 && __GNU_MP_VERSION >= 5 + /* Note: since we test a low-level bug, src is initialized + without using a GMP function, just in case. */ + mp_limb_t src[5] = + { 0x90000000, 0xbaa55f4f, 0x2cbec4d9, 0xfcef3242, 0xda827999 }; + mp_limb_t exd[10] = + { 0x00000000, 0x31000000, 0xbd4bc59a, 0x41fbe2b5, 0x33471e7e, + 0x90e826a7, 0xbaa55f4f, 0x2cbec4d9, 0xfcef3242, 0xba827999 }; + mp_limb_t dst[10]; + int i; + + mpn_sqr (dst, src, 5); /* new in GMP 5 */ + for (i = 0; i < 10; i++) + { + if (dst[i] != exd[i]) + { + printf ("Error in check_mpn_sqr\n"); + printf ("exd[%d] = 0x%08lx\n", i, (unsigned long) exd[i]); + printf ("dst[%d] = 0x%08lx\n", i, (unsigned long) dst[i]); + printf ("Note: This is not a bug in MPFR, but a bug in" + " either GMP or, more\nprobably, in the compiler." + " It may cause other tests to fail.\n"); + exit (1); + } + } +#endif +} + +int +main (void) +{ + mpfr_prec_t p; + + tests_start_mpfr (); + + check_mpn_sqr (); + + check_special (); + for (p = 2; p < 200; p++) + check_random (p); + + test_generic (2, 200, 15); + data_check ("data/sqr", mpfr_sqr, "mpfr_sqr"); + bad_cases (mpfr_sqr, mpfr_sqrt, "mpfr_sqr", 8, -256, 255, 4, 128, 800, 50); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsqrt.c b/mpfr/tests/tsqrt.c new file mode 100644 index 0000000000..e1fd4261c1 --- /dev/null +++ b/mpfr/tests/tsqrt.c @@ -0,0 +1,740 @@ +/* Test file for mpfr_sqrt. + +Copyright 1999, 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_sqrt (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b); + if (ok) + { + mpfr_print_raw (b); + } + res = mpfr_sqrt (a, b, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_sqrt mpfr_sqrt +#endif + +static void +check3 (const char *as, mpfr_rnd_t rnd_mode, const char *qs) +{ + mpfr_t q; + + mpfr_init2 (q, 53); + mpfr_set_str1 (q, as); + test_sqrt (q, q, rnd_mode); + if (mpfr_cmp_str1 (q, qs) ) + { + printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n", + as, mpfr_print_rnd_mode (rnd_mode)); + printf ("expected sqrt is %s, got ",qs); + mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + mpfr_clear (q); +} + +static void +check4 (const char *as, mpfr_rnd_t rnd_mode, const char *Qs) +{ + mpfr_t q; + + mpfr_init2 (q, 53); + mpfr_set_str1 (q, as); + test_sqrt (q, q, rnd_mode); + if (mpfr_cmp_str (q, Qs, 16, MPFR_RNDN)) + { + printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n", + as, mpfr_print_rnd_mode(rnd_mode)); + printf ("expected "); + mpfr_out_str (stdout, 16, 0, q, MPFR_RNDN); + printf ("\ngot %s\n", Qs); + mpfr_clear (q); + exit (1); + } + mpfr_clear (q); +} + +static void +check24 (const char *as, mpfr_rnd_t rnd_mode, const char *qs) +{ + mpfr_t q; + + mpfr_init2 (q, 24); + mpfr_set_str1 (q, as); + test_sqrt (q, q, rnd_mode); + if (mpfr_cmp_str1 (q, qs)) + { + printf ("mpfr_sqrt failed for a=%s, prec=24, rnd_mode=%s\n", + as, mpfr_print_rnd_mode(rnd_mode)); + printf ("expected sqrt is %s, got ",qs); + mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clear (q); +} + +static void +check_diverse (const char *as, mpfr_prec_t p, const char *qs) +{ + mpfr_t q; + + mpfr_init2 (q, p); + mpfr_set_str1 (q, as); + test_sqrt (q, q, MPFR_RNDN); + if (mpfr_cmp_str1 (q, qs)) + { + printf ("mpfr_sqrt failed for a=%s, prec=%lu, rnd_mode=%s\n", + as, (unsigned long) p, mpfr_print_rnd_mode (MPFR_RNDN)); + printf ("expected sqrt is %s, got ", qs); + mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clear (q); +} + +/* the following examples come from the paper "Number-theoretic Test + Generation for Directed Rounding" from Michael Parks, Table 3 */ +static void +check_float (void) +{ + check24("70368760954880.0", MPFR_RNDN, "8.388609e6"); + check24("281474943156224.0", MPFR_RNDN, "1.6777215e7"); + check24("70368777732096.0", MPFR_RNDN, "8.388610e6"); + check24("281474909601792.0", MPFR_RNDN, "1.6777214e7"); + check24("100216216748032.0", MPFR_RNDN, "1.0010805e7"); + check24("120137273311232.0", MPFR_RNDN, "1.0960715e7"); + check24("229674600890368.0", MPFR_RNDN, "1.5155019e7"); + check24("70368794509312.0", MPFR_RNDN, "8.388611e6"); + check24("281474876047360.0", MPFR_RNDN, "1.6777213e7"); + check24("91214552498176.0", MPFR_RNDN, "9.550631e6"); + + check24("70368760954880.0", MPFR_RNDZ, "8.388608e6"); + check24("281474943156224.0", MPFR_RNDZ, "1.6777214e7"); + check24("70368777732096.0", MPFR_RNDZ, "8.388609e6"); + check24("281474909601792.0", MPFR_RNDZ, "1.6777213e7"); + check24("100216216748032.0", MPFR_RNDZ, "1.0010805e7"); + check24("120137273311232.0", MPFR_RNDZ, "1.0960715e7"); + check24("229674600890368.0", MPFR_RNDZ, "1.5155019e7"); + check24("70368794509312.0", MPFR_RNDZ, "8.38861e6"); + check24("281474876047360.0", MPFR_RNDZ, "1.6777212e7"); + check24("91214552498176.0", MPFR_RNDZ, "9.550631e6"); + + check24("70368760954880.0", MPFR_RNDU, "8.388609e6"); + check24("281474943156224.0",MPFR_RNDU, "1.6777215e7"); + check24("70368777732096.0", MPFR_RNDU, "8.388610e6"); + check24("281474909601792.0", MPFR_RNDU, "1.6777214e7"); + check24("100216216748032.0", MPFR_RNDU, "1.0010806e7"); + check24("120137273311232.0", MPFR_RNDU, "1.0960716e7"); + check24("229674600890368.0", MPFR_RNDU, "1.515502e7"); + check24("70368794509312.0", MPFR_RNDU, "8.388611e6"); + check24("281474876047360.0", MPFR_RNDU, "1.6777213e7"); + check24("91214552498176.0", MPFR_RNDU, "9.550632e6"); + + check24("70368760954880.0", MPFR_RNDD, "8.388608e6"); + check24("281474943156224.0", MPFR_RNDD, "1.6777214e7"); + check24("70368777732096.0", MPFR_RNDD, "8.388609e6"); + check24("281474909601792.0", MPFR_RNDD, "1.6777213e7"); + check24("100216216748032.0", MPFR_RNDD, "1.0010805e7"); + check24("120137273311232.0", MPFR_RNDD, "1.0960715e7"); + check24("229674600890368.0", MPFR_RNDD, "1.5155019e7"); + check24("70368794509312.0", MPFR_RNDD, "8.38861e6"); + check24("281474876047360.0", MPFR_RNDD, "1.6777212e7"); + check24("91214552498176.0", MPFR_RNDD, "9.550631e6"); + + /* check that rounding away is just rounding toward plus infinity */ + check24("91214552498176.0", MPFR_RNDA, "9.550632e6"); +} + +static void +special (void) +{ + mpfr_t x, y, z; + int inexact; + mpfr_prec_t p; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + mpfr_set_prec (x, 64); + mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1"); + mpfr_set_prec (y, 32); + test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 2405743844UL)) + { + printf ("Error for n^2+n+1/2 with n=2405743843\n"); + exit (1); + } + + mpfr_set_prec (x, 65); + mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2"); + mpfr_set_prec (y, 32); + test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 2405743844UL)) + { + printf ("Error for n^2+n+1/4 with n=2405743843\n"); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 66); + mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3"); + mpfr_set_prec (y, 32); + test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 2405743844UL)) + { + printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n"); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 66); + mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3"); + mpfr_set_prec (y, 32); + test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 2405743843UL)) + { + printf ("Error for n^2+n+1/8 with n=2405743843\n"); + mpfr_dump (y); + exit (1); + } + + mpfr_set_prec (x, 27); + mpfr_set_str_binary (x, "0.110100111010101000010001011"); + if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0) + { + printf ("Wrong inexact flag: expected -1, got %d\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 2); + for (p=2; p<1000; p++) + { + mpfr_set_prec (z, p); + mpfr_set_ui (z, 1, MPFR_RNDN); + mpfr_nexttoinf (z); + test_sqrt (x, z, MPFR_RNDU); + if (mpfr_cmp_ui_2exp(x, 3, -1)) + { + printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n", + (unsigned int) p); + printf ("got "); mpfr_print_binary (x); puts (""); + exit (1); + } + } + + /* check inexact flag */ + mpfr_set_prec (x, 5); + mpfr_set_str_binary (x, "1.1001E-2"); + if ((inexact = test_sqrt (x, x, MPFR_RNDN))) + { + printf ("Wrong inexact flag: expected 0, got %d\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (z, 2); + + /* checks the sign is correctly set */ + mpfr_set_si (x, 1, MPFR_RNDN); + mpfr_set_si (z, -1, MPFR_RNDN); + test_sqrt (z, x, MPFR_RNDN); + if (mpfr_cmp_ui (z, 0) < 0) + { + printf ("Error: square root of 1 gives "); + mpfr_print_binary(z); + putchar('\n'); + exit (1); + } + + mpfr_set_prec (x, 192); + mpfr_set_prec (z, 160); + mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1"); + mpfr_set_prec (x, 160); + test_sqrt(x, z, MPFR_RNDN); + test_sqrt(z, x, MPFR_RNDN); + + mpfr_set_prec (x, 53); + mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN); + mpfr_div_2exp (x, x, 1075, MPFR_RNDN); + test_sqrt (x, x, MPFR_RNDN); + mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN); + if (mpfr_cmp (x, z)) + { + printf ("Error: square root of 8093416094703476*2^(-1075)\n"); + printf ("expected "); mpfr_dump (z); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10"); + mpfr_set_prec (z, 157); + inexact = test_sqrt (z, x, MPFR_RNDN); + mpfr_set_prec (x, 157); + mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5"); + if (mpfr_cmp (x, z)) + { + printf ("Error: square root (1)\n"); + exit (1); + } + if (inexact <= 0) + { + printf ("Error: wrong inexact flag (1)\n"); + exit (1); + } + + /* case prec(result) << prec(input) */ + mpfr_set_prec (z, 2); + for (p = 2; p < 1000; p++) + { + mpfr_set_prec (x, p); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextabove (x); + /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */ + inexact = test_sqrt (z, x, MPFR_RNDN); + MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0); + inexact = test_sqrt (z, x, MPFR_RNDZ); + MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0); + inexact = test_sqrt (z, x, MPFR_RNDU); + MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0); + inexact = test_sqrt (z, x, MPFR_RNDD); + MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0); + inexact = test_sqrt (z, x, MPFR_RNDA); + MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0); + } + + /* corner case rw = 0 in rounding to nearest */ + mpfr_set_prec (z, GMP_NUMB_BITS - 1); + mpfr_set_prec (y, GMP_NUMB_BITS - 1); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_mul_2exp (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN); + mpfr_nextabove (y); + for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++) + { + mpfr_set_prec (x, p); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_exp (x, GMP_NUMB_BITS); + mpfr_add_ui (x, x, 1, MPFR_RNDN); + /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */ + MPFR_ASSERTN (mpfr_mul (x, x, x, MPFR_RNDN) == 0); /* exact */ + inexact = test_sqrt (z, x, MPFR_RNDN); + /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */ + MPFR_ASSERTN (inexact < 0); + MPFR_ASSERTN (mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0); + mpfr_nextbelow (x); + /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */ + inexact = test_sqrt (z, x, MPFR_RNDN); + MPFR_ASSERTN(inexact < 0 && + mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0); + mpfr_nextabove (x); + mpfr_nextabove (x); + /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */ + inexact = test_sqrt (z, x, MPFR_RNDN); + if (mpfr_cmp (z, y)) + { + printf ("Error for sqrt(x) in rounding to nearest\n"); + printf ("x="); mpfr_dump (x); + printf ("Expected "); mpfr_dump (y); + printf ("Got "); mpfr_dump (z); + exit (1); + } + if (inexact <= 0) + { + printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p); + exit (1); + } + } + + mpfr_set_prec (x, 1000); + mpfr_set_ui (x, 9, MPFR_RNDN); + mpfr_set_prec (y, 10); + inexact = test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 3) || inexact != 0) + { + printf ("Error in sqrt(9:1000) for prec=10\n"); + exit (1); + } + mpfr_set_prec (y, GMP_NUMB_BITS); + mpfr_nextabove (x); + inexact = test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 3) || inexact >= 0) + { + printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS); + exit (1); + } + mpfr_set_prec (x, 2 * GMP_NUMB_BITS); + mpfr_set_prec (y, GMP_NUMB_BITS); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_nextabove (y); + mpfr_set (x, y, MPFR_RNDN); + inexact = test_sqrt (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1) || inexact >= 0) + { + printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_inexact (mpfr_prec_t p) +{ + mpfr_t x, y, z; + mpfr_rnd_t rnd; + int inexact, sign; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, 2*p); + mpfr_urandomb (x, RANDS); + rnd = RND_RAND (); + inexact = test_sqrt (y, x, rnd); + if (mpfr_mul (z, y, y, rnd)) /* exact since prec(z) = 2*prec(y) */ + { + printf ("Error: multiplication should be exact\n"); + exit (1); + } + mpfr_sub (z, z, x, rnd); /* exact also */ + sign = mpfr_cmp_ui (z, 0); + if (((inexact == 0) && (sign)) || + ((inexact > 0) && (sign <= 0)) || + ((inexact < 0) && (sign >= 0))) + { + printf ("Error: wrong inexact flag, expected %d, got %d\n", + sign, inexact); + printf ("x="); + mpfr_print_binary (x); + printf (" rnd=%s\n", mpfr_print_rnd_mode (rnd)); + printf ("y="); mpfr_print_binary (y); puts (""); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_singular (void) +{ + mpfr_t x, got; + + mpfr_init2 (x, 100L); + mpfr_init2 (got, 100L); + + /* sqrt(NaN) == NaN */ + MPFR_SET_NAN (x); + MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_nan_p (got)); + + /* sqrt(-1) == NaN */ + mpfr_set_si (x, -1L, MPFR_RNDZ); + MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_nan_p (got)); + + /* sqrt(+inf) == +inf */ + MPFR_SET_INF (x); + MPFR_SET_POS (x); + MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (got)); + + /* sqrt(-inf) == NaN */ + MPFR_SET_INF (x); + MPFR_SET_NEG (x); + MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_nan_p (got)); + + /* sqrt(+0) == +0 */ + mpfr_set_si (x, 0L, MPFR_RNDZ); + MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (got)); + MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0); + MPFR_ASSERTN (MPFR_IS_POS (got)); + + /* sqrt(-0) == -0 */ + mpfr_set_si (x, 0L, MPFR_RNDZ); + MPFR_SET_NEG (x); + MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (got)); + MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0); + MPFR_ASSERTN (MPFR_IS_NEG (got)); + + mpfr_clear (x); + mpfr_clear (got); +} + +/* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up + with s = 0 and s = 1 */ +static void +test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s) +{ + mpfr_t x, y, z, t; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, p); + mpfr_init2 (t, p); + + mpfr_urandomb (x, RANDS); + mpfr_mul (z, x, x, r); + if (s) + { + mpfr_urandomb (y, RANDS); + mpfr_mul (t, y, y, r); + mpfr_add (z, z, t, r); + } + mpfr_sqrt (z, z, r); + mpfr_div (z, x, z, r); + /* Note: if both x and y are 0, z is NAN, but the test below will + be false. So, everything is fine. */ + if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0) + { + printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n", + mpfr_print_rnd_mode (r)); + printf ("x="); mpfr_dump (x); + printf ("y="); mpfr_dump (y); + printf ("got "); mpfr_dump (z); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +/* check sqrt(x^2) = x */ +static void +test_property2 (mpfr_prec_t p, mpfr_rnd_t r) +{ + mpfr_t x, y; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + + mpfr_urandomb (x, RANDS); + mpfr_mul (y, x, x, r); + mpfr_sqrt (y, y, r); + if (mpfr_cmp (y, x)) + { + printf ("Error, sqrt(x^2) = x does not hold for r=%s\n", + mpfr_print_rnd_mode (r)); + printf ("x="); mpfr_dump (x); + printf ("got "); mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +/* Bug reported by Fredrik Johansson, occurring when: + - the precision of the result is a multiple of the number of bits + per word (GMP_NUMB_BITS), + - the rounding mode is to nearest (MPFR_RNDN), + - internally, the result has to be rounded up to a power of 2. +*/ +static void +bug20160120 (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 4 * GMP_NUMB_BITS); + mpfr_init2 (y, GMP_NUMB_BITS); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_nextbelow (x); + mpfr_sqrt (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_check (y)); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); + + mpfr_set_prec (y, 2 * GMP_NUMB_BITS); + mpfr_sqrt (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_check (y)); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); + + mpfr_clear(x); + mpfr_clear(y); +} + +#define TEST_FUNCTION test_sqrt +#define TEST_RANDOM_POS 8 +#include "tgeneric.c" + +int +main (void) +{ + mpfr_prec_t p; + int k; + + tests_start_mpfr (); + + for (p = MPFR_PREC_MIN; p <= 128; p++) + { + test_property1 (p, MPFR_RNDN, 0); + test_property1 (p, MPFR_RNDU, 0); + test_property1 (p, MPFR_RNDA, 0); + test_property1 (p, MPFR_RNDN, 1); + test_property1 (p, MPFR_RNDU, 1); + test_property1 (p, MPFR_RNDA, 1); + test_property2 (p, MPFR_RNDN); + } + + check_diverse ("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328", 160, "796887792767063979679855997149887366668464780637"); + special (); + check_singular (); + + for (p=2; p<200; p++) + for (k=0; k<200; k++) + check_inexact (p); + check_float(); + + check3 ("-0.0", MPFR_RNDN, "0.0"); + check4 ("6.37983013646045901440e+32", MPFR_RNDN, "5.9bc5036d09e0c@13"); + check4 ("1.0", MPFR_RNDN, "1"); + check4 ("1.0", MPFR_RNDZ, "1"); + check4 ("3.725290298461914062500000e-9", MPFR_RNDN, "4@-4"); + check4 ("3.725290298461914062500000e-9", MPFR_RNDZ, "4@-4"); + check4 ("1190456976439861.0", MPFR_RNDZ, "2.0e7957873529a@6"); + check4 ("1219027943874417664.0", MPFR_RNDZ, "4.1cf2af0e6a534@7"); + /* the following examples are bugs in Cygnus compiler/system, found by + Fabrice Rouillier while porting mpfr to Windows */ + check4 ("9.89438396044940256501e-134", MPFR_RNDU, "8.7af7bf0ebbee@-56"); + check4 ("7.86528588050363751914e+31", MPFR_RNDZ, "1.f81fc40f32062@13"); + check4 ("0.99999999999999988897", MPFR_RNDN, "f.ffffffffffff8@-1"); + check4 ("1.00000000000000022204", MPFR_RNDN, "1"); + /* the following examples come from the paper "Number-theoretic Test + Generation for Directed Rounding" from Michael Parks, Table 4 */ + + check4 ("78652858805036375191418371571712.0", MPFR_RNDN, + "1.f81fc40f32063@13"); + check4 ("38510074998589467860312736661504.0", MPFR_RNDN, + "1.60c012a92fc65@13"); + check4 ("35318779685413012908190921129984.0", MPFR_RNDN, + "1.51d17526c7161@13"); + check4 ("26729022595358440976973142425600.0", MPFR_RNDN, + "1.25e19302f7e51@13"); + check4 ("22696567866564242819241453027328.0", MPFR_RNDN, + "1.0ecea7dd2ec3d@13"); + check4 ("22696888073761729132924856434688.0", MPFR_RNDN, + "1.0ecf250e8e921@13"); + check4 ("36055652513981905145251657416704.0", MPFR_RNDN, + "1.5552f3eedcf33@13"); + check4 ("30189856268896404997497182748672.0", MPFR_RNDN, + "1.3853ee10c9c99@13"); + check4 ("36075288240584711210898775080960.0", MPFR_RNDN, + "1.556abe212b56f@13"); + check4 ("72154663483843080704304789585920.0", MPFR_RNDN, + "1.e2d9a51977e6e@13"); + + check4 ("78652858805036375191418371571712.0", MPFR_RNDZ, + "1.f81fc40f32062@13"); + check4 ("38510074998589467860312736661504.0", MPFR_RNDZ, + "1.60c012a92fc64@13"); + check4 ("35318779685413012908190921129984.0", MPFR_RNDZ, "1.51d17526c716@13"); + check4 ("26729022595358440976973142425600.0", MPFR_RNDZ, "1.25e19302f7e5@13"); + check4 ("22696567866564242819241453027328.0", MPFR_RNDZ, + "1.0ecea7dd2ec3c@13"); + check4 ("22696888073761729132924856434688.0", MPFR_RNDZ, "1.0ecf250e8e92@13"); + check4 ("36055652513981905145251657416704.0", MPFR_RNDZ, + "1.5552f3eedcf32@13"); + check4 ("30189856268896404997497182748672.0", MPFR_RNDZ, + "1.3853ee10c9c98@13"); + check4 ("36075288240584711210898775080960.0", MPFR_RNDZ, + "1.556abe212b56e@13"); + check4 ("72154663483843080704304789585920.0", MPFR_RNDZ, + "1.e2d9a51977e6d@13"); + + check4 ("78652858805036375191418371571712.0", MPFR_RNDU, + "1.f81fc40f32063@13"); + check4 ("38510074998589467860312736661504.0", MPFR_RNDU, + "1.60c012a92fc65@13"); + check4 ("35318779685413012908190921129984.0", MPFR_RNDU, + "1.51d17526c7161@13"); + check4 ("26729022595358440976973142425600.0", MPFR_RNDU, + "1.25e19302f7e51@13"); + check4 ("22696567866564242819241453027328.0", MPFR_RNDU, + "1.0ecea7dd2ec3d@13"); + check4 ("22696888073761729132924856434688.0", MPFR_RNDU, + "1.0ecf250e8e921@13"); + check4 ("36055652513981905145251657416704.0", MPFR_RNDU, + "1.5552f3eedcf33@13"); + check4 ("30189856268896404997497182748672.0", MPFR_RNDU, + "1.3853ee10c9c99@13"); + check4 ("36075288240584711210898775080960.0", MPFR_RNDU, + "1.556abe212b56f@13"); + check4 ("72154663483843080704304789585920.0", MPFR_RNDU, + "1.e2d9a51977e6e@13"); + + check4 ("78652858805036375191418371571712.0", MPFR_RNDD, + "1.f81fc40f32062@13"); + check4 ("38510074998589467860312736661504.0", MPFR_RNDD, + "1.60c012a92fc64@13"); + check4 ("35318779685413012908190921129984.0", MPFR_RNDD, "1.51d17526c716@13"); + check4 ("26729022595358440976973142425600.0", MPFR_RNDD, "1.25e19302f7e5@13"); + check4 ("22696567866564242819241453027328.0", MPFR_RNDD, + "1.0ecea7dd2ec3c@13"); + check4 ("22696888073761729132924856434688.0", MPFR_RNDD, "1.0ecf250e8e92@13"); + check4 ("36055652513981905145251657416704.0", MPFR_RNDD, + "1.5552f3eedcf32@13"); + check4 ("30189856268896404997497182748672.0", MPFR_RNDD, + "1.3853ee10c9c98@13"); + check4 ("36075288240584711210898775080960.0", MPFR_RNDD, + "1.556abe212b56e@13"); + check4 ("72154663483843080704304789585920.0", MPFR_RNDD, + "1.e2d9a51977e6d@13"); + + /* check that rounding away is just rounding toward plus infinity */ + check4 ("72154663483843080704304789585920.0", MPFR_RNDA, + "1.e2d9a51977e6e@13"); + + test_generic (2, 300, 15); + data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt"); + bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 8, -256, 255, 4, 128, 800, 50); + + bug20160120 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsqrt_ui.c b/mpfr/tests/tsqrt_ui.c new file mode 100644 index 0000000000..d9ea3ea98e --- /dev/null +++ b/mpfr/tests/tsqrt_ui.c @@ -0,0 +1,56 @@ +/* Test file for mpfr_sqrt_ui. + +Copyright 2000-2003, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check (unsigned long a, mpfr_rnd_t rnd_mode, const char *qs) +{ + mpfr_t q; + + mpfr_init2 (q, 53); + mpfr_sqrt_ui (q, a, rnd_mode); + if (mpfr_cmp_str1 (q, qs)) + { + printf ("mpfr_sqrt_ui failed for a=%lu, rnd_mode=%s\n", + a, mpfr_print_rnd_mode (rnd_mode)); + printf ("sqrt gives %s, mpfr_sqrt_ui gives ", qs); + mpfr_out_str(stdout, 10, 0, q, MPFR_RNDN); + exit (1); + } + mpfr_clear (q); +} + +int +main (void) +{ + tests_start_mpfr (); + + check (0, MPFR_RNDN, "0.0"); + check (2116118, MPFR_RNDU, "1.45468828276026215e3"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tstckintc.c b/mpfr/tests/tstckintc.c new file mode 100644 index 0000000000..1935f5671e --- /dev/null +++ b/mpfr/tests/tstckintc.c @@ -0,0 +1,325 @@ +/* Test file for mpfr_custom_* + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +#define BUFFER_SIZE 250 +#define PREC_TESTED 200 + +long Buffer[BUFFER_SIZE]; +char *stack = (char *) Buffer; +long *org = (long *) Buffer; +mpfr_prec_t p = PREC_TESTED; + +#define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long)) + +static void * +new_st (size_t s) +{ + void *p = (void *) stack; + + if (MPFR_UNLIKELY (s > (char *) &Buffer[BUFFER_SIZE] - stack)) + { + printf ("[INTERNAL TEST ERROR] Stack overflow.\n"); + exit (1); + } + stack += ALIGNED (s); + return p; +} + +static void +reset_stack (void) +{ + stack = (char *) Buffer; +} + +/*************************************************************************/ + + /* Alloc a new mpfr_t on the main stack */ +static mpfr_ptr +new_mpfr (mpfr_prec_t p) +{ + mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); + void *mantissa = new_st (mpfr_custom_get_size (p)); + mpfr_custom_init (mantissa, p); + mpfr_custom_init_set (x, 0, 0, p, mantissa); + return x; +} + + /* Alloc a new mpfr_t on the main stack */ +static mpfr_ptr +new_nan (mpfr_prec_t p) +{ + mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); + void *mantissa = new_st ((mpfr_custom_get_size) (p)); + (mpfr_custom_init) (mantissa, p); + (mpfr_custom_init_set) (x, MPFR_NAN_KIND, 0, p, mantissa); + return x; +} + + /* Alloc a new mpfr_t on the main stack */ +static mpfr_ptr +new_inf (mpfr_prec_t p) +{ + mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); + void *mantissa = new_st ((mpfr_custom_get_size) (p)); + (mpfr_custom_init) (mantissa, p); + (mpfr_custom_init_set) (x, -MPFR_INF_KIND, 0, p, mantissa); + return x; +} + + /* Garbage the stack by keeping only x and save it in old_stack */ +static mpfr_ptr +return_mpfr (mpfr_ptr x, char *old_stack) +{ + void *mantissa = mpfr_custom_get_significand (x); + size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x)); + mpfr_ptr newx; + + memmove (old_stack, x, sizeof (mpfr_t)); + memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa); + newx = (mpfr_ptr) old_stack; + mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t))); + stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa); + return newx; +} + + /* Garbage the stack by keeping only x and save it in old_stack */ +static mpfr_ptr +return_mpfr_func (mpfr_ptr x, char *old_stack) +{ + void *mantissa = (mpfr_custom_get_significand) (x); + size_t size_mantissa = (mpfr_custom_get_size) (mpfr_get_prec (x)); + mpfr_ptr newx; + + memmove (old_stack, x, sizeof (mpfr_t)); + memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa); + newx = (mpfr_ptr) old_stack; + (mpfr_custom_move) (newx, old_stack + ALIGNED (sizeof (mpfr_t))); + stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa); + return newx; +} + +/*************************************************************************/ + +static void +test1 (void) +{ + mpfr_ptr x, y; + + reset_stack (); + org = (long *) stack; + + x = new_mpfr (p); + y = new_mpfr (p); + mpfr_set_ui (x, 42, MPFR_RNDN); + mpfr_set_ui (y, 17, MPFR_RNDN); + mpfr_add (y, x, y, MPFR_RNDN); + y = return_mpfr (y, (char *) org); + if ((long *) y != org || mpfr_cmp_ui (y, 59) != 0) + { + printf ("Compact (1) failed!\n"); + exit (1); + } + + x = new_mpfr (p); + y = new_mpfr (p); + mpfr_set_ui (x, 4217, MPFR_RNDN); + mpfr_set_ui (y, 1742, MPFR_RNDN); + mpfr_add (y, x, y, MPFR_RNDN); + y = return_mpfr_func (y, (char *) org); + if ((long *) y != org || mpfr_cmp_ui (y, 5959) != 0) + { + printf ("Compact (5) failed!\n"); + exit (1); + } + + reset_stack (); +} + +static void +test_nan_inf_zero (void) +{ + mpfr_ptr val; + int sign; + int kind; + + reset_stack (); + + val = new_mpfr (MPFR_PREC_MIN); + mpfr_set_nan (val); + kind = (mpfr_custom_get_kind) (val); + if (kind != MPFR_NAN_KIND) + { + printf ("mpfr_custom_get_kind error: "); + mpfr_dump (val); + printf (" is kind %d instead of %d\n", kind, (int) MPFR_NAN_KIND); + exit (1); + } + + val = new_nan (MPFR_PREC_MIN); + if (!mpfr_nan_p(val)) + { + printf ("Error: mpfr_custom_init_set doesn't set NAN mpfr.\n"); + exit (1); + } + + val = new_inf (MPFR_PREC_MIN); + if (!mpfr_inf_p(val) || mpfr_sgn(val) >= 0) + { + printf ("Error: mpfr_custom_init_set doesn't set -INF mpfr.\n"); + exit (1); + } + + sign = 1; + mpfr_set_inf (val, sign); + kind = (mpfr_custom_get_kind) (val); + if ((ABS (kind) != MPFR_INF_KIND) || (SIGN (kind) != SIGN (sign))) + { + printf ("mpfr_custom_get_kind error: "); + mpfr_dump (val); + printf (" is kind %d instead of %d\n", kind, (int) MPFR_INF_KIND); + printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign)); + exit (1); + } + + sign = -1; + mpfr_set_zero (val, sign); + kind = (mpfr_custom_get_kind) (val); + if ((ABS (kind) != MPFR_ZERO_KIND) || (SIGN (kind) != SIGN (sign))) + { + printf ("mpfr_custom_get_kind error: "); + mpfr_dump (val); + printf (" is kind %d instead of %d\n", kind, (int) MPFR_ZERO_KIND); + printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign)); + exit (1); + } + + reset_stack (); +} + +/*************************************************************************/ + +/* We build the MPFR variable each time it is needed */ +/* a[0] is the kind, a[1] is the exponent, &a[2] is the mantissa */ +static long * +dummy_new (void) +{ + long *r; + + r = (long *) new_st (ALIGNED (2 * sizeof (long)) + + ALIGNED (mpfr_custom_get_size (p))); + (mpfr_custom_init) (&r[2], p); + r[0] = (int) MPFR_NAN_KIND; + r[1] = 0; + return r; +} + +static long * +dummy_set_si (long si) +{ + mpfr_t x; + long * r = dummy_new (); + (mpfr_custom_init_set) (x, MPFR_REGULAR_KIND, 0, p, &r[2]); + mpfr_set_si (x, si, MPFR_RNDN); + r[0] = mpfr_custom_get_kind (x); + r[1] = mpfr_custom_get_exp (x); + return r; +} + +static long * +dummy_add (long *a, long *b) +{ + mpfr_t x, y, z; + long *r = dummy_new (); + mpfr_custom_init_set (x, 0 + MPFR_REGULAR_KIND, 0, p, &r[2]); + (mpfr_custom_init_set) (y, a[0], a[1], p, &a[2]); + mpfr_custom_init_set (z, 0 + b[0], b[1], p, &b[2]); + mpfr_add (x, y, z, MPFR_RNDN); + r[0] = (mpfr_custom_get_kind) (x); + r[1] = (mpfr_custom_get_exp) (x); + return r; +} + +static long * +dummy_compact (long *r, long *org_stack) +{ + memmove (org_stack, r, + ALIGNED (2*sizeof (long)) + ALIGNED ((mpfr_custom_get_size) (p))); + return org_stack; +} + +/*************************************************************************/ + +static void +test2 (void) +{ + mpfr_t x; + long *a, *b, *c; + + reset_stack (); + org = (long *) stack; + + a = dummy_set_si (42); + b = dummy_set_si (17); + c = dummy_add (a, b); + c = dummy_compact (c, org); + (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]); + if (c != org || mpfr_cmp_ui (x, 59) != 0) + { + printf ("Compact (2) failed! c=%p a=%p\n", (void *) c, (void *) a); + mpfr_dump (x); + exit (1); + } + + a = dummy_set_si (42); + b = dummy_set_si (-17); + c = dummy_add (a, b); + c = dummy_compact (c, org); + (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]); + if (c != org || mpfr_cmp_ui (x, 25) != 0) + { + printf ("Compact (6) failed! c=%p a=%p\n", (void *) c, (void *) a); + mpfr_dump (x); + exit (1); + } + + reset_stack (); +} + + +int +main (void) +{ + tests_start_mpfr (); + /* We test iff long = mp_limb_t */ + if (sizeof (long) == sizeof (mp_limb_t)) + { + test1 (); + test2 (); + test_nan_inf_zero (); + } + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tstdint.c b/mpfr/tests/tstdint.c new file mode 100644 index 0000000000..1c51cdd385 --- /dev/null +++ b/mpfr/tests/tstdint.c @@ -0,0 +1,76 @@ +/* Test file for multiple mpfr.h inclusion and intmax_t related functions + +Copyright 2010-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if HAVE_STDINT_H + +#include <stdlib.h> + +#if _MPFR_EXP_FORMAT == 4 +/* If mpfr_exp_t is defined as intmax_t, intmax_t must be defined before + the inclusion of mpfr.h (this test doesn't use mpfr-impl.h). */ +# include <stdint.h> +#endif + +/* Assume that this is in fact a header inclusion for some library + that uses MPFR, i.e. this inclusion is hidden in another one. + MPFR currently (rev 6704) fails to handle this case. */ +#include <mpfr.h> + +#include <stdint.h> + +#define MPFR_USE_INTMAX_T +#include <mpfr.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t x; + intmax_t j; + + tests_start_mpfr (); + + mpfr_init_set_ui (x, 1, MPFR_RNDN); + j = mpfr_get_uj (x, MPFR_RNDN); + mpfr_clear (x); + if (j != 1) + { + printf ("Error: got %jd instead of 1.\n", j); + exit (1); + } + + tests_end_mpfr (); + return 0; +} + +#else /* HAVE_STDINT_H */ + +/* The test is disabled. */ + +int +main (void) +{ + return 77; +} + +#endif /* HAVE_STDINT_H */ diff --git a/mpfr/tests/tstrtofr.c b/mpfr/tests/tstrtofr.c new file mode 100644 index 0000000000..97575413ac --- /dev/null +++ b/mpfr/tests/tstrtofr.c @@ -0,0 +1,1211 @@ +/* Test file for mpfr_set_str. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +check_special (void) +{ + mpfr_t x, y; + int res; + char *s; + + mpfr_init (x); + mpfr_init (y); + + /* Check dummy case */ + res = mpfr_strtofr (x, "1234567.89E1", NULL, 10, MPFR_RNDN); + mpfr_set_str (y, "1234567.89E1", 10, MPFR_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Results differ between strtofr and set_str.\n" + " set_str gives: "); + mpfr_dump (y); + printf (" strtofr gives: "); + mpfr_dump (x); + exit (1); + } + + /* Check NAN */ + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "NaN", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || *s != 0) + { + printf ("Error for setting NAN (1)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "+NaN", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || *s != 0) + { + printf ("Error for setting +NAN (1)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, " -NaN", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || *s != 0) + { + printf ("Error for setting -NAN (1)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "@nAn@xx", &s, 16, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "xx") ) + { + printf ("Error for setting NAN (2)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "NAN(abcdEDF__1256)Hello", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "Hello") ) + { + printf ("Error for setting NAN (3)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "NAN(abcdEDF)__1256)Hello", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "__1256)Hello") ) + { + printf ("Error for setting NAN (4)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "NAN(abc%dEDF)__1256)Hello", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "(abc%dEDF)__1256)Hello") ) + { + printf ("Error for setting NAN (5)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "NAN((abc))", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "((abc))") ) + { + printf ("Error for setting NAN (6)\n"); + exit (1); + } + mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ + res = mpfr_strtofr (x, "NAN()foo", &s, 10, MPFR_RNDN); + if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "foo") ) + { + printf ("Error for setting NAN (7)\n"); + exit (1); + } + + /* Check INF */ + res = mpfr_strtofr (x, "INFINITY", &s, 8, MPFR_RNDN); + if (res != 0 || !mpfr_inf_p (x) || *s != 0) + { + printf ("Error for setting INFINITY (1)\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + res = mpfr_strtofr (x, "INFANITY", &s, 8, MPFR_RNDN); + if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "ANITY")) + { + printf ("Error for setting INFINITY (2)\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + res = mpfr_strtofr (x, "@INF@*2", &s, 11, MPFR_RNDN); + if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "*2")) + { + printf ("Error for setting INFINITY (3)\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + + /* Check Zero */ + res = mpfr_strtofr (x, " 00000", &s, 11, MPFR_RNDN); + if (res != 0 || !mpfr_zero_p (x) || s[0] != 0) + { + printf ("Error for setting ZERO (1)\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + + /* Check base 62 */ + res = mpfr_strtofr (x, "A", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 10)) + { + printf ("Error for setting 'A' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "a", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 36)) + { + printf ("Error for setting 'a' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "Z", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 35)) + { + printf ("Error for setting 'Z' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "z", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 61)) + { + printf ("Error for setting 'z' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "ZA", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 2180)) + { + printf ("Error for setting 'ZA' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "za", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 3818)) + { + printf ("Error for setting 'za' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "aZ", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 2267)) + { + printf ("Error for setting 'aZ' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "Az", NULL, 62, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 681)) + { + printf ("Error for setting 'Az' in base 62\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + + /* Check base 60 */ + res = mpfr_strtofr (x, "Aa", NULL, 60, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 636)) + { + printf ("Error for setting 'Aa' in base 60\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + res = mpfr_strtofr (x, "Zz", &s, 60, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 35) || strcmp(s, "z") ) + { + printf ("Error for setting 'Zz' in base 60\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + + /* Check base 61 */ + res = mpfr_strtofr (x, "z", &s, 61, MPFR_RNDN); + if (res != 0 || mpfr_cmp_ui (x, 0) || strcmp(s, "z") ) + { + printf ("Error for setting 'z' in base 61\n x="); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +/* The following RefTable has been generated by this following code */ +#if 0 +#define MAX_NUM 100 + +int randomab (int a, int b) +{ + return a + rand () % (b-a); +} + +int +main (void) +{ + int i, base; + mpfr_t x; + mpfr_prec_t p; + mpfr_exp_t e; + + mpfr_init (x); + printf ("struct dymmy_test { \n" + " mpfr_prec_t prec; \n" + " int base; \n" + " const char *str; \n" + " const char *binstr; \n" + " } RefTable[] = { \n"); + for (i = 0 ; i < MAX_NUM ; i++) + { + p = randomab(2, 180); + base = randomab (2, 30); + e = randomab (-1<<15, 1<<15); + mpfr_set_prec (x, p); + mpfr_urandomb (x, RANDS); + mpfr_mul_2si (x, x, e, MPFR_RNDN); + printf("{%lu, %d,\n\"", p, base); + mpfr_out_str (stdout, base, p, x, MPFR_RNDN); + printf ("\",\n\""); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf ("\"}%c\n", i == MAX_NUM-1 ? ' ' : ',' ); + } + printf("};\n"); + mpfr_clear (x); +} +#endif + +static struct dymmy_test { + mpfr_prec_t prec; + int base; + const char *str; + const char *binstr; + } RefTable[] = { +{39, 20, +"1.1c9jeh9jg12d8iiggf26b8ce2cig24agai51d9@1445", +"1.00111010111010001110110001101011101011e6245"}, +{119, 3, +"1.2210112120221020220021000020101121120011021202212101222000011110211211122222001001221110102220122021121021101010120101e-5655", +"1.1111101110011110001101011100011000011100001011011100010011010010001000000111001010000001110111010100011000110010000000e-8963"}, +{166, 18, +"3.ecg67g31434b74d8hhbe2dbbb46g9546cae72cae0cfghfh00ed7gebe9ca63b47h08bgbdeb880a76dea12he31e1ccd67e9dh22a911b46h517b745169b2g43egg2e4eah820cdb2132d6a4f9c63505dd4a0dafbc@-5946", +"1.011110010000110011111011111100110110010110000010100001101111111000010000011111110101100000010110011001100000010001100101000001101000010010001011001011000110100011001e-24793"}, +{139, 4, +"1.020302230021023320300300101212330121100031233000032101123133120221012000000000000000000000000000000000000000000000000000000000000000000000e11221", +"1.001000110010101100001001001011111000110000110000010001100110111100011001010000001101101111000000001110010001011011011111011000101001000110e22442"}, +{126, 13, +"4.a3cb351c6c548a0475218519514c6c54366681447019ac70a387862c39c86546ab27608c9c2863328860aa2464288070a76c0773882728c5213a335289259@2897", +"1.01011010000001110001100001101111100111011010010111000011000101111011000100001010010100110111101001001001000000011100010000000e10722"}, +{6, 26, +"1.j79f6@-1593", +"1.00000e-7487"}, +{26, 18, +"3.5e99682hh310aa89hb2fb4h88@-5704", +"1.0110010100010101000101100e-23784"}, +{12, 21, +"4.j7f3e2ccdfa@-3524", +"1.10110101011e-15477"}, +{38, 28, +"o.agr0m367b9bmm76rplg7b53qlj7f02g717cab@6452", +"1.1001010011101100110100111000111010001e31021"}, +{75, 17, +"4.00abd9gc99902e1cae2caa7647gcc029g01370e96d3f8e9g02f814d3ge5faa29d40b9db470@5487", +"1.11100000110101010111101001110001001010111111010100000100001010100111011101e22429"}, +{91, 16, +"1.0a812a627160014a3bda1f00000000000000000000000000000000000000000000000000000000000000000000@7897", +"1.000010101000000100101010011000100111000101100000000000010100101000111011110110100001111100e31588"}, +{154, 19, +"1.989279dda02a8ic15e936ahig3c695f6059a3i01b7d1ge6a418bf84gd87e36061hb2bi62ciagcgb9226fafea41d2ig1e2f0a10ea3i40d6dahf598bdbh372bdf5901gh276866804ah53b6338bi@5285", +"1.110101101101101111110010001011110001100000010100011101101001000100110100000011110111000011011101011110010100110101011011111100101101001100000101101000010e22450"}, +{53, 2, +"1.0100010111100111001010000100011011111011011100110111e-20319", +"1.0100010111100111001010000100011011111011011100110111e-20319"}, +{76, 3, +"2.101212121100222100012112101120011222102000021110201110000202111122221100001e1511", +"1.000110101010111000011001011111110000001001101001011011111110111111010000111e2396"}, +{31, 9, +"1.171774371505084376877631528681e3258", +"1.110101101011111011111000110011e10327"}, +{175, 8, +"4.506242760242070533035566017365410474451421355546570157251400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3483", +"1.001010001100101000101111100000101000100001110001010110110000111011011101100000011110111101011000010001001111001001010011000100010111011011011001101011110000011011110101010011e10451"}, +{103, 24, +"8.0hmlm3g183cj358fn4bimn5bie1l89k95m647474mm8jg5kh1c011gi0m7de9j7b48c595g1bki4n32kll7b882eg7klgga0h0gf11@4510", +"1.001000110101001101011010101001111010110100010100110101010101110000001011001101110110010111000101010111e20681"}, +{12, 9, +"3.00221080453e2479", +"1.11000111010e7859"}, +{86, 11, +"6.873680186953174a274754118026423965415553a088387303452447389287133a0956111602a5a085446@5035", +"1.0000000000110100010110000111010001010100101011000100101010010011101010000110011110001e17421"}, +{68, 10, +"6.1617378719016284192718392572980535262609909598793237475124371481233e481", +"1.0110001011000101110010111101100101111110001100001011110011001101111e1600"}, +{11, 15, +"5.ab10c18d45@907", +"1.0000101111e3546"}, +{77, 26, +"6.e6kl84g6h30o3nfnj7fjjff4n1ee6e5iop76gabj23e7hgan9o6724domc7bp4hdll95g817519f@5114", +"1.1011000101111111111110011011101100000100101000001001100000001011010001001000e24040"}, +{28, 27, +"d.odiqp9kgh84o8d2aoqg4c21hemi@3566", +"1.101001111001111111110011110e16959"}, +{45, 14, +"7.cddc6295a576980adbc8c16111d6301bad3146a1143c@-6227", +"1.10000000110011000000101100110001011100010111e-23706"}, +{54, 19, +"1.b6e67i2124hfga2g819g1d6527g2b603eg3cd8hhca9gecig8geg1@4248", +"1.11010100100010101101110110010100000010111010010101110e18045"}, +{49, 20, +"1.jj68bj6idadg44figi10d2ji99g6ddi6c6ich96a5h86i529@-3149", +"1.001011111101100100001010001000011100000000101110e-13609"}, +{171, 16, +"6.22cf0e566d8ff11359d70bd9200065cfd72600b12e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@5602", +"1.10001000101100111100001110010101100110110110001111111100010001001101011001110101110000101111011001001000000000000001100101110011111101011100100110000000001011000100101110e22410"}, +{144, 14, +"1.425d9709b4c125651ab88bb1a0370c14270d067a9a74a612dad48d5c025531c175c1b905201d0d9773aa686c8249db9c0b841b10821791c02baa2525a4aa7571850439c2cc965cd@-3351", +"1.11100111110001001101010111010000101010011000111001101011000001011110101110011011100100111001101101111011001001101011001101001011011101101111011e-12759"}, +{166, 6, +"3.324252232403440543134003140400220120040245215204322153511143504542403430152410543444455151104314552352030352125540101550151410414122051500201022252511512332523431554e8340", +"1.010101111101111101001001110010111110010000001111010101100110011011010110011001001100001111010101100000010111011111101110110111101110010001110001111000001010001111000e21560"}, +{141, 24, +"2.i3c88lkm2958l9ncb9f85kk35namjli84clek5j6jjkli82kb9m4e4i2g39me63db2094cif80gcba8ie6l15ia0d667kn9i1f77bdak599e1ach0j05cdn8kf6c6kfd82j2k6hj2c4d@4281", +"1.10011100001010110111001000000000101011100010101011001010001101110100110111011000111101000001111101100000110100100010101011001100100011001011e19629"}, +{84, 6, +"2.41022133512503223022555143021524424430350133500020112434301542311050052304150111243e982", +"1.11010001111111001010011100011000011100100111111010001111010010101001001000011100001e2539"}, +{56, 9, +"1.5305472255016741401411184703518332515066156086511016413e2936", +"1.0111110010001101000000110101110000110101001011001100111e9307"}, +{18, 8, +"3.63542400000000000e-599", +"1.11100111011000101e-1796"}, +{111, 13, +"8.b693ac7a24679b98708a0057a6202c867bc146740ab1971b380756a24c99804b63436419239ba0510030b819933771a636c57c5747b883@-6160", +"1.01011011111110100101110010100100000110000011011101001110010110000011101110111111010111000011011101101001100100e-22792"}, +{162, 16, +"4.f2abe958a313566adbf3169e55cdcff3785dbd5c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@382", +"1.00111100101010101111101001010110001010001100010011010101100110101011011011111100110001011010011110010101011100110111001111111100110111100001011101101111010101110e1530"}, +{117, 23, +"2.4b6kk3ag3if217ih1hggkk69bmcecfil1cd38dijh35j8e6ckhd335a4gj7l05bedk19473i8449b1ajc3jd3ka95eceheh72lh2jh17jamlm1142gll@-3628", +"1.10010010001010001110011000010000011111011101111100110101100100101111101110010011101001111010100010001111110100101111e-16411"}, +{179, 2, +"1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203", +"1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203"}, +{18, 27, +"4.ll743n2f654gh3154@-6039", +"1.01101001111010011e-28713"}, +{178, 15, +"1.e5443105cad2d014b700c42aa3de854c4b95322420695d07db3564ec07473da83bde123b74c794139265a838ebeca745ad3dc97d7c356271ca935ea8e83306562c2a8edc6e886c1b6b2d3e17038379c33826526770985c068@821", +"1.011100001000101100111111111111000100110111110011101010001111011001111101111001010011100100100101100011101001000000101001010100011111001011001010011101101001000111111010101101011e3208"}, +{161, 22, +"2.46ikji624bg042877h8g2jdki4ece6ede62841j7li843a4becdkkii86c54192jkefehikkb3kcb26ij1b3k9agfbb07dih88d6ej0ee0d63i8hedc7f0g0i9g7jf9gf6423j70h421bg5hf2bja9j0a432lb10@-5125", +"1.0111011000111110000010011100001100100110001011101001011110111010100000011100000010011101011100101100111100110000001101010101011110100011101111001011001111100000e-22854"}, +{62, 19, +"7.bgd1g0886a6c3a9ee67cc7g3bgf718i98d90788idi5587358e660iffc0ic6@3257", +"1.0101100100001110000100010110100100000111110001111001011110100e13838"}, +{127, 19, +"1.413bgf99eidba75ged25f7187080bce3h7ebdeghea4ig6c79g94di7b42a3e4cdi4ic6a53i71d2e4hdbe50ih0a0egf2fi469732131ig6g496bf7h8g3c86ie7h@-4465", +"1.001101111000011011100010010010010110111001001001110011110101111111000001110101111110001110010000110011111101000011000101111101e-18967"}, +{17, 21, +"4.7d5b70gh4k0gj4fj@-116", +"1.1000100010000110e-508"}, +{141, 13, +"2.2b4988c5cb57072a6a1a9c42224794a1cbc175a9bc673bb28aa045c3182b9396ca8bb8590969672b0239608a845a2c35c08908a58c2a83748c89241a6561422c7cc4866c8454@4358", +"1.10010110101000001000001001111001000100111110100010100110111011111011010010101000110101110000111100010000101101000110000000000001111110110011e16127"}, +{39, 7, +"3.00350342452505221136410100232265245244e202", +"1.10011000111110011010100110101101010010e568"}, +{119, 24, +"5.2aene587kc2d9a55mm8clhn4dn0a551de58b1fcli8e8hf1jlm7i0376dl5fhb2k8acka03077mnbn9d4dmi0641dce871c81g2b3ge76m3kngm4a9g5gh@-892", +"1.0111101010010100001001111110000000100101110010010111111100100101100001010010100110111000101100101010111000101111000010e-4088"}, +{41, 14, +"5.c3dc5c49373d0c0075624931133022185bd08b16@-5294", +"1.0101011000010111111111000010100110011111e-20154"}, +{41, 6, +"3.2411143454422033245255450304104450302500e2250", +"1.1110111101010101001001100000100011110111e5817"}, +{17, 13, +"3.65789aa26aa273b1@-4490", +"1.1100011101010111e-16614"}, +{10, 26, +"1.5p4hag1fl@6017", +"1.110010111e28282"}, +{130, 11, +"2.606a72601843700427667823172635a47055021a0a68a99326875195a179483948407aa13726244552332114a1784aaa7239956521604460876871a65708458aa@-6285", +"1.110001001110111110110111000010101000110010011110010101100100001000101011010010000001000101000110111111110101000100000111100010100e-21742"}, +{29, 20, +"j.4356d9b7i38i955jjj1j442501bj@163", +"1.1010101011110011100000100100e708"}, +{140, 21, +"9.2f5k7aid6bj2b2g5bff29i73hk3a8d8g0i7ifa07hkb79g4hd3c7j6g4hjj2jbhai01gkje3h9g3gj3i34f0194kaed32iea9dcgcj8h7i1khdkf965c1ak97gf3h03fcab3ggi03fa@4864", +"1.0101011100011101000110101001010011111111010011000111111111100000011011100111010001100101100110001110001001100101001100110000011110100101101e21367"}, +{133, 13, +"2.3721a9107307a71c75c07c83b70a25a9853619030b5bcb55101ca5c2060bca46c331b92b33aa957c3ac7c817335287c6917999c38c3806b6b5919623023ac52063bb@6602", +"1.011001101111100001100100110100010100010011100010111110110100100000000010011101001011000100000110011011101001010010011110111100010010e24431"}, +{118, 2, +"1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960", +"1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960"}, +{102, 23, +"l.26lhk42clcm9g940eihakhi32gb3331lld488cf1j4f73ge051bfl8gcmcg78gkjc2iibjf752eag0dee6dafa97k79jlh11j3270@-2160", +"1.01101011011000100101110111110001011000101101011001011111001101000110111010000010011111101110101100010e-9767"}, +{156, 18, +"b.eb927dd4g48abee3cc2begehb9c3b8h83cae152db850ac2f3g816d6787825122c8h3aa3g8023h23000a8hg61065b3e367ac59ca373067730f96dd0d3b73b3c43fef91750b333gd497b8ce9228e7@5504", +"1.11000110111100011101100011001001110011101100011111010100101110010010010011111001100000011010011111111011001011111010001001011001110001100001101000000110000e22954"}, +{158, 5, +"3.0112043214104344433122444210142004032004444213123303302023242414000243311324332203224340334422234000104132020124210141322013240010134130441413233111204013422e-10468", +"1.1001011000111111110100100101110011100001110100101001101110011001101001101011010010111010111111101010100011100010101100110111011101000110110100000111001100011e-24305"}, +{7, 9, +"2.141540e-146", +"1.001111e-462"}, +{111, 5, +"3.21233234110011204313222402442032333320324004133424222041314021020411320312421014434003440431230413141402230403e7641", +"1.10010000000101010000101010101011011010000100010010010000010110001111000111111111000110111001100101101110101101e17743"}, +{76, 13, +"7.1c0861453a4ac156b6119ba7548251b5cb00b7c409c2bb8138214676468c9949676226013c1@4639", +"1.001000011000000011101101101010100010010001010111100110010101111110110010111e17169"}, +{6, 25, +"c.aj660@-6978", +"1.11000e-32402"}, +{156, 3, +"2.22101000022222000012110122210202211110020121210120112102122121111210000211020001020201202200011021211102012110220222110022001121011022011202000110120021012e-14744", +"1.11010001111000101111110000010011001101000100010010110011100100110001100111011101011111111100011111001100001111100101100000001000001100000000010010001011101e-23368"}, +{7, 23, +"1.4hclk2@2148", +"1.110110e9716"}, +{69, 11, +"2.77684920493191632416690544493465617a187218365952a6740034288687745a26@3263", +"1.01111000111000001111001110000110000110001111110011101100101111011100e11289"}, +{146, 21, +"3.agg4d0dj636d526d4i8643ch5jee4ge2c3i46k121857dbedagd98cjifaf0fgc09ca739g2fkfbfh06i687kic2kb8c7i48gda57bb6d9bh81eh49h0d8e3i7ad2kgb1ek86b86g3589k27d@3562", +"1.0010111111111100101010101010001100110101010011011100001110111000101101001110001110010100000001010001000111010000010011110100010010101100101000001e15647"}, +{20, 3, +"1.2000000021102111102e-16642", +"1.1011101011111110000e-26377"}, +{68, 13, +"1.a43205b2164676727806614acc0398925569c3962a3ba419881a5c63b651aa3ab46@-618", +"1.1111011000001110010100111000110010110110011001110001100101011111000e-2287"}, +{129, 4, +"2.22033002012102010122130132103000303000120122313322000222121000300000000000000000000000000000000000000000000000000000000000000000e13222", +"1.01010001111000010000110010010000100011010011100011110010011000000110011000000011000011010110111111010000000101010011001000000110e26445"}, +{22, 6, +"1.420033001013011530142e11704", +"1.001000110010110110001e30255"}, +{108, 6, +"1.03345424443433104422104400512453214240453335230205104304115343030341144544051005432030344054100542125304500e7375", +"1.00101101110001011101101111000010101011101000001111001110001101100000111100010101010101101100011110111010000e19064"}, +{91, 27, +"2.ao077kf8oqoihn5pm6f5eqdcgnd2132d7p6n7di8ep82a1a9be99pm36g1emacbenaeiqphpgpdjhmm9ke3pn4pdea@-5482", +"1.111101100001000011101010001000000111000100100111110010101101110001101101101101101010111110e-26066"}, +{96, 9, +"8.25805186310703506315505842015248775712246416686874260383701323213202658278523870037877823670166e-8134", +"1.11010111111000011100111001011010001110010001011101011101110101000101100100100010110011001010000e-25782"}, +{161, 16, +"7.3a7627c1e42ef738698e292f0b81728c4b14fe8c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-3342", +"1.1100111010011101100010011111000001111001000010111011110111001110000110100110001110001010010010111100001011100000010111001010001100010010110001010011111110100011e-13366"}, +{90, 3, +"2.10212200011211012002002221112120210222002020100202111000211012122020011102022112222021001e-3447", +"1.11100010111011011000101111110001000101000111110001100001010111101101011011110001000010001e-5463"}, +{100, 27, +"a.f81hjjakdnc021op6ffh530ec8ige6n2fqc8f8j7ia7qelebgqkm4ic5ohh652hq1kgpag6pp0ldin6ce1fg6mj34077f5qc5oe@6576", +"1.011101001010010011110001100011111111010001110110100100101001010000101011101011110010010011111100000e31271"}, +{152, 16, +"e.37ac48a0303f903c9d20883eddea4300d1190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-1388", +"1.1100011011110101100010010001010000000110000001111111001000000111100100111010010000010001000001111101101110111101010010000110000000011010001000110010000e-5549"}, +{106, 20, +"1.3g2h7i2776d50gjibi937f8cdci3idecdeh3j2gba0j8d1ghgg3eg609ji55h5g7jeai1bii3a4f9jhjfij6jd1g3cg0f6024e252gc3e@6422", +"1.100110000101011010100111100110000000100101000110110011010010000101000100110010001110011110111100010000111e27755"}, +{23, 17, +"9.f72e724454d1g0f60g93g6@-6563", +"1.0011100011110110010001e-26823"}, +{98, 6, +"1.2444223304453415235424343034030405514010421403514410005234221430055051205523402412055242134042045e-8535", +"1.1101110011010001101001001111100101111010100111001011110001000010100101101110011011101100000111011e-22063"}, +{4, 18, +"1.gec@-6711", +"1.100e-27984"}, +{69, 24, +"8.d45gdfnhkhb7a20nj96dnggic83imhjne0cceldechn1m4e9fbd9db0ablngjf9n7810@6975", +"1.00100111111100101100110011110110110000110110110010100101011111000100e31983"}, +{122, 8, +"4.0227760456667717717077553523466457265600000000000000000000000000000000000000000000000000000000000000000000000000000000000e-1767", +"1.0000001001011111111000010010111011011011111100111111100111100011111110110101110101001110011011010010111101011010111000000e-5299"}, +{144, 23, +"8.b01c48dg20bek9a5k376clc501aecg92bdjaeji2dm9230i7j3k36jm50b0c5a0753i2b18534cji34bcl2li033cc534m52k2gbegc25a5g30lf4calag58026i5d7li61jg9digj5ceb1@-4456", +"1.00010000110011010111011011110111001101111001010110001101011100100101101110110000010011011111100000100110001001001111111011010110000000001111110e-20154"}, +{111, 4, +"2.23100111310122202021232133233012212012232222323230133100000000000000000000000000000000000000000000000000000000e-10458", +"1.01011010000010101110100011010100010001001101110011111101111000110100110000110101110101010111011101100011111010e-20915"}, +{117, 10, +"1.61207328685870427963864999744776917701013812304254540861834226053316419217753608451422967376154318603744156166920074e-6440", +"1.01100011000100111001100010000000110010100001001011111010100001101111100100101100111010100011101110001010011010010010e-21393"}, +{106, 16, +"1.dd30a1d24091263243ca1c144f0000000000000000000000000000000000000000000000000000000000000000000000000000000@354", +"1.110111010011000010100001110100100100000010010001001001100011001001000011110010100001110000010100010011110e1416"}, +{77, 14, +"4.90d6913ba57b149d8d85a58c311b4d537c10bd7d3c10d69c62bc08d32269760126a58115a105@-7311", +"1.1001000000111100000111001001011000110101001111100001100111010100010000011111e-27834"}, +{8, 4, +"3.2230000e15197", +"1.1101011e30395"}, +{81, 24, +"1.84ni25h558abmhg2dk7bl2jbbmkf4i8i2bemc5cgmk9jf301c00k24271m9h7mgm4301be1lnldn4364@2573", +"1.01110010011000110110100101011001011111101111101100010110101101011101100001000010e11797"}, +{94, 2, +"1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427", +"1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427"}, +{77, 21, +"1.87e4k9df85g50ead6fcj4h86820ikdjdjg93d90ca406g470hhkh7ciaba1aggg753g36553ebh5@2538", +"1.0010001100011000111010000010011001010011000000100101010001100000111101000111e11148"}, +{80, 17, +"1.923gga999230g94fce02efg753ce001045a35e0264c9c2cb17850e32484fc3526dcg38ed874g5f2@3392", +"1.0011100111101001001101111001110100001100111110011110110001100110101010111001110e13865"}, +{99, 7, +"4.53646362336126606650465342500160461331562113222506144210636341332436342025203333264316511653025011e-5540", +"1.01101101111001001100001101101101010011001001100110111000010000101000011001001001101000011101011001e-15551"}, +{119, 20, +"1.c8966iabcf4de94ad15f9e83j407i3he7fch54h5jh0g5d74e06c057gg72a107didj8d1j8geibbfec5j36c3fgd5e12edjb9g10j7c9i03f33hi80ce0@7153", +"1.0101110101100011110001001110100110011000100000001001000110111110011111100011111010011101011111101101010011110111110100e30915"}, +{93, 13, +"2.c749cb562c3a758b1a21a650666a4c6c53c76ca58a1a75a0358c9ac3866887972b3551a03aa6c150856531258508@193", +"1.10101111101001011010111101100100111110011111010110111101100100010011001001100011110100111110e715"}, +{145, 14, +"1.c61614b64261d22c62cb9d16163ca4d144ac23351b708506b3b610b1b67b764ca974448d7a2c6515a6bc97503d4b2a530c75b2b677a464c6629c69b6c3d7860d7749b4b653c434d5@2050", +"1.111111100001101111100011001111100010010000101000011110000001110100111001011010100001001010111111010001111101000110011000011101110110001001100101e7805"}, +{159, 23, +"4.bj9l07l0215e7l6lf1dkf62i056l37jaa0gdih717656f1kk1a77883jf99jg31le43em76bmcg4lddl782ihkla0m392886d8lm67d6c3a1l4j12kg0l1k52ee77lmk0gech11g8jeei680k85bi460c7el17@-1539", +"1.01010100110100100101100001011100000001100011110001001101000010000001000010000110000110010001110100001101011101101001001101101111001101101111101001010010010100e-6960"}, +{24, 25, +"g.m749al09kflg5b42jnn4a7b@-2820", +"1.01010010101011010111011e-13092"}, +{88, 18, +"3.5ed0gad0bhhb7aa9ge2ad1dhcg6833f3e068936hghf23gd2aa69f13539f15hfce50aa64achfee49bfg7249g@-4058", +"1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"} +}; + +static void +check_reftable (void) +{ + int i, base; + mpfr_t x, y; + mpfr_prec_t p; + char *s; + + mpfr_init2 (x, 200); + mpfr_init2 (y, 200); + for (i = 0 ; i < numberof (RefTable) ; i++) + { + base = RefTable[i].base; + p = RefTable[i].prec; + mpfr_set_prec (x, p); + mpfr_set_prec (y, p); + mpfr_set_str_binary (x, RefTable[i].binstr); + mpfr_strtofr (y, RefTable[i].str, &s, base, MPFR_RNDN); + if (s == NULL || *s != 0) + { + printf ("strtofr didn't parse entire input for i=%d:\n" + " Str=%s", i, RefTable[i].str); + exit (1); + } + if (mpfr_cmp (x, y)) + { + printf ("Results differ between strtofr and set_binary for i=%d:\n" + " Set binary gives: ", i); + mpfr_dump (x); + printf (" strtofr gives: "); + mpfr_dump (y); + printf (" setstr gives: "); + mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN); + mpfr_dump (x); + mpfr_set_prec (x, 2*p); + mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN); + printf (" setstr ++ gives: "); + mpfr_dump (x); + exit (1); + } + } + mpfr_clear (y); + mpfr_clear (x); +} + +static void +check_parse (void) +{ + mpfr_t x; + char *s; + int res; + + mpfr_init (x); + + /* Invalid data */ + mpfr_set_si (x, -1, MPFR_RNDN); + res = mpfr_strtofr (x, " invalid", NULL, 10, MPFR_RNDN); + if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x)) + { + printf ("Failed parsing ' invalid' (1)\n X="); + mpfr_dump (x); + exit (1); + } + MPFR_ASSERTN (res == 0); + mpfr_set_si (x, -1, MPFR_RNDN); + res = mpfr_strtofr (x, " invalid", &s, 0, MPFR_RNDN); + if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x) || strcmp (s, " invalid")) + { + printf ("Failed parsing ' invalid' (2)\n S=%s\n X=", s); + mpfr_dump (x); + exit (1); + } + MPFR_ASSERTN (res == 0); + /* Check if it stops correctly */ + mpfr_strtofr (x, "15*x", &s, 10, MPFR_RNDN); + if (mpfr_cmp_ui (x, 15) || strcmp (s, "*x")) + { + printf ("Failed parsing '15*x'\n S=%s\n X=", s); + mpfr_dump (x); + exit (1); + } + /* Check for leading spaces */ + mpfr_strtofr (x, " 1.5E-10 *x^2", &s, 10, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "1.5E-10") || strcmp (s, " *x^2")) + { + printf ("Failed parsing '1.5E-10*x^2'\n S=%s\n X=", s); + mpfr_dump (x); + exit (1); + } + /* Check for leading sign */ + mpfr_strtofr (x, " +17.5E-42E ", &s, 10, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "17.5E-42") || strcmp (s, "E ")) + { + printf ("Failed parsing '+17.5E-42E '\n S=%s\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-17.5E+42E\n", &s, 10, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "-17.5E42") || strcmp (s, "E\n")) + { + printf ("Failed parsing '-17.5E+42\\n'\n S=%s\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* P form */ + mpfr_strtofr (x, "0x42P17", &s, 16, MPFR_RNDN); + if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '0x42P17' (base = 16)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-0X42p17", &s, 16, MPFR_RNDN); + if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '-0x42p17' (base = 16)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "42p17", &s, 16, MPFR_RNDN); + if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '42p17' (base = 16)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-42P17", &s, 16, MPFR_RNDN); + if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '-42P17' (base = 16)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "0b1001P17", &s, 2, MPFR_RNDN); + if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '0b1001P17' (base = 2)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-0B1001p17", &s, 2, MPFR_RNDN); + if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '-0B1001p17' (base = 2)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "1001p17", &s, 2, MPFR_RNDN); + if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '1001p17' (base = 2)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-1001P17", &s, 2, MPFR_RNDN); + if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '-1001P17' (base = 2)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* Check for auto-detection of the base */ + mpfr_strtofr (x, "+0x42P17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str (x, "42P17", 16, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-42E17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str (x, "-42E17", 10, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '-42E17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-42P17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str (x, "-42", 10, MPFR_RNDN) || strcmp (s, "P17")) + { + printf ("Failed parsing '-42P17' (base = 0)\n S='%s'\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, " 0b0101.011@42", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, " 0b0101.011P42", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "+0x42@17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str (x, "4.2@18", 16, MPFR_RNDN) || *s != 0) + { + printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + + + /* Check for space inside the mantissa */ + mpfr_strtofr (x, "+0x4 2@17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 4) || strcmp(s," 2@17")) + { + printf ("Failed parsing '+0x4 2@17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "+0x42 P17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0x42) || strcmp(s," P17")) + { + printf ("Failed parsing '+0x42 P17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* Space between mantissa and exponent */ + mpfr_strtofr (x, " -0b0101P 17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_si (x, -5) || strcmp(s,"P 17")) + { + printf ("Failed parsing '-0b0101P 17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* Check for Invalid exponent. */ + mpfr_strtofr (x, " -0b0101PF17", &s, 0, MPFR_RNDN); + if (mpfr_cmp_si (x, -5) || strcmp(s,"PF17")) + { + printf ("Failed parsing '-0b0101PF17'\n S=%s\n X=", s); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* At least one digit in the mantissa. */ + mpfr_strtofr (x, " .E10", &s, 0, MPFR_RNDN); + if (strcmp(s," .E10")) + { + printf ("Failed parsing ' .E10'\n S=%s\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* Check 2 '.': 2.3.4 */ + mpfr_strtofr (x, "-1.2.3E4", &s, 0, MPFR_RNDN); + if (mpfr_cmp_str1 (x, "-1.2") || strcmp(s,".3E4")) + { + printf ("Failed parsing '-1.2.3E4'\n S=%s\n X=", s); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + /* Check for 0x and 0b */ + mpfr_strtofr (x, " 0xG", &s, 0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) || strcmp(s,"xG")) + { + printf ("Failed parsing ' 0xG'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, " 0b2", &s, 0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) || strcmp(s,"b2")) + { + printf ("Failed parsing ' 0b2'\n S=%s\n X=", s); + mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, "-0x.23@2Z33", &s, 0, MPFR_RNDN); + if (mpfr_cmp_si (x, -0x23) || strcmp(s,"Z33")) + { + printf ("Failed parsing '-0x.23@2Z33'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + mpfr_strtofr (x, " 0x", &s, 0, MPFR_RNDN); + if (mpfr_cmp_ui (x, 0) || strcmp(s,"x")) + { + printf ("Failed parsing ' 0x'\n S=%s\n X=", s); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + + mpfr_clear (x); +} + +static void +check_overflow (void) +{ + mpfr_t x; + char *s; + + mpfr_init (x); + + /* Huge overflow */ + mpfr_strtofr (x, "123456789E2147483646", &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) + { + printf ("Check overflow failed (1) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "123456789E9223372036854775807", &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) + { + printf ("Check overflow failed (2) with:\n s='%s'\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "123456789E170141183460469231731687303715884105728", + &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) + { + printf ("Check overflow failed (3) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + + /* Limit overflow */ + mpfr_strtofr (x, "12E2147483646", &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) + { + printf ("Check overflow failed (4) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "12E2147483645", &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) + { + printf ("Check overflow failed (5) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "0123456789ABCDEF@2147483640", &s, 16, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) + { + printf ("Check overflow failed (6) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "0123456789ABCDEF@540000000", &s, 16, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) + { + printf ("Check overflow failed (7) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + + /* Check underflow */ + mpfr_strtofr (x, "123456789E-2147483646", &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) ) + { + printf ("Check underflow failed (1) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "123456789E-9223372036854775807", &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) ) + { + printf ("Check underflow failed (2) with:\n s='%s'\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "-123456789E-170141183460469231731687303715884105728", + &s, 0, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_NEG (x) ) + { + printf ("Check underflow failed (3) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + mpfr_strtofr (x, "0123456789ABCDEF@-540000000", &s, 16, MPFR_RNDN); + if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x)) + { + printf ("Check overflow failed (7) with:\n s=%s\n x=", s); + mpfr_dump (x); + exit (1); + } + + mpfr_clear (x); +} + +static void +check_retval (void) +{ + mpfr_t x; + int res; + + mpfr_init2 (x, 10); + + res = mpfr_strtofr (x, "01011000111", NULL, 2, MPFR_RNDN); + MPFR_ASSERTN (res == 0); + res = mpfr_strtofr (x, "11011000111", NULL, 2, MPFR_RNDN); + MPFR_ASSERTN (res > 0); + res = mpfr_strtofr (x, "110110001101", NULL, 2, MPFR_RNDN); + MPFR_ASSERTN (res < 0); + + mpfr_clear (x); +} + +/* Bug found by Christoph Lauter (in mpfr_set_str). */ +static struct bug20081025_test { + mpfr_rnd_t rnd; + int inexact; + const char *str; + const char *binstr; +} Bug20081028Table[] = { + {MPFR_RNDN, -1, "1.00000000000000000006", "1"}, + {MPFR_RNDZ, -1, "1.00000000000000000006", "1"}, + {MPFR_RNDU, +1, "1.00000000000000000006", + "10000000000000000000000000000001e-31"}, + {MPFR_RNDD, -1, "1.00000000000000000006", "1"}, + + + {MPFR_RNDN, +1, "-1.00000000000000000006", "-1"}, + {MPFR_RNDZ, +1, "-1.00000000000000000006", "-1"}, + {MPFR_RNDU, +1, "-1.00000000000000000006", "-1"}, + {MPFR_RNDD, -1, "-1.00000000000000000006", + "-10000000000000000000000000000001e-31"}, + + {MPFR_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"}, + {MPFR_RNDZ, -1, "0.999999999999999999999999999999999999999999999", + "11111111111111111111111111111111e-32"}, + {MPFR_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"}, + {MPFR_RNDD, -1, "0.999999999999999999999999999999999999999999999", + "11111111111111111111111111111111e-32"}, + + {MPFR_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"}, + {MPFR_RNDZ, +1, "-0.999999999999999999999999999999999999999999999", + "-11111111111111111111111111111111e-32"}, + {MPFR_RNDU, +1, "-0.999999999999999999999999999999999999999999999", + "-11111111111111111111111111111111e-32"}, + {MPFR_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"} +}; + +static void +bug20081028 (void) +{ + int i; + int inexact, res; + mpfr_rnd_t rnd; + mpfr_t x, y; + char *s; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 32); + for (i = 0 ; i < numberof (Bug20081028Table) ; i++) + { + rnd = Bug20081028Table[i].rnd; + inexact = Bug20081028Table[i].inexact; + mpfr_set_str_binary (x, Bug20081028Table[i].binstr); + res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd); + if (s == NULL || *s != 0) + { + printf ("Error in Bug20081028: strtofr didn't parse entire input\n" + "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str); + exit (1); + } + if (! SAME_SIGN (res, inexact)) + { + printf ("Error in Bug20081028: expected %s ternary value, " + "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ", + inexact > 0 ? "positive" : "negative", + res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str); + mpfr_dump (x); + printf (" strtofr gives: "); + mpfr_dump (y); + exit (1); + } + if (mpfr_cmp (x, y)) + { + printf ("Error in Bug20081028: Results differ between strtofr and " + "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n" + " Set binary gives: ", + i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str); + mpfr_dump (x); + printf (" strtofr gives: "); + mpfr_dump (y); + exit (1); + } + } + mpfr_clear (y); + mpfr_clear (x); +} + +/* check that 1.23e is correctly parsed, cf + http://gmplib.org/list-archives/gmp-bugs/2010-March/001898.html */ +static void +test20100310 (void) +{ + mpfr_t x, y; + char str[] = "1.23e", *endptr; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_strtofr (x, str, &endptr, 10, MPFR_RNDN); + mpfr_strtofr (y, "1.23", NULL, 10, MPFR_RNDN); + if (mpfr_cmp (x, y) != 0) + { + printf ("x <> y in test20100310\n"); + exit (1); + } + if (endptr != str + 4) /* strtofr should take into account '1.23', + not '1.23e' */ + { + printf ("endptr <> str + 4 in test20100310\n"); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); +} + +/* From a bug reported by Joseph S. Myers + https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */ +static void +bug20120814 (void) +{ + mpfr_exp_t emin = -30, e; + mpfr_t x, y; + int r; + char s[64], *p; + + mpfr_init2 (x, 2); + mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN); + mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD); + s[0] = s[1]; + s[1] = '.'; + for (p = s; *p != 0; p++) ; + *p = 'e'; + sprintf (p + 1, "%d", (int) e - 1); + + mpfr_init2 (y, 4); + r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN); + if (r <= 0 || ! mpfr_equal_p (x, y)) + { + printf ("Error in bug20120814\n"); + printf ("mpfr_strtofr failed on string \"%s\"\n", s); + printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin); + printf ("Got inex = %-6d and y = ", r); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +static void +bug20120829 (void) +{ + mpfr_t x1, x2, e; + int inex1, inex2, i, r; + char s[48] = "1e-1"; + + mpfr_init2 (e, 128); + mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0); + + inex1 = mpfr_set_si (e, -1, MPFR_RNDN); + MPFR_ASSERTN (inex1 == 0); + + for (i = 1; i <= sizeof(s) - 5; i++) + { + s[3+i] = '0'; + s[4+i] = 0; + inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN); + MPFR_ASSERTN (inex1 == 0); + RND_LOOP(r) + { + mpfr_rnd_t rnd = (mpfr_rnd_t) r; + + inex1 = mpfr_exp10 (x1, e, rnd); + inex1 = SIGN (inex1); + inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd); + inex2 = SIGN (inex2); + /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do: + strtofr.c:...: MPFR assertion failed: cy == 0 + r8396 is OK. + On 64-bit machines, for i = 15, + r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0) + r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize + r8394 and r8396 are OK. + */ + if (! mpfr_equal_p (x1, x2) || inex1 != inex2) + { + printf ("Error in bug20120829 for i = %d, rnd = %s\n", + i, mpfr_print_rnd_mode (rnd)); + printf ("Expected inex = %d, x = ", inex1); + mpfr_dump (x1); + printf ("Got inex = %d, x = ", inex2); + mpfr_dump (x2); + exit (1); + } + } + } + + mpfr_clears (e, x1, x2, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_special(); + check_reftable (); + check_parse (); + check_overflow (); + check_retval (); + bug20081028 (); + test20100310 (); + bug20120814 (); + bug20120829 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsub.c b/mpfr/tests/tsub.c new file mode 100644 index 0000000000..a8aee323fb --- /dev/null +++ b/mpfr/tests/tsub.c @@ -0,0 +1,658 @@ +/* Test file for mpfr_sub. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c); + if (ok) + { + mpfr_print_raw (b); + printf (" "); + mpfr_print_raw (c); + } + res = mpfr_sub (a, b, c, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_sub mpfr_sub +#endif + +static void +check_diverse (void) +{ + mpfr_t x, y, z; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + /* check corner case cancel=0, but add_exp=1 */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 4); + mpfr_set_prec (z, 2); + mpfr_setmax (y, __gmpfr_emax); + mpfr_set_str_binary (z, "0.1E-10"); /* tiny */ + test_sub (x, y, z, MPFR_RNDN); /* should round to 2^emax, i.e. overflow */ + if (!mpfr_inf_p (x) || mpfr_sgn (x) < 0) + { + printf ("Error in mpfr_sub(a,b,c,RNDN) for b=maxfloat, prec(a)<prec(b), c tiny\n"); + exit (1); + } + + /* other coverage test */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_prec (z, 2); + mpfr_set_ui (y, 1, MPFR_RNDN); + mpfr_set_si (z, -2, MPFR_RNDN); + test_sub (x, y, z, MPFR_RNDD); + if (mpfr_cmp_ui (x, 3)) + { + printf ("Error in mpfr_sub(1,-2,RNDD)\n"); + exit (1); + } + + mpfr_set_prec (x, 288); + mpfr_set_prec (y, 288); + mpfr_set_prec (z, 288); + mpfr_set_str_binary (y, "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80"); + mpfr_set_str_binary (z, "0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258"); + inexact = test_sub (x, y, z, MPFR_RNDN); + if (inexact <= 0) + { + printf ("Wrong inexact flag for prec=288\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 63); + mpfr_set_prec (z, 63); + mpfr_set_str_binary (x, "0.101101111011011100100100100111E31"); + mpfr_set_str_binary (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1"); + test_sub (z, x, y, MPFR_RNDN); + mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31"); + if (mpfr_cmp (z, y)) + { + printf ("Error in mpfr_sub (5)\n"); + printf ("expected "); mpfr_print_binary (y); puts (""); + printf ("got "); mpfr_print_binary (z); puts (""); + exit (1); + } + + mpfr_set_prec (y, 63); + mpfr_set_prec (z, 63); + mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31"); + mpfr_sub_ui (z, y, 1541116494, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.11111001001010010011010110101E-1"); + if (mpfr_cmp (z, y)) + { + printf ("Error in mpfr_sub (7)\n"); + printf ("expected "); mpfr_print_binary (y); puts (""); + printf ("got "); mpfr_print_binary (z); puts (""); + exit (1); + } + + mpfr_set_prec (y, 63); + mpfr_set_prec (z, 63); + mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31"); + mpfr_sub_ui (z, y, 1541116494, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.11111001001010010011010110101E-1"); + if (mpfr_cmp (z, y)) + { + printf ("Error in mpfr_sub (6)\n"); + printf ("expected "); mpfr_print_binary (y); puts (""); + printf ("got "); mpfr_print_binary (z); puts (""); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "0.10110111101001110100100101111000E0"); + mpfr_set_str_binary (y, "0.10001100100101000100110111000100E0"); + if ((inexact = test_sub (x, x, y, MPFR_RNDN))) + { + printf ("Wrong inexact flag (2): got %d instead of 0\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "0.11111000110111011000100111011010E0"); + mpfr_set_str_binary (y, "0.10011111101111000100001000000000E-3"); + if ((inexact = test_sub (x, x, y, MPFR_RNDN))) + { + printf ("Wrong inexact flag (1): got %d instead of 0\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 33); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.1E-32"); + mpfr_add (x, x, y, MPFR_RNDN); + mpfr_set_str_binary (y, "0.111111111111111111111111111111111E0"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_sub (1 - 1E-33) with prec=33\n"); + printf ("Expected "); mpfr_print_binary (y); puts (""); + printf ("got "); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 33); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_set_str_binary (y, "-0.1E-32"); + mpfr_add (x, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error in mpfr_sub (1 - 1E-33) with prec=32\n"); + printf ("Expected 1.0, got "); mpfr_print_binary (x); puts (""); + exit (1); + } + + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 65); + mpfr_set_prec (z, 64); + mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101"); + mpfr_set_str_binary (y, "0.1110111011110001110111011111111111101000011001011100101100101100"); + test_sub (z, x, y, MPFR_RNDZ); + if (mpfr_cmp_ui (z, 1)) + { + printf ("Error in mpfr_sub (1)\n"); + exit (1); + } + test_sub (z, x, y, MPFR_RNDU); + mpfr_set_str_binary (x, "1.000000000000000000000000000000000000000000000000000000000000001"); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_sub (2)\n"); + printf ("Expected "); mpfr_print_binary (x); puts (""); + printf ("Got "); mpfr_print_binary (z); puts (""); + exit (1); + } + mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101"); + test_sub (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 1)) + { + printf ("Error in mpfr_sub (3)\n"); + exit (1); + } + inexact = test_sub (z, x, y, MPFR_RNDA); + mpfr_set_str_binary (x, "1.000000000000000000000000000000000000000000000000000000000000001"); + if (mpfr_cmp (z, x) || inexact <= 0) + { + printf ("Error in mpfr_sub (4)\n"); + exit (1); + } + mpfr_set_prec (x, 66); + mpfr_set_str_binary (x, "1.11101110111100011101110111111111111010000110010111001011001010111"); + test_sub (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 1)) + { + printf ("Error in mpfr_sub (5)\n"); + exit (1); + } + + /* check in-place operations */ + mpfr_set_ui (x, 1, MPFR_RNDN); + test_sub (x, x, x, MPFR_RNDN); + if (mpfr_cmp_ui(x, 0)) + { + printf ("Error for mpfr_sub (x, x, x, MPFR_RNDN) with x=1.0\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_prec (z, 53); + mpfr_set_str1 (x, "1.229318102e+09"); + mpfr_set_str1 (y, "2.32221184180698677665e+05"); + test_sub (z, x, y, MPFR_RNDN); + if (mpfr_cmp_str1 (z, "1229085880.815819263458251953125")) + { + printf ("Error in mpfr_sub (1.22e9 - 2.32e5)\n"); + printf ("expected 1229085880.815819263458251953125, got "); + mpfr_out_str(stdout, 10, 0, z, MPFR_RNDN); + putchar('\n'); + exit (1); + } + + mpfr_set_prec (x, 112); + mpfr_set_prec (y, 98); + mpfr_set_prec (z, 54); + mpfr_set_str_binary (x, "0.11111100100000000011000011100000101101010001000111E-401"); + mpfr_set_str_binary (y, "0.10110000100100000101101100011111111011101000111000101E-464"); + test_sub (z, x, y, MPFR_RNDN); + if (mpfr_cmp (z, x)) { + printf ("mpfr_sub(z, x, y) failed for prec(x)=112, prec(y)=98\n"); + printf ("expected "); mpfr_print_binary (x); puts (""); + printf ("got "); mpfr_print_binary (z); puts (""); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_div_2exp (x, x, 32, MPFR_RNDN); + mpfr_sub_ui (x, x, 1, MPFR_RNDN); + + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_str_binary (x, "1e-12"); + mpfr_set_ui (y, 1, MPFR_RNDN); + test_sub (x, y, x, MPFR_RNDD); + mpfr_set_str_binary (y, "0.11111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_sub (x, y, x, MPFR_RNDD) for x=2^(-12), y=1\n"); + exit (1); + } + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_binary (x, "-0.100010000000000000000000E19"); + mpfr_set_str_binary (y, "0.100000000000000000000100E15"); + mpfr_add (x, x, y, MPFR_RNDD); + mpfr_set_str_binary (y, "-0.1E19"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_add (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 10); + mpfr_set_prec (z, 10); + mpfr_set_ui (y, 0, MPFR_RNDN); + mpfr_set_str_binary (z, "0.10001"); + if (test_sub (x, y, z, MPFR_RNDN) <= 0) + { + printf ("Wrong inexact flag in x=mpfr_sub(0,z) for prec(z)>prec(x)\n"); + exit (1); + } + if (test_sub (x, z, y, MPFR_RNDN) >= 0) + { + printf ("Wrong inexact flag in x=mpfr_sub(z,0) for prec(z)>prec(x)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +bug_ddefour(void) +{ + mpfr_t ex, ex1, ex2, ex3, tot, tot1; + + mpfr_init2(ex, 53); + mpfr_init2(ex1, 53); + mpfr_init2(ex2, 53); + mpfr_init2(ex3, 53); + mpfr_init2(tot, 150); + mpfr_init2(tot1, 150); + + mpfr_set_ui( ex, 1, MPFR_RNDN); + mpfr_mul_2exp( ex, ex, 906, MPFR_RNDN); + mpfr_log( tot, ex, MPFR_RNDN); + mpfr_set( ex1, tot, MPFR_RNDN); /* ex1 = high(tot) */ + test_sub( ex2, tot, ex1, MPFR_RNDN); /* ex2 = high(tot - ex1) */ + test_sub( tot1, tot, ex1, MPFR_RNDN); /* tot1 = tot - ex1 */ + mpfr_set( ex3, tot1, MPFR_RNDN); /* ex3 = high(tot - ex1) */ + + if (mpfr_cmp(ex2, ex3)) + { + printf ("Error in ddefour test.\n"); + printf ("ex2="); mpfr_print_binary (ex2); puts (""); + printf ("ex3="); mpfr_print_binary (ex3); puts (""); + exit (1); + } + + mpfr_clear (ex); + mpfr_clear (ex1); + mpfr_clear (ex2); + mpfr_clear (ex3); + mpfr_clear (tot); + mpfr_clear (tot1); +} + +/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */ +static void +check_two_sum (mpfr_prec_t p) +{ + mpfr_t x, y, u, v, w; + mpfr_rnd_t rnd; + int inexact; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (u, p); + mpfr_init2 (v, p); + mpfr_init2 (w, p); + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + if (mpfr_cmpabs (x, y) < 0) + mpfr_swap (x, y); + rnd = MPFR_RNDN; + inexact = test_sub (u, x, y, rnd); + test_sub (v, u, x, rnd); + mpfr_add (w, v, y, rnd); + /* as u = (x-y) - w, we should have inexact and w of opposite signs */ + if (((inexact == 0) && mpfr_cmp_ui (w, 0)) || + ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) || + ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0))) + { + printf ("Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, + mpfr_print_rnd_mode (rnd)); + printf ("x="); mpfr_print_binary(x); puts (""); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("u="); mpfr_print_binary(u); puts (""); + printf ("v="); mpfr_print_binary(v); puts (""); + printf ("w="); mpfr_print_binary(w); puts (""); + printf ("inexact = %d\n", inexact); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (u); + mpfr_clear (v); + mpfr_clear (w); +} + +#define MAX_PREC 200 + +static void +check_inexact (void) +{ + mpfr_t x, y, z, u; + mpfr_prec_t px, py, pu, pz; + int inexact, cmp; + mpfr_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (u); + + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 6, MPFR_RNDN); + mpfr_div_2exp (x, x, 4, MPFR_RNDN); /* x = 6/16 */ + mpfr_set_prec (y, 2); + mpfr_set_si (y, -1, MPFR_RNDN); + mpfr_div_2exp (y, y, 4, MPFR_RNDN); /* y = -1/16 */ + inexact = test_sub (y, y, x, MPFR_RNDN); /* y = round(-7/16) = -1/2 */ + if (inexact >= 0) + { + printf ("Error: wrong inexact flag for -1/16 - (6/16)\n"); + exit (1); + } + + for (px=2; px<MAX_PREC; px++) + { + mpfr_set_prec (x, px); + do + { + mpfr_urandomb (x, RANDS); + } + while (mpfr_cmp_ui (x, 0) == 0); + for (pu=2; pu<MAX_PREC; pu++) + { + mpfr_set_prec (u, pu); + do + { + mpfr_urandomb (u, RANDS); + } + while (mpfr_cmp_ui (u, 0) == 0); + { + py = 2 + (randlimb () % (MAX_PREC - 2)); + mpfr_set_prec (y, py); + /* warning: MPFR_EXP is undefined for 0 */ + pz = (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u) + : MPFR_EXP(u) - MPFR_EXP(x); + pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)); + mpfr_set_prec (z, pz); + rnd = RND_RAND (); + if (test_sub (z, x, u, rnd)) + { + printf ("z <- x - u should be exact\n"); + exit (1); + } + { + rnd = RND_RAND (); + inexact = test_sub (y, x, u, rnd); + cmp = mpfr_cmp (y, z); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong inexact flag for rnd=%s\n", + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("u="); mpfr_print_binary (u); puts (""); + printf ("y= "); mpfr_print_binary (y); puts (""); + printf ("x-u="); mpfr_print_binary (z); puts (""); + exit (1); + } + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); +} + +/* Bug found by Jakub Jelinek + * http://bugzilla.redhat.com/643657 + * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301 + * The consequence can be either an assertion failure (i = 2 in the + * testcase below, in debug mode) or an incorrectly rounded value. + */ +static void +bug20101017 (void) +{ + mpfr_t a, b, c; + int inex; + int i; + + mpfr_init2 (a, GMP_NUMB_BITS * 2); + mpfr_init2 (b, GMP_NUMB_BITS); + mpfr_init2 (c, GMP_NUMB_BITS); + + /* a = 2^(2N) + k.2^(2N-1) + 2^N and b = 1 + with N = GMP_NUMB_BITS and k = 0 or 1. + c = a - b should round to the same value as a. */ + + for (i = 2; i <= 3; i++) + { + mpfr_set_ui_2exp (a, i, GMP_NUMB_BITS - 1, MPFR_RNDN); + mpfr_add_ui (a, a, 1, MPFR_RNDN); + mpfr_mul_2ui (a, a, GMP_NUMB_BITS, MPFR_RNDN); + mpfr_set_ui (b, 1, MPFR_RNDN); + inex = mpfr_sub (c, a, b, MPFR_RNDN); + mpfr_set (b, a, MPFR_RNDN); + if (! mpfr_equal_p (c, b)) + { + printf ("Error in bug20101017 for i = %d.\n", i); + printf ("Expected "); + mpfr_out_str (stdout, 16, 0, b, MPFR_RNDN); + putchar ('\n'); + printf ("Got "); + mpfr_out_str (stdout, 16, 0, c, MPFR_RNDN); + putchar ('\n'); + exit (1); + } + if (inex >= 0) + { + printf ("Error in bug20101017 for i = %d: bad inex value.\n", i); + printf ("Expected negative, got %d.\n", inex); + exit (1); + } + } + + mpfr_set_prec (a, 64); + mpfr_set_prec (b, 129); + mpfr_set_prec (c, 2); + mpfr_set_str_binary (b, "0.100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001E65"); + mpfr_set_str_binary (c, "0.10E1"); + inex = mpfr_sub (a, b, c, MPFR_RNDN); + if (mpfr_cmp_ui_2exp (a, 1, 64) != 0 || inex >= 0) + { + printf ("Error in mpfr_sub for b-c for b=2^64+1+2^(-64), c=1\n"); + printf ("Expected result 2^64 with inex < 0\n"); + printf ("Got "); mpfr_print_binary (a); + printf (" with inex=%d\n", inex); + exit (1); + } + + mpfr_clears (a, b, c, (mpfr_ptr) 0); +} + +/* hard test of rounding */ +static void +check_rounding (void) +{ + mpfr_t a, b, c, res; + mpfr_prec_t p; + long k, l; + int i; + +#define MAXKL (2 * GMP_NUMB_BITS) + for (p = MPFR_PREC_MIN; p <= GMP_NUMB_BITS; p++) + { + mpfr_init2 (a, p); + mpfr_init2 (res, p); + mpfr_init2 (b, p + 1 + MAXKL); + mpfr_init2 (c, MPFR_PREC_MIN); + + /* b = 2^p + 1 + 2^(-k), c = 2^(-l) */ + for (k = 0; k <= MAXKL; k++) + for (l = 0; l <= MAXKL; l++) + { + mpfr_set_ui_2exp (b, 1, p, MPFR_RNDN); + mpfr_add_ui (b, b, 1, MPFR_RNDN); + mpfr_mul_2ui (b, b, k, MPFR_RNDN); + mpfr_add_ui (b, b, 1, MPFR_RNDN); + mpfr_div_2ui (b, b, k, MPFR_RNDN); + mpfr_set_ui_2exp (c, 1, -l, MPFR_RNDN); + i = mpfr_sub (a, b, c, MPFR_RNDN); + /* b - c = 2^p + 1 + 2^(-k) - 2^(-l), should be rounded to + 2^p for l <= k, and 2^p+2 for l < k */ + if (l <= k) + { + if (mpfr_cmp_ui_2exp (a, 1, p) != 0) + { + printf ("Wrong result in check_rounding\n"); + printf ("p=%lu k=%ld l=%ld\n", (unsigned long) p, k, l); + printf ("b="); mpfr_print_binary (b); puts (""); + printf ("c="); mpfr_print_binary (c); puts (""); + printf ("Expected 2^%lu\n", (unsigned long) p); + printf ("Got "); mpfr_print_binary (a); puts (""); + exit (1); + } + if (i >= 0) + { + printf ("Wrong ternary value in check_rounding\n"); + printf ("p=%lu k=%ld l=%ld\n", (unsigned long) p, k, l); + printf ("b="); mpfr_print_binary (b); puts (""); + printf ("c="); mpfr_print_binary (c); puts (""); + printf ("a="); mpfr_print_binary (a); puts (""); + printf ("Expected < 0, got %d\n", i); + exit (1); + } + } + else /* l < k */ + { + mpfr_set_ui_2exp (res, 1, p, MPFR_RNDN); + mpfr_add_ui (res, res, 2, MPFR_RNDN); + if (mpfr_cmp (a, res) != 0) + { + printf ("Wrong result in check_rounding\n"); + printf ("b="); mpfr_print_binary (b); puts (""); + printf ("c="); mpfr_print_binary (c); puts (""); + printf ("Expected "); mpfr_print_binary (res); puts (""); + printf ("Got "); mpfr_print_binary (a); puts (""); + exit (1); + } + if (i <= 0) + { + printf ("Wrong ternary value in check_rounding\n"); + printf ("b="); mpfr_print_binary (b); puts (""); + printf ("c="); mpfr_print_binary (c); puts (""); + printf ("Expected > 0, got %d\n", i); + exit (1); + } + } + } + + mpfr_clear (a); + mpfr_clear (res); + mpfr_clear (b); + mpfr_clear (c); + } +} + +#define TEST_FUNCTION test_sub +#define TWO_ARGS +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + mpfr_prec_t p; + unsigned int i; + + tests_start_mpfr (); + + bug20101017 (); + check_rounding (); + check_diverse (); + check_inexact (); + bug_ddefour (); + for (p=2; p<200; p++) + for (i=0; i<50; i++) + check_two_sum (p); + test_generic (2, 800, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsub1sp.c b/mpfr/tests/tsub1sp.c new file mode 100644 index 0000000000..38feddbd71 --- /dev/null +++ b/mpfr/tests/tsub1sp.c @@ -0,0 +1,515 @@ +/* Test file for mpfr_sub1sp. + +Copyright 2003-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void check_special (void); +static void check_random (mpfr_prec_t p); + +int +main (void) +{ + mpfr_prec_t p; + + tests_start_mpfr (); + + check_special (); + for (p = 2 ; p < 200 ; p++) + check_random (p); + + tests_end_mpfr (); + return 0; +} + +#define STD_ERROR \ + do \ + { \ + printf("ERROR: for %s and p=%lu and i=%d:\nY=", \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \ + mpfr_print_binary(y); \ + printf("\nZ="); mpfr_print_binary(z); \ + printf("\nReal: "); mpfr_print_binary(x2); \ + printf("\nGot : "); mpfr_print_binary(x); \ + putchar('\n'); \ + exit(1); \ + } \ + while (0) + +#define STD_ERROR2 \ + do \ + { \ + printf("ERROR: for %s and p=%lu and i=%d:\nY=", \ + mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \ + mpfr_print_binary(y); \ + printf("\nZ="); mpfr_print_binary(z); \ + printf("\nR="); mpfr_print_binary(x); \ + printf("\nWrong inexact flag. Real: %d. Got: %d\n", \ + inexact1, inexact2); \ + exit(1); \ + } \ + while (0) + +static void +check_random (mpfr_prec_t p) +{ + mpfr_t x,y,z,x2; + int r; + int i, inexact1, inexact2; + + mpfr_inits2 (p, x, y, z, x2, (mpfr_ptr) 0); + + for (i = 0 ; i < 500 ; i++) + { + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + if (MPFR_IS_PURE_FP(y) && MPFR_IS_PURE_FP(z)) + for(r = 0 ; r < MPFR_RND_MAX ; r++) + { + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + } + } + + mpfr_clears (x, y, z, x2, (mpfr_ptr) 0); +} + +static void +check_special (void) +{ + mpfr_t x,y,z,x2; + int r; + mpfr_prec_t p; + int i = -1, inexact1, inexact2; + mpfr_exp_t es; + + mpfr_inits (x, y, z, x2, (mpfr_ptr) 0); + + for (r = 0 ; r < MPFR_RND_MAX ; r++) + { + p = 53; + mpfr_set_prec(x, 53); + mpfr_set_prec(x2, 53); + mpfr_set_prec(y, 53); + mpfr_set_prec(z, 53); + + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011000001101101011011001E31"); + + mpfr_sub1sp (x, y, y, (mpfr_rnd_t) r); + if (mpfr_cmp_ui(x, 0)) + { + printf("Error for x-x with p=%lu. Expected 0. Got:", + (unsigned long) p); + mpfr_print_binary(x); + exit(1); + } + + mpfr_set(z, y, (mpfr_rnd_t) r); + mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp_ui(x, 0)) + { + printf("Error for x-y with y=x and p=%lu. Expected 0. Got:", + (unsigned long) p); + mpfr_print_binary(x); + exit(1); + } + /* diff = 0 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011001001101101011011001E31"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + /* Diff = 1 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011000001101101011011001E30"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + /* Diff = 2 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011000101101101011011001E32"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + /* Diff = 32 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011000001101101011011001E63"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + /* Diff = 52 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011010001101101011011001E83"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + /* Diff = 53 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011111000001101101011011001E31"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + /* Diff > 200 */ + mpfr_set_str_binary (y, + "0.10110111101101110010010010011011000001101101011011001E331"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000000000000000000000000E31"); + mpfr_set_str_binary (z, + "0.11111111111111111111111111111111111111111111111111111E30"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000000000000000000000000E31"); + mpfr_set_str_binary (z, + "0.11111111111111111111111111111111111111111111111111111E29"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000000000000000000000000E52"); + mpfr_set_str_binary (z, + "0.10000000000010000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.11100000000000000000000000000000000000000000000000000E53"); + mpfr_set_str_binary (z, + "0.10000000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(z, y, z, (mpfr_rnd_t) r); + mpfr_set(x, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000000000000000000000000E53"); + mpfr_set_str_binary (z, + "0.10100000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000000000000000000000000E54"); + mpfr_set_str_binary (z, + "0.10100000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 63; + mpfr_set_prec(x, p); + mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); + mpfr_set_prec(z, p); + mpfr_set_str_binary (y, + "0.100000000000000000000000000000000000000000000000000000000000000E62"); + mpfr_set_str_binary (z, + "0.110000000000000000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 64; + mpfr_set_prec(x, 64); + mpfr_set_prec(x2, 64); + mpfr_set_prec(y, 64); + mpfr_set_prec(z, 64); + + mpfr_set_str_binary (y, + "0.1100000000000000000000000000000000000000000000000000000000000000E31"); + mpfr_set_str_binary (z, + "0.1111111111111111111111111110000000000000000000000000011111111111E29"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.1000000000000000000000000000000000000000000000000000000000000000E63"); + mpfr_set_str_binary (z, + "0.1011000000000000000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.1000000000000000000000000000000000000000000000000000000000000000E63"); + mpfr_set_str_binary (z, + "0.1110000000000000000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000000000000000000000000000000000E63"); + mpfr_set_str_binary (z, + "0.10000000000000000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.1000000000000000000000000000000000000000000000000000000000000000E64"); + mpfr_set_str_binary (z, + "0.1010000000000000000000000000000000000000000000000000000000000000E00"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + MPFR_SET_NAN(x); + MPFR_SET_NAN(x2); + mpfr_set_str_binary (y, + "0.1000000000000000000000000000000000000000000000000000000000000000" + "E-1073741823"); + mpfr_set_str_binary (z, + "0.1100000000000000000000000000000000000000000000000000000000000000" + "E-1073741823"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 9; + mpfr_set_prec(x, p); + mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); + mpfr_set_prec(z, p); + + mpfr_set_str_binary (y, "0.100000000E1"); + mpfr_set_str_binary (z, "0.100000000E-8"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 34; + mpfr_set_prec(x, p); + mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); + mpfr_set_prec(z, p); + + mpfr_set_str_binary (y, "-0.1011110000111100010111011100110100E-18"); + mpfr_set_str_binary (z, "0.1000101010110011010101011110000000E-14"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 124; + mpfr_set_prec(x, p); + mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); + mpfr_set_prec(z, p); + + mpfr_set_str_binary (y, +"0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1"); + mpfr_set_str_binary (z, +"0.1011111000100111000011001000011101010101101100101010101001000001110100001101110110001110111010000011101001100010111110001100E-31"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 288; + mpfr_set_prec(x, p); + mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); + mpfr_set_prec(z, p); + + mpfr_set_str_binary (y, + "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80"); + mpfr_set_str_binary (z, + "-0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 85; + mpfr_set_prec(x, p); + mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); + mpfr_set_prec(z, p); + + mpfr_set_str_binary (y, +"0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4"); + mpfr_set_str_binary (z, +"0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + p = 64; + mpfr_set_prec(x, p); mpfr_set_prec(x2, p); + mpfr_set_prec(y, p); mpfr_set_prec(z, p); + + mpfr_set_str_binary (y, + "0.11000000000000000000000000000000" + "00000000000000000000000000000000E1"); + mpfr_set_str_binary (z, + "0.10000000000000000000000000000000" + "00000000000000000000000000000001E0"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.11000000000000000000000000000000" + "000000000000000000000000000001E1"); + mpfr_set_str_binary (z, + "0.10000000000000000000000000000000" + "00000000000000000000000000000001E0"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + es = mpfr_get_emin (); + set_emin (-1024); + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000" + "000000000000000000000000000000E-1023"); + mpfr_set_str_binary (z, + "0.10000000000000000000000000000000" + "00000000000000000000000000000001E-1023"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + mpfr_set_str_binary (y, + "0.10000000000000000000000000000000" + "000000000000000000000000000000E-1023"); + mpfr_set_str_binary (z, + "0.1000000000000000000000000000000" + "000000000000000000000000000000E-1023"); + inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r); + inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r); + if (mpfr_cmp(x, x2)) + STD_ERROR; + if (inexact1 != inexact2) + STD_ERROR2; + + set_emin (es); + } + + mpfr_clears (x, y, z, x2, (mpfr_ptr) 0); +} diff --git a/mpfr/tests/tsub_d.c b/mpfr/tests/tsub_d.c new file mode 100644 index 0000000000..dcaa031534 --- /dev/null +++ b/mpfr/tests/tsub_d.c @@ -0,0 +1,128 @@ +/* Test file for mpfr_sub_d + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) + +static void +check_nans (void) +{ + mpfr_t x, y; + int inexact; + + mpfr_init2 (x, 123); + mpfr_init2 (y, 123); + + /* nan - 1.0 is nan */ + mpfr_set_nan (x); + mpfr_clear_flags (); + inexact = mpfr_sub_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf - 1.0 == +inf */ + mpfr_set_inf (x, 1); + mpfr_clear_flags (); + inexact = mpfr_sub_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_POS (y)); + + /* -inf - 1.0 == -inf */ + mpfr_set_inf (x, -1); + mpfr_clear_flags (); + inexact = mpfr_sub_d (y, x, 1.0, MPFR_RNDN); + MPFR_ASSERTN (inexact == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (MPFR_IS_NEG (y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_sub_d +#define DOUBLE_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (void) +{ + mpfr_t x, y, z; + double d; + int inexact; + tests_start_mpfr (); + + /* check with enough precision */ + mpfr_init2 (x, IEEE_DBL_MANT_DIG); + mpfr_init2 (y, IEEE_DBL_MANT_DIG); + mpfr_init2 (z, IEEE_DBL_MANT_DIG); + + mpfr_set_str (y, "4096", 10, MPFR_RNDN); + d = 0.125; + mpfr_clear_flags (); + inexact = mpfr_sub_d (x, y, d, MPFR_RNDN); + if (inexact != 0) + { + printf ("Inexact flag error in mpfr_sub_d\n"); + exit (1); + } + mpfr_set_str (z, "4095.875", 10, MPFR_RNDN); + if (mpfr_cmp (z, x)) + { + printf ("Error in mpfr_sub_d ("); + mpfr_out_str (stdout, 10, 7, y, MPFR_RNDN); + printf (" + %.20g)\nexpected ", d); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\ngot "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clears (x, y, z, (mpfr_ptr) 0); + + check_nans (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} + +#else + +int +main (void) +{ + printf ("Warning! Test disabled for this MPFR version.\n"); + return 0; +} + +#endif diff --git a/mpfr/tests/tsub_ui.c b/mpfr/tests/tsub_ui.c new file mode 100644 index 0000000000..6536895755 --- /dev/null +++ b/mpfr/tests/tsub_ui.c @@ -0,0 +1,144 @@ +/* Test file for mpfr_sub_ui + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +/* checks that x-y gives the right results with 53 bits of precision */ +static void +check3 (const char *xs, unsigned long y, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx,zz; + + mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_sub_ui (zz, xx, y, rnd_mode); + if (mpfr_cmp_str1(zz, zs)) + { + printf ("expected sum is %s, got ", zs); + mpfr_print_binary(zz); + printf ("\nmpfr_sub_ui failed for x=%s y=%lu with rnd_mode=%s\n", + xs, y, mpfr_print_rnd_mode (rnd_mode)); + exit (1); + } + mpfr_clears (xx, zz, (mpfr_ptr) 0); +} + +/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v), + then x + y = u + w +thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */ +static void +check_two_sum (mpfr_prec_t p) +{ + unsigned int x; + mpfr_t y, u, v, w; + mpfr_rnd_t rnd; + int inexact; + + mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0); + do + { + x = randlimb (); + } + while (x < 1); + mpfr_urandomb (y, RANDS); + rnd = MPFR_RNDN; + inexact = mpfr_sub_ui (u, y, x, rnd); + mpfr_add_ui (v, u, x, rnd); + mpfr_sub (w, v, y, rnd); + /* as u - (y-x) = w, we should have inexact and w of same sign */ + if (((inexact == 0) && mpfr_cmp_ui (w, 0)) || + ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) || + ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0))) + { + printf ("Wrong inexact flag for prec=%u, rnd=%s\n", + (unsigned int) p, mpfr_print_rnd_mode (rnd)); + printf ("x=%u\n", x); + printf ("y="); mpfr_print_binary(y); puts (""); + printf ("u="); mpfr_print_binary(u); puts (""); + printf ("v="); mpfr_print_binary(v); puts (""); + printf ("w="); mpfr_print_binary(w); puts (""); + printf ("inexact = %d\n", inexact); + exit (1); + } + mpfr_clears (y, u, v, w, (mpfr_ptr) 0); +} + +static void +check_nans (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + /* nan - 1 == nan */ + mpfr_set_nan (x); + mpfr_sub_ui (y, x, 1L, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf - 1 == +inf */ + mpfr_set_inf (x, 1); + mpfr_sub_ui (y, x, 1L, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) > 0); + + /* -inf - 1 == -inf */ + mpfr_set_inf (x, -1); + mpfr_sub_ui (y, x, 1L, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) < 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +#define TEST_FUNCTION mpfr_sub_ui +#define ULONG_ARG2 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_prec_t p; + int k; + + tests_start_mpfr (); + + check_nans (); + + for (p=2; p<200; p++) + for (k=0; k<200; k++) + check_two_sum (p); + + check3 ("0.9999999999", 1, MPFR_RNDN, + "-10000000827403709990903735160827636718750e-50"); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsubnormal.c b/mpfr/tests/tsubnormal.c new file mode 100644 index 0000000000..9c5a7feaea --- /dev/null +++ b/mpfr/tests/tsubnormal.c @@ -0,0 +1,222 @@ +/* Test file for mpfr_subnormalize. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +static const struct { + const char *in; + int i; + mpfr_rnd_t rnd; + const char *out; + int j; +} tab[] = { /* 4th field: use the mpfr_dump format, in case of error. */ + {"1E1", 0, MPFR_RNDN, "0.100000000E2", 0}, + {"1E1", -1, MPFR_RNDZ, "0.100000000E2", -1}, + {"1E1", -1, MPFR_RNDD, "0.100000000E2", -1}, + {"1E1", 1, MPFR_RNDU, "0.100000000E2", 1}, + {"0.10000E-10", 0, MPFR_RNDN, "0.100000000E-10", 0}, + {"0.10001E-10", 0, MPFR_RNDN, "0.100000000E-10", -1}, + {"0.11001E-10", 0, MPFR_RNDN, "0.100000000E-9", 1}, + {"0.11001E-10", 0, MPFR_RNDZ, "0.100000000E-10", -1}, + {"0.11001E-10", 0, MPFR_RNDU, "0.100000000E-9", 1}, + {"0.11000E-10", 0, MPFR_RNDN, "0.100000000E-9", 1}, + {"0.11000E-10", -1, MPFR_RNDN, "0.100000000E-9", 1}, + {"0.11000E-10", 1, MPFR_RNDN, "0.100000000E-10", -1}, + {"0.11111E-8", 0, MPFR_RNDN, "0.100000000E-7", 1}, + {"0.10111E-8", 0, MPFR_RNDN, "0.110000000E-8", 1}, + {"0.11110E-8", -1, MPFR_RNDN, "0.100000000E-7", 1}, + {"0.10110E-8", 1, MPFR_RNDN, "0.101000000E-8", -1} +}; + +static void +check1 (void) +{ + mpfr_t x; + int i, j, k, s, old_inex, tiny, expj; + mpfr_exp_t emin, emax; + unsigned int expflags, flags; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_set_default_prec (9); + mpfr_set_emin (-10); + mpfr_set_emax (10); + + mpfr_init (x); + for (i = 0; i < (sizeof (tab) / sizeof (tab[0])); i++) + for (s = 0; s <= (tab[i].rnd == MPFR_RNDN); s++) + for (k = 0; k <= 1; k++) + { + mpfr_set_str (x, tab[i].in, 2, MPFR_RNDN); + old_inex = tab[i].i; + expj = tab[i].j; + if (s) + { + mpfr_neg (x, x, MPFR_RNDN); + old_inex = - old_inex; + expj = - expj; + } + if (k && old_inex) + old_inex = old_inex < 0 ? INT_MIN : INT_MAX; + tiny = MPFR_GET_EXP (x) <= -3; + mpfr_clear_flags (); + j = mpfr_subnormalize (x, old_inex, tab[i].rnd); + expflags = + (tiny ? MPFR_FLAGS_UNDERFLOW : 0) | + (expj ? MPFR_FLAGS_INEXACT : 0); + flags = __gmpfr_flags; + if (s) + mpfr_neg (x, x, MPFR_RNDN); + if (mpfr_cmp_str (x, tab[i].out, 2, MPFR_RNDN) != 0 || + flags != expflags || ! SAME_SIGN (j, expj)) + { + const char *sgn = s ? "-" : ""; + printf ("Error for i = %d (old_inex = %d), k = %d, x = %s%s\n" + "Expected: %s%s\nGot: ", i, old_inex, k, + sgn, tab[i].in, sgn, tab[i].out); + if (s) + mpfr_neg (x, x, MPFR_RNDN); + mpfr_dump (x); + printf ("Expected flags = %u, got %u\n", expflags, flags); + printf ("Expected ternary value = %d, got %d\n", expj, j); + exit (1); + } + } + mpfr_clear (x); + + MPFR_ASSERTN (mpfr_get_emin () == -10); + MPFR_ASSERTN (mpfr_get_emax () == 10); + + set_emin (emin); + set_emax (emax); +} + +/* bug found by Kevin P. Rauch on 22 Oct 2007 */ +static void +check2 (void) +{ + mpfr_t x, y, z; + int tern; + mpfr_exp_t emin; + + emin = mpfr_get_emin (); + + mpfr_init2 (x, 32); + mpfr_init2 (y, 32); + mpfr_init2 (z, 32); + + mpfr_set_ui (x, 0xC0000000U, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); + mpfr_set_ui (y, 0xFFFFFFFEU, MPFR_RNDN); + mpfr_set_exp (x, 0); + mpfr_set_exp (y, 0); + mpfr_set_emin (-29); + + tern = mpfr_mul (z, x, y, MPFR_RNDN); + /* z = -0.BFFFFFFE, tern > 0 */ + + tern = mpfr_subnormalize (z, tern, MPFR_RNDN); + /* z should be -0.75 */ + MPFR_ASSERTN (tern < 0 && mpfr_cmp_si_2exp (z, -3, -2) == 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + MPFR_ASSERTN (mpfr_get_emin () == -29); + + set_emin (emin); +} + +/* bug found by Kevin P. Rauch on 22 Oct 2007 */ +static void +check3 (void) +{ + mpfr_t x, y, z; + int tern; + mpfr_exp_t emin; + + emin = mpfr_get_emin (); + + mpfr_init2 (x, 32); + mpfr_init2 (y, 32); + mpfr_init2 (z, 32); + + mpfr_set_ui (x, 0xBFFFFFFFU, MPFR_RNDN); /* 3221225471/2^32 */ + mpfr_set_ui (y, 0x80000001U, MPFR_RNDN); /* 2147483649/2^32 */ + mpfr_set_exp (x, 0); + mpfr_set_exp (y, 0); + mpfr_set_emin (-1); + + /* the exact product is 6917529028714823679/2^64, which is rounded to + 3/8 = 0.375, which is smaller, thus tern < 0 */ + tern = mpfr_mul (z, x, y, MPFR_RNDN); + MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0); + + tern = mpfr_subnormalize (z, tern, MPFR_RNDN); + /* since emin = -1, and EXP(z)=-1, z should be rounded to precision + EXP(z)-emin+1 = 1, i.e., z should be a multiple of the smallest possible + positive representable value with emin=-1, which is 1/4. The two + possible values are 1/4 and 2/4, which are at equal distance of z. + But since tern < 0, we should choose the largest value, i.e., 2/4. */ + MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0); + + /* here is another test for the alternate case, where z was rounded up + first, thus we have to round down */ + mpfr_set_str_binary (x, "0.11111111111010110101011011011011"); + mpfr_set_str_binary (y, "0.01100000000001111100000000001110"); + tern = mpfr_mul (z, x, y, MPFR_RNDN); + MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0); + tern = mpfr_subnormalize (z, tern, MPFR_RNDN); + MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 1, -2) == 0); + + /* finally the case where z was exact, which we simulate here */ + mpfr_set_ui_2exp (z, 3, -3, MPFR_RNDN); + tern = mpfr_subnormalize (z, 0, MPFR_RNDN); + MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + MPFR_ASSERTN (mpfr_get_emin () == -1); + + set_emin (emin); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check1 (); + check2 (); + check3 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tsum.c b/mpfr/tests/tsum.c new file mode 100644 index 0000000000..190a3562f3 --- /dev/null +++ b/mpfr/tests/tsum.c @@ -0,0 +1,357 @@ +/* tsum -- test file for the list summation function + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include "mpfr-test.h" + +static int +check_is_sorted (unsigned long n, mpfr_srcptr *perm) +{ + unsigned long i; + + for (i = 0; i < n - 1; i++) + if (MPFR_GET_EXP(perm[i]) < MPFR_GET_EXP(perm[i+1])) + return 0; + return 1; +} + +static int +sum_tab (mpfr_ptr ret, mpfr_t *tab, unsigned long n, mpfr_rnd_t rnd) +{ + mpfr_ptr *tabtmp; + unsigned long i; + int inexact; + MPFR_TMP_DECL(marker); + + MPFR_TMP_MARK(marker); + tabtmp = (mpfr_ptr *) MPFR_TMP_ALLOC(n * sizeof(mpfr_srcptr)); + for (i = 0; i < n; i++) + tabtmp[i] = tab[i]; + + inexact = mpfr_sum (ret, tabtmp, n, rnd); + MPFR_TMP_FREE(marker); + return inexact; +} + + +static mpfr_prec_t +get_prec_max (mpfr_t *tab, unsigned long n, mpfr_prec_t f) +{ + mpfr_prec_t res; + mpfr_exp_t min, max; + unsigned long i; + + i = 0; + while (MPFR_IS_ZERO (tab[i])) + { + i++; + if (i == n) + return MPFR_PREC_MIN; /* all values are 0 */ + } + + if (! mpfr_check (tab[i])) + { + printf ("tab[%lu] is not valid.\n", i); + exit (1); + } + MPFR_ASSERTN (MPFR_IS_FP (tab[i])); + min = max = MPFR_GET_EXP(tab[i]); + for (i++; i < n; i++) + { + if (! mpfr_check (tab[i])) + { + printf ("tab[%lu] is not valid.\n", i); + exit (1); + } + MPFR_ASSERTN (MPFR_IS_FP (tab[i])); + if (! MPFR_IS_ZERO (tab[i])) + { + if (MPFR_GET_EXP(tab[i]) > max) + max = MPFR_GET_EXP(tab[i]); + if (MPFR_GET_EXP(tab[i]) < min) + min = MPFR_GET_EXP(tab[i]); + } + } + res = max - min; + res += f; + res += __gmpfr_ceil_log2 (n) + 1; + return res; +} + + +static void +algo_exact (mpfr_t somme, mpfr_t *tab, unsigned long n, mpfr_prec_t f) +{ + unsigned long i; + mpfr_prec_t prec_max; + + prec_max = get_prec_max(tab, n, f); + mpfr_set_prec (somme, prec_max); + mpfr_set_ui (somme, 0, MPFR_RNDN); + for (i = 0; i < n; i++) + { + if (mpfr_add(somme, somme, tab[i], MPFR_RNDN)) + { + printf ("FIXME: algo_exact is buggy.\n"); + exit (1); + } + } +} + +/* Test the sorting function */ +static void +test_sort (mpfr_prec_t f, unsigned long n) +{ + mpfr_t *tab; + mpfr_ptr *tabtmp; + mpfr_srcptr *perm; + unsigned long i; + mpfr_prec_t prec = MPFR_PREC_MIN; + + /* Init stuff */ + tab = (mpfr_t *) tests_allocate (n * sizeof (mpfr_t)); + for (i = 0; i < n; i++) + mpfr_init2 (tab[i], f); + tabtmp = (mpfr_ptr *) tests_allocate (n * sizeof(mpfr_ptr)); + perm = (mpfr_srcptr *) tests_allocate (n * sizeof(mpfr_srcptr)); + + for (i = 0; i < n; i++) + { + mpfr_urandomb (tab[i], RANDS); + tabtmp[i] = tab[i]; + } + + mpfr_sum_sort ((mpfr_srcptr *)tabtmp, n, perm, &prec); + + if (check_is_sorted (n, perm) == 0) + { + printf ("mpfr_sum_sort incorrect.\n"); + for (i = 0; i < n; i++) + mpfr_dump (perm[i]); + exit (1); + } + + /* Clear stuff */ + for (i = 0; i < n; i++) + mpfr_clear (tab[i]); + tests_free (tab, n * sizeof (mpfr_t)); + tests_free (tabtmp, n * sizeof(mpfr_ptr)); + tests_free (perm, n * sizeof(mpfr_srcptr)); +} + +static void +test_sum (mpfr_prec_t f, unsigned long n) +{ + mpfr_t sum, real_sum, real_non_rounded; + mpfr_t *tab; + unsigned long i; + int rnd_mode; + + /* Init */ + tab = (mpfr_t *) tests_allocate (n * sizeof(mpfr_t)); + for (i = 0; i < n; i++) + mpfr_init2 (tab[i], f); + mpfr_inits2 (f, sum, real_sum, real_non_rounded, (mpfr_ptr) 0); + + /* First Uniform */ + for (i = 0; i < n; i++) + mpfr_urandomb (tab[i], RANDS); + algo_exact (real_non_rounded, tab, n, f); + for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++) + { + sum_tab (sum, tab, n, (mpfr_rnd_t) rnd_mode); + mpfr_set (real_sum, real_non_rounded, (mpfr_rnd_t) rnd_mode); + if (mpfr_cmp (real_sum, sum) != 0) + { + printf ("mpfr_sum incorrect.\n"); + mpfr_dump (real_sum); + mpfr_dump (sum); + exit (1); + } + } + + /* Then non uniform */ + for (i = 0; i < n; i++) + { + mpfr_urandomb (tab[i], RANDS); + if (! mpfr_zero_p (tab[i])) + mpfr_set_exp (tab[i], randlimb () % 1000); + } + algo_exact (real_non_rounded, tab, n, f); + for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++) + { + sum_tab (sum, tab, n, (mpfr_rnd_t) rnd_mode); + mpfr_set (real_sum, real_non_rounded, (mpfr_rnd_t) rnd_mode); + if (mpfr_cmp (real_sum, sum) != 0) + { + printf ("mpfr_sum incorrect.\n"); + mpfr_dump (real_sum); + mpfr_dump (sum); + exit (1); + } + } + + /* Clear stuff */ + for (i = 0; i < n; i++) + mpfr_clear (tab[i]); + mpfr_clears (sum, real_sum, real_non_rounded, (mpfr_ptr) 0); + tests_free (tab, n * sizeof(mpfr_t)); +} + +static +void check_special (void) +{ + mpfr_t tab[3], r; + mpfr_ptr tabp[3]; + int i; + + mpfr_inits (tab[0], tab[1], tab[2], r, (mpfr_ptr) 0); + tabp[0] = tab[0]; + tabp[1] = tab[1]; + tabp[2] = tab[2]; + + i = mpfr_sum (r, tabp, 0, MPFR_RNDN); + if (!MPFR_IS_ZERO (r) || !MPFR_IS_POS (r) || i != 0) + { + printf ("Special case n==0 failed!\n"); + exit (1); + } + + mpfr_set_ui (tab[0], 42, MPFR_RNDN); + i = mpfr_sum (r, tabp, 1, MPFR_RNDN); + if (mpfr_cmp_ui (r, 42) || i != 0) + { + printf ("Special case n==1 failed!\n"); + exit (1); + } + + mpfr_set_ui (tab[1], 17, MPFR_RNDN); + MPFR_SET_NAN (tab[2]); + i = mpfr_sum (r, tabp, 3, MPFR_RNDN); + if (!MPFR_IS_NAN (r) || i != 0) + { + printf ("Special case NAN failed!\n"); + exit (1); + } + + MPFR_SET_INF (tab[2]); + MPFR_SET_POS (tab[2]); + i = mpfr_sum (r, tabp, 3, MPFR_RNDN); + if (!MPFR_IS_INF (r) || !MPFR_IS_POS (r) || i != 0) + { + printf ("Special case +INF failed!\n"); + exit (1); + } + + MPFR_SET_INF (tab[2]); + MPFR_SET_NEG (tab[2]); + i = mpfr_sum (r, tabp, 3, MPFR_RNDN); + if (!MPFR_IS_INF (r) || !MPFR_IS_NEG (r) || i != 0) + { + printf ("Special case -INF failed!\n"); + exit (1); + } + + MPFR_SET_ZERO (tab[1]); + i = mpfr_sum (r, tabp, 2, MPFR_RNDN); + if (mpfr_cmp_ui (r, 42) || i != 0) + { + printf ("Special case 42+0 failed!\n"); + exit (1); + } + + MPFR_SET_NAN (tab[0]); + i = mpfr_sum (r, tabp, 3, MPFR_RNDN); + if (!MPFR_IS_NAN (r) || i != 0) + { + printf ("Special case NAN+0+-INF failed!\n"); + exit (1); + } + + mpfr_set_inf (tab[0], 1); + mpfr_set_ui (tab[1], 59, MPFR_RNDN); + mpfr_set_inf (tab[2], -1); + i = mpfr_sum (r, tabp, 3, MPFR_RNDN); + if (!MPFR_IS_NAN (r) || i != 0) + { + printf ("Special case +INF + 59 +-INF failed!\n"); + exit (1); + } + + mpfr_clears (tab[0], tab[1], tab[2], r, (mpfr_ptr) 0); +} + +/* bug reported by Joseph S. Myers on 2013-10-27 + https://sympa.inria.fr/sympa/arc/mpfr/2013-10/msg00015.html */ +static void +bug20131027 (void) +{ + mpfr_t r, t[4]; + mpfr_ptr p[4]; + char *s[4] = { + "0x1p1000", + "-0x0.fffffffffffff80000000000000001p1000", + "-0x1p947", + "0x1p880" + }; + int i; + + mpfr_init2 (r, 53); + for (i = 0; i < 4; i++) + { + mpfr_init2 (t[i], i == 0 ? 53 : 1000); + mpfr_set_str (t[i], s[i], 0, MPFR_RNDN); + p[i] = t[i]; + } + mpfr_sum (r, p, 4, MPFR_RNDN); + + if (MPFR_NOTZERO (r)) + { + printf ("mpfr_sum incorrect in bug20131027: expected 0, got\n"); + mpfr_dump (r); + exit (1); + } + + for (i = 0; i < 4; i++) + mpfr_clear (t[i]); + mpfr_clear (r); +} + +int +main (void) +{ + mpfr_prec_t p; + unsigned long n; + + tests_start_mpfr (); + + check_special (); + bug20131027 (); + test_sort (1764, 1026); + for (p = 2 ; p < 444 ; p += 17) + for (n = 2 ; n < 1026 ; n += 42 + p) + test_sum (p, n); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tswap.c b/mpfr/tests/tswap.c new file mode 100644 index 0000000000..afc20b801b --- /dev/null +++ b/mpfr/tests/tswap.c @@ -0,0 +1,51 @@ +/* Test file for mpfr_swap. + +Copyright 2000-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (void) +{ + mpfr_t u, v; + + tests_start_mpfr (); + + mpfr_init2 (u, 24); + mpfr_init2 (v, 53); + mpfr_set_ui (u, 16777215, MPFR_RNDN); /* 2^24 - 1 */ + mpfr_set_str1 (v, "9007199254740991.0"); /* 2^53 - 1 */ + mpfr_swap (u, v); + mpfr_swap (u, v); + if (mpfr_cmp_ui (u, 16777215) || mpfr_cmp_str1 (v, "9007199254740991.0")) + { + printf ("Error in mpfr_swap\n"); + exit (1); + } + mpfr_clear (u); + mpfr_clear (v); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/ttan.c b/mpfr/tests/ttan.c new file mode 100644 index 0000000000..36426afa6a --- /dev/null +++ b/mpfr/tests/ttan.c @@ -0,0 +1,163 @@ +/* Test file for mpfr_tan. + +Copyright 2001-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_tan +#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */ +#include "tgeneric.c" + +static void +check_nans (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + mpfr_set_nan (x); + mpfr_tan (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: tan(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_tan (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: tan(Inf) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_tan (y, x, MPFR_RNDN); + if (! mpfr_nan_p (y)) + { + printf ("Error: tan(-Inf) != NaN\n"); + exit (1); + } + + /* exercise recomputation */ + mpfr_set_prec (x, 14); + mpfr_set_str_binary (x, "0.10100000101010E0"); + mpfr_set_prec (y, 24); + mpfr_tan (y, x, MPFR_RNDU); + mpfr_set_prec (x, 24); + mpfr_set_str_binary (x, "101110011011001100100001E-24"); + MPFR_ASSERTN(mpfr_cmp (x, y) == 0); + + /* Compute ~Pi/2 to check overflow */ + mpfr_set_prec (x, 20000); + mpfr_const_pi (x, MPFR_RNDD); + mpfr_div_2ui (x, x, 1, MPFR_RNDN); + mpfr_set_prec (y, 24); + mpfr_tan (y, x, MPFR_RNDN); + if (mpfr_cmp_str (y, "0.100011101101011000100011E20001", 2, MPFR_RNDN)) + { + printf("Error computing tan(~Pi/2)\n"); + mpfr_dump (y); + exit (1); + } + + /* bug found by Kaveh Ghazi on 13 Jul 2007 */ + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_str_binary (x, "0.10011100110111000001000010110100101000000000000000000E34"); + mpfr_tan (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.1000010011001010001000010100000110100111000011010101E41"); + MPFR_ASSERTN(mpfr_cmp (x, y) == 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + unsigned int i; + unsigned int prec[10] = {14, 15, 19, 22, 23, 24, 25, 40, 41, 52}; + unsigned int prec2[10] = {4, 5, 6, 19, 70, 95, 100, 106, 107, 108}; + + tests_start_mpfr (); + + check_nans (); + + mpfr_init (x); + + mpfr_set_prec (x, 2); + mpfr_set_str (x, "0.5", 10, MPFR_RNDN); + mpfr_tan (x, x, MPFR_RNDD); + if (mpfr_cmp_ui_2exp(x, 1, -1)) + { + printf ("mpfr_tan(0.5, MPFR_RNDD) failed\n" + "expected 0.5, got"); + mpfr_print_binary(x); + putchar('\n'); + exit (1); + } + + /* check that tan(3*Pi/4) ~ -1 */ + for (i=0; i<10; i++) + { + mpfr_set_prec (x, prec[i]); + mpfr_const_pi (x, MPFR_RNDN); + mpfr_mul_ui (x, x, 3, MPFR_RNDN); + mpfr_div_ui (x, x, 4, MPFR_RNDN); + mpfr_tan (x, x, MPFR_RNDN); + if (mpfr_cmp_si (x, -1)) + { + printf ("tan(3*Pi/4) fails for prec=%u\n", prec[i]); + exit (1); + } + } + + /* check that tan(7*Pi/4) ~ -1 */ + for (i=0; i<10; i++) + { + mpfr_set_prec (x, prec2[i]); + mpfr_const_pi (x, MPFR_RNDN); + mpfr_mul_ui (x, x, 7, MPFR_RNDN); + mpfr_div_ui (x, x, 4, MPFR_RNDN); + mpfr_tan (x, x, MPFR_RNDN); + if (mpfr_cmp_si (x, -1)) + { + printf ("tan(3*Pi/4) fails for prec=%u\n", prec2[i]); + exit (1); + } + } + + mpfr_clear (x); + + test_generic (2, 100, 10); + + data_check ("data/tan", mpfr_tan, "mpfr_tan"); + bad_cases (mpfr_tan, mpfr_atan, "mpfr_tan", 256, -256, 255, 4, 128, 800, 40); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/ttanh.c b/mpfr/tests/ttanh.c new file mode 100644 index 0000000000..c844624b5c --- /dev/null +++ b/mpfr/tests/ttanh.c @@ -0,0 +1,138 @@ +/* Test file for mpfr_tanh. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_tanh +#define TEST_RANDOM_EMIN -36 +#define TEST_RANDOM_EMAX 36 +#include "tgeneric.c" + +static void +special (void) +{ + mpfr_t x; + + mpfr_init (x); + + mpfr_set_nan (x); + mpfr_tanh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (x)); + + mpfr_set_inf (x, 1); + mpfr_tanh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0); + + mpfr_set_inf (x, -1); + mpfr_tanh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_si (x, -1) == 0); + + mpfr_set_prec (x, 10); + mpfr_set_str_binary (x, "-0.1001011001"); + mpfr_tanh (x, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_si_2exp (x, -135, -8) == 0); + + mpfr_clear (x); +} + +static void +special_overflow (void) +{ + mpfr_t x, y; + int i; + mpfr_exp_t emin, emax; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_clear_overflow (); + set_emin (-125); + set_emax (128); + mpfr_init2 (x, 24); + mpfr_init2 (y, 24); + + mpfr_set_str_binary (x, "0.101100100000000000110100E7"); + i = mpfr_tanh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1) || i != 1) + { + printf("Overflow error (1). i=%d\ny=", i); + mpfr_dump (y); + exit (1); + } + MPFR_ASSERTN (!mpfr_overflow_p ()); + + i = mpfr_tanh (y, x, MPFR_RNDZ); + if (mpfr_cmp_str (y, "0.111111111111111111111111E0", 2, MPFR_RNDN) + || i != -1) + { + printf("Overflow error (2).i=%d\ny=", i); + mpfr_dump (y); + exit (1); + } + MPFR_ASSERTN (!mpfr_overflow_p ()); + + set_emin (emin); + set_emax (emax); + + mpfr_set_str_binary (x, "0.1E1000000000"); + i = mpfr_tanh (y, x, MPFR_RNDN); + if (mpfr_cmp_ui (y, 1) || i != 1) + { + printf("Overflow error (3). i=%d\ny=", i); + mpfr_dump (y); + exit (1); + } + MPFR_ASSERTN (!mpfr_overflow_p ()); + mpfr_set_str_binary (x, "-0.1E1000000000"); + i = mpfr_tanh (y, x, MPFR_RNDU); + if (mpfr_cmp_str (y, "-0.111111111111111111111111E0", 2, MPFR_RNDN) + || i != 1) + { + printf("Overflow error (4). i=%d\ny=", i); + mpfr_dump (y); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special_overflow (); + special (); + + test_generic (2, 100, 100); + + data_check ("data/tanh", mpfr_tanh, "mpfr_tanh"); + bad_cases (mpfr_tanh, mpfr_atanh, "mpfr_tanh", 256, -128, 0, + 4, 128, 800, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/ttrunc.c b/mpfr/tests/ttrunc.c new file mode 100644 index 0000000000..780358c4b7 --- /dev/null +++ b/mpfr/tests/ttrunc.c @@ -0,0 +1,133 @@ +/* Test file for mpfr_trunc, mpfr_ceil, mpfr_floor. + +Copyright 1999-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define SIZEX 100 + +int +main (void) +{ + int j, k; + mpfr_t x, y, z, t, y2, z2, t2; + + tests_start_mpfr (); + + mpfr_inits2 (SIZEX, x, y, z, t, y2, z2, t2, (mpfr_ptr) 0); + + mpfr_set_str1 (x, "0.5"); + mpfr_ceil(y, x); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error in mpfr_ceil for x=0.5: expected 1.0, got "); + mpfr_print_binary(y); + putchar('\n'); + exit (1); + } + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_ceil(y, x); + if (mpfr_cmp_ui(y,0)) + { + printf ("Error in mpfr_ceil for x=0.0: expected 0.0, got "); + mpfr_print_binary(y); + putchar('\n'); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_ceil(y, x); + if (mpfr_cmp_ui(y,1)) + { + printf ("Error in mpfr_ceil for x=1.0: expected 1.0, got "); + mpfr_print_binary(y); + putchar('\n'); + exit (1); + } + + for (j=0;j<1000;j++) + { + mpfr_urandomb (x, RANDS); + MPFR_EXP (x) = 2; + + for (k = 2; k <= SIZEX; k++) + { + mpfr_set_prec(y, k); + mpfr_set_prec(y2, k); + mpfr_set_prec(z, k); + mpfr_set_prec(z2, k); + mpfr_set_prec(t, k); + mpfr_set_prec(t2, k); + + mpfr_floor(y, x); + mpfr_set(y2, x, MPFR_RNDD); + + mpfr_trunc(z, x); + mpfr_set(z2, x, MPFR_RNDZ); + + mpfr_ceil(t, x); + mpfr_set(t2, x, MPFR_RNDU); + + if (!mpfr_eq(y, y2, k)) + { + printf("Error in floor, x = "); mpfr_print_binary(x); + printf("\n"); + printf("floor(x) = "); mpfr_print_binary(y); + printf("\n"); + printf("round(x, RNDD) = "); mpfr_print_binary(y2); + printf("\n"); + exit(1); + } + + if (!mpfr_eq(z, z2, k)) + { + printf("Error in trunc, x = "); mpfr_print_binary(x); + printf("\n"); + printf("trunc(x) = "); mpfr_print_binary(z); + printf("\n"); + printf("round(x, RNDZ) = "); mpfr_print_binary(z2); + printf("\n"); + exit(1); + } + + if (!mpfr_eq(y, y2, k)) + { + printf("Error in ceil, x = "); mpfr_print_binary(x); + printf("\n"); + printf("ceil(x) = "); mpfr_print_binary(t); + printf("\n"); + printf("round(x, RNDU) = "); mpfr_print_binary(t2); + printf("\n"); + exit(1); + } + MPFR_EXP(x)++; + } + } + + mpfr_clears (x, y, z, t, y2, z2, t2, (mpfr_ptr) 0); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tui_div.c b/mpfr/tests/tui_div.c new file mode 100644 index 0000000000..1e69d9970c --- /dev/null +++ b/mpfr/tests/tui_div.c @@ -0,0 +1,257 @@ +/* Test file for mpfr_ui_div. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +/* checks that y/x gives the right result with 53 bits of precision */ +static void +check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, zz; + + mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_ui_div (zz, y, xx, rnd_mode); + if (mpfr_cmp_str1(zz, zs)) + { + printf ("expected quotient is %s, got ", zs); + mpfr_out_str (stdout, 10, 0, zz, MPFR_RNDN); + printf ("mpfr_ui_div failed for y=%lu x=%s with rnd_mode=%s\n", + y, xs, mpfr_print_rnd_mode (rnd_mode)); + exit (1); + } + mpfr_clears (xx, zz, (mpfr_ptr) 0); +} + +static void +check_inexact (void) +{ + mpfr_t x, y, z; + mpfr_prec_t px, py; + int inexact, cmp; + unsigned long int u; + int rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + for (px = 2; px < 300; px++) + { + mpfr_set_prec (x, px); + do + { + mpfr_urandomb (x, RANDS); + } + while (mpfr_cmp_ui (x, 0) == 0); + u = randlimb (); + for (py = 2; py < 300; py++) + { + mpfr_set_prec (y, py); + mpfr_set_prec (z, py + px); + for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) + { + inexact = mpfr_ui_div (y, u, x, (mpfr_rnd_t) rnd); + if (mpfr_mul (z, y, x, (mpfr_rnd_t) rnd)) + { + printf ("z <- y * x should be exact\n"); + exit (1); + } + cmp = mpfr_cmp_ui (z, u); + if (! SAME_SIGN (inexact, cmp)) + { + printf ("Wrong inexact flag for u=%lu, rnd=%s\n", + u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x = "); mpfr_dump (x); + printf ("y = "); mpfr_dump (y); + printf ("y*x = "); mpfr_dump (z); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +static void +check_special (void) +{ + mpfr_t d, q; + + mpfr_init2 (d, 100L); + mpfr_init2 (q, 100L); + + /* 1/+inf == 0 */ + MPFR_SET_INF (d); + MPFR_SET_POS (d); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* 1/-inf == -0 */ + MPFR_SET_INF (d); + MPFR_SET_NEG (d); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_number_p (q)); + MPFR_ASSERTN (mpfr_sgn (q) == 0); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* 1/nan == nan */ + MPFR_SET_NAN (d); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_nan_p (q)); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + /* 0/0 == nan */ + mpfr_set_ui (d, 0L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_nan_p (q)); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN); + + /* 1/+0 = +inf */ + mpfr_set_ui (d, 0L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + /* 1/-0 = -inf */ + mpfr_set_ui (d, 0L, MPFR_RNDN); + mpfr_neg (d, d, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0); + MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0); + + /* 0/1 = +0 */ + mpfr_set_ui (d, 1L, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_POS (q)); + MPFR_ASSERTN (__gmpfr_flags == 0); + + /* 0/-1 = -0 */ + mpfr_set_si (d, -1, MPFR_RNDN); + mpfr_clear_flags (); + MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */ + MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_NEG (q)); + MPFR_ASSERTN (__gmpfr_flags == 0); + + mpfr_clear (d); + mpfr_clear (q); +} + +static int +mpfr_inv (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r) +{ + return mpfr_ui_div (y, 1, x, r); +} + +static void +check_overflow (void) +{ + mpfr_exp_t emin, emax; + mpfr_t x, y1, y2; + int inex1, inex2, rnd_mode; + unsigned int flags1, flags2; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + mpfr_inits2 (32, x, y1, y2, (mpfr_ptr) 0); + mpfr_setmin (x, MPFR_EMIN_MIN); + RND_LOOP (rnd_mode) + { + inex1 = mpfr_overflow (y1, (mpfr_rnd_t) rnd_mode, 1); + flags1 = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; + mpfr_clear_flags (); + inex2 = mpfr_ui_div (y2, 1, x, (mpfr_rnd_t) rnd_mode); + flags2 = __gmpfr_flags; + if (!(mpfr_equal_p (y1, y2) && + SAME_SIGN (inex1, inex2) && + flags1 == flags2)) + { + printf ("Error in check_overflow for %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd_mode)); + printf ("Expected "); + mpfr_dump (y1); + printf (" with inex = %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (y2); + printf (" with inex = %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +#define TEST_FUNCTION mpfr_ui_div +#define ULONG_ARG1 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_special (); + check_inexact (); + check(948002822, "1.22191250737771397120e+20", MPFR_RNDN, + "7.758352715731357946e-12"); + check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ, + "1.5772563211925444801e-223"); + check(740454110, "2.11496253355831863313e+183", MPFR_RNDZ, + "3.5010270784996976041e-175"); + check(1690540942, "1.28278599852446657468e-276", MPFR_RNDU, + "1.3178666932321966062e285"); + check(1476599377, "-2.14191393656148625995e+305", MPFR_RNDD, + "-6.8938315017943889615e-297"); + check_overflow (); + + test_generic (2, 1000, 100); + + /* inv is for 1/x */ + data_check ("data/inv", mpfr_inv, "mpfr_ui_div(1,x)"); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tui_pow.c b/mpfr/tests/tui_pow.c new file mode 100644 index 0000000000..99fc780157 --- /dev/null +++ b/mpfr/tests/tui_pow.c @@ -0,0 +1,262 @@ +/* Test file for mpfr_ui_pow and mpfr_ui_pow_ui. + +Copyright 2001-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "mpfr-test.h" + +static void +test1 (void) +{ + mpfr_t x, y, z, a; + int res1, res2; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 65); + mpfr_init2 (z, 17); + mpfr_init2 (a, 17); + + mpfr_set_str_binary (x, "-0.101110001001011011011e-9"); + mpfr_ui_pow (y, 7, x, MPFR_RNDN); + + mpfr_set_prec (x, 40); + mpfr_set_str_binary (x, "-0.1100101100101111011001010010110011110110E-1"); + mpfr_set_prec (y, 74); + mpfr_ui_pow (y, 8, x, MPFR_RNDN); + mpfr_set_prec (x, 74); + mpfr_set_str_binary (x, "0.11100000010100111101000011111011011010011000011000101011010011010101000011E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error for input of 40 bits, output of 74 bits\n"); + exit (1); + } + + /* Check for ui_pow_ui */ + mpfr_ui_pow_ui (x, 0, 1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x)); + mpfr_ui_pow_ui (x, 0, 4, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x)); + res1 = mpfr_ui_pow_ui (z, 17, 42, MPFR_RNDD); + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_set_ui (y, 42, MPFR_RNDN); + res2 = mpfr_pow (a, x, y, MPFR_RNDD); + if (mpfr_cmp (z, a) || res1 != res2) + { + printf ("Error for ui_pow_ui for 17^42\n" + "Inexact1 = %d Inexact2 = %d\n", res1, res2); + mpfr_dump (z); + mpfr_dump (a); + exit (1); + } + mpfr_set_prec (x, 2); + mpfr_ui_pow_ui (x, 65537, 65535, MPFR_RNDN); + if (mpfr_cmp_str (x, "0.11E1048562", 2, MPFR_RNDN) != 0) + { + printf ("Error for ui_pow_ui for 65537 ^65535 with 2 bits of precision\n"); + mpfr_dump (x); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (a); +} + +static void +check1 (mpfr_ptr x, mpfr_prec_t prec, unsigned long nt, mpfr_rnd_t rnd) +{ + mpfr_t y, z, t; + int inexact, compare, compare2; + mpfr_prec_t yprec; + mpfr_exp_t err; + + yprec = prec + 10; + + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + mpfr_set_prec (y, yprec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + + compare = mpfr_ui_pow (y, nt, x, rnd); + err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = mpfr_ui_pow (z, nt, x, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf (" n=%lu", nt); + printf (" prec=%u rnd_mode=%s\n", (unsigned) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + puts (""); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf ("approx "); + mpfr_print_binary (y); + puts (""); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if ((rnd != MPFR_RNDN) && (compare * compare2 >= 0)) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x="); mpfr_print_binary (x); puts (""); + printf ("y="); mpfr_print_binary (y); puts (""); + printf ("t="); mpfr_print_binary (t); puts (""); + exit (1); + } + } + + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + unsigned long int n; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + n = randlimb (); + + MPFR_SET_INF(x); + mpfr_ui_pow (y, n, x, MPFR_RNDN); + if(!MPFR_IS_INF(y)) + { + printf ("evaluation of function in INF does not return INF\n"); + exit (1); + } + + MPFR_CHANGE_SIGN(x); + mpfr_ui_pow (y, n, x, MPFR_RNDN); + if(!MPFR_IS_ZERO(y)) + { + printf ("evaluation of function in -INF does not return 0"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_ui_pow (y, n, x, MPFR_RNDN); + if(!MPFR_IS_NAN(y)) + { + printf ("evaluation of function in NAN does not return NAN"); + exit (1); + } + + test1 (); + + { + mpfr_t z, t; + mpfr_prec_t prec; + mpfr_rnd_t rnd; + unsigned int n; + + mpfr_prec_t p0=2, p1=100; + unsigned int N=20; + + mpfr_init2 (z, 38); + mpfr_init2 (t, 6); + + /* check exact power */ + mpfr_set_str_binary (t, "0.110000E5"); + mpfr_ui_pow (z, 3, t, MPFR_RNDN); + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_str (x, "-0.5", 10, MPFR_RNDZ); + mpfr_ui_pow (y, 4, x, MPFR_RNDD); + if (mpfr_cmp_ui_2exp(y, 1, -1)) + { + fprintf (stderr, "Error for 4^(-0.5), prec=2, MPFR_RNDD\n"); + fprintf (stderr, "expected 0.5, got "); + mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + /* problem found by Kevin on spe175.testdrive.compaq.com + (03 Sep 2003), ia64 under HP-UX */ + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 2); + mpfr_set_str (x, "0.5", 10, MPFR_RNDN); + mpfr_ui_pow (y, 398441521, x, MPFR_RNDN); + if (mpfr_cmp_ui_2exp(y, 1, 14)) + { + fprintf (stderr, "Error for 398441521^(0.5), prec=2, MPFR_RNDN\n"); + fprintf (stderr, "expected 1.0e14, got "); + mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + mpfr_clear (z); + mpfr_clear (t); + + mpfr_set_prec (x, 2); + mpfr_set_str (x, "0.5", 10, MPFR_RNDN); + check1 (x, 2, 398441521, MPFR_RNDN); /* 398441521 = 19961^2 */ + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + for (n=0; n<N; n++) + { + int nt; + nt = randlimb () & INT_MAX; + mpfr_urandomb (x, RANDS); + rnd = RND_RAND (); + check1 (x, prec, nt, rnd); + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tui_sub.c b/mpfr/tests/tui_sub.c new file mode 100644 index 0000000000..b5649ccd6a --- /dev/null +++ b/mpfr/tests/tui_sub.c @@ -0,0 +1,362 @@ +/* Test file for mpfr_ui_sub. + +Copyright 2000-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <float.h> + +#include "mpfr-test.h" + +static void +special (void) +{ + mpfr_t x, y, res; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (res); + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_binary (y, "0.111100110001011010111"); + inexact = mpfr_ui_sub (x, 1, y, MPFR_RNDN); + if (inexact) + { + printf ("Wrong inexact flag: got %d, expected 0\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_binary (y, "0.111100110001011010111"); + if ((inexact = mpfr_ui_sub (x, 38181761, y, MPFR_RNDN)) >= 0) + { + printf ("Wrong inexact flag: got %d, expected -1\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 63); + mpfr_set_prec (y, 63); + mpfr_set_str_binary (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1"); + if ((inexact = mpfr_ui_sub (x, 1541116494, y, MPFR_RNDN)) <= 0) + { + printf ("Wrong inexact flag: got %d, expected +1\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (y, "0.11011000110111010001011100011100E-1"); + if ((inexact = mpfr_ui_sub (x, 2000375416, y, MPFR_RNDN)) >= 0) + { + printf ("Wrong inexact flag: got %d, expected -1\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_binary (y, "0.110011011001010011110111E-2"); + if ((inexact = mpfr_ui_sub (x, 927694848, y, MPFR_RNDN)) <= 0) + { + printf ("Wrong inexact flag: got %d, expected +1\n", inexact); + exit (1); + } + + /* bug found by Mathieu Dutour, 12 Apr 2001 */ + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_prec (res, 5); + mpfr_set_str_binary (x, "1e-12"); + + mpfr_ui_sub (y, 1, x, MPFR_RNDD); + mpfr_set_str_binary (res, "0.11111"); + if (mpfr_cmp (y, res)) + { + printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDD) for x=2^(-12)\nexpected 1.1111e-1, got "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_ui_sub (y, 1, x, MPFR_RNDU); + mpfr_set_str_binary (res, "1.0"); + if (mpfr_cmp (y, res)) + { + printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDU) for x=2^(-12)\n" + "expected 1.0, got "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_ui_sub (y, 1, x, MPFR_RNDN); + mpfr_set_str_binary (res, "1.0"); + if (mpfr_cmp (y, res)) + { + printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDN) for x=2^(-12)\n" + "expected 1.0, got "); + mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 10); + mpfr_set_prec (y, 10); + mpfr_urandomb (x, RANDS); + mpfr_ui_sub (y, 0, x, MPFR_RNDN); + if (MPFR_IS_ZERO(x)) + MPFR_ASSERTN(MPFR_IS_ZERO(y)); + else + MPFR_ASSERTN(mpfr_cmpabs (x, y) == 0 && mpfr_sgn (x) != mpfr_sgn (y)); + + mpfr_set_prec (x, 73); + mpfr_set_str_binary (x, "0.1101111010101011011011100011010000000101110001011111001011011000101111101E-99"); + mpfr_ui_sub (x, 1, x, MPFR_RNDZ); + mpfr_nextabove (x); + MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (res); +} + +/* checks that (y-x) gives the right results with 53 bits of precision */ +static void +check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, zz; + + mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_ui_sub (zz, y, xx, rnd_mode); + if (mpfr_cmp_str1 (zz, zs) ) + { + printf ("expected difference is %s, got\n",zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + printf ("mpfr_ui_sub failed for y=%lu x=%s with rnd_mode=%s\n", + y, xs, mpfr_print_rnd_mode (rnd_mode)); + exit (1); + } + mpfr_clears (xx, zz, (mpfr_ptr) 0); +} + +/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */ +static void +check_two_sum (mpfr_prec_t p) +{ + unsigned int x; + mpfr_t y, u, v, w; + mpfr_rnd_t rnd; + int inexact, cmp; + + mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0); + do + { + x = randlimb (); + } + while (x < 1); + mpfr_urandomb (y, RANDS); + rnd = MPFR_RNDN; + inexact = mpfr_ui_sub (u, x, y, rnd); + mpfr_sub_ui (v, u, x, rnd); + mpfr_add (w, v, y, rnd); + cmp = mpfr_cmp_ui (w, 0); + /* as u = (x-y) + w, we should have inexact and w of same sign */ + if (! SAME_SIGN (inexact, cmp)) + { + printf ("Wrong inexact flag for prec=%u, rnd=%s\n", + (unsigned int) p, mpfr_print_rnd_mode (rnd)); + printf ("x = %u\n", x); + printf ("y = "); mpfr_dump (y); + printf ("u = "); mpfr_dump (u); + printf ("v = "); mpfr_dump (v); + printf ("w = "); mpfr_dump (w); + printf ("inexact = %d\n", inexact); + exit (1); + } + mpfr_clears (y, u, v, w, (mpfr_ptr) 0); +} + +static void +check_nans (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + + /* 1 - nan == nan */ + mpfr_set_nan (x); + mpfr_ui_sub (y, 1L, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* 1 - +inf == -inf */ + mpfr_set_inf (x, 1); + mpfr_ui_sub (y, 1L, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) < 0); + + /* 1 - -inf == +inf */ + mpfr_set_inf (x, -1); + mpfr_ui_sub (y, 1L, x, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (y)); + MPFR_ASSERTN (mpfr_sgn (y) > 0); + + mpfr_clear (x); + mpfr_clear (y); +} + +/* Check mpfr_ui_sub with u = 0 (unsigned). */ +static void check_neg (void) +{ + mpfr_t x, yneg, ysub; + int i, s; + int r; + + mpfr_init2 (x, 64); + mpfr_init2 (yneg, 32); + mpfr_init2 (ysub, 32); + + for (i = 0; i <= 25; i++) + { + mpfr_sqrt_ui (x, i, MPFR_RNDN); + for (s = 0; s <= 1; s++) + { + RND_LOOP (r) + { + int tneg, tsub; + + tneg = mpfr_neg (yneg, x, (mpfr_rnd_t) r); + tsub = mpfr_ui_sub (ysub, 0, x, (mpfr_rnd_t) r); + MPFR_ASSERTN (mpfr_equal_p (yneg, ysub)); + MPFR_ASSERTN (!(MPFR_IS_POS (yneg) ^ MPFR_IS_POS (ysub))); + MPFR_ASSERTN (tneg == tsub); + } + mpfr_neg (x, x, MPFR_RNDN); + } + } + + mpfr_clear (x); + mpfr_clear (yneg); + mpfr_clear (ysub); +} + +static void +check_overflow (void) +{ + mpfr_exp_t emin, emax; + mpfr_t x, y1, y2; + int inex1, inex2, rnd_mode; + unsigned int flags1, flags2; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + + mpfr_inits2 (32, x, y1, y2, (mpfr_ptr) 0); + mpfr_setmax (x, MPFR_EMAX_MAX); + mpfr_neg (x, x, MPFR_RNDN); + RND_LOOP (rnd_mode) + { + if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA) + { + inex1 = mpfr_overflow (y1, (mpfr_rnd_t) rnd_mode, 1); + flags1 = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; + } + else + { + mpfr_neg (y1, x, MPFR_RNDN); + inex1 = -1; + flags1 = MPFR_FLAGS_INEXACT; + } + mpfr_clear_flags (); + inex2 = mpfr_ui_sub (y2, 1, x, (mpfr_rnd_t) rnd_mode); + flags2 = __gmpfr_flags; + if (!(mpfr_equal_p (y1, y2) && + SAME_SIGN (inex1, inex2) && + flags1 == flags2)) + { + printf ("Error in check_overflow for %s\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd_mode)); + printf ("Expected "); + mpfr_dump (y1); + printf (" with inex = %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (y2); + printf (" with inex = %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + mpfr_clears (x, y1, y2, (mpfr_ptr) 0); + + set_emin (emin); + set_emax (emax); +} + +#define TEST_FUNCTION mpfr_ui_sub +#define ULONG_ARG1 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_prec_t p; + unsigned k; + + tests_start_mpfr (); + + check_nans (); + + special (); + for (p=2; p<100; p++) + for (k=0; k<100; k++) + check_two_sum (p); + + check(1196426492, "1.4218093058435347e-3", MPFR_RNDN, + "1.1964264919985781e9"); + check(1092583421, "-1.0880649218158844e9", MPFR_RNDN, + "2.1806483428158845901e9"); + check(948002822, "1.22191250737771397120e+20", MPFR_RNDN, + "-1.2219125073682338611e20"); + check(832100416, "4.68311314939691330000e-215", MPFR_RNDD, + "8.3210041599999988079e8"); + check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ, + "-1.2529639586454686577e232"); + check(2128997392, "-1.08496826129284207724e+187", MPFR_RNDU, + "1.0849682612928422704e187"); + check(293607738, "-1.9967571564050541e-5", MPFR_RNDU, + "2.9360773800002003e8"); + check(354270183, "2.9469161763489528e3", MPFR_RNDN, + "3.5426723608382362e8"); + check_overflow (); + + check_neg (); + + test_generic (2, 1000, 100); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/turandom.c b/mpfr/tests/turandom.c new file mode 100644 index 0000000000..fc875120d8 --- /dev/null +++ b/mpfr/tests/turandom.c @@ -0,0 +1,249 @@ +/* Test file for mpfr_urandom + +Copyright 1999-2004, 2006-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +test_urandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd, long bit_index, + int verbose) +{ + mpfr_t x; + int *tab, size_tab, k, sh, xn; + double d, av = 0, var = 0, chi2 = 0, th; + mpfr_exp_t emin; + mp_size_t limb_index = 0; + mp_limb_t limb_mask = 0; + long count = 0; + int i; + int inex = 1; + + size_tab = (nbtests >= 1000 ? nbtests / 50 : 20); + tab = (int *) calloc (size_tab, sizeof(int)); + if (tab == NULL) + { + fprintf (stderr, "trandom: can't allocate memory in test_urandom\n"); + exit (1); + } + + mpfr_init2 (x, prec); + xn = 1 + (prec - 1) / mp_bits_per_limb; + sh = xn * mp_bits_per_limb - prec; + if (bit_index >= 0 && bit_index < prec) + { + /* compute the limb index and limb mask to fetch the bit #bit_index */ + limb_index = (prec - bit_index) / mp_bits_per_limb; + i = 1 + bit_index - (bit_index / mp_bits_per_limb) * mp_bits_per_limb; + limb_mask = MPFR_LIMB_ONE << (mp_bits_per_limb - i); + } + + for (k = 0; k < nbtests; k++) + { + i = mpfr_urandom (x, RANDS, rnd); + inex = (i != 0) && inex; + /* check that lower bits are zero */ + if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh) && !MPFR_IS_ZERO (x)) + { + printf ("Error: mpfr_urandom() returns invalid numbers:\n"); + mpfr_print_binary (x); puts (""); + exit (1); + } + /* check that the value is in [0,1] */ + if (mpfr_cmp_ui (x, 0) < 0 || mpfr_cmp_ui (x, 1) > 0) + { + printf ("Error: mpfr_urandom() returns number outside [0, 1]:\n"); + mpfr_print_binary (x); puts (""); + exit (1); + } + + d = mpfr_get_d1 (x); av += d; var += d*d; + i = (int)(size_tab * d); + if (d == 1.0) i --; + tab[i]++; + + if (limb_mask && (MPFR_MANT (x)[limb_index] & limb_mask)) + count ++; + } + + if (inex == 0) + { + /* one call in the loop pretended to return an exact number! */ + printf ("Error: mpfr_urandom() returns a zero ternary value.\n"); + exit (1); + } + + /* coverage test */ + emin = mpfr_get_emin (); + for (k = 0; k < 5; k++) + { + set_emin (k+1); + inex = mpfr_urandom (x, RANDS, rnd); + if (( (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) + && (!MPFR_IS_ZERO (x) || inex != -1)) + || ((rnd == MPFR_RNDU || rnd == MPFR_RNDA) + && (mpfr_cmp_ui (x, 1 << k) != 0 || inex != +1)) + || (rnd == MPFR_RNDN + && (k > 0 || mpfr_cmp_ui (x, 1 << k) != 0 || inex != +1) + && (!MPFR_IS_ZERO (x) || inex != -1))) + { + printf ("Error: mpfr_urandom() do not handle correctly a restricted" + " exponent range.\nrounding mode: %s\nternary value: %d\n" + "random value: ", mpfr_print_rnd_mode (rnd), inex); + mpfr_print_binary (x); puts (""); + exit (1); + } + } + set_emin (emin); + + mpfr_clear (x); + if (!verbose) + { + free(tab); + return; + } + + av /= nbtests; + var = (var / nbtests) - av * av; + + th = (double)nbtests / size_tab; + printf ("Average = %.5f\nVariance = %.5f\n", av, var); + printf ("Repartition for urandom with rounding mode %s. " + "Each integer should be close to %d.\n", + mpfr_print_rnd_mode (rnd), (int)th); + + for (k = 0; k < size_tab; k++) + { + chi2 += (tab[k] - th) * (tab[k] - th) / th; + printf("%d ", tab[k]); + if (((k+1) & 7) == 0) + printf("\n"); + } + + printf("\nChi2 statistics value (with %d degrees of freedom) : %.5f\n", + size_tab - 1, chi2); + + if (limb_mask) + printf ("Bit #%ld is set %ld/%ld = %.1f %% of time\n", + bit_index, count, nbtests, count * 100.0 / nbtests); + + puts (""); + + free(tab); + return; +} + +/* problem reported by Carl Witty */ +static void +bug20100914 (void) +{ + mpfr_t x; + gmp_randstate_t s; + +#if __MPFR_GMP(4,2,0) +# define C1 "0.8488312" +# define C2 "0.8156509" +#else +# define C1 "0.6485367" +# define C2 "0.9362717" +#endif + + gmp_randinit_default (s); + gmp_randseed_ui (s, 42); + mpfr_init2 (x, 17); + mpfr_urandom (x, s, MPFR_RNDN); + if (mpfr_cmp_str1 (x, C1) != 0) + { + printf ("Error in bug20100914, expected " C1 ", got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_urandom (x, s, MPFR_RNDN); + if (mpfr_cmp_str1 (x, C2) != 0) + { + printf ("Error in bug20100914, expected " C2 ", got "); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + mpfr_clear (x); + gmp_randclear (s); +} + +int +main (int argc, char *argv[]) +{ + long nbtests; + mpfr_prec_t prec; + int verbose = 0; + int rnd; + long bit_index; + + tests_start_mpfr (); + + if (argc > 1) + verbose = 1; + + nbtests = 10000; + if (argc > 1) + { + long a = atol(argv[1]); + if (a != 0) + nbtests = a; + } + + if (argc <= 2) + prec = 1000; + else + prec = atol(argv[2]); + + if (argc <= 3) + bit_index = -1; + else + { + bit_index = atol(argv[3]); + if (bit_index >= prec) + { + printf ("Warning. Cannot compute the bit frequency: the given bit " + "index (= %ld) is not less than the precision (= %ld).\n", + bit_index, (long) prec); + bit_index = -1; + } + } + + RND_LOOP(rnd) + { + test_urandom (nbtests, prec, (mpfr_rnd_t) rnd, bit_index, verbose); + + if (argc == 1) /* check also small precision */ + { + test_urandom (nbtests, 2, (mpfr_rnd_t) rnd, -1, 0); + } + } + + bug20100914 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tvalist.c b/mpfr/tests/tvalist.c new file mode 100644 index 0000000000..b45f8f88b3 --- /dev/null +++ b/mpfr/tests/tvalist.c @@ -0,0 +1,80 @@ +/* Test file for multiple mpfr.h inclusion and va_list related functions + +Copyright 2011-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if HAVE_STDARG + +#if _MPFR_EXP_FORMAT == 4 +/* If mpfr_exp_t is defined as intmax_t, intmax_t must be defined before + the inclusion of mpfr.h (this test doesn't use mpfr-impl.h). */ +# include <stdint.h> +#endif + +/* Assume that this is in fact a header inclusion for some library + that uses MPFR, i.e. this inclusion is hidden in another one. + MPFR currently (rev 6704) fails to handle this case. */ +#include <mpfr.h> + +#include <stdarg.h> +#define MPFR_USE_VA_LIST /* necessary due to GMP bug concerning inclusions */ +#include <mpfr.h> + +#include <stdio.h> +#define MPFR_USE_FILE /* necessary due to GMP bug concerning inclusions */ +#include <mpfr.h> + +#include "mpfr-test.h" + +static void +test (FILE *fout, const char *fmt, ...) +{ + int (*fct) (FILE*, __gmp_const char*, va_list); + + fct = mpfr_vfprintf; + if (0) + { + va_list ap; + va_start (ap, fmt); + fct (fout, fmt, ap); + va_end (ap); + } +} + +int +main (void) +{ + tests_start_mpfr (); + test (stdout, "%d\n", 0); + tests_end_mpfr (); + return 0; +} + +#else /* HAVE_STDARG */ + +/* The test is disabled. */ + +int +main (void) +{ + return 77; +} + +#endif /* HAVE_STDARG */ diff --git a/mpfr/tests/tversion.c b/mpfr/tests/tversion.c new file mode 100644 index 0000000000..c84ac88038 --- /dev/null +++ b/mpfr/tests/tversion.c @@ -0,0 +1,176 @@ +/* Test file for mpfr_version. + +Copyright 2004-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> + +#include "mpfr-intmax.h" +#include "mpfr-test.h" + +int +main (void) +{ + int err = 0; + + /* Test the GMP and MPFR versions. */ + if (test_version ()) + exit (1); + + printf ("[tversion] MPFR %s\n", MPFR_VERSION_STRING); + + /* TODO: We may want to output info for non-GNUC-compat compilers too. See: + * http://sourceforge.net/p/predef/wiki/Compilers/ + * http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros + * + * For ICC, do not check the __ICC macro as it is obsolete and not always + * defined. + */ +#define COMP "[tversion] Compiler: " +#ifdef __INTEL_COMPILER +# ifdef __VERSION__ +# define ICCV " [" __VERSION__ "]" +# else +# define ICCV "" +# endif + printf (COMP "ICC %d.%d.%d" ICCV "\n", __INTEL_COMPILER / 100, + __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE); +#elif (defined(__GNUC__) || defined(__clang__)) && defined(__VERSION__) +# ifdef __clang__ +# define COMP2 COMP +# else +# define COMP2 COMP "GCC " +# endif + printf (COMP2 "%s\n", __VERSION__); +#endif + +#ifdef __MPIR_VERSION + printf ("[tversion] MPIR: header %d.%d.%d, library %s\n", + __MPIR_VERSION, __MPIR_VERSION_MINOR, __MPIR_VERSION_PATCHLEVEL, + mpir_version); +#else + printf ("[tversion] GMP: header %d.%d.%d, library %s\n", + __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL, + gmp_version); +#endif + + if ( +#ifdef MPFR_USE_THREAD_SAFE + ! +#endif + mpfr_buildopt_tls_p ()) + { + printf ("ERROR! mpfr_buildopt_tls_p() and macros" + " do not match!\n"); + err = 1; + } + + if ( +#ifdef MPFR_WANT_DECIMAL_FLOATS + ! +#endif + mpfr_buildopt_decimal_p ()) + { + printf ("ERROR! mpfr_buildopt_decimal_p() and macros" + " do not match!\n"); + err = 1; + } + + if ( +#if defined(MPFR_HAVE_GMP_IMPL) || defined(WANT_GMP_INTERNALS) + ! +#endif + mpfr_buildopt_gmpinternals_p ()) + { + printf ("ERROR! mpfr_buildopt_gmpinternals_p() and macros" + " do not match!\n"); + err = 1; + } + + printf ("[tversion] TLS = %s, decimal = %s, GMP internals = %s\n", + mpfr_buildopt_tls_p () ? "yes" : "no", + mpfr_buildopt_decimal_p () ? "yes" : "no", + mpfr_buildopt_gmpinternals_p () ? "yes" : "no"); + + printf ("[tversion] intmax_t = " +#if defined(_MPFR_H_HAVE_INTMAX_T) + "yes" +#else + "no" +#endif + ", printf = " +#if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP) + "yes" +#else + "no" +#endif + "\n"); + + printf ("[tversion] gmp_printf: hhd = " +#if defined(NPRINTF_HH) + "no" +#else + "yes" +#endif + ", lld = " +#if defined(NPRINTF_LL) + "no" +#else + "yes" +#endif + ", jd = " +#if defined(NPRINTF_J) + "no" +#else + "yes" +#endif + ", td = " +#if defined(NPRINTF_T) + "no" +#else + "yes" +#endif + ", Ld = " +#if defined(NPRINTF_L) + "no" +#else + "yes" +#endif + "\n"); + + if (strcmp (mpfr_buildopt_tune_case (), MPFR_TUNE_CASE) != 0) + { + printf ("ERROR! mpfr_buildopt_tune_case() and MPFR_TUNE_CASE" + " do not match!\n %s\n %s\n", + mpfr_buildopt_tune_case (), MPFR_TUNE_CASE); + err = 1; + } + else + printf ("[tversion] MPFR tuning parameters from %s\n", MPFR_TUNE_CASE); + + if (strcmp (mpfr_get_patches (), "") != 0) + printf ("[tversion] MPFR patches: %s\n", mpfr_get_patches ()); + + return err; +} diff --git a/mpfr/tests/ty0.c b/mpfr/tests/ty0.c new file mode 100644 index 0000000000..b4b8190745 --- /dev/null +++ b/mpfr/tests/ty0.c @@ -0,0 +1,98 @@ +/* ty0 -- test file for the Bessel function of second kind (order 0) + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_y0 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + /* special values */ + mpfr_set_nan (x); + mpfr_y0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_y0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_inf (x, -1); /* -Inf */ + mpfr_y0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ + mpfr_y0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(+0)=-Inf */ + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_y0 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(-0)=-Inf */ + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_y0 (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.00010110100110000000001000100110111100110101100011011111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_y0 for x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_y0 (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error in mpfr_y0 for x=-1, rnd=MPFR_RNDN\n"); + printf ("Expected NaN\n"); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + + test_generic (2, 100, 1); + + data_check ("data/y0", mpfr_y0, "mpfr_y0"); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/ty1.c b/mpfr/tests/ty1.c new file mode 100644 index 0000000000..b36cb6126b --- /dev/null +++ b/mpfr/tests/ty1.c @@ -0,0 +1,98 @@ +/* ty1 -- test file for the Bessel function of second kind (order 1) + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_y1 +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + /* special values */ + mpfr_set_nan (x); + mpfr_y1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_y1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_inf (x, -1); /* -Inf */ + mpfr_y1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ + mpfr_y1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y1(+0)=-Inf */ + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_y1 (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y1(-0)=-Inf */ + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_y1 (y, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.110001111111110110010000001111101011001101011100101"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_y1 for x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_si (x, -1, MPFR_RNDN); + mpfr_y1 (y, x, MPFR_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error in mpfr_y1 for x=-1, rnd=MPFR_RNDN\n"); + printf ("Expected NaN\n"); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + + test_generic (2, 100, 1); + + data_check ("data/y1", mpfr_y1, "mpfr_y1"); + + tests_end_mpfr (); + + return 0; +} diff --git a/mpfr/tests/tyn.c b/mpfr/tests/tyn.c new file mode 100644 index 0000000000..92c97ced50 --- /dev/null +++ b/mpfr/tests/tyn.c @@ -0,0 +1,192 @@ +/* tyn -- test file for the Bessel function of second kind + +Copyright 2007-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + long n; + mpfr_prec_t prec = 53; + + tests_start_mpfr (); + + mpfr_init (x); + mpfr_init (y); + + if (argc != 1) + { + if (argc != 4) + { + printf ("Usage: tyn n x prec\n"); + exit (1); + } + n = atoi (argv[1]); + prec = atoi (argv[3]); + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_str (x, argv[2], 10, MPFR_RNDN); + mpfr_yn (y, n, x, MPFR_RNDN); + printf ("Y(%ld,", n); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf (")="); + mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); + printf ("\n"); + goto end; + } + + /* special values */ + mpfr_set_nan (x); + mpfr_yn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); /* +Inf */ + mpfr_yn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); + + mpfr_set_inf (x, -1); /* -Inf */ + mpfr_yn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */ + mpfr_yn (y, 0, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(+0)=-Inf */ + mpfr_yn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y17(+0)=-Inf */ + mpfr_yn (y, -17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_POS (y)); /* y(-17,+0)=+Inf */ + mpfr_yn (y, -42, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y(-42,+0)=-Inf */ + + mpfr_set_ui (x, 0, MPFR_RNDN); + mpfr_neg (x, x, MPFR_RNDN); /* -0 */ + mpfr_yn (y, 0, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(-0)=-Inf */ + mpfr_yn (y, 17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y17(-0)=-Inf */ + mpfr_yn (y, -17, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_POS (y)); /* y(-17,-0)=+Inf */ + mpfr_yn (y, -42, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y(-42,-0)=-Inf */ + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, 0, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.00010110100110000000001000100110111100110101100011011111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=0, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, 1, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.110001111111110110010000001111101011001101011100101"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=1, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, -1, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.110001111111110110010000001111101011001101011100101"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=-1, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, 2, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-1.101001101001001100100010101001000101101000010010001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=2, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, -2, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-1.101001101001001100100010101001000101101000010010001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=-2, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, 17, x, MPFR_RNDN); + mpfr_set_str_binary (x, "-0.11000100111000100010101101011000110011001101100001011E60"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=17, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_yn (y, -17, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.11000100111000100010101101011000110011001101100001011E60"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=-17, x=1, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_yn (y, 1, x, MPFR_RNDN); + mpfr_set_str_binary (x, "0.00101010110011011111001100000001101011011001111111"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_yn for n=1, x=17, rnd=MPFR_RNDN\n"); + printf ("Expected "); mpfr_dump (x); + printf ("Got "); mpfr_dump (y); + exit (1); + } + + end: + mpfr_clear (x); + mpfr_clear (y); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tzeta.c b/mpfr/tests/tzeta.c new file mode 100644 index 0000000000..9eb731fa32 --- /dev/null +++ b/mpfr/tests/tzeta.c @@ -0,0 +1,426 @@ +/* tzeta -- test file for the Riemann Zeta function + +Copyright 2003-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +static void +test1 (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 42); + + mpfr_set_str_binary (x, "1.1111111101000111011010010010100e-1"); + mpfr_zeta (y, x, MPFR_RNDN); /* shouldn't crash */ + + mpfr_set_prec (x, 40); + mpfr_set_prec (y, 50); + mpfr_set_str_binary (x, "1.001101001101000010011010110100110000101e-1"); + mpfr_zeta (y, x, MPFR_RNDU); + mpfr_set_prec (x, 50); + mpfr_set_str_binary (x, "-0.11111100011100111111101111100011110111001111111111E1"); + if (mpfr_cmp (x, y)) + { + printf ("Error for input on 40 bits, output on 50 bits\n"); + printf ("Expected "); mpfr_print_binary (x); puts (""); + printf ("Got "); mpfr_print_binary (y); puts (""); + mpfr_set_str_binary (x, "1.001101001101000010011010110100110000101e-1"); + mpfr_zeta (y, x, MPFR_RNDU); + mpfr_print_binary (x); puts (""); + mpfr_print_binary (y); puts (""); + exit (1); + } + + mpfr_set_prec (x, 2); + mpfr_set_prec (y, 55); + mpfr_set_str_binary (x, "0.11e3"); + mpfr_zeta (y, x, MPFR_RNDN); + mpfr_set_prec (x, 55); + mpfr_set_str_binary (x, "0.1000001000111000010011000010011000000100100100100010010E1"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_zeta (1)\n"); + printf ("Expected "); mpfr_print_binary (x); puts (""); + printf ("Got "); mpfr_print_binary (y); puts (""); + exit (1); + } + + mpfr_set_prec (x, 3); + mpfr_set_prec (y, 47); + mpfr_set_str_binary (x, "0.111e4"); + mpfr_zeta (y, x, MPFR_RNDN); + mpfr_set_prec (x, 47); + mpfr_set_str_binary (x, "1.0000000000000100000000111001001010111100101011"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_zeta (2)\n"); + exit (1); + } + + /* coverage test */ + mpfr_set_prec (x, 7); + mpfr_set_str_binary (x, "1.000001"); + mpfr_set_prec (y, 2); + mpfr_zeta (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 64) == 0); + + /* another coverage test */ + mpfr_set_prec (x, 24); + mpfr_set_ui (x, 2, MPFR_RNDN); + mpfr_set_prec (y, 2); + mpfr_zeta (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 3, -1) == 0); + + mpfr_set_nan (x); + mpfr_zeta (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_set_inf (x, 1); + mpfr_zeta (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); + + mpfr_set_inf (x, -1); + mpfr_zeta (y, x, MPFR_RNDN); + MPFR_ASSERTN(mpfr_nan_p (y)); + + mpfr_clear (x); + mpfr_clear (y); +} + +static const char *const val[] = { + "-2000", "0.0", + "-2.0", "0.0", + "-1.0", "-0.000101010101010101010101010101010101010101010101010101010101010", + "-0.9", "-0.000110011110011111010001010001100010111101001010100110001110110", + /* "-0.8", "-0.000111110011101010001011100011010010000001010011110100010001110", + "-0.7", "-0.00100101011011111100110011110011111010111111000110110100010110", + "-0.6", "-0.00101100101100100100110111111000110010111010110010111000001100", + "-0.5", "-0.00110101001110000000100000011001100100010000111100010001111100", + "-0.4", "-0.00111111010001100011110001010010111110010001010101111101110001", + "-0.3", "-0.0100101100110111010101010100111011000001001010111010110101010", + "-0.2", "-0.0101100110000011101110101011011110101111000010000010110101111", + "-0.1", "-0.0110101011001111011101001111011000010001111010110011011111011", + "-0.0", "-0.100000000000000000000000000000000000000000000000000000000000", + "0.1", "-0.100110100110000010101010101110100000101100100011011001000101", + "0.2", "-0.10111011111000100011110111100010010001111010010010010100010110", + "0.3", "-0.11100111100100010011001000001011001100110010110101101110110110", + "0.4", "-1.0010001010000010000110111000100101001000001011101010110101011", + "0.5", "-1.0111010111011001110010110000011111100111001111111110111000110", + "0.6", "-1.1111001111100001100111101110010001001000001101100110110000100", + "0.7", "-10.110001110100010001110111000101010011110011000110010100101000", + "0.8", "-100.01110000000000101000010010000011000000111101100101100011010", + "0.9", "-1001.0110111000011011111100111100111011100010001111111010000100", + "0.99","-0.11000110110110001101011010110001011010011000110001011100101110E7", + "0.997", "-0.10100110011000001100111110011111100011110000111011101110001010E9", + "0.9995", "-0.11111001111011011000011110111111010111101001000110001111110010E11", + "0.99998", "-0.11000011010011110110110000111011101100001000101101011001110100E16", + "1.00001", "0.11000011010100000100100111100010001110100000110101110011111011E17", + "1.0002", "0.10011100010001001001111000101010111000011011011111110010110100E13", + "1.003","0.10100110111101001001010000000110101101110100001010100000110000E9", + "1.04", "11001.100101001000001011000111010110011010000001000010111101101", + "1.1", "1010.1001010110011110011010100010001100101001001111111101100001", + "1.2", "101.10010111011100011111001001100101101111110000110001101100010", + "1.3", "11.111011101001010000111001001110100100000101000101101011010100", + "1.4", "11.000110110000010100100101011110110001100001110100100100111111", + "1.5", "10.100111001100010010100001011111110111101100010011101011011100", + "1.6", "10.010010010010011111110000010011000110101001110011101010100110", + "1.7", "10.000011011110010111011110001100110010100010011100011111110010", + "1.8", "1.1110000111011001110011001101110101010000011011101100010111001", + "1.9", "1.1011111111101111011000011110001100100111100110111101101000101", + "2.0", "1.1010010100011010011001100010010100110000011111010011001000110", + "42.17", "1.0000000000000000000000000000000000000000001110001110001011001", + "-17.42", "-11.101110101010101000000001001000001111111101000100001100101100", + "-24.17", "-0.10001111010010011111000010001011111010010111101011000010010011E13"*/ +}; + +static void +test2 (void) +{ + mpfr_t x, y; + int i, n = numberof(val); + + mpfr_inits2 (55, x, y, (mpfr_ptr) 0); + + for(i = 0 ; i < n ; i+=2) + { + mpfr_set_str1 (x, val[i]); + mpfr_zeta(y, x, MPFR_RNDZ); + if (mpfr_cmp_str (y, val[i+1] , 2, MPFR_RNDZ)) + { + printf("Wrong result for zeta(%s=", val[i]); + mpfr_print_binary (x); + printf (").\nGot : "); + mpfr_print_binary(y); putchar('\n'); + printf("Expected: "); + mpfr_set_str (y, val[i+1], 2, MPFR_RNDZ); + mpfr_print_binary(y); putchar('\n'); + mpfr_set_prec(y, 65); + mpfr_zeta(y, x, MPFR_RNDZ); + printf("+ Prec : "); + mpfr_print_binary(y); putchar('\n'); + exit(1); + } + } + mpfr_clears (x, y, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION mpfr_zeta +#define TEST_RANDOM_EMIN -48 +#define TEST_RANDOM_EMAX 31 +#include "tgeneric.c" + +/* Usage: tzeta - generic tests + tzeta s prec rnd_mode - compute zeta(s) with precision 'prec' + and rounding mode 'mode' */ +int +main (int argc, char *argv[]) +{ + mpfr_t s, y, z; + mpfr_prec_t prec; + mpfr_rnd_t rnd_mode; + int inex; + + tests_start_mpfr (); + + if (argc != 1 && argc != 4) + { + printf ("Usage: tzeta\n" + " or tzeta s prec rnd_mode\n"); + exit (1); + } + + if (argc == 4) + { + prec = atoi(argv[2]); + mpfr_init2 (s, prec); + mpfr_init2 (z, prec); + mpfr_set_str (s, argv[1], 10, MPFR_RNDN); + rnd_mode = (mpfr_rnd_t) atoi(argv[3]); + + mpfr_zeta (z, s, rnd_mode); + mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN); + printf ("\n"); + + mpfr_clear (s); + mpfr_clear (z); + + return 0; + } + + test1(); + + mpfr_init2 (s, MPFR_PREC_MIN); + mpfr_init2 (y, MPFR_PREC_MIN); + mpfr_init2 (z, MPFR_PREC_MIN); + + + /* the following seems to loop */ + mpfr_set_prec (s, 6); + mpfr_set_prec (z, 6); + mpfr_set_str_binary (s, "1.10010e4"); + mpfr_zeta (z, s, MPFR_RNDZ); + + mpfr_set_prec (s, 53); + mpfr_set_prec (y, 53); + mpfr_set_prec (z, 53); + + mpfr_set_ui (s, 1, MPFR_RNDN); + mpfr_clear_divby0(); + mpfr_zeta (z, s, MPFR_RNDN); + if (!mpfr_inf_p (z) || MPFR_SIGN (z) < 0 || !mpfr_divby0_p()) + { + printf ("Error in mpfr_zeta for s = 1 (should be +inf) with divby0 flag\n"); + exit (1); + } + + mpfr_set_str_binary (s, "0.1100011101110111111111111010000110010111001011001011"); + mpfr_set_str_binary (y, "-0.11111101111011001001001111111000101010000100000100100E2"); + mpfr_zeta (z, s, MPFR_RNDN); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (1,RNDN)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDZ); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (1,RNDZ)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDU); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (1,RNDU)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDD); + mpfr_nexttoinf (y); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (1,RNDD)\n"); + exit (1); + } + + mpfr_set_str_binary (s, "0.10001011010011100110010001100100001011000010011001011"); + mpfr_set_str_binary (y, "-0.11010011010010101101110111011010011101111101111010110E1"); + mpfr_zeta (z, s, MPFR_RNDN); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (2,RNDN)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDZ); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (2,RNDZ)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDU); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (2,RNDU)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDD); + mpfr_nexttoinf (y); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (2,RNDD)\n"); + exit (1); + } + + mpfr_set_str_binary (s, "0.1100111110100001111110111000110101111001011101000101"); + mpfr_set_str_binary (y, "-0.10010111010110000111011111001101100001111011000001010E3"); + mpfr_zeta (z, s, MPFR_RNDN); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (3,RNDN)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDD); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (3,RNDD)\n"); + exit (1); + } + mpfr_nexttozero (y); + mpfr_zeta (z, s, MPFR_RNDZ); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (3,RNDZ)\n"); + exit (1); + } + mpfr_zeta (z, s, MPFR_RNDU); + if (mpfr_cmp (z, y) != 0) + { + printf ("Error in mpfr_zeta (3,RNDU)\n"); + exit (1); + } + + mpfr_set_str (s, "-400000001", 10, MPFR_RNDZ); + mpfr_zeta (z, s, MPFR_RNDN); + if (!(mpfr_inf_p (z) && MPFR_SIGN(z) < 0)) + { + printf ("Error in mpfr_zeta (-400000001)\n"); + exit (1); + } + mpfr_set_str (s, "-400000003", 10, MPFR_RNDZ); + mpfr_zeta (z, s, MPFR_RNDN); + if (!(mpfr_inf_p (z) && MPFR_SIGN(z) > 0)) + { + printf ("Error in mpfr_zeta (-400000003)\n"); + exit (1); + } + + mpfr_set_prec (s, 34); + mpfr_set_prec (z, 34); + mpfr_set_str_binary (s, "-1.111111100001011110000010001010000e-35"); + mpfr_zeta (z, s, MPFR_RNDD); + mpfr_set_str_binary (s, "-1.111111111111111111111111111111111e-2"); + if (mpfr_cmp (s, z)) + { + printf ("Error in mpfr_zeta, prec=34, MPFR_RNDD\n"); + mpfr_dump (z); + exit (1); + } + + /* bug found by nightly tests on June 7, 2007 */ + mpfr_set_prec (s, 23); + mpfr_set_prec (z, 25); + mpfr_set_str_binary (s, "-1.0110110110001000000000e-27"); + mpfr_zeta (z, s, MPFR_RNDN); + mpfr_set_prec (s, 25); + mpfr_set_str_binary (s, "-1.111111111111111111111111e-2"); + if (mpfr_cmp (s, z)) + { + printf ("Error in mpfr_zeta, prec=25, MPFR_RNDN\n"); + printf ("expected "); mpfr_dump (s); + printf ("got "); mpfr_dump (z); + exit (1); + } + + /* bug reported by Kevin Rauch on 26 Oct 2007 */ + mpfr_set_prec (s, 128); + mpfr_set_prec (z, 128); + mpfr_set_str_binary (s, "-0.1000000000000000000000000000000000000000000000000000000000000001E64"); + inex = mpfr_zeta (z, s, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (z) && MPFR_SIGN (z) < 0 && inex < 0); + inex = mpfr_zeta (z, s, MPFR_RNDU); + mpfr_set_inf (s, -1); + mpfr_nextabove (s); + MPFR_ASSERTN (mpfr_equal_p (z, s) && inex > 0); + + /* bug reported by Fredrik Johansson on 19 Jan 2016 */ + mpfr_set_prec (s, 536); + mpfr_set_ui_2exp (s, 1, -424, MPFR_RNDN); + mpfr_sub_ui (s, s, 128, MPFR_RNDN); /* -128 + 2^(-424) */ + for (prec = 6; prec <= 536; prec += 8) /* should go through 318 */ + { + mpfr_set_prec (z, prec); + mpfr_zeta (z, s, MPFR_RNDD); + mpfr_set_prec (y, prec + 10); + mpfr_zeta (y, s, MPFR_RNDD); + mpfr_prec_round (y, prec, MPFR_RNDD); + if (! mpfr_equal_p (z, y)) + { + printf ("mpfr_zeta fails near -128 for inprec=%lu outprec=%lu\n", + (unsigned long) mpfr_get_prec (s), (unsigned long) prec); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (z); + exit (1); + } + } + + mpfr_clear (s); + mpfr_clear (y); + mpfr_clear (z); + + test_generic (2, 70, 5); + test2 (); + + tests_end_mpfr (); + return 0; +} diff --git a/mpfr/tests/tzeta_ui.c b/mpfr/tests/tzeta_ui.c new file mode 100644 index 0000000000..3467c0cfd2 --- /dev/null +++ b/mpfr/tests/tzeta_ui.c @@ -0,0 +1,210 @@ +/* Test file for mpfr_zeta_ui. + +Copyright 2005-2016 Free Software Foundation, Inc. +Contributed by the AriC and Caramba projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#define TEST_FUNCTION mpfr_zeta_ui + +int +main (int argc, char *argv[]) +{ +#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0) + unsigned int prec, yprec; + int rnd; + mpfr_t x, y, z, t; + unsigned long n; + int inex; + mpfr_exp_t emin, emax; + unsigned int flags, ex_flags; + int i; + + tests_start_mpfr (); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + if (argc >= 3) /* tzeta_ui n prec [rnd] */ + { + mpfr_set_prec (x, atoi (argv[2])); + mpfr_zeta_ui (x, atoi (argv[1]), + argc > 3 ? (mpfr_rnd_t) atoi (argv[3]) : MPFR_RNDN); + mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); + printf ("\n"); + goto clear_and_exit; + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 33); + mpfr_zeta_ui (x, 3, MPFR_RNDZ); + mpfr_set_str_binary (y, "0.100110011101110100000000001001111E1"); + if (mpfr_cmp (x, y)) + { + printf ("Error for zeta(3), prec=33, MPFR_RNDZ\n"); + printf ("expected "); mpfr_dump (y); + printf ("got "); mpfr_dump (x); + exit (1); + } + + mpfr_clear_flags (); + inex = mpfr_zeta_ui (x, 0, MPFR_RNDN); + flags = __gmpfr_flags; + MPFR_ASSERTN (inex == 0 && mpfr_cmp_si_2exp (x, -1, -1) == 0 && flags == 0); + + for (i = -2; i <= 2; i += 2) + RND_LOOP (rnd) + { + int ex_inex; + + set_emin (i); + set_emax (i); + mpfr_clear_flags (); + inex = mpfr_zeta_ui (x, 0, (mpfr_rnd_t) rnd); + flags = __gmpfr_flags; + if (i < 0) + { + mpfr_set_inf (y, -1); + if (rnd == MPFR_RNDU || rnd == MPFR_RNDZ) + { + mpfr_nextabove (y); + ex_inex = 1; + } + else + { + ex_inex = -1; + } + ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; + } + else if (i > 0) + { + mpfr_set_zero (y, -1); + if (rnd == MPFR_RNDD || rnd == MPFR_RNDA) + { + mpfr_nextbelow (y); + ex_inex = -1; + } + else + { + ex_inex = 1; + } + ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; + } + else + { + mpfr_set_str_binary (y, "-1e-1"); + ex_inex = 0; + ex_flags = 0; + } + set_emin (emin); + set_emax (emax); + if (! (mpfr_equal_p (x, y) && MPFR_IS_NEG (x) && + SAME_SIGN (inex, ex_inex) && flags == ex_flags)) + { + printf ("Failure for zeta(0) in %s, exponent range [%d,%d]\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), i, i); + printf ("Expected "); + mpfr_dump (y); + printf (" with inex ~ %d, flags =", ex_inex); + flags_out (ex_flags); + printf ("Got "); + mpfr_dump (x); + printf (" with inex = %d, flags =", inex); + flags_out (flags); + exit (1); + } + } + + mpfr_clear_divby0 (); + inex = mpfr_zeta_ui (x, 1, MPFR_RNDN); + MPFR_ASSERTN (inex == 0 && MPFR_IS_INF (x) && MPFR_IS_POS (x) + && mpfr_divby0_p ()); + + for (prec = MPFR_PREC_MIN; prec <= 100; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + mpfr_set_prec (y, yprec); + + for (n = 0; n < 50; n++) + RND_LOOP (rnd) + { + mpfr_zeta_ui (y, n, MPFR_RNDN); + if (mpfr_can_round (y, yprec, MPFR_RNDN, MPFR_RNDZ, prec + + (rnd == MPFR_RNDN))) + { + mpfr_set (t, y, (mpfr_rnd_t) rnd); + for (i = 0; i <= 1; i++) + { + if (i) + { + mpfr_exp_t e; + + if (MPFR_IS_SINGULAR (t)) + break; + e = mpfr_get_exp (t); + set_emin (e); + set_emax (e); + } + mpfr_zeta_ui (z, n, (mpfr_rnd_t) rnd); + if (i) + { + set_emin (emin); + set_emax (emax); + } + if (mpfr_cmp (t, z)) + { + printf ("results differ for n = %lu, prec = %u," + " %s%s\n", n, prec, + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + i ? ", reduced exponent range" : ""); + printf (" got "); + mpfr_dump (z); + printf (" expected "); + mpfr_dump (t); + printf (" approx "); + mpfr_dump (y); + exit (1); + } + } + } + } + } + + clear_and_exit: + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + tests_end_mpfr (); +#endif + return 0; +} |