diff options
author | Kevin Ryde <user42@zip.com.au> | 2002-03-09 23:49:20 +0100 |
---|---|---|
committer | Kevin Ryde <user42@zip.com.au> | 2002-03-09 23:49:20 +0100 |
commit | 5548ebac58434a675c5c9daa25dbc1fe572beb0c (patch) | |
tree | 6a9e6f49e2f25c7401b64946fdf055bf8b2e965d | |
parent | 9262a18b652b66e71b8fd0fb84f77e3c8588e21c (diff) | |
download | gmp-5548ebac58434a675c5c9daa25dbc1fe572beb0c.tar.gz |
* mpfr: Update to 20020301, except internal_ceil_exp2.c,
internal_ceil_log2.c, internal_floor_log2.c renamed to i_ceil_exp2.c,
i_ceil_log2.c, i_floor_log2.c to be unique in DOS 8.3. And sqrtrem.c
removed since no longer required.
156 files changed, 4836 insertions, 3361 deletions
diff --git a/mpfr/AUTHORS b/mpfr/AUTHORS index 3c5c3016b..73c8a3358 100644 --- a/mpfr/AUTHORS +++ b/mpfr/AUTHORS @@ -1,17 +1,17 @@ -The MPFR library was developed by the PolKA project at INRIA Lorraine and -LORIA. Authors and contributors are: +Authors of MPFR (in chronological order of initial contribution): -Sylvie Boldo <sboldo@ens-lyon.fr> wrote the agm and log routines -Guillaume Hanrot <hanrot@loria.fr> wrote part of the library -Emmanuel Jeandel <E_Jeandel@mail.dotcom.fr> wrote the hypergeometric code -Vincent Lefe`vre <lefevre@loria.fr> contributed many test cases for elementary - functions -Thom Mulders <mulders@inf.ethz.ch> contributed the short multiplication code -Fabrice Rouillier <rouillie@loria.fr> helped a lot for testing and porting -Jean-Luc Re'my <remy@loria.fr> wrote a prototype of the Zeta function -Paul Zimmermann <zimmerma@loria.fr> wrote part of the library +Guillaume Hanrot Main author +Fabrice Rouillier Original version of mul_ui.c, gmp_op.c +Paul Zimmermann Main author +Sylvie Boldo Original version of agm.c and log.c +Emmanuel Jeandel Original version of generic.c, exp3.c, pi.c, sincos.c +Mathieu Dutour asin.c, atan.c and gamma.c +Vincent Lefe`vre Main author +David Daney Hyperbolic and inverse hyperbolic functions, base-2 + and base-10 exponential and logarithm, factorial -All the authors are included in the MPFR mailing-list <mpfr@loria.fr>. +All authors are included in the MPFR mailing-list <mpfr@loria.fr>. This is the preferred way to contact us. For further information, please -look at the MPFR web page <http://www.loria.fr/projets/mpfr/>. +look at the MPFR web page <http://www.mpfr.org/> or +<http://www.loria.fr/projets/mpfr/>. diff --git a/mpfr/Makefile.in b/mpfr/Makefile.in index 0dab09e4c..a635c565e 100644 --- a/mpfr/Makefile.in +++ b/mpfr/Makefile.in @@ -13,7 +13,7 @@ @SET_MAKE@ -# Copyright 2000, 2001 Free Software Foundation, Inc. +# Copyright 2000, 2001, 2002 Free Software Foundation, Inc. # # This file is part of the GNU MP Library. # @@ -150,9 +150,7 @@ INCLUDES = -I$(top_srcdir) info_TEXINFOS = mpfr.texi TEXINFO_TEX = ../texinfo.tex -libmpfr_a_SOURCES = cputime.h mpfr.h mpfr-impl.h exceptions.c save_expo.c extract.c add.c add1.c add_ui.c add_ulp.c agm.c clear.c cmp.c cmp_abs.c cmp_ui.c div_2exp.c div.c div_ui.c dump.c eq.c exp2.c exp3.c exp.c get_str.c init.c inp_str.c isinteger.c isinf.c isnan.c isnum.c log2.c log.c mul_2exp.c mul.c mul_ui.c neg.c out_str.c pi.c pow.c pow_si.c pow_ui.c print_raw.c print_rnd_mode.c random2.c random.c reldiff.c rnd_mode.c round.c set.c set_d.c set_dfl_prec.c set_rnd.c set_f.c set_prc_raw.c set_prec.c set_q.c set_si.c set_str.c set_str_raw.c set_ui.c set_z.c sqrt.c sqrt_ui.c sub.c sub1.c sub_ui.c trunc.c ui_div.c ui_sub.c urandomb.c mpz_set_fr.c swap.c factorial.c cosh.c sinh.c tanh.c acosh.c asinh.c atanh.c atan.c cmp2.c exp_2.c asin.c euler.c cos.c sin.c tan.c fma.c hypot.c log1p.c expm1.c log_base_2.c ui_pow.c ui_pow_ui.c log_base_10.c minmax.c dim.c copysign.c gmp_op.c init2.c \ - floor.c ceil.c - +libmpfr_a_SOURCES = cputime.h mpfr.h mpfr-impl.h exceptions.c save_expo.c extract.c i_ceil_exp2.c i_ceil_log2.c i_floor_log2.c add.c add1.c add_one_ulp.c add_ui.c agm.c clear.c cmp.c cmp_abs.c cmp_ui.c div_2exp.c div_2si.c div_2ui.c div.c div_ui.c dump.c eq.c exp2.c exp3.c exp.c get_str.c init.c inp_str.c isinteger.c isinf.c isnan.c isnum.c const_log2.c log.c mul_2exp.c mul_2si.c mul_2ui.c mul.c mul_ui.c neg.c out_str.c const_pi.c pow.c pow_si.c pow_ui.c print_raw.c print_rnd_mode.c random2.c random.c reldiff.c rnd_mode.c round_prec.c set.c set_d.c set_dfl_prec.c set_rnd.c set_f.c set_prc_raw.c set_prec.c set_q.c set_si.c set_str.c set_str_raw.c set_ui.c set_z.c sqrt.c sqrt_ui.c sub.c sub1.c sub_one_ulp.c sub_ui.c rint.c ui_div.c ui_sub.c urandomb.c mpz_set_fr.c swap.c factorial.c cosh.c sinh.c tanh.c acosh.c asinh.c atanh.c atan.c cmp2.c exp_2.c asin.c const_euler.c cos.c sin.c tan.c fma.c hypot.c log1p.c expm1.c log2.c log10.c ui_pow.c ui_pow_ui.c minmax.c dim.c copysign.c gmp_op.c init2.c acos.c EXTRA_DIST = generic.c mpfr-test.h mpf2mpfr.h subdir = mpfr @@ -164,39 +162,42 @@ LIBRARIES = $(lib_LIBRARIES) libmpfr_a_AR = $(AR) cru libmpfr_a_LIBADD = am_libmpfr_a_OBJECTS = exceptions$U.$(OBJEXT) save_expo$U.$(OBJEXT) \ - extract$U.$(OBJEXT) add$U.$(OBJEXT) add1$U.$(OBJEXT) \ - add_ui$U.$(OBJEXT) add_ulp$U.$(OBJEXT) agm$U.$(OBJEXT) \ - clear$U.$(OBJEXT) cmp$U.$(OBJEXT) cmp_abs$U.$(OBJEXT) \ - cmp_ui$U.$(OBJEXT) div_2exp$U.$(OBJEXT) div$U.$(OBJEXT) \ - div_ui$U.$(OBJEXT) dump$U.$(OBJEXT) eq$U.$(OBJEXT) \ - exp2$U.$(OBJEXT) exp3$U.$(OBJEXT) exp$U.$(OBJEXT) \ - get_str$U.$(OBJEXT) init$U.$(OBJEXT) inp_str$U.$(OBJEXT) \ - isinteger$U.$(OBJEXT) isinf$U.$(OBJEXT) isnan$U.$(OBJEXT) \ - isnum$U.$(OBJEXT) log2$U.$(OBJEXT) log$U.$(OBJEXT) \ - mul_2exp$U.$(OBJEXT) mul$U.$(OBJEXT) mul_ui$U.$(OBJEXT) \ - neg$U.$(OBJEXT) out_str$U.$(OBJEXT) pi$U.$(OBJEXT) \ + extract$U.$(OBJEXT) i_ceil_exp2$U.$(OBJEXT) \ + i_ceil_log2$U.$(OBJEXT) i_floor_log2$U.$(OBJEXT) \ + add$U.$(OBJEXT) add1$U.$(OBJEXT) add_one_ulp$U.$(OBJEXT) \ + add_ui$U.$(OBJEXT) agm$U.$(OBJEXT) clear$U.$(OBJEXT) \ + cmp$U.$(OBJEXT) cmp_abs$U.$(OBJEXT) cmp_ui$U.$(OBJEXT) \ + div_2exp$U.$(OBJEXT) div_2si$U.$(OBJEXT) div_2ui$U.$(OBJEXT) \ + div$U.$(OBJEXT) div_ui$U.$(OBJEXT) dump$U.$(OBJEXT) \ + eq$U.$(OBJEXT) exp2$U.$(OBJEXT) exp3$U.$(OBJEXT) \ + exp$U.$(OBJEXT) get_str$U.$(OBJEXT) init$U.$(OBJEXT) \ + inp_str$U.$(OBJEXT) isinteger$U.$(OBJEXT) isinf$U.$(OBJEXT) \ + isnan$U.$(OBJEXT) isnum$U.$(OBJEXT) const_log2$U.$(OBJEXT) \ + log$U.$(OBJEXT) mul_2exp$U.$(OBJEXT) mul_2si$U.$(OBJEXT) \ + mul_2ui$U.$(OBJEXT) mul$U.$(OBJEXT) mul_ui$U.$(OBJEXT) \ + neg$U.$(OBJEXT) out_str$U.$(OBJEXT) const_pi$U.$(OBJEXT) \ pow$U.$(OBJEXT) pow_si$U.$(OBJEXT) pow_ui$U.$(OBJEXT) \ print_raw$U.$(OBJEXT) print_rnd_mode$U.$(OBJEXT) \ random2$U.$(OBJEXT) random$U.$(OBJEXT) reldiff$U.$(OBJEXT) \ - rnd_mode$U.$(OBJEXT) round$U.$(OBJEXT) set$U.$(OBJEXT) \ + rnd_mode$U.$(OBJEXT) round_prec$U.$(OBJEXT) set$U.$(OBJEXT) \ set_d$U.$(OBJEXT) set_dfl_prec$U.$(OBJEXT) set_rnd$U.$(OBJEXT) \ set_f$U.$(OBJEXT) set_prc_raw$U.$(OBJEXT) set_prec$U.$(OBJEXT) \ set_q$U.$(OBJEXT) set_si$U.$(OBJEXT) set_str$U.$(OBJEXT) \ set_str_raw$U.$(OBJEXT) set_ui$U.$(OBJEXT) set_z$U.$(OBJEXT) \ sqrt$U.$(OBJEXT) sqrt_ui$U.$(OBJEXT) sub$U.$(OBJEXT) \ - sub1$U.$(OBJEXT) sub_ui$U.$(OBJEXT) trunc$U.$(OBJEXT) \ - ui_div$U.$(OBJEXT) ui_sub$U.$(OBJEXT) urandomb$U.$(OBJEXT) \ - mpz_set_fr$U.$(OBJEXT) swap$U.$(OBJEXT) factorial$U.$(OBJEXT) \ - cosh$U.$(OBJEXT) sinh$U.$(OBJEXT) tanh$U.$(OBJEXT) \ - acosh$U.$(OBJEXT) asinh$U.$(OBJEXT) atanh$U.$(OBJEXT) \ - atan$U.$(OBJEXT) cmp2$U.$(OBJEXT) exp_2$U.$(OBJEXT) \ - asin$U.$(OBJEXT) euler$U.$(OBJEXT) cos$U.$(OBJEXT) \ - sin$U.$(OBJEXT) tan$U.$(OBJEXT) fma$U.$(OBJEXT) \ + sub1$U.$(OBJEXT) sub_one_ulp$U.$(OBJEXT) sub_ui$U.$(OBJEXT) \ + rint$U.$(OBJEXT) ui_div$U.$(OBJEXT) ui_sub$U.$(OBJEXT) \ + urandomb$U.$(OBJEXT) mpz_set_fr$U.$(OBJEXT) swap$U.$(OBJEXT) \ + factorial$U.$(OBJEXT) cosh$U.$(OBJEXT) sinh$U.$(OBJEXT) \ + tanh$U.$(OBJEXT) acosh$U.$(OBJEXT) asinh$U.$(OBJEXT) \ + atanh$U.$(OBJEXT) atan$U.$(OBJEXT) cmp2$U.$(OBJEXT) \ + exp_2$U.$(OBJEXT) asin$U.$(OBJEXT) const_euler$U.$(OBJEXT) \ + cos$U.$(OBJEXT) sin$U.$(OBJEXT) tan$U.$(OBJEXT) fma$U.$(OBJEXT) \ hypot$U.$(OBJEXT) log1p$U.$(OBJEXT) expm1$U.$(OBJEXT) \ - log_base_2$U.$(OBJEXT) ui_pow$U.$(OBJEXT) ui_pow_ui$U.$(OBJEXT) \ - log_base_10$U.$(OBJEXT) minmax$U.$(OBJEXT) dim$U.$(OBJEXT) \ + log2$U.$(OBJEXT) log10$U.$(OBJEXT) ui_pow$U.$(OBJEXT) \ + ui_pow_ui$U.$(OBJEXT) minmax$U.$(OBJEXT) dim$U.$(OBJEXT) \ copysign$U.$(OBJEXT) gmp_op$U.$(OBJEXT) init2$U.$(OBJEXT) \ - floor$U.$(OBJEXT) ceil$U.$(OBJEXT) + acos$U.$(OBJEXT) libmpfr_a_OBJECTS = $(am_libmpfr_a_OBJECTS) DEFS = @DEFS@ @@ -301,16 +302,18 @@ mostlyclean-kr: .c.lo: $(LTCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$< +acos_.c: acos.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/acos.c; then echo $(srcdir)/acos.c; else echo acos.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > acos_.c || rm -f acos_.c acosh_.c: acosh.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/acosh.c; then echo $(srcdir)/acosh.c; else echo acosh.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > acosh_.c || rm -f acosh_.c add_.c: add.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/add.c; then echo $(srcdir)/add.c; else echo add.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > add_.c || rm -f add_.c add1_.c: add1.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/add1.c; then echo $(srcdir)/add1.c; else echo add1.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > add1_.c || rm -f add1_.c +add_one_ulp_.c: add_one_ulp.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/add_one_ulp.c; then echo $(srcdir)/add_one_ulp.c; else echo add_one_ulp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > add_one_ulp_.c || rm -f add_one_ulp_.c add_ui_.c: add_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/add_ui.c; then echo $(srcdir)/add_ui.c; else echo add_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > add_ui_.c || rm -f add_ui_.c -add_ulp_.c: add_ulp.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/add_ulp.c; then echo $(srcdir)/add_ulp.c; else echo add_ulp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > add_ulp_.c || rm -f add_ulp_.c agm_.c: agm.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/agm.c; then echo $(srcdir)/agm.c; else echo agm.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > agm_.c || rm -f agm_.c asin_.c: asin.c $(ANSI2KNR) @@ -321,8 +324,6 @@ atan_.c: atan.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/atan.c; then echo $(srcdir)/atan.c; else echo atan.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > atan_.c || rm -f atan_.c atanh_.c: atanh.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/atanh.c; then echo $(srcdir)/atanh.c; else echo atanh.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > atanh_.c || rm -f atanh_.c -ceil_.c: ceil.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ceil.c; then echo $(srcdir)/ceil.c; else echo ceil.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ceil_.c || rm -f ceil_.c clear_.c: clear.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/clear.c; then echo $(srcdir)/clear.c; else echo clear.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > clear_.c || rm -f clear_.c cmp_.c: cmp.c $(ANSI2KNR) @@ -333,6 +334,12 @@ cmp_abs_.c: cmp_abs.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/cmp_abs.c; then echo $(srcdir)/cmp_abs.c; else echo cmp_abs.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > cmp_abs_.c || rm -f cmp_abs_.c cmp_ui_.c: cmp_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/cmp_ui.c; then echo $(srcdir)/cmp_ui.c; else echo cmp_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > cmp_ui_.c || rm -f cmp_ui_.c +const_euler_.c: const_euler.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/const_euler.c; then echo $(srcdir)/const_euler.c; else echo const_euler.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > const_euler_.c || rm -f const_euler_.c +const_log2_.c: const_log2.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/const_log2.c; then echo $(srcdir)/const_log2.c; else echo const_log2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > const_log2_.c || rm -f const_log2_.c +const_pi_.c: const_pi.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/const_pi.c; then echo $(srcdir)/const_pi.c; else echo const_pi.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > const_pi_.c || rm -f const_pi_.c copysign_.c: copysign.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/copysign.c; then echo $(srcdir)/copysign.c; else echo copysign.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > copysign_.c || rm -f copysign_.c cos_.c: cos.c $(ANSI2KNR) @@ -345,14 +352,16 @@ div_.c: div.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/div.c; then echo $(srcdir)/div.c; else echo div.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > div_.c || rm -f div_.c div_2exp_.c: div_2exp.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/div_2exp.c; then echo $(srcdir)/div_2exp.c; else echo div_2exp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > div_2exp_.c || rm -f div_2exp_.c +div_2si_.c: div_2si.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/div_2si.c; then echo $(srcdir)/div_2si.c; else echo div_2si.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > div_2si_.c || rm -f div_2si_.c +div_2ui_.c: div_2ui.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/div_2ui.c; then echo $(srcdir)/div_2ui.c; else echo div_2ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > div_2ui_.c || rm -f div_2ui_.c div_ui_.c: div_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/div_ui.c; then echo $(srcdir)/div_ui.c; else echo div_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > div_ui_.c || rm -f div_ui_.c dump_.c: dump.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/dump.c; then echo $(srcdir)/dump.c; else echo dump.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > dump_.c || rm -f dump_.c eq_.c: eq.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/eq.c; then echo $(srcdir)/eq.c; else echo eq.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > eq_.c || rm -f eq_.c -euler_.c: euler.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/euler.c; then echo $(srcdir)/euler.c; else echo euler.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > euler_.c || rm -f euler_.c exceptions_.c: exceptions.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exceptions.c; then echo $(srcdir)/exceptions.c; else echo exceptions.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > exceptions_.c || rm -f exceptions_.c exp_.c: exp.c $(ANSI2KNR) @@ -369,8 +378,6 @@ extract_.c: extract.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/extract.c; then echo $(srcdir)/extract.c; else echo extract.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > extract_.c || rm -f extract_.c factorial_.c: factorial.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/factorial.c; then echo $(srcdir)/factorial.c; else echo factorial.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > factorial_.c || rm -f factorial_.c -floor_.c: floor.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/floor.c; then echo $(srcdir)/floor.c; else echo floor.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > floor_.c || rm -f floor_.c fma_.c: fma.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/fma.c; then echo $(srcdir)/fma.c; else echo fma.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > fma_.c || rm -f fma_.c get_str_.c: get_str.c $(ANSI2KNR) @@ -379,6 +386,12 @@ gmp_op_.c: gmp_op.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/gmp_op.c; then echo $(srcdir)/gmp_op.c; else echo gmp_op.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > gmp_op_.c || rm -f gmp_op_.c hypot_.c: hypot.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/hypot.c; then echo $(srcdir)/hypot.c; else echo hypot.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > hypot_.c || rm -f hypot_.c +i_ceil_exp2_.c: i_ceil_exp2.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/i_ceil_exp2.c; then echo $(srcdir)/i_ceil_exp2.c; else echo i_ceil_exp2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > i_ceil_exp2_.c || rm -f i_ceil_exp2_.c +i_ceil_log2_.c: i_ceil_log2.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/i_ceil_log2.c; then echo $(srcdir)/i_ceil_log2.c; else echo i_ceil_log2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > i_ceil_log2_.c || rm -f i_ceil_log2_.c +i_floor_log2_.c: i_floor_log2.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/i_floor_log2.c; then echo $(srcdir)/i_floor_log2.c; else echo i_floor_log2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > i_floor_log2_.c || rm -f i_floor_log2_.c init_.c: init.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/init.c; then echo $(srcdir)/init.c; else echo init.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > init_.c || rm -f init_.c init2_.c: init2.c $(ANSI2KNR) @@ -395,14 +408,12 @@ isnum_.c: isnum.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/isnum.c; then echo $(srcdir)/isnum.c; else echo isnum.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > isnum_.c || rm -f isnum_.c log_.c: log.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/log.c; then echo $(srcdir)/log.c; else echo log.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > log_.c || rm -f log_.c +log10_.c: log10.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/log10.c; then echo $(srcdir)/log10.c; else echo log10.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > log10_.c || rm -f log10_.c log1p_.c: log1p.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/log1p.c; then echo $(srcdir)/log1p.c; else echo log1p.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > log1p_.c || rm -f log1p_.c log2_.c: log2.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/log2.c; then echo $(srcdir)/log2.c; else echo log2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > log2_.c || rm -f log2_.c -log_base_10_.c: log_base_10.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/log_base_10.c; then echo $(srcdir)/log_base_10.c; else echo log_base_10.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > log_base_10_.c || rm -f log_base_10_.c -log_base_2_.c: log_base_2.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/log_base_2.c; then echo $(srcdir)/log_base_2.c; else echo log_base_2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > log_base_2_.c || rm -f log_base_2_.c minmax_.c: minmax.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/minmax.c; then echo $(srcdir)/minmax.c; else echo minmax.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > minmax_.c || rm -f minmax_.c mpz_set_fr_.c: mpz_set_fr.c $(ANSI2KNR) @@ -411,14 +422,16 @@ mul_.c: mul.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mul.c; then echo $(srcdir)/mul.c; else echo mul.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > mul_.c || rm -f mul_.c mul_2exp_.c: mul_2exp.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mul_2exp.c; then echo $(srcdir)/mul_2exp.c; else echo mul_2exp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > mul_2exp_.c || rm -f mul_2exp_.c +mul_2si_.c: mul_2si.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mul_2si.c; then echo $(srcdir)/mul_2si.c; else echo mul_2si.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > mul_2si_.c || rm -f mul_2si_.c +mul_2ui_.c: mul_2ui.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mul_2ui.c; then echo $(srcdir)/mul_2ui.c; else echo mul_2ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > mul_2ui_.c || rm -f mul_2ui_.c mul_ui_.c: mul_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mul_ui.c; then echo $(srcdir)/mul_ui.c; else echo mul_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > mul_ui_.c || rm -f mul_ui_.c neg_.c: neg.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/neg.c; then echo $(srcdir)/neg.c; else echo neg.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > neg_.c || rm -f neg_.c out_str_.c: out_str.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/out_str.c; then echo $(srcdir)/out_str.c; else echo out_str.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > out_str_.c || rm -f out_str_.c -pi_.c: pi.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/pi.c; then echo $(srcdir)/pi.c; else echo pi.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > pi_.c || rm -f pi_.c pow_.c: pow.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/pow.c; then echo $(srcdir)/pow.c; else echo pow.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > pow_.c || rm -f pow_.c pow_si_.c: pow_si.c $(ANSI2KNR) @@ -435,10 +448,12 @@ random2_.c: random2.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/random2.c; then echo $(srcdir)/random2.c; else echo random2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > random2_.c || rm -f random2_.c reldiff_.c: reldiff.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/reldiff.c; then echo $(srcdir)/reldiff.c; else echo reldiff.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > reldiff_.c || rm -f reldiff_.c +rint_.c: rint.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/rint.c; then echo $(srcdir)/rint.c; else echo rint.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > rint_.c || rm -f rint_.c rnd_mode_.c: rnd_mode.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/rnd_mode.c; then echo $(srcdir)/rnd_mode.c; else echo rnd_mode.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > rnd_mode_.c || rm -f rnd_mode_.c -round_.c: round.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/round.c; then echo $(srcdir)/round.c; else echo round.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > round_.c || rm -f round_.c +round_prec_.c: round_prec.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/round_prec.c; then echo $(srcdir)/round_prec.c; else echo round_prec.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > round_prec_.c || rm -f round_prec_.c save_expo_.c: save_expo.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/save_expo.c; then echo $(srcdir)/save_expo.c; else echo save_expo.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > save_expo_.c || rm -f save_expo_.c set_.c: set.c $(ANSI2KNR) @@ -479,6 +494,8 @@ sub_.c: sub.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sub.c; then echo $(srcdir)/sub.c; else echo sub.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > sub_.c || rm -f sub_.c sub1_.c: sub1.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sub1.c; then echo $(srcdir)/sub1.c; else echo sub1.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > sub1_.c || rm -f sub1_.c +sub_one_ulp_.c: sub_one_ulp.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sub_one_ulp.c; then echo $(srcdir)/sub_one_ulp.c; else echo sub_one_ulp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > sub_one_ulp_.c || rm -f sub_one_ulp_.c sub_ui_.c: sub_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sub_ui.c; then echo $(srcdir)/sub_ui.c; else echo sub_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > sub_ui_.c || rm -f sub_ui_.c swap_.c: swap.c $(ANSI2KNR) @@ -487,8 +504,6 @@ tan_.c: tan.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tan.c; then echo $(srcdir)/tan.c; else echo tan.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tan_.c || rm -f tan_.c tanh_.c: tanh.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tanh.c; then echo $(srcdir)/tanh.c; else echo tanh.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tanh_.c || rm -f tanh_.c -trunc_.c: trunc.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/trunc.c; then echo $(srcdir)/trunc.c; else echo trunc.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > trunc_.c || rm -f trunc_.c ui_div_.c: ui_div.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ui_div.c; then echo $(srcdir)/ui_div.c; else echo ui_div.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ui_div_.c || rm -f ui_div_.c ui_pow_.c: ui_pow.c $(ANSI2KNR) @@ -499,50 +514,54 @@ ui_sub_.c: ui_sub.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ui_sub.c; then echo $(srcdir)/ui_sub.c; else echo ui_sub.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ui_sub_.c || rm -f ui_sub_.c urandomb_.c: urandomb.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/urandomb.c; then echo $(srcdir)/urandomb.c; else echo urandomb.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > urandomb_.c || rm -f urandomb_.c -acosh_.$(OBJEXT) acosh_.lo add_.$(OBJEXT) add_.lo add1_.$(OBJEXT) \ -add1_.lo add_ui_.$(OBJEXT) add_ui_.lo add_ulp_.$(OBJEXT) add_ulp_.lo \ -agm_.$(OBJEXT) agm_.lo asin_.$(OBJEXT) asin_.lo asinh_.$(OBJEXT) \ -asinh_.lo atan_.$(OBJEXT) atan_.lo atanh_.$(OBJEXT) atanh_.lo \ -ceil_.$(OBJEXT) ceil_.lo clear_.$(OBJEXT) clear_.lo cmp_.$(OBJEXT) \ +acos_.$(OBJEXT) acos_.lo acosh_.$(OBJEXT) acosh_.lo add_.$(OBJEXT) \ +add_.lo add1_.$(OBJEXT) add1_.lo add_one_ulp_.$(OBJEXT) add_one_ulp_.lo \ +add_ui_.$(OBJEXT) add_ui_.lo agm_.$(OBJEXT) agm_.lo asin_.$(OBJEXT) \ +asin_.lo asinh_.$(OBJEXT) asinh_.lo atan_.$(OBJEXT) atan_.lo \ +atanh_.$(OBJEXT) atanh_.lo clear_.$(OBJEXT) clear_.lo cmp_.$(OBJEXT) \ cmp_.lo cmp2_.$(OBJEXT) cmp2_.lo cmp_abs_.$(OBJEXT) cmp_abs_.lo \ -cmp_ui_.$(OBJEXT) cmp_ui_.lo copysign_.$(OBJEXT) copysign_.lo \ -cos_.$(OBJEXT) cos_.lo cosh_.$(OBJEXT) cosh_.lo dim_.$(OBJEXT) dim_.lo \ -div_.$(OBJEXT) div_.lo div_2exp_.$(OBJEXT) div_2exp_.lo \ -div_ui_.$(OBJEXT) div_ui_.lo dump_.$(OBJEXT) dump_.lo eq_.$(OBJEXT) \ -eq_.lo euler_.$(OBJEXT) euler_.lo exceptions_.$(OBJEXT) exceptions_.lo \ -exp_.$(OBJEXT) exp_.lo exp2_.$(OBJEXT) exp2_.lo exp3_.$(OBJEXT) \ -exp3_.lo exp_2_.$(OBJEXT) exp_2_.lo expm1_.$(OBJEXT) expm1_.lo \ -extract_.$(OBJEXT) extract_.lo factorial_.$(OBJEXT) factorial_.lo \ -floor_.$(OBJEXT) floor_.lo fma_.$(OBJEXT) fma_.lo get_str_.$(OBJEXT) \ -get_str_.lo gmp_op_.$(OBJEXT) gmp_op_.lo hypot_.$(OBJEXT) hypot_.lo \ +cmp_ui_.$(OBJEXT) cmp_ui_.lo const_euler_.$(OBJEXT) const_euler_.lo \ +const_log2_.$(OBJEXT) const_log2_.lo const_pi_.$(OBJEXT) const_pi_.lo \ +copysign_.$(OBJEXT) copysign_.lo cos_.$(OBJEXT) cos_.lo cosh_.$(OBJEXT) \ +cosh_.lo dim_.$(OBJEXT) dim_.lo div_.$(OBJEXT) div_.lo \ +div_2exp_.$(OBJEXT) div_2exp_.lo div_2si_.$(OBJEXT) div_2si_.lo \ +div_2ui_.$(OBJEXT) div_2ui_.lo div_ui_.$(OBJEXT) div_ui_.lo \ +dump_.$(OBJEXT) dump_.lo eq_.$(OBJEXT) eq_.lo exceptions_.$(OBJEXT) \ +exceptions_.lo exp_.$(OBJEXT) exp_.lo exp2_.$(OBJEXT) exp2_.lo \ +exp3_.$(OBJEXT) exp3_.lo exp_2_.$(OBJEXT) exp_2_.lo expm1_.$(OBJEXT) \ +expm1_.lo extract_.$(OBJEXT) extract_.lo factorial_.$(OBJEXT) \ +factorial_.lo fma_.$(OBJEXT) fma_.lo get_str_.$(OBJEXT) get_str_.lo \ +gmp_op_.$(OBJEXT) gmp_op_.lo hypot_.$(OBJEXT) hypot_.lo \ +i_ceil_exp2_.$(OBJEXT) i_ceil_exp2_.lo i_ceil_log2_.$(OBJEXT) \ +i_ceil_log2_.lo i_floor_log2_.$(OBJEXT) i_floor_log2_.lo \ init_.$(OBJEXT) init_.lo init2_.$(OBJEXT) init2_.lo inp_str_.$(OBJEXT) \ inp_str_.lo isinf_.$(OBJEXT) isinf_.lo isinteger_.$(OBJEXT) \ isinteger_.lo isnan_.$(OBJEXT) isnan_.lo isnum_.$(OBJEXT) isnum_.lo \ -log_.$(OBJEXT) log_.lo log1p_.$(OBJEXT) log1p_.lo log2_.$(OBJEXT) \ -log2_.lo log_base_10_.$(OBJEXT) log_base_10_.lo log_base_2_.$(OBJEXT) \ -log_base_2_.lo minmax_.$(OBJEXT) minmax_.lo mpz_set_fr_.$(OBJEXT) \ -mpz_set_fr_.lo mul_.$(OBJEXT) mul_.lo mul_2exp_.$(OBJEXT) mul_2exp_.lo \ -mul_ui_.$(OBJEXT) mul_ui_.lo neg_.$(OBJEXT) neg_.lo out_str_.$(OBJEXT) \ -out_str_.lo pi_.$(OBJEXT) pi_.lo pow_.$(OBJEXT) pow_.lo \ -pow_si_.$(OBJEXT) pow_si_.lo pow_ui_.$(OBJEXT) pow_ui_.lo \ +log_.$(OBJEXT) log_.lo log10_.$(OBJEXT) log10_.lo log1p_.$(OBJEXT) \ +log1p_.lo log2_.$(OBJEXT) log2_.lo minmax_.$(OBJEXT) minmax_.lo \ +mpz_set_fr_.$(OBJEXT) mpz_set_fr_.lo mul_.$(OBJEXT) mul_.lo \ +mul_2exp_.$(OBJEXT) mul_2exp_.lo mul_2si_.$(OBJEXT) mul_2si_.lo \ +mul_2ui_.$(OBJEXT) mul_2ui_.lo mul_ui_.$(OBJEXT) mul_ui_.lo \ +neg_.$(OBJEXT) neg_.lo out_str_.$(OBJEXT) out_str_.lo pow_.$(OBJEXT) \ +pow_.lo pow_si_.$(OBJEXT) pow_si_.lo pow_ui_.$(OBJEXT) pow_ui_.lo \ print_raw_.$(OBJEXT) print_raw_.lo print_rnd_mode_.$(OBJEXT) \ print_rnd_mode_.lo random_.$(OBJEXT) random_.lo random2_.$(OBJEXT) \ -random2_.lo reldiff_.$(OBJEXT) reldiff_.lo rnd_mode_.$(OBJEXT) \ -rnd_mode_.lo round_.$(OBJEXT) round_.lo save_expo_.$(OBJEXT) \ -save_expo_.lo set_.$(OBJEXT) set_.lo set_d_.$(OBJEXT) set_d_.lo \ -set_dfl_prec_.$(OBJEXT) set_dfl_prec_.lo set_f_.$(OBJEXT) set_f_.lo \ -set_prc_raw_.$(OBJEXT) set_prc_raw_.lo set_prec_.$(OBJEXT) set_prec_.lo \ -set_q_.$(OBJEXT) set_q_.lo set_rnd_.$(OBJEXT) set_rnd_.lo \ -set_si_.$(OBJEXT) set_si_.lo set_str_.$(OBJEXT) set_str_.lo \ -set_str_raw_.$(OBJEXT) set_str_raw_.lo set_ui_.$(OBJEXT) set_ui_.lo \ -set_z_.$(OBJEXT) set_z_.lo sin_.$(OBJEXT) sin_.lo sinh_.$(OBJEXT) \ -sinh_.lo sqrt_.$(OBJEXT) sqrt_.lo sqrt_ui_.$(OBJEXT) sqrt_ui_.lo \ -sub_.$(OBJEXT) sub_.lo sub1_.$(OBJEXT) sub1_.lo sub_ui_.$(OBJEXT) \ +random2_.lo reldiff_.$(OBJEXT) reldiff_.lo rint_.$(OBJEXT) rint_.lo \ +rnd_mode_.$(OBJEXT) rnd_mode_.lo round_prec_.$(OBJEXT) round_prec_.lo \ +save_expo_.$(OBJEXT) save_expo_.lo set_.$(OBJEXT) set_.lo \ +set_d_.$(OBJEXT) set_d_.lo set_dfl_prec_.$(OBJEXT) set_dfl_prec_.lo \ +set_f_.$(OBJEXT) set_f_.lo set_prc_raw_.$(OBJEXT) set_prc_raw_.lo \ +set_prec_.$(OBJEXT) set_prec_.lo set_q_.$(OBJEXT) set_q_.lo \ +set_rnd_.$(OBJEXT) set_rnd_.lo set_si_.$(OBJEXT) set_si_.lo \ +set_str_.$(OBJEXT) set_str_.lo set_str_raw_.$(OBJEXT) set_str_raw_.lo \ +set_ui_.$(OBJEXT) set_ui_.lo set_z_.$(OBJEXT) set_z_.lo sin_.$(OBJEXT) \ +sin_.lo sinh_.$(OBJEXT) sinh_.lo sqrt_.$(OBJEXT) sqrt_.lo \ +sqrt_ui_.$(OBJEXT) sqrt_ui_.lo sub_.$(OBJEXT) sub_.lo sub1_.$(OBJEXT) \ +sub1_.lo sub_one_ulp_.$(OBJEXT) sub_one_ulp_.lo sub_ui_.$(OBJEXT) \ sub_ui_.lo swap_.$(OBJEXT) swap_.lo tan_.$(OBJEXT) tan_.lo \ -tanh_.$(OBJEXT) tanh_.lo trunc_.$(OBJEXT) trunc_.lo ui_div_.$(OBJEXT) \ -ui_div_.lo ui_pow_.$(OBJEXT) ui_pow_.lo ui_pow_ui_.$(OBJEXT) \ -ui_pow_ui_.lo ui_sub_.$(OBJEXT) ui_sub_.lo urandomb_.$(OBJEXT) \ -urandomb_.lo : $(ANSI2KNR) +tanh_.$(OBJEXT) tanh_.lo ui_div_.$(OBJEXT) ui_div_.lo ui_pow_.$(OBJEXT) \ +ui_pow_.lo ui_pow_ui_.$(OBJEXT) ui_pow_ui_.lo ui_sub_.$(OBJEXT) \ +ui_sub_.lo urandomb_.$(OBJEXT) urandomb_.lo : $(ANSI2KNR) mpfr.info: mpfr.texi mpfr.dvi: mpfr.texi diff --git a/mpfr/README b/mpfr/README index f6bf86927..9a2e15f62 100644 --- a/mpfr/README +++ b/mpfr/README @@ -1,15 +1,27 @@ -The mpfr functions have been removed from the public GMP 4.0 -release. This was made since paperwork was not ready in -time for the release. The mpfr developers also wanted to -address some known issues, before a new mpfr is released -with GMP. +The MPFR distribution contains the following files: -While we could have kept the old mpfr code that was included -with GMP 3, the mpfr developers felt that that code is -obsolete. -If you need to use the mpfr functions now, please see: -<http://www.mpfr.org/>. - -We expect that the next GMP release (4.1) or a possible -patch release (4.0.1) will again include mpfr. +AUTHORS - the authors of the library +BUGS - bugs in MPFR - please read this file! +COPYING - the license under which the MPFR library is distributed +ChangeLog - the log of changes +INSTALL - how to install MPFR (see also mpfr.texi) +Makefile* - files for building the library +NEWS - new features with respect to previous versions +README - this file +TODO - what remains to do (any help is welcome!) +ac* - automatic configuration files +*.c - source files +config* - configuration files +cputime.h - header file for timings +install* - installation files +missing - auxiliary installation file +mkinst* - auxiliary installation file +mpf2mpfr.h - header file for compatibility with MPF +mpfr-impl.h - internal header file for MPFR +mpfr.h - external header file for MPFR +mpfr-test.h - header file for test files +mpfr.info - info file for MPFR +mpfr.texi - texinfo documentation for MPFR +tests/ - test directory +texinfo.tex - TeX macros to handle mpfr.texi @@ -13,12 +13,16 @@ Installation: New functions to implement: +- those from LIA: missing secant, cosecant, cotangent (trigo/hyperbolic) + Rounding: Efficiency: Miscellaneous: +- initialize variables to signalling NaN (TG) + - change Library GPL to Lesser GPL, and mention INRIA and/or SPACES - rename mpf2mpfr.h to gmp-mpf2mpfr.h? @@ -54,3 +58,12 @@ i.e.0.10101011100001010011001101100101110011101110010001011000000000000000000000 (PUTOT Sylvie <sputot@aigle.saclay.cea.fr>, Tue, 20 Mar 2001) - check correctness of +/-0 - +/-0 with different rounding modes. + +- rename mpz_set_fr to mpfr_get_mantissa_exp. + (Kevin Ryde <user42@zip.com.au>, 22 Jan 2002) + (Vincent Lefevre, 03 Feb 2002) + +- rewrite mpfr_get_str and mpfr_set_str to use mpn_get_str and mpn_set_str. + (Torbjorn Granlund <tege@swox.com>, 30 Jan 2002) + +- mpfr_pow isn't completely specified (concerning signed zeros). diff --git a/mpfr/acos.c b/mpfr/acos.c new file mode 100644 index 000000000..1a26a25f0 --- /dev/null +++ b/mpfr/acos.c @@ -0,0 +1,124 @@ +/* mpfr_acos -- arc-cosinus of a floating-point number + +Copyright (C) 2001 Free Software Foundation. + +This file is part of the MPFR Library, and was contributed by Mathieu Dutour. + +The 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 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode) +{ + mpfr_t xp; + mpfr_t arcc; + + int signe, suplement; + + mpfr_t tmp; + int Prec; + int prec_acos; + int good = 0; + int realprec; + int compared; + int inexact = 0; + + /* Trivial cases */ + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) + { + MPFR_SET_NAN(acos); + MPFR_RET_NAN; + } + + /* Set x_p=|x| */ + signe = MPFR_SIGN(x); + mpfr_init2 (xp, MPFR_PREC(x)); + mpfr_abs (xp, x, rnd_mode); + + compared = mpfr_cmp_ui (xp, 1); + + if (compared > 0) /* acos(x) = NaN for x > 1 */ + { + MPFR_SET_NAN(acos); + MPFR_RET_NAN; + } + + if (compared == 0) + { + if (signe > 0) /* acos(+1) = 0 */ + return mpfr_set_ui (acos, 0, rnd_mode); + else /* acos(-1) = Pi */ + { + mpfr_const_pi (acos, rnd_mode); + return 1; /* inexact */ + } + } + + if (MPFR_IS_ZERO(x)) /* acos(0)=Pi/2 */ + { + mpfr_const_pi (acos, rnd_mode); + MPFR_EXP(acos)--; + return 1; /* inexact */ + } + + prec_acos = MPFR_PREC(acos); + mpfr_ui_sub (xp, 1, xp, GMP_RNDD); + + if (signe > 0) + suplement = 2 - 2 * MPFR_EXP(xp); + else + suplement = 2 - MPFR_EXP(xp); + + realprec = prec_acos + 10; + + while (!good) + { + Prec = realprec+suplement; + + /* Initialisation */ + mpfr_init2 (tmp, Prec); + mpfr_init2 (arcc, Prec); + + mpfr_mul (tmp, x, x, GMP_RNDN); + mpfr_ui_sub (tmp, 1, tmp, GMP_RNDN); + mpfr_sqrt (tmp, tmp, GMP_RNDN); + mpfr_div (tmp, x, tmp, GMP_RNDN); + mpfr_atan (arcc, tmp, GMP_RNDN); + mpfr_const_pi (tmp, GMP_RNDN); + mpfr_div_2ui (tmp, tmp, 1, GMP_RNDN); + mpfr_sub (arcc, tmp, arcc, GMP_RNDN); + + if (mpfr_can_round (arcc, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(acos))) + { + inexact = mpfr_set (acos, arcc, rnd_mode); + good = 1; + } + else + realprec += _mpfr_ceil_log2 ((double) realprec); + + mpfr_clear (tmp); + mpfr_clear (arcc); + } + + mpfr_clear (xp); + return inexact; +} diff --git a/mpfr/acosh.c b/mpfr/acosh.c index 6953b9b37..9a73d158e 100644 --- a/mpfr/acosh.c +++ b/mpfr/acosh.c @@ -1,6 +1,6 @@ /* mpfr_acosh -- Inverse Hyperbolic Cosine of Unsigned Integer Number -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -39,7 +39,7 @@ mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } comp=mpfr_cmp_ui(x,1); @@ -47,22 +47,22 @@ mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode) if(comp < 0) { MPFR_SET_NAN(y); - return(1); + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); if(comp == 0) { MPFR_SET_ZERO(y); /* acosh(1) = 0 */ - return(0); + MPFR_SET_POS(y); + MPFR_RET(0); } if (MPFR_IS_INF(x)) { MPFR_SET_INF(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 1; + MPFR_SET_POS(y); + MPFR_RET(0); } MPFR_CLEAR_INF(y); diff --git a/mpfr/add.c b/mpfr/add.c index f35f72b18..aa91104e0 100644 --- a/mpfr/add.c +++ b/mpfr/add.c @@ -87,33 +87,7 @@ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) if (MPFR_SIGN(b) != MPFR_SIGN(c)) { /* signs differ, it's a subtraction */ - if (MPFR_EXP(b) < MPFR_EXP(c)) - { - return mpfr_sub1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); - } - else if (MPFR_EXP(b) > MPFR_EXP(c)) - { - return mpfr_sub1(a, b, c, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); - } - else - { /* MPFR_EXP(b) == MPFR_EXP(c) */ - int d = mpfr_cmp_abs(b,c); - if (d == 0) - { - if (rnd_mode == GMP_RNDD) - MPFR_SET_NEG(a); - else - MPFR_SET_POS(a); - MPFR_SET_ZERO(a); - MPFR_RET(0); - } - else if (d > 0) - return mpfr_sub1(a, b, c, rnd_mode, 0); - else - return mpfr_sub1(a, c, b, rnd_mode, 0); - } + return mpfr_sub1(a, b, c, rnd_mode, 0); } else { /* signs are equal, it's an addition */ diff --git a/mpfr/add1.c b/mpfr/add1.c index 2c2cd39f0..09a41a032 100644 --- a/mpfr/add1.c +++ b/mpfr/add1.c @@ -25,9 +25,9 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -/* signs of b and c are supposed equal, +/* compute sign(b) * (|b| + |c|) diff_exp is the difference between the exponents of b and c, - which is supposed >= 0 */ + which is >= 0 */ int mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, @@ -42,7 +42,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_NOTZERO(b)); MPFR_ASSERTN(MPFR_IS_FP(c) && MPFR_NOTZERO(c)); - + TMP_MARK(marker); ap = MPFR_MANT(a); bp = MPFR_MANT(b); @@ -50,14 +50,14 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, if (ap == bp) { - bp = (mp_ptr) TMP_ALLOC(MPFR_ABSSIZE(b) * BYTES_PER_MP_LIMB); + bp = (mp_ptr) TMP_ALLOC((size_t) MPFR_ABSSIZE(b) * BYTES_PER_MP_LIMB); MPN_COPY (bp, ap, MPFR_ABSSIZE(b)); if (ap == cp) { cp = bp; } } else if (ap == cp) { - cp = (mp_ptr) TMP_ALLOC (MPFR_ABSSIZE(c) * BYTES_PER_MP_LIMB); + cp = (mp_ptr) TMP_ALLOC ((size_t) MPFR_ABSSIZE(c) * BYTES_PER_MP_LIMB); MPN_COPY(cp, ap, MPFR_ABSSIZE(c)); } @@ -210,7 +210,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, /* determine rounding and sticky bits (and possible carry) */ - difw = an - diff_exp / BITS_PER_MP_LIMB; + difw = (mp_exp_t) an - (mp_exp_t) (diff_exp / BITS_PER_MP_LIMB); /* difw is the number of limbs from b (regarded as having an infinite precision) that have already been combined with c; -n if the next n limbs from b won't be combined with c. */ @@ -454,7 +454,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, { mp_limb_t cc; - cc = difs ? (/*MPFR_ASSERTN(ck < cn),*/ + cc = difs ? (MPFR_ASSERTN(ck < cn), cp[ck] << (BITS_PER_MP_LIMB - difs)) : cp[--ck]; if (rb < 0) { diff --git a/mpfr/add_one_ulp.c b/mpfr/add_one_ulp.c new file mode 100644 index 000000000..a889ea226 --- /dev/null +++ b/mpfr/add_one_ulp.c @@ -0,0 +1,56 @@ +/* mpfr_add_one_ulp -- add one unit in last place + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +/* sets x to x+sign(x)*ulp(x) */ +int +mpfr_add_one_ulp (mpfr_ptr x, mp_rnd_t rnd_mode) +{ + mp_size_t xn; + int sh; + mp_limb_t *xp; + + if (MPFR_IS_NAN(x)) + MPFR_RET_NAN; + + if (MPFR_IS_INF(x) || MPFR_IS_ZERO(x)) + return 0; + + xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB; + sh = xn * BITS_PER_MP_LIMB - MPFR_PREC(x); + xp = MPFR_MANT(x); + if (mpn_add_1 (xp, xp, xn, MP_LIMB_T_ONE << sh)) /* got 1.0000... */ + { + mp_exp_t exp = MPFR_EXP(x); + if (exp == __mpfr_emax) + return mpfr_set_overflow(x, rnd_mode, MPFR_SIGN(x)); + else + { + MPFR_EXP(x)++; + xp[xn-1] = MP_LIMB_T_HIGHBIT; + } + } + return 0; +} diff --git a/mpfr/add_ui.c b/mpfr/add_ui.c index eb1dfdcbf..fb9526034 100644 --- a/mpfr/add_ui.c +++ b/mpfr/add_ui.c @@ -1,6 +1,6 @@ /* mpfr_add_ui -- add a floating-point number with a machine integer -Copyright (C) 2000-2001 Free Software Foundation. +Copyright (C) 2000-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -35,22 +34,18 @@ mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) mpfr_t uu; mp_limb_t up[1]; unsigned long cnt; - int inex_add, inex_cr; + int inex; MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1); count_leading_zeros(cnt, (mp_limb_t) u); *up = (mp_limb_t) u << cnt; - MPFR_EXP(uu) = BITS_PER_MP_LIMB-cnt; + MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt; /* Optimization note: Exponent operations may be removed if mpfr_add works even when uu is out-of-range. */ mpfr_save_emin_emax(); - inex_add = mpfr_add(y, x, uu, rnd_mode); - mpfr_restore_emin_emax(); /* flags are restored too */ - inex_cr = mpfr_check_range(y, rnd_mode); - if (inex_cr) - return inex_cr; /* underflow or overflow */ - MPFR_RET(inex_add); + inex = mpfr_add(y, x, uu, rnd_mode); + MPFR_RESTORE_RET(inex, y, rnd_mode); } else return mpfr_set (y, x, rnd_mode); diff --git a/mpfr/agm.c b/mpfr/agm.c index b87ff9de3..12638c500 100644 --- a/mpfr/agm.c +++ b/mpfr/agm.c @@ -1,6 +1,6 @@ /* mpfr_agm -- arithmetic-geometric mean of two floating-point numbers -Copyright (C) 1999, 2001 Free Software Foundation. +Copyright (C) 1999-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -19,57 +19,11 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" #include "mpfr-impl.h" -/* returns ceil(log(d)/log(2)) */ -long -_mpfr_ceil_log2 (double d) -{ - long exp; - union ieee_double_extract x; - - x.d = d; - exp = x.s.exp - 1023; - x.s.exp = 1023; /* value for 1 <= d < 2 */ - if (x.d != 1.0) exp++; - return exp; -} - -/* returns floor(log(d)/log(2)) */ -long -_mpfr_floor_log2 (double d) -{ - union ieee_double_extract x; - - x.d = d; - return (long) x.s.exp - 1023; -} - -/* returns y >= 2^d */ -double -_mpfr_ceil_exp2 (double d) -{ - long exp; - union ieee_double_extract x; - - exp = (long) d; - if (d != (double) exp) exp++; - /* now exp = ceil(d) */ - x.d = 1.0; - if (exp < -1022) exp = -1022; - else if (exp > 1024) { - fprintf (stderr, "Overflow in _mpfr_ceil_exp2\n"); - exit (1); - } - x.s.exp = 1023 + exp; - return x.d; -} - void mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) { @@ -79,11 +33,14 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) mp_limb_t *up, *vp, *tmpp, *tmpup, *tmpvp, *ap, *bp; mpfr_t u, v, tmp, tmpu, tmpv, a, b; TMP_DECL(marker1); + { + TMP_DECL(marker2); /* If a or b is NaN, the result is NaN */ if (MPFR_IS_NAN(op1) || MPFR_IS_NAN(op2)) { MPFR_SET_NAN(r); + __mpfr_flags |= MPFR_FLAGS_NAN; return; } @@ -91,6 +48,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) if ((MPFR_SIGN(op1) < 0) || (MPFR_SIGN(op2) < 0)) { MPFR_SET_NAN(r); + __mpfr_flags |= MPFR_FLAGS_NAN; return; } @@ -124,8 +82,6 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) s=(p-1)/BITS_PER_MP_LIMB+1; MPFR_INIT(ap, a, p, s); MPFR_INIT(bp, b, p, s); - { - TMP_DECL(marker2); TMP_MARK(marker2); MPFR_INIT(up, u, p, s); MPFR_INIT(vp, v, p, s); @@ -162,9 +118,8 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) /* Main loop */ while (go_on) { - int err, eq, can_round; - - eq=0; + int err, can_round; + mp_prec_t eq; err=1 + (int) ((3.0/2.0*(double)_mpfr_ceil_log2((double)p)+1.0)*_mpfr_ceil_exp2(-(double)p) +3.0*_mpfr_ceil_exp2(-2.0*(double)p*uo/(vo-uo))); @@ -176,18 +131,16 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) } /* Calculus of un and vn */ - while (eq<=p-2) { - mpfr_mul(tmp,u,v,GMP_RNDN); - mpfr_sqrt (tmpu, tmp, GMP_RNDN); - mpfr_add(tmp,u,v,GMP_RNDN); - mpfr_div_2exp(tmpv,tmp,1,GMP_RNDN); - mpfr_set(u,tmpu,GMP_RNDN); - mpfr_set(v,tmpv,GMP_RNDN); - if (mpfr_cmp(v,u) >= 0) - eq = mpfr_cmp2(v,u); - else - eq = mpfr_cmp2(u,v); - } + do + { + mpfr_mul(tmp, u, v, GMP_RNDN); + mpfr_sqrt (tmpu, tmp, GMP_RNDN); + mpfr_add(tmp, u, v, GMP_RNDN); + mpfr_div_2ui(tmpv, tmp, 1, GMP_RNDN); + mpfr_set(u, tmpu, GMP_RNDN); + mpfr_set(v, tmpv, GMP_RNDN); + } + while (mpfr_cmp2(u, v, &eq) != 0 && eq <= p - 2); /* Roundability of the result */ can_round=mpfr_can_round(v,p-err-3,GMP_RNDN,rnd_mode,q); @@ -222,4 +175,3 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode) return ; } - diff --git a/mpfr/asin.c b/mpfr/asin.c index 27d15af2e..95fd59a1c 100644 --- a/mpfr/asin.c +++ b/mpfr/asin.c @@ -43,10 +43,10 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) int compared; /* Trivial cases */ - if (MPFR_IS_NAN(x)) + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) { MPFR_SET_NAN(asin); - return 1; + MPFR_RET_NAN; } /* Set x_p=|x| */ @@ -54,7 +54,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_init2 (xp, MPFR_PREC(x)); mpfr_set (xp, x, rnd_mode); if (signe == -1) - MPFR_CHANGE_SIGN(xp); + MPFR_CHANGE_SIGN(xp); compared = mpfr_cmp_ui (xp, 1); @@ -62,7 +62,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) { MPFR_SET_NAN(asin); mpfr_clear(xp); - return 1; + MPFR_RET_NAN; } if (compared == 0) /* x = 1 or x = -1 */ @@ -82,7 +82,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) return 1; /* inexact */ } - if (!MPFR_NOTZERO(x)) /* x = 0 */ + if (MPFR_IS_ZERO(x)) /* x = 0 */ { mpfr_set_ui (asin, 0, GMP_RNDN); mpfr_clear(xp); diff --git a/mpfr/asinh.c b/mpfr/asinh.c index a4ab317af..ac6de2595 100644 --- a/mpfr/asinh.c +++ b/mpfr/asinh.c @@ -1,6 +1,6 @@ /* mpfr_asinh -- Inverse Hyperbolic Sinus of Unsigned Integer Number -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -29,51 +29,45 @@ MA 02111-1307, USA. */ asinh= ln(x+sqrt(x^2+1)) */ int -mpfr_asinh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) +mpfr_asinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) { - int inexact =0; + int inexact; mpfr_t x; int flag_neg=0; + mp_prec_t Nx; - mp_prec_t Nx=MPFR_PREC(xt); /* Precision of input variable */ - mpfr_init2(x,Nx); - mpfr_set(x,xt,GMP_RNDN); - - if (MPFR_SIGN(x) < 0) - { - MPFR_CHANGE_SIGN(x); - flag_neg=1; - } - - if (MPFR_IS_NAN(x)) + if (MPFR_IS_NAN(xt)) { MPFR_SET_NAN(y); - mpfr_clear(x); - return 1; + MPFR_RET_NAN; } + MPFR_CLEAR_NAN(y); - - if (MPFR_IS_INF(x)) + if (MPFR_IS_INF(xt)) { MPFR_SET_INF(y); - MPFR_SET_SAME_SIGN(y,x); - if(flag_neg) - MPFR_CHANGE_SIGN(y); - mpfr_clear(x); - return 1; + MPFR_SET_SAME_SIGN(y, xt); + MPFR_RET(0); } MPFR_CLEAR_INF(y); - if(!MPFR_NOTZERO(x)) + if (MPFR_IS_ZERO(xt)) { MPFR_SET_ZERO(y); /* asinh(0) = 0 */ - MPFR_SET_SAME_SIGN(y,x); - if(flag_neg) - MPFR_CHANGE_SIGN(y); - mpfr_clear(x); - return 0; + MPFR_SET_SAME_SIGN(y, xt); + MPFR_RET(0); + } + + Nx = MPFR_PREC(xt); /* Precision of input variable */ + mpfr_init2(x, Nx); + mpfr_set(x, xt, GMP_RNDN); + + if (MPFR_SIGN(x) < 0) + { + MPFR_CHANGE_SIGN(x); + flag_neg=1; } /* General case */ @@ -132,5 +126,5 @@ mpfr_asinh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) mpfr_clear(te); } mpfr_clear(x); - return inexact; + MPFR_RET(inexact); } diff --git a/mpfr/atan.c b/mpfr/atan.c index 1c26c46e8..94f410f2b 100644 --- a/mpfr/atan.c +++ b/mpfr/atan.c @@ -78,7 +78,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) int realprec; int estimated_delta; /* calculation of the floor */ - int exptol; + mp_exp_t exptol; int N0; int logn; @@ -87,11 +87,12 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(arctangent); - return 1; + MPFR_RET_NAN; } if (MPFR_IS_INF(x)) { + MPFR_CLEAR_FLAGS(arctangent); if (MPFR_SIGN(x) > 0) /* arctan(+inf) = Pi/2 */ mpfr_const_pi (arctangent, rnd_mode); else /* arctan(-inf) = -Pi/2 */ @@ -106,9 +107,10 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) return 1; /* inexact */ } - if (!MPFR_NOTZERO(x)) + MPFR_CLEAR_FLAGS(arctangent); + if (MPFR_IS_ZERO(x)) { - mpfr_set_ui(arctangent, 0, GMP_RNDN); + mpfr_set_ui (arctangent, 0, GMP_RNDN); return 0; /* exact result */ } @@ -126,15 +128,15 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) if (comparaison == 0) { mpfr_init2(Pisur2, prec_arctan); mpfr_const_pi(Pisur2, rnd_mode); - mpfr_div_2exp(arctangent, Pisur2, 2, rnd_mode); + mpfr_div_2ui(arctangent, Pisur2, 2, rnd_mode); if (signe == -1) - MPFR_CHANGE_SIGN(arctangent); + MPFR_CHANGE_SIGN(arctangent); mpfr_clear(Pisur2); mpfr_clear(xp); return 0; /* Result correct */ } if (comparaison > 0) - suplement = 1; + suplement = 2; else suplement = 2-MPFR_EXP(xp); @@ -169,55 +171,55 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) if (comparaison > 0) { mpfr_init2(Pisur2, Prec); - mpfr_const_pi(Pisur2, GMP_RNDD); - mpfr_div_2exp(Pisur2, Pisur2, 1, GMP_RNDD); - mpfr_ui_div(sk, 1, xp, GMP_RNDD); + mpfr_const_pi(Pisur2, GMP_RNDN); + mpfr_div_2ui(Pisur2, Pisur2, 1, GMP_RNDN); + mpfr_ui_div(sk, 1, xp, GMP_RNDN); } else mpfr_set(sk, xp, GMP_RNDN); /* Assignation */ - mpfr_set_ui(tmp_arctan, 0, GMP_RNDN); + mpfr_set_ui (tmp_arctan, 0, GMP_RNDN); twopoweri = 1; for(i = 0; i <= N0; i++){ - mpfr_mul_2exp(tmp, sk, twopoweri, GMP_RNDD); + mpfr_mul_2ui(tmp, sk, twopoweri, GMP_RNDN); /* Calculation of trunc(tmp) --> mpz */ - mpfr_trunc(ukf, tmp); - exptol=mpz_set_fr(ukz, ukf); + mpfr_trunc (ukf, tmp); + exptol = mpfr_get_z_exp (ukz, ukf); if (exptol>0) - mpz_mul_2exp(ukz, ukz, exptol); + mpz_mul_2exp (ukz, ukz, exptol); else - mpz_tdiv_q_2exp(ukz, ukz, (unsigned long int) (-exptol)); + mpz_tdiv_q_2exp (ukz, ukz, (unsigned long int) (-exptol)); /* Calculation of arctan(Ak) */ mpz_mul(square, ukz, ukz); mpz_neg(square, square); mpfr_atan_aux(t_arctan, square, 2*twopoweri, N0 - i); - mpfr_set_z(Ak, ukz, GMP_RNDD); - mpfr_div_2exp(Ak, Ak, twopoweri, GMP_RNDD); - mpfr_mul(t_arctan, t_arctan, Ak, GMP_RNDD); + mpfr_set_z(Ak, ukz, GMP_RNDN); + mpfr_div_2ui(Ak, Ak, twopoweri, GMP_RNDN); + mpfr_mul(t_arctan, t_arctan, Ak, GMP_RNDN); /* Addition and iteration */ - mpfr_add(tmp_arctan, tmp_arctan, t_arctan, GMP_RNDD); + mpfr_add(tmp_arctan, tmp_arctan, t_arctan, GMP_RNDN); if (i<N0) { - mpfr_sub(tmp, sk, Ak, GMP_RNDD); - mpfr_mul(tmp2, sk, Ak, GMP_RNDU); - mpfr_add_ui(tmp2, tmp2, 1, GMP_RNDU); - mpfr_div(sk, tmp, tmp2, GMP_RNDD); + mpfr_sub(tmp, sk, Ak, GMP_RNDN); + mpfr_mul(tmp2, sk, Ak, GMP_RNDN); + mpfr_add_ui(tmp2, tmp2, 1, GMP_RNDN); + mpfr_div(sk, tmp, tmp2, GMP_RNDN); twopoweri <<= 1; } } if (comparaison > 0) { - mpfr_sub(arctgt, Pisur2, tmp_arctan, GMP_RNDD); + mpfr_sub(arctgt, Pisur2, tmp_arctan, GMP_RNDN); if (signe == -1) MPFR_CHANGE_SIGN(arctgt); } else { - mpfr_set(arctgt, tmp_arctan, GMP_RNDD); + mpfr_set(arctgt, tmp_arctan, GMP_RNDN); if (signe == -1) MPFR_CHANGE_SIGN(arctgt); } @@ -226,7 +228,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_set(tst, arctgt, rnd_mode); #endif - if (mpfr_can_round(arctgt, realprec, GMP_RNDD, rnd_mode, MPFR_PREC(arctangent))) + if (mpfr_can_round(arctgt, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(arctangent))) { mpfr_set(arctangent, arctgt, rnd_mode); good = 1; diff --git a/mpfr/atanh.c b/mpfr/atanh.c index b59f72659..5726a52af 100644 --- a/mpfr/atanh.c +++ b/mpfr/atanh.c @@ -1,6 +1,6 @@ /* mpfr_atanh -- Inverse Hyperbolic Tangente of Unsigned Integer Number -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -50,7 +50,7 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) { MPFR_SET_NAN(y); mpfr_clear(x); - return 1; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); @@ -62,19 +62,19 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) if(flag_neg) MPFR_CHANGE_SIGN(y); mpfr_clear(x); - return 0; + MPFR_RET(0); } MPFR_CLEAR_INF(y); - if(!MPFR_NOTZERO(x)) + if (MPFR_IS_ZERO(x)) { MPFR_SET_ZERO(y); /* atanh(0) = 0 */ MPFR_SET_SAME_SIGN(y,x); if(flag_neg) MPFR_CHANGE_SIGN(y); mpfr_clear(x); - return 0; + MPFR_RET(0); } /* General case */ @@ -110,9 +110,9 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) /* compute atanh */ mpfr_ui_sub(te,1,x,GMP_RNDU); /* (1-xt)*/ mpfr_add_ui(ti,x,1,GMP_RNDD); /* (xt+1)*/ - mpfr_div(te,ti,te,GMP_RNDN); /* (1+xt)/(1-xt)*/ - mpfr_log(te,te,GMP_RNDN); /* ln((1+xt)/(1-xt))*/ - mpfr_div_2exp(t,te,1,GMP_RNDN); /* (1/2)*ln((1+xt)/(1-xt))*/ + mpfr_div(te,ti,te,GMP_RNDN); /* (1+xt)/(1-xt)*/ + mpfr_log(te,te,GMP_RNDN); /* ln((1+xt)/(1-xt))*/ + mpfr_div_2ui(t,te,1,GMP_RNDN); /* (1/2)*ln((1+xt)/(1-xt))*/ /* estimation of the error see- algorithms.ps*/ /* err=Nt-_mpfr_ceil_log2(1+5*pow(2,1-MPFR_EXP(t)));*/ diff --git a/mpfr/ceil.c b/mpfr/ceil.c deleted file mode 100644 index 4ec951671..000000000 --- a/mpfr/ceil.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MPFR_CEIL 1 -#include "trunc.c" diff --git a/mpfr/cmp2.c b/mpfr/cmp2.c index 725cf5867..46df8c60c 100644 --- a/mpfr/cmp2.c +++ b/mpfr/cmp2.c @@ -25,72 +25,124 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -/* returns the number of cancelled bits when one subtracts abs(c) from abs(b). - Assumes |b| >= |c|, which implies MPFR_EXP(b)>=MPFR_EXP(c). - if |b| = |c|, returns prec(b). +/* Returns the number of canceled bits when one subtracts |c| from |b| + if |b| != |c|, and the sign. Assumes neither of b or c is NaN or +/- infinity. - In other terms mpfr_cmp2 (b, c) returns EXP(b) - EXP(b-c). + In other terms, if |b| != |c|, mpfr_cmp2 (b, c) returns + EXP(max(|b|,|c|)) - EXP(|b| - |c|). */ -mp_prec_t -mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c) + +int +mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mp_prec_t *cancel) { mp_limb_t *bp, *cp, bb, cc = 0, lastc = 0, dif, high_dif = 0; mp_size_t bn, cn; mp_exp_unsigned_t diff_exp; mp_prec_t res = 0; + int sign; MPFR_ASSERTN(MPFR_IS_FP(b)); MPFR_ASSERTN(MPFR_IS_FP(c)); - if (MPFR_IS_ZERO(c)) + /* Optimized case x - x */ + if (b == c) return 0; - MPFR_ASSERTN(MPFR_NOTZERO(b)); + if (MPFR_IS_ZERO(b)) + { + if (MPFR_IS_ZERO(c)) + return 0; - bp = MPFR_MANT(b); - cp = MPFR_MANT(c); + *cancel = 0; + return -1; + } - bn = (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB; - cn = (MPFR_PREC(c) - 1) / BITS_PER_MP_LIMB; + if (MPFR_IS_ZERO(c)) + { + *cancel = 0; + return 1; + } - MPFR_ASSERTN(MPFR_EXP(b) >= MPFR_EXP(c)); - diff_exp = (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c); - - if (diff_exp == 0) /* otherwise the shifted most significant limb of c - cannot match bp[bn] */ + if (MPFR_EXP(b) >= MPFR_EXP(c)) { - while (bn>=0 && cn>=0 && bp[bn] == cp[cn]) - { - bn--; - cn--; - res += BITS_PER_MP_LIMB; - } + sign = 1; + diff_exp = (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c); - if (bn < 0) /* b = c */ - return MPFR_PREC(b); + bp = MPFR_MANT(b); + cp = MPFR_MANT(c); - if (cn < 0) /* c discards exactly the upper part of b */ - { - unsigned int z; + bn = (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB; + cn = (MPFR_PREC(c) - 1) / BITS_PER_MP_LIMB; - while (bn>=0 && bp[bn]==0) - { - bn--; - res += BITS_PER_MP_LIMB; - } + if (diff_exp == 0) + { + while (bn >= 0 && cn >= 0 && bp[bn] == cp[cn]) + { + bn--; + cn--; + res += BITS_PER_MP_LIMB; + } + + if (bn < 0) + { + if (cn < 0) /* b = c */ + return 0; - if (bn < 0) /* b = c */ - return MPFR_PREC(b); + bp = cp; + bn = cn; + cn = -1; + sign = -1; + } - count_leading_zeros(z, bp[bn]); /* bp[bn] <> 0 */ - return res + z; - } + if (cn < 0) /* c discards exactly the upper part of b */ + { + unsigned int z; + + MPFR_ASSERTN(bn >= 0); + + while (bp[bn] == 0) + { + if (--bn < 0) /* b = c */ + return 0; + res += BITS_PER_MP_LIMB; + } + + count_leading_zeros(z, bp[bn]); /* bp[bn] <> 0 */ + *cancel = res + z; + return sign; + } + + MPFR_ASSERTN(bn >= 0); + MPFR_ASSERTN(cn >= 0); + MPFR_ASSERTN(bp[bn] != cp[cn]); + if (bp[bn] < cp[cn]) + { + mp_limb_t *tp; + mp_size_t tn; + + tp = bp; bp = cp; cp = tp; + tn = bn; bn = cn; cn = tn; + sign = -1; + } + } + } /* MPFR_EXP(b) >= MPFR_EXP(c) */ + else /* MPFR_EXP(b) < MPFR_EXP(c) */ + { + sign = -1; + diff_exp = (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b); + + bp = MPFR_MANT(c); + cp = MPFR_MANT(b); + + bn = (MPFR_PREC(c) - 1) / BITS_PER_MP_LIMB; + cn = (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB; } /* now we have removed the identical upper limbs of b and c - (can happen only when diff_exp = 0): bp[bn] > cc, bn>=0, cn>=0 */ + (can happen only when diff_exp = 0), and after the possible + swap, we have |b| > |c|: bp[bn] > cc, bn >= 0, cn >= 0 */ if (diff_exp < BITS_PER_MP_LIMB) { @@ -135,7 +187,10 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c) { res--; if (dif != 0) - return res; + { + *cancel = res; + return sign; + } } else /* high_dif = 0 */ { @@ -144,7 +199,10 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c) count_leading_zeros(z, dif); /* dif > 1 here */ res += z; if (dif != (MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - z - 1))) - return res; /* dif is not a power of two */ + { /* dif is not a power of two */ + *cancel = res; + return sign; + } } /* now result is res + (low(b) < low(c)) */ @@ -166,18 +224,26 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c) cn--; } if (bp[bn] != cc) - return res + (bp[bn] < cc); + { + *cancel = res + (bp[bn] < cc); + return sign; + } bn--; } if (bn < 0) { if (lastc != 0) - return res + 1; - while (cn >= 0 && cp[cn] == 0) - cn--; - return res + (cn >= 0); + res++; + else + { + while (cn >= 0 && cp[cn] == 0) + cn--; + if (cn >= 0) + res++; + } } - return res; /* remainder from c is 0 */ + *cancel = res; + return sign; } diff --git a/mpfr/euler.c b/mpfr/const_euler.c index eb36fe6e6..1ae448b81 100644 --- a/mpfr/euler.c +++ b/mpfr/const_euler.c @@ -106,7 +106,7 @@ mpfr_const_euler_S (mpfr_t x, unsigned long n) thus that the error on x is at most one ulp */ mpfr_set_z (x, s, GMP_RNDD); - mpfr_div_2exp (x, x, m, GMP_RNDD); + mpfr_div_2ui (x, x, m, GMP_RNDD); mpz_clear (a); mpz_clear (s); @@ -152,7 +152,7 @@ mpfr_const_euler_R (mpfr_t x, unsigned long n) exit (1); } mpfr_set_z (x, s, GMP_RNDD); /* exact */ - mpfr_div_2exp (x, x, m, GMP_RNDD); + mpfr_div_2ui (x, x, m, GMP_RNDD); /* now x = 1/n * sum(k!/(-n)^k, k=0..n-2) <= 1/n */ /* err(x) <= (n+1)/2^m <= (n+1)*exp(n)/2^PREC(x) */ diff --git a/mpfr/const_log2.c b/mpfr/const_log2.c new file mode 100644 index 000000000..e5d368684 --- /dev/null +++ b/mpfr/const_log2.c @@ -0,0 +1,186 @@ +/* mpfr_const_log2 -- compute natural logarithm of 2 + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include <stdio.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +mpfr_t __mpfr_const_log2; /* stored value of log(2) */ +int __mpfr_const_log2_prec=0; /* precision of stored value */ +mp_rnd_t __mpfr_const_log2_rnd; /* rounding mode of stored value */ + +static int mpfr_aux_log2 _PROTO ((mpfr_ptr, mpz_srcptr, int, int)); +static int mpfr_const_aux_log2 _PROTO ((mpfr_ptr, mp_rnd_t)); + +#define A +#define A1 1 +#define A2 1 +#undef B +#define C +#define C1 2 +#define C2 1 +#define NO_FACTORIAL +#undef R_IS_RATIONAL +#define GENERIC mpfr_aux_log2 +#include "generic.c" +#undef A +#undef A1 +#undef A2 +#undef NO_FACTORIAL +#undef GENERIC +#undef C +#undef C1 +#undef C2 + +static int +mpfr_const_aux_log2 (mpfr_ptr mylog, mp_rnd_t rnd_mode) +{ + int prec; + mpfr_t tmp1, tmp2, result,tmp3; + mpz_t cst; + int good = 0; + int logn; + int prec_i_want = MPFR_PREC(mylog); + int prec_x; + + mpz_init(cst); + logn = _mpfr_ceil_log2 ((double) MPFR_PREC(mylog)); + prec_x = prec_i_want + logn; + while (!good){ + prec = _mpfr_ceil_log2 ((double) prec_x); + mpfr_init2(tmp1, prec_x); + mpfr_init2(result, prec_x); + mpfr_init2(tmp2, prec_x); + mpfr_init2(tmp3, prec_x); + mpz_set_ui(cst, 1); + mpfr_aux_log2(tmp1, cst, 4, prec-2); + mpfr_div_2ui(tmp1, tmp1, 4, GMP_RNDD); + mpfr_mul_ui(tmp1, tmp1, 15, GMP_RNDD); + + mpz_set_ui(cst, 3); + mpfr_aux_log2(tmp2, cst, 7, prec-2); + mpfr_div_2ui(tmp2, tmp2, 7, GMP_RNDD); + mpfr_mul_ui(tmp2, tmp2, 5*3, GMP_RNDD); + mpfr_sub(result, tmp1, tmp2, GMP_RNDD); + + mpz_set_ui(cst, 13); + mpfr_aux_log2(tmp3, cst, 8, prec-2); + mpfr_div_2ui(tmp3, tmp3, 8, GMP_RNDD); + mpfr_mul_ui(tmp3, tmp3, 3*13, GMP_RNDD); + mpfr_sub(result, result, tmp3, GMP_RNDD); + + mpfr_clear(tmp1); + mpfr_clear(tmp2); + mpfr_clear(tmp3); + if (mpfr_can_round(result, prec_x, GMP_RNDD, rnd_mode, prec_i_want)){ + mpfr_set(mylog, result, rnd_mode); + good = 1; + } else + { + prec_x += logn; + } + mpfr_clear(result); + } + mpz_clear(cst); + return 0; +} + +/* Cross-over point from nai"ve Taylor series to binary splitting, + obtained experimentally on a Pentium II. Optimal value for + target machine should be determined by tuneup. */ +#define LOG2_THRESHOLD 25000 + +/* set x to log(2) rounded to precision MPFR_PREC(x) with direction rnd_mode + + use formula log(2) = sum(1/k/2^k, k=1..infinity) + + whence 2^N*log(2) = S(N) + R(N) + + where S(N) = sum(2^(N-k)/k, k=1..N-1) + and R(N) = sum(1/k/2^(k-N), k=N..infinity) < 2/N + + Let S'(N) = sum(floor(2^(N-k)/k), k=1..N-1) + + Then 2^N*log(2)-S'(N) <= N-1+2/N <= N for N>=2. +*/ +void +mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode) +{ + int N, k, precx; mpz_t s, t, u; + + precx = MPFR_PREC(x); + MPFR_CLEAR_FLAGS(x); + + /* has stored value enough precision ? */ + if (precx <= __mpfr_const_log2_prec) + { + if ((rnd_mode == __mpfr_const_log2_rnd) || + mpfr_can_round (__mpfr_const_log2, __mpfr_const_log2_prec - 1, + __mpfr_const_log2_rnd, rnd_mode, precx)) + { + mpfr_set (x, __mpfr_const_log2, rnd_mode); + return; + } + } + + /* need to recompute */ + if (precx < LOG2_THRESHOLD) /* use nai"ve Taylor series evaluation */ + { + /* the following was checked by exhaustive search to give a correct + result for all 4 rounding modes up to precx = 13500 */ + N = precx + 2 * _mpfr_ceil_log2 ((double) precx) + 1; + + mpz_init (s); /* set to zero */ + mpz_init (u); + mpz_init_set_ui (t, 1); + + /* use log(2) = sum((6*k-1)/(2*k^2-k)/2^(2*k+1), k=1..infinity) */ + mpz_mul_2exp (t, t, N-1); + for (k=1; k<=N/2; k++) + { + mpz_div_2exp (t, t, 2); + mpz_mul_ui (u, t, 6*k-1); + mpz_fdiv_q_ui (u, u, k*(2*k-1)); + mpz_add (s, s, u); + } + + mpfr_set_z (x, s, rnd_mode); + MPFR_EXP(x) -= N; + mpz_clear (s); + mpz_clear (t); + mpz_clear (u); + } + else /* use binary splitting method */ + mpfr_const_aux_log2(x, rnd_mode); + + /* store computed value */ + if (__mpfr_const_log2_prec == 0) + mpfr_init2 (__mpfr_const_log2, precx); + else + mpfr_set_prec (__mpfr_const_log2, precx); + + mpfr_set (__mpfr_const_log2, x, rnd_mode); + __mpfr_const_log2_prec = precx; + __mpfr_const_log2_rnd = rnd_mode; +} diff --git a/mpfr/pi.c b/mpfr/const_pi.c index 94ea9fb3c..edca47860 100644 --- a/mpfr/pi.c +++ b/mpfr/const_pi.c @@ -97,7 +97,7 @@ mpfr_pi_machin3 (mpfr_ptr mylog, mp_rnd_t rnd_mode) mpfr_sub(result, result, tmp4, GMP_RNDD); mpfr_add(result, result, tmp5, GMP_RNDD); mpfr_add(result, result, tmp6, GMP_RNDD); - mpfr_mul_2exp(result, result, 2, GMP_RNDD); + mpfr_mul_2ui(result, result, 2, GMP_RNDD); mpfr_clear(tmp1); mpfr_clear(tmp2); mpfr_clear(tmp3); diff --git a/mpfr/copysign.c b/mpfr/copysign.c index 1dd88dc2f..6a15ec0ce 100644 --- a/mpfr/copysign.c +++ b/mpfr/copysign.c @@ -1,6 +1,6 @@ /* mpfr_copysign -- Produce a value with the magnitude of x and sign of y -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -31,46 +30,13 @@ MA 02111-1307, USA. */ */ int -mpfr_copysign (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) +mpfr_copysign (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) { - - if (MPFR_IS_NAN(y)) - { - MPFR_SET_NAN(z); - return 1; - } - - if (MPFR_IS_NAN(x)) - { - MPFR_SET_NAN(z); - MPFR_SET_SAME_SIGN(z,y); - return 1; - } - - MPFR_CLEAR_NAN(z); - - if (MPFR_IS_INF(x)) { - - MPFR_SET_INF(z); - MPFR_SET_SAME_SIGN(z,y); - return 0; - } - - MPFR_CLEAR_INF(z); - - if (!MPFR_NOTZERO(x)) - { - MPFR_SET_ZERO(z); - MPFR_SET_SAME_SIGN(z,y); - return 0; - } - - /* GENERAL CASE*/ + if (MPFR_IS_NAN(y)) { - int inexact=0; - inexact =mpfr_set(z,x,rnd_mode); - MPFR_SET_SAME_SIGN(z,y); - return inexact; + MPFR_SET_NAN(z); + MPFR_RET_NAN; } - + else + return mpfr_set4(z, x, rnd_mode, MPFR_SIGN(y)); } diff --git a/mpfr/cos.c b/mpfr/cos.c index 02461cedc..dce32c0a0 100644 --- a/mpfr/cos.c +++ b/mpfr/cos.c @@ -1,6 +1,6 @@ /* mpfr_cos -- cosine of a floating-point number -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -30,16 +30,16 @@ static int mpfr_cos2_aux _PROTO ((mpfr_ptr, mpfr_srcptr)); int mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { - int K, precy, m, k, l, inexact; + int K0, K, precy, m, k, l, inexact; mpfr_t r, s; if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } - if (!MPFR_NOTZERO(x)) + if (MPFR_IS_ZERO(x)) { mpfr_set_ui (y, 1, GMP_RNDN); return 0; @@ -47,11 +47,9 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) precy = MPFR_PREC(y); - K = _mpfr_isqrt(precy / 2); - if (MPFR_EXP(x) > 0) - K += MPFR_EXP(x); + K0 = _mpfr_isqrt(precy / 2); /* we need at least K + log2(precy/K) extra bits */ - m = precy + 3 * K + 3; + m = precy + 3 * K0 + 3; mpfr_init2 (r, m); mpfr_init2 (s, m); @@ -59,7 +57,11 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) do { mpfr_mul (r, x, x, GMP_RNDU); /* err <= 1 ulp */ - mpfr_div_2exp (r, r, 2 * K, GMP_RNDN); /* r = (x/2^K)^2, err <= 1 ulp */ + + /* we need that |r| < 1 for mpfr_cos2_aux, i.e. up(x^2)/2^(2K) < 1 */ + K = K0 + MAX(MPFR_EXP(r), 0); + + mpfr_div_2ui (r, r, 2 * K, GMP_RNDN); /* r = (x/2^K)^2, err <= 1 ulp */ /* s <- 1 - r/2! + ... + (-1)^l r^l/(2l)! */ l = mpfr_cos2_aux (s, r); @@ -67,7 +69,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) for (k = 0; k < K; k++) { mpfr_mul (s, s, s, GMP_RNDU); /* err <= 2*olderr */ - mpfr_mul_2exp (s, s, 1, GMP_RNDU); /* err <= 4*olderr */ + mpfr_mul_2ui (s, s, 1, GMP_RNDU); /* err <= 4*olderr */ mpfr_sub_ui (s, s, 1, GMP_RNDN); } @@ -103,7 +105,7 @@ static int mpfr_cos2_aux (mpfr_ptr s, mpfr_srcptr r) { unsigned int l, b = 2; - int prec_t, m = MPFR_PREC(s); + long int prec_t, m = MPFR_PREC(s); mpfr_t t; MPFR_ASSERTN (MPFR_EXP(r) <= 0); @@ -111,7 +113,7 @@ mpfr_cos2_aux (mpfr_ptr s, mpfr_srcptr r) mpfr_set_ui (t, 1, GMP_RNDN); mpfr_set_ui(s, 1, GMP_RNDN); - for (l = 1; MPFR_EXP(t) >= -m; l++) + for (l = 1; MPFR_EXP(t) + m >= 0; l++) { mpfr_mul (t, t, r, GMP_RNDU); /* err <= (3l-1) ulp */ mpfr_div_ui (t, t, (2*l-1)*(2*l), GMP_RNDU); /* err <= 3l ulp */ @@ -126,8 +128,8 @@ mpfr_cos2_aux (mpfr_ptr s, mpfr_srcptr r) /* now 3l <= 2^b, we want 3l*ulp(t) <= 2^(-m) i.e. b+EXP(t)-PREC(t) <= -m */ prec_t = m + MPFR_EXP(t) + b; - if (prec_t > 0) - mpfr_round (t, GMP_RNDN, prec_t); + if (prec_t >= MPFR_PREC_MIN) + mpfr_round_prec (t, GMP_RNDN, prec_t); } mpfr_clear (t); diff --git a/mpfr/cosh.c b/mpfr/cosh.c index 98b0ede6e..a124585af 100644 --- a/mpfr/cosh.c +++ b/mpfr/cosh.c @@ -1,6 +1,6 @@ /* mpfr_cosh -- hyperbolic cosine -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -42,7 +42,7 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) if (MPFR_IS_NAN(xt)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); @@ -51,21 +51,16 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) MPFR_SET_INF(y); if (MPFR_SIGN(y) < 0) MPFR_CHANGE_SIGN(y); - return 0; + MPFR_RET(0); } MPFR_CLEAR_INF(y); - if(!MPFR_NOTZERO(xt)) - return mpfr_set_ui(y,1,rnd_mode); /* cosh(0) = 1 */ + if (MPFR_IS_ZERO(xt)) + return mpfr_set_ui(y,1,rnd_mode); /* cosh(0) = 1 */ mpfr_init2(x,Nxt); - mpfr_set(x,xt,GMP_RNDN); - - if(MPFR_SIGN(x)<0) - { - MPFR_CHANGE_SIGN(x); - } + mpfr_set4(x, xt, GMP_RNDN, 1); /* General case */ { @@ -104,7 +99,7 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) mpfr_exp(te,x,GMP_RNDD); /* exp(x) */ mpfr_ui_div(ti,1,te,GMP_RNDU); /* 1/exp(x) */ mpfr_add(t,te,ti,GMP_RNDN); /* exp(x) + 1/exp(x)*/ - mpfr_div_2exp(t,t,1,GMP_RNDN); /* 1/2(exp(x) + 1/exp(x))*/ + mpfr_div_2ui(t,t,1,GMP_RNDN); /* 1/2(exp(x) + 1/exp(x))*/ /* estimation of the error */ err=Nt-3; diff --git a/mpfr/dim.c b/mpfr/dim.c index 4715ba95d..39e981c8d 100644 --- a/mpfr/dim.c +++ b/mpfr/dim.c @@ -1,6 +1,6 @@ /* mpfr_dim -- dim of x, y -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -32,24 +31,22 @@ MA 02111-1307, USA. */ */ int -mpfr_dim (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) +mpfr_dim (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) { - - if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ) - { - MPFR_SET_NAN(z); - return 1; + if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y)) + { + MPFR_SET_NAN(z); + MPFR_RET_NAN; } - MPFR_CLEAR_NAN(z); - if(mpfr_cmp(x,y) > 0) - return mpfr_sub(z,x,y,rnd_mode); - else + MPFR_CLEAR_NAN(z); + + if (mpfr_cmp(x,y) > 0) + return mpfr_sub(z, x, y, rnd_mode); + else { MPFR_SET_ZERO(z); - if(MPFR_SIGN(z) < 0) - MPFR_CHANGE_SIGN(z); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } } - diff --git a/mpfr/div.c b/mpfr/div.c index 9f9b2850a..865cfdf23 100644 --- a/mpfr/div.c +++ b/mpfr/div.c @@ -19,8 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -53,62 +51,61 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode) * * **************************************************************************/ - if (MPFR_IS_NAN(u) || MPFR_IS_NAN(v)) - { - MPFR_SET_NAN(q); MPFR_RET_NAN; + if (MPFR_IS_NAN(u) || MPFR_IS_NAN(v)) + { + MPFR_SET_NAN(q); + MPFR_RET_NAN; } MPFR_CLEAR_NAN(q); - if (MPFR_IS_INF(u)) - { - if (MPFR_IS_INF(v)) - { - MPFR_SET_NAN(q); MPFR_RET_NAN; + sign_quotient = MPFR_SIGN(u) * MPFR_SIGN(v); + if (MPFR_SIGN(q) != sign_quotient) + MPFR_CHANGE_SIGN(q); + + if (MPFR_IS_INF(u)) + { + if (MPFR_IS_INF(v)) + { + MPFR_SET_NAN(q); + MPFR_RET_NAN; } else - { - MPFR_SET_INF(q); - if (MPFR_SIGN(q) != MPFR_SIGN(u) * MPFR_SIGN(v)) - MPFR_CHANGE_SIGN(q); - MPFR_RET(0); + { + MPFR_SET_INF(q); + MPFR_RET(0); } } else if (MPFR_IS_INF(v)) { - MPFR_CLEAR_INF(q); - MPFR_SET_ZERO(q); - if (MPFR_SIGN(q) != MPFR_SIGN(u) * MPFR_SIGN(v)) - MPFR_CHANGE_SIGN(q); - MPFR_RET(0); + MPFR_CLEAR_INF(q); + MPFR_SET_ZERO(q); + MPFR_RET(0); } MPFR_CLEAR_INF(q); /* clear Inf flag */ - if (!MPFR_NOTZERO(v)) + if (MPFR_IS_ZERO(v)) { - if (!MPFR_NOTZERO(u)) - { - MPFR_SET_NAN(q); MPFR_RET(1); + if (MPFR_IS_ZERO(u)) + { + MPFR_SET_NAN(q); + MPFR_RET_NAN; } else { - MPFR_SET_INF(q); - if (MPFR_SIGN(q) != MPFR_SIGN(v) * MPFR_SIGN(u)) - MPFR_CHANGE_SIGN(q); - MPFR_RET(0); + MPFR_SET_INF(q); + MPFR_RET(0); } } - - if (!MPFR_NOTZERO(u)) - { - MPFR_SET_ZERO(q); MPFR_RET(0); + + if (MPFR_IS_ZERO(u)) + { + MPFR_SET_ZERO(q); + MPFR_RET(0); } - sign_quotient = ((MPFR_SIGN(u) * MPFR_SIGN(v) > 0) ? 1 : -1); - if (sign_quotient * MPFR_SIGN(q) < 0) { MPFR_CHANGE_SIGN(q); } - /************************************************************************** * * * End of the part concerning special values. * @@ -234,8 +231,8 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode) * * * The attempt to use only part of u and v failed. We first compute a * * correcting term, then perform the full division. * - * Put u = uhi + ulo, v = vhi + vlo. We have uhi = vhi * rp + tp, * - * thus u - v * rp = tp + ulo - rp*vlo, that we shall divide by v. * + * Put u = uhi + ulo, v = vhi + vlo. We have uhi = vhi * qp + rp, * + * thus u - qp * v = rp + ulo - qp * vlo, that we shall divide by v. * * * **************************************************************************/ @@ -447,4 +444,3 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode) MPFR_RET(inex); } - diff --git a/mpfr/div_2exp.c b/mpfr/div_2exp.c index 68284f0a4..3a9f67e21 100644 --- a/mpfr/div_2exp.c +++ b/mpfr/div_2exp.c @@ -19,21 +19,17 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" #include "mpfr-impl.h" +/* Obsolete function, use mpfr_div_2ui or mpfr_div_2si instead. */ + +#undef mpfr_div_2exp + int mpfr_div_2exp (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mp_rnd_t rnd_mode) { - int inexact = 0; - - /* Important particular case */ - if (y != x) - inexact = mpfr_set (y, x, rnd_mode); - return ((MPFR_EXP(y) -= n) < __mpfr_emin) - ? mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y)) : inexact; + return mpfr_div_2ui (y, x, n, rnd_mode); } - diff --git a/mpfr/div_2si.c b/mpfr/div_2si.c new file mode 100644 index 000000000..d03a06b20 --- /dev/null +++ b/mpfr/div_2si.c @@ -0,0 +1,48 @@ +/* mpfr_div_2si -- divide a floating-point number by a power of two + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +mpfr_div_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) +{ + int inexact; + + inexact = y != x ? mpfr_set (y, x, rnd_mode) : 0; + + if (MPFR_IS_FP(y) && MPFR_NOTZERO(y)) + { + if (n > 0 && (__mpfr_emin > MPFR_EMAX_MAX - n || + MPFR_EXP(y) < __mpfr_emin + n)) + return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y)); + + if (n < 0 && (__mpfr_emax < MPFR_EMIN_MIN - n || + MPFR_EXP(y) > __mpfr_emax + n)) + return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y)); + + MPFR_EXP(y) -= n; + } + + return inexact; +} diff --git a/mpfr/div_2ui.c b/mpfr/div_2ui.c new file mode 100644 index 000000000..b69a9b874 --- /dev/null +++ b/mpfr/div_2ui.c @@ -0,0 +1,59 @@ +/* mpfr_div_2ui -- divide a floating-point number by a power of two + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +mpfr_div_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mp_rnd_t rnd_mode) +{ + int inexact; + + inexact = y != x ? mpfr_set (y, x, rnd_mode) : 0; + + if (MPFR_IS_FP(y) && MPFR_NOTZERO(y)) + { + /* n will have to be casted to long to make sure that the addition + and subtraction below (for overflow detection) are signed */ + while (n > LONG_MAX) + { + int inex2; + + n -= LONG_MAX; + inex2 = mpfr_div_2ui(y, y, LONG_MAX, rnd_mode); + if (inex2) + return inex2; /* underflow */ + } + + /* MPFR_EMAX_MAX - (long) n is signed and doesn't lead to an overflow; + the first test useful so that the real test can't lead to an + overflow. */ + if (__mpfr_emin > MPFR_EMAX_MAX - (long) n || + MPFR_EXP(y) < __mpfr_emin + (long) n) + return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y)); + + MPFR_EXP(y) -= (long) n; + } + + return inexact; +} diff --git a/mpfr/div_ui.c b/mpfr/div_ui.c index c3986f07d..69a44007f 100644 --- a/mpfr/div_ui.c +++ b/mpfr/div_ui.c @@ -1,6 +1,6 @@ /* mpfr_div_ui -- divide a floating-point number by a machine integer -Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -45,13 +45,12 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) if (MPFR_IS_INF(x)) { - MPFR_SET_INF(y); - if (MPFR_SIGN(y) * MPFR_SIGN(x) < 0) /* consider u=0 as +0 */ - MPFR_CHANGE_SIGN(y); - return 0; + MPFR_SET_INF(y); + MPFR_SET_SAME_SIGN(y, x); + MPFR_RET(0); } - if (u == 0) + if (u == 0) { if (MPFR_IS_ZERO(x)) /* 0/0 is NaN */ { @@ -59,19 +58,20 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) MPFR_RET_NAN; } else /* x/0 is Inf */ - { + { MPFR_SET_INF(y); MPFR_SET_SAME_SIGN(y, x); - return 0; + MPFR_RET(0); } } MPFR_CLEAR_INF(y); - + MPFR_SET_SAME_SIGN(y, x); + if (MPFR_IS_ZERO(x)) { MPFR_SET_ZERO(y); - return 0; + MPFR_RET(0); } TMP_MARK(marker); @@ -81,8 +81,6 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) xp = MPFR_MANT(x); yp = MPFR_MANT(y); MPFR_EXP(y) = MPFR_EXP(x); - if (MPFR_SIGN(x) * MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); dif = yn + 1 - xn; @@ -149,12 +147,12 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) case GMP_RNDU: if (MPFR_SIGN(y) > 0) - mpfr_add_one_ulp (y); + mpfr_add_one_ulp (y, rnd_mode); MPFR_RET(1); /* result is inexact */ case GMP_RNDD: if (MPFR_SIGN(y) < 0) - mpfr_add_one_ulp (y); + mpfr_add_one_ulp (y, rnd_mode); MPFR_RET(-1); /* result is inexact */ case GMP_RNDN: @@ -162,7 +160,7 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) MPFR_RET(-MPFR_SIGN(x)); else if (sh && d > (MP_LIMB_T_ONE << (sh - 1))) { - mpfr_add_one_ulp (y); + mpfr_add_one_ulp (y, rnd_mode); MPFR_RET(MPFR_SIGN(x)); } else /* sh = 0 or d = 1 << (sh-1) */ @@ -173,7 +171,7 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) */ if ((sh && inexact) || (!sh && (middle > 0)) || (*yp & (MP_LIMB_T_ONE << sh))) { - mpfr_add_one_ulp (y); + mpfr_add_one_ulp (y, rnd_mode); MPFR_RET(MPFR_SIGN(x)); } else diff --git a/mpfr/dump.c b/mpfr/dump.c index 017298e9a..74a7c90ca 100644 --- a/mpfr/dump.c +++ b/mpfr/dump.c @@ -33,14 +33,18 @@ mpfr_dump (mpfr_srcptr u, mp_rnd_t rnd_mode) mp_exp_t exp; char *str; - if (MPFR_IS_INF(u)) + if (MPFR_IS_NAN(u)) { - if (MPFR_SIGN(u) == 1) printf("Inf\n"); else printf("-Inf\n"); + printf ("NaN\n"); return; } - if (MPFR_IS_NAN(u)) + + if (MPFR_IS_INF(u)) { - printf("NaN\n"); + if (MPFR_SIGN(u) == 1) + printf ("Inf\n"); + else + printf ("-Inf\n"); return; } diff --git a/mpfr/exceptions.c b/mpfr/exceptions.c index 043c3140a..de171cba5 100644 --- a/mpfr/exceptions.c +++ b/mpfr/exceptions.c @@ -39,14 +39,10 @@ mpfr_get_emin (void) #undef mpfr_set_emin -/* this strangely written form avoids a powerpc64 gcc 3.0 -O2 bug */ int mpfr_set_emin (mp_exp_t exponent) { - if (exponent < MPFR_EMIN_MIN) - return 1; - - if (exponent <= MPFR_EMIN_MAX) + if (exponent >= MPFR_EMIN_MIN && exponent <= MPFR_EMIN_MAX) { __mpfr_emin = exponent; return 0; @@ -67,14 +63,10 @@ mpfr_get_emax (void) #undef mpfr_set_emax -/* this strangely written form avoids a powerpc64 gcc 3.0 -O2 bug */ int mpfr_set_emax (mp_exp_t exponent) { - if (exponent < MPFR_EMAX_MIN) - return 1; - - if (exponent <= MPFR_EMAX_MAX) + if (exponent >= MPFR_EMAX_MIN && exponent <= MPFR_EMAX_MAX) { __mpfr_emax = exponent; return 0; @@ -217,12 +209,15 @@ mpfr_set_overflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign) || (rnd_mode == GMP_RNDD && sign > 0)) { mp_size_t xn, i; + int sh; mp_limb_t *xp; MPFR_EXP(x) = __mpfr_emax; - xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB; + xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB; + sh = xn * BITS_PER_MP_LIMB - MPFR_PREC(x); xp = MPFR_MANT(x); - for (i = 0; i <= xn; i++) + xp[0] = MP_LIMB_T_MAX << sh; + for (i = 1; i < xn; i++) xp[i] = MP_LIMB_T_MAX; inex = -1; } diff --git a/mpfr/exp.c b/mpfr/exp.c index c2130880f..12be08919 100644 --- a/mpfr/exp.c +++ b/mpfr/exp.c @@ -1,6 +1,6 @@ /* mpfr_exp -- exponential of a floating-point number -Copyright (C) 1999-2001 Free Software Foundation. +Copyright (C) 1999-2002 Free Software Foundation. Contributed by the Spaces project. This file is part of the MPFR Library. @@ -44,36 +44,30 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); - if (MPFR_IS_INF(x)) - { + if (MPFR_IS_INF(x)) + { if (MPFR_SIGN(x) > 0) { MPFR_SET_INF(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); } else { MPFR_CLEAR_INF(y); MPFR_SET_ZERO(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); } - return 0; + MPFR_SET_POS(y); + MPFR_RET(0); } MPFR_CLEAR_INF(y); - - if (!MPFR_NOTZERO(x)) - { - mpfr_set_ui (y, 1, GMP_RNDN); - return 0; - } + + if (MPFR_IS_ZERO(x)) + return mpfr_set_ui (y, 1, GMP_RNDN); expx = MPFR_EXP(x); precy = MPFR_PREC(y); @@ -82,22 +76,12 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) x >= __mpfr_emax * log(2) */ d = mpfr_get_d (x); if (d >= (double) __mpfr_emax * LOG2) - { - MPFR_SET_INF(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 1; /* overflow */ - } + return mpfr_set_overflow(y, rnd_mode, 1); /* result is 0 when exp(x) < 1/2*2^(__mpfr_emin), i.e. x < (__mpfr_emin-1) * LOG2 */ if (d < ((double) __mpfr_emin - 1.0) * LOG2) - { - MPFR_SET_ZERO(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 1; /* underflow */ - } + return mpfr_set_underflow(y, rnd_mode, 1); /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */ if (expx < -precy) @@ -107,12 +91,12 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_set_ui (y, 1, rnd_mode); if (signx > 0 && rnd_mode == GMP_RNDU) { - mpfr_add_one_ulp (y); + mpfr_add_one_ulp (y, rnd_mode); return 1; } else if (signx < 0 && (rnd_mode == GMP_RNDD || rnd_mode == GMP_RNDZ)) { - mpfr_sub_one_ulp (y); + mpfr_sub_one_ulp (y, rnd_mode); return -1; } return -signx; diff --git a/mpfr/exp2.c b/mpfr/exp2.c index 3768778f5..8370510a1 100644 --- a/mpfr/exp2.c +++ b/mpfr/exp2.c @@ -1,6 +1,6 @@ /* mpfr_exp2 -- power of 2 function 2^y -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -37,35 +37,30 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x)) { - MPFR_SET_NAN(y); - return 1; + MPFR_SET_NAN(y); + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); if (MPFR_IS_INF(x)) { - if (MPFR_SIGN(x) < 0) + if (MPFR_SIGN(x) > 0) { - MPFR_SET_ZERO(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 0; + MPFR_SET_INF(y); } else { - MPFR_SET_INF(y); - if(MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 0; + MPFR_CLEAR_INF(y); + MPFR_SET_ZERO(y); } + MPFR_SET_POS(y); + MPFR_RET(0); } /* 2^0 = 1 */ - if(mpfr_cmp_ui(x,0)==0) - { - return mpfr_set_ui(y,1,rnd_mode); - } + if (MPFR_IS_ZERO(x)) + return mpfr_set_ui (y, 1, rnd_mode); /* General case */ { diff --git a/mpfr/exp3.c b/mpfr/exp3.c index 8441850b9..c56745eb0 100644 --- a/mpfr/exp3.c +++ b/mpfr/exp3.c @@ -110,7 +110,7 @@ mpfr_exp_rational (mpfr_ptr y, mpz_srcptr p, int r, int m) mpfr_set_z(y,S[0], GMP_RNDD); MPFR_EXP(y) += expo; - mpfr_div_2exp(y, y, r*(i-1),GMP_RNDN); + mpfr_div_2ui(y, y, r*(i-1),GMP_RNDN); for (i=0;i<=m;i++) { mpz_clear(P[i]); mpz_clear(S[i]); mpz_clear(ptoj[i]); } TMP_FREE (marker); return 0; @@ -151,7 +151,7 @@ mpfr_exp3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (ttt > 0) { shift_x = ttt; - mpfr_mul_2exp(x_copy,x,-ttt, GMP_RNDN); + mpfr_div_2ui(x_copy, x, ttt, GMP_RNDN); ttt = MPFR_EXP(x_copy); } realprec = MPFR_PREC(y)+logn; diff --git a/mpfr/exp_2.c b/mpfr/exp_2.c index 402919092..a8da4f4f9 100644 --- a/mpfr/exp_2.c +++ b/mpfr/exp_2.c @@ -143,7 +143,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) in order to get an upper bound of r = x-n*log(2) */ mpfr_const_log2 (s, (n>=0) ? GMP_RNDZ : GMP_RNDU); #ifdef DEBUG - printf("n=%d log(2)=",n); mpfr_print_raw(s); putchar('\n'); + printf("n=%d log(2)=",n); mpfr_print_binary(s); putchar('\n'); #endif mpfr_mul_ui (r, s, (n<0) ? -n : n, (n>=0) ? GMP_RNDZ : GMP_RNDU); if (n<0) mpfr_neg(r, r, GMP_RNDD); @@ -151,9 +151,9 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) #ifdef DEBUG printf("x=%1.20e\n",mpfr_get_d(x)); - printf(" ="); mpfr_print_raw(x); putchar('\n'); + printf(" ="); mpfr_print_binary(x); putchar('\n'); printf("r=%1.20e\n",mpfr_get_d(r)); - printf(" ="); mpfr_print_raw(r); putchar('\n'); + printf(" ="); mpfr_print_binary(r); putchar('\n'); #endif mpfr_sub(r, x, r, GMP_RNDU); if (MPFR_SIGN(r)<0) { /* initial approximation n was too large */ @@ -164,14 +164,14 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) } #ifdef DEBUG printf("x-r=%1.20e\n",mpfr_get_d(r)); - printf(" ="); mpfr_print_raw(r); putchar('\n'); + printf(" ="); mpfr_print_binary(r); putchar('\n'); if (MPFR_SIGN(r)<0) { fprintf(stderr,"Error in mpfr_exp: r<0\n"); exit(1); } #endif - mpfr_div_2exp(r, r, K, GMP_RNDU); /* r = (x-n*log(2))/2^K */ + mpfr_div_2ui(r, r, K, GMP_RNDU); /* r = (x-n*log(2))/2^K */ TMP_MARK(marker); MY_INIT_MPZ(ss, 3 + 2*((q-1)/BITS_PER_MP_LIMB)); - exps = mpz_set_fr(ss, s); + exps = mpfr_get_z_exp(ss, s); /* s <- 1 + r/1! + r^2/2! + ... + r^l/l! */ l = (precy<SWITCH) ? mpfr_exp2_aux(ss, r, q, &exps) /* naive method */ : mpfr_exp2_aux2(ss, r, q, &exps); /* Brent/Kung method */ @@ -187,8 +187,8 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_set_z(s, ss, GMP_RNDN); MPFR_EXP(s) += exps; TMP_FREE(marker); /* don't need ss anymore */ - if (n>0) mpfr_mul_2exp(s, s, n, GMP_RNDU); - else mpfr_div_2exp(s, s, -n, GMP_RNDU); + if (n>0) mpfr_mul_2ui(s, s, n, GMP_RNDU); + else mpfr_div_2ui(s, s, -n, GMP_RNDU); /* error is at most 2^K*(3l*(l+1)) ulp for mpfr_exp2_aux */ if (precy<SWITCH) l = 3*l*(l+1); @@ -199,7 +199,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) #ifdef DEBUG printf("after mult. by 2^n:\n"); if (MPFR_EXP(s)>-1024) printf("s=%1.20e\n",mpfr_get_d(s)); - printf(" ="); mpfr_print_raw(s); putchar('\n'); + printf(" ="); mpfr_print_binary(s); putchar('\n'); printf("err=%d bits\n", K); #endif @@ -243,7 +243,7 @@ mpfr_exp2_aux (mpz_t s, mpfr_srcptr r, int q, int *exps) MY_INIT_MPZ(rr, qn+1); mpz_set_ui(t, 1); expt=0; mpz_set_ui(s, 1); mpz_mul_2exp(s, s, q-1); *exps = 1-q; /* s = 2^(q-1) */ - expr = mpz_set_fr(rr, r); /* no error here */ + expr = mpfr_get_z_exp(rr, r); /* no error here */ l = 0; do { @@ -300,7 +300,7 @@ mpfr_exp2_aux2 (mpz_t s, mpfr_srcptr r, int q, int *exps) MY_INIT_MPZ(t, 2*sizer); /* double size for products */ mpz_set_ui(s, 0); *exps = 1-q; /* initialize s to zero, 1 ulp = 2^(1-q) */ for (i=0;i<=m;i++) MY_INIT_MPZ(R[i], sizer+2); - expR[1] = mpz_set_fr(R[1], r); /* exact operation: no error */ + expR[1] = mpfr_get_z_exp(R[1], r); /* exact operation: no error */ expR[1] = mpz_normalize2(R[1], R[1], expR[1], 1-q); /* error <= 1 ulp */ mpz_mul(t, R[1], R[1]); /* err(t) <= 2 ulps */ mpz_div_2exp(R[2], t, q-1); /* err(R[2]) <= 3 ulps */ diff --git a/mpfr/expm1.c b/mpfr/expm1.c index cdb41072d..c3cca2b54 100644 --- a/mpfr/expm1.c +++ b/mpfr/expm1.c @@ -1,6 +1,6 @@ /* mpfr_expm1 -- Compute exp(x)-1 -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -32,38 +32,36 @@ MA 02111-1307, USA. */ int mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode) { - int inexact = 0; - if (MPFR_IS_NAN(x)) + if (MPFR_IS_NAN(x)) { - MPFR_SET_NAN(y); - return 1; + MPFR_SET_NAN(y); + MPFR_RET_NAN; } - MPFR_CLEAR_NAN(y); + MPFR_CLEAR_NAN(y); /* check for inf or -inf (expm1(-inf)=-1) */ if (MPFR_IS_INF(x)) { - if(MPFR_SIGN(x) > 0) + if (MPFR_SIGN(x) > 0) { MPFR_SET_INF(y); - MPFR_SET_SAME_SIGN(y,x); + MPFR_SET_POS(y); return 0; } - else - return mpfr_set_ui(y,-1,rnd_mode); + else + return mpfr_set_si(y, -1, rnd_mode); } MPFR_CLEAR_INF(y); - - if(!MPFR_NOTZERO(x)) + if(MPFR_IS_ZERO(x)) { MPFR_SET_ZERO(y); /* expm1(+/- 0) = +/- 0 */ MPFR_SET_SAME_SIGN(y,x); - return 0; + MPFR_RET(0); } /* General case */ diff --git a/mpfr/floor.c b/mpfr/floor.c deleted file mode 100644 index 7509f699b..000000000 --- a/mpfr/floor.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MPFR_FLOOR 1 -#include "trunc.c" diff --git a/mpfr/fma.c b/mpfr/fma.c index 0a6c1ce73..8abebc743 100644 --- a/mpfr/fma.c +++ b/mpfr/fma.c @@ -1,6 +1,6 @@ /* mpfr_fma -- Floating multiply-add -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001, 2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -22,7 +22,6 @@ the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -34,167 +33,173 @@ MA 02111-1307, USA. */ */ int -mpfr_fma (mpfr_ptr s, mpfr_srcptr x ,mpfr_srcptr y ,mpfr_srcptr z , mp_rnd_t rnd_mode) +mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z, + mp_rnd_t rnd_mode) { - int inexact =0; + int inexact = 0; /* Flag calcul exacte */ - int not_exact=0; - - /* particular cases */ - if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z)) - { - MPFR_SET_NAN(s); - return 1; - } - - /* cases Inf*0+z, 0*Inf+z, Inf-Inf */ - if ((MPFR_IS_INF(x) && MPFR_IS_ZERO(y)) || - (MPFR_IS_INF(y) && MPFR_IS_ZERO(x)) || - ((MPFR_IS_INF(x) || MPFR_IS_INF(y)) && MPFR_IS_INF(z) && - ((MPFR_SIGN(x) * MPFR_SIGN(y)) != MPFR_SIGN(z)))) - { - MPFR_SET_NAN(s); - return 1; - } - - MPFR_CLEAR_NAN(s); - - if (MPFR_IS_INF(x) || MPFR_IS_INF(y)) - { - if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */ - { - MPFR_SET_INF(s); - MPFR_SET_SAME_SIGN(s, z); - return 0; - } - else /* z is finite */ - { - MPFR_SET_INF(s); - if (MPFR_SIGN(s) != (MPFR_SIGN(x) * MPFR_SIGN(y))) - MPFR_CHANGE_SIGN(s); - return 0; - } - } - - /* now x and y are finite */ - if (MPFR_IS_INF(z)) - { - MPFR_SET_INF(s); - MPFR_SET_SAME_SIGN(s, z); - return 0; - } - - MPFR_CLEAR_INF(s); - - if(!MPFR_NOTZERO(x) || !MPFR_NOTZERO(y)) - return mpfr_set (s, z, rnd_mode); - if (!MPFR_NOTZERO(z)) - return mpfr_mul (s, x, y, rnd_mode); - - /* General case */ - /* Detail of the compute */ - - /* u <- x*y */ - /* t <- z+u */ + int not_exact = 0; + + /* particular cases */ + if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z)) + { + MPFR_SET_NAN(s); + MPFR_RET_NAN; + } + + if (MPFR_IS_INF(x) || MPFR_IS_INF(y)) + { + /* cases Inf*0+z, 0*Inf+z, Inf-Inf */ + if ((MPFR_IS_FP(y) && MPFR_IS_ZERO(y)) || + (MPFR_IS_FP(x) && MPFR_IS_ZERO(x)) || + (MPFR_IS_INF(z) && ((MPFR_SIGN(x) * MPFR_SIGN(y)) != MPFR_SIGN(z)))) { - /* Declaration of the intermediary variable */ - mpfr_t t, u; - int d,fl1,fl2; - int accu=0; - - /* Declaration of the size variable */ - mp_prec_t Nx = MPFR_PREC(x); /* Precision of input variable */ - mp_prec_t Ny = MPFR_PREC(y); /* Precision of input variable */ - mp_prec_t Nz = MPFR_PREC(z); /* Precision of input variable */ - mp_prec_t Ns = MPFR_PREC(s); /* Precision of output variable */ - int Nt; /* Precision of the intermediary variable */ - long int err; /* Precision of error */ - unsigned int first_pass=0; /* temporary precision */ - - /* compute the precision of intermediary variable */ - Nt=MAX(MAX(Nx,Ny),Nz); - - /* the optimal number of bits is MPFR_EXP(u)-MPFR_EXP(v)+1 */ - /* but u and v are not yet compute, also we take in account */ - /* just one bit */ - Nt=Nt+1+_mpfr_ceil_log2(Nt)+20; - /* initialise the intermediary variables */ - mpfr_init(u); - mpfr_init(t); - - /* First computation of fma */ - do { - if(accu++ >2) - { - mpfr_clear(t); - mpfr_clear(u); - goto fma_paul; - } - - not_exact=0; - - /* reactualisation of the precision */ - mpfr_set_prec(u,Nt); - mpfr_set_prec(t,Nt); - - /* computations */ - fl1=mpfr_mul(u,x,y,GMP_RNDN); - if(fl1) not_exact=1; - - fl2=mpfr_add(t,z,u,GMP_RNDN); - if(fl2) not_exact=1; - - /*Nt=Nt+(d+1)+_mpfr_ceil_log2(Nt); */ - d = MPFR_EXP(u)-MPFR_EXP(t); + MPFR_SET_NAN(s); + MPFR_RET_NAN; + } - /* estimation of the error */ - err=Nt-(d+1); + MPFR_CLEAR_NAN(s); - /* actualisation of the precision */ - Nt +=(1-first_pass)*d + first_pass*10; - if(Nt<0)Nt=0; + if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */ + { + MPFR_SET_INF(s); + MPFR_SET_SAME_SIGN(s, z); + MPFR_RET(0); + } + else /* z is finite */ + { + MPFR_SET_INF(s); + if (MPFR_SIGN(s) != (MPFR_SIGN(x) * MPFR_SIGN(y))) + MPFR_CHANGE_SIGN(s); + MPFR_RET(0); + } + } - first_pass=1; + MPFR_CLEAR_NAN(s); - } while ( (fl1!=fl2) || (err <0) || ((!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ns)) && not_exact )); + /* now x and y are finite */ + if (MPFR_IS_INF(z)) + { + MPFR_SET_INF(s); + MPFR_SET_SAME_SIGN(s, z); + MPFR_RET(0); + } - inexact = mpfr_set (s, t, rnd_mode); - mpfr_clear(t); - mpfr_clear(u); + MPFR_CLEAR_INF(s); - goto fin; + if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y)) + { + if (MPFR_IS_ZERO(z)) + { + int sign_p, sign_z; + sign_p = MPFR_SIGN(x) * MPFR_SIGN(y); + sign_z = MPFR_SIGN(z); + if (MPFR_SIGN(s) != + (rnd_mode != GMP_RNDD ? + ((sign_p < 0 && sign_z < 0) ? -1 : 1) : + ((sign_p > 0 && sign_z > 0) ? 1 : -1))) + { + MPFR_CHANGE_SIGN(s); + } + MPFR_SET_ZERO(s); + MPFR_RET(0); } - - - - fma_paul: - - - /* General case */ - /* Detail of the compute */ - /* u <- x*y exact */ - /* s <- z+u */ - { - mpfr_t u; - - /* if we take prec(u) >= prec(x) + prec(y), the product - u <- x*y is always exact */ - mpfr_init2 (u, MPFR_PREC(x) + MPFR_PREC(y)); - - mpfr_mul (u, x, y, GMP_RNDN); /* always exact */ - inexact = mpfr_add (s, z, u, rnd_mode); - mpfr_clear(u); - } - return inexact; - - fin: - if (not_exact == 0 && inexact == 0) - return 0; - - if (not_exact != 0 && inexact == 0) - return 1; - - return inexact; - + else + return mpfr_set (s, z, rnd_mode); + } + + if (MPFR_IS_ZERO(z)) + return mpfr_mul (s, x, y, rnd_mode); + + + /* General case */ + /* Detail of the compute */ + + /* u <- x*y */ + /* t <- z+u */ + { + /* Declaration of the intermediary variable */ + mpfr_t t, u; + int d; + int accu = 0; + + /* Declaration of the size variable */ + mp_prec_t Nx = MPFR_PREC(x); /* Precision of input variable */ + mp_prec_t Ny = MPFR_PREC(y); /* Precision of input variable */ + mp_prec_t Nz = MPFR_PREC(z); /* Precision of input variable */ + mp_prec_t Ns = MPFR_PREC(s); /* Precision of output variable */ + mp_prec_t Nt; /* Precision of the intermediary variable */ + long int err; /* Precision of error */ + unsigned int first_pass = 0; /* temporary precision */ + + /* compute the precision of intermediary variable */ + Nt = MAX(MAX(Nx,Ny),Nz); + + /* the optimal number of bits is MPFR_EXP(u)-MPFR_EXP(v)+1 */ + /* but u and v are not yet compute, also we take in account */ + /* just one bit */ + Nt += 1 + _mpfr_ceil_log2(Nt) + 20; + /* initialise the intermediary variables */ + mpfr_init(u); + mpfr_init(t); + + /* First computation of fma */ + do + { + if (accu++ > 2) + { + mpfr_clear(t); + mpfr_clear(u); + + /* General case */ + /* Detail of the compute */ + /* u <- x*y exact */ + /* s <- z+u */ + + /* if we take prec(u) >= prec(x) + prec(y), the product + u <- x*y is always exact */ + mpfr_init2 (u, MPFR_PREC(x) + MPFR_PREC(y)); + mpfr_mul (u, x, y, GMP_RNDN); /* always exact */ + inexact = mpfr_add (s, z, u, rnd_mode); + mpfr_clear(u); + return inexact; + } + + /* reactualisation of the precision */ + mpfr_set_prec(u, Nt); + mpfr_set_prec(t, Nt); + + /* computations */ + not_exact = mpfr_mul (u, x, y, GMP_RNDN); + + not_exact |= mpfr_add (t, z, u, GMP_RNDN); + + /* Nt = Nt + (d+1) + _mpfr_ceil_log2(Nt); */ + d = MPFR_EXP(u) - MPFR_EXP(t); + + /* estimate of the error */ + err = Nt - (d+1); + + /* actualisation of the precision */ + Nt += (1-first_pass) * d + first_pass * 10; + if (Nt < 0) + Nt = 0; + + first_pass = 1; + } + while (not_exact && + ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ns))); + + inexact = mpfr_set (s, t, rnd_mode); + mpfr_clear(t); + mpfr_clear(u); + } + + if (not_exact == 0 && inexact == 0) + return 0; + + if (not_exact != 0 && inexact == 0) + return 1; + + return inexact; } - diff --git a/mpfr/generic.c b/mpfr/generic.c index b49c17ef0..d1b459513 100644 --- a/mpfr/generic.c +++ b/mpfr/generic.c @@ -188,7 +188,7 @@ GENERIC (mpfr_ptr y, mpz_srcptr p, int r, int m) mpfr_div (y, y, tmp, GMP_RNDD); mpfr_clear (tmp); #else - mpfr_div_2exp(y, y, r*(i-1), GMP_RNDN); + mpfr_div_2ui(y, y, r*(i-1), GMP_RNDN); #endif for (i=0;i<=m;i++) { diff --git a/mpfr/get_str.c b/mpfr/get_str.c index 93af194b0..1117a6946 100644 --- a/mpfr/get_str.c +++ b/mpfr/get_str.c @@ -1,6 +1,6 @@ /* mpfr_get_str -- output a floating-point number to a string -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include <stdlib.h> #include <string.h> #include "gmp.h" @@ -28,6 +27,8 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" +#define ERR 5 + /* Convert op to a string in base 'base' with 'n' digits and writes the mantissa in 'str', the exponent in 'expptr'. @@ -37,177 +38,314 @@ MA 02111-1307, USA. */ */ char* mpfr_get_str (char *str, mp_exp_t *expptr, int base, size_t n, - mpfr_srcptr op, mp_rnd_t rnd_mode) + mpfr_srcptr op, mp_rnd_t rnd_mode) { - double d; - long e, q, div, p, err, prec, sh; - mpfr_t a, b; - mpz_t bz; - char *str0=NULL; - mp_rnd_t rnd1; - int f, pow2, ok=0, neg, str_is_null=(str==NULL); - - if (base<2 || 36<base) { - fprintf(stderr, "Error: too small or too large base in mpfr_get_str: %d\n", - base); - exit(1); - } - - neg = MPFR_SIGN(op) < 0; - - if (MPFR_IS_INF(op)) { - if (str == NULL) - str = (*__gmp_allocate_func)(neg + 4); - str0 = str; - if (neg) { *str++ = '-'; } - *str++ = 'I'; *str++ = 'n'; *str++ = 'f'; *str='\0'; - return str0; /* strlen(str0) = neg + 3 */ - } - - if (!MPFR_NOTZERO(op)) { - if (str == NULL) - str = (*__gmp_allocate_func)(neg + n + 1); - str0 = str; - if (neg) *str++ = '-'; - for (f=0;f<n;f++) *str++ = '0'; - *str++ = '\0'; - *expptr = 1; - return str0; /* strlen(str0) = neg + n */ - } - - count_leading_zeros(pow2, (mp_limb_t) base); - pow2 = BITS_PER_MP_LIMB - pow2 - 1; - if (base != (1<<pow2)) pow2=0; - /* if pow2 <> 0, then base = 2^pow2 */ - - /* first determines the exponent */ - e = MPFR_EXP(op); - d = ABS(mpfr_get_d2(op, 0)); - /* the absolute value of op is between 1/2*2^e and 2^e */ - /* the output exponent f is such that base^(f-1) <= |op| < base^f - i.e. f = 1 + floor(log(|op|)/log(base)) - = 1 + floor((log(|m|)+e*log(2))/log(base)) */ - /* f = 1 + (int) floor((log(d)/LOG2+(double)e)*LOG2/log((double)base)); */ - /* when base = 2^pow2, then |op| < 2^(pow2*f) - i.e. e <= pow2*f and f = ceil(e/pow2) */ - if (pow2) - f = ((e < 0) ? e : (e + pow2 - 1)) / pow2; - else + int neg; + + if (base < 2 || base > 36) + return NULL; + + if (n == 0) /* determine n from precision of op */ { - d = ((double) e + (double) _mpfr_floor_log2(d)) - * __mp_bases[base].chars_per_bit_exactly; - /* warning: (int) d rounds towards 0 */ - f = (int) d; /* f equals floor(d) if d >= 0 and ceil(d) if d < 0 */ - if (f <= d) f++; + n = __mp_bases[base].chars_per_bit_exactly * MPFR_PREC(op); + if (n < 2) + n = 2; } - if (n==0) { - /* performs exact rounding, i.e. returns y such that for GMP_RNDU - for example, we have: x*2^(e-p) <= y*base^(f-n) - */ - n = (int) (__mp_bases[base].chars_per_bit_exactly * MPFR_PREC(op)); - if (n==0) n=1; - } - /* now the first n digits of the mantissa are obtained from - rnd(op*base^(n-f)) */ - if (pow2) prec = n*pow2; - else - prec = 1 + (long) ((double) n / __mp_bases[base].chars_per_bit_exactly); - err = 5; - q = prec + err; - /* one has to use at least q bits */ - q = (((q-1)/BITS_PER_MP_LIMB)+1)*BITS_PER_MP_LIMB; - mpfr_init2(a, q); mpfr_init2(b, q); - - do { - p = n-f; if ((div=(p<0))) p=-p; - rnd1 = rnd_mode; - if (div) { - /* if div we divide by base^p so we have to invert the rounding mode */ - switch (rnd1) { - case GMP_RNDN: rnd1=GMP_RNDN; break; - case GMP_RNDZ: rnd1=GMP_RNDU; break; - case GMP_RNDU: rnd1=GMP_RNDZ; break; - case GMP_RNDD: rnd1=GMP_RNDZ; break; - } + + /* Do not use MPFR_PREC_MIN as this applies to base 2 only. Perhaps we + should allow n == 1 for directed rounding modes and odd bases. */ + if (n < 2) + return NULL; + + if (MPFR_IS_NAN(op)) + { + if (str == NULL) + str = (*__gmp_allocate_func)(4); + str[0] = 'N'; + str[1] = 'a'; + str[2] = 'N'; + str[3] = '\0'; + return str; + } + + neg = MPFR_SIGN(op) < 0; /* 0 if positive, 1 if negative */ + + if (MPFR_IS_INF(op)) + { + char *str0; + + if (str == NULL) + str = (*__gmp_allocate_func)(neg + 4); + str0 = str; + if (neg) + *str++ = '-'; + *str++ = 'I'; + *str++ = 'n'; + *str++ = 'f'; + *str = '\0'; + return str0; /* strlen(str0) = neg + 3 */ } - if (pow2) - { - if (div) - mpfr_div_2exp (b, op, pow2*p, rnd_mode); - else - mpfr_mul_2exp (b, op, pow2*p, rnd_mode); - } - else { - /* compute base^p with q bits and rounding towards zero */ - mpfr_set_prec(b, q); - if (p==0) { mpfr_set(b, op, rnd_mode); mpfr_set_ui(a, 1, rnd_mode); } - else { - mpfr_set_prec(a, q); - mpfr_ui_pow_ui(a, base, p, rnd1); - if (div) { - mpfr_set_ui(b, 1, rnd_mode); - mpfr_div(a, b, a, rnd_mode); - } - /* now a is an approximation by default of 1/base^(f-n) */ - mpfr_mul(b, op, a, rnd_mode); - } + /* op is a floating-point number */ + + if (MPFR_IS_ZERO(op)) + { + char *str0; + + if (str == NULL) + str = (*__gmp_allocate_func)(neg + n + 1); + str0 = str; + if (neg) + *str++ = '-'; + memset(str, '0', n); + str[n] = '\0'; + *expptr = 0; /* a bit like frexp() in ISO C99 */ + return str0; /* strlen(str0) = neg + n */ } - if (neg) MPFR_CHANGE_SIGN(b); /* put b positive */ - if (q>2*prec+BITS_PER_MP_LIMB) { - /* if the intermediate precision exceeds twice that of the input, - a worst-case for the division cannot occur */ - ok=1; - rnd_mode=GMP_RNDN; + else + { + int str_is_null; + int pow2; + mp_exp_t e, f; + mpfr_t a, b; + mpz_t bz; + char *str0; + size_t len; + + str_is_null = str == NULL; + + if (IS_POW2(base)) /* Is base a power of 2? */ + { + count_leading_zeros (pow2, (mp_limb_t) base); + pow2 = BITS_PER_MP_LIMB - pow2 - 1; /* base = 2^pow2 */ + } + else + pow2 = 0; + + /* first determines the exponent */ + e = MPFR_EXP(op); + + /* the absolute value of op is between 1/2*2^e and 2^e */ + /* the output exponent f is such that base^(f-1) <= |op| < base^f + i.e. f = 1 + floor(log(|op|)/log(base)) + = 1 + floor((log(|m|)+e*log(2))/log(base)) */ + /* f = 1 + (int)floor((log(d)/LOG2+(double)e)*LOG2/log((double)base)); */ + /* when base = 2^pow2, then |op| < 2^(pow2*f) + i.e. e <= pow2*f and f = ceil(e/pow2) */ + if (pow2) + f = e <= 0 ? e / pow2 : (e - 1) / pow2 + 1; /* int overflow avoided */ + else + { + double d; + + d = mpfr_get_d2(op, 0); + d = ((double) e + (double) _mpfr_floor_log2 (ABS(d))) + * __mp_bases[base].chars_per_bit_exactly; + MPFR_ASSERTN(d >= MP_EXP_T_MIN); + MPFR_ASSERTN(d <= MP_EXP_T_MAX); + /* warning: (mp_exp_t) d rounds towards 0 */ + f = (mp_exp_t) d; /* f = floor(d) if d >= 0 and ceil(d) if d < 0 */ + if (f <= d) + { + MPFR_ASSERTN(f < MP_EXP_T_MAX); + f++; + } + } + + mpfr_init (a); + mpfr_init (b); + mpz_init (bz); + + str0 = str; + + do + { + mp_prec_t prec, q; + + /* now the first n digits of the mantissa are obtained from + rnd(op*base^(n-f)) */ + if (pow2) + { + MPFR_ASSERTN(n <= MPFR_INTPREC_MAX / pow2); + prec = (mp_prec_t) n * pow2; + } + else + { + double d; + + d = (double) n / __mp_bases[base].chars_per_bit_exactly; + MPFR_ASSERTN(d <= MPFR_INTPREC_MAX - 1); + prec = (mp_prec_t) d + 1; + } + + MPFR_ASSERTN(prec <= MPFR_INTPREC_MAX - ERR); + /* one has to use at least q bits */ + q = ((prec + (ERR-1)) / BITS_PER_MP_LIMB + 1) * BITS_PER_MP_LIMB; + mpfr_set_prec (a, q); + mpfr_set_prec (b, q); + + while (1) + { + mp_exp_unsigned_t p; + int div; + + if (f < 0) + { + p = (mp_exp_unsigned_t) n - f; + MPFR_ASSERTN(p > n); + div = 0; + } + else if (n >= f) + { + p = n - f; + div = 0; + } + else + { + p = f - n; + div = 1; + } + + if (pow2) + { + MPFR_ASSERTN(p <= ULONG_MAX / pow2); + MPFR_ASSERTN(p <= __mpfr_emax / pow2); + if (div) + mpfr_div_2ui (b, op, pow2*p, rnd_mode); + else + mpfr_mul_2ui (b, op, pow2*p, rnd_mode); + } + else + { + /* compute base^p with q bits */ + mpfr_set_prec (b, q); + if (p == 0) + { + mpfr_set (b, op, rnd_mode); + mpfr_set_ui (a, 1, rnd_mode); + } + else + { + mp_rnd_t rnd1; + + mpfr_set_prec (a, q); + if (div) + { + /* if div, we divide by base^p, so we have to invert + the rounding mode to compute base^p */ + switch (rnd_mode) + { + case GMP_RNDN: rnd1 = GMP_RNDN; break; + case GMP_RNDZ: rnd1 = GMP_RNDU; break; + case GMP_RNDU: rnd1 = GMP_RNDZ; break; + case GMP_RNDD: rnd1 = GMP_RNDU; break; + default: MPFR_ASSERTN(0); + } + } + else + { + rnd1 = rnd_mode; + } + mpfr_ui_pow_ui (a, base, p, rnd1); + if (div) + { + mpfr_set_ui (b, 1, rnd_mode); + mpfr_div (a, b, a, rnd_mode); + } + /* now a is an approximation to 1/base^(f-n) */ + mpfr_mul (b, op, a, rnd_mode); + } + } + + if (neg) + MPFR_CHANGE_SIGN(b); /* put b positive */ + + if (prec <= (MPFR_INTPREC_MAX - BITS_PER_MP_LIMB) / 2 && + q > 2 * prec + BITS_PER_MP_LIMB) + { + /* if the intermediate precision exceeds twice that of the + input, a worst-case for the division cannot occur */ + rnd_mode = GMP_RNDN; + break; + } + else if (pow2 || + mpfr_can_round (b, q-ERR, rnd_mode, rnd_mode, prec)) + break; + + MPFR_ASSERTN(q <= MPFR_INTPREC_MAX - BITS_PER_MP_LIMB); + q += BITS_PER_MP_LIMB; + } + + { + mp_rnd_t rnd = rnd_mode; + + if (neg) + switch (rnd_mode) + { + case GMP_RNDU: rnd = GMP_RNDZ; break; + case GMP_RNDD: rnd = GMP_RNDU; break; + } + + mpfr_round_prec (b, rnd, MPFR_EXP(b)); + } + + prec = MPFR_EXP(b); /* may have changed due to rounding */ + + { + mp_size_t n, e; + int sh; + + /* now the mantissa is the integer part of b */ + n = 1 + (prec - 1) / BITS_PER_MP_LIMB; + _mpz_realloc (bz, n); + sh = prec % BITS_PER_MP_LIMB; + e = 1 + (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB; + MPFR_ASSERTN(e >= n); + e -= n; + if (sh != 0) + mpn_rshift (PTR(bz), MPFR_MANT(b) + e, n, BITS_PER_MP_LIMB - sh); + else + MPN_COPY(PTR(bz), MPFR_MANT(b) + e, n); + bz->_mp_size = n; + } + + /* computes the number of characters needed */ + /* n+1 may not be enough for 100000... */ + if (str0 == NULL) + str0 = (*__gmp_allocate_func) (neg + n + 2); + + str = str0; /* restore initial value in case we had to restart */ + + if (neg) + *str++ = '-'; + + mpz_get_str (str, base, bz); /* n digits of mantissa */ + len = strlen(str); + } + while (len > n && (f++, 1)); + + if (len == n - 1) + { + len++; + f--; + str[n-1]='0'; + str[n]='\0'; + } + + *expptr = f; + mpfr_clear (a); + mpfr_clear (b); + mpz_clear (bz); + + /* if the given string was null, ensure we return a block + which is exactly strlen(str0)+1 bytes long (useful for + __gmp_free_func and the C++ wrapper) */ + + /* NOTE: len != n + 1 is always satisfied; either this condition + is useless or there is a bug somewhere */ + if (str_is_null && len != n + 1) + str0 = (*__gmp_reallocate_func) (str0, neg + n + 2, neg + len + 1); + + return str0; } - else ok = pow2 || mpfr_can_round(b, q-err, rnd_mode, rnd_mode, prec); - - } while (ok==0 && (q+=BITS_PER_MP_LIMB) ); - - if (neg) - switch (rnd_mode) { - case GMP_RNDU: rnd_mode=GMP_RNDZ; break; - case GMP_RNDD: rnd_mode=GMP_RNDU; break; - } - - if (ok) - mpfr_round (b, rnd_mode, MPFR_EXP(b)); - - prec=MPFR_EXP(b); /* may have changed due to rounding */ - - /* now the mantissa is the integer part of b */ - mpz_init(bz); q=1+(prec-1)/BITS_PER_MP_LIMB; - _mpz_realloc(bz, q); - sh = prec%BITS_PER_MP_LIMB; - e = 1 + (MPFR_PREC(b)-1)/BITS_PER_MP_LIMB-q; - if (sh) mpn_rshift(PTR(bz), MPFR_MANT(b)+e, q, BITS_PER_MP_LIMB-sh); - else MPN_COPY(PTR(bz), MPFR_MANT(b)+e, q); - bz->_mp_size=q; - - /* computes the number of characters needed */ - q = neg + n + 2; /* n+1 may not be enough for 100000... */ - if (str == NULL) { - str0 = str = (*__gmp_allocate_func) (q); - } - if (neg) *str++='-'; - mpz_get_str(str, base, bz); /* n digits of mantissa */ - if (strlen(str)==n+1) { - f++; /* possible due to rounding */ - str[n]='\0'; /* ensures we get only n digits of output */ - } - else if (strlen(str)==n-1) { - f--; - str[n-1]='0'; - str[n]='\0'; - } - *expptr = f; - mpfr_clear(a); mpfr_clear(b); mpz_clear(bz); - - /* if the given string was null, ensure we return a block which is exactly - strlen(str)+1 bytes long (useful for __gmp_free_func and the C++ wrapper) - */ - if (str_is_null && ((strlen(str0) + 1) != q)) - str0 = (char*) (*__gmp_reallocate_func) (str0, q, strlen(str0) + 1); - - return str0; } diff --git a/mpfr/hypot.c b/mpfr/hypot.c index 1e799f9a9..6ee55942e 100644 --- a/mpfr/hypot.c +++ b/mpfr/hypot.c @@ -1,6 +1,6 @@ /* mpfr_hypot -- Euclidean distance -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -41,27 +41,26 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) /* particular cases */ if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y)) - { - MPFR_SET_NAN(z); - return 1; - } + { + MPFR_SET_NAN(z); + MPFR_RET_NAN; + } MPFR_CLEAR_NAN(z); if (MPFR_IS_INF(x) || MPFR_IS_INF(y)) - { - MPFR_SET_INF(z); - if (MPFR_SIGN(z) < 0) - MPFR_CHANGE_SIGN(z); - return 0; - } + { + MPFR_SET_INF(z); + MPFR_SET_POS(z); + MPFR_RET(0); + } MPFR_CLEAR_INF(z); - - if(!MPFR_NOTZERO(x)) + + if(MPFR_IS_ZERO(x)) return mpfr_abs (z, y, rnd_mode); - - if(!MPFR_NOTZERO(y)) + + if(MPFR_IS_ZERO(y)) return mpfr_abs (z, x, rnd_mode); /* General case */ diff --git a/mpfr/i_ceil_exp2.c b/mpfr/i_ceil_exp2.c new file mode 100644 index 000000000..94f7e85e0 --- /dev/null +++ b/mpfr/i_ceil_exp2.c @@ -0,0 +1,42 @@ +/* _mpfr_ceil_exp2 - returns y >= 2^d + +Copyright (C) 1999-2002 Free Software Foundation. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +/* returns y >= 2^d, assuming that d <= 1024 */ +double +_mpfr_ceil_exp2 (double d) +{ + long exp; + union ieee_double_extract x; + + MPFR_ASSERTN(d <= 1024.0); + exp = (long) d; + if (d != (double) exp) + exp++; + /* now exp = ceil(d) */ + x.d = 1.0; + x.s.exp = exp <= -1022 ? 1 : 1023 + exp; + return x.d; +} diff --git a/mpfr/i_ceil_log2.c b/mpfr/i_ceil_log2.c new file mode 100644 index 000000000..e70dd261d --- /dev/null +++ b/mpfr/i_ceil_log2.c @@ -0,0 +1,40 @@ +/* _mpfr_ceil_log2 - returns ceil(log(d)/log(2)) + +Copyright (C) 1999-2002 Free Software Foundation. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +/* returns ceil(log(d)/log(2)) */ +long +_mpfr_ceil_log2 (double d) +{ + long exp; + union ieee_double_extract x; + + x.d = d; + exp = x.s.exp - 1023; + x.s.exp = 1023; /* value for 1 <= d < 2 */ + if (x.d != 1.0) /* d: not a power of two? */ + exp++; + return exp; +} diff --git a/mpfr/tests/tlog_base_2.c b/mpfr/i_floor_log2.c index d0f1aa019..a4879610e 100644 --- a/mpfr/tests/tlog_base_2.c +++ b/mpfr/i_floor_log2.c @@ -1,7 +1,6 @@ -/* Test file for mpfr_log2. +/* _mpfr_floor_log2 - returns floor(log(d)/log(2)) -Copyright (C) 2001 Free Software Foundation. -Adapted from tsinh.c. +Copyright (C) 1999-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -20,19 +19,17 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> #include "gmp.h" +#include "gmp-impl.h" #include "mpfr.h" -#include "mpfr-test.h" +#include "mpfr-impl.h" -#define TEST_FUNCTION mpfr_log2 -#include "tgeneric.c" - -int -main (int argc, char *argv[]) +/* returns floor(log(d)/log(2)) */ +long +_mpfr_floor_log2 (double d) { - test_generic (1, 100, 30); + union ieee_double_extract x; - return 0; + x.d = d; + return (long) x.s.exp - 1023; } diff --git a/mpfr/init2.c b/mpfr/init2.c index 6261ae305..2b516df1b 100644 --- a/mpfr/init2.c +++ b/mpfr/init2.c @@ -19,8 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -29,18 +27,18 @@ MA 02111-1307, USA. */ void mpfr_init2 (mpfr_ptr x, mp_prec_t p) { - mp_prec_t xsize; + mp_size_t xsize; - if (p==0) { - fprintf(stderr, "*** cannot initialize mpfr with precision 0\n"); exit(1); - } + /* p=1 is not allowed since the rounding to nearest even rule requires at + least two bits of mantissa: the neighbours of 3/2 are 1*2^0 and 1*2^1, + which both have an odd mantissa */ + MPFR_ASSERTN(p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX); - xsize = (p - 1)/BITS_PER_MP_LIMB + 1; + xsize = (mp_size_t) ((p - 1) / BITS_PER_MP_LIMB) + 1; MPFR_PREC(x) = p; - MPFR_MANT(x) = (mp_ptr) (*__gmp_allocate_func) (xsize * BYTES_PER_MP_LIMB); + MPFR_MANT(x) = (mp_ptr) + (*__gmp_allocate_func) ((size_t) xsize * BYTES_PER_MP_LIMB); MPFR_SIZE(x) = xsize; - MPFR_CLEAR_FLAGS(x); - MPFR_SET_ZERO(x); /* initializes to zero */ - MPFR_EXP(x) = 0; /* avoids uninitialized memory reads for zero */ + MPFR_SET_NAN(x); /* initializes to NaN */ } diff --git a/mpfr/log.c b/mpfr/log.c index e15eb0f31..97b1607af 100644 --- a/mpfr/log.c +++ b/mpfr/log.c @@ -1,6 +1,6 @@ /* mpfr_log -- natural logarithm of a floating-point number -Copyright (C) 1999, 2001 Free Software Foundation. +Copyright (C) 1999-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -55,7 +55,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(a)) { MPFR_SET_NAN(r); - return 1; /* NaN is inexact */ + MPFR_RET_NAN; } MPFR_CLEAR_NAN(r); @@ -66,40 +66,39 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) if (MPFR_SIGN(a) < 0) /* log(-Inf) = NaN */ { MPFR_SET_NAN(r); - return 1; + MPFR_RET_NAN; } else /* log(+Inf) = +Inf */ { MPFR_SET_INF(r); - if (MPFR_SIGN(r) < 0) - MPFR_CHANGE_SIGN(r); - return 0; + MPFR_SET_POS(r); + MPFR_RET(0); } } /* Now we can clear the flags without damage even if r == a */ - MPFR_CLEAR_INF(r); + MPFR_CLEAR_INF(r); - if (MPFR_IS_ZERO(a)) + if (MPFR_IS_ZERO(a)) { - MPFR_SET_INF(r); - if (MPFR_SIGN(r) > 0) - MPFR_CHANGE_SIGN(r); - return 0; /* log(0) is an exact infinity */ + MPFR_SET_INF(r); + MPFR_SET_POS(r); + MPFR_RET(0); /* log(0) is an exact infinity */ } /* If a is negative, the result is NaN */ if (MPFR_SIGN(a) < 0) { MPFR_SET_NAN(r); - return 1; + MPFR_RET_NAN; } /* If a is 1, the result is 0 */ - if (mpfr_cmp_ui_2exp (a, 1, 0) == 0) + if (mpfr_cmp_ui (a, 1) == 0) { MPFR_SET_ZERO(r); - return 0; /* only "normal" case where the result is exact */ + MPFR_SET_POS(r); + MPFR_RET(0); /* only "normal" case where the result is exact */ } q=MPFR_PREC(r); @@ -118,7 +117,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) while (bool==1) { #ifdef DEBUG - printf("a="); mpfr_print_raw(a); putchar('\n'); + printf("a="); mpfr_print_binary(a); putchar('\n'); printf("p=%d\n", p); #endif /* Calculus of m (depends on p) */ @@ -138,10 +137,10 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) mpfr_set_si (mm, m, GMP_RNDN); /* I have m, supposed exact */ mpfr_set_si (tmp1, 1, GMP_RNDN); /* I have 1, exact */ mpfr_set_si (tmp2, 4, GMP_RNDN); /* I have 4, exact */ - mpfr_mul_2exp (s, a, m, GMP_RNDN); /* I compute s=a*2^m, err <= 1 ulp */ + mpfr_mul_2si (s, a, m, GMP_RNDN); /* I compute s=a*2^m, err <= 1 ulp */ mpfr_div (rapport, tmp2, s, GMP_RNDN);/* I compute 4/s, err <= 2 ulps */ mpfr_agm (agm, tmp1, rapport, GMP_RNDN); /* AG(1,4/s), err<=3 ulps */ - mpfr_mul_2exp (tmp1, agm, 1, GMP_RNDN); /* 2*AG(1,4/s), still err<=3 ulps */ + mpfr_mul_2ui (tmp1, agm, 1, GMP_RNDN); /* 2*AG(1,4/s), still err<=3 ulps */ mpfr_const_pi (cst, GMP_RNDN); /* compute pi, err<=1ulp */ mpfr_div (tmp2, cst, tmp1, GMP_RNDN); /* pi/2*AG(1,4/s), err<=5ulps */ mpfr_const_log2 (cst, GMP_RNDN); /* compute log(2), err<=1ulp */ @@ -150,8 +149,8 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) mpfr_sub(cst,tmp2,tmp1,GMP_RNDN); /* log(a), err<=7ulps+cancel */ cancel -= MPFR_EXP(cst); #ifdef DEBUG - printf("cancelled bits=%d\n", cancel); - printf("approx="); mpfr_print_raw(cst); putchar('\n'); + printf("canceled bits=%d\n", cancel); + printf("approx="); mpfr_print_binary(cst); putchar('\n'); #endif if (cancel<0) cancel=0; @@ -159,11 +158,11 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) /* we have 7 ulps of error from the above roundings, 4 ulps from the 4/s^2 second order term, - plus the cancelled bits */ + plus the canceled bits */ if (mpfr_can_round (cst, p - cancel - 4, GMP_RNDN, rnd_mode, q) == 1) { inexact = mpfr_set (r, cst, rnd_mode); #ifdef DEBUG - printf("result="); mpfr_print_raw(r); putchar('\n'); + printf("result="); mpfr_print_binary(r); putchar('\n'); #endif bool=0; } diff --git a/mpfr/log_base_10.c b/mpfr/log10.c index b1e5e7d6f..b9e7a3ff7 100644 --- a/mpfr/log_base_10.c +++ b/mpfr/log10.c @@ -1,6 +1,6 @@ /* mpfr_log10 -- log in base 10 -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -31,9 +31,8 @@ MA 02111-1307, USA. */ */ int -mpfr_log10 (mpfr_ptr r, mpfr_srcptr a , mp_rnd_t rnd_mode) +mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) { - int inexact = 0; /* If a is NaN, the result is NaN */ @@ -43,58 +42,49 @@ mpfr_log10 (mpfr_ptr r, mpfr_srcptr a , mp_rnd_t rnd_mode) MPFR_RET_NAN; } - /* If a is negative, the result is NaN */ - if (MPFR_SIGN(a) < 0) - { - if (!MPFR_IS_INF(a) && MPFR_IS_ZERO(a)) - { - MPFR_CLEAR_NAN(r); - MPFR_SET_INF(r); - if (MPFR_SIGN(r) > 0) - MPFR_CHANGE_SIGN(r); - return 0; - } - else - { - MPFR_SET_NAN(r); - MPFR_RET_NAN; - } - } - MPFR_CLEAR_NAN(r); /* check for infinity before zero */ if (MPFR_IS_INF(a)) { - /* only +Inf can go here */ - MPFR_SET_INF(r); - if(MPFR_SIGN(r) < 0) - MPFR_CHANGE_SIGN(r); - return 0; + if (MPFR_SIGN(a) < 0) /* log10(-Inf) = NaN */ + { + MPFR_SET_NAN(r); + MPFR_RET_NAN; + } + else /* log10(+Inf) = +Inf */ + { + MPFR_SET_INF(r); + MPFR_SET_POS(r); + MPFR_RET(0); + } } /* Now we can clear the flags without damage even if r == a */ + MPFR_CLEAR_INF(r); - MPFR_CLEAR_INF(r); + if (MPFR_IS_ZERO(a)) + { + MPFR_SET_INF(r); + MPFR_SET_POS(r); + MPFR_RET(0); /* log10(0) is an exact infinity */ + } - if (MPFR_IS_ZERO(a)) + /* If a is negative, the result is NaN */ + if (MPFR_SIGN(a) < 0) { - MPFR_SET_INF(r); - if (MPFR_SIGN(r) > 0) - MPFR_CHANGE_SIGN(r); - /* Execption GMP*/ - return 0; + MPFR_SET_NAN(r); + MPFR_RET_NAN; } /* If a is 1, the result is 0 */ - if (mpfr_cmp_ui(a,1) == 0) + if (mpfr_cmp_ui(a, 1) == 0) { - MPFR_SET_SAME_SIGN(r,a); MPFR_SET_ZERO(r); - return 0; + MPFR_SET_POS(r); + MPFR_RET(0); /* only "normal" case where the result is exact */ } - /* General case */ { /* Declaration of the intermediary variable */ diff --git a/mpfr/log1p.c b/mpfr/log1p.c index 3eb4d110e..ae3e410a5 100644 --- a/mpfr/log1p.c +++ b/mpfr/log1p.c @@ -1,6 +1,6 @@ /* mpfr_log1p -- Compute log(1+x) -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -30,63 +30,58 @@ MA 02111-1307, USA. */ */ int -mpfr_log1p (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode) +mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { int comp, inexact = 0; if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } + MPFR_CLEAR_NAN(y); /* check for inf or -inf (result is not defined) */ if (MPFR_IS_INF(x)) - { - if(MPFR_SIGN(x) > 0) + { + if (MPFR_SIGN(x) > 0) { MPFR_SET_INF(y); - - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - - return 0; + MPFR_SET_POS(y); + MPFR_RET(0); } else { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } } comp = mpfr_cmp_si(x,-1); /* x<-1 undefined */ - if(comp < 0) - { - MPFR_SET_NAN(y); - return 1; + if (comp < 0) + { + MPFR_SET_NAN(y); + MPFR_RET_NAN; } /* x=0: log1p(-1)=-inf (division by zero) */ - if(comp == 0) + if (comp == 0) { - DIVIDE_BY_ZERO; /* Exception GMP */ - MPFR_SET_INF(y); - if (MPFR_SIGN(y) > 0) - MPFR_CHANGE_SIGN(y); - return 1; + MPFR_SET_INF(y); + MPFR_SET_POS(y); + MPFR_RET_NAN; } MPFR_CLEAR_INF(y); - if(!MPFR_NOTZERO(x)) + if (MPFR_IS_ZERO(x)) { MPFR_SET_ZERO(y); /* log1p(+/- 0) = +/- 0 */ MPFR_SET_SAME_SIGN(y, x); - return 0; + MPFR_RET(0); } - /* General case */ { /* Declaration of the intermediary variable */ diff --git a/mpfr/log2.c b/mpfr/log2.c index fcfc76920..80db9911e 100644 --- a/mpfr/log2.c +++ b/mpfr/log2.c @@ -1,6 +1,6 @@ -/* mpfr_const_log2 -- compute natural logarithm of 2 +/* mpfr_log2 -- log base 2 -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -22,165 +22,121 @@ MA 02111-1307, USA. */ #include <stdio.h> #include "gmp.h" #include "gmp-impl.h" -#include "longlong.h" #include "mpfr.h" #include "mpfr-impl.h" -mpfr_t __mpfr_const_log2; /* stored value of log(2) */ -int __mpfr_const_log2_prec=0; /* precision of stored value */ -mp_rnd_t __mpfr_const_log2_rnd; /* rounding mode of stored value */ - -static int mpfr_aux_log2 _PROTO ((mpfr_ptr, mpz_srcptr, int, int)); -static int mpfr_const_aux_log2 _PROTO ((mpfr_ptr, mp_rnd_t)); - -#define A -#define A1 1 -#define A2 1 -#undef B -#define C -#define C1 2 -#define C2 1 -#define NO_FACTORIAL -#undef R_IS_RATIONAL -#define GENERIC mpfr_aux_log2 -#include "generic.c" -#undef A -#undef A1 -#undef A2 -#undef NO_FACTORIAL -#undef GENERIC -#undef C -#undef C1 -#undef C2 - -static int -mpfr_const_aux_log2 (mpfr_ptr mylog, mp_rnd_t rnd_mode) -{ - int prec; - mpfr_t tmp1, tmp2, result,tmp3; - mpz_t cst; - int good = 0; - int logn; - int prec_i_want = MPFR_PREC(mylog); - int prec_x; - - mpz_init(cst); - logn = _mpfr_ceil_log2 ((double) MPFR_PREC(mylog)); - prec_x = prec_i_want + logn; - while (!good){ - prec = _mpfr_ceil_log2 ((double) prec_x); - mpfr_init2(tmp1, prec_x); - mpfr_init2(result, prec_x); - mpfr_init2(tmp2, prec_x); - mpfr_init2(tmp3, prec_x); - mpz_set_ui(cst, 1); - mpfr_aux_log2(tmp1, cst, 4, prec-2); - mpfr_div_2exp(tmp1, tmp1, 4,GMP_RNDD); - mpfr_mul_ui(tmp1, tmp1, 15,GMP_RNDD); - - mpz_set_ui(cst, 3); - mpfr_aux_log2(tmp2, cst, 7, prec-2); - mpfr_div_2exp(tmp2, tmp2, 7,GMP_RNDD); - mpfr_mul_ui(tmp2, tmp2, 5*3,GMP_RNDD); - mpfr_sub(result, tmp1, tmp2, GMP_RNDD); - - mpz_set_ui(cst, 13); - mpfr_aux_log2(tmp3, cst, 8, prec-2); - mpfr_div_2exp(tmp3, tmp3, 8,GMP_RNDD); - mpfr_mul_ui(tmp3, tmp3, 3*13,GMP_RNDD); - mpfr_sub(result, result, tmp3, GMP_RNDD); - - mpfr_clear(tmp1); - mpfr_clear(tmp2); - mpfr_clear(tmp3); - if (mpfr_can_round(result, prec_x, GMP_RNDD, rnd_mode, prec_i_want)){ - mpfr_set(mylog, result, rnd_mode); - good = 1; - } else - { - prec_x += logn; - } - mpfr_clear(result); - } - mpz_clear(cst); - return 0; -} - -/* Cross-over point from nai"ve Taylor series to binary splitting, - obtained experimentally on a Pentium II. Optimal value for - target machine should be determined by tuneup. */ -#define LOG2_THRESHOLD 25000 - -/* set x to log(2) rounded to precision MPFR_PREC(x) with direction rnd_mode - - use formula log(2) = sum(1/k/2^k, k=1..infinity) + /* The computation of r=log2(a) - whence 2^N*log(2) = S(N) + R(N) + r=log2(a)=log(a)/log(2) + */ - where S(N) = sum(2^(N-k)/k, k=1..N-1) - and R(N) = sum(1/k/2^(k-N), k=N..infinity) < 2/N +int +mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode) +{ + int inexact = 0; - Let S'(N) = sum(floor(2^(N-k)/k), k=1..N-1) + /* If a is NaN, the result is NaN */ + if (MPFR_IS_NAN(a)) + { + MPFR_SET_NAN(r); + MPFR_RET_NAN; + } - Then 2^N*log(2)-S'(N) <= N-1+2/N <= N for N>=2. -*/ -void -mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode) -{ - int N, oldN, k, precx; mpz_t s, t, u; - - precx = MPFR_PREC(x); - MPFR_CLEAR_FLAGS(x); - - /* has stored value enough precision ? */ - if (precx <= __mpfr_const_log2_prec) { - if (rnd_mode==__mpfr_const_log2_rnd || mpfr_can_round(__mpfr_const_log2, - __mpfr_const_log2_prec, __mpfr_const_log2_rnd, rnd_mode, precx)) - { - mpfr_set(x, __mpfr_const_log2, rnd_mode); return; - } - } + MPFR_CLEAR_NAN(r); - /* need to recompute */ - if (precx < LOG2_THRESHOLD) /* use nai"ve Taylor series evaluation */ + /* check for infinity before zero */ + if (MPFR_IS_INF(a)) { - N=2; - do + if (MPFR_SIGN(a) < 0) /* log(-Inf) = NaN */ { - oldN = N; - N = precx + _mpfr_ceil_log2 ((double) N); + MPFR_SET_NAN(r); + MPFR_RET_NAN; } - while (N != oldN); - mpz_init (s); /* set to zero */ - mpz_init (u); - mpz_init_set_ui (t, 1); - - /* use log(2) = sum((6*k-1)/(2*k^2-k)/2^(2*k+1), k=1..infinity) */ - mpz_mul_2exp (t, t, N-1); - for (k=1; k<N/2; k++) + else /* log(+Inf) = +Inf */ { - mpz_div_2exp (t, t, 2); - mpz_mul_ui (u, t, 6*k-1); - mpz_fdiv_q_ui (u, u, k*(2*k-1)); - mpz_add (s, s, u); + MPFR_SET_INF(r); + MPFR_SET_POS(r); + MPFR_RET(0); } + } - mpfr_set_z (x, s, rnd_mode); - MPFR_EXP(x) -= N; - mpz_clear (s); - mpz_clear (t); - mpz_clear (u); + /* Now we can clear the flags without damage even if r == a */ + MPFR_CLEAR_INF(r); + + if (MPFR_IS_ZERO(a)) + { + MPFR_SET_INF(r); + MPFR_SET_POS(r); + MPFR_RET(0); /* log(0) is an exact infinity */ + } + + /* If a is negative, the result is NaN */ + if (MPFR_SIGN(a) < 0) + { + MPFR_SET_NAN(r); + MPFR_RET_NAN; } - else /* use binary splitting method */ - mpfr_const_aux_log2(x, rnd_mode); - - /* store computed value */ - if (__mpfr_const_log2_prec == 0) - mpfr_init2 (__mpfr_const_log2, precx); - else - mpfr_set_prec (__mpfr_const_log2, precx); - - mpfr_set (__mpfr_const_log2, x, rnd_mode); - __mpfr_const_log2_prec = precx; - __mpfr_const_log2_rnd = rnd_mode; + + /* If a is 1, the result is 0 */ + if (mpfr_cmp_ui(a, 1) == 0) + { + MPFR_SET_ZERO(r); + MPFR_SET_POS(r); + MPFR_RET(0); /* only "normal" case where the result is exact */ + } + + /* If a is integer, log2(a) is exact*/ + if (mpfr_cmp_ui_2exp(a,1,MPFR_EXP(a)-1) == 0) + return mpfr_set_si(r,MPFR_EXP(a)-1,rnd_mode); + + + /* General case */ + { + /* Declaration of the intermediary variable */ + mpfr_t t, tt; + + /* Declaration of the size variable */ + mp_prec_t Nx = MPFR_PREC(a); /* Precision of input variable */ + mp_prec_t Ny = MPFR_PREC(r); /* Precision of input variable */ + + mp_prec_t Nt; /* Precision of the intermediary variable */ + long int err; /* Precision of error */ + + + /* compute the precision of intermediary variable */ + Nt=MAX(Nx,Ny); + /* the optimal number of bits : see algorithms.ps */ + Nt=Nt+3+_mpfr_ceil_log2(Nt); + + /* initialise of intermediary variable */ + mpfr_init(t); + mpfr_init(tt); + + + /* First computation of log2 */ + do { + + /* reactualisation of the precision */ + mpfr_set_prec(t,Nt); + mpfr_set_prec(tt,Nt); + + /* compute log2 */ + mpfr_const_log2(t,GMP_RNDD); /* log(2) */ + mpfr_log(tt,a,GMP_RNDN); /* log(a) */ + mpfr_div(t,tt,t,GMP_RNDN); /* log(a)/log(2) */ + + + /* estimation of the error */ + err=Nt-3; + + /* actualisation of the precision */ + Nt += 10; + } while ((err<0) || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny)); + + inexact = mpfr_set(r,t,rnd_mode); + + mpfr_clear(t); + mpfr_clear(tt); + } + return inexact; } diff --git a/mpfr/log_base_2.c b/mpfr/log_base_2.c deleted file mode 100644 index 234249e16..000000000 --- a/mpfr/log_base_2.c +++ /dev/null @@ -1,151 +0,0 @@ -/* mpfr_log2 -- log base 2 - -Copyright (C) 2001 Free Software Foundation, Inc. - -This file is part of the MPFR Library. - -The MPFR Library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or (at your -option) any later version. - -The MPFR Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with the MPFR Library; see the file COPYING.LIB. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA. */ - -#include <stdio.h> -#include "gmp.h" -#include "gmp-impl.h" -#include "mpfr.h" -#include "mpfr-impl.h" - - /* The computation of r=log2(a) - - r=log2(a)=log(a)/log(2) - */ - -int -mpfr_log2 (mpfr_ptr r, mpfr_srcptr a , mp_rnd_t rnd_mode) -{ - - int inexact = 0; - - /* If a is NaN, the result is NaN */ - if (MPFR_IS_NAN(a)) - { - MPFR_SET_NAN(r); - MPFR_RET_NAN; - } - - MPFR_CLEAR_NAN(r); - - /* If a is negative, the result is NaN */ - if (MPFR_SIGN(a) < 0) - { - if (!MPFR_IS_INF(a) && MPFR_IS_ZERO(a)) - { - MPFR_SET_INF(r); - if (MPFR_SIGN(r) > 0) - MPFR_CHANGE_SIGN(r); - return 0; - } - else - { - MPFR_SET_NAN(r); - MPFR_RET_NAN; - } - } - - /* check for infinity before zero */ - if (MPFR_IS_INF(a)) - { - MPFR_SET_INF(r); - if(MPFR_SIGN(r) < 0) - MPFR_CHANGE_SIGN(r); - return 0; - } - - /* Now we can clear the flags without damage even if r == a */ - - MPFR_CLEAR_INF(r); - - if (MPFR_IS_ZERO(a)) - { - MPFR_CLEAR_FLAGS(r); - MPFR_SET_INF(r); - if (MPFR_SIGN(r) > 0) - MPFR_CHANGE_SIGN(r); - /* Execption GMP*/ - return 0; - } - - /* If a is 1, the result is 0 */ - if (mpfr_cmp_ui(a,1) == 0) - { - MPFR_CLEAR_FLAGS(r); - MPFR_SET_SAME_SIGN(r,a); - MPFR_SET_ZERO(r); - return 0; - } - - /* If a is integer, log2(a) is exact*/ - if (mpfr_cmp_ui_2exp(a,1,MPFR_EXP(a)-1) == 0) - return mpfr_set_si(r,MPFR_EXP(a)-1,rnd_mode); - - - /* General case */ - { - /* Declaration of the intermediary variable */ - mpfr_t t, tt; - - /* Declaration of the size variable */ - mp_prec_t Nx = MPFR_PREC(a); /* Precision of input variable */ - mp_prec_t Ny = MPFR_PREC(r); /* Precision of input variable */ - - mp_prec_t Nt; /* Precision of the intermediary variable */ - long int err; /* Precision of error */ - - - /* compute the precision of intermediary variable */ - Nt=MAX(Nx,Ny); - /* the optimal number of bits : see algorithms.ps */ - Nt=Nt+3+_mpfr_ceil_log2(Nt); - - /* initialise of intermediary variable */ - mpfr_init(t); - mpfr_init(tt); - - - /* First computation of log2 */ - do { - - /* reactualisation of the precision */ - mpfr_set_prec(t,Nt); - mpfr_set_prec(tt,Nt); - - /* compute log2 */ - mpfr_const_log2(t,GMP_RNDD); /* log(2) */ - mpfr_log(tt,a,GMP_RNDN); /* log(a) */ - mpfr_div(t,tt,t,GMP_RNDN); /* log(a)/log(2) */ - - - /* estimation of the error */ - err=Nt-3; - - /* actualisation of the precision */ - Nt += 10; - } while ((err<0) || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny)); - - inexact = mpfr_set(r,t,rnd_mode); - - mpfr_clear(t); - mpfr_clear(tt); - } - return inexact; -} diff --git a/mpfr/minmax.c b/mpfr/minmax.c index 0cb986ceb..bc57da7e4 100644 --- a/mpfr/minmax.c +++ b/mpfr/minmax.c @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -32,50 +31,67 @@ MA 02111-1307, USA. */ */ int -mpfr_min (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y ,mp_rnd_t rnd_mode) +mpfr_min (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode) { - if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) ) + if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) ) { MPFR_SET_NAN(z); - return 1; + MPFR_RET_NAN; } - MPFR_CLEAR_NAN(z); - if (MPFR_IS_NAN(x) ) - return mpfr_set(z,y,rnd_mode); - - if (MPFR_IS_NAN(y) ) - return mpfr_set(z,x,rnd_mode); - - if(mpfr_cmp(x,y) <= 0) - return mpfr_set(z,x,rnd_mode); - else - return mpfr_set(z,y,rnd_mode); + MPFR_CLEAR_NAN(z); + + if (MPFR_IS_NAN(x)) + return mpfr_set(z, y, rnd_mode); + + if (MPFR_IS_NAN(y)) + return mpfr_set(z, x, rnd_mode); + + if (MPFR_IS_FP(x) && MPFR_IS_ZERO(x) && MPFR_IS_FP(y) && MPFR_IS_ZERO(y)) + { + if (MPFR_SIGN(x) < 0) + return mpfr_set(z, x, rnd_mode); + else + return mpfr_set(z, y, rnd_mode); + } + + if (mpfr_cmp(x,y) <= 0) + return mpfr_set(z, x, rnd_mode); + else + return mpfr_set(z, y, rnd_mode); } + /* The computation of z=max(x,y) z=x if x >= y z=y if x < y */ + int -mpfr_max (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y ,mp_rnd_t rnd_mode) +mpfr_max (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode) { - if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) ) + if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) ) { - MPFR_SET_NAN(z); - return 1; + MPFR_SET_NAN(z); + MPFR_RET_NAN; } - MPFR_CLEAR_NAN(z); - - if (MPFR_IS_NAN(x) ) - return mpfr_set(z,y,rnd_mode); - - if (MPFR_IS_NAN(y) ) - return mpfr_set(z,x,rnd_mode); - - if(mpfr_cmp(x,y) <= 0) - return mpfr_set(z,y,rnd_mode); - else - return mpfr_set(z,x,rnd_mode); -} + MPFR_CLEAR_NAN(z); + + if (MPFR_IS_NAN(x)) + return mpfr_set(z, y, rnd_mode); + if (MPFR_IS_NAN(y)) + return mpfr_set(z, x, rnd_mode); + if (MPFR_IS_FP(x) && MPFR_IS_ZERO(x) && MPFR_IS_FP(y) && MPFR_IS_ZERO(y)) + { + if (MPFR_SIGN(x) < 0) + return mpfr_set(z, y, rnd_mode); + else + return mpfr_set(z, x, rnd_mode); + } + + if (mpfr_cmp(x,y) <= 0) + return mpfr_set(z, y, rnd_mode); + else + return mpfr_set(z, x, rnd_mode); +} diff --git a/mpfr/mpf2mpfr.h b/mpfr/mpf2mpfr.h index 99b86204d..cdb374916 100644 --- a/mpfr/mpf2mpfr.h +++ b/mpfr/mpf2mpfr.h @@ -1,6 +1,6 @@ /* mpf2mpfr.h -- Compatibility include file with mpf. -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -50,7 +50,7 @@ MA 02111-1307, USA. */ #undef mpf_set_default_prec #define mpf_set_default_prec mpfr_set_default_prec #undef mpf_set_prec -#define mpf_set_prec(x,p) mpfr_round(x,__gmp_default_rounding_mode,p) +#define mpf_set_prec(x,p) mpfr_round_prec(x, __gmp_default_rounding_mode, p) #undef mpf_set_prec_raw #define mpf_set_prec_raw mpfr_set_prec_raw #undef mpf_trunc diff --git a/mpfr/mpfr-impl.h b/mpfr/mpfr-impl.h index fc18e4a01..0eb06aa08 100644 --- a/mpfr/mpfr-impl.h +++ b/mpfr/mpfr-impl.h @@ -1,6 +1,6 @@ /* Utilities for MPFR developers, not exported. -Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,6 +19,11 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Test if X (positive) is a power of 2 */ + +#define IS_POW2(X) (((X) & ((X) - 1)) == 0) +#define NOT_POW2(X) (((X) & ((X) - 1)) != 0) + /* This unsigned type must correspond to the signed one defined in gmp.h */ #if defined (_CRAY) && ! defined (_CRAYMPP) typedef unsigned int mp_exp_unsigned_t; @@ -28,17 +33,32 @@ typedef unsigned long int mp_exp_unsigned_t; typedef unsigned long int mp_size_unsigned_t; #endif +#define MP_EXP_T_MAX ((mp_exp_t) ((~ (mp_exp_unsigned_t) 0) >> 1)) +#define MP_EXP_T_MIN (-MP_EXP_T_MAX-1) + #define MP_LIMB_T_ONE ((mp_limb_t) 1) +#if (BITS_PER_MP_LIMB & (BITS_PER_MP_LIMB - 1)) +#error "BITS_PER_MP_LIMB must be a power of 2" +#endif + +#define MPFR_INTPREC_MAX (ULONG_MAX & ~(unsigned long) (BITS_PER_MP_LIMB - 1)) + /* Assertions */ /* Compile with -DWANT_ASSERT to check all assert statements */ -/* MPFR_ASSERTN(expr): assertion checked in the normal debug level */ -#define MPFR_ASSERTN(expr) ASSERT_ALWAYS(expr) +/* MPFR_ASSERTN(expr): assertions that should always be checked */ +/* #define MPFR_ASSERTN(expr) ASSERT_ALWAYS(expr) */ +#define MPFR_ASSERTN(expr) ((expr) ? (void) 0 : (void) ASSERT_FAIL (expr)) -/* MPFR_ASSERTD(expr): assertion checked in debug level 33 or higher */ -#define MPFR_ASSERTD(expr) ASSERT(expr) +/* MPFR_ASSERTD(expr): assertions that should be checked when testing */ +/* #define MPFR_ASSERTD(expr) ASSERT(expr) */ +#if WANT_ASSERT +#define MPFR_ASSERTD(expr) ASSERT_ALWAYS (expr) +#else +#define MPFR_ASSERTD(expr) ((void) 0) +#endif /* Definition of constants */ @@ -77,6 +97,9 @@ typedef union ieee_double_extract Ieee_double_extract; #define MPFR_IS_FP(x) ((((x) -> _mpfr_size >> 29) & 3) == 0) #define MPFR_ABSSIZE(x) \ ((x)->_mpfr_size & (((mp_size_unsigned_t) 1 << 29) - 1)) +#define MPFR_SET_ABSSIZE(x, n) \ + ((x)->_mpfr_size = ((x)->_mpfr_size & ((mp_size_unsigned_t) 7 << 29)) \ + | (mp_size_unsigned_t) (n)) #define MPFR_SIZE(x) ((x)->_mpfr_size) #define MPFR_EXP(x) ((x)->_mpfr_exp) #define MPFR_MANT(x) ((x)->_mpfr_d) @@ -105,15 +128,33 @@ typedef union ieee_double_extract Ieee_double_extract; (I) ? ((__mpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0 #define MPFR_RET_NAN return (__mpfr_flags |= MPFR_FLAGS_NAN), 0 +/* The following macro restores the exponent range and the flags, + checks that the result is in the exponent range and returns the + ternary inexact value. */ +#define MPFR_RESTORE_RET(inex, x, rnd_mode) \ + do \ + { \ + int inex_cr; \ + mpfr_restore_emin_emax(); \ + inex_cr = mpfr_check_range(x, rnd_mode); \ + if (inex_cr) \ + return inex_cr; /* underflow or overflow */ \ + MPFR_RET(inex); \ + } \ + while(0) + /* Memory gestion */ /* temporary allocate s limbs at xp, and initialize mpfr variable x */ #define MPFR_INIT(xp, x, p, s) \ - (xp = (mp_ptr) TMP_ALLOC((s)*BYTES_PER_MP_LIMB), \ - MPFR_PREC(x) = p, MPFR_MANT(x) = xp, MPFR_SIZE(x) = s, MPFR_EXP(x) = 0) + (xp = (mp_ptr) TMP_ALLOC((size_t) (s) * BYTES_PER_MP_LIMB), \ + MPFR_PREC(x) = (p), \ + MPFR_MANT(x) = (xp), \ + MPFR_SIZE(x) = (s), \ + MPFR_EXP(x) = 0) /* same when xp is already allocated */ #define MPFR_INIT1(xp, x, p, s) \ - (MPFR_PREC(x) = p, MPFR_MANT(x) = xp, MPFR_SIZE(x) = s) + (MPFR_PREC(x) = (p), MPFR_MANT(x) = (xp), MPFR_SIZE(x) = (s)) #ifndef _PROTO #if defined (__STDC__) || defined (__cplusplus) @@ -134,15 +175,15 @@ void mpfr_restore_emin_emax _PROTO ((void)); int mpfr_add1 _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t, mp_exp_unsigned_t)); int mpfr_sub1 _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, - mp_rnd_t, mp_exp_unsigned_t)); + mp_rnd_t, int)); int mpfr_round_raw_generic _PROTO ((mp_limb_t *, mp_limb_t *, mp_prec_t, int, mp_prec_t, mp_rnd_t, int *, int)); -int mpfr_can_round_raw _PROTO ((mp_limb_t *, mp_prec_t, int, mp_prec_t, +int mpfr_can_round_raw _PROTO ((mp_limb_t *, mp_size_t, int, mp_exp_t, mp_rnd_t, mp_rnd_t, mp_prec_t)); -double mpfr_get_d2 _PROTO ((mpfr_srcptr, long)); +double mpfr_get_d2 _PROTO ((mpfr_srcptr, mp_exp_t)); mp_size_t mpn_sqrtrem_new _PROTO ((mp_limb_t *, mp_limb_t *, mp_limb_t *, mp_size_t)); int mpfr_cmp_abs _PROTO ((mpfr_srcptr, mpfr_srcptr)); -mp_prec_t mpfr_cmp2 _PROTO ((mpfr_srcptr, mpfr_srcptr)); +int mpfr_cmp2 _PROTO ((mpfr_srcptr, mpfr_srcptr, mp_prec_t *)); long _mpfr_ceil_log2 _PROTO ((double)); long _mpfr_floor_log2 _PROTO ((double)); double _mpfr_ceil_exp2 _PROTO ((double)); @@ -153,10 +194,9 @@ unsigned long _mpfr_cuberoot _PROTO ((unsigned long)); mpfr_round_raw_generic((yp), (xp), (xprec), (neg), (yprec), (r), (inexp), 0) #define mpfr_round_raw2(xp, xn, neg, r, prec) \ - mpfr_round_raw_generic(NULL, (xp), (xn) * BITS_PER_MP_LIMB, (neg), \ + mpfr_round_raw_generic(0, (xp), (xn) * BITS_PER_MP_LIMB, (neg), \ (prec), (r), 0, 1); #if defined (__cplusplus) } #endif - diff --git a/mpfr/mpfr-test.h b/mpfr/mpfr-test.h index aed0c8a5d..a436a5fb6 100644 --- a/mpfr/mpfr-test.h +++ b/mpfr/mpfr-test.h @@ -51,7 +51,7 @@ double Ulp _PROTO ((double)); /* generate a random double using the whole range of possible values, including denormalized numbers, NaN, infinities, ... */ double -drand () +drand (void) { double d; int *i, expo; diff --git a/mpfr/mpfr.h b/mpfr/mpfr.h index ac161cc11..97b054f9c 100644 --- a/mpfr/mpfr.h +++ b/mpfr/mpfr.h @@ -38,7 +38,7 @@ MA 02111-1307, USA. */ /* Definition of exponent limits */ -#define MPFR_EMAX_DEFAULT ((mp_exp_t) (((unsigned long) 1 <<31)-1)) +#define MPFR_EMAX_DEFAULT ((mp_exp_t) (((unsigned long) 1 << 31) - 1)) #define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT)) #define MPFR_EMIN_MIN MPFR_EMIN_DEFAULT @@ -57,7 +57,11 @@ MA 02111-1307, USA. */ /* Definitions of types and their semantics */ typedef unsigned long int mp_prec_t; /* easy to change if necessary */ -typedef int mp_rnd_t; /* preferred to char */ +#define MPFR_PREC_MIN 2 +#define MPFR_PREC_MAX (ULONG_MAX >> 1) +/* Limit mainly due to the multiplication code. */ + +typedef int mp_rnd_t; typedef struct { mp_prec_t _mpfr_prec; /* WARNING : for the mpfr type, the precision */ @@ -98,7 +102,16 @@ typedef __gmp_const __mpfr_struct *mpfr_srcptr; /* Prototypes */ #ifndef _PROTO -#define _PROTO(x) __GMP_PROTO(x) +#if defined (__STDC__) || defined (__cplusplus) +#define _PROTO(x) x +#else +#define _PROTO(x) () +#endif +#endif + +/* _PROTO will be renamed __GMP_PROTO in gmp 4.1 */ +#ifndef __GMP_PROTO +#define __GMP_PROTO(x) _PROTO(x) #endif #if defined (__cplusplus) @@ -125,18 +138,18 @@ int mpfr_inexflag_p _PROTO ((void)); void mpfr_init2 _PROTO ((mpfr_ptr, mp_prec_t)); void mpfr_init _PROTO ((mpfr_ptr)); -int mpfr_round _PROTO ((mpfr_ptr, mp_rnd_t, mp_prec_t)); -int mpfr_can_round _PROTO ((mpfr_ptr, mp_prec_t, mp_rnd_t, mp_rnd_t, +int mpfr_round_prec _PROTO ((mpfr_ptr, mp_rnd_t, mp_prec_t)); +int mpfr_can_round _PROTO ((mpfr_ptr, mp_exp_t, mp_rnd_t, mp_rnd_t, mp_prec_t)); int mpfr_set_d _PROTO ((mpfr_ptr, double, mp_rnd_t)); int mpfr_set_z _PROTO ((mpfr_ptr, mpz_srcptr, mp_rnd_t)); -mp_exp_t mpz_set_fr _PROTO ((mpz_ptr, mpfr_srcptr)); +mp_exp_t mpfr_get_z_exp _PROTO ((mpz_ptr, mpfr_srcptr)); int mpfr_set_q _PROTO ((mpfr_ptr, mpq_srcptr, mp_rnd_t)); double mpfr_get_d _PROTO ((mpfr_srcptr)); int mpfr_set_f _PROTO ((mpfr_ptr, mpf_srcptr, mp_rnd_t)); int mpfr_set_si _PROTO ((mpfr_ptr, long, mp_rnd_t)); int mpfr_set_ui _PROTO ((mpfr_ptr, unsigned long, mp_rnd_t)); -void mpfr_print_raw _PROTO ((mpfr_srcptr)); +void mpfr_print_binary _PROTO ((mpfr_srcptr)); void mpfr_random _PROTO ((mpfr_ptr)); void mpfr_random2 _PROTO ((mpfr_ptr, mp_size_t, mp_exp_t)); void mpfr_urandomb _PROTO ((mpfr_ptr, gmp_randstate_t)); @@ -160,7 +173,7 @@ int mpfr_sqrt_ui _PROTO ((mpfr_ptr, unsigned long, mp_rnd_t)); int mpfr_add _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); int mpfr_add_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); int mpfr_sub_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); -void mpfr_add_one_ulp _PROTO ((mpfr_ptr)); +int mpfr_add_one_ulp _PROTO ((mpfr_ptr, mp_rnd_t)); int mpfr_sub _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); int mpfr_ui_sub _PROTO ((mpfr_ptr, unsigned long, mpfr_srcptr, mp_rnd_t)); void mpfr_reldiff _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); @@ -179,6 +192,10 @@ int mpfr_cmp_ui_2exp _PROTO ((mpfr_srcptr, unsigned long int, int)); int mpfr_cmp_si_2exp _PROTO ((mpfr_srcptr, long int, int)); int mpfr_mul_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); int mpfr_div_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); +int mpfr_mul_2ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); +int mpfr_div_2ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); +int mpfr_mul_2si _PROTO((mpfr_ptr, mpfr_srcptr, long int, mp_rnd_t)); +int mpfr_div_2si _PROTO((mpfr_ptr, mpfr_srcptr, long int, mp_rnd_t)); int mpfr_set_prec _PROTO((mpfr_ptr, mp_prec_t)); void mpfr_set_prec_raw _PROTO((mpfr_ptr, mp_prec_t)); void mpfr_set_default_prec _PROTO((mp_prec_t)); @@ -187,15 +204,17 @@ extern mp_prec_t __mpfr_default_fp_bit_precision; extern mp_rnd_t __gmp_default_rounding_mode; char * mpfr_print_rnd_mode _PROTO((mp_rnd_t)); int mpfr_neg _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); -void mpfr_sub_one_ulp _PROTO((mpfr_ptr)); +int mpfr_sub_one_ulp _PROTO((mpfr_ptr, mp_rnd_t)); int mpfr_div_ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); int mpfr_ui_div _PROTO((mpfr_ptr, unsigned long int, mpfr_srcptr, mp_rnd_t)); mp_prec_t mpfr_get_prec _PROTO((mpfr_srcptr)); void mpfr_set_default_rounding_mode _PROTO((mp_rnd_t)); int mpfr_eq _PROTO((mpfr_srcptr, mpfr_srcptr, unsigned long)); -void mpfr_floor _PROTO((mpfr_ptr, mpfr_srcptr)); -void mpfr_trunc _PROTO((mpfr_ptr, mpfr_srcptr)); -void mpfr_ceil _PROTO((mpfr_ptr, mpfr_srcptr)); +int mpfr_rint _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_round _PROTO((mpfr_ptr, mpfr_srcptr)); +int mpfr_trunc _PROTO((mpfr_ptr, mpfr_srcptr)); +int mpfr_ceil _PROTO((mpfr_ptr, mpfr_srcptr)); +int mpfr_floor _PROTO((mpfr_ptr, mpfr_srcptr)); void mpfr_extract _PROTO((mpz_ptr, mpfr_srcptr, unsigned int)); void mpfr_swap _PROTO((mpfr_ptr, mpfr_ptr)); void mpfr_dump _PROTO((mpfr_srcptr, mp_rnd_t)); @@ -204,6 +223,7 @@ int mpfr_cmp3 _PROTO ((mpfr_srcptr, mpfr_srcptr, int)); int mpfr_nan_p _PROTO((mpfr_srcptr)); int mpfr_inf_p _PROTO((mpfr_srcptr)); int mpfr_number_p _PROTO((mpfr_srcptr)); +int mpfr_acos _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_asin _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_atan _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); @@ -275,12 +295,19 @@ int mpfr_sub_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t)); #define mpfr_inexflag_p() \ ((int) (__mpfr_flags & MPFR_FLAGS_INEXACT)) +#define mpfr_round(a,b) mpfr_rint((a), (b), GMP_RNDN) +#define mpfr_trunc(a,b) mpfr_rint((a), (b), GMP_RNDZ) +#define mpfr_ceil(a,b) mpfr_rint((a), (b), GMP_RNDU) +#define mpfr_floor(a,b) mpfr_rint((a), (b), GMP_RNDD) + #define mpfr_cmp_ui(b,i) mpfr_cmp_ui_2exp((b),(i),0) #define mpfr_cmp_si(b,i) mpfr_cmp_si_2exp((b),(i),0) #define mpfr_set(a,b,r) mpfr_set4(a,b,r,MPFR_SIGN(b)) #define mpfr_abs(a,b,r) mpfr_set4(a,b,r,1) #define mpfr_cmp(b, c) mpfr_cmp3(b, c, 1) #define mpfr_sgn(x) mpfr_cmp_ui(x,0) +#define mpfr_mul_2exp(y,x,n,r) mpfr_mul_2ui((y),(x),(n),(r)) +#define mpfr_div_2exp(y,x,n,r) mpfr_div_2ui((y),(x),(n),(r)) #define mpfr_init_set_si(x, i, rnd) \ ( mpfr_init(x), mpfr_set_si((x), (i), (rnd)) ) diff --git a/mpfr/mpfr.texi b/mpfr/mpfr.texi index 3c62c1963..547b667c6 100644 --- a/mpfr/mpfr.texi +++ b/mpfr/mpfr.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @c %**start of header @setfilename mpfr.info -@settitle MPFR 1.0 +@settitle MPFR 2002 @synindex tp fn @iftex @afourpaper @@ -62,7 +62,7 @@ by the Foundation. @title MPFR @subtitle The Multiple Precision Floating-Point Reliable Library -@subtitle Edition 1.1 +@subtitle Edition 2002 @subtitle November 2001 @author the MPFR team, LORIA/INRIA Lorraine @@ -108,7 +108,7 @@ by the Foundation. @top MPFR This manual documents how to install and use the Multiple Precision -Floating-Point Reliable Library, version 1.0 +Floating-Point Reliable Library, version 2002 @end ifinfo @@ -177,8 +177,8 @@ with the @code{mpf} class are: @item the @code{mpfr} code is portable, i.e. the result of any operation does not depend (or should not) on the machine word size @code{mp_bits_per_limb} (32 or 64 on most machines); -@item the precision in bits can be set exactly to any positive value -for each variable (including one bit of precision); +@item the precision in bits can be set exactly to any valid value +for each variable (including very small precision); @item @code{mpfr} provides the four rounding modes from the IEEE 754 standard. @end itemize @@ -374,6 +374,9 @@ in the floating-point format, like 0 divided by 0, or Infinity minus Infinity. The @dfn{Precision} is the number of bits used to represent the mantissa of a floating-point number; the corresponding C data type is @code{mp_prec_t}. +The precision can be any integer between @code{MPFR_PREC_MIN} and +@code{MPFR_PREC_MAX}. In the current implementation, @code{MPFR_PREC_MIN} +is equal to 2 and @code{MPFR_PREC_MAX} is equal to @code{ULONG_MAX}. @cindex Rounding Mode @tindex @code{mp_rnd_t} @@ -547,7 +550,7 @@ Sets the default rounding mode to @var{rnd}. The default rounding mode is to nearest initially. @end deftypefun -@deftypefun int mpfr_round (mpfr_t @var{x}, mp_rnd_t @var{rnd}, mp_prec_t @var{prec}) +@deftypefun int mpfr_round_prec (mpfr_t @var{x}, mp_rnd_t @var{rnd}, mp_prec_t @var{prec}) Rounds @var{x} according to @var{rnd} with precision @var{prec}, which may be different from that of @var{x}. If @var{prec} is greater or equal to the precision of @var{x}, then new @@ -556,6 +559,8 @@ Otherwise, the mantissa is rounded to precision @var{prec} with the given direction. In both cases, the precision of @var{x} is changed to @var{prec}. The returned value is zero when the result is exact, positive when it is greater than the original value of @var{x}, and negative when it is smaller. +The precision @var{prec} can be any integer between @code{MPFR_PREC_MIN} and +@code{MPFR_PREC_MAX}. @end deftypefun @c @deftypefun void mpfr_set_machine_rnd_mode (mp_rnd_t @var{rnd}) @@ -633,7 +638,8 @@ All subsequent calls to @code{mpfr_init} will use this precision, but previously initialized variables are unaffected. This default precision is set to 53 bits initially. -The precision can be any positive integer, even a precision of 1 is possible. +The precision can be any integer between @code{MPFR_PREC_MIN} and +@code{MPFR_PREC_MAX}. @end deftypefun @deftypefun mp_prec_t mpfr_get_default_prec () @@ -659,6 +665,8 @@ Normally, a variable should be initialized once only or at least be cleared, using @code{mpfr_clear}, between initializations. To change the precision of a variable which has already been initialized, use @code{mpfr_set_prec} instead. +The precision @var{prec} can be any integer between @code{MPFR_PREC_MIN} and +@code{MPFR_PREC_MAX}. @end deftypefun @deftypefun void mpfr_clear (mpfr_t @var{x}) @@ -691,11 +699,11 @@ The previous value stored in @var{x} is lost. It is equivalent to a call to @code{mpfr_clear(x)} followed by a call to @code{mpfr_init2(x, prec)}, but more efficient as no allocation is done in case the current allocated space for the mantissa of @var{x} is enough. -It is not allowed to set @var{prec} to zero: in that case, a non-zero value -is returned, as well as when the allocation fails. +The precision @var{prec} can be any integer between @code{MPFR_PREC_MIN} and +@code{MPFR_PREC_MAX}. In case you want to keep the previous value stored in @var{x}, -use @code{mpfr_round} instead. +use @code{mpfr_round_prec} instead. @end deftypefun @deftypefun mp_prec_t mpfr_get_prec (mpfr_t @var{x}) @@ -739,11 +747,13 @@ to a mpfr floating-point number. @end deftypefun @deftypefun int mpfr_set_str (mpfr_t @var{x}, char *@var{s}, int @var{base}, mp_rnd_t @var{rnd}) -Set @var{x} to the value of the string @var{s} in base @var{base}, -rounded in direction @var{rnd} to the precision of @var{x}. +Set @var{x} to the value of the string @var{s} in base @var{base} (between +2 and 36), rounded in direction @var{rnd} to the precision of @var{x}. The exponent is read in decimal. -This function returns 0 if the entire string up to the final '\0' is a valid -number in base @var{base}, and @minus{}1 otherwise. +This function returns @minus{}1 if an internal overflow occurred (for +instance, because the exponent is too large). Otherwise it returns 0 +if the base is valid and if the entire string up to the final '\0' is +a valid number in base @var{base}, and 1 if the input is incorrect. @end deftypefun @deftypefun void mpfr_set_str_raw (mpfr_t @var{x}, char *@var{s}) @@ -794,7 +804,7 @@ and negative when @var{rop}<@var{op}. @end deftypefn @deftypefun int mpfr_init_set_str (mpfr_t @var{x}, char *@var{s}, int @var{base}, mp_rnd_t @var{rnd}) -Initialize @var{x} and sets its value from +Initialize @var{x} and set its value from the string @var{s} in base @var{base}, rounded to direction @var{rnd}. See @code{mpfr_set_str}. @@ -809,38 +819,49 @@ See @code{mpfr_set_str}. Convert @var{op} to a double, using the current @emph{machine} rounding mode. @end deftypefun +@deftypefun mp_exp_t mpfr_get_z_exp (mpz_t @var{z}, mpfr_t @var{op}) +Puts the mantissa of @var{op} into @var{z}, and returns the exponent +@var{exp} such that @var{op} equals @var{z} multiplied by two exponent +@var{exp}. +@end deftypefun + @deftypefun {char *} mpfr_get_str (char *@var{str}, mp_exp_t *@var{expptr}, int @var{base}, size_t @var{n_digits}, mpfr_t @var{op}, mp_rnd_t @var{rnd}) Convert @var{op} to a string of digits in base @var{base}, with rounding in direction @var{rnd}. The base may vary from 2 to 36. Generate exactly @var{n_digits} significant digits. -If @var{n_digits} is 0, it prints the maximum possible number of digits +If @var{n_digits} is 0, it writes the maximum possible number of digits giving an exact rounding in the given base @var{base} with the direction @var{rnd}. In other words, if @var{op} was the exact rounding -of a real number in direction @var{rnd}, then the printed value is also +of a real number in direction @var{rnd}, then the written value is also an exact rounding in base @var{base} of that real number with the same precision. An error occurs when one is unable to determine the leading digit, which can happen especially if the precision of @var{op} is small. -If @var{str} is NULL, space for the mantissa is allocated using the default -allocation function, and a pointer to the string is returned. +If @var{str} is a null pointer, space for the mantissa is allocated using +the default allocation function, and a pointer to the string is returned. In that case, the user should her/himself free the corresponding memory with @code{(*_mp_free_func)(s, strlen(s) + 1)}. -If @var{str} is not NULL, it should point to a block of storage large enough -for the mantissa, i.e., @var{n_digits} + 2. The two extra bytes are for a -possible minus sign, and for the terminating null character. +If @var{str} is not a null pointer, it should point to a block of storage +large enough for the mantissa, i.e., @var{n_digits} + 2 or more. The extra +two bytes are for a possible minus sign, and for the terminating null +character. -The exponent is written through the pointer @var{expptr}. +If the input number is a real number, the exponent is written through +the pointer @var{expptr} (the current minimal exponent for 0). -If @var{n_digits} is 0, note that the space -requirements for @var{str} in this case will be impossible for the user to -predetermine. Therefore, one needs to pass NULL for the string argument -whenever @var{n_digits} is 0. +If @var{n_digits} is 0, note that the space requirements for @var{str} +in this case will be impossible for the user to predetermine. Therefore, +one needs to pass a null pointer for the string argument whenever +@var{n_digits} is 0. The generated string is a fraction, with an implicit radix point immediately to the left of the first digit. For example, the number 3.1416 would be returned as "31416" in the string and 1 written at @var{expptr}. + +A pointer to the string is returned, unless there is an error, in which +case a null pointer is returned. @end deftypefun @@ -1023,8 +1044,7 @@ Both @var{op1} and @var{op2} are considered to their full own precision, which may differ. In case @var{op1} and @var{op2} are of same sign but different, the absolute value returned is one plus the absolute difference of their exponents. -In case one of the operands is NaN (Not-a-Number), it returns 1, even if -both are NaN. +It is not allowed that one of the operands is NaN (Not-a-Number). @end deftypefun @deftypefun int mpfr_cmp_ui_2exp (mpfr_t @var{op1}, unsigned long int @var{op2}, int @var{e}) @@ -1161,12 +1181,12 @@ Set @var{rop} to the arithmetic-geometric mean of @var{op1} and @var{op2}, rounded to the direction @var{rnd} with the precision of @var{rop}. @end deftypefun -@deftypefun int mpfr_asin (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd}) +@deftypefun int mpfr_acos (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd}) +@deftypefunx int mpfr_asin (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd}) @deftypefunx int mpfr_atan (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd}) -Set @var{rop} to the arc-sine or arc-tangent of @var{op}, +Set @var{rop} to the arc-cosine, arc-sine or arc-tangent of @var{op}, rounded to the direction @var{rnd} with the precision of @var{rop}. -Return 0 iff the result is exact (this occurs in fact only when @var{op} is 0 -i.e. the result is 0). +Return 0 iff the result is exact. @end deftypefun @deftypefun void mpfr_const_log2 (mpfr_t @var{rop}, mp_rnd_t @var{rnd}) @@ -1198,7 +1218,7 @@ rounded to the direction @var{rnd} with the precision of @var{rop}. Functions that perform input from a standard input/output stream, and functions that output to a standard input/output stream. -Passing a NULL pointer for a @var{stream} argument to any of +Passing a null pointer for a @var{stream} argument to any of these functions will make them read from @code{stdin} and write to @code{stdout}, respectively. @@ -1245,7 +1265,7 @@ numbers like @samp{0.23} are not interpreted as octal. Return the number of bytes read, or if an error occurred, return 0. @end deftypefun -@deftypefun void mpfr_print_raw (mpfr_t @var{float}) +@deftypefun void mpfr_print_binary (mpfr_t @var{float}) Output @var{float} on stdout in raw binary format (the exponent is in decimal, yet). The last bits from the least significant limb which do not belong to @@ -1264,12 +1284,23 @@ they should always be zero. @section Miscellaneous Functions @cindex Miscellaneous float functions -@deftypefun void mpfr_ceil (mpfr_t @var{rop}, mpfr_t @var{op}) -@deftypefunx void mpfr_floor (mpfr_t @var{rop}, mpfr_t @var{op}) -@deftypefunx void mpfr_trunc (mpfr_t @var{rop}, mpfr_t @var{op}) +@deftypefun int mpfr_rint (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd}) +@deftypefunx int mpfr_ceil (mpfr_t @var{rop}, mpfr_t @var{op}) +@deftypefunx int mpfr_floor (mpfr_t @var{rop}, mpfr_t @var{op}) +@deftypefunx int mpfr_round (mpfr_t @var{rop}, mpfr_t @var{op}) +@deftypefunx int mpfr_trunc (mpfr_t @var{rop}, mpfr_t @var{op}) Set @var{rop} to @var{op} rounded to an integer. @code{mpfr_ceil} rounds -to the next higher integer, @code{mpfr_floor} to the next lower, -and @code{mpfr_trunc} to the integer towards zero. +to the next higher representable integer, @code{mpfr_floor} to the next lower, +@code{mpfr_round} to the nearest representable integer, rounding halfway cases +away from zero, and @code{mpfr_trunc} to the representable integer towards +zero. @code{mpfr_rint} behaves like one of these four functions, depending +on the rounding mode. +The returned value is zero when the result is exact, positive when it is +greater than the original value of @var{op}, and negative when it is smaller. +More precisely, the returned value is 0 when @var{op} is an integer +representable in @var{rop}, 1 or @minus{}1 when @var{op} is an integer +that is not representable in @var{rop}, 2 or @minus{}2 when @var{op} is +not an integer. @end deftypefun @deftypefun void mpfr_urandomb (mpfr_t @var{rop}, gmp_randstate_t @var{state}) @@ -1306,19 +1337,22 @@ These functions were mainly designed for the implementation of @code{mpfr}, but may be useful for users too. You need to include @code{mpfr-impl.h} to use them. -@deftypefun int mpfr_add_one_ulp (mpfr_t @var{x}) -Add one unit in last place (ulp) to the mantissa of @var{x} -if it is positive or zero, and subtracts one ulp otherwise. -Always return 0 (result is exact). +@deftypefun int mpfr_add_one_ulp (mpfr_t @var{x}, mp_rnd_t @var{rnd}) +Add one unit in last place (ulp) to @var{x} if @var{x} is finite +and positive, subtract one ulp if @var{x} is finite and negative; +otherwise, @var{x} is not changed. +The return value is zero unless an overflow occurs, in which case the +@code{mpfr_add_one_ulp} function behaves like a conventional addition. @end deftypefun -@deftypefun int mpfr_sub_one_ulp (mpfr_t @var{x}) -Subtract one ulp to @var{x} if it is positive or zero, -and adds one ulp otherwise. -Always return 0 (result is exact). +@deftypefun int mpfr_sub_one_ulp (mpfr_t @var{x}, mp_rnd_t @var{rnd}) +Subtract one ulp to @var{x} if @var{x} is finite and positive, add one +ulp if @var{x} is finite and negative; otherwise, @var{x} is not changed. +The return value is zero unless an underflow occurs, in which case the +@code{mpfr_sub_one_ulp} function behaves like a conventional subtraction. @end deftypefun -@deftypefun int mpfr_can_round (mpfr_t @var{b}, mp_prec_t @var{err}, mp_rnd_t @var{rnd1}, mp_rnd_t @var{rnd2}, mp_prec_t @var{prec}) +@deftypefun int mpfr_can_round (mpfr_t @var{b}, mp_exp_t @var{err}, mp_rnd_t @var{rnd1}, mp_rnd_t @var{rnd2}, mp_prec_t @var{prec}) Assuming @var{b} is an approximation of an unknown number @var{x} in direction @var{rnd1} with error at most two to the power E(b)-@var{err} where E(b) is the exponent of diff --git a/mpfr/mpz_set_fr.c b/mpfr/mpz_set_fr.c index ff5c636b7..da30e5479 100644 --- a/mpfr/mpz_set_fr.c +++ b/mpfr/mpz_set_fr.c @@ -1,6 +1,7 @@ -/* mpz_set_fr -- set a multiple-precision integer from a floating-point number +/* mpfr_get_z_exp -- get a multiple-precision integer and an exponent + from a floating-point number -Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +Copyright (C) 2000-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,24 +20,35 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" -#include "mpfr.h" -#include "mpfr-impl.h" #include "gmp-impl.h" #include "longlong.h" +#include "mpfr.h" +#include "mpfr-impl.h" /* puts the mantissa of f into z, and returns 'exp' such that f = z * 2^exp + * + * 0 doesn't have an exponent, therefore the returned exponent in this case + * isn't really important. We choose to return __mpfr_emin because + * 1) it is in the exponent range [__mpfr_emin,__mpfr_emax], + * 2) the smaller a number is (in absolute value), the smaller its + * exponent is. In other words, the f -> exp function is monotonous + * on nonnegative numbers. + * Note that this is different from the C function frexp(). */ + mp_exp_t -mpz_set_fr (mpz_ptr z, mpfr_srcptr f) +mpfr_get_z_exp (mpz_ptr z, mpfr_srcptr f) { - int fn, sh; + mp_size_t fn; + int sh; + + MPFR_ASSERTN(MPFR_IS_FP(f)); - if (MPFR_IS_NAN(f) || MPFR_IS_INF(f)) + if (MPFR_IS_ZERO(f)) { - fprintf (stderr, "Error in mpz_set_fr: input is NaN or Inf\n"); - exit (1); + mpz_set_ui (z, 0); + return __mpfr_emin; } fn = 1 + (MPFR_PREC(f) - 1) / BITS_PER_MP_LIMB; @@ -45,13 +57,15 @@ mpz_set_fr (mpz_ptr z, mpfr_srcptr f) if (ALLOC(z) < fn) MPZ_REALLOC(z, fn); - sh = fn * BITS_PER_MP_LIMB - MPFR_PREC(f); + sh = (mp_prec_t) fn * BITS_PER_MP_LIMB - MPFR_PREC(f); if (sh) mpn_rshift (PTR(z), MPFR_MANT(f), fn, sh); else MPN_COPY (PTR(z), MPFR_MANT(f), fn); - SIZ(z) = (MPFR_MANT(f)[fn-1] == 0 ? 0 : fn); + SIZ(z) = fn; + MPFR_ASSERTN((mp_exp_unsigned_t) MPFR_EXP(f) - MPFR_EMIN_MIN + >= (mp_exp_unsigned_t) MPFR_PREC(f)); return MPFR_EXP(f) - MPFR_PREC(f); } diff --git a/mpfr/mul.c b/mpfr/mul.c index 9165f0430..2ac3e5140 100644 --- a/mpfr/mul.c +++ b/mpfr/mul.c @@ -1,6 +1,6 @@ /* mpfr_mul -- multiply two floating-point numbers -Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -28,73 +27,124 @@ MA 02111-1307, USA. */ int mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) { - unsigned int bn, cn, an, tn, k; - int cc, inexact = 0; - mp_limb_t *ap=MPFR_MANT(a), *bp=MPFR_MANT(b), *cp=MPFR_MANT(c), *tmp, b1; - long int sign_product; - mp_prec_t prec_a=MPFR_PREC(a), prec_b=MPFR_PREC(b), prec_c=MPFR_PREC(c); - TMP_DECL(marker); + int sign_product, cc, inexact, ec, em = 0; + mp_exp_t bx, cx; + mp_limb_t *ap, *bp, *cp, *tmp; + mp_limb_t b1; + mp_prec_t aq, bq, cq; + mp_size_t an, bn, cn, tn, k; + TMP_DECL(marker); /* deal with NaN and zero */ if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) { - MPFR_CLEAR_FLAGS(a); MPFR_SET_NAN(a); - return 1; + MPFR_RET_NAN; } + MPFR_CLEAR_NAN(a); + + sign_product = MPFR_SIGN(b) * MPFR_SIGN(c); + if (MPFR_IS_INF(b)) { - if (!MPFR_NOTZERO(c)) - { - MPFR_CLEAR_FLAGS(a); - MPFR_SET_NAN(a); - return 1; - } + if (MPFR_IS_INF(c) || MPFR_NOTZERO(c)) + { + if (MPFR_SIGN(a) != sign_product) + MPFR_CHANGE_SIGN(a); + MPFR_SET_INF(a); + MPFR_RET(0); /* exact */ + } else { - if (MPFR_SIGN(a) != MPFR_SIGN(b) * MPFR_SIGN(c)) - MPFR_CHANGE_SIGN(a); - MPFR_CLEAR_FLAGS(a); - MPFR_SET_INF(a); - return 0; + MPFR_SET_NAN(a); + MPFR_RET_NAN; } } else if (MPFR_IS_INF(c)) { - if (!MPFR_NOTZERO(b)) - { - MPFR_CLEAR_FLAGS(a); - MPFR_SET_NAN(a); - return 1; - } + if (MPFR_NOTZERO(b)) + { + if (MPFR_SIGN(a) != sign_product) + MPFR_CHANGE_SIGN(a); + MPFR_SET_INF(a); + MPFR_RET(0); /* exact */ + } else { - if (MPFR_SIGN(a) != MPFR_SIGN(b) * MPFR_SIGN(c)) - MPFR_CHANGE_SIGN(a); - MPFR_CLEAR_FLAGS(a); - MPFR_SET_INF(a); - return 0; + MPFR_SET_NAN(a); + MPFR_RET_NAN; } } - if (!MPFR_NOTZERO(b) || !MPFR_NOTZERO(c)) + MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_IS_FP(c)); + MPFR_CLEAR_INF(a); /* clear Inf flag */ + + if (MPFR_IS_ZERO(b) || MPFR_IS_ZERO(c)) { - MPFR_CLEAR_FLAGS(a); + if (MPFR_SIGN(a) != sign_product) + MPFR_CHANGE_SIGN(a); MPFR_SET_ZERO(a); - return 0; + MPFR_RET(0); /* 0 * 0 is exact */ } - sign_product = MPFR_SIGN(b) * MPFR_SIGN(c); + bx = MPFR_EXP(b); + cx = MPFR_EXP(c); + /* Note: exponent of the result will be bx + cx + ec with ec in {-1,0,1} */ + if (bx >= 0 && cx > 0) + { /* bx + cx > 0 */ + if (__mpfr_emax < 0 || + (mp_exp_unsigned_t) bx + cx > (mp_exp_unsigned_t) __mpfr_emax + 1) + return mpfr_set_overflow(a, rnd_mode, sign_product); + + if ((mp_exp_unsigned_t) bx + cx == (mp_exp_unsigned_t) __mpfr_emax + 1) + em = 1; + } + else if (bx <= 0 && cx < 0) + { /* bx + cx < 0 */ + if (__mpfr_emin > 0 || + (mp_exp_unsigned_t) bx + cx < (mp_exp_unsigned_t) __mpfr_emin - 1) + return mpfr_set_underflow(a, rnd_mode, sign_product); + + if ((mp_exp_unsigned_t) bx + cx == (mp_exp_unsigned_t) __mpfr_emin - 1) + em = -1; + } + else + { /* bx != 0 and cx doesn't have the same sign */ + if ((bx + cx) - 1 > __mpfr_emax) + return mpfr_set_overflow(a, rnd_mode, sign_product); + + if ((bx + cx) - 1 == __mpfr_emax) + em = 1; + + if ((bx + cx) + 1 < __mpfr_emin) + return mpfr_set_underflow(a, rnd_mode, sign_product); + + if ((bx + cx) + 1 == __mpfr_emin) + em = -1; + } + + ap = MPFR_MANT(a); + bp = MPFR_MANT(b); + cp = MPFR_MANT(c); + + aq = MPFR_PREC(a); + bq = MPFR_PREC(b); + cq = MPFR_PREC(c); + + an = (aq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of a */ + bn = (bq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of b */ + cn = (cq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of c */ + + MPFR_ASSERTN((mp_size_unsigned_t) bn + cn <= MP_SIZE_T_MAX); + k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */ - MPFR_CLEAR_FLAGS(a); - an = (prec_a - 1)/BITS_PER_MP_LIMB + 1; /* nb of significant limbs of a */ - bn = (prec_b - 1)/BITS_PER_MP_LIMB + 1; /* nb of significant limbs of b */ - cn = (prec_c - 1)/BITS_PER_MP_LIMB + 1; /* nb of significant limbs of c */ - tn = (prec_c + prec_b - 1)/BITS_PER_MP_LIMB + 1; - k = bn + cn; /* effective nb of limbs used by b*c (=tn or tn+1) */ + MPFR_ASSERTN(bq + cq >= bq); /* no integer overflow */ + tn = (bq + cq - 1) / BITS_PER_MP_LIMB + 1; /* <= k, thus no int overflow */ + + MPFR_ASSERTN(k <= ((size_t) -1) / BYTES_PER_MP_LIMB); TMP_MARK(marker); - tmp = (mp_limb_t*) TMP_ALLOC(k * BYTES_PER_MP_LIMB); + tmp = (mp_limb_t *) TMP_ALLOC((size_t) k * BYTES_PER_MP_LIMB); /* multiplies two mantissa in temporary allocated space */ b1 = (bn >= cn) ? mpn_mul (tmp, bp, bn, cp, cn) @@ -106,17 +156,44 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) tmp += k - tn; if (b1 == 0) - mpn_lshift (tmp, tmp, tn, 1); - cc = mpfr_round_raw (ap, tmp, prec_b + prec_c, sign_product < 0, prec_a, + mpn_lshift (tmp, tmp, tn, 1); + cc = mpfr_round_raw (ap, tmp, bq + cq, sign_product < 0, aq, rnd_mode, &inexact); if (cc) /* cc = 1 ==> result is a power of two */ ap[an-1] = MP_LIMB_T_HIGHBIT; TMP_FREE(marker); - MPFR_EXP(a) = MPFR_EXP(b) + MPFR_EXP(c) + b1 - 1 + cc; + ec = b1 - 1 + cc; + + if (em == 0) + { + mp_exp_t ax = bx + cx; + + if (ax == __mpfr_emax && ec > 0) + return mpfr_set_overflow(a, rnd_mode, sign_product); + + if (ax == __mpfr_emin && ec < 0) + return mpfr_set_underflow(a, rnd_mode, sign_product); + + MPFR_EXP(a) = ax + ec; + } + else if (em > 0) + { + if (ec >= 0) + return mpfr_set_overflow(a, rnd_mode, sign_product); + + MPFR_EXP(a) = __mpfr_emax; + } + else + { + if (ec <= 0) + return mpfr_set_underflow(a, rnd_mode, sign_product); + + MPFR_EXP(a) = __mpfr_emin; + } - if (sign_product * MPFR_SIGN(a) < 0) + if (MPFR_SIGN(a) != sign_product) MPFR_CHANGE_SIGN(a); return inexact; diff --git a/mpfr/mul_2exp.c b/mpfr/mul_2exp.c index e070896a3..6f3ef9eb3 100644 --- a/mpfr/mul_2exp.c +++ b/mpfr/mul_2exp.c @@ -19,21 +19,17 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" #include "mpfr-impl.h" +/* Obsolete function, use mpfr_mul_2ui or mpfr_mul_2si instead. */ + +#undef mpfr_mul_2exp + int mpfr_mul_2exp (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mp_rnd_t rnd_mode) { - int inexact = 0; - - /* Important particular case */ - if (y != x) - inexact = mpfr_set (y, x, rnd_mode); - return ((MPFR_EXP(y) += n) > __mpfr_emax) - ? mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y)) : inexact; + return mpfr_mul_2ui (y, x, n, rnd_mode); } - diff --git a/mpfr/mul_2si.c b/mpfr/mul_2si.c new file mode 100644 index 000000000..b1189242f --- /dev/null +++ b/mpfr/mul_2si.c @@ -0,0 +1,48 @@ +/* mpfr_mul_2si -- multiply a floating-point number by a power of two + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +mpfr_mul_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) +{ + int inexact; + + inexact = y != x ? mpfr_set (y, x, rnd_mode) : 0; + + if (MPFR_IS_FP(y) && MPFR_NOTZERO(y)) + { + if (n > 0 && (__mpfr_emax < MPFR_EMIN_MIN + n || + MPFR_EXP(y) > __mpfr_emax - n)) + return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y)); + + if (n < 0 && (__mpfr_emin > MPFR_EMAX_MAX + n || + MPFR_EXP(y) < __mpfr_emin - n)) + return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y)); + + MPFR_EXP(y) += n; + } + + return inexact; +} diff --git a/mpfr/mul_2ui.c b/mpfr/mul_2ui.c new file mode 100644 index 000000000..64ac7c7ae --- /dev/null +++ b/mpfr/mul_2ui.c @@ -0,0 +1,59 @@ +/* mpfr_mul_2ui -- multiply a floating-point number by a power of two + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +mpfr_mul_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mp_rnd_t rnd_mode) +{ + int inexact; + + inexact = y != x ? mpfr_set (y, x, rnd_mode) : 0; + + if (MPFR_IS_FP(y) && MPFR_NOTZERO(y)) + { + /* n will have to be casted to long to make sure that the addition + and subtraction below (for overflow detection) are signed */ + while (n > LONG_MAX) + { + int inex2; + + n -= LONG_MAX; + inex2 = mpfr_mul_2ui(y, y, LONG_MAX, rnd_mode); + if (inex2) + return inex2; /* overflow */ + } + + /* MPFR_EMIN_MIN + (long) n is signed and doesn't lead to an overflow; + the first test useful so that the real test can't lead to an + overflow. */ + if (__mpfr_emax < MPFR_EMIN_MIN + (long) n || + MPFR_EXP(y) > __mpfr_emax - (long) n) + return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y)); + + MPFR_EXP(y) += (long) n; + } + + return inexact; +} diff --git a/mpfr/mul_ui.c b/mpfr/mul_ui.c index 8c916273d..72f9decef 100644 --- a/mpfr/mul_ui.c +++ b/mpfr/mul_ui.c @@ -1,6 +1,6 @@ /* mpfr_mul_ui -- multiply a floating-point number by a machine integer -Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -29,90 +28,94 @@ MA 02111-1307, USA. */ int mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) { - mp_limb_t *my, *old_my; - unsigned long xn, yn, cnt, c; - int inexact; + mp_limb_t *yp, *old_yp; + mp_size_t xn, yn; + int cnt, c, inexact; TMP_DECL(marker); if (MPFR_IS_NAN(x)) { - MPFR_CLEAR_FLAGS(y); MPFR_SET_NAN(y); - return 1; /* a NaN is always inexact */ + MPFR_RET_NAN; } if (MPFR_IS_INF(x)) { - MPFR_CLEAR_FLAGS(y); - if (u) - { - MPFR_SET_INF(y); - if (MPFR_SIGN(y) != MPFR_SIGN(x)) - MPFR_CHANGE_SIGN(y); - return 0; /* infinity is exact */ + if (u != 0) + { + MPFR_CLEAR_FLAGS(y); + MPFR_SET_INF(y); + MPFR_SET_SAME_SIGN(y, x); + MPFR_RET(0); /* infinity is exact */ } else /* 0 * infinity */ { MPFR_SET_NAN(y); - return 1; /* NaN is inexact */ + MPFR_RET_NAN; } } - if (MPFR_IS_ZERO(x) || !u) + MPFR_CLEAR_FLAGS(y); + + if (u == 0 || MPFR_IS_ZERO(x)) { - MPFR_CLEAR_FLAGS(y); MPFR_SET_ZERO(y); - return 0; /* zero is exact */ + MPFR_SET_SAME_SIGN(y, x); + MPFR_RET(0); /* zero is exact */ } - MPFR_CLEAR_FLAGS(y); - if (u == 1) return mpfr_set (y, x, rnd_mode); TMP_MARK(marker); - my = MPFR_MANT(y); + yp = MPFR_MANT(y); yn = (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB + 1; xn = (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB + 1; - old_my = my; + old_yp = yp; + MPFR_ASSERTN(xn < MP_SIZE_T_MAX); if (yn < xn + 1) - my = (mp_ptr) TMP_ALLOC ((xn + 1) * BYTES_PER_MP_LIMB); + yp = (mp_ptr) TMP_ALLOC ((size_t) (xn + 1) * BYTES_PER_MP_LIMB); + + yp[xn] = mpn_mul_1 (yp, MPFR_MANT(x), xn, u); - my[xn] = mpn_mul_1 (my, MPFR_MANT(x), xn, u); - - /* x * u is stored in my[xn], ..., my[0] */ + /* x * u is stored in yp[xn], ..., yp[0] */ /* since the case u=1 was treated above, we have u >= 2, thus - my[xn] >= 1 since x was msb-normalized */ - MPFR_ASSERTN(my[xn] != 0); - cnt = 0; - if ((my[xn] & MP_LIMB_T_HIGHBIT) == 0) + yp[xn] >= 1 since x was msb-normalized */ + MPFR_ASSERTN(yp[xn] != 0); + if ((yp[xn] & MP_LIMB_T_HIGHBIT) == 0) { - count_leading_zeros(cnt, my[xn]); - mpn_lshift (my, my, xn + 1, cnt); + count_leading_zeros(cnt, yp[xn]); + mpn_lshift (yp, yp, xn + 1, cnt); + } + else + { + cnt = 0; } - /* now my[xn], ..., my[0] is msb-normalized too, and has at most + /* now yp[xn], ..., yp[0] is msb-normalized too, and has at most PREC(x) + (BITS_PER_MP_LIMB - cnt) non-zero bits */ - c = mpfr_round_raw (old_my, my, (xn + 1) * BITS_PER_MP_LIMB, + c = mpfr_round_raw (old_yp, yp, (mp_prec_t) (xn + 1) * BITS_PER_MP_LIMB, (MPFR_SIGN(x) < 0), MPFR_PREC(y), rnd_mode, &inexact); - MPFR_EXP(y) = MPFR_EXP(x) + BITS_PER_MP_LIMB - cnt; + cnt = BITS_PER_MP_LIMB - cnt; if (c) /* rounded result is 1.0000000000000000... */ { - old_my[yn-1] = MP_LIMB_T_HIGHBIT; - MPFR_EXP(y) ++; + old_yp[yn-1] = MP_LIMB_T_HIGHBIT; + cnt++; } - /* set sign */ - if (MPFR_SIGN(y) * MPFR_SIGN(x) < 0) - MPFR_CHANGE_SIGN(y); - TMP_FREE(marker); + if (__mpfr_emax < MPFR_EMAX_MIN + cnt || MPFR_EXP(x) > __mpfr_emax - cnt) + return mpfr_set_overflow(y, rnd_mode, MPFR_SIGN(x)); + + MPFR_EXP(y) = MPFR_EXP(x) + cnt; + MPFR_SET_SAME_SIGN(y, x); + return inexact; } diff --git a/mpfr/out_str.c b/mpfr/out_str.c index 0ad99983c..964aa9951 100644 --- a/mpfr/out_str.c +++ b/mpfr/out_str.c @@ -21,6 +21,7 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <string.h> +#include <limits.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -42,7 +43,7 @@ mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op, if (MPFR_IS_INF(op)) { - if (MPFR_SIGN(op) == 1) + if (MPFR_SIGN(op) > 0) { fprintf (stream, "Inf"); return 3; @@ -54,20 +55,27 @@ mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op, } } - if (!MPFR_NOTZERO(op)) + if (MPFR_IS_ZERO(op)) { - l = (MPFR_SIGN(op) < 0) ? fprintf (stream, "-") : 0; - fprintf(stream, "0"); - return l + 1; + if (MPFR_SIGN(op) > 0) + { + fprintf(stream, "0"); + return 1; + } + else + { + fprintf(stream, "-0"); + return 2; + } } - if (!MPFR_NOTZERO(op)) { fprintf(stream, "0"); return 1; } s = mpfr_get_str (NULL, &e, base, n_digits, op, rnd_mode); s0 = s; /* for op=3.1416 we have s = "31416" and e = 1 */ - - l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str */ + + l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str + - may be incorrect, as only an upper bound? */ if (*s == '-') fputc (*s++, stream); @@ -78,9 +86,12 @@ mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op, (*__gmp_free_func) (s0, l); /* outputs exponent */ - if (e) { - l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), e); - } + if (e) + { + MPFR_ASSERTN(e >= LONG_MIN); + MPFR_ASSERTN(e <= LONG_MAX); + l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e); + } return l; } diff --git a/mpfr/pow.c b/mpfr/pow.c index 60398c340..af4bddec7 100644 --- a/mpfr/pow.c +++ b/mpfr/pow.c @@ -1,6 +1,6 @@ /* mpfr_pow -- power function x^y -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -24,128 +24,110 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" - /* The computation of y=pow(x,z) is done by - - y=exp(z*log(x))=x^z - */ +/* The computation of z = pow(x,y) is done by + z = exp(y * log(x)) = x^y */ int -mpfr_pow (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) +mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode) { int inexact = 0; - if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ) + if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y)) { - MPFR_SET_NAN(z); - return 1; + MPFR_SET_NAN(z); + MPFR_RET_NAN; } if (MPFR_IS_INF(y)) { - mpfr_t px; - mpfr_init2(px,MPFR_PREC(x)); - mpfr_abs(px,x,GMP_RNDN); - if(MPFR_SIGN(y)>0) + mpfr_t one; + int cmp; + + if (MPFR_SIGN(y) > 0) { - if(MPFR_IS_INF(x)) - { - if(MPFR_SIGN(x)>0) + if (MPFR_IS_INF(x)) { MPFR_CLEAR_FLAGS(z); - MPFR_SET_INF(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + if (MPFR_SIGN(x) > 0) + MPFR_SET_INF(z); + else + MPFR_SET_ZERO(z); + MPFR_SET_POS(z); + MPFR_RET(0); } - else + MPFR_CLEAR_FLAGS(z); + if (MPFR_IS_ZERO(x)) { - MPFR_CLEAR_FLAGS(z); MPFR_SET_ZERO(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } - } - if(mpfr_cmp_ui(px,1) > 0) + mpfr_init2(one, BITS_PER_MP_LIMB); + mpfr_set_ui(one, 1, GMP_RNDN); + cmp = mpfr_cmp_abs(x, one); + mpfr_clear(one); + if (cmp > 0) { - MPFR_CLEAR_FLAGS(z); MPFR_SET_INF(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } - if(mpfr_cmp_ui(px,1) < 0) + else if (cmp < 0) { - MPFR_CLEAR_FLAGS(z); MPFR_SET_ZERO(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } - if(mpfr_cmp_ui(px,1)==0) + else { - MPFR_CLEAR_FLAGS(z); MPFR_SET_NAN(z); - mpfr_clear(px); - return 1; + MPFR_RET_NAN; } } else { - if(MPFR_IS_INF(x)) - { - if(MPFR_SIGN(x)>0) + if (MPFR_IS_INF(x)) { MPFR_CLEAR_FLAGS(z); - MPFR_SET_ZERO(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + if (MPFR_SIGN(x) > 0) + MPFR_SET_ZERO(z); + else + MPFR_SET_INF(z); + MPFR_SET_POS(z); + MPFR_RET(0); } - else + if (MPFR_IS_ZERO(x)) { - MPFR_CLEAR_FLAGS(z); MPFR_SET_INF(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } - } - if(mpfr_cmp_ui(px,1) > 0) + mpfr_init2(one, BITS_PER_MP_LIMB); + mpfr_set_ui(one, 1, GMP_RNDN); + cmp = mpfr_cmp_abs(x, one); + mpfr_clear(one); + MPFR_CLEAR_FLAGS(z); + if (cmp > 0) { - MPFR_CLEAR_FLAGS(z); MPFR_SET_ZERO(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } - if(mpfr_cmp_ui(px,1) < 0) + else if (cmp < 0) { - MPFR_CLEAR_FLAGS(z); MPFR_SET_INF(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - mpfr_clear(px); - return 0; + MPFR_SET_POS(z); + MPFR_RET(0); } - if(mpfr_cmp_ui(px,1)==0) + else { - MPFR_CLEAR_FLAGS(z); MPFR_SET_NAN(z); - mpfr_clear(px); - return 1; + MPFR_RET_NAN; } } } - if(MPFR_IS_ZERO(y)) + if (MPFR_IS_ZERO(y)) { return mpfr_set_ui(z,1,GMP_RNDN); } @@ -157,7 +139,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) int exptol; mpz_init(zi); - exptol=mpz_set_fr(zi,y); + exptol = mpfr_get_z_exp (zi, y); if (exptol>0) mpz_mul_2exp(zi, zi, exptol); @@ -169,50 +151,42 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode) mpz_clear(zi); return mpfr_pow_si(z,x,zii,rnd_mode); } + if (MPFR_IS_INF(x)) { if (MPFR_SIGN(x) > 0) { - if (MPFR_SIGN(y) >0) - { - MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(z); + if (MPFR_SIGN(y) > 0) MPFR_SET_INF(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - return 0; - } - else - { - MPFR_CLEAR_FLAGS(z); + else MPFR_SET_ZERO(z); - if(MPFR_SIGN(z) <0) - MPFR_CHANGE_SIGN(z); - return 0; - } + MPFR_SET_POS(z); + MPFR_RET(0); } else { - MPFR_CLEAR_FLAGS(z); - MPFR_SET_NAN(z); - return 1; + MPFR_SET_NAN(z); + MPFR_RET_NAN; } - } - - MPFR_CLEAR_INF(z); - if(MPFR_SIGN(x) < 0) - { - MPFR_CLEAR_FLAGS(z); - MPFR_SET_NAN(z); - return 1; } - MPFR_CLEAR_NAN(z); - if(mpfr_cmp_ui(x,0) == 0) + if (MPFR_IS_ZERO(x)) { MPFR_CLEAR_FLAGS(z); MPFR_SET_ZERO(z); - return 0; + MPFR_SET_SAME_SIGN(z, x); + MPFR_RET(0); + } + + if (MPFR_SIGN(x) < 0) + { + MPFR_SET_NAN(z); + MPFR_RET_NAN; } + + MPFR_CLEAR_FLAGS(z); + /* General case */ { /* Declaration of the intermediary variable */ diff --git a/mpfr/pow_si.c b/mpfr/pow_si.c index 07cb58151..0380b2fa7 100644 --- a/mpfr/pow_si.c +++ b/mpfr/pow_si.c @@ -1,6 +1,6 @@ /* mpfr_pow_si -- power function x^y with y an unsigned int -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -34,77 +34,47 @@ MA 02111-1307, USA. */ int mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) { - - if (n>0) - return mpfr_pow_ui(y,x,(unsigned long int)n,rnd_mode); + if (n > 0) + return mpfr_pow_ui(y, x, n, rnd_mode); else { - int inexact = 0; - n=-n; - - /* x is NaN*/ - if (MPFR_IS_NAN(x)) + if (MPFR_IS_NAN(x)) { - MPFR_SET_NAN(y); - return 1; + MPFR_SET_NAN(y); + MPFR_RET_NAN; } + MPFR_CLEAR_NAN(y); - /* n=0 */ - if(n==0) - return mpfr_set_ui(y,1,GMP_RNDN);; + if (n == 0) + return mpfr_set_ui(y, 1, GMP_RNDN); - /* case x is INF */ - if(MPFR_IS_INF(x)) + if (MPFR_IS_INF(x)) { - if(MPFR_SIGN(x)>0) /* +Inf */ - { - MPFR_SET_ZERO(y); - if(MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 0; - } + MPFR_SET_ZERO(y); + if (MPFR_SIGN(x) > 0 || ((unsigned) n & 1) == 0) + MPFR_SET_POS(y); else - { - MPFR_SET_ZERO(y); /* -Inf */ - if(!(n%2)) /* n is odd */ - { - if(MPFR_SIGN(y) > 0) - MPFR_CHANGE_SIGN(y); - } - else /* n is not odd */ - { - if(MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - } - return 0; - } + MPFR_SET_NEG(y); + MPFR_RET(0); } - /* case x=0 */ - if(mpfr_cmp_ui(x,0) == 0) + if (MPFR_IS_ZERO(x)) { - if(!(n%2)) /* n is odd */ - { - MPFR_SET_INF(y); - MPFR_SET_SAME_SIGN(y,x); - DIVIDE_BY_ZERO; /* Execption GMP*/ - return 0; - } - else /* n is not odd */ - { - MPFR_SET_INF(y); - if(MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - DIVIDE_BY_ZERO; /* Execption GMP*/ - return 0; - } + MPFR_SET_INF(y); + if (MPFR_SIGN(x) > 0 || ((unsigned) n & 1) == 0) + MPFR_SET_POS(y); + else + MPFR_SET_NEG(y); + MPFR_RET(0); } MPFR_CLEAR_INF(y); + n = -n; + /* General case */ { /* Declaration of the intermediary variable */ @@ -133,7 +103,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) mpfr_set_prec(ti,Nt); /* compute 1/(x^n) n>0*/ - mpfr_pow_ui(ti,y,(unsigned long int)(n),GMP_RNDN); + mpfr_pow_ui(ti,x,(unsigned long int)(n),GMP_RNDN); mpfr_ui_div(t,1,ti,GMP_RNDN); /* estimation of the error -- see pow function in algorithms.ps*/ diff --git a/mpfr/pow_ui.c b/mpfr/pow_ui.c index 42a3ee3ee..0badba7e4 100644 --- a/mpfr/pow_ui.c +++ b/mpfr/pow_ui.c @@ -1,7 +1,7 @@ /* mpfr_pow_ui-- compute the power of a floating-point by a machine integer -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -20,7 +20,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-impl.h" @@ -46,24 +45,22 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd) if (n == 0) /* x^0 = 1 for any x */ { - mpfr_set_ui (x, 1, rnd); - return 0; + /* The return mpfr_set_ui is important as 1 isn't necessarily + in the exponent range. */ + return mpfr_set_ui (x, 1, rnd); } - if (MPFR_IS_INF(y)) + if (MPFR_IS_INF(y)) { /* Inf^n = Inf, (-Inf)^n = Inf for n even, -Inf for n odd */ if ((MPFR_SIGN(y) < 0) && (n % 2 == 1)) - { - if (MPFR_SIGN(x) > 0) - MPFR_CHANGE_SIGN(x); - } - else if (MPFR_SIGN(x) < 0) - MPFR_CHANGE_SIGN(x); + MPFR_SET_NEG(x); + else + MPFR_SET_POS(x); MPFR_SET_INF(x); - return 0; + MPFR_RET(0); } - + MPFR_CLEAR_INF(x); mpfr_init (res); diff --git a/mpfr/print_raw.c b/mpfr/print_raw.c index c78c1faa1..0f127f2a1 100644 --- a/mpfr/print_raw.c +++ b/mpfr/print_raw.c @@ -1,4 +1,4 @@ -/* mpfr_print_raw -- print the internal binary representation of a +/* mpfr_print_binary -- print the internal binary representation of a floating-point number Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. @@ -59,7 +59,7 @@ mpfr_get_str_raw (char *digit_ptr, mpfr_srcptr x) } void -mpfr_print_raw (mpfr_srcptr x) +mpfr_print_binary (mpfr_srcptr x) { char *str; unsigned long alloc_size; diff --git a/mpfr/rint.c b/mpfr/rint.c new file mode 100644 index 000000000..05875cda1 --- /dev/null +++ b/mpfr/rint.c @@ -0,0 +1,261 @@ +/* mpfr_rint -- Round to an integer. + +Copyright (C) 1999-2002 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode) +{ + int sign; + mp_exp_t exp; + + if (MPFR_IS_NAN(u)) + { + MPFR_SET_NAN(r); + MPFR_RET_NAN; + } + + MPFR_CLEAR_NAN(r); + MPFR_SET_SAME_SIGN(r, u); + + if (MPFR_IS_INF(u)) + { + MPFR_SET_INF(r); + MPFR_RET(0); /* infinity is exact */ + } + + MPFR_CLEAR_INF(r); + + if (MPFR_IS_ZERO(u)) + { + MPFR_SET_ZERO(r); + MPFR_RET(0); /* zero is exact */ + } + + sign = MPFR_SIGN(u); + exp = MPFR_EXP(u); + + /* Single out the case where |u| < 1. */ + if (exp <= 0) /* 0 < |u| < 1 */ + { + if ((rnd_mode == GMP_RNDD && sign < 0) || + (rnd_mode == GMP_RNDU && sign > 0) || + (rnd_mode == GMP_RNDN && exp == 0)) + { + mp_limb_t *rp; + mp_size_t rm; + + rp = MPFR_MANT(r); + rm = (MPFR_PREC(r) - 1) / BITS_PER_MP_LIMB; + rp[rm] = MP_LIMB_T_HIGHBIT; + MPN_ZERO(rp, rm); + MPFR_EXP(r) = 1; /* |r| = 1 */ + MPFR_RET(sign > 0 ? 2 : -2); + } + else + { + MPFR_SET_ZERO(r); /* r = 0 */ + MPFR_RET(sign > 0 ? -2 : 2); + } + } + else /* exp > 0, |u| >= 1 */ + { + mp_limb_t *up, *rp; + mp_size_t un, rn, ui; + int sh, idiff; + int uflags; + + /* + * uflags will contain: + * _ 0 if u is an integer representable in r, + * _ 1 if u is an integer not representable in r, + * _ 2 if u is not an integer. + */ + + up = MPFR_MANT(u); + rp = MPFR_MANT(r); + + un = MPFR_ESIZE(u); + rn = MPFR_ESIZE(r); + sh = rn * BITS_PER_MP_LIMB - MPFR_PREC(r); + + MPFR_EXP(r) = exp; + + if ((exp - 1) / BITS_PER_MP_LIMB >= un) + { + ui = un; + idiff = 0; + uflags = 0; /* u is an integer */ + } + else + { + mp_size_t uj; + + ui = (exp - 1) / BITS_PER_MP_LIMB + 1; /* #limbs of the int part */ + uj = un - ui; /* lowest limb of the integer part */ + idiff = exp % BITS_PER_MP_LIMB; /* #int-part bits in up[uj] or 0 */ + + uflags = idiff == 0 || (up[uj] << idiff) == 0 ? 0 : 2; + if (uflags == 0) + while (uj > 0) + if (up[--uj] != 0) + { + uflags = 2; + break; + } + } + + if (ui > rn) + { + MPFR_ASSERTN(rp != up && un > rn); + MPN_COPY(rp, up + (un - rn), rn); + /* In the rounding to the nearest mode, if the rounding bit + is 0, change the rounding mode to GMP_RNDZ. */ + if (rnd_mode == GMP_RNDN && + ((sh != 0 && (rp[0] & (MP_LIMB_T_ONE << (sh - 1))) == 0) || + (sh == 0 && (up[un - rn - 1] & MP_LIMB_T_HIGHBIT) == 0))) + rnd_mode = GMP_RNDZ; + if (uflags == 0) + { /* u is an integer; determine if it is representable */ + if (sh != 0 && rp[0] << (BITS_PER_MP_LIMB - sh) != 0) + uflags = 1; /* u is not representable in r */ + else + { + mp_size_t i; + for (i = un - rn - 1; i >= 0; i--) + if (up[i] != 0) + { + uflags = 1; /* u is not representable in r */ + break; + } + } + } + if (sh != 0) + rp[0] &= MP_LIMB_T_MAX << sh; + } + else + { + mp_size_t uj, rj; + int ush; + + uj = un - ui; /* lowest limb of the integer part in u */ + rj = rn - ui; /* lowest limb of the integer part in r */ + + MPN_ZERO(rp, rj); + + if (rp != up) + MPN_COPY(rp + rj, up + uj, ui); + + rp += rj; + rn = ui; + + ush = idiff == 0 ? 0 : BITS_PER_MP_LIMB - idiff; + if (rj == 0 && ush < sh) + { + /* In the rounding to the nearest mode, if the rounding bit + is 0, change the rounding mode to GMP_RNDZ. */ + if (rnd_mode == GMP_RNDN && + (rp[0] & (MP_LIMB_T_ONE << (sh - 1))) == 0) + rnd_mode = GMP_RNDZ; /* rounding bit is 0 */ + if (uflags == 0) + { /* u is an integer; determine if it is representable */ + mp_limb_t mask; + mask = (MP_LIMB_T_ONE << sh) - (MP_LIMB_T_ONE << ush); + if ((rp[0] & mask) != 0) + uflags = 1; /* u is not representable in r */ + } + } + else + { + sh = ush; + if (rnd_mode == GMP_RNDN && + ((ush != 0 && + (up[uj] & (MP_LIMB_T_ONE << (ush - 1))) == 0) || + (ush == 0 && + (uj == 0 || (up[uj - 1] & MP_LIMB_T_HIGHBIT) == 0)))) + rnd_mode = GMP_RNDZ; /* rounding bit is 0 */ + } + if (sh != 0) + rp[0] &= MP_LIMB_T_MAX << sh; + } + + if (uflags == 0) + MPFR_RET(0); + + /* Note: if rnd_mode == GMP_RNDN, then round away from 0 (if + the rounding bit was 0 and rnd_mode == GMP_RNDN, rnd_mode + has been changed to GMP_RNDZ). */ + + if ((rnd_mode == GMP_RNDN || + (rnd_mode == GMP_RNDD && sign < 0) || + (rnd_mode == GMP_RNDU && sign > 0)) + && mpn_add_1(rp, rp, rn, MP_LIMB_T_ONE << sh)) + { + if (exp == __mpfr_emax) + return mpfr_set_overflow(r, rnd_mode, MPFR_SIGN(r)) >= 0 ? + uflags : -uflags; + else + { + MPFR_EXP(r)++; + rp[rn-1] = MP_LIMB_T_HIGHBIT; + } + } + + MPFR_RET(rnd_mode == GMP_RNDU || + (rnd_mode == GMP_RNDZ && sign < 0) || + (rnd_mode == GMP_RNDN && sign > 0) ? uflags : -uflags); + } /* exp > 0, |u| >= 1 */ +} + +#undef mpfr_round + +int +mpfr_round (mpfr_ptr r, mpfr_srcptr u) +{ + return mpfr_rint(r, u, GMP_RNDN); +} + +#undef mpfr_trunc + +int +mpfr_trunc (mpfr_ptr r, mpfr_srcptr u) +{ + return mpfr_rint(r, u, GMP_RNDZ); +} + +#undef mpfr_ceil + +int +mpfr_ceil (mpfr_ptr r, mpfr_srcptr u) +{ + return mpfr_rint(r, u, GMP_RNDU); +} + +#undef mpfr_floor + +int +mpfr_floor (mpfr_ptr r, mpfr_srcptr u) +{ + return mpfr_rint(r, u, GMP_RNDD); +} diff --git a/mpfr/rnd_mode.c b/mpfr/rnd_mode.c index 85e303c67..eba015dc5 100644 --- a/mpfr/rnd_mode.c +++ b/mpfr/rnd_mode.c @@ -21,6 +21,7 @@ MA 02111-1307, USA. */ #ifdef TEST #include <stdio.h> +#include <stdlib.h> #include "gmp.h" #include "mpfr.h" diff --git a/mpfr/round.c b/mpfr/round_prec.c index 182f38184..e0228d87e 100644 --- a/mpfr/round.c +++ b/mpfr/round_prec.c @@ -1,7 +1,7 @@ -/* mpfr_round_raw_generic, mpfr_round_raw2, mpfr_round_raw, mpfr_round, +/* mpfr_round_raw_generic, mpfr_round_raw2, mpfr_round_raw, mpfr_round_prec, mpfr_can_round, mpfr_can_round_raw -- various rounding functions -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -20,7 +20,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -150,54 +149,63 @@ mpfr_round_raw_generic(mp_limb_t *yp, mp_limb_t *xp, mp_prec_t xprec, } int -mpfr_round (mpfr_ptr x, mp_rnd_t rnd_mode, mp_prec_t prec) +mpfr_round_prec (mpfr_ptr x, mp_rnd_t rnd_mode, mp_prec_t prec) { - mp_limb_t *tmp; - int carry, neg, inexact; + mp_limb_t *tmp, *xp; + int carry, inexact; mp_prec_t nw; TMP_DECL(marker); + MPFR_ASSERTN(prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX); + + nw = 1 + (prec - 1) / BITS_PER_MP_LIMB; /* needed allocated limbs */ + + /* check if x has enough allocated space for the mantissa */ + if (nw > MPFR_ABSSIZE(x)) + { + MPFR_MANT(x) = (mp_ptr) (*__gmp_reallocate_func) + (MPFR_MANT(x), (size_t) MPFR_ABSSIZE(x) * BYTES_PER_MP_LIMB, + (size_t) nw * BYTES_PER_MP_LIMB); + MPFR_SET_ABSSIZE(x, nw); /* new number of allocated limbs */ + } + if (MPFR_IS_NAN(x)) MPFR_RET_NAN; if (MPFR_IS_INF(x)) return 0; /* infinity is exact */ - nw = 1 + (prec - 1) / BITS_PER_MP_LIMB; /* needed allocated limbs */ - neg = MPFR_SIGN(x) < 0; - - /* check if x has enough allocated space for the mantissa */ - if (nw > MPFR_ABSSIZE(x)) { - MPFR_MANT(x) = (mp_ptr) (*__gmp_reallocate_func) - (MPFR_MANT(x), MPFR_ABSSIZE(x)*BYTES_PER_MP_LIMB, nw * BYTES_PER_MP_LIMB); - MPFR_SIZE(x) = nw; /* new number of allocated limbs */ - if (neg) - MPFR_CHANGE_SIGN(x); - } + /* x is a real number */ TMP_MARK(marker); tmp = TMP_ALLOC (nw * BYTES_PER_MP_LIMB); - carry = mpfr_round_raw (tmp, MPFR_MANT(x), MPFR_PREC(x), neg, prec, rnd_mode, - &inexact); + xp = MPFR_MANT(x); + carry = mpfr_round_raw (tmp, xp, MPFR_PREC(x), MPFR_SIGN(x) < 0, + prec, rnd_mode, &inexact); + MPFR_PREC(x) = prec; if (carry) { - /* Is a shift necessary here? Isn't the result 1.0000...? */ - mpn_rshift (tmp, tmp, nw, 1); - tmp [nw-1] |= MP_LIMB_T_HIGHBIT; - MPFR_EXP(x)++; + mp_exp_t exp = MPFR_EXP(x); + + if (exp == __mpfr_emax) + (void) mpfr_set_overflow(x, rnd_mode, MPFR_SIGN(x)); + else + { + MPFR_EXP(x)++; + xp[nw - 1] = MP_LIMB_T_HIGHBIT; + if (nw - 1 > 0) + MPN_ZERO(xp, nw - 1); + } } + else + MPN_COPY(xp, tmp, nw); - MPFR_PREC(x) = prec; - MPN_COPY(MPFR_MANT(x), tmp, nw); TMP_FREE(marker); - return inexact; } -/* assumptions: - (i) BITS_PER_MP_LIMB is a power of 2 - (ii) in a test, the left part of the && is evaluated first */ +/* assumption: BITS_PER_MP_LIMB is a power of 2 */ /* assuming b is an approximation of x in direction rnd1 with error at most 2^(MPFR_EXP(b)-err), returns 1 if one is @@ -208,137 +216,103 @@ mpfr_round (mpfr_ptr x, mp_rnd_t rnd_mode, mp_prec_t prec) */ int -mpfr_can_round (mpfr_ptr b, mp_prec_t err, mp_rnd_t rnd1, +mpfr_can_round (mpfr_ptr b, mp_exp_t err, mp_rnd_t rnd1, mp_rnd_t rnd2, mp_prec_t prec) { - return (MPFR_IS_ZERO(b)) ? 0 : /* we cannot round if b=0 */ + return MPFR_IS_ZERO(b) ? 0 : /* we cannot round if b=0 */ mpfr_can_round_raw (MPFR_MANT(b), (MPFR_PREC(b) - 1)/BITS_PER_MP_LIMB + 1, MPFR_SIGN(b), err, rnd1, rnd2, prec); } int -mpfr_can_round_raw (mp_limb_t *bp, mp_prec_t bn, int neg, mp_prec_t err, - mp_rnd_t rnd1, mp_rnd_t rnd2, mp_prec_t prec) +mpfr_can_round_raw (mp_limb_t *bp, mp_size_t bn, int neg, mp_exp_t err0, + mp_rnd_t rnd1, mp_rnd_t rnd2, mp_prec_t prec) { - int k, k1, l, l1, tn; - mp_limb_t cc, cc2, *tmp; + mp_prec_t err; + mp_size_t k, k1, tn; + int s, s1; + mp_limb_t cc, cc2; + mp_limb_t *tmp; TMP_DECL(marker); - if (err <= prec) - return 0; - neg = (neg > 0 ? 0 : 1); + if (err0 < 0 || (mp_exp_unsigned_t) err0 <= prec) + return 0; /* can't round */ + + neg = neg <= 0; /* if the error is smaller than ulp(b), then anyway it will propagate up to ulp(b) */ - if (err > bn * BITS_PER_MP_LIMB) - err = bn * BITS_PER_MP_LIMB; + err = ((mp_exp_unsigned_t) err0 > (mp_prec_t) bn * BITS_PER_MP_LIMB) ? + (mp_prec_t) bn * BITS_PER_MP_LIMB : err0; /* warning: if k = m*BITS_PER_MP_LIMB, consider limb m-1 and not m */ k = (err - 1) / BITS_PER_MP_LIMB; - l = err % BITS_PER_MP_LIMB; - if (l) - l = BITS_PER_MP_LIMB - l; - /* the error corresponds to bit l in limb k, the most significant limb - being limb 0 */ + s = err % BITS_PER_MP_LIMB; + if (s) + s = BITS_PER_MP_LIMB - s; + /* the error corresponds to bit s in limb k, the most significant limb + being limb 0 */ k1 = (prec - 1) / BITS_PER_MP_LIMB; - l1 = prec % BITS_PER_MP_LIMB; - if (l1) - l1 = BITS_PER_MP_LIMB - l1; + s1 = prec % BITS_PER_MP_LIMB; + if (s1) + s1 = BITS_PER_MP_LIMB - s1; - /* the last significant bit is bit l1 in limb k1 */ + /* the last significant bit is bit s1 in limb k1 */ /* don't need to consider the k1 most significant limbs */ k -= k1; bn -= k1; - prec -= k1 * BITS_PER_MP_LIMB; - k1=0; - /* if when adding or subtracting (1 << l) in bp[bn-1-k], it does not - change bp[bn-1] >> l1, then we can round */ + prec -= (mp_prec_t) k1 * BITS_PER_MP_LIMB; + /* if when adding or subtracting (1 << s) in bp[bn-1-k], it does not + change bp[bn-1] >> s1, then we can round */ if (rnd1 == GMP_RNDU) if (neg) rnd1 = GMP_RNDZ; + if (rnd1 == GMP_RNDD) - rnd1 = (neg) ? GMP_RNDU : GMP_RNDZ; + rnd1 = neg ? GMP_RNDU : GMP_RNDZ; /* in the sequel, RNDU = towards infinity, RNDZ = towards zero */ TMP_MARK(marker); tn = bn; k++; /* since we work with k+1 everywhere */ + tmp = TMP_ALLOC(tn * BYTES_PER_MP_LIMB); + if (bn > k) + MPN_COPY (tmp, bp, bn - k); - switch (rnd1) - { - case GMP_RNDZ: /* b <= x <= b+2^(MPFR_EXP(b)-err) */ - tmp = TMP_ALLOC(tn * BYTES_PER_MP_LIMB); - cc = (bp[bn-1] >> l1) & 1; - cc ^= mpfr_round_raw2(bp, bn, neg, rnd2, prec); - - /* now round b+2^(MPFR_EXP(b)-err) */ - if (bn > k) - MPN_COPY (tmp, bp, bn - k); - cc2 = mpn_add_1 (tmp+bn-k, bp+bn-k, k, MP_LIMB_T_ONE << l); - /* if cc2=1, then all bits up to err were to 1, and we can round only - if cc==0 and mpfr_round_raw2 returns 0 below */ - if (cc2 && cc) - { - TMP_FREE(marker); - return 0; - } - cc2 = (tmp[bn-1]>>l1) & 1; /* gives 0 when carry */ - cc2 ^= mpfr_round_raw2(tmp, bn, neg, rnd2, prec); - - TMP_FREE(marker); - return (cc == cc2); - - case GMP_RNDU: /* b-2^(MPFR_EXP(b)-err) <= x <= b */ - tmp = TMP_ALLOC(tn * BYTES_PER_MP_LIMB); - /* first round b */ - cc = (bp[bn-1]>>l1) & 1; + if (rnd1 != GMP_RNDN) + { /* GMP_RNDZ or GMP_RNDU */ + cc = (bp[bn - 1] >> s1) & 1; cc ^= mpfr_round_raw2(bp, bn, neg, rnd2, prec); - /* now round b-2^(MPFR_EXP(b)-err) */ - if (bn > k) - MPN_COPY (tmp, bp, bn - k); - cc2 = mpn_sub_1(tmp+bn-k, bp+bn-k, k, MP_LIMB_T_ONE << l); - /* if cc2=1, then all bits up to err were to 0, and we can round only - if cc==0 and mpfr_round_raw2 returns 1 below */ - if (cc2 && cc) - { - TMP_FREE(marker); - return 0; - } - cc2 = (tmp[bn-1]>>l1) & 1; /* gives 1 when carry */ - cc2 ^= mpfr_round_raw2(tmp, bn, neg, rnd2, prec); - - TMP_FREE(marker); - return (cc == cc2); - - case GMP_RNDN: /* b-2^(MPFR_EXP(b)-err) <= x <= b+2^(MPFR_EXP(b)-err) */ - tmp = TMP_ALLOC(tn * BYTES_PER_MP_LIMB); - - if (bn > k) - MPN_COPY (tmp, bp, bn - k); + /* now round b +/- 2^(MPFR_EXP(b)-err) */ + cc2 = rnd1 == GMP_RNDZ ? + mpn_add_1 (tmp + bn - k, bp + bn - k, k, MP_LIMB_T_ONE << s) : + mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MP_LIMB_T_ONE << s); + } + else + { /* GMP_RNDN */ /* first round b+2^(MPFR_EXP(b)-err) */ - cc = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MP_LIMB_T_ONE << l); - cc = (tmp[bn - 1] >> l1) & 1; /* gives 0 when cc=1 */ + cc = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MP_LIMB_T_ONE << s); + cc = (tmp[bn - 1] >> s1) & 1; /* gives 0 when cc=1 */ cc ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec); /* now round b-2^(MPFR_EXP(b)-err) */ - cc2 = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MP_LIMB_T_ONE << l); - /* if cc2=1, then all bits up to err were to 0, and we can round only - if cc==0 and mpfr_round_raw2 returns 1 below */ - if (cc2 && cc) - { - TMP_FREE(marker); - return 0; - } - cc2 = (tmp[bn - 1] >> l1) & 1; /* gives 1 when cc2=1 */ - cc2 ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec); + cc2 = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MP_LIMB_T_ONE << s); + } - TMP_FREE(marker); - return (cc == cc2); + if (cc2 && cc) + { + TMP_FREE(marker); + return 0; } - return 0; + + cc2 = (tmp[bn - 1] >> s1) & 1; + cc2 ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec); + + TMP_FREE(marker); + return cc == cc2; } diff --git a/mpfr/set_d.c b/mpfr/set_d.c index 58c9c337c..2c7ff2e16 100644 --- a/mpfr/set_d.c +++ b/mpfr/set_d.c @@ -1,7 +1,7 @@ /* mpfr_set_d, mpfr_get_d -- convert a multiple precision floating-point number from/to a machine double precision float -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -20,11 +20,12 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <float.h> #include "gmp.h" -#include "mpfr.h" -#include "mpfr-impl.h" #include "gmp-impl.h" #include "longlong.h" +#include "mpfr.h" +#include "mpfr-impl.h" #if (BITS_PER_MP_LIMB==32) #define MPFR_LIMBS_PER_DOUBLE 2 @@ -84,14 +85,14 @@ __mpfr_extract_double (mp_ptr rp, double d, int e) x.d = d; exp = x.s.exp; - if (exp) + if (exp) { #if BITS_PER_MP_LIMB == 64 manl = ((MP_LIMB_T_ONE << 63) | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11)); #else manh = (MP_LIMB_T_ONE << 31) | (x.s.manh << 11) | (x.s.manl >> 21); - manl = x.s.manl << 11; + manl = x.s.manl << 11; #endif } else @@ -100,7 +101,7 @@ __mpfr_extract_double (mp_ptr rp, double d, int e) manl = ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11); #else manh = (x.s.manh << 11) | (x.s.manl >> 21); - manl = x.s.manl << 11; + manl = x.s.manl << 11; #endif } } @@ -150,7 +151,7 @@ __mpfr_extract_double (mp_ptr rp, double d, int e) } #endif - if (exp) exp = (unsigned) exp - 1022; else exp = -1021; + if (exp) exp = (unsigned) exp - 1022; else exp = -1021; #if BITS_PER_MP_LIMB == 64 rp[0] = manl; @@ -168,65 +169,63 @@ __mpfr_extract_double (mp_ptr rp, double d, int e) } /* End of part included from gmp-2.0.2 */ -/* Part included from gmp temporary releases */ +/* Part included from gmp temporary releases and modified */ static double __mpfr_scale2 (double d, int exp) { #if _GMP_IEEE_FLOATS { union ieee_double_extract x; + + if (exp < -2099) + return 0.0 * d; /* 0 with the correct sign */ + x.d = d; - exp += x.s.exp; - x.s.exp = exp; - if (exp >= 2047) + if (exp >= 2047 || exp + x.s.exp >= 2047) { /* Return +-infinity */ x.s.exp = 2047; x.s.manl = x.s.manh = 0; } - else if (exp < 1) + else if (exp + x.s.exp < 1) { - x.s.exp = 1; /* smallest exponent (biased) */ - /* Divide result by 2 until we have scaled it to the right IEEE - denormalized number, but stop if it becomes zero. */ - while (exp < 1 && x.d != 0) - { - x.d *= 0.5; - exp++; - } + exp += x.s.exp; + if (exp <= -52) + return 0.0 * d; /* 0 with the correct sign */ + x.s.exp = 1; /* smallest exponent (biased) */ + x.d *= __mpfr_scale2(1.0, exp - 1); + } + else + { + x.s.exp += exp; } return x.d; } #else { - double factor, r; + double factor; - factor = 2.0; if (exp < 0) { factor = 0.5; exp = -exp; } - r = d; - if (exp != 0) + else + { + factor = 2.0; + } + while (exp != 0) { if ((exp & 1) != 0) - r *= factor; + d *= factor; exp >>= 1; - while (exp != 0) - { - factor *= factor; - if ((exp & 1) != 0) - r *= factor; - exp >>= 1; - } + factor *= factor; } return r; } #endif } - /* End of part included from gmp */ int @@ -235,7 +234,7 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode) int signd, sizer, sizetmp, inexact; unsigned int cnt; mpfr_ptr tmp; - TMP_DECL(marker); + TMP_DECL(marker); TMP_MARK(marker); MPFR_CLEAR_FLAGS(r); @@ -247,7 +246,7 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode) MPFR_SET_ZERO(r); /* set correct sign */ x.d = d; - if (((x.s.sig == 1) && (MPFR_SIGN(r) > 0)) + if (((x.s.sig == 1) && (MPFR_SIGN(r) > 0)) || ((x.s.sig == 0) && (MPFR_SIGN(r) < 0))) MPFR_CHANGE_SIGN(r); return 0; /* 0 is exact */ @@ -260,10 +259,10 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode) } else if (DOUBLE_ISINF(d)) - { - MPFR_SET_INF(r); + { + MPFR_SET_INF(r); if ((d > 0 && (MPFR_SIGN(r) == -1)) || (d < 0 && (MPFR_SIGN(r) == 1))) - MPFR_CHANGE_SIGN(r); + MPFR_CHANGE_SIGN(r); return 0; /* infinity is exact */ } @@ -287,82 +286,85 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode) if (cnt) mpn_lshift (MPFR_MANT(tmp), MPFR_MANT(tmp), sizetmp, cnt); - - MPFR_EXP(tmp) -= cnt; + + MPFR_EXP(tmp) -= cnt; /* tmp is exact since PREC(tmp)=53 */ - inexact = mpfr_set4(r, tmp, rnd_mode, signd); + inexact = mpfr_set4(r, tmp, rnd_mode, signd); - TMP_FREE(marker); + TMP_FREE(marker); return inexact; } double -mpfr_get_d2 (mpfr_srcptr src, long e) +mpfr_get_d2 (mpfr_srcptr src, mp_exp_t e) { - double res; - mp_size_t size, i, n_limbs_to_use; - mp_ptr qp; - int negative; + double d; + mpfr_t tmp; + int s, negative; if (MPFR_IS_NAN(src)) - { -#ifdef DEBUG - printf("recognized NaN\n"); -#endif - return NaN; - } + return NaN; + + negative = MPFR_SIGN(src) < 0; if (MPFR_IS_INF(src)) - { -#ifdef DEBUG - printf("Found Inf.\n"); -#endif - return (MPFR_SIGN(src) == 1 ? Infp : Infm); - } + return negative ? Infm : Infp; - if (MPFR_NOTZERO(src) == 0) - return 0.0; - - size = 1+(MPFR_PREC(src)-1)/BITS_PER_MP_LIMB; - qp = MPFR_MANT(src); - negative = (MPFR_SIGN(src) < 0); - - /* Warning: don't compute the abs(res) and set the sign afterwards, - otherwise the current machine rounding mode will not be taken - correctly into account. */ - /* res = (negative) ? -(double)qp[size - 1] : qp[size - 1]; */ - res = 0.0; - /* Warning: an arbitrary number of limbs may be required for an exact - rounding. The following code is correct but not optimal since one - may be able to decide without considering all limbs. */ - /* n_limbs_to_use = MIN (MPFR_LIMBS_PER_DOUBLE, size); */ - n_limbs_to_use = size; - /* Accumulate the limbs from less significant to most significant - otherwise due to rounding we may accumulate several ulps, - especially in rounding towards -/+infinity. */ - for (i = n_limbs_to_use; i>=1; i--) { -#if (BITS_PER_MP_LIMB == 32) - res = res / MP_BASE_AS_DOUBLE + - ((negative) ? -(double)qp[size - i] : qp[size - i]); -#else -#if (BITS_PER_MP_LIMB == 64) - mp_limb_t q; - q = qp[size - i] & CNST_LIMB(0xFFFFFFFF); - res = res / MP_BASE_AS_DOUBLE + ((negative) ? -(double)q : q); - q = qp[size - i] - q; - res = res + ((negative) ? -(double)q : q); -#endif /* BITS_PER_MP_LIMB == 64 */ -#endif /* BITS_PER_MP_LIMB == 32 */ - } - res = __mpfr_scale2 (res, e - BITS_PER_MP_LIMB); + if (MPFR_IS_ZERO(src)) + return negative ? -0.0 : 0.0; + + if (e < -1076) + { /* Simulate the underflow with the current IEEE rounding mode. */ + d = DBL_MIN; + d *= negative ? -DBL_MIN : DBL_MIN; + /* -> double precision forced by the affectation */ + } + else if (e > 1024) + { /* Simulate the overflow with the current IEEE rounding mode. */ + d = DBL_MAX; + d *= negative ? -2 : 2; + } + else + { + mp_ptr tp; + mp_size_t np, i; + double r; + + mpfr_save_emin_emax(); + + /* Truncate src to 54 bits + * --> rounding bit stored to the 54th bit + * --> sticky bit stored to variable s */ + mpfr_init2(tmp, 54); + s = mpfr_set(tmp, src, GMP_RNDZ); + MPFR_ASSERTN(MPFR_IS_FP(tmp) && MPFR_NOTZERO(tmp)); + + /* Warning: the rounding may still be incorrect in the rounding + to the nearest mode when the result is a subnormal because of + a double rounding (-> 53 bits -> final precision). */ + tp = MPFR_MANT(tmp); + d = (tp[0] & (MP_LIMB_T_MAX << 11)) / MP_BASE_AS_DOUBLE; + np = (MPFR_PREC(tmp) - 1) / BITS_PER_MP_LIMB; + for (i = 1; i <= np; i++) + d = (d + tp[i]) / MP_BASE_AS_DOUBLE; + /* d is the mantissa (between 1/2 and 1) of the argument truncated + to 53 bits */ + r = (((tp[0] >> 9) & 2) + (s != 0)) * (DBL_EPSILON / 8.0); + d += r; /* double precision forced by the affectation */ + d = __mpfr_scale2(d, e); + if (negative) + d = -d; + + mpfr_clear(tmp); + mpfr_restore_emin_emax(); + } - return res; + return d; } -double +double mpfr_get_d (mpfr_srcptr src) { return mpfr_get_d2 (src, MPFR_EXP(src)); } - diff --git a/mpfr/set_dfl_prec.c b/mpfr/set_dfl_prec.c index 425638978..d24f1c037 100644 --- a/mpfr/set_dfl_prec.c +++ b/mpfr/set_dfl_prec.c @@ -20,20 +20,22 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gmp.h" -#include "mpfr.h" #include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" /* default is 53 bits */ mp_prec_t __mpfr_default_fp_bit_precision = 53; void -mpfr_set_default_prec (mp_prec_t prec_in_bits) +mpfr_set_default_prec (mp_prec_t prec) { - __mpfr_default_fp_bit_precision = prec_in_bits; + MPFR_ASSERTN(prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX); + __mpfr_default_fp_bit_precision = prec; } mp_prec_t -mpfr_get_default_prec () +mpfr_get_default_prec (void) { return __mpfr_default_fp_bit_precision; } diff --git a/mpfr/set_prc_raw.c b/mpfr/set_prc_raw.c index c04318486..0f893d59e 100644 --- a/mpfr/set_prc_raw.c +++ b/mpfr/set_prc_raw.c @@ -29,16 +29,13 @@ MA 02111-1307, USA. */ void mpfr_set_prec_raw (mpfr_ptr x, mp_prec_t p) { - if (p==0) { - fprintf(stderr, "*** cannot set precision to 0 bits\n"); exit(1); - } + MPFR_ASSERTN(p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX); - if (p > MPFR_ABSSIZE(x) * BITS_PER_MP_LIMB) { - fprintf(stderr, "*** precision too large for allocated space\n"); - exit(1); - } + if (p > (mp_prec_t) MPFR_ABSSIZE(x) * BITS_PER_MP_LIMB) + { + fprintf (stderr, "*** precision too large for allocated space\n"); + exit (1); + } MPFR_PREC(x) = p; } - - diff --git a/mpfr/set_prec.c b/mpfr/set_prec.c index ebee34ed2..f6591c0f2 100644 --- a/mpfr/set_prec.c +++ b/mpfr/set_prec.c @@ -20,7 +20,6 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <stdio.h> -#include <stdlib.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -29,20 +28,22 @@ MA 02111-1307, USA. */ int mpfr_set_prec (mpfr_ptr x, mp_prec_t p) { - mp_prec_t xsize; + mp_size_t xsize; - if (p == 0) - return 1; + MPFR_ASSERTN(p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX); - xsize = (p - 1)/BITS_PER_MP_LIMB + 1; /* new limb size */ + xsize = (p - 1) / BITS_PER_MP_LIMB + 1; /* new limb size */ - if (xsize > MPFR_ABSSIZE(x)) { - MPFR_MANT(x) = (mp_ptr) (*__gmp_reallocate_func) (MPFR_MANT(x), - MPFR_ABSSIZE(x)*BYTES_PER_MP_LIMB, xsize * BYTES_PER_MP_LIMB); - MPFR_SIZE(x) = xsize; /* new number of allocated limbs */ - } + if (xsize > MPFR_ABSSIZE(x)) + { + MPFR_MANT(x) = (mp_ptr) (*__gmp_reallocate_func) + (MPFR_MANT(x), (size_t) MPFR_ABSSIZE(x) * BYTES_PER_MP_LIMB, + (size_t) xsize * BYTES_PER_MP_LIMB); + MPFR_SIZE(x) = xsize; /* new number of allocated limbs */ + } MPFR_PREC(x) = p; + MPFR_SET_NAN(x); /* initializes to NaN */ return MPFR_MANT(x) == NULL; } diff --git a/mpfr/set_rnd.c b/mpfr/set_rnd.c index 666488e98..7948ba36a 100644 --- a/mpfr/set_rnd.c +++ b/mpfr/set_rnd.c @@ -20,8 +20,8 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gmp.h" -#include "mpfr.h" #include "gmp-impl.h" +#include "mpfr.h" mp_rnd_t __gmp_default_rounding_mode = 0; @@ -30,4 +30,3 @@ mpfr_set_default_rounding_mode (mp_rnd_t rnd_mode) { __gmp_default_rounding_mode = rnd_mode; } - diff --git a/mpfr/set_si.c b/mpfr/set_si.c index cb4fcc092..8690e6b8f 100644 --- a/mpfr/set_si.c +++ b/mpfr/set_si.c @@ -37,8 +37,7 @@ mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode) if (i == 0) { MPFR_SET_ZERO(x); - if (MPFR_SIGN(x) < 0) - MPFR_CHANGE_SIGN(x); + MPFR_SET_POS(x); MPFR_RET(0); } @@ -75,7 +74,6 @@ mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode) } } - /* warning: don't change the precision of x! */ if ((i < 0) ^ (MPFR_SIGN(x) < 0)) MPFR_CHANGE_SIGN(x); diff --git a/mpfr/set_str.c b/mpfr/set_str.c index 7cde1c052..d4a6b686d 100644 --- a/mpfr/set_str.c +++ b/mpfr/set_str.c @@ -1,6 +1,6 @@ /* mpfr_set_str -- set a floating-point number from a string -Copyright (C) 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 2000-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -22,7 +22,8 @@ MA 02111-1307, USA. */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include <limits.h> +#include <errno.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -32,104 +33,141 @@ MA 02111-1307, USA. */ int mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) { - char negative = 0, *endptr; - unsigned long k = 0, l, q; - long expn = 0, e; mpz_t mantissa; + int negative, inex; + long k = 0; + unsigned char c; + long e; + mp_prec_t q; mpfr_t y, z; - mpz_init(mantissa); mpz_set_ui(mantissa, 0); - l = strlen(str); - if (*str == '-') { negative = 1; str++; l--; } - else if (*str == '+') { str++; l--; } + if (base < 2 || base > 36) + return 1; - while (*str == '0') { str++; l--; } /* skip initial zeros */ + mpz_init(mantissa); + mpz_set_ui(mantissa, 0); + + negative = *str == '-'; + if (negative || *str == '+') + str++; + + while (*str == '0') + str++; /* skip initial zeros */ /* allowed characters are '0' to '0'+base-1 if base <= 10, and '0' to '9' plus 'a' to 'a'+base-11 if 10 < base <= 36 */ - while ((isdigit((unsigned char) *str) && (unsigned char) *str < '0'+base) - || (islower((unsigned char) *str) && (unsigned char) *str < 'a'+base-10)) - { + while (c = *str, + (isdigit(c) && c < '0' + base) || + (islower(c) && c < 'a'-10 + base)) + { + str++; mpz_mul_ui(mantissa, mantissa, base); - mpz_add_ui(mantissa, mantissa, isdigit((unsigned char) *str) ? - (*str)-'0' : (*str)-'a'+10); - str++; l--; + mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10)); } /* k is the number of non-zero digits before the decimal point */ - if (*str == '.') + if (*str == '.') { - str++; l--; - while ((isdigit((unsigned char) *str) && (unsigned char) *str < '0'+base) - || (islower((unsigned char) *str) && (unsigned char) *str < 'a'+base-10)) - { - mpz_mul_ui(mantissa, mantissa, base); - mpz_add_ui(mantissa, mantissa, isdigit((unsigned char) *str) ? - (*str)-'0' : (*str)-'a'+10); - str++; l--; + str++; + while (c = *str, + (isdigit(c) && c < '0' + base) || + (islower(c) && c < 'a'-10 + base)) + { + if (k == LONG_MAX) + { + mpz_clear(mantissa); + return -1; + } k++; + str++; + mpz_mul_ui(mantissa, mantissa, base); + mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10)); } } - - if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@') + + if (*str == '\0') /* no exponent */ { - str++; l--; + e = -k; + } + else if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@') + { + char *endptr; + + if (*++str == '\0') /* exponent character but no exponent */ + { + mpz_clear(mantissa); + return 1; + } + + errno = 0; e = strtol(str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */ - expn = e - k; - if (expn > e) - fprintf(stderr, "Warning: exponent underflow in mpfr_set_str\n"); + if (*endptr != '\0') + { + mpz_clear(mantissa); + return 1; + } + if (errno) + { + mpz_clear(mantissa); + return -1; + } + + if (e < 0 && (unsigned long) e - k < (unsigned long) LONG_MIN) + { + mpz_clear(mantissa); + return -1; + } + e -= k; + } + else /* unexpected character */ + { + mpz_clear(mantissa); + return 1; } - else if (l) { - /* unexpected end of string */ - return -1; - } - else { - expn = -k; - endptr = (char*) str; - } /* the number is mantissa*base^expn */ - q = (MPFR_PREC(x)/BITS_PER_MP_LIMB)*BITS_PER_MP_LIMB; + q = MPFR_PREC(x) & ~(mp_prec_t) (BITS_PER_MP_LIMB - 1); mpfr_init(y); mpfr_init(z); - do { - q += BITS_PER_MP_LIMB; - mpfr_set_prec(y, q); - mpfr_set_z(y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */ - - mpfr_set_prec(z, q); - if (expn>0) { - e = mpfr_ui_pow_ui(z, base, expn, GMP_RNDN); - mpfr_mul(y, y, z, GMP_RNDN); - } - else if (expn<0) { - e = mpfr_ui_pow_ui(z, base, -expn, GMP_RNDN); - mpfr_div(y, y, z, GMP_RNDN); + do + { + q += BITS_PER_MP_LIMB; + mpfr_set_prec(y, q); + mpfr_set_z(y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */ + + mpfr_set_prec(z, q); + if (e > 0) + { + inex = mpfr_ui_pow_ui(z, base, e, GMP_RNDN); + mpfr_mul(y, y, z, GMP_RNDN); + } + else if (e < 0) + { + inex = mpfr_ui_pow_ui(z, base, -e, GMP_RNDN); + mpfr_div(y, y, z, GMP_RNDN); + } + else + inex = 1; + if (negative) + mpfr_neg(y, y, GMP_RNDN); } - else e=1; - if (negative) mpfr_neg(y, y, GMP_RNDN); - - /* now y is an approximation of mantissa*base^expn with error at most - 2^e*ulp(y) */ - - } while (mpfr_can_round(y, q-e, GMP_RNDN, rnd_mode, MPFR_PREC(x))==0 - && q<=2*MPFR_PREC(x)); + while (mpfr_can_round(y, q-inex, GMP_RNDN, rnd_mode, MPFR_PREC(x))==0 + && q<=2*MPFR_PREC(x)); mpfr_set(x, y, rnd_mode); mpz_clear(mantissa); mpfr_clear(y); mpfr_clear(z); - return ((*endptr=='\0') ? 0 : -1); + return 0; } int mpfr_init_set_str (mpfr_ptr x, char *str, int base, mp_rnd_t rnd_mode) -{ +{ mpfr_init (x); return mpfr_set_str (x, str, base, rnd_mode); } - diff --git a/mpfr/set_str_raw.c b/mpfr/set_str_raw.c index 6fbf831d8..d76f502d8 100644 --- a/mpfr/set_str_raw.c +++ b/mpfr/set_str_raw.c @@ -43,23 +43,30 @@ mpfr_set_str_raw (mpfr_ptr x, char *str) xsize = 1 + (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB; alloc = (strlen(str)+1) * sizeof(char); - if (*str == '-') { negative = 1; str++; } - else if (*str == '+') str++; + if (*str == '-') + { + negative = 1; + str++; + } + else if (*str == '+') + str++; + if (*str == 'N') + { + MPFR_SET_NAN(x); + __mpfr_flags |= MPFR_FLAGS_NAN; + return; + } + if (*str == 'I') { + MPFR_CLEAR_NAN(x); MPFR_SET_INF(x); if (MPFR_ISNEG(x) != negative) MPFR_CHANGE_SIGN(x); return; } - if (*str == 'N') - { - MPFR_SET_NAN(x); - return; - } - MPFR_CLEAR_FLAGS(x); str0 = str2 = (char *) (*__gmp_allocate_func) (alloc); diff --git a/mpfr/set_ui.c b/mpfr/set_ui.c index 2ae08b7ff..e14b29278 100644 --- a/mpfr/set_ui.c +++ b/mpfr/set_ui.c @@ -71,9 +71,7 @@ mpfr_set_ui (mpfr_ptr x, unsigned long i, mp_rnd_t rnd_mode) } } - /* warning: don't change the precision of x! */ - if (MPFR_SIGN(x) < 0) - MPFR_CHANGE_SIGN(x); + MPFR_SET_POS(x); MPFR_RET(inex); } diff --git a/mpfr/set_z.c b/mpfr/set_z.c index 742b806ac..5f4ffeb5e 100644 --- a/mpfr/set_z.c +++ b/mpfr/set_z.c @@ -1,6 +1,6 @@ /* mpfr_set_z -- set a floating-point number from a multiple-precision integer -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -20,88 +20,148 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gmp.h" -#include "mpfr.h" -#include "mpfr-impl.h" #include "gmp-impl.h" #include "longlong.h" +#include "mpfr.h" +#include "mpfr-impl.h" /* set f to the integer z */ int -mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd) +mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode) { - mp_size_t fn, zn, dif, sh; - int k, sign_z; - mp_limb_t *fp = MPFR_MANT(f), *zp, cc, c2; + mp_size_t fn, zn, dif; + int k, sign_z, inex; + mp_limb_t *fp, *zp; + mp_exp_t exp; MPFR_CLEAR_FLAGS (f); /* z cannot be NaN nor Inf */ sign_z = mpz_cmp_ui (z, 0); - if (sign_z==0) { - MPFR_SET_ZERO(f); - return 0; - } + if (sign_z == 0) + { + MPFR_SET_ZERO(f); + MPFR_SET_POS(f); + MPFR_RET(0); + } - fn = 1 + (MPFR_PREC(f)-1)/BITS_PER_MP_LIMB; + fp = MPFR_MANT(f); + fn = 1 + (MPFR_PREC(f) - 1) / BITS_PER_MP_LIMB; zn = ABS(SIZ(z)); - dif = zn-fn; + dif = zn - fn; zp = PTR(z); count_leading_zeros(k, zp[zn-1]); - MPFR_EXP(f) = zn*BITS_PER_MP_LIMB-k; - if (MPFR_SIGN(f)*sign_z<0) MPFR_CHANGE_SIGN(f); - if (dif>=0) { /* number has to be truncated */ - if (k) { - mpn_lshift(fp, zp + dif, fn, k); - if (dif) *fp += zp[dif-1] >> (BITS_PER_MP_LIMB-k); - } - else MPN_COPY(fp, zp + dif, fn); - sh = fn*BITS_PER_MP_LIMB-MPFR_PREC(f); - cc = *fp & ((MP_LIMB_T_ONE << sh) - 1); - *fp = *fp & ~cc; - if (rnd==GMP_RNDN) { - if (sh) c2 = MP_LIMB_T_ONE << (sh - 1); - else { /* sh=0 */ - c2 = MP_LIMB_T_HIGHBIT; - dif--; - cc = (dif>=0) ? ((zp[dif])<<k) : 0; - if (dif>0 && k) cc += zp[dif-1] >> (BITS_PER_MP_LIMB-k); - } - /* now compares cc to c2 */ - if (cc>c2) { mpfr_add_one_ulp(f); return cc; } - else if (cc<c2) goto towards_zero; - else { - cc=0; - while (dif>0 && (cc=zp[dif-1])==0) dif--; - if (cc) { mpfr_add_one_ulp(f); return cc; } - else /* exactly in middle: inexact in both cases */ - if (*fp & (MP_LIMB_T_ONE << sh)) { mpfr_add_one_ulp(f); return 1; } - else return 1; - } - } - else if ((sign_z>0 && rnd==GMP_RNDU) || (sign_z<0 && rnd==GMP_RNDD)) { - /* round towards infinity */ - /* result is exact iff all remaining bits are zero */ - if (dif>0 && cc==0) cc=zp[--dif]<<k; - while (cc==0 && dif>0) cc=zp[--dif]; - if (cc) { mpfr_add_one_ulp(f); return 1; } - else return 0; - } - else { /* round towards zero */ - /* result is exact iff all remaining bits are zero */ - towards_zero: - if (cc==0 && dif>0) cc=zp[--dif]<<k; - while (cc==0 && dif>0) cc=zp[--dif]; - return cc; - } - } - else { - if (k) mpn_lshift(fp-dif, zp, zn, k); - else MPN_COPY(fp-dif, zp, zn); - /* fill with zeroes */ - MPN_ZERO(fp, -dif); - return 0; /* result is exact */ - } -} + exp = (mp_prec_t) zn * BITS_PER_MP_LIMB - k; + /* The exponent will be exp or exp + 1 (due to rounding) */ + if (exp > __mpfr_emax) + return mpfr_set_overflow(f, rnd_mode, sign_z); + if (exp + 1 < __mpfr_emin) + return mpfr_set_underflow(f, rnd_mode, sign_z); + + if (MPFR_SIGN(f) * sign_z < 0) + MPFR_CHANGE_SIGN(f); + if (dif >= 0) + { + mp_limb_t cc; + int sh; + /* number has to be truncated */ + if (k != 0) + { + mpn_lshift(fp, zp + dif, fn, k); + if (dif != 0) + fp[0] += zp[dif - 1] >> (BITS_PER_MP_LIMB - k); + } + else + MPN_COPY(fp, zp + dif, fn); + + sh = (mp_prec_t) fn * BITS_PER_MP_LIMB - MPFR_PREC(f); + cc = fp[0] & ((MP_LIMB_T_ONE << sh) - 1); + fp[0] &= ~cc; + + if ((rnd_mode == GMP_RNDU && sign_z < 0) || + (rnd_mode == GMP_RNDD && sign_z > 0)) + rnd_mode = GMP_RNDZ; + + /* remaining bits... */ + if (rnd_mode == GMP_RNDN) + { + /* 1) If rounding bit is 0, behave like rounding to 0. + 2) Determine the sticky bit (cc != 0). */ + if (sh != 0) + { + mp_limb_t rb; + + rb = MP_LIMB_T_ONE << (sh - 1); + if ((cc & rb) == 0) + rnd_mode = GMP_RNDZ; /* rounding bit is 0 */ + else + cc &= ~rb; + if (cc == 0 && dif > 0) + cc = zp[--dif] << k; + } + else /* sh == 0 */ + { + MPFR_ASSERTN(cc == 0); + if (dif > 0) + cc = zp[--dif] << k; + if ((cc & MP_LIMB_T_HIGHBIT) == 0) + rnd_mode = GMP_RNDZ; /* rounding bit is 0 */ + else + cc <<= 1; + } + + while (cc == 0 && dif > 0) + cc = zp[--dif]; + + if (rnd_mode == GMP_RNDN && cc == 0) /* even rounding */ + { + cc = 1; + if ((fp[0] & (MP_LIMB_T_ONE << sh)) == 0) + rnd_mode = GMP_RNDZ; + } + } /* rnd_mode == GMP_RNDN */ + else if (cc == 0 && dif > 0) + { + cc = zp[--dif] << k; + while (cc == 0 && dif > 0) + cc = zp[--dif]; + } + + if (cc == 0) + inex = 0; + else if (rnd_mode == GMP_RNDZ) + inex = -sign_z; + else + { + if (mpn_add_1(fp, fp, fn, MP_LIMB_T_ONE << sh)) + { + if (exp == __mpfr_emax) + return mpfr_set_overflow(f, rnd_mode, sign_z); + else + { + exp++; + fp[fn-1] = MP_LIMB_T_HIGHBIT; + } + } + inex = sign_z; + } + } /* dif >= 0 */ + else /* dif < 0 */ + { + if (k != 0) + mpn_lshift(fp - dif, zp, zn, k); + else + MPN_COPY(fp - dif, zp, zn); + /* fill with zeroes */ + MPN_ZERO(fp, -dif); + inex = 0; /* result is exact */ + } + + if (exp < __mpfr_emin) + return mpfr_set_underflow(f, rnd_mode, sign_z); + MPFR_EXP(f) = exp; + MPFR_RET(inex); +} diff --git a/mpfr/sin.c b/mpfr/sin.c index 8d625159c..20db37436 100644 --- a/mpfr/sin.c +++ b/mpfr/sin.c @@ -1,6 +1,6 @@ /* mpfr_sin -- sine of a floating-point number -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -34,13 +33,15 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) { MPFR_SET_NAN(y); - return 1; /* inexact */ + MPFR_RET_NAN; } - if (!MPFR_NOTZERO(x)) + if (MPFR_IS_ZERO(x)) { - mpfr_set_ui (y, 0, GMP_RNDN); - return 0; /* exact */ + MPFR_CLEAR_FLAGS(y); + MPFR_SET_ZERO(y); + MPFR_SET_SAME_SIGN(y, x); + MPFR_RET(0); } precy = MPFR_PREC(y); @@ -51,7 +52,7 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) /* first determine sign */ mpfr_const_pi (c, GMP_RNDN); - mpfr_mul_2exp (c, c, 1, GMP_RNDN); /* 2*Pi */ + mpfr_mul_2ui (c, c, 1, GMP_RNDN); /* 2*Pi */ mpfr_div (k, x, c, GMP_RNDN); /* x/(2*Pi) */ mpfr_floor (k, k); /* floor(x/(2*Pi)) */ mpfr_mul (c, k, c, GMP_RNDN); diff --git a/mpfr/sinh.c b/mpfr/sinh.c index 2646aad4b..aa9bc5c9a 100644 --- a/mpfr/sinh.c +++ b/mpfr/sinh.c @@ -1,6 +1,6 @@ /* mpfr_sinh -- hyperbolic sine -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -31,7 +31,7 @@ MA 02111-1307, USA. */ */ int -mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) +mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode) { /****** Declaration ******/ mpfr_t x; @@ -41,7 +41,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) if (MPFR_IS_NAN(xt)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); @@ -49,16 +49,16 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) { MPFR_SET_INF(y); MPFR_SET_SAME_SIGN(y,xt); - return 0; + MPFR_RET(0); } MPFR_CLEAR_INF(y); - if(!MPFR_NOTZERO(xt)) + if (MPFR_IS_ZERO(xt)) { MPFR_SET_ZERO(y); /* sinh(0) = 0 */ MPFR_SET_SAME_SIGN(y,xt); - return(0); + MPFR_RET(0); } mpfr_init2(x,Nxt); @@ -107,7 +107,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) mpfr_exp(te,x,GMP_RNDD); /* exp(x) */ mpfr_ui_div(ti,1,te,GMP_RNDU); /* 1/exp(x) */ mpfr_sub(t,te,ti,GMP_RNDN); /* exp(x) - 1/exp(x)*/ - mpfr_div_2exp(t,t,1,GMP_RNDN); /* 1/2(exp(x) - 1/exp(x))*/ + mpfr_div_2ui(t,t,1,GMP_RNDN); /* 1/2(exp(x) - 1/exp(x))*/ /* calculation of the error*/ d = MPFR_EXP(te)-MPFR_EXP(t)+2; diff --git a/mpfr/sqrt.c b/mpfr/sqrt.c index 839f769bd..89082ad89 100644 --- a/mpfr/sqrt.c +++ b/mpfr/sqrt.c @@ -1,6 +1,6 @@ /* mpfr_sqrt -- square root of a floating-point number -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,8 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -34,243 +32,256 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode) mp_ptr up, rp, tmp, remp; mp_size_t usize, rrsize; mp_size_t rsize; - mp_size_t prec, err; + mp_size_t err; mp_limb_t q_limb; + int odd_exp_u; long rw, nw, k; int inexact = 0, t; unsigned long cc = 0; - char can_round = 0; - TMP_DECL(marker0); + int can_round = 0; - if (MPFR_IS_NAN(u)) { - MPFR_SET_NAN(r); - return 1; /* NaN is always inexact */ - } + TMP_DECL(marker0); + { + TMP_DECL (marker); - if (MPFR_SIGN(u) < 0) { - if (MPFR_IS_INF(u) || MPFR_NOTZERO(u)) { - MPFR_SET_NAN(r); - return 1; /* NaN is always inexact */ - } - else { /* sqrt(-0) = -0 */ - MPFR_SET_ZERO(r); - if (MPFR_SIGN(r) > 0) MPFR_CHANGE_SIGN(r); - return 0; /* zero is exact */ - } - } + if (MPFR_IS_NAN(u)) + { + MPFR_SET_NAN(r); + MPFR_RET_NAN; + } - MPFR_CLEAR_NAN(r); + if (MPFR_SIGN(u) < 0) + { + if (MPFR_IS_INF(u) || MPFR_NOTZERO(u)) + { + MPFR_SET_NAN(r); + MPFR_RET_NAN; + } + else + { /* sqrt(-0) = -0 */ + MPFR_CLEAR_INF(r); + MPFR_SET_ZERO(r); + MPFR_SET_NEG(r); + MPFR_RET(0); + } + } - if (MPFR_SIGN(r) < 0) MPFR_CHANGE_SIGN(r); - if (MPFR_IS_INF(u)) - { - MPFR_SET_INF(r); - return 0; /* infinity is exact */ - } + MPFR_CLEAR_NAN(r); + MPFR_SET_POS(r); - MPFR_CLEAR_INF(r); + if (MPFR_IS_INF(u)) + { + MPFR_SET_INF(r); + MPFR_RET(0); + } - prec = MPFR_PREC(r); + MPFR_CLEAR_INF(r); - if (!MPFR_NOTZERO(u)) - { - MPFR_EXP(r) = 0; - rsize = (prec-1)/BITS_PER_MP_LIMB + 1; - MPN_ZERO(MPFR_MANT(r), rsize); - return 0; /* zero is exact */ - } + if (MPFR_IS_ZERO(u)) + { + MPFR_SET_ZERO(r); + MPFR_RET(0); /* zero is exact */ + } - up = MPFR_MANT(u); - usize = (MPFR_PREC(u) - 1)/BITS_PER_MP_LIMB + 1; + up = MPFR_MANT(u); + usize = (MPFR_PREC(u) - 1)/BITS_PER_MP_LIMB + 1; #ifdef DEBUG - printf("Entering square root : "); - for(k = usize - 1; k >= 0; k--) { printf("%lu ", up[k]); } - printf(".\n"); + printf("Entering square root : "); + for(k = usize - 1; k >= 0; k--) { printf("%lu ", up[k]); } + printf(".\n"); #endif - /* Compare the mantissas */ - - rsize = ((MPFR_PREC(r) + 2 + (MPFR_EXP(u) & 1))/BITS_PER_MP_LIMB + 1) << 1; - rrsize = (MPFR_PREC(r) + 2 + (MPFR_EXP(u) & 1))/BITS_PER_MP_LIMB + 1; - /* One extra bit is needed in order to get the square root with enough - precision ; take one extra bit for rrsize in order to solve more - easily the problem of rounding to nearest. - Need to have 2*rrsize = rsize... - Take one extra bit if the exponent of u is odd since we shall have - to shift then. - */ - - TMP_MARK(marker0); - if (MPFR_EXP(u) & 1) /* Shift u one bit to the right */ - { - if (MPFR_PREC(u) & (BITS_PER_MP_LIMB - 1)) - { - up = TMP_ALLOC(usize*BYTES_PER_MP_LIMB); - mpn_rshift(up, MPFR_MANT(u), usize, 1); - } - else - { - up = TMP_ALLOC((usize + 1)*BYTES_PER_MP_LIMB); - if (mpn_rshift(up + 1, MPFR_MANT(u), usize, 1)) - up [0] = MP_LIMB_T_HIGHBIT; - else up[0] = 0; - usize++; - } - } - - MPFR_EXP(r) = ((MPFR_EXP(u) + (MPFR_EXP(u) & 1)) / 2) ; - - { - TMP_DECL (marker); - do - { - TMP_MARK (marker); - - err = rsize*BITS_PER_MP_LIMB; - if (rsize < usize) { err--; } - if (err > rrsize * BITS_PER_MP_LIMB) - { err = rrsize * BITS_PER_MP_LIMB; } - - tmp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB); - rp = (mp_ptr) TMP_ALLOC (rrsize * BYTES_PER_MP_LIMB); - remp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB); - - if (usize >= rsize) { - MPN_COPY (tmp, up + usize - rsize, rsize); - } - else { - MPN_COPY (tmp + rsize - usize, up, usize); - MPN_ZERO (tmp, rsize - usize); + /* Compare the mantissas */ + + odd_exp_u = (unsigned int) MPFR_EXP(u) & 1; + MPFR_ASSERTN(MPFR_PREC(r) <= MPFR_INTPREC_MAX - 3); + rrsize = (MPFR_PREC(r) + 2 + odd_exp_u) / BITS_PER_MP_LIMB + 1; + MPFR_ASSERTN(rrsize <= MP_SIZE_T_MAX/2); + rsize = rrsize << 1; + /* One extra bit is needed in order to get the square root with enough + precision ; take one extra bit for rrsize in order to solve more + easily the problem of rounding to nearest. + Need to have 2*rrsize = rsize... + Take one extra bit if the exponent of u is odd since we shall have + to shift then. + */ + + TMP_MARK(marker0); + if (odd_exp_u) /* Shift u one bit to the right */ + { + if (MPFR_PREC(u) & (BITS_PER_MP_LIMB - 1)) + { + up = TMP_ALLOC(usize * BYTES_PER_MP_LIMB); + mpn_rshift(up, MPFR_MANT(u), usize, 1); + } + else + { + up = TMP_ALLOC((usize + 1) * BYTES_PER_MP_LIMB); + if (mpn_rshift(up + 1, MPFR_MANT(u), usize, 1)) + up[0] = MP_LIMB_T_HIGHBIT; + else + up[0] = 0; + usize++; + } } - /* Do the real job */ + MPFR_EXP(r) = MPFR_EXP(u) != MPFR_EMAX_MAX + ? (MPFR_EXP(u) + odd_exp_u) / 2 + : (MPFR_EMAX_MAX - 1) / 2 + 1; + + do + { + TMP_MARK (marker); + + err = rsize * BITS_PER_MP_LIMB; + if (rsize < usize) + err--; + if (err > rrsize * BITS_PER_MP_LIMB) + err = rrsize * BITS_PER_MP_LIMB; + + tmp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB); + rp = (mp_ptr) TMP_ALLOC (rrsize * BYTES_PER_MP_LIMB); + remp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB); + + if (usize >= rsize) + { + MPN_COPY (tmp, up + usize - rsize, rsize); + } + else + { + MPN_COPY (tmp + rsize - usize, up, usize); + MPN_ZERO (tmp, rsize - usize); + } + + /* Do the real job */ #ifdef DEBUG - printf("Taking the sqrt of : "); - for(k = rsize - 1; k >= 0; k--) { - printf("+%lu*2^%lu",tmp[k],k*BITS_PER_MP_LIMB); } - printf(".\n"); + printf("Taking the sqrt of : "); + for(k = rsize - 1; k >= 0; k--) + printf("+%lu*2^%lu",tmp[k],k*BITS_PER_MP_LIMB); + printf(".\n"); #endif - q_limb = mpn_sqrtrem (rp, remp, tmp, rsize); + q_limb = mpn_sqrtrem (rp, remp, tmp, rsize); #ifdef DEBUG - printf ("The result is : \n"); - printf ("sqrt : "); - for (k = rrsize - 1; k >= 0; k--) - printf ("%lu ", rp[k]); - printf ("(inexact = %lu)\n", q_limb); + printf ("The result is : \n"); + printf ("sqrt : "); + for (k = rrsize - 1; k >= 0; k--) + printf ("%lu ", rp[k]); + printf ("(inexact = %lu)\n", q_limb); #endif - - can_round = mpfr_can_round_raw(rp, rrsize, 1, err, - GMP_RNDZ, rnd_mode, MPFR_PREC(r)); - /* If we used all the limbs of both the dividend and the divisor, - then we have the correct RNDZ rounding */ + can_round = mpfr_can_round_raw(rp, rrsize, 1, err, + GMP_RNDZ, rnd_mode, MPFR_PREC(r)); - if (!can_round && (rsize < 2*usize)) - { + /* If we used all the limbs of both the dividend and the divisor, + then we have the correct RNDZ rounding */ + + if (!can_round && (rsize < 2*usize)) + { #ifdef DEBUG - printf("Increasing the precision.\n"); + printf("Increasing the precision.\n"); #endif - TMP_FREE(marker); - } - } - while (!can_round && (rsize < 2*usize) - && (rsize += 2) && (rrsize ++)); + TMP_FREE(marker); + } + } + while (!can_round && (rsize < 2*usize) && (rsize += 2) && (rrsize++)); #ifdef DEBUG - printf ("can_round = %d\n", can_round); + printf ("can_round = %d\n", can_round); #endif - /* This part may be deplaced upper to avoid a few mpfr_can_round_raw */ - /* when the square root is exact. It is however very unprobable that */ - /* it would improve the behaviour of the present code on average. */ + /* This part may be deplaced upper to avoid a few mpfr_can_round_raw */ + /* when the square root is exact. It is however very unprobable that */ + /* it would improve the behaviour of the present code on average. */ - if (!q_limb) /* the sqrtrem call was exact, possible exact square root */ - { - /* if we have taken into account the whole of up */ - for (k = usize - rsize - 1; k >= 0; k ++) - if (up[k]) break; - - if (k < 0) - goto fin; /* exact square root ==> inexact = 0 */ - } - - if (can_round) - { - cc = mpfr_round_raw (rp, rp, err, 0, MPFR_PREC(r), rnd_mode, &inexact); - if (!inexact) /* exact high part: inexact flag depends from remainder */ - inexact = -q_limb; - rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; - } - else - /* Use the return value of sqrtrem to decide of the rounding */ - /* Note that at this point the sqrt has been computed */ - /* EXACTLY. */ - switch (rnd_mode) + if (!q_limb) /* the sqrtrem call was exact, possible exact square root */ + { + /* if we have taken into account the whole of up */ + for (k = usize - rsize - 1; k >= 0; k++) + if (up[k] != 0) + break; + + if (k < 0) + goto fin; /* exact square root ==> inexact = 0 */ + } + + if (can_round) + { + cc = mpfr_round_raw (rp, rp, err, 0, MPFR_PREC(r), rnd_mode, &inexact); + if (inexact == 0) /* exact high part: inex flag depends on remainder */ + inexact = -q_limb; + rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; + } + else { - case GMP_RNDZ : - case GMP_RNDD : - inexact = -1; /* result is truncated */ - break; - - case GMP_RNDN : - /* Not in the situation ...0 111111 */ - rw = (MPFR_PREC(r) + 1) & (BITS_PER_MP_LIMB - 1); - if (rw) - { - rw = BITS_PER_MP_LIMB - rw; - nw = 0; - } - else - nw = 1; - if ((rp[nw] >> rw) & 1 && /* Not 0111111111 */ - (q_limb || /* Nonzero remainder */ - (rw ? (rp[nw] >> (rw + 1)) & 1 : - (rp[nw] >> (BITS_PER_MP_LIMB - 1)) & 1))) /* or even rounding */ - { - cc = mpn_add_1 (rp + nw, rp + nw, rrsize, MP_LIMB_T_ONE << rw); - inexact = 1; - } - else - inexact = -1; - break; + /* Use the return value of sqrtrem to decide of the rounding */ + /* Note that at this point the sqrt has been computed */ + /* EXACTLY. */ + switch (rnd_mode) + { + case GMP_RNDZ : + case GMP_RNDD : + inexact = -1; /* result is truncated */ + break; + + case GMP_RNDN : + /* Not in the situation ...0 111111 */ + rw = (MPFR_PREC(r) + 1) & (BITS_PER_MP_LIMB - 1); + if (rw != 0) + { + rw = BITS_PER_MP_LIMB - rw; + nw = 0; + } + else + nw = 1; + if ((rp[nw] >> rw) & 1 && /* Not 0111111111 */ + (q_limb || /* Nonzero remainder */ + (rw ? (rp[nw] >> (rw + 1)) & 1 : + (rp[nw] >> (BITS_PER_MP_LIMB - 1)) & 1))) /* or even r. */ + { + cc = mpn_add_1 (rp + nw, rp + nw, rrsize, MP_LIMB_T_ONE << rw); + inexact = 1; + } + else + inexact = -1; + break; - case GMP_RNDU: - /* we should arrive here only when the result is inexact, - i.e. either q_limb > 0 (the remainder from mpn_sqrtrem is non-zero) - or up[0..usize-rsize-1] is non zero, thus we have to add one - ulp, and inexact = 1 */ - inexact = 1; - t = MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1); - rsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; - if (t) + case GMP_RNDU: + /* we should arrive here only when the result is inexact, i.e. + either q_limb > 0 (the remainder from mpn_sqrtrem is non-zero) + or up[0..usize-rsize-1] is non zero, thus we have to add one + ulp, and inexact = 1 */ + inexact = 1; + t = MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1); + rsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; cc = mpn_add_1 (rp + rrsize - rsize, rp + rrsize - rsize, rsize, - MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - t)); - else - cc = mpn_add_1 (rp + rrsize - rsize, rp + rrsize - rsize, rsize, - MP_LIMB_T_ONE); + t != 0 ? + MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - t) : + MP_LIMB_T_ONE); + } } - if (cc) - { - /* Is a shift necessary here? Isn't the result 1.0000...? */ - mpn_rshift (rp, rp, rrsize, 1); - rp[rrsize-1] |= MP_LIMB_T_HIGHBIT; - MPFR_EXP(r)++; - } - - fin: - rsize = rrsize; - rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; - MPN_COPY(MPFR_MANT(r), rp + rsize - rrsize, rrsize); - - if (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1)) - MPFR_MANT(r) [0] &= ~((MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - - (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1)))) - 1) ; - - TMP_FREE (marker); + if (cc) + { + /* Is a shift necessary here? Isn't the result 1.0000...? */ + mpn_rshift (rp, rp, rrsize, 1); + rp[rrsize-1] |= MP_LIMB_T_HIGHBIT; + MPFR_EXP(r)++; + } + + fin: + rsize = rrsize; + rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; + MPN_COPY(MPFR_MANT(r), rp + rsize - rrsize, rrsize); + + if (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1)) + MPFR_MANT(r)[0] &= ~((MP_LIMB_T_ONE << + (BITS_PER_MP_LIMB - + (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1)))) - 1); + + TMP_FREE (marker); } TMP_FREE(marker0); return inexact; diff --git a/mpfr/sqrt_ui.c b/mpfr/sqrt_ui.c index 4e044c137..e72f0227a 100644 --- a/mpfr/sqrt_ui.c +++ b/mpfr/sqrt_ui.c @@ -1,6 +1,6 @@ /* mpfr_sqrt_ui -- square root of a machine integer -Copyright (C) 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 2000-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,8 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -35,18 +33,22 @@ mpfr_sqrt_ui (mpfr_ptr r, unsigned long u, mp_rnd_t rnd_mode) mpfr_t uu; mp_limb_t up[1]; unsigned long cnt; - + int inex; + MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1); count_leading_zeros (cnt, (mp_limb_t) u); *up = (mp_limb_t) u << cnt; MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt; - - return mpfr_sqrt(r, uu, rnd_mode); + + mpfr_save_emin_emax(); + inex = mpfr_sqrt(r, uu, rnd_mode); + MPFR_RESTORE_RET(inex, r, rnd_mode); } else /* sqrt(0) = 0 */ { MPFR_CLEAR_FLAGS(r); MPFR_SET_ZERO(r); - return 0; + MPFR_SET_POS(r); + MPFR_RET(0); } } diff --git a/mpfr/sub.c b/mpfr/sub.c index e830bf692..95f05c9b6 100644 --- a/mpfr/sub.c +++ b/mpfr/sub.c @@ -29,124 +29,83 @@ int mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) { if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) - { - MPFR_SET_NAN(a); - MPFR_RET_NAN; - } + { + MPFR_SET_NAN(a); + MPFR_RET_NAN; + } MPFR_CLEAR_NAN(a); if (MPFR_IS_INF(b)) - { - if (!MPFR_IS_INF(c) || MPFR_SIGN(b) != MPFR_SIGN(c)) - { - MPFR_SET_INF(a); - MPFR_SET_SAME_SIGN(a, b); - MPFR_RET(0); /* exact */ - } - else { - MPFR_SET_NAN(a); - MPFR_RET_NAN; + if (!MPFR_IS_INF(c) || MPFR_SIGN(b) != MPFR_SIGN(c)) + { + MPFR_SET_INF(a); + MPFR_SET_SAME_SIGN(a, b); + MPFR_RET(0); /* exact */ + } + else + { + MPFR_SET_NAN(a); + MPFR_RET_NAN; + } } - } else if (MPFR_IS_INF(c)) - { - MPFR_SET_INF(a); - if (MPFR_SIGN(c) == MPFR_SIGN(a)) - MPFR_CHANGE_SIGN(a); - MPFR_RET(0); /* exact */ - } + { + MPFR_SET_INF(a); + if (MPFR_SIGN(c) == MPFR_SIGN(a)) + MPFR_CHANGE_SIGN(a); + MPFR_RET(0); /* exact */ + } MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_IS_FP(c)); if (MPFR_IS_ZERO(b)) - { - if (MPFR_IS_ZERO(c)) { - if (MPFR_SIGN(a) != - (rnd_mode != GMP_RNDD ? - ((MPFR_SIGN(b) < 0 && MPFR_SIGN(c) > 0) ? -1 : 1) : - ((MPFR_SIGN(b) > 0 && MPFR_SIGN(c) < 0) ? 1 : -1))) - MPFR_CHANGE_SIGN(a); - MPFR_CLEAR_INF(a); - MPFR_SET_ZERO(a); - MPFR_RET(0); /* 0 - 0 is exact */ + if (MPFR_IS_ZERO(c)) + { + if (MPFR_SIGN(a) != + (rnd_mode != GMP_RNDD ? + ((MPFR_SIGN(b) < 0 && MPFR_SIGN(c) > 0) ? -1 : 1) : + ((MPFR_SIGN(b) > 0 && MPFR_SIGN(c) < 0) ? 1 : -1))) + MPFR_CHANGE_SIGN(a); + MPFR_CLEAR_INF(a); + MPFR_SET_ZERO(a); + MPFR_RET(0); /* 0 - 0 is exact */ + } + return mpfr_neg (a, c, rnd_mode); } - return mpfr_neg (a, c, rnd_mode); - } if (MPFR_IS_ZERO(c)) - { - return mpfr_set (a, b, rnd_mode); - } + { + return mpfr_set (a, b, rnd_mode); + } MPFR_CLEAR_INF(a); if (MPFR_SIGN(b) == MPFR_SIGN(c)) - { /* signs are equal, it's a real subtraction */ - if (MPFR_EXP(b) < MPFR_EXP(c)) - { /* exchange rounding modes towards +/- infinity */ - int inexact; - if (rnd_mode == GMP_RNDU) - rnd_mode = GMP_RNDD; - else if (rnd_mode == GMP_RNDD) - rnd_mode = GMP_RNDU; - inexact = - mpfr_sub1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); - MPFR_CHANGE_SIGN(a); - return inexact; - } - else if (MPFR_EXP(b) > MPFR_EXP(c)) - return mpfr_sub1(a, b, c, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); - else - { /* MPFR_EXP(b) == MPFR_EXP(c) */ - int d = mpfr_cmp_abs (b, c); - - if (d == 0) - { - if (rnd_mode == GMP_RNDD) - MPFR_SET_NEG(a); - else - MPFR_SET_POS(a); - MPFR_SET_ZERO(a); - MPFR_RET(0); - } - else if (d > 0) - return mpfr_sub1 (a, b, c, rnd_mode, 0); - else - { /* exchange rounding modes towards +/- infinity */ - int inexact; - if (rnd_mode == GMP_RNDU) - rnd_mode = GMP_RNDD; - else if (rnd_mode == GMP_RNDD) - rnd_mode = GMP_RNDU; - inexact = - mpfr_sub1 (a, c, b, rnd_mode, 0); - MPFR_CHANGE_SIGN(a); - return inexact; - } + { /* signs are equal, it's a real subtraction */ + return mpfr_sub1(a, b, c, rnd_mode, 1); } - } else - { /* signs differ, it's an addition */ - if (MPFR_EXP(b) < MPFR_EXP(c)) - { /* exchange rounding modes towards +/- infinity */ - int inexact; - if (rnd_mode == GMP_RNDU) - rnd_mode = GMP_RNDD; - else if (rnd_mode == GMP_RNDD) - rnd_mode = GMP_RNDU; - inexact = mpfr_add1(a, c, b, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); - MPFR_CHANGE_SIGN(a); - return inexact; - } - else - { - return mpfr_add1(a, b, c, rnd_mode, - (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); + { /* signs differ, it's an addition */ + if (MPFR_EXP(b) < MPFR_EXP(c)) + { /* exchange rounding modes towards +/- infinity */ + int inexact; + if (rnd_mode == GMP_RNDU) + rnd_mode = GMP_RNDD; + else if (rnd_mode == GMP_RNDD) + rnd_mode = GMP_RNDU; + inexact = mpfr_add1(a, c, b, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b)); + MPFR_CHANGE_SIGN(a); + return inexact; + } + else + { + return mpfr_add1(a, b, c, rnd_mode, + (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c)); + } } - } } diff --git a/mpfr/sub1.c b/mpfr/sub1.c index 3de855729..99e119d8e 100644 --- a/mpfr/sub1.c +++ b/mpfr/sub1.c @@ -25,35 +25,56 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" -/* signs of b and c differ, abs(b) > abs(c), - diff_exp = EXP(b) - EXP(c). +/* compute sign(b) * (|b| - |c|), with |b| > |c|, diff_exp = EXP(b) - EXP(c) Returns 0 iff result is exact, a negative value when the result is less than the exact value, a positive value otherwise. */ int -mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, - mp_rnd_t rnd_mode, mp_exp_unsigned_t diff_exp) +mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode, + int sub) { - unsigned long cancel, cancel1, sh, k; - long int cancel2, an, bn, cn, cn0; - mp_limb_t *ap, *bp, *cp, carry, bb, cc, borrow = 0; - int inexact = 0, shift_b, shift_c, is_exact = 1, down = 0, add_exp=0; + int sign; + mp_exp_unsigned_t diff_exp; + mp_prec_t cancel, cancel1; + mp_size_t cancel2, an, bn, cn, cn0; + mp_limb_t *ap, *bp, *cp; + mp_limb_t carry, bb, cc, borrow = 0; + int inexact = 0, shift_b, shift_c, is_exact = 1, down = 0, add_exp = 0; + int sh, k; TMP_DECL(marker); -#ifdef DEBUG - printf("\nenter mpfr_sub, rnd_mode=%s:\n", mpfr_print_rnd_mode(rnd_mode)); - printf("b="); if (MPFR_SIGN(b)>0) putchar(' '); mpfr_print_raw(b); putchar('\n'); - printf("c="); if (MPFR_SIGN(c)>0) putchar(' '); for (k=0; k<diff_exp; k++) putchar(' '); mpfr_print_raw(c); putchar('\n'); - printf("PREC(a)=%u PREC(b)=%u PREC(c)=%u\n", MPFR_PREC(a), MPFR_PREC(b), - MPFR_PREC(c)); -#endif TMP_MARK(marker); ap = MPFR_MANT(a); an = 1 + (MPFR_PREC(a) - 1) / BITS_PER_MP_LIMB; - cancel = mpfr_cmp2 (b, c); + sign = mpfr_cmp2 (b, c, &cancel); + if (sign == 0) + { + if (rnd_mode == GMP_RNDD) + MPFR_SET_NEG(a); + else + MPFR_SET_POS(a); + MPFR_SET_ZERO(a); + MPFR_RET(0); + } + + /* If subtraction: sign(a) = sign * sign(b) */ + if (sub && MPFR_SIGN(a) != sign * MPFR_SIGN(b)) + MPFR_CHANGE_SIGN(a); + + if (sign < 0) /* swap b and c so that |b| > |c| */ + { + mpfr_srcptr t; + t = b; b = c; c = t; + } + + /* If addition: sign(a) = sign of the larger argument in absolute value */ + if (!sub) + MPFR_SET_SAME_SIGN(a, b); + + diff_exp = (mp_exp_unsigned_t) MPFR_EXP(b) - MPFR_EXP(c); /* reserve a space to store b aligned with the result, i.e. shifted by (-cancel) % BITS_PER_MP_LIMB to the right */ @@ -101,17 +122,16 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, cp = (mp_ptr) TMP_ALLOC (cn * BYTES_PER_MP_LIMB); MPN_COPY(cp, ap, cn); } + + /* here we have shift_c = (diff_exp - cancel) % BITS_PER_MP_LIMB, + thus we want cancel2 = ceil((cancel - diff_exp) / BITS_PER_MP_LIMB) */ - cancel2 = (long int) (cancel + shift_c - diff_exp) / BITS_PER_MP_LIMB; + cancel2 = (long int) (cancel - (diff_exp - shift_c)) / BITS_PER_MP_LIMB; /* the high cancel2 limbs from b should not be taken into account */ #ifdef DEBUG printf("cancel=%u cancel1=%u cancel2=%d\n", cancel, cancel1, cancel2); #endif - /* adjust sign of result */ - if (MPFR_SIGN(a)*MPFR_SIGN(b) < 0) - MPFR_CHANGE_SIGN(a); - /* ap[an-1] ap[0] <----------------+-----------|----> <----------PREC(a)----------><-sh-> @@ -145,7 +165,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, MPN_ZERO (ap, an); #ifdef DEBUG - printf("after copying high(b), a="); mpfr_print_raw(a); putchar('\n'); + printf("after copying high(b), a="); mpfr_print_binary(a); putchar('\n'); #endif /* subtract high(c) */ @@ -183,7 +203,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, } #ifdef DEBUG - printf("after subtracting high(c), a="); mpfr_print_raw(a); putchar('\n'); + printf("after subtracting high(c), a="); mpfr_print_binary(a); putchar('\n'); #endif /* now perform rounding */ @@ -210,8 +230,8 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, } else /* directed rounding: set rnd_mode to RNDZ iff towards zero */ { - if (((rnd_mode == GMP_RNDD) && (MPFR_SIGN(b) > 0)) || - ((rnd_mode == GMP_RNDU) && (MPFR_SIGN(b) < 0))) + if (((rnd_mode == GMP_RNDD) && (MPFR_SIGN(a) > 0)) || + ((rnd_mode == GMP_RNDU) && (MPFR_SIGN(a) < 0))) rnd_mode = GMP_RNDZ; if (carry) @@ -232,10 +252,10 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, cn0 = cn; cn -= (long int) an + cancel2; #ifdef DEBUG - printf("last %u bits from a are %lu, bn=%ld, cn=%ld\n", sh, carry, bn, cn); + printf("last %d bits from a are %lu, bn=%ld, cn=%ld\n", sh, carry, bn, cn); #endif - for (k=0; (bn > 0) || (cn > 0); k++) + for (k = 0; (bn > 0) || (cn > 0); k = 1) { bb = (bn > 0) ? bp[--bn] : 0; if ((cn > 0) && (cn-- <= cn0)) @@ -243,13 +263,10 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, else cc = 0; -#ifdef DEBUG - printf("k=%u bb=%lu cc=%lu down=%d\n", k, bb, cc, down); -#endif if (down == 0) down = (bb < cc); - if ((rnd_mode == GMP_RNDN) && !k && !sh) + if ((rnd_mode == GMP_RNDN) && !k && sh == 0) { mp_limb_t half = MP_LIMB_T_HIGHBIT; @@ -290,12 +307,12 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, } else /* round to nearest */ { - if (is_exact && !sh) + if (is_exact && sh == 0) { inexact = 0; goto truncate; } - else if (down && !sh) + else if (down && sh == 0) goto sub_one_ulp; else { @@ -398,9 +415,9 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, } TMP_FREE(marker); #ifdef DEBUG - printf ("result is a="); mpfr_print_raw(a); putchar('\n'); + printf ("result is a="); mpfr_print_binary(a); putchar('\n'); #endif /* check that result is msb-normalized */ MPFR_ASSERTN(ap[an-1] > ~ap[an-1]); - return inexact * MPFR_SIGN(b); + return inexact * MPFR_SIGN(a); } diff --git a/mpfr/add_ulp.c b/mpfr/sub_one_ulp.c index a0c0e58f0..3d229eb0c 100644 --- a/mpfr/add_ulp.c +++ b/mpfr/sub_one_ulp.c @@ -1,4 +1,4 @@ -/* mpfr_add_one_ulp, mpfr_sub_one_ulp -- add/subtract one unit in last place +/* mpfr_sub_one_ulp -- subtract one unit in last place Copyright (C) 1999, 2001 Free Software Foundation, Inc. @@ -20,50 +20,43 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gmp.h" +#include "gmp-impl.h" #include "mpfr.h" #include "mpfr-impl.h" -#include "gmp-impl.h" -/* sets x to x+sign(x)*2^(MPFR_EXP(x)-MPFR_PREC(x)) */ -void -mpfr_add_one_ulp (mpfr_ptr x) +/* sets x to x-sign(x)*ulp(x) */ +int +mpfr_sub_one_ulp(mpfr_ptr x, mp_rnd_t rnd_mode) { - int xn, sh; + mp_size_t xn; + int sh; mp_limb_t *xp; - if (MPFR_IS_INF(x)) - return; + if (MPFR_IS_NAN(x)) + MPFR_RET_NAN; - xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB; - sh = xn * BITS_PER_MP_LIMB - MPFR_PREC(x); - xp = MPFR_MANT(x); - if (mpn_add_1 (xp, xp, xn, MP_LIMB_T_ONE << sh)) /* got 1.0000... */ - { - MPFR_EXP(x)++; - xp[xn-1] = MP_LIMB_T_HIGHBIT; - } - return; -} - -/* sets x to x-sign(x)*ulp(x) */ -void -mpfr_sub_one_ulp(mpfr_ptr x) -{ - int xn, sh; - mp_limb_t *xp; + if (MPFR_IS_INF(x) || MPFR_IS_ZERO(x)) + return 0; - if (MPFR_IS_INF(x)) - return; + MPFR_ASSERTN(MPFR_PREC_MIN > 1); xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB; sh = xn * BITS_PER_MP_LIMB - MPFR_PREC(x); xp = MPFR_MANT(x); mpn_sub_1 (xp, xp, xn, MP_LIMB_T_ONE << sh); - if (xp[xn-1] >> (BITS_PER_MP_LIMB - 1) == 0) { - /* was an exact power of two: not normalized any more */ - MPFR_EXP(x)--; - mpn_lshift (xp, xp, xn, 1); - *xp |= MP_LIMB_T_ONE << sh; - } - return; + if (xp[xn-1] >> (BITS_PER_MP_LIMB - 1) == 0) + { /* was an exact power of two: not normalized any more */ + mp_exp_t exp = MPFR_EXP(x); + if (exp == __mpfr_emin) + return mpfr_set_underflow(x, rnd_mode, MPFR_SIGN(x)); + else + { + int i; + MPFR_EXP(x)--; + xp[0] = (sh + 1 == BITS_PER_MP_LIMB) ? 0 : MP_LIMB_T_MAX << (sh + 1); + for (i = 1; i < xn; i++) + xp[i] = MP_LIMB_T_MAX; + } + } + return 0; } diff --git a/mpfr/sub_ui.c b/mpfr/sub_ui.c index cb18307d0..ce4b0bc63 100644 --- a/mpfr/sub_ui.c +++ b/mpfr/sub_ui.c @@ -1,6 +1,6 @@ /* mpfr_sub_ui -- subtract a floating-point number and a machine integer -Copyright (C) 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 2000-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -34,22 +33,18 @@ mpfr_sub_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) mpfr_t uu; mp_limb_t up[1]; unsigned long cnt; - int inex_sub, inex_cr; + int inex; MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1); count_leading_zeros(cnt, (mp_limb_t) u); *up = (mp_limb_t) u << cnt; - MPFR_EXP(uu) = BITS_PER_MP_LIMB-cnt; + MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt; /* Optimization note: Exponent operations may be removed - if mpfr_add works even when uu is out-of-range. */ + if mpfr_sub works even when uu is out-of-range. */ mpfr_save_emin_emax(); - inex_sub = mpfr_sub (y, x, uu, rnd_mode); - mpfr_restore_emin_emax(); - inex_cr = mpfr_check_range(y, rnd_mode); - if (inex_cr) - return inex_cr; /* underflow or overflow */ - MPFR_RET(inex_sub); + inex = mpfr_sub(y, x, uu, rnd_mode); + MPFR_RESTORE_RET(inex, y, rnd_mode); } else return mpfr_set (y, x, rnd_mode); diff --git a/mpfr/tan.c b/mpfr/tan.c index 3effc8749..aa2930488 100644 --- a/mpfr/tan.c +++ b/mpfr/tan.c @@ -1,6 +1,6 @@ /* mpfr_tan -- tangent of a floating-point number -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "mpfr.h" @@ -27,7 +26,7 @@ MA 02111-1307, USA. */ /* computes tan(x) = sign(x)*sqrt(1/cos(x)^2-1) */ int -mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) +mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) { int precy, m, ok, e, inexact; mpfr_t c; @@ -35,13 +34,15 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) { MPFR_SET_NAN(y); - return 1; /* inexact */ + MPFR_RET_NAN; } - if (!MPFR_NOTZERO(x)) + if (MPFR_IS_ZERO(x)) { - mpfr_set_ui (y, 0, GMP_RNDN); - return 0; /* exact */ + MPFR_CLEAR_FLAGS(y); + MPFR_SET_ZERO(y); + MPFR_SET_SAME_SIGN(y, x); + MPFR_RET(0); } precy = MPFR_PREC(y); diff --git a/mpfr/tanh.c b/mpfr/tanh.c index 4f0baa5ec..13996358c 100644 --- a/mpfr/tanh.c +++ b/mpfr/tanh.c @@ -1,6 +1,6 @@ /* mpfr_tanh -- hyperbolic tangent -Copyright (C) 2001 Free Software Foundation. +Copyright (C) 2001-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -50,13 +50,13 @@ mpfr_tanh (y, xt, rnd_mode) if (MPFR_IS_NAN(xt)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); if (MPFR_IS_INF(xt)) { - if(MPFR_SIGN(xt) > 0) + if (MPFR_SIGN(xt) > 0) return mpfr_set_si(y,1,rnd_mode); /* tanh(inf) = 1 */ else return mpfr_set_si(y,-1,rnd_mode); /* tanh(-inf) = -1 */ @@ -64,17 +64,17 @@ mpfr_tanh (y, xt, rnd_mode) MPFR_CLEAR_INF(y); /* tanh(0) = 0 */ - if(!MPFR_NOTZERO(xt)) + if (MPFR_IS_ZERO(xt)) { MPFR_SET_ZERO(y); MPFR_SET_SAME_SIGN(y,xt); - return 0; + MPFR_RET(0); } - + mpfr_init2(x,Nxt); mpfr_set(x,xt,GMP_RNDN); - if(MPFR_SIGN(x)<0) + if (MPFR_SIGN(x) < 0) { MPFR_CHANGE_SIGN(x); flag_neg=1; @@ -115,7 +115,7 @@ mpfr_tanh (y, xt, rnd_mode) mpfr_set_prec(tb,Nt); /* compute tanh */ - mpfr_mul_2exp(te,x,1,GMP_RNDN); /* 2x */ + mpfr_mul_2ui(te,x,1,GMP_RNDN); /* 2x */ mpfr_exp(te,te,GMP_RNDN); /* exp(2x) */ mpfr_add_ui(ta,te,1,GMP_RNDD); /* exp(2x) + 1*/ mpfr_sub_ui(tb,te,1,GMP_RNDU); /* exp(2x) - 1*/ diff --git a/mpfr/tests/Makefile.am b/mpfr/tests/Makefile.am index 98c419dc7..9cbc3f922 100644 --- a/mpfr/tests/Makefile.am +++ b/mpfr/tests/Makefile.am @@ -25,7 +25,7 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mpfr LDADD = ../libmpfr.a $(top_builddir)/libgmp.la $(LIBM) if WANT_MPFR -check_PROGRAMS= reuse tabs tadd tagm tcan_round tcmp tcmp2 tcmp_ui tdiv tdiv_ui tdump teq texp tget_str tlog tlog2 tmul tmul_2exp tmul_ui tout_str tpi tpow trandom tround tset_d tset_f tset_q tset_si tset_str tset_z tsqrt tsqrt_ui tui_div tui_sub tswap ttrunc tisnan tget_d tatan tcosh tsinh ttanh tacosh tasinh tatanh thyperbolic texp2 tfactorial tsub tasin teuler tcos tsin ttan tsub_ui tset tlog1p texpm1 tlog_base_2 tui_pow tpow3 tlog_base_10 tadd_ui texceptions tfma thypot +check_PROGRAMS= reuse tabs tadd tagm tcan_round tcmp tcmp2 tcmp_ui tdiv tdiv_ui tdump teq texp tget_str tlog tconst_log2 tmul tmul_2exp tmul_ui tout_str tconst_pi tpow trandom tround_prec tset_d tset_f tset_q tset_si tset_str tset_z tsqrt tsqrt_ui tui_div tui_sub tswap ttrunc trint tisnan tget_d tatan tcosh tsinh ttanh tacosh tasinh tatanh thyperbolic texp2 tfactorial tsub tasin tconst_euler tcos tsin ttan tsub_ui tset tlog1p texpm1 tlog2 tlog10 tui_pow tpow3 tadd_ui texceptions tfma thypot tacos TESTS = $(check_PROGRAMS) endif EXTRA_DIST= tgeneric.c diff --git a/mpfr/tests/Makefile.in b/mpfr/tests/Makefile.in index 6672743bb..92351d1e6 100644 --- a/mpfr/tests/Makefile.in +++ b/mpfr/tests/Makefile.in @@ -137,7 +137,7 @@ AUTOMAKE_OPTIONS = gnu no-dependencies $(top_builddir)/ansi2knr INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mpfr LDADD = ../libmpfr.a $(top_builddir)/libgmp.la $(LIBM) -@WANT_MPFR_TRUE@check_PROGRAMS = reuse tabs tadd tagm tcan_round tcmp tcmp2 tcmp_ui tdiv tdiv_ui tdump teq texp tget_str tlog tlog2 tmul tmul_2exp tmul_ui tout_str tpi tpow trandom tround tset_d tset_f tset_q tset_si tset_str tset_z tsqrt tsqrt_ui tui_div tui_sub tswap ttrunc tisnan tget_d tatan tcosh tsinh ttanh tacosh tasinh tatanh thyperbolic texp2 tfactorial tsub tasin teuler tcos tsin ttan tsub_ui tset tlog1p texpm1 tlog_base_2 tui_pow tpow3 tlog_base_10 tadd_ui texceptions tfma thypot +@WANT_MPFR_TRUE@check_PROGRAMS = reuse tabs tadd tagm tcan_round tcmp tcmp2 tcmp_ui tdiv tdiv_ui tdump teq texp tget_str tlog tconst_log2 tmul tmul_2exp tmul_ui tout_str tconst_pi tpow trandom tround_prec tset_d tset_f tset_q tset_si tset_str tset_z tsqrt tsqrt_ui tui_div tui_sub tswap ttrunc trint tisnan tget_d tatan tcosh tsinh ttanh tacosh tasinh tatanh thyperbolic texp2 tfactorial tsub tasin tconst_euler tcos tsin ttan tsub_ui tset tlog1p texpm1 tlog2 tlog10 tui_pow tpow3 tadd_ui texceptions tfma thypot tacos @WANT_MPFR_TRUE@TESTS = $(check_PROGRAMS) EXTRA_DIST = tgeneric.c subdir = mpfr/tests @@ -149,27 +149,29 @@ CONFIG_CLEAN_FILES = @WANT_MPFR_TRUE@ tcmp$(EXEEXT) tcmp2$(EXEEXT) tcmp_ui$(EXEEXT) \ @WANT_MPFR_TRUE@ tdiv$(EXEEXT) tdiv_ui$(EXEEXT) tdump$(EXEEXT) \ @WANT_MPFR_TRUE@ teq$(EXEEXT) texp$(EXEEXT) tget_str$(EXEEXT) \ -@WANT_MPFR_TRUE@ tlog$(EXEEXT) tlog2$(EXEEXT) tmul$(EXEEXT) \ -@WANT_MPFR_TRUE@ tmul_2exp$(EXEEXT) tmul_ui$(EXEEXT) \ -@WANT_MPFR_TRUE@ tout_str$(EXEEXT) tpi$(EXEEXT) tpow$(EXEEXT) \ -@WANT_MPFR_TRUE@ trandom$(EXEEXT) tround$(EXEEXT) \ +@WANT_MPFR_TRUE@ tlog$(EXEEXT) tconst_log2$(EXEEXT) \ +@WANT_MPFR_TRUE@ tmul$(EXEEXT) tmul_2exp$(EXEEXT) \ +@WANT_MPFR_TRUE@ tmul_ui$(EXEEXT) tout_str$(EXEEXT) \ +@WANT_MPFR_TRUE@ tconst_pi$(EXEEXT) tpow$(EXEEXT) \ +@WANT_MPFR_TRUE@ trandom$(EXEEXT) tround_prec$(EXEEXT) \ @WANT_MPFR_TRUE@ tset_d$(EXEEXT) tset_f$(EXEEXT) tset_q$(EXEEXT) \ @WANT_MPFR_TRUE@ tset_si$(EXEEXT) tset_str$(EXEEXT) \ @WANT_MPFR_TRUE@ tset_z$(EXEEXT) tsqrt$(EXEEXT) \ @WANT_MPFR_TRUE@ tsqrt_ui$(EXEEXT) tui_div$(EXEEXT) \ @WANT_MPFR_TRUE@ tui_sub$(EXEEXT) tswap$(EXEEXT) ttrunc$(EXEEXT) \ -@WANT_MPFR_TRUE@ tisnan$(EXEEXT) tget_d$(EXEEXT) tatan$(EXEEXT) \ -@WANT_MPFR_TRUE@ tcosh$(EXEEXT) tsinh$(EXEEXT) ttanh$(EXEEXT) \ -@WANT_MPFR_TRUE@ tacosh$(EXEEXT) tasinh$(EXEEXT) tatanh$(EXEEXT) \ -@WANT_MPFR_TRUE@ thyperbolic$(EXEEXT) texp2$(EXEEXT) \ -@WANT_MPFR_TRUE@ tfactorial$(EXEEXT) tsub$(EXEEXT) \ -@WANT_MPFR_TRUE@ tasin$(EXEEXT) teuler$(EXEEXT) tcos$(EXEEXT) \ +@WANT_MPFR_TRUE@ trint$(EXEEXT) tisnan$(EXEEXT) tget_d$(EXEEXT) \ +@WANT_MPFR_TRUE@ tatan$(EXEEXT) tcosh$(EXEEXT) tsinh$(EXEEXT) \ +@WANT_MPFR_TRUE@ ttanh$(EXEEXT) tacosh$(EXEEXT) tasinh$(EXEEXT) \ +@WANT_MPFR_TRUE@ tatanh$(EXEEXT) thyperbolic$(EXEEXT) \ +@WANT_MPFR_TRUE@ texp2$(EXEEXT) tfactorial$(EXEEXT) \ +@WANT_MPFR_TRUE@ tsub$(EXEEXT) tasin$(EXEEXT) \ +@WANT_MPFR_TRUE@ tconst_euler$(EXEEXT) tcos$(EXEEXT) \ @WANT_MPFR_TRUE@ tsin$(EXEEXT) ttan$(EXEEXT) tsub_ui$(EXEEXT) \ @WANT_MPFR_TRUE@ tset$(EXEEXT) tlog1p$(EXEEXT) texpm1$(EXEEXT) \ -@WANT_MPFR_TRUE@ tlog_base_2$(EXEEXT) tui_pow$(EXEEXT) \ -@WANT_MPFR_TRUE@ tpow3$(EXEEXT) tlog_base_10$(EXEEXT) \ -@WANT_MPFR_TRUE@ tadd_ui$(EXEEXT) texceptions$(EXEEXT) \ -@WANT_MPFR_TRUE@ tfma$(EXEEXT) thypot$(EXEEXT) +@WANT_MPFR_TRUE@ tlog2$(EXEEXT) tlog10$(EXEEXT) tui_pow$(EXEEXT) \ +@WANT_MPFR_TRUE@ tpow3$(EXEEXT) tadd_ui$(EXEEXT) \ +@WANT_MPFR_TRUE@ texceptions$(EXEEXT) tfma$(EXEEXT) \ +@WANT_MPFR_TRUE@ thypot$(EXEEXT) tacos$(EXEEXT) @WANT_MPFR_FALSE@check_PROGRAMS = reuse_SOURCES = reuse.c reuse_OBJECTS = reuse$U.$(OBJEXT) @@ -181,6 +183,11 @@ tabs_OBJECTS = tabs$U.$(OBJEXT) tabs_LDADD = $(LDADD) tabs_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la tabs_LDFLAGS = +tacos_SOURCES = tacos.c +tacos_OBJECTS = tacos$U.$(OBJEXT) +tacos_LDADD = $(LDADD) +tacos_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +tacos_LDFLAGS = tacosh_SOURCES = tacosh.c tacosh_OBJECTS = tacosh$U.$(OBJEXT) tacosh_LDADD = $(LDADD) @@ -241,6 +248,21 @@ tcmp_ui_OBJECTS = tcmp_ui$U.$(OBJEXT) tcmp_ui_LDADD = $(LDADD) tcmp_ui_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la tcmp_ui_LDFLAGS = +tconst_euler_SOURCES = tconst_euler.c +tconst_euler_OBJECTS = tconst_euler$U.$(OBJEXT) +tconst_euler_LDADD = $(LDADD) +tconst_euler_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +tconst_euler_LDFLAGS = +tconst_log2_SOURCES = tconst_log2.c +tconst_log2_OBJECTS = tconst_log2$U.$(OBJEXT) +tconst_log2_LDADD = $(LDADD) +tconst_log2_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +tconst_log2_LDFLAGS = +tconst_pi_SOURCES = tconst_pi.c +tconst_pi_OBJECTS = tconst_pi$U.$(OBJEXT) +tconst_pi_LDADD = $(LDADD) +tconst_pi_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +tconst_pi_LDFLAGS = tcos_SOURCES = tcos.c tcos_OBJECTS = tcos$U.$(OBJEXT) tcos_LDADD = $(LDADD) @@ -271,11 +293,6 @@ teq_OBJECTS = teq$U.$(OBJEXT) teq_LDADD = $(LDADD) teq_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la teq_LDFLAGS = -teuler_SOURCES = teuler.c -teuler_OBJECTS = teuler$U.$(OBJEXT) -teuler_LDADD = $(LDADD) -teuler_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la -teuler_LDFLAGS = texceptions_SOURCES = texceptions.c texceptions_OBJECTS = texceptions$U.$(OBJEXT) texceptions_LDADD = $(LDADD) @@ -336,6 +353,11 @@ tlog_OBJECTS = tlog$U.$(OBJEXT) tlog_LDADD = $(LDADD) tlog_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la tlog_LDFLAGS = +tlog10_SOURCES = tlog10.c +tlog10_OBJECTS = tlog10$U.$(OBJEXT) +tlog10_LDADD = $(LDADD) +tlog10_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +tlog10_LDFLAGS = tlog1p_SOURCES = tlog1p.c tlog1p_OBJECTS = tlog1p$U.$(OBJEXT) tlog1p_LDADD = $(LDADD) @@ -346,16 +368,6 @@ tlog2_OBJECTS = tlog2$U.$(OBJEXT) tlog2_LDADD = $(LDADD) tlog2_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la tlog2_LDFLAGS = -tlog_base_10_SOURCES = tlog_base_10.c -tlog_base_10_OBJECTS = tlog_base_10$U.$(OBJEXT) -tlog_base_10_LDADD = $(LDADD) -tlog_base_10_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la -tlog_base_10_LDFLAGS = -tlog_base_2_SOURCES = tlog_base_2.c -tlog_base_2_OBJECTS = tlog_base_2$U.$(OBJEXT) -tlog_base_2_LDADD = $(LDADD) -tlog_base_2_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la -tlog_base_2_LDFLAGS = tmul_SOURCES = tmul.c tmul_OBJECTS = tmul$U.$(OBJEXT) tmul_LDADD = $(LDADD) @@ -376,11 +388,6 @@ tout_str_OBJECTS = tout_str$U.$(OBJEXT) tout_str_LDADD = $(LDADD) tout_str_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la tout_str_LDFLAGS = -tpi_SOURCES = tpi.c -tpi_OBJECTS = tpi$U.$(OBJEXT) -tpi_LDADD = $(LDADD) -tpi_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la -tpi_LDFLAGS = tpow_SOURCES = tpow.c tpow_OBJECTS = tpow$U.$(OBJEXT) tpow_LDADD = $(LDADD) @@ -396,11 +403,16 @@ trandom_OBJECTS = trandom$U.$(OBJEXT) trandom_LDADD = $(LDADD) trandom_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la trandom_LDFLAGS = -tround_SOURCES = tround.c -tround_OBJECTS = tround$U.$(OBJEXT) -tround_LDADD = $(LDADD) -tround_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la -tround_LDFLAGS = +trint_SOURCES = trint.c +trint_OBJECTS = trint$U.$(OBJEXT) +trint_LDADD = $(LDADD) +trint_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +trint_LDFLAGS = +tround_prec_SOURCES = tround_prec.c +tround_prec_OBJECTS = tround_prec$U.$(OBJEXT) +tround_prec_LDADD = $(LDADD) +tround_prec_DEPENDENCIES = ../libmpfr.a $(top_builddir)/libgmp.la +tround_prec_LDFLAGS = tset_SOURCES = tset.c tset_OBJECTS = tset$U.$(OBJEXT) tset_LDADD = $(LDADD) @@ -516,18 +528,19 @@ CCLD = $(CC) LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ CFLAGS = @CFLAGS@ -DIST_SOURCES = reuse.c tabs.c tacosh.c tadd.c tadd_ui.c tagm.c tasin.c \ - tasinh.c tatan.c tatanh.c tcan_round.c tcmp.c tcmp2.c tcmp_ui.c \ - tcos.c tcosh.c tdiv.c tdiv_ui.c tdump.c teq.c teuler.c \ - texceptions.c texp.c texp2.c texpm1.c tfactorial.c tfma.c \ - tget_d.c tget_str.c thyperbolic.c thypot.c tisnan.c tlog.c \ - tlog1p.c tlog2.c tlog_base_10.c tlog_base_2.c tmul.c \ - tmul_2exp.c tmul_ui.c tout_str.c tpi.c tpow.c tpow3.c trandom.c \ - tround.c tset.c tset_d.c tset_f.c tset_q.c tset_si.c tset_str.c \ - tset_z.c tsin.c tsinh.c tsqrt.c tsqrt_ui.c tsub.c tsub_ui.c \ - tswap.c ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c +DIST_SOURCES = reuse.c tabs.c tacos.c tacosh.c tadd.c tadd_ui.c tagm.c \ + tasin.c tasinh.c tatan.c tatanh.c tcan_round.c tcmp.c tcmp2.c \ + tcmp_ui.c tconst_euler.c tconst_log2.c tconst_pi.c tcos.c \ + tcosh.c tdiv.c tdiv_ui.c tdump.c teq.c texceptions.c texp.c \ + texp2.c texpm1.c tfactorial.c tfma.c tget_d.c tget_str.c \ + thyperbolic.c thypot.c tisnan.c tlog.c tlog10.c tlog1p.c \ + tlog2.c tmul.c tmul_2exp.c tmul_ui.c tout_str.c tpow.c tpow3.c \ + trandom.c trint.c tround_prec.c tset.c tset_d.c tset_f.c \ + tset_q.c tset_si.c tset_str.c tset_z.c tsin.c tsinh.c tsqrt.c \ + tsqrt_ui.c tsub.c tsub_ui.c tswap.c ttan.c ttanh.c ttrunc.c \ + tui_div.c tui_pow.c tui_sub.c DIST_COMMON = Makefile.am Makefile.in -SOURCES = reuse.c tabs.c tacosh.c tadd.c tadd_ui.c tagm.c tasin.c tasinh.c tatan.c tatanh.c tcan_round.c tcmp.c tcmp2.c tcmp_ui.c tcos.c tcosh.c tdiv.c tdiv_ui.c tdump.c teq.c teuler.c texceptions.c texp.c texp2.c texpm1.c tfactorial.c tfma.c tget_d.c tget_str.c thyperbolic.c thypot.c tisnan.c tlog.c tlog1p.c tlog2.c tlog_base_10.c tlog_base_2.c tmul.c tmul_2exp.c tmul_ui.c tout_str.c tpi.c tpow.c tpow3.c trandom.c tround.c tset.c tset_d.c tset_f.c tset_q.c tset_si.c tset_str.c tset_z.c tsin.c tsinh.c tsqrt.c tsqrt_ui.c tsub.c tsub_ui.c tswap.c ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c +SOURCES = reuse.c tabs.c tacos.c tacosh.c tadd.c tadd_ui.c tagm.c tasin.c tasinh.c tatan.c tatanh.c tcan_round.c tcmp.c tcmp2.c tcmp_ui.c tconst_euler.c tconst_log2.c tconst_pi.c tcos.c tcosh.c tdiv.c tdiv_ui.c tdump.c teq.c texceptions.c texp.c texp2.c texpm1.c tfactorial.c tfma.c tget_d.c tget_str.c thyperbolic.c thypot.c tisnan.c tlog.c tlog10.c tlog1p.c tlog2.c tmul.c tmul_2exp.c tmul_ui.c tout_str.c tpow.c tpow3.c trandom.c trint.c tround_prec.c tset.c tset_d.c tset_f.c tset_q.c tset_si.c tset_str.c tset_z.c tsin.c tsinh.c tsqrt.c tsqrt_ui.c tsub.c tsub_ui.c tswap.c ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c all: all-am @@ -558,6 +571,9 @@ reuse$(EXEEXT): $(reuse_OBJECTS) $(reuse_DEPENDENCIES) tabs$(EXEEXT): $(tabs_OBJECTS) $(tabs_DEPENDENCIES) @rm -f tabs$(EXEEXT) $(LINK) $(tabs_LDFLAGS) $(tabs_OBJECTS) $(tabs_LDADD) $(LIBS) +tacos$(EXEEXT): $(tacos_OBJECTS) $(tacos_DEPENDENCIES) + @rm -f tacos$(EXEEXT) + $(LINK) $(tacos_LDFLAGS) $(tacos_OBJECTS) $(tacos_LDADD) $(LIBS) tacosh$(EXEEXT): $(tacosh_OBJECTS) $(tacosh_DEPENDENCIES) @rm -f tacosh$(EXEEXT) $(LINK) $(tacosh_LDFLAGS) $(tacosh_OBJECTS) $(tacosh_LDADD) $(LIBS) @@ -594,6 +610,15 @@ tcmp2$(EXEEXT): $(tcmp2_OBJECTS) $(tcmp2_DEPENDENCIES) tcmp_ui$(EXEEXT): $(tcmp_ui_OBJECTS) $(tcmp_ui_DEPENDENCIES) @rm -f tcmp_ui$(EXEEXT) $(LINK) $(tcmp_ui_LDFLAGS) $(tcmp_ui_OBJECTS) $(tcmp_ui_LDADD) $(LIBS) +tconst_euler$(EXEEXT): $(tconst_euler_OBJECTS) $(tconst_euler_DEPENDENCIES) + @rm -f tconst_euler$(EXEEXT) + $(LINK) $(tconst_euler_LDFLAGS) $(tconst_euler_OBJECTS) $(tconst_euler_LDADD) $(LIBS) +tconst_log2$(EXEEXT): $(tconst_log2_OBJECTS) $(tconst_log2_DEPENDENCIES) + @rm -f tconst_log2$(EXEEXT) + $(LINK) $(tconst_log2_LDFLAGS) $(tconst_log2_OBJECTS) $(tconst_log2_LDADD) $(LIBS) +tconst_pi$(EXEEXT): $(tconst_pi_OBJECTS) $(tconst_pi_DEPENDENCIES) + @rm -f tconst_pi$(EXEEXT) + $(LINK) $(tconst_pi_LDFLAGS) $(tconst_pi_OBJECTS) $(tconst_pi_LDADD) $(LIBS) tcos$(EXEEXT): $(tcos_OBJECTS) $(tcos_DEPENDENCIES) @rm -f tcos$(EXEEXT) $(LINK) $(tcos_LDFLAGS) $(tcos_OBJECTS) $(tcos_LDADD) $(LIBS) @@ -612,9 +637,6 @@ tdump$(EXEEXT): $(tdump_OBJECTS) $(tdump_DEPENDENCIES) teq$(EXEEXT): $(teq_OBJECTS) $(teq_DEPENDENCIES) @rm -f teq$(EXEEXT) $(LINK) $(teq_LDFLAGS) $(teq_OBJECTS) $(teq_LDADD) $(LIBS) -teuler$(EXEEXT): $(teuler_OBJECTS) $(teuler_DEPENDENCIES) - @rm -f teuler$(EXEEXT) - $(LINK) $(teuler_LDFLAGS) $(teuler_OBJECTS) $(teuler_LDADD) $(LIBS) texceptions$(EXEEXT): $(texceptions_OBJECTS) $(texceptions_DEPENDENCIES) @rm -f texceptions$(EXEEXT) $(LINK) $(texceptions_LDFLAGS) $(texceptions_OBJECTS) $(texceptions_LDADD) $(LIBS) @@ -651,18 +673,15 @@ tisnan$(EXEEXT): $(tisnan_OBJECTS) $(tisnan_DEPENDENCIES) tlog$(EXEEXT): $(tlog_OBJECTS) $(tlog_DEPENDENCIES) @rm -f tlog$(EXEEXT) $(LINK) $(tlog_LDFLAGS) $(tlog_OBJECTS) $(tlog_LDADD) $(LIBS) +tlog10$(EXEEXT): $(tlog10_OBJECTS) $(tlog10_DEPENDENCIES) + @rm -f tlog10$(EXEEXT) + $(LINK) $(tlog10_LDFLAGS) $(tlog10_OBJECTS) $(tlog10_LDADD) $(LIBS) tlog1p$(EXEEXT): $(tlog1p_OBJECTS) $(tlog1p_DEPENDENCIES) @rm -f tlog1p$(EXEEXT) $(LINK) $(tlog1p_LDFLAGS) $(tlog1p_OBJECTS) $(tlog1p_LDADD) $(LIBS) tlog2$(EXEEXT): $(tlog2_OBJECTS) $(tlog2_DEPENDENCIES) @rm -f tlog2$(EXEEXT) $(LINK) $(tlog2_LDFLAGS) $(tlog2_OBJECTS) $(tlog2_LDADD) $(LIBS) -tlog_base_10$(EXEEXT): $(tlog_base_10_OBJECTS) $(tlog_base_10_DEPENDENCIES) - @rm -f tlog_base_10$(EXEEXT) - $(LINK) $(tlog_base_10_LDFLAGS) $(tlog_base_10_OBJECTS) $(tlog_base_10_LDADD) $(LIBS) -tlog_base_2$(EXEEXT): $(tlog_base_2_OBJECTS) $(tlog_base_2_DEPENDENCIES) - @rm -f tlog_base_2$(EXEEXT) - $(LINK) $(tlog_base_2_LDFLAGS) $(tlog_base_2_OBJECTS) $(tlog_base_2_LDADD) $(LIBS) tmul$(EXEEXT): $(tmul_OBJECTS) $(tmul_DEPENDENCIES) @rm -f tmul$(EXEEXT) $(LINK) $(tmul_LDFLAGS) $(tmul_OBJECTS) $(tmul_LDADD) $(LIBS) @@ -675,9 +694,6 @@ tmul_ui$(EXEEXT): $(tmul_ui_OBJECTS) $(tmul_ui_DEPENDENCIES) tout_str$(EXEEXT): $(tout_str_OBJECTS) $(tout_str_DEPENDENCIES) @rm -f tout_str$(EXEEXT) $(LINK) $(tout_str_LDFLAGS) $(tout_str_OBJECTS) $(tout_str_LDADD) $(LIBS) -tpi$(EXEEXT): $(tpi_OBJECTS) $(tpi_DEPENDENCIES) - @rm -f tpi$(EXEEXT) - $(LINK) $(tpi_LDFLAGS) $(tpi_OBJECTS) $(tpi_LDADD) $(LIBS) tpow$(EXEEXT): $(tpow_OBJECTS) $(tpow_DEPENDENCIES) @rm -f tpow$(EXEEXT) $(LINK) $(tpow_LDFLAGS) $(tpow_OBJECTS) $(tpow_LDADD) $(LIBS) @@ -687,9 +703,12 @@ tpow3$(EXEEXT): $(tpow3_OBJECTS) $(tpow3_DEPENDENCIES) trandom$(EXEEXT): $(trandom_OBJECTS) $(trandom_DEPENDENCIES) @rm -f trandom$(EXEEXT) $(LINK) $(trandom_LDFLAGS) $(trandom_OBJECTS) $(trandom_LDADD) $(LIBS) -tround$(EXEEXT): $(tround_OBJECTS) $(tround_DEPENDENCIES) - @rm -f tround$(EXEEXT) - $(LINK) $(tround_LDFLAGS) $(tround_OBJECTS) $(tround_LDADD) $(LIBS) +trint$(EXEEXT): $(trint_OBJECTS) $(trint_DEPENDENCIES) + @rm -f trint$(EXEEXT) + $(LINK) $(trint_LDFLAGS) $(trint_OBJECTS) $(trint_LDADD) $(LIBS) +tround_prec$(EXEEXT): $(tround_prec_OBJECTS) $(tround_prec_DEPENDENCIES) + @rm -f tround_prec$(EXEEXT) + $(LINK) $(tround_prec_LDFLAGS) $(tround_prec_OBJECTS) $(tround_prec_LDADD) $(LIBS) tset$(EXEEXT): $(tset_OBJECTS) $(tset_DEPENDENCIES) @rm -f tset$(EXEEXT) $(LINK) $(tset_LDFLAGS) $(tset_OBJECTS) $(tset_LDADD) $(LIBS) @@ -776,6 +795,8 @@ reuse_.c: reuse.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/reuse.c; then echo $(srcdir)/reuse.c; else echo reuse.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > reuse_.c || rm -f reuse_.c tabs_.c: tabs.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tabs.c; then echo $(srcdir)/tabs.c; else echo tabs.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tabs_.c || rm -f tabs_.c +tacos_.c: tacos.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tacos.c; then echo $(srcdir)/tacos.c; else echo tacos.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tacos_.c || rm -f tacos_.c tacosh_.c: tacosh.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tacosh.c; then echo $(srcdir)/tacosh.c; else echo tacosh.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tacosh_.c || rm -f tacosh_.c tadd_.c: tadd.c $(ANSI2KNR) @@ -800,6 +821,12 @@ tcmp2_.c: tcmp2.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tcmp2.c; then echo $(srcdir)/tcmp2.c; else echo tcmp2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tcmp2_.c || rm -f tcmp2_.c tcmp_ui_.c: tcmp_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tcmp_ui.c; then echo $(srcdir)/tcmp_ui.c; else echo tcmp_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tcmp_ui_.c || rm -f tcmp_ui_.c +tconst_euler_.c: tconst_euler.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tconst_euler.c; then echo $(srcdir)/tconst_euler.c; else echo tconst_euler.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tconst_euler_.c || rm -f tconst_euler_.c +tconst_log2_.c: tconst_log2.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tconst_log2.c; then echo $(srcdir)/tconst_log2.c; else echo tconst_log2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tconst_log2_.c || rm -f tconst_log2_.c +tconst_pi_.c: tconst_pi.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tconst_pi.c; then echo $(srcdir)/tconst_pi.c; else echo tconst_pi.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tconst_pi_.c || rm -f tconst_pi_.c tcos_.c: tcos.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tcos.c; then echo $(srcdir)/tcos.c; else echo tcos.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tcos_.c || rm -f tcos_.c tcosh_.c: tcosh.c $(ANSI2KNR) @@ -812,8 +839,6 @@ tdump_.c: tdump.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tdump.c; then echo $(srcdir)/tdump.c; else echo tdump.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tdump_.c || rm -f tdump_.c teq_.c: teq.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/teq.c; then echo $(srcdir)/teq.c; else echo teq.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > teq_.c || rm -f teq_.c -teuler_.c: teuler.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/teuler.c; then echo $(srcdir)/teuler.c; else echo teuler.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > teuler_.c || rm -f teuler_.c texceptions_.c: texceptions.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/texceptions.c; then echo $(srcdir)/texceptions.c; else echo texceptions.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > texceptions_.c || rm -f texceptions_.c texp_.c: texp.c $(ANSI2KNR) @@ -838,14 +863,12 @@ tisnan_.c: tisnan.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tisnan.c; then echo $(srcdir)/tisnan.c; else echo tisnan.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tisnan_.c || rm -f tisnan_.c tlog_.c: tlog.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tlog.c; then echo $(srcdir)/tlog.c; else echo tlog.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tlog_.c || rm -f tlog_.c +tlog10_.c: tlog10.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tlog10.c; then echo $(srcdir)/tlog10.c; else echo tlog10.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tlog10_.c || rm -f tlog10_.c tlog1p_.c: tlog1p.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tlog1p.c; then echo $(srcdir)/tlog1p.c; else echo tlog1p.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tlog1p_.c || rm -f tlog1p_.c tlog2_.c: tlog2.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tlog2.c; then echo $(srcdir)/tlog2.c; else echo tlog2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tlog2_.c || rm -f tlog2_.c -tlog_base_10_.c: tlog_base_10.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tlog_base_10.c; then echo $(srcdir)/tlog_base_10.c; else echo tlog_base_10.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tlog_base_10_.c || rm -f tlog_base_10_.c -tlog_base_2_.c: tlog_base_2.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tlog_base_2.c; then echo $(srcdir)/tlog_base_2.c; else echo tlog_base_2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tlog_base_2_.c || rm -f tlog_base_2_.c tmul_.c: tmul.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tmul.c; then echo $(srcdir)/tmul.c; else echo tmul.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tmul_.c || rm -f tmul_.c tmul_2exp_.c: tmul_2exp.c $(ANSI2KNR) @@ -854,16 +877,16 @@ tmul_ui_.c: tmul_ui.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tmul_ui.c; then echo $(srcdir)/tmul_ui.c; else echo tmul_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tmul_ui_.c || rm -f tmul_ui_.c tout_str_.c: tout_str.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tout_str.c; then echo $(srcdir)/tout_str.c; else echo tout_str.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tout_str_.c || rm -f tout_str_.c -tpi_.c: tpi.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tpi.c; then echo $(srcdir)/tpi.c; else echo tpi.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tpi_.c || rm -f tpi_.c tpow_.c: tpow.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tpow.c; then echo $(srcdir)/tpow.c; else echo tpow.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tpow_.c || rm -f tpow_.c tpow3_.c: tpow3.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tpow3.c; then echo $(srcdir)/tpow3.c; else echo tpow3.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tpow3_.c || rm -f tpow3_.c trandom_.c: trandom.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/trandom.c; then echo $(srcdir)/trandom.c; else echo trandom.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > trandom_.c || rm -f trandom_.c -tround_.c: tround.c $(ANSI2KNR) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tround.c; then echo $(srcdir)/tround.c; else echo tround.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tround_.c || rm -f tround_.c +trint_.c: trint.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/trint.c; then echo $(srcdir)/trint.c; else echo trint.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > trint_.c || rm -f trint_.c +tround_prec_.c: tround_prec.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tround_prec.c; then echo $(srcdir)/tround_prec.c; else echo tround_prec.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tround_prec_.c || rm -f tround_prec_.c tset_.c: tset.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tset.c; then echo $(srcdir)/tset.c; else echo tset.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tset_.c || rm -f tset_.c tset_d_.c: tset_d.c $(ANSI2KNR) @@ -904,36 +927,38 @@ tui_pow_.c: tui_pow.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tui_pow.c; then echo $(srcdir)/tui_pow.c; else echo tui_pow.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tui_pow_.c || rm -f tui_pow_.c tui_sub_.c: tui_sub.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tui_sub.c; then echo $(srcdir)/tui_sub.c; else echo tui_sub.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tui_sub_.c || rm -f tui_sub_.c -reuse_.$(OBJEXT) reuse_.lo tabs_.$(OBJEXT) tabs_.lo tacosh_.$(OBJEXT) \ -tacosh_.lo tadd_.$(OBJEXT) tadd_.lo tadd_ui_.$(OBJEXT) tadd_ui_.lo \ -tagm_.$(OBJEXT) tagm_.lo tasin_.$(OBJEXT) tasin_.lo tasinh_.$(OBJEXT) \ -tasinh_.lo tatan_.$(OBJEXT) tatan_.lo tatanh_.$(OBJEXT) tatanh_.lo \ +reuse_.$(OBJEXT) reuse_.lo tabs_.$(OBJEXT) tabs_.lo tacos_.$(OBJEXT) \ +tacos_.lo tacosh_.$(OBJEXT) tacosh_.lo tadd_.$(OBJEXT) tadd_.lo \ +tadd_ui_.$(OBJEXT) tadd_ui_.lo tagm_.$(OBJEXT) tagm_.lo \ +tasin_.$(OBJEXT) tasin_.lo tasinh_.$(OBJEXT) tasinh_.lo \ +tatan_.$(OBJEXT) tatan_.lo tatanh_.$(OBJEXT) tatanh_.lo \ tcan_round_.$(OBJEXT) tcan_round_.lo tcmp_.$(OBJEXT) tcmp_.lo \ tcmp2_.$(OBJEXT) tcmp2_.lo tcmp_ui_.$(OBJEXT) tcmp_ui_.lo \ -tcos_.$(OBJEXT) tcos_.lo tcosh_.$(OBJEXT) tcosh_.lo tdiv_.$(OBJEXT) \ -tdiv_.lo tdiv_ui_.$(OBJEXT) tdiv_ui_.lo tdump_.$(OBJEXT) tdump_.lo \ -teq_.$(OBJEXT) teq_.lo teuler_.$(OBJEXT) teuler_.lo \ -texceptions_.$(OBJEXT) texceptions_.lo texp_.$(OBJEXT) texp_.lo \ -texp2_.$(OBJEXT) texp2_.lo texpm1_.$(OBJEXT) texpm1_.lo \ -tfactorial_.$(OBJEXT) tfactorial_.lo tfma_.$(OBJEXT) tfma_.lo \ -tget_d_.$(OBJEXT) tget_d_.lo tget_str_.$(OBJEXT) tget_str_.lo \ +tconst_euler_.$(OBJEXT) tconst_euler_.lo tconst_log2_.$(OBJEXT) \ +tconst_log2_.lo tconst_pi_.$(OBJEXT) tconst_pi_.lo tcos_.$(OBJEXT) \ +tcos_.lo tcosh_.$(OBJEXT) tcosh_.lo tdiv_.$(OBJEXT) tdiv_.lo \ +tdiv_ui_.$(OBJEXT) tdiv_ui_.lo tdump_.$(OBJEXT) tdump_.lo \ +teq_.$(OBJEXT) teq_.lo texceptions_.$(OBJEXT) texceptions_.lo \ +texp_.$(OBJEXT) texp_.lo texp2_.$(OBJEXT) texp2_.lo texpm1_.$(OBJEXT) \ +texpm1_.lo tfactorial_.$(OBJEXT) tfactorial_.lo tfma_.$(OBJEXT) \ +tfma_.lo tget_d_.$(OBJEXT) tget_d_.lo tget_str_.$(OBJEXT) tget_str_.lo \ thyperbolic_.$(OBJEXT) thyperbolic_.lo thypot_.$(OBJEXT) thypot_.lo \ -tisnan_.$(OBJEXT) tisnan_.lo tlog_.$(OBJEXT) tlog_.lo tlog1p_.$(OBJEXT) \ -tlog1p_.lo tlog2_.$(OBJEXT) tlog2_.lo tlog_base_10_.$(OBJEXT) \ -tlog_base_10_.lo tlog_base_2_.$(OBJEXT) tlog_base_2_.lo tmul_.$(OBJEXT) \ -tmul_.lo tmul_2exp_.$(OBJEXT) tmul_2exp_.lo tmul_ui_.$(OBJEXT) \ -tmul_ui_.lo tout_str_.$(OBJEXT) tout_str_.lo tpi_.$(OBJEXT) tpi_.lo \ +tisnan_.$(OBJEXT) tisnan_.lo tlog_.$(OBJEXT) tlog_.lo tlog10_.$(OBJEXT) \ +tlog10_.lo tlog1p_.$(OBJEXT) tlog1p_.lo tlog2_.$(OBJEXT) tlog2_.lo \ +tmul_.$(OBJEXT) tmul_.lo tmul_2exp_.$(OBJEXT) tmul_2exp_.lo \ +tmul_ui_.$(OBJEXT) tmul_ui_.lo tout_str_.$(OBJEXT) tout_str_.lo \ tpow_.$(OBJEXT) tpow_.lo tpow3_.$(OBJEXT) tpow3_.lo trandom_.$(OBJEXT) \ -trandom_.lo tround_.$(OBJEXT) tround_.lo tset_.$(OBJEXT) tset_.lo \ -tset_d_.$(OBJEXT) tset_d_.lo tset_f_.$(OBJEXT) tset_f_.lo \ -tset_q_.$(OBJEXT) tset_q_.lo tset_si_.$(OBJEXT) tset_si_.lo \ -tset_str_.$(OBJEXT) tset_str_.lo tset_z_.$(OBJEXT) tset_z_.lo \ -tsin_.$(OBJEXT) tsin_.lo tsinh_.$(OBJEXT) tsinh_.lo tsqrt_.$(OBJEXT) \ -tsqrt_.lo tsqrt_ui_.$(OBJEXT) tsqrt_ui_.lo tsub_.$(OBJEXT) tsub_.lo \ -tsub_ui_.$(OBJEXT) tsub_ui_.lo tswap_.$(OBJEXT) tswap_.lo \ -ttan_.$(OBJEXT) ttan_.lo ttanh_.$(OBJEXT) ttanh_.lo ttrunc_.$(OBJEXT) \ -ttrunc_.lo tui_div_.$(OBJEXT) tui_div_.lo tui_pow_.$(OBJEXT) \ -tui_pow_.lo tui_sub_.$(OBJEXT) tui_sub_.lo : $(ANSI2KNR) +trandom_.lo trint_.$(OBJEXT) trint_.lo tround_prec_.$(OBJEXT) \ +tround_prec_.lo tset_.$(OBJEXT) tset_.lo tset_d_.$(OBJEXT) tset_d_.lo \ +tset_f_.$(OBJEXT) tset_f_.lo tset_q_.$(OBJEXT) tset_q_.lo \ +tset_si_.$(OBJEXT) tset_si_.lo tset_str_.$(OBJEXT) tset_str_.lo \ +tset_z_.$(OBJEXT) tset_z_.lo tsin_.$(OBJEXT) tsin_.lo tsinh_.$(OBJEXT) \ +tsinh_.lo tsqrt_.$(OBJEXT) tsqrt_.lo tsqrt_ui_.$(OBJEXT) tsqrt_ui_.lo \ +tsub_.$(OBJEXT) tsub_.lo tsub_ui_.$(OBJEXT) tsub_ui_.lo \ +tswap_.$(OBJEXT) tswap_.lo ttan_.$(OBJEXT) ttan_.lo ttanh_.$(OBJEXT) \ +ttanh_.lo ttrunc_.$(OBJEXT) ttrunc_.lo tui_div_.$(OBJEXT) tui_div_.lo \ +tui_pow_.$(OBJEXT) tui_pow_.lo tui_sub_.$(OBJEXT) tui_sub_.lo : \ +$(ANSI2KNR) uninstall-info-am: tags: TAGS diff --git a/mpfr/tests/reuse.c b/mpfr/tests/reuse.c index 879708025..3626b6e49 100644 --- a/mpfr/tests/reuse.c +++ b/mpfr/tests/reuse.c @@ -608,12 +608,12 @@ main (void) testfunc = (void*) mpfr_add; test3 ("mpfr_add", 53, GMP_RNDN); testfunc = (void*) mpfr_add_ui; test2ui ("mpfr_add_ui", 53, GMP_RNDN); testfunc = mpfr_agm; test3 ("mpfr_agm", 53, GMP_RNDN); - testfunc = mpfr_ceil; test2 ("mpfr_ceil", 53, GMP_RNDN); + testfunc = (void*) mpfr_ceil; test2 ("mpfr_ceil", 53, GMP_RNDN); testfunc = (void*) mpfr_div; test3 ("mpfr_div", 53, GMP_RNDN); testfunc = (void*) mpfr_div_2exp; test2ui ("mpfr_div_2exp", 53, GMP_RNDN); testfunc = (void*) mpfr_div_ui; test2ui ("mpfr_div_ui", 53, GMP_RNDN); testfunc = (void*) mpfr_exp; test2 ("mpfr_exp", 53, GMP_RNDN); - testfunc = mpfr_floor; test2 ("mpfr_floor", 53, GMP_RNDN); + testfunc = (void*) mpfr_floor; test2 ("mpfr_floor", 53, GMP_RNDN); testfunc = (void*) mpfr_log; test2 ("mpfr_log", 53, GMP_RNDN); testfunc = (void*) mpfr_mul; test3 ("mpfr_mul", 53, GMP_RNDN); testfunc = (void*) mpfr_mul_2exp; test2ui ("mpfr_mul_2exp", 53, GMP_RNDN); @@ -626,8 +626,9 @@ main (void) testfunc = (void*) mpfr_sqrt; test2 ("mpfr_sqrt", 53, GMP_RNDN); testfunc = (void*) mpfr_ui_div; testui2 ("mpfr_ui_div", 53, GMP_RNDN); testfunc = (void*) mpfr_ui_sub; testui2 ("mpfr_ui_sub", 53, GMP_RNDN); - testfunc = mpfr_trunc; test2 ("mpfr_trunc", 53, GMP_RNDN); + testfunc = (void*) mpfr_trunc; test2 ("mpfr_trunc", 53, GMP_RNDN); testfunc = (void*) mpfr_asin; test2 ("mpfr_asin", 53, GMP_RNDN); + testfunc = (void*) mpfr_acos; test2 ("mpfr_acos", 53, GMP_RNDN); testfunc = (void*) mpfr_atan; test2 ("mpfr_atan", 53, GMP_RNDN); testfunc = (void*) mpfr_sinh; test2 ("mpfr_sinh", 53, GMP_RNDN); testfunc = (void*) mpfr_cosh; test2 ("mpfr_cosh", 53, GMP_RNDN); diff --git a/mpfr/tests/tabs.c b/mpfr/tests/tabs.c index 8b3a90cab..193a51f6c 100644 --- a/mpfr/tests/tabs.c +++ b/mpfr/tests/tabs.c @@ -1,6 +1,6 @@ /* Test file for mpfr_abs. -Copyright (C) 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 2000-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -21,7 +21,6 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <stdlib.h> -#include <math.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-test.h" @@ -31,7 +30,7 @@ MA 02111-1307, USA. */ void check_inexact _PROTO((void)); void -check_inexact () +check_inexact (void) { mp_prec_t p, q; mpfr_t x, y, absx; @@ -42,7 +41,7 @@ check_inexact () mpfr_init (y); mpfr_init (absx); - for (p=1; p<500; p++) + for (p=2; p<500; p++) { mpfr_set_prec (x, p); mpfr_set_prec (absx, p); @@ -54,7 +53,7 @@ check_inexact () } else mpfr_set (absx, x, GMP_RNDN); - for (q=1; q<2*p; q++) + for (q=2; q<2*p; q++) { mpfr_set_prec (y, q); for (rnd=0; rnd<4; rnd++) @@ -66,9 +65,9 @@ check_inexact () ((inexact < 0) && (cmp >= 0))) { fprintf (stderr, "Wrong inexact flag: expected %d, got %d\n", cmp, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("absx="); mpfr_print_raw (absx); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("absx="); mpfr_print_binary (absx); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); exit (1); } } @@ -129,11 +128,11 @@ main (int argc, char *argv[]) mpfr_set_d(x, d, 0); mpfr_abs(x, x, rnd); dd = mpfr_get_d(x); - if (dd != fabs(d) && !isnan(d)) + if (!isnan(d) && dd != ABS(d)) { fprintf(stderr, "Mismatch on d = %1.18g\n", d); - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); exit(1); } } diff --git a/mpfr/tests/tacos.c b/mpfr/tests/tacos.c new file mode 100644 index 000000000..a8705463c --- /dev/null +++ b/mpfr/tests/tacos.c @@ -0,0 +1,95 @@ +/* Test file for mpfr_acos. + +Copyright (C) 2001 Free Software Foundation. +Contributed by Mathieu Dutour. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +main (void) +{ + unsigned int prec, err, yprec, n; + mp_rnd_t rnd; + mpfr_t x, y, z; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + MPFR_SET_NAN(x); + mpfr_acos (y, x, GMP_RNDN); + if (mpfr_nan_p(y) == 0) + { + fprintf (stderr, "Error: acos(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_ui (x, 2, GMP_RNDN); + mpfr_acos (y, x, GMP_RNDN); + if (mpfr_nan_p(y) == 0) + { + fprintf (stderr, "Error: acos(2) != NaN\n"); + exit (1); + } + + for (prec = 2; prec <= 100; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + yprec = prec + 10; + + for (n=0; n<10; n++) + { + mpfr_random (x); + rnd = random () % 4; + mpfr_set_prec (y, yprec); + mpfr_acos (y, x, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_round_prec (y, rnd, prec); + mpfr_acos (z, x, rnd); + if (mpfr_cmp (y, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode (rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, y, GMP_RNDN); + putchar ('\n'); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + return 0; +} diff --git a/mpfr/tests/tacosh.c b/mpfr/tests/tacosh.c index d9d288f92..e3fcedea6 100644 --- a/mpfr/tests/tacosh.c +++ b/mpfr/tests/tacosh.c @@ -33,7 +33,11 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 25); + test_generic (2, 100, 25); return 0; } + + + + diff --git a/mpfr/tests/tadd.c b/mpfr/tests/tadd.c index 02017deaf..e540a9fbb 100644 --- a/mpfr/tests/tadd.c +++ b/mpfr/tests/tadd.c @@ -21,7 +21,6 @@ MA 02111-1307, USA. */ #define N 100000 -#include <math.h> #include <stdio.h> #include <stdlib.h> #include "gmp.h" @@ -167,12 +166,14 @@ check5 (double x, mp_rnd_t rnd_mode) z1 = (neg) ? x-x : x+x; z2 = mpfr_get_d(xx); mpfr_set_d (yy, z2, GMP_RNDN); - if (!mpfr_cmp (xx, yy) && z1!=z2 && !(isnan(z1) && isnan(z2))) { - printf("expected result is %1.20e, got %1.20e\n",z1,z2); - printf("mpfr_%s(x,x,x) failed for x=%1.20e with rnd_mode=%s\n", - (neg) ? "sub" : "add", x, mpfr_print_rnd_mode (rnd_mode)); - exit(1); - } + /* check NaNs first since mpfr_cmp does not like them */ + if (!(isnan(z1) && isnan(z2)) && !mpfr_cmp (xx, yy) && z1!=z2) + { + printf ("expected result is %1.20e, got %1.20e\n",z1,z2); + printf ("mpfr_%s(x,x,x) failed for x=%1.20e with rnd_mode=%s\n", + (neg) ? "sub" : "add", x, mpfr_print_rnd_mode (rnd_mode)); + exit (1); + } mpfr_clear(xx); mpfr_clear(yy); } @@ -195,7 +196,7 @@ check2 (double x, int px, double y, int py, int pz, mp_rnd_t rnd_mode) printf("got %1.20e\n",z2); printf("result should be %1.20e (diff=%d ulp)\n",z,u); mpfr_set_d(zz, z, rnd_mode); - printf("i.e."); mpfr_print_raw(zz); putchar('\n'); + printf("i.e."); mpfr_print_binary(zz); putchar('\n'); exit(1); } mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); } @@ -216,15 +217,15 @@ check2a (double x, int px, double y, int py, int pz, mp_rnd_t rnd_mode, if (mpfr_cmp(xx, zz)) { printf("x=%1.20e,%d y=%1.20e,%d pz=%d,rnd=%s\n", x,px,y,py,pz,mpfr_print_rnd_mode(rnd_mode)); - printf("got "); mpfr_print_raw(zz); putchar('\n'); - printf("instead of "); mpfr_print_raw(xx); putchar('\n'); + printf("got "); mpfr_print_binary(zz); putchar('\n'); + printf("instead of "); mpfr_print_binary(xx); putchar('\n'); exit(1); } mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); } void -check64 () +check64 (void) { mpfr_t x, t, u; @@ -258,7 +259,7 @@ check64 () if (MPFR_MANT(u)[0] << 2) { fprintf (stderr, "result not normalized for prec=2\n"); - mpfr_print_raw (u); putchar ('\n'); + mpfr_print_binary (u); putchar ('\n'); exit (1); } mpfr_set_str_raw (t, "-1.0e-1"); @@ -310,7 +311,7 @@ check64 () mpfr_sub(u, x, t, GMP_RNDU); mpfr_set_str_raw(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100"); if (mpfr_cmp(u,t)) { - printf("expect "); mpfr_print_raw(t); putchar('\n'); + printf("expect "); mpfr_print_binary(t); putchar('\n'); fprintf (stderr, "mpfr_add failed for precisions 53-76\n"); exit(1); } mpfr_set_prec(x, 53); mpfr_set_prec(t, 108); mpfr_set_prec(u, 108); @@ -319,7 +320,7 @@ check64 () mpfr_sub(u, x, t, GMP_RNDU); mpfr_set_str_raw(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111"); if (mpfr_cmp(u,t)) { - printf("expect "); mpfr_print_raw(t); putchar('\n'); + printf("expect "); mpfr_print_binary(t); putchar('\n'); fprintf(stderr, "mpfr_add failed for precisions 53-108\n"); exit(1); } mpfr_set_prec(x, 97); mpfr_set_prec(t, 97); mpfr_set_prec(u, 97); @@ -365,9 +366,9 @@ check64 () mpfr_add(u, x, t, GMP_RNDU); if ((MPFR_MANT(u)[0] & 1) != 1) { printf("error in mpfr_add with rnd_mode=GMP_RNDU\n"); - printf("b= "); mpfr_print_raw(x); putchar('\n'); - printf("c= "); mpfr_print_raw(t); putchar('\n'); - printf("b+c="); mpfr_print_raw(u); putchar('\n'); + printf("b= "); mpfr_print_binary(x); putchar('\n'); + printf("c= "); mpfr_print_binary(t); putchar('\n'); + printf("b+c="); mpfr_print_binary(u); putchar('\n'); exit(1); } @@ -456,10 +457,10 @@ check_case_1b (void) mpfr_init (b); mpfr_init (c); - for (prec_a = 1; prec_a <= 64; prec_a++) + for (prec_a = 2; prec_a <= 64; prec_a++) { mpfr_set_prec (a, prec_a); - for (prec_b = prec_a + 1; prec_b <= 64; prec_b++) + for (prec_b = prec_a + 2; prec_b <= 64; prec_b++) { dif = prec_b - prec_a; mpfr_set_prec (b, prec_b); @@ -481,9 +482,9 @@ check_case_1b (void) if (mpfr_cmp_ui (a, 1) != 0) { fprintf (stderr, "case (1b) failed for prec_a=%u, prec_b=%u, prec_c=%u\n", prec_a, prec_b, prec_c); - printf("b="); mpfr_print_raw(b); putchar('\n'); - printf("c="); mpfr_print_raw(c); putchar('\n'); - printf("a="); mpfr_print_raw(a); putchar('\n'); + printf("b="); mpfr_print_binary(b); putchar('\n'); + printf("c="); mpfr_print_binary(c); putchar('\n'); + printf("a="); mpfr_print_binary(a); putchar('\n'); exit (1); } } @@ -530,7 +531,7 @@ check_case_2 (void) /* checks when source and destination are equal */ void -check_same () +check_same (void) { mpfr_t x; @@ -548,7 +549,7 @@ check_same () #define MAX_PREC 100 void -check_inexact () +check_inexact (void) { mpfr_t x, y, z, u; mp_prec_t px, py, pu, pz; @@ -560,7 +561,7 @@ check_inexact () mpfr_init (z); mpfr_init (u); - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); mpfr_set_str_raw (x, "0.1E-4"); mpfr_set_prec (u, 33); mpfr_set_str_raw (u, "0.101110100101101100000000111100000E-1"); @@ -571,7 +572,7 @@ check_inexact () exit (1); } - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); mpfr_set_str_raw (x, "0.1E-4"); mpfr_set_prec (u, 33); mpfr_set_str_raw (u, "0.101110100101101100000000111100000E-1"); @@ -582,15 +583,15 @@ check_inexact () exit (1); } - for (px=1; px<MAX_PREC; px++) + for (px=2; px<MAX_PREC; px++) { mpfr_set_prec (x, px); mpfr_random (x); - for (pu=1; pu<MAX_PREC; pu++) + for (pu=2; pu<MAX_PREC; pu++) { mpfr_set_prec (u, pu); mpfr_random (u); - for (py=1; py<MAX_PREC; py++) + for (py=2; py<MAX_PREC; py++) { mpfr_set_prec (y, py); pz = (mpfr_cmp_abs (x, u) >= 0) ? MPFR_EXP(x)-MPFR_EXP(u) @@ -603,9 +604,9 @@ check_inexact () if (mpfr_add (z, x, u, rnd)) { fprintf (stderr, "z <- x + u should be exact\n"); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("u="); mpfr_print_raw (u); putchar ('\n'); - printf ("z="); mpfr_print_raw (z); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("u="); mpfr_print_binary (u); putchar ('\n'); + printf ("z="); mpfr_print_binary (z); putchar ('\n'); exit (1); } for (rnd=0; rnd<4; rnd++) @@ -619,10 +620,10 @@ check_inexact () fprintf (stderr, "Wrong inexact flag for rnd=%s\n", mpfr_print_rnd_mode(rnd)); printf ("expected %d, got %d\n", cmp, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("u="); mpfr_print_raw (u); putchar ('\n'); - printf ("y= "); mpfr_print_raw (y); putchar ('\n'); - printf ("x+u="); mpfr_print_raw (z); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("u="); mpfr_print_binary (u); putchar ('\n'); + printf ("y= "); mpfr_print_binary (y); putchar ('\n'); + printf ("x+u="); mpfr_print_binary (z); putchar ('\n'); exit (1); } } diff --git a/mpfr/tests/tagm.c b/mpfr/tests/tagm.c index 6e2b617be..8e5802bf0 100644 --- a/mpfr/tests/tagm.c +++ b/mpfr/tests/tagm.c @@ -35,7 +35,7 @@ void check_large _PROTO((void)); void slave _PROTO((int, int)); double -drand_agm() +drand_agm(void) { double d; long int *i; @@ -109,7 +109,8 @@ if (ck==0) printf("%1.20e\n", res1); mpfr_clear(ta); mpfr_clear(tb); mpfr_clear(tres); } -void check_large () +void +check_large (void) { mpfr_t a, b, agm; diff --git a/mpfr/tests/tasin.c b/mpfr/tests/tasin.c index 7faf0088a..018160ce5 100644 --- a/mpfr/tests/tasin.c +++ b/mpfr/tests/tasin.c @@ -37,7 +37,7 @@ main (void) mpfr_init (y); mpfr_init (z); - for (prec = 1; prec <= 100; prec++) + for (prec = 2; prec <= 100; prec++) { mpfr_set_prec (x, prec); mpfr_set_prec (z, prec); @@ -52,7 +52,7 @@ main (void) err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; if (mpfr_can_round (y, err, rnd, rnd, prec)) { - mpfr_round (y, rnd, prec); + mpfr_round_prec (y, rnd, prec); mpfr_asin (z, x, rnd); if (mpfr_cmp (y, z)) { diff --git a/mpfr/tests/tasinh.c b/mpfr/tests/tasinh.c index 1eee4e583..f41bbd8b9 100644 --- a/mpfr/tests/tasinh.c +++ b/mpfr/tests/tasinh.c @@ -42,7 +42,7 @@ main (int argc, char *argv[]) mpfr_set_str_raw (x, "0.111001101100000110011001010000101"); mpfr_asinh (y, x, GMP_RNDZ); - test_generic (1, 100, 25); + test_generic (2, 100, 25); mpfr_clear (x); mpfr_clear (y); diff --git a/mpfr/tests/tatan.c b/mpfr/tests/tatan.c index 08c3d2148..7fb8cc365 100644 --- a/mpfr/tests/tatan.c +++ b/mpfr/tests/tatan.c @@ -26,15 +26,48 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-test.h" -int mpfr_arctan_aux2 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +void worst_cases _PROTO((void)); +int mpfr_arctan_aux2 _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); + +void +worst_cases (void) +{ + mpfr_t x, y, z; + + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); + mpfr_init2 (z, 53); + + mpfr_set_str_raw (x, "1.0000100110000001100111100011001110101110100111011101"); + mpfr_set_str_raw (y, "1.1001101101110100101100110011011101101000011010111110e-1"); + mpfr_atan (z, x, GMP_RNDN); + if (mpfr_cmp (y, z)) + { + fprintf (stderr, "Error in mpfr_atan for prec=53, rnd=GMP_RNDN\n"); + fprintf (stderr, "x="); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\nexpected "); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\ngot "); + mpfr_out_str (stderr, 2, 0, z, GMP_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} int main (int argc, char *argv[]) { - unsigned int prec, err, yprec, n, p0 = 1, p1 = 100, N = 10; + unsigned int prec, err, yprec, n, p0 = 2, p1 = 100, N = 10; mp_rnd_t rnd; mpfr_t x, y, z, t; + worst_cases (); + mpfr_init (x); mpfr_init (y); mpfr_init (z); @@ -78,7 +111,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf (" approximation was "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } diff --git a/mpfr/tests/tatanh.c b/mpfr/tests/tatanh.c index c3c96e3d1..91469a11a 100644 --- a/mpfr/tests/tatanh.c +++ b/mpfr/tests/tatanh.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 25); + test_generic (2, 100, 25); return 0; } diff --git a/mpfr/tests/tcmp.c b/mpfr/tests/tcmp.c index 98b7b4412..df6f23bdd 100644 --- a/mpfr/tests/tcmp.c +++ b/mpfr/tests/tcmp.c @@ -36,6 +36,7 @@ main (void) double x, y; mpfr_t xx, yy; int i, c; + mp_prec_t p; mpfr_init (xx); mpfr_init (yy); @@ -54,18 +55,30 @@ main (void) mpfr_set_prec (yy, 65); mpfr_set_str_raw(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623"); mpfr_set_str_raw(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); - if (mpfr_cmp2(xx,yy)!=64) { printf("Error (1) in mpfr_cmp\n"); exit(1); } + p = 0; + if (mpfr_cmp2(xx, yy, &p) <= 0 || p != 64) + { + printf("Error (1) in mpfr_cmp2\n"); + exit(1); + } mpfr_set_str_raw(xx, "0.10100010001110110111000010001000010011111101000100011101000011100"); mpfr_set_str_raw(yy, "0.10100010001110110111000010001000010011111101000100011101000011011"); - if (mpfr_cmp2(xx,yy)!=64) { printf("Error (2) in mpfr_cmp\n"); exit(1); } + 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_raw (xx, "0.1E1"); mpfr_set_str_raw (yy, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100"); - if (mpfr_cmp2 (xx, yy) != 144) { - printf("Error (3) in mpfr_cmp\n"); - exit(1); - } + 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_d(xx, 1.0, 0); diff --git a/mpfr/tests/tcmp2.c b/mpfr/tests/tcmp2.c index b8e557d58..691afa933 100644 --- a/mpfr/tests/tcmp2.c +++ b/mpfr/tests/tcmp2.c @@ -54,10 +54,11 @@ set_bit (mpfr_t x, unsigned int n, int b) mpfr_cmp2 (x, y) returns 1 + |u| + |v| + k for low(x) >= low(y), and 1 + |u| + |v| + k + 1 otherwise */ void -worst_cases () +worst_cases (void) { mpfr_t x, y; - unsigned int i, j, k, l, b, expected; + unsigned int i, j, k, b, expected; + mp_prec_t l; mpfr_init2 (x, 200); mpfr_init2 (y, 200); @@ -68,24 +69,26 @@ worst_cases () mpfr_set_ui (x, 1, GMP_RNDN); mpfr_div_2exp (y, y, 1, GMP_RNDN); /* y = 1/2^i */ - if ((l = mpfr_cmp2 (x, y)) != 1) + l = 0; + if (mpfr_cmp2 (x, y, &l) <= 0 || l != 1) { fprintf (stderr, "Error in mpfr_cmp2:\nx="); mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); fprintf (stderr, "\ny="); mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); - fprintf (stderr, "\ngot %u instead of %u\n", l, 1); + fprintf (stderr, "\ngot %lu instead of %u\n", l, 1); exit(1); } mpfr_add (x, x, y, GMP_RNDN); /* x = 1 + 1/2^i */ - if ((l = mpfr_cmp2 (x, y)) != 0) + l = 0; + if (mpfr_cmp2 (x, y, &l) <= 0 || l != 0) { fprintf (stderr, "Error in mpfr_cmp2:\nx="); mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); fprintf (stderr, "\ny="); mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); - fprintf (stderr, "\ngot %u instead of %u\n", l, 0); + fprintf (stderr, "\ngot %lu instead of %u\n", l, 0); exit(1); } } @@ -110,7 +113,7 @@ worst_cases () set_bit (x, i + j + k + 2, 1); set_bit (y, i + j + k + 2, 0); - l = mpfr_cmp2 (x, y); + l = 0; mpfr_cmp2 (x, y, &l); expected = i + j + k + 1; if (l != expected) { @@ -118,14 +121,14 @@ worst_cases () mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); fprintf (stderr, "\ny="); mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); - fprintf (stderr, "\ngot %u instead of %u\n", l, expected); + fprintf (stderr, "\ngot %lu instead of %u\n", 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 = mpfr_cmp2 (x, y); + l = 0; mpfr_cmp2 (x, y, &l); expected = i + j + k + 2; if (l != expected) { @@ -133,7 +136,7 @@ worst_cases () mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); fprintf (stderr, "\ny="); mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); - fprintf (stderr, "\ngot %u instead of %u\n", l, expected); + fprintf (stderr, "\ngot %lu instead of %u\n", l, expected); exit(1); } } @@ -148,7 +151,7 @@ void tcmp2 (double x, double y, int i) { mpfr_t xx, yy; - int j; + mp_prec_t j; if (i==-1) { if (x==y) i=53; @@ -157,22 +160,35 @@ tcmp2 (double x, double y, int i) mpfr_init2(xx, 53); mpfr_init2(yy, 53); mpfr_set_d (xx, x, GMP_RNDN); mpfr_set_d (yy, y, GMP_RNDN); - j = mpfr_cmp2 (xx, yy); - if (j != i) { + j = 0; + if (mpfr_cmp2 (xx, yy, &j) == 0) + { + if (x != y) + { + fprintf (stderr, "Error in mpfr_cmp2 for\nx="); + mpfr_out_str (stderr, 2, 0, xx, GMP_RNDN); + fprintf (stderr, "\ny="); + mpfr_out_str (stderr, 2, 0, yy, GMP_RNDN); + fprintf (stderr, "\ngot sign 0 for x != y\n"); + exit(1); + } + } + else if (j != i) { fprintf (stderr, "Error in mpfr_cmp2 for\nx="); mpfr_out_str (stderr, 2, 0, xx, GMP_RNDN); fprintf (stderr, "\ny="); mpfr_out_str (stderr, 2, 0, yy, GMP_RNDN); - fprintf (stderr, "\ngot %u instead of %u\n", j, i); + fprintf (stderr, "\ngot %lu instead of %u\n", j, i); exit(1); } mpfr_clear(xx); mpfr_clear(yy); } -void special () +void +special (void) { mpfr_t x, y; - int j; + mp_prec_t j; mpfr_init (x); mpfr_init (y); @@ -181,37 +197,40 @@ void special () mpfr_set_prec (y, 65); mpfr_set_str_raw (x, "0.10000000000000000000000000000000000001110010010110100110011110000E1"); mpfr_set_str_raw (y, "0.11100100101101001100111011111111110001101001000011101001001010010E-35"); - if ((j = mpfr_cmp2 (x, y)) != 1) { + j = 0; + if (mpfr_cmp2 (x, y, &j) <= 0 || j != 1) { printf ("Error in mpfr_cmp2:\n"); printf ("x="); - mpfr_print_raw (x); + mpfr_print_binary (x); putchar ('\n'); printf ("y="); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); - printf ("got %d, expected 1\n", j); + printf ("got %lu, expected 1\n", j); exit (1); } mpfr_set_prec(x, 127); mpfr_set_prec(y, 127); mpfr_set_str_raw(x, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6"); mpfr_set_str_raw(y, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6"); - if ((j=mpfr_cmp2(x, y)) != 32) { + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 32) { printf("Error in mpfr_cmp2:\n"); - printf("x="); mpfr_print_raw(x); putchar('\n'); - printf("y="); mpfr_print_raw(y); putchar('\n'); - printf("got %d, expected 32\n", j); + printf("x="); mpfr_print_binary(x); putchar('\n'); + printf("y="); mpfr_print_binary(y); putchar('\n'); + printf("got %lu, expected 32\n", j); exit(1); } mpfr_set_prec (x, 128); mpfr_set_prec (y, 239); mpfr_set_str_raw (x, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100100000000000E167"); mpfr_set_str_raw (y, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100011111111111111111111111111111111111111111111111011111100101011100011001101000100111000010000000000101100110000111111000101E167"); - if ((j=mpfr_cmp2(x, y)) != 164) { + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 164) { printf("Error in mpfr_cmp2:\n"); - printf("x="); mpfr_print_raw(x); putchar('\n'); - printf("y="); mpfr_print_raw(y); putchar('\n'); - printf("got %d, expected 164\n", j); + printf("x="); mpfr_print_binary(x); putchar('\n'); + printf("y="); mpfr_print_binary(y); putchar('\n'); + printf("got %lu, expected 164\n", j); exit(1); } @@ -219,11 +238,12 @@ void special () mpfr_set_prec (x, 130); mpfr_set_prec (y, 130); mpfr_set_str_raw (x, "0.1100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2"); mpfr_set_str_raw (y, "0.1011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100E2"); - if ((j=mpfr_cmp2(x, y)) != 127) { + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 127) { printf("Error in mpfr_cmp2:\n"); - printf("x="); mpfr_print_raw(x); putchar('\n'); - printf("y="); mpfr_print_raw(y); putchar('\n'); - printf("got %d, expected 127\n", j); + printf("x="); mpfr_print_binary(x); putchar('\n'); + printf("y="); mpfr_print_binary(y); putchar('\n'); + printf("got %lu, expected 127\n", j); exit(1); } @@ -231,11 +251,12 @@ void special () mpfr_set_prec (x, 65); mpfr_set_prec (y, 65); mpfr_set_ui (x, 5, GMP_RNDN); mpfr_set_str_raw (y, "0.10011111111111111111111111111111111111111111111111111111111111101E3"); - if ((j=mpfr_cmp2(x, y)) != 63) { + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 63) { printf("Error in mpfr_cmp2:\n"); - printf("x="); mpfr_print_raw(x); putchar('\n'); - printf("y="); mpfr_print_raw(y); putchar('\n'); - printf("got %d, expected 63\n", j); + printf("x="); mpfr_print_binary(x); putchar('\n'); + printf("y="); mpfr_print_binary(y); putchar('\n'); + printf("got %lu, expected 63\n", j); exit(1); } @@ -243,11 +264,12 @@ void special () mpfr_set_prec (x, 65); mpfr_set_prec (y, 65); mpfr_set_str_raw (x, "0.10011011111000101001110000000000000000000000000000000000000000000E-69"); mpfr_set_str_raw (y, "0.10011011111000101001101111111111111111111111111111111111111111101E-69"); - if ((j=mpfr_cmp2(x, y)) != 63) { + j = 0; + if (mpfr_cmp2(x, y, &j) <= 0 || j != 63) { printf("Error in mpfr_cmp2:\n"); - printf("x="); mpfr_print_raw(x); putchar('\n'); - printf("y="); mpfr_print_raw(y); putchar('\n'); - printf("got %d, expected 63\n", j); + printf("x="); mpfr_print_binary(x); putchar('\n'); + printf("y="); mpfr_print_binary(y); putchar('\n'); + printf("got %lu, expected 63\n", j); exit(1); } diff --git a/mpfr/tests/teuler.c b/mpfr/tests/tconst_euler.c index c1a82e00d..ab9f74321 100644 --- a/mpfr/tests/teuler.c +++ b/mpfr/tests/tconst_euler.c @@ -29,7 +29,7 @@ int main (int argc, char *argv[]) { mpfr_t gamma, y, z, t; - unsigned int err, prec, yprec, p0 = 1, p1 = 200; + unsigned int err, prec, yprec, p0 = 2, p1 = 200; mp_rnd_t rnd; prec = (argc < 2) ? 53 : atoi(argv[1]); @@ -74,7 +74,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf (" approximation was "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } diff --git a/mpfr/tests/tconst_log2.c b/mpfr/tests/tconst_log2.c new file mode 100644 index 000000000..b3b120d61 --- /dev/null +++ b/mpfr/tests/tconst_log2.c @@ -0,0 +1,116 @@ +/* Test file for mpfr_const_log2. + +Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" + +/* tlog2 [prec] [rnd] [0 = no print] */ + +extern mp_prec_t __mpfr_const_log2_prec; +void check _PROTO ((mp_prec_t, mp_prec_t)); + +void +check (mp_prec_t p0, mp_prec_t p1) +{ + mpfr_t x, y, z; + mp_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init2 (z, p1 + 10); + mpfr_const_log2 (z, GMP_RNDN); + __mpfr_const_log2_prec = 1; + + for (; p0<=p1; p0++) + { + mpfr_set_prec (x, p0); + mpfr_set_prec (y, p0); + for (rnd = 0; rnd < 4; rnd++) + { + mpfr_const_log2 (x, rnd); + mpfr_set (y, z, rnd); + if (mpfr_cmp (x, y) && mpfr_can_round (z, mpfr_get_prec(z), GMP_RNDN, + rnd, p0)) + { + fprintf (stderr, "mpfr_const_log2 fails for prec=%u, rnd=%s\n", + (unsigned int) p0, mpfr_print_rnd_mode (rnd)); + fprintf (stderr, "expected "); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\ngot "); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + int p; + unsigned char rnd; + + p = (argc>1) ? atoi(argv[1]) : 53; + rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ; + + mpfr_init (x); + + check (2, 1000); + + /* check precision of 2 bits */ + mpfr_set_prec (x, 2); + mpfr_const_log2 (x, GMP_RNDN); + if (mpfr_get_d (x) != 0.75) + { + fprintf (stderr, "mpfr_const_log2 failed for prec=2, rnd=GMP_RNDN\n"); + fprintf (stderr, "expected 0.75, got %f\n", mpfr_get_d (x)); + 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); + putchar('\n'); + } + + mpfr_set_prec (x, 53); + mpfr_const_log2 (x, rnd); + if (mpfr_get_d(x) != 6.9314718055994530941e-1) + { + fprintf (stderr, "mpfr_const_log2 failed for prec=53\n"); + exit (1); + } + + mpfr_clear(x); + + return 0; +} diff --git a/mpfr/tests/tpi.c b/mpfr/tests/tconst_pi.c index 60604d3e8..60604d3e8 100644 --- a/mpfr/tests/tpi.c +++ b/mpfr/tests/tconst_pi.c diff --git a/mpfr/tests/tcos.c b/mpfr/tests/tcos.c index 440c0bbdc..f50767500 100644 --- a/mpfr/tests/tcos.c +++ b/mpfr/tests/tcos.c @@ -60,6 +60,11 @@ main (int argc, char *argv[]) mpfr_init (x); mpfr_init (y); + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 2); + mpfr_set_d (x, 9.81333845856942e-1, GMP_RNDN); + mpfr_cos (y, x, GMP_RNDN); + mpfr_set_prec (x, 30); mpfr_set_prec (y, 30); mpfr_set_str_raw (x, "1.00001010001101110010100010101e-1"); @@ -68,8 +73,8 @@ main (int argc, char *argv[]) if (mpfr_cmp (y, x)) { fprintf (stderr, "Error for prec=30, rnd=GMP_RNDU\n"); - printf ("expected "); mpfr_print_raw (x); putchar ('\n'); - printf (" got "); mpfr_print_raw (y); putchar ('\n'); + printf ("expected "); mpfr_print_binary (x); putchar ('\n'); + printf (" got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -81,8 +86,8 @@ main (int argc, char *argv[]) if (mpfr_cmp (y, x)) { fprintf (stderr, "Error for prec=59, rnd=GMP_RNDU\n"); - printf ("expected "); mpfr_print_raw (x); putchar ('\n'); - printf (" got "); mpfr_print_raw (y); putchar ('\n'); + printf ("expected "); mpfr_print_binary (x); putchar ('\n'); + printf (" got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -94,7 +99,7 @@ main (int argc, char *argv[]) if (mpfr_cmp (y, x)) { fprintf (stderr, "Error for x=1.1100e-2, rnd=GMP_RNDD\n"); - printf ("expected 1.1100e-1, got "); mpfr_print_raw (y); putchar ('\n'); + printf ("expected 1.1100e-1, got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -114,7 +119,7 @@ main (int argc, char *argv[]) check53 (1.00591265847407274059, 0.53531755997839769456, GMP_RNDN); - test_generic (1, 100, 100); + test_generic (2, 100, 100); mpfr_clear (x); mpfr_clear (y); diff --git a/mpfr/tests/tcosh.c b/mpfr/tests/tcosh.c index be1789fb7..44421b380 100644 --- a/mpfr/tests/tcosh.c +++ b/mpfr/tests/tcosh.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/tdiv.c b/mpfr/tests/tdiv.c index fca86efb0..70bb7ca47 100644 --- a/mpfr/tests/tdiv.c +++ b/mpfr/tests/tdiv.c @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <math.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -27,6 +26,8 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-test.h" +#define NaN (0./0.) + #define check53(n, d, rnd, res) check4(n, d, rnd, 53, res) void check4 _PROTO((double, double, mp_rnd_t, int, double)); @@ -82,7 +83,7 @@ check24 (float N, float D, mp_rnd_t rnd_mode, float Q) /* the following examples come from the paper "Number-theoretic Test Generation for Directed Rounding" from Michael Parks, Table 2 */ void -check_float() +check_float(void) { float b=8388608.0; /* 2^23 */ @@ -128,7 +129,7 @@ check_float() } void -check_convergence () +check_convergence (void) { mpfr_t x, y; int i, j; @@ -146,8 +147,8 @@ check_convergence () mpfr_set_str_raw(y, "0.10010010011011010100101001010111100000101110010010101E-529"); if (mpfr_cmp(x, y)) { fprintf(stderr, "Error in mpfr_div for prec=64, rnd=GMP_RNDN\n"); - printf("got "); mpfr_print_raw(x); putchar('\n'); - printf("instead of "); mpfr_print_raw(y); putchar('\n'); + printf("got "); mpfr_print_binary(x); putchar('\n'); + printf("instead of "); mpfr_print_binary(y); putchar('\n'); exit(1); } @@ -161,7 +162,7 @@ check_convergence () if (mpfr_cmp_ui(y, 1)) { fprintf(stderr, "mpfr_div failed for x=1.0, y=1.0, prec=%u rnd=%s\n", i, mpfr_print_rnd_mode(j)); - printf("got "); mpfr_print_raw(y); putchar('\n'); + printf("got "); mpfr_print_binary(y); putchar('\n'); exit(1); } } @@ -171,7 +172,7 @@ check_convergence () } void -check_lowr () +check_lowr (void) { mpfr_t x, y, z, z2, z3, tmp; int k, c; @@ -195,8 +196,8 @@ check_lowr () { fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDN\n"); printf("Dividing "); - printf("got "); mpfr_print_raw(z2); putchar('\n'); - printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("got "); mpfr_print_binary(z2); putchar('\n'); + printf("instead of "); mpfr_print_binary(z); putchar('\n'); printf("inex flag = %d\n", c); exit(1); } @@ -214,33 +215,33 @@ check_lowr () { fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDN\n"); printf("Dividing "); - printf("got "); mpfr_print_raw(z2); putchar('\n'); - printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("got "); mpfr_print_binary(z2); putchar('\n'); + printf("instead of "); mpfr_print_binary(z); putchar('\n'); printf("inex flag = %d\n", c); exit(1); } else if (c == 2) { - mpfr_add_one_ulp(z); + mpfr_add_one_ulp(z, GMP_RNDN); if (mpfr_cmp(z2, z)) { fprintf(stderr, "Error in mpfr_div [even rnd?] rnd=GMP_RNDN\n"); printf("Dividing "); - printf("got "); mpfr_print_raw(z2); putchar('\n'); - printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("got "); mpfr_print_binary(z2); putchar('\n'); + printf("instead of "); mpfr_print_binary(z); putchar('\n'); printf("inex flag = %d\n", 1); exit(1); } } else if (c == -2) { - mpfr_sub_one_ulp(z); + mpfr_sub_one_ulp(z, GMP_RNDN); if (mpfr_cmp(z2, z)) { fprintf(stderr, "Error in mpfr_div [even rnd?] rnd=GMP_RNDN\n"); printf("Dividing "); - printf("got "); mpfr_print_raw(z2); putchar('\n'); - printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("got "); mpfr_print_binary(z2); putchar('\n'); + printf("instead of "); mpfr_print_binary(z); putchar('\n'); printf("inex flag = %d\n", 1); exit(1); } @@ -261,7 +262,7 @@ check_lowr () mpfr_random(tmp); mpfr_mul(x, z, tmp, GMP_RNDN); mpfr_set(y, tmp, GMP_RNDD); - mpfr_add_one_ulp(x); + mpfr_add_one_ulp(x, GMP_RNDN); c = mpfr_div(z2, x, y, GMP_RNDD); mpfr_div(z3, x, y, GMP_RNDD); @@ -270,8 +271,8 @@ check_lowr () if (c != -1 || mpfr_cmp(z2, z)) { fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDD\n"); - printf("got "); mpfr_print_raw(z2); putchar('\n'); - printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("got "); mpfr_print_binary(z2); putchar('\n'); + printf("instead of "); mpfr_print_binary(z); putchar('\n'); printf("inex flag = %d\n", c); exit(1); } @@ -283,8 +284,8 @@ check_lowr () if (c != 1 || mpfr_cmp(z2, z)) { fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDU\n"); - printf("got "); mpfr_print_raw(z2); putchar('\n'); - printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("got "); mpfr_print_binary(z2); putchar('\n'); + printf("instead of "); mpfr_print_binary(z); putchar('\n'); printf("inex flag = %d\n", c); exit(1); } @@ -301,7 +302,7 @@ check_lowr () #define MAX_PREC 100 void -check_inexact () +check_inexact (void) { mpfr_t x, y, z, u; mp_prec_t px, py, pu; @@ -315,7 +316,7 @@ check_inexact () mpfr_set_prec (x, 33); mpfr_set_str_raw (x, "0.101111100011011101010011101100001E0"); - mpfr_set_prec (u, 1); + mpfr_set_prec (u, 2); mpfr_set_str_raw (u, "0.1E0"); mpfr_set_prec (y, 28); if ((inexact = mpfr_div (y, x, u, GMP_RNDN) >= 0)) @@ -334,19 +335,19 @@ check_inexact () { fprintf (stderr, "Wrong inexact flag (1): expected 1, got %d\n", inexact); - mpfr_print_raw(y); putchar('\n'); + mpfr_print_binary(y); putchar('\n'); exit (1); } - for (px=1; px<MAX_PREC; px++) + for (px=2; px<MAX_PREC; px++) { mpfr_set_prec (x, px); mpfr_random (x); - for (pu=1; pu<=MAX_PREC; pu++) + for (pu=2; pu<=MAX_PREC; pu++) { mpfr_set_prec (u, pu); do { mpfr_random (u); } while (mpfr_cmp_ui (u, 0) == 0); - for (py=1; py<=MAX_PREC; py++) + for (py=2; py<=MAX_PREC; py++) { mpfr_set_prec (y, py); mpfr_set_prec (z, py + pu); @@ -366,10 +367,10 @@ check_inexact () fprintf (stderr, "Wrong inexact flag for rnd=%s\n", mpfr_print_rnd_mode(rnd)); printf ("expected %d, got %d\n", cmp, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("u="); mpfr_print_raw (u); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("y*u="); mpfr_print_raw (z); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("u="); mpfr_print_binary (u); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("y*u="); mpfr_print_binary (z); putchar ('\n'); exit (1); } } @@ -425,12 +426,12 @@ main (int argc, char *argv[]) 65, 0.0); check53(9.89438396044940256501e-134, 5.93472984109987421717e-67, GMP_RNDU, 1.6672003992376663654e-67); - check53(1.0, sqrt(-1.0), GMP_RNDD, sqrt(-1.0)); - check53(sqrt(-1.0), 1.0, GMP_RNDD, sqrt(-1.0)); + check53(1.0, NaN, GMP_RNDD, NaN); + check53(NaN, 1.0, GMP_RNDD, NaN); check53(2.0/0.0, 1.0, GMP_RNDD, 1.0/0.0); check53(1.0, 2.0/0.0, GMP_RNDD, 0.0); - check53(0.0, 0.0, GMP_RNDD, sqrt(-1.0)); - check53(1.0/0.0, 1.0/0.0, GMP_RNDD, sqrt(-1.0)); + check53(0.0, 0.0, GMP_RNDD, NaN); + check53(1.0/0.0, 1.0/0.0, GMP_RNDD, NaN); check53(9.89438396044940256501e-134, -5.93472984109987421717e-67, GMP_RNDU, -1.6672003992376663654e-67); check53(-4.53063926135729747564e-308, 7.02293374921793516813e-84, GMP_RNDD, @@ -445,7 +446,7 @@ main (int argc, char *argv[]) #ifdef TEST srand48(getpid()); for (i=0;i<N;i++) { - do { n = drand(); d = drand(); e = fabs(n)/fabs(d); } + do { n = drand(); d = drand(); e = ABS(n)/ABS(d); } /* smallest normalized is 2^(-1022), largest is 2^(1023)*(2-2^(-52)) */ while (e>=MAXNORM || e<MINNORM); check4(n, d, rand() % 4, 53, 0.0); diff --git a/mpfr/tests/tdiv_ui.c b/mpfr/tests/tdiv_ui.c index c89a57742..77de7e123 100644 --- a/mpfr/tests/tdiv_ui.c +++ b/mpfr/tests/tdiv_ui.c @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <math.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -84,10 +83,16 @@ special (void) mpfr_set_prec (x, 110); mpfr_set_prec (y, 60); mpfr_set_str_raw (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44"); - mpfr_div_ui(y, x, 17, __gmp_default_rounding_mode); - if (mpfr_get_d (y) != 2.8114572543455207632e-15) + mpfr_div_ui (y, x, 17, GMP_RNDN); + mpfr_set_str_raw (x, "0.11001010100101100011101110000001100001010110101001010011011E-48"); + if (mpfr_cmp (x, y)) { - fprintf (stderr, "Error in x / 17 for x=1/16!\n"); + fprintf (stderr, "Error in x/17 for x=1/16!\n"); + fprintf (stderr, "Expected "); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\nGot "); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\n"); exit (1); } @@ -102,8 +107,8 @@ special (void) if (mpfr_get_d (x) != mpfr_get_d (y)) { fprintf (stderr, "division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec); - printf ("expected "); mpfr_print_raw (x); putchar ('\n'); - printf ("got "); mpfr_print_raw (y); putchar ('\n'); + printf ("expected "); mpfr_print_binary (x); putchar ('\n'); + printf ("got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } } @@ -114,7 +119,7 @@ special (void) } void -check_inexact () +check_inexact (void) { mpfr_t x, y, z; mp_prec_t px, py; @@ -126,12 +131,12 @@ check_inexact () mpfr_init (y); mpfr_init (z); - for (px=1; px<300; px++) + for (px=2; px<300; px++) { mpfr_set_prec (x, px); mpfr_random (x); do { u = lrand48 (); } while (u == 0); - for (py=1; py<300; py++) + for (py=2; py<300; py++) { mpfr_set_prec (y, py); mpfr_set_prec (z, py + mp_bits_per_limb); @@ -141,8 +146,8 @@ check_inexact () if (mpfr_mul_ui (z, y, u, rnd)) { fprintf (stderr, "z <- y * u should be exact for u=%lu\n", u); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("z="); mpfr_print_raw (z); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("z="); mpfr_print_binary (z); putchar ('\n'); exit (1); } cmp = mpfr_cmp (z, x); @@ -152,8 +157,8 @@ check_inexact () { fprintf (stderr, "Wrong inexact flag for u=%lu, rnd=%s\n", u, mpfr_print_rnd_mode(rnd)); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); exit (1); } } @@ -175,7 +180,7 @@ main (int argc, char **argv) srand(getpid()); for (i=0;i<1000000;i++) { do { u = lrand48(); } while (u==0); - do { d = drand(); } while (fabs(d/u)<2.2e-307); + do { d = drand(); } while (ABS(d/u)<2.2e-307); check(d, u, rand() % 4, 0.0); } #endif diff --git a/mpfr/tests/tdump.c b/mpfr/tests/tdump.c index 8c3a51f09..8da7069f9 100644 --- a/mpfr/tests/tdump.c +++ b/mpfr/tests/tdump.c @@ -30,11 +30,11 @@ main (void) { mpfr_t z; - mpfr_init2(z, 100); - mpfr_set_ui(z, 0, GMP_RNDN); - mpfr_dump(z, GMP_RNDD); - printf(" ^--- 0.e1 printed above is ok\n"); - mpfr_clear(z); + mpfr_init2 (z, 2); + mpfr_set_ui (z, 0, GMP_RNDN); + mpfr_dump (z, GMP_RNDD); + printf (" ^--- 0.00e0 printed above is ok\n"); + mpfr_clear (z); return 0; } diff --git a/mpfr/tests/teq.c b/mpfr/tests/teq.c index 91fe9bbcb..fbb9a82b9 100644 --- a/mpfr/tests/teq.c +++ b/mpfr/tests/teq.c @@ -26,6 +26,7 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-impl.h" +void teq _PROTO ((mpfr_t)); void teq (mpfr_t x) @@ -47,8 +48,8 @@ teq (mpfr_t x) !mpfr_eq(y, x, k - 1)) { fprintf(stderr, "Error in eq.\n"); - printf("x = "); mpfr_print_raw(x); printf("\n"); - printf("y = "); mpfr_print_raw(y); printf("\n"); + printf("x = "); mpfr_print_binary(x); printf("\n"); + printf("y = "); mpfr_print_binary(y); printf("\n"); printf("k = %ld\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)); mpfr_clear(x); mpfr_clear(y); diff --git a/mpfr/tests/texceptions.c b/mpfr/tests/texceptions.c index 1c84fe37f..ed981ba7a 100644 --- a/mpfr/tests/texceptions.c +++ b/mpfr/tests/texceptions.c @@ -92,7 +92,7 @@ main (int argc, char *argv[]) { fprintf (stderr, "Error: x+x rounded to nearest for x=2^1023 should give +Inf\n"); printf ("emax = %ld\n", mpfr_get_emax ()); - printf ("got "); mpfr_print_raw (x); putchar ('\n'); + printf ("got "); mpfr_print_binary (x); putchar ('\n'); exit (1); } @@ -112,7 +112,7 @@ main (int argc, char *argv[]) if (mpfr_cmp_ui (y, 0)) { fprintf (stderr, "Error: y-x rounded to zero should give 0 for y=3/2*2^(-1022), x=2^(-1022)\n"); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); exit (1); } diff --git a/mpfr/tests/texp.c b/mpfr/tests/texp.c index 6cff7fee8..21e19fb0c 100644 --- a/mpfr/tests/texp.c +++ b/mpfr/tests/texp.c @@ -102,7 +102,7 @@ check_large (double d, int n, mp_rnd_t rnd) else printf("exp(%1.20e)=",d); mpfr_out_str(stdout, 10, 0, y, rnd); putchar('\n'); - printf(" ="); mpfr_print_raw(y); putchar('\n'); + printf(" ="); mpfr_print_binary(y); putchar('\n'); if (n==53) printf(" =%1.20e\n", mpfr_get_d(y)); mpfr_clear(x); mpfr_clear(y); @@ -124,7 +124,7 @@ check_worst_case (double X, double expx) mpfr_exp(x, x, GMP_RNDN); mpfr_set_d(x, X, GMP_RNDN); mpfr_exp(x, x, GMP_RNDU); - mpfr_add_one_ulp(y); + mpfr_add_one_ulp(y, GMP_RNDN); if (mpfr_cmp(x,y)) { fprintf(stderr, "exp(x) rounded towards +infinity is wrong\n"); exit(1); } @@ -134,7 +134,7 @@ check_worst_case (double X, double expx) /* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */ int -check_worst_cases () +check_worst_cases (void) { mpfr_t x; mpfr_t y; @@ -178,23 +178,36 @@ compare_exp2_exp3 (int n) { mpfr_t x, y, z; int prec; mp_rnd_t rnd; - mpfr_init(x); mpfr_init(y); mpfr_init(z); - for (prec=20;prec<=n;prec++) { - mpfr_set_prec(x, prec); mpfr_set_prec(y, prec); mpfr_set_prec(z, prec); - mpfr_random(x); - rnd = rand() % 4; - mpfr_exp_2 (y, x, rnd); - mpfr_exp3 (z, x, rnd); - if (mpfr_cmp(y,z)) { - printf("mpfr_exp_2 and mpfr_exp3 disagree for rnd=%s and\nx=", - mpfr_print_rnd_mode(rnd)); - mpfr_print_raw(x); putchar('\n'); - printf("mpfr_exp_2 gives "); mpfr_print_raw(y); putchar('\n'); - printf("mpfr_exp3 gives "); mpfr_print_raw(z); putchar('\n'); - exit(1); - } + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + for (prec=20; prec<=n; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_prec (z, prec); + mpfr_random (x); + rnd = rand() % 4; + mpfr_exp_2 (y, x, rnd); + mpfr_exp3 (z, x, rnd); + if (mpfr_cmp (y,z)) + { + printf ("mpfr_exp_2 and mpfr_exp3 disagree for rnd=%s and\nx=", + mpfr_print_rnd_mode (rnd)); + mpfr_print_binary (x); + putchar ('\n'); + printf ("mpfr_exp_2 gives "); + mpfr_print_binary (y); + putchar ('\n'); + printf ("mpfr_exp3 gives "); + mpfr_print_binary (z); + putchar ('\n'); + exit (1); + } } - mpfr_clear(x); mpfr_clear(y); mpfr_clear(z); + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); } #define TEST_FUNCTION mpfr_exp @@ -207,7 +220,7 @@ main (int argc, char *argv[]) int i, N, s=0, e, maxe=0; double d, lo, hi; #endif - test_generic (1, 100, 100); + test_generic (2, 100, 100); if (argc == 4) { diff --git a/mpfr/tests/texp2.c b/mpfr/tests/texp2.c index 27efc99b7..7b9487c45 100644 --- a/mpfr/tests/texp2.c +++ b/mpfr/tests/texp2.c @@ -39,7 +39,7 @@ main (int argc, char *argv[]) mpfr_init (x); mpfr_init (y); - + MPFR_CLEAR_NAN(x); MPFR_SET_INF(x); mpfr_exp2 (y, x, GMP_RNDN); if(!MPFR_IS_INF(y)) @@ -64,7 +64,7 @@ main (int argc, char *argv[]) exit (1); } - test_generic (1, 100, 100); + test_generic (2, 100, 100); mpfr_clear (x); mpfr_clear (y); diff --git a/mpfr/tests/texpm1.c b/mpfr/tests/texpm1.c index ce1a90494..f05f7d22a 100644 --- a/mpfr/tests/texpm1.c +++ b/mpfr/tests/texpm1.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/tfactorial.c b/mpfr/tests/tfactorial.c index 9656f4643..4b81bb22a 100644 --- a/mpfr/tests/tfactorial.c +++ b/mpfr/tests/tfactorial.c @@ -50,7 +50,7 @@ main (int argc, char *argv[]) exit (1); } - for (prec = 1; prec <= 100; prec++) + for (prec = 2; prec <= 100; prec++) { mpfr_set_prec (x, prec); mpfr_set_prec (z, prec); @@ -84,7 +84,7 @@ main (int argc, char *argv[]) { fprintf (stderr, "Wrong inexact flag: expected inexact\n"); printf ("n=%u prec=%u\n", n, prec); - mpfr_print_raw(z); putchar('\n'); + mpfr_print_binary(z); putchar('\n'); exit (1); } } @@ -101,7 +101,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf (" approximation was "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } diff --git a/mpfr/tests/tfma.c b/mpfr/tests/tfma.c index 4db3a26bb..d661e78a1 100644 --- a/mpfr/tests/tfma.c +++ b/mpfr/tests/tfma.c @@ -39,6 +39,15 @@ main (int argc, char *argv[]) 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_d (x, -0.75, GMP_RNDN); + mpfr_set_d (y, 0.5, GMP_RNDN); + mpfr_set_d (z, 0.375, GMP_RNDN); + mpfr_fma (s, x, y, z, GMP_RNDU); /* result is 0 */ MPFR_SET_NAN(x); mpfr_random(y); @@ -46,7 +55,7 @@ main (int argc, char *argv[]) mpfr_fma (s,x, y,z, GMP_RNDN); if(!MPFR_IS_NAN(s)) { - printf ("evaluation of function in x=NAN does not return NAN"); + fprintf (stderr, "evaluation of function in x=NAN does not return NAN"); exit (1); } @@ -220,7 +229,7 @@ main (int argc, char *argv[]) int inexact, compare; unsigned int n; - int p0=1; + int p0=2; int p1=200; int N=200; @@ -238,7 +247,6 @@ main (int argc, char *argv[]) for (n=0; n<N; n++) { - mpfr_random (x); mpfr_random (y); mpfr_random (z); @@ -276,7 +284,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf ("approx "); - mpfr_print_raw (slong); + mpfr_print_binary (slong); putchar ('\n'); exit (1); } diff --git a/mpfr/tests/tgeneric.c b/mpfr/tests/tgeneric.c index d03e3ed9e..8ce1153cb 100644 --- a/mpfr/tests/tgeneric.c +++ b/mpfr/tests/tgeneric.c @@ -70,7 +70,7 @@ test_generic (int p0, int p1, int N) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf ("approx "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -87,9 +87,9 @@ test_generic (int p0, int p1, int N) { fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", mpfr_print_rnd_mode (rnd), compare, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("t="); mpfr_print_raw (t); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("t="); mpfr_print_binary (t); putchar ('\n'); exit (1); } } diff --git a/mpfr/tests/tget_d.c b/mpfr/tests/tget_d.c index 6a6bca608..56de029e2 100644 --- a/mpfr/tests/tget_d.c +++ b/mpfr/tests/tget_d.c @@ -1,6 +1,6 @@ /* Test file for mpfr_get_d -Copyright (C) 1999-2001 Free Software Foundation. +Copyright (C) 1999-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -22,34 +22,88 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <stdlib.h> #include "gmp.h" +#include "gmp-impl.h" #include "mpfr.h" +#include "mpfr-impl.h" + +#define TEST +#include "rnd_mode.c" int main (void) { - mpfr_t x; + mpfr_t half, x, y; + mp_rnd_t rnd_mode; - mpfr_init2 (x, 2); + mpfr_init2(half, 2); + mpfr_set_ui(half, 1, GMP_RNDZ); + mpfr_div_2ui(half, half, 1, GMP_RNDZ); /* has exponent 0 */ - /* checks that rounds to nearest sets the last - bit to zero in case of equal distance */ - mpfr_set_d (x, 5.0, GMP_RNDN); - if (mpfr_get_d (x) != 4.0) - { - fprintf (stderr, "Error in tget_d: got %1.1f instead of 4.0\n", - mpfr_get_d (x)); - exit (1); - } + mpfr_init2(x, 128); + mpfr_init2(y, 128); - mpfr_set_d (x, 9.84891017624509146344e-01, GMP_RNDU); - if (mpfr_get_d (x) != 1.0) + for (rnd_mode = 0; rnd_mode <= 3; rnd_mode++) { - fprintf (stderr, "Error in tround: got %f instead of 1.0\n", - mpfr_get_d (x)); - exit (1); + int i, j, si, sj; + double di, dj; + + mpfr_set_machine_rnd_mode(rnd_mode); + for (i = 1, di = 0.25; i < 127; i++, di *= 0.5) + for (si = 0; si <= 1; si++) + { + mpfr_div_2ui(x, half, i, GMP_RNDZ); + (si ? mpfr_sub : mpfr_add)(x, half, x, GMP_RNDZ); + for (j = i+1, dj = di * 0.5; j < 128 && j < i+53; j++, dj *= 0.5) + for (sj = 0; sj <= 1; sj++) + { + double c, d, dd; + int exp; + char *f; + + mpfr_div_2ui(y, half, j, GMP_RNDZ); + (sj ? mpfr_sub : mpfr_add)(y, x, y, GMP_RNDZ); + exp = (rand() % 47) - 23; + mpfr_mul_2si(y, y, exp, GMP_RNDZ); + if (mpfr_inexflag_p()) + { + fprintf(stderr, "Error in tget_d: inexact flag for " + "(i,si,j,sj,rnd,exp) = (%d,%d,%d,%d,%d,%d)\n", + i, si, j, sj, rnd_mode, exp); + exit(1); + } + dd = si != sj ? di - dj : di + dj; + d = si ? 0.5 - dd : 0.5 + dd; + if ((rand() / 1024) & 1) + { + c = mpfr_get_d(y); + f = "mpfr_get_d"; + } + else + { + exp = (rand() % 47) - 23; + c = mpfr_get_d2(y, exp); + f = "mpfr_get_d2"; + if (si) /* then real d < 0.5 */ + d *= sj && i == 1 ? 4 : 2; /* normalize real d */ + } + if (exp > 0) + d *= 1 << exp; + if (exp < 0) + d /= 1 << -exp; + if (c != d) + { + fprintf(stderr, "Error in tget_d (%s) for " + "(i,si,j,sj,rnd,exp) = (%d,%d,%d,%d,%d,%d)\n" + "got %.17g instead of %.17g\n", + f, i, si, j, sj, rnd_mode, exp, c, d); + exit(1); + } + } + } } - - mpfr_clear(x); + mpfr_clear(half); + mpfr_clear(x); + mpfr_clear(y); return 0; } diff --git a/mpfr/tests/tget_str.c b/mpfr/tests/tget_str.c index 9f6495a11..07ae5c1ae 100644 --- a/mpfr/tests/tget_str.c +++ b/mpfr/tests/tget_str.c @@ -51,19 +51,20 @@ check3 (double d, mp_rnd_t rnd, char *res) { mpfr_t x; char *str; mp_exp_t e; - mpfr_init2(x, 53); - mpfr_set_d(x, d, rnd); - str = mpfr_get_str(NULL, &e, 10, 5, x, rnd); - if (strcmp(str, res)) { - fprintf(stderr, "Error in mpfr_get_str for x=%1.20e\n", d); - fprintf(stderr, "got %s instead of %s\n", str, res); - } - mpfr_clear(x); - free(str); + mpfr_init2 (x, 53); + mpfr_set_d (x, d, rnd); + str = mpfr_get_str (NULL, &e, 10, 5, x, rnd); + if (strcmp(str, res)) + { + fprintf (stderr, "Error in mpfr_get_str for x=%1.20e\n", d); + fprintf (stderr, "got %s instead of %s\n", str, res); + } + mpfr_clear (x); + free (str); } void -check_small () +check_small (void) { mpfr_t x; char *s; diff --git a/mpfr/tests/thyperbolic.c b/mpfr/tests/thyperbolic.c index 5f310283b..f3f8cdcd8 100644 --- a/mpfr/tests/thyperbolic.c +++ b/mpfr/tests/thyperbolic.c @@ -52,7 +52,7 @@ check_NAN (void) /******cosh********/ tester=mpfr_cosh(ch,t,GMP_RNDD); - if (!MPFR_IS_NAN(ch) || !tester ) + if (!MPFR_IS_NAN(ch) || tester!=0 ) { printf("cosh NAN \n"); mpfr_clear(t); @@ -68,7 +68,7 @@ check_NAN (void) /******sinh********/ tester=mpfr_sinh(sh,t,GMP_RNDD); - if (!MPFR_IS_NAN(sh) || !tester ) + if (!MPFR_IS_NAN(sh) || tester!=0 ) { printf("sinh NAN \n"); mpfr_clear(t); @@ -84,7 +84,7 @@ check_NAN (void) /******tanh********/ tester=mpfr_tanh(th,t,GMP_RNDD); - if (!MPFR_IS_NAN(th) || !tester ) + if (!MPFR_IS_NAN(th) || tester!=0 ) { printf("tanh NAN \n"); mpfr_clear(t); @@ -100,7 +100,7 @@ check_NAN (void) /******acosh********/ tester=mpfr_acosh(ach,t,GMP_RNDD); - if (!MPFR_IS_NAN(ach) || !tester ) + if (!MPFR_IS_NAN(ach) || tester!=0 ) { printf("acosh NAN \n"); return(1); @@ -109,7 +109,7 @@ check_NAN (void) /******asinh********/ tester=mpfr_asinh(ash,t,GMP_RNDD); - if (!MPFR_IS_NAN(ash) || !tester ) + if (!MPFR_IS_NAN(ash) || tester!=0 ) { printf("asinh NAN \n"); mpfr_clear(t); @@ -125,7 +125,7 @@ check_NAN (void) /******atanh********/ tester=mpfr_atanh(ath,t,GMP_RNDD); - if (!MPFR_IS_NAN(ath) || !tester ) + if (!MPFR_IS_NAN(ath) || tester!=0 ) { printf("atanh NAN \n"); mpfr_clear(t); @@ -291,7 +291,7 @@ check_INF (void) mpfr_init2(ash,200); mpfr_init2(ath,200); - + MPFR_CLEAR_NAN(t); MPFR_SET_INF(t); if(MPFR_SIGN(t)<0) @@ -300,7 +300,7 @@ check_INF (void) /******cosh********/ tester = mpfr_cosh(ch,t,GMP_RNDD); - if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester ) + if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester!=0 ) { printf("cosh(INF) \n"); mpfr_clear(t); @@ -316,7 +316,7 @@ check_INF (void) /******sinh********/ tester=mpfr_sinh(sh,t,GMP_RNDD); - if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) < 0 || tester ) + if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) < 0 || tester!=0 ) { printf("sinh(INF) \n"); mpfr_clear(t); @@ -332,7 +332,7 @@ check_INF (void) /******tanh********/ tester=mpfr_tanh(th,t,GMP_RNDD); - if (mpfr_cmp_ui(th,1) != 0 || tester ) + if (mpfr_cmp_ui(th,1) != 0 || tester!=0 ) { printf("tanh(INF) \n"); mpfr_clear(t); @@ -348,7 +348,7 @@ check_INF (void) /******acosh********/ tester=mpfr_acosh(ach,t,GMP_RNDD); - if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || !tester ) + if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || tester!=0 ) { printf("acosh(INF) \n"); mpfr_clear(t); @@ -364,7 +364,7 @@ check_INF (void) /******asinh********/ tester=mpfr_asinh(ash,t,GMP_RNDD); - if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) < 0 || !tester ) + if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) < 0 || tester!=0 ) { printf("asinh(INF) \n"); mpfr_clear(t); @@ -398,7 +398,7 @@ check_INF (void) /******cosh********/ tester=mpfr_cosh(ch,t,GMP_RNDD); - if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester ) + if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester!=0 ) { printf("cosh(-INF) \n"); mpfr_clear(t); @@ -414,7 +414,7 @@ check_INF (void) /******sinh********/ tester=mpfr_sinh(sh,t,GMP_RNDD); - if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) > 0 || tester ) + if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) > 0 || tester!=0 ) { printf("sinh(-INF) \n"); mpfr_clear(t); @@ -430,7 +430,7 @@ check_INF (void) /******tanh********/ tester=mpfr_tanh(th,t,GMP_RNDD); - if (!mpfr_cmp_ui(th,-1) || tester ) + if (!mpfr_cmp_ui(th,-1) || tester!=0 ) { printf("tanh(-INF) \n"); mpfr_clear(t); @@ -446,7 +446,7 @@ check_INF (void) /******acosh********/ tester=mpfr_acosh(ach,t,GMP_RNDD); - if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || !tester ) + if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || tester!=0 ) { printf("acosh(-INF) \n"); mpfr_clear(t); @@ -462,7 +462,7 @@ check_INF (void) /******asinh********/ tester=mpfr_asinh(ash,t,GMP_RNDD); - if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) > 0 || !tester ) + if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) > 0 || tester!=0 ) { printf("asinh(-INF) \n"); mpfr_clear(t); @@ -594,7 +594,7 @@ check_O (void) } int -main() +main(void) { if (check_INF())printf("Error in evaluation of INF\n"); diff --git a/mpfr/tests/thypot.c b/mpfr/tests/thypot.c index 38e4b0938..42621c3e6 100644 --- a/mpfr/tests/thypot.c +++ b/mpfr/tests/thypot.c @@ -34,7 +34,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - unsigned int prec, err, yprec, n, p0 = 1, p1 = 100, N = 100; + unsigned int prec, err, yprec, n, p0 = 2, p1 = 100, N = 100; mp_rnd_t rnd; mpfr_t x1, x2, y, z, t; int inexact, compare, compare2; @@ -92,7 +92,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf (" approximation was "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -109,9 +109,9 @@ main (int argc, char *argv[]) { fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", mpfr_print_rnd_mode (rnd), compare, inexact); - printf ("x1="); mpfr_print_raw (x1); putchar ('\n'); - printf ("x2="); mpfr_print_raw (x2); putchar ('\n'); - printf ("t="); mpfr_print_raw (t); putchar ('\n'); + printf ("x1="); mpfr_print_binary (x1); putchar ('\n'); + printf ("x2="); mpfr_print_binary (x2); putchar ('\n'); + printf ("t="); mpfr_print_binary (t); putchar ('\n'); exit (1); } } diff --git a/mpfr/tests/tlog.c b/mpfr/tests/tlog.c index e386018f0..a3e2bc049 100644 --- a/mpfr/tests/tlog.c +++ b/mpfr/tests/tlog.c @@ -43,7 +43,7 @@ void special _PROTO((void)); double -drand_log () +drand_log (void) { double d; INT32 *i; @@ -107,7 +107,7 @@ check3 (double d, unsigned long prec, mp_rnd_t rnd) mpfr_set_d(x, d, rnd); mpfr_log(y, x, rnd); mpfr_out_str(stdout, 10, 0, y, rnd); putchar('\n'); - mpfr_print_raw(y); putchar('\n'); + mpfr_print_binary(y); putchar('\n'); mpfr_clear(x); mpfr_clear(y); } @@ -155,7 +155,7 @@ slave (int N, int p) */ void -check_worst_cases () +check_worst_cases (void) { check2(1.00089971802309629645, GMP_RNDD, 8.99313519443722736088e-04); check2(1.00089971802309629645, GMP_RNDN, 8.99313519443722844508e-04); @@ -239,7 +239,7 @@ check_worst_cases () } void -special () +special (void) { mpfr_t x, y; @@ -352,7 +352,7 @@ main (int argc, char *argv[]) check2(6.09969788341579732815e+00,GMP_RNDD,1.80823924264386204363e+00); } - test_generic (1, 100, 40); + test_generic (2, 100, 40); return 0; } diff --git a/mpfr/tests/tlog_base_10.c b/mpfr/tests/tlog10.c index a8e77e3d0..6d134321b 100644 --- a/mpfr/tests/tlog_base_10.c +++ b/mpfr/tests/tlog10.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/tlog1p.c b/mpfr/tests/tlog1p.c index 20038d2fb..9716f2e9c 100644 --- a/mpfr/tests/tlog1p.c +++ b/mpfr/tests/tlog1p.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/tlog2.c b/mpfr/tests/tlog2.c index 3d9dc721a..efe4f53a5 100644 --- a/mpfr/tests/tlog2.c +++ b/mpfr/tests/tlog2.c @@ -1,6 +1,7 @@ -/* Test file for mpfr_const_log2. +/* Test file for mpfr_log2. -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 2001 Free Software Foundation. +Adapted from tsinh.c. This file is part of the MPFR Library. @@ -23,27 +24,15 @@ MA 02111-1307, USA. */ #include <stdlib.h> #include "gmp.h" #include "mpfr.h" +#include "mpfr-test.h" -/* tlog2 [prec] [rnd] [0 = no print] */ +#define TEST_FUNCTION mpfr_log2 +#include "tgeneric.c" int main (int argc, char *argv[]) { - mpfr_t x; - int p; - unsigned char rnd; - - p = (argc>1) ? atoi(argv[1]) : 53; - rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ; - mpfr_init2(x, p); - mpfr_const_log2(x, rnd); - if (argc>=2) { - printf("log(2)="); mpfr_out_str(stdout, 10, 0, x, rnd); putchar('\n'); - } - else if (mpfr_get_d(x) != 6.9314718055994530941e-1) { - fprintf(stderr, "mpfr_const_log2 failed for prec=53\n"); exit(1); - } - mpfr_clear(x); + test_generic (2, 100, 30); return 0; } diff --git a/mpfr/tests/tmul.c b/mpfr/tests/tmul.c index cd7e0a2f1..5c49f869b 100644 --- a/mpfr/tests/tmul.c +++ b/mpfr/tests/tmul.c @@ -23,7 +23,9 @@ MA 02111-1307, USA. */ #include <stdlib.h> #include <unistd.h> #include "gmp.h" +#include "gmp-impl.h" #include "mpfr.h" +#include "mpfr-impl.h" #include "mpfr-test.h" void check _PROTO((double, double, mp_rnd_t, unsigned int, @@ -33,6 +35,8 @@ void check24 _PROTO((float, float, mp_rnd_t, float)); void check_float _PROTO((void)); void check_sign _PROTO((void)); void check_exact _PROTO((void)); +void check_max _PROTO((void)); +void check_min _PROTO((void)); /* checks that x*y gives the same results in double and with mpfr with 53 bits of precision */ @@ -42,9 +46,9 @@ check (double x, double y, mp_rnd_t rnd_mode, unsigned int px, { double z1, z2; mpfr_t xx, yy, zz; - mpfr_init2(xx, px); - mpfr_init2(yy, py); - mpfr_init2(zz, pz); + mpfr_init2 (xx, px); + mpfr_init2 (yy, py); + mpfr_init2 (zz, pz); mpfr_set_d(xx, x, rnd_mode); mpfr_set_d(yy, y, rnd_mode); mpfr_mul(zz, xx, yy, rnd_mode); @@ -69,13 +73,13 @@ check53 (double x, double y, mp_rnd_t rnd_mode, double z1) { double z2; mpfr_t xx, yy, zz; - mpfr_init2(xx, 53); - mpfr_init2(yy, 53); - mpfr_init2(zz, 53); - mpfr_set_d(xx, x, rnd_mode); - mpfr_set_d(yy, y, rnd_mode); - mpfr_mul(zz, xx, yy, rnd_mode); - z2 = mpfr_get_d(zz); + mpfr_init2 (xx, 53); + mpfr_init2 (yy, 53); + mpfr_init2 (zz, 53); + mpfr_set_d (xx, x, rnd_mode); + mpfr_set_d (yy, y, rnd_mode); + mpfr_mul (zz, xx, yy, rnd_mode); + z2 = mpfr_get_d (zz); if (z1!=z2 && (!isnan(z1) || !isnan(z2))) { printf("mpfr_mul failed for x=%1.20e y=%1.20e with rnd_mode=%s\n", x, y, mpfr_print_rnd_mode(rnd_mode)); @@ -92,13 +96,13 @@ check24 (float x, float y, mp_rnd_t rnd_mode, float z1) { float z2; mpfr_t xx, yy, zz; - mpfr_init2(xx, 24); - mpfr_init2(yy, 24); - mpfr_init2(zz, 24); - mpfr_set_d(xx, x, rnd_mode); - mpfr_set_d(yy, y, rnd_mode); - mpfr_mul(zz, xx, yy, rnd_mode); - z2 = (float) mpfr_get_d(zz); + mpfr_init2 (xx, 24); + mpfr_init2 (yy, 24); + mpfr_init2 (zz, 24); + mpfr_set_d (xx, x, rnd_mode); + mpfr_set_d (yy, y, rnd_mode); + mpfr_mul (zz, xx, yy, rnd_mode); + z2 = (float) mpfr_get_d (zz); if (z1!=z2) { printf("mpfr_mul failed for x=%1.0f y=%1.0f with prec=24 and rnd_mode=%s\n", x, y, mpfr_print_rnd_mode(rnd_mode)); printf("libm.a gives %1.0f, mpfr_mul gives %1.0f\n", z1, z2); @@ -110,7 +114,7 @@ check24 (float x, float y, mp_rnd_t rnd_mode, float z1) /* the following examples come from the paper "Number-theoretic Test Generation for Directed Rounding" from Michael Parks, Table 1 */ void -check_float () +check_float (void) { check24(8388609.0, 8388609.0, GMP_RNDN, 70368760954880.0); check24(16777213.0, 8388609.0, GMP_RNDN, 140737479966720.0); @@ -155,11 +159,12 @@ check_float () /* check sign of result */ void -check_sign () +check_sign (void) { mpfr_t a, b; - mpfr_init2(a, 53); mpfr_init2(b, 53); + mpfr_init2 (a, 53); + mpfr_init2 (b, 53); mpfr_set_d(a, -1.0, GMP_RNDN); mpfr_set_d(b, 2.0, GMP_RNDN); mpfr_mul(a, b, b, GMP_RNDN); @@ -171,7 +176,7 @@ check_sign () /* checks that the inexact return value is correct */ void -check_exact () +check_exact (void) { mpfr_t a, b, c, d; mp_prec_t prec; @@ -240,6 +245,99 @@ check_exact () mpfr_clear (d); } +void +check_max(void) +{ + mpfr_t xx, yy, zz; + + mpfr_init2(xx, 4); + mpfr_init2(yy, 4); + mpfr_init2(zz, 4); + mpfr_set_d(xx, 11.0/16, GMP_RNDN); + mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, GMP_RNDN); + mpfr_set_d(yy, 11.0/16, GMP_RNDN); + mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, GMP_RNDN); + mpfr_clear_flags(); + mpfr_mul(zz, xx, yy, GMP_RNDU); + if (!(mpfr_overflow_p() && MPFR_IS_INF(zz))) + { + printf("check_max failed (should be an overflow)\n"); + exit(1); + } + + mpfr_clear_flags(); + mpfr_mul(zz, xx, yy, GMP_RNDD); + if (mpfr_overflow_p() || MPFR_IS_INF(zz)) + { + printf("check_max failed (should NOT be an overflow)\n"); + exit(1); + } + mpfr_set_d(xx, 15.0/16, GMP_RNDN); + mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, GMP_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, GMP_RNDZ); + printf(" instead of "); + mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ); + printf("\n"); + exit(1); + } + + mpfr_clear(xx); + mpfr_clear(yy); + mpfr_clear(zz); +} + +void +check_min(void) +{ + mpfr_t xx, yy, zz; + + mpfr_init2(xx, 4); + mpfr_init2(yy, 4); + mpfr_init2(zz, 3); + mpfr_set_d(xx, 15.0/16, GMP_RNDN); + mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, GMP_RNDN); + mpfr_set_d(yy, 15.0/16, GMP_RNDN); + mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, GMP_RNDN); + mpfr_mul(zz, xx, yy, GMP_RNDD); + if (mpfr_sgn(zz) != 0) + { + printf("check_min failed: got "); + mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ); + printf(" instead of 0\n"); + exit(1); + } + + mpfr_mul(zz, xx, yy, GMP_RNDU); + mpfr_set_d(xx, 0.5, GMP_RNDN); + mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, GMP_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, GMP_RNDZ); + printf(" instead of "); + mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ); + printf("\n"); + exit(1); + } + + mpfr_clear(xx); + mpfr_clear(yy); + mpfr_clear(zz); +} + int main (int argc, char *argv[]) { @@ -263,7 +361,7 @@ main (int argc, char *argv[]) check53(0.31869277231188065, 0.88642843322303122, GMP_RNDZ, 2.8249833483992453642e-1); check(8.47622108205396074254e-01, 3.24039313247872939883e-01, GMP_RNDU, - 28, 45, 1, 0.5); + 28, 45, 2, 0.375); check(2.63978122803639081440e-01, 6.8378615379333496093e-1, GMP_RNDN, 34, 23, 31, 0.180504585267044603); check(1.0, 0.11835170935876249132, GMP_RNDU, 6, 41, 36, 0.1183517093595583); @@ -275,7 +373,9 @@ main (int argc, char *argv[]) check(3.90798504668055102229e-14, 9.85394674650308388664e-04, GMP_RNDN, 46, 22, 12, 0.385027296503914762e-16); check(4.58687081072827851358e-01, 2.20543551472118792844e-01, GMP_RNDN, - 49, 3, 1, 0.125); + 49, 3, 2, 0.09375); + check_max(); + check_min(); #ifdef TEST srand48(getpid()); prec = (argc<2) ? 53 : atoi(argv[1]); diff --git a/mpfr/tests/tmul_ui.c b/mpfr/tests/tmul_ui.c index 0bc0f5d14..8ca7491b6 100644 --- a/mpfr/tests/tmul_ui.c +++ b/mpfr/tests/tmul_ui.c @@ -23,6 +23,7 @@ MA 02111-1307, USA. */ #include <stdlib.h> #include <math.h> #include "gmp.h" +#include "gmp-impl.h" #include "mpfr.h" #include "mpfr-impl.h" @@ -47,7 +48,8 @@ check_inexact (mp_prec_t p) fprintf (stderr, "Error: result should be exact\n"); exit (1); } - for (q=1; q<=p; q++) + + for (q=2; q<=p; q++) for (rnd=0; rnd<4; rnd++) { mpfr_set_prec (y, q); @@ -63,11 +65,11 @@ check_inexact (mp_prec_t p) } } - mpfr_set_prec (x, 1); - mpfr_set_ui (x, 2, GMP_RNDN); - if (mpfr_mul_ui (x, x, 3, GMP_RNDZ) == 0) + mpfr_set_prec (x, 2); + mpfr_set_ui (x, 1, GMP_RNDN); + if (mpfr_mul_ui (x, x, 5, GMP_RNDZ) == 0) { - fprintf (stderr, "mul_ui(2, 3) cannot be exact with prec=1\n"); + fprintf (stderr, "mul_ui(1, 5) cannot be exact with prec=2\n"); exit (1); } @@ -83,7 +85,7 @@ main (int argc, char *argv[]) unsigned int xprec, yprec, i; mp_prec_t p; - for (p=1; p<100; p++) + for (p=2; p<100; p++) for (i=1; i<50; i++) check_inexact (p); @@ -101,8 +103,8 @@ main (int argc, char *argv[]) if (mpfr_cmp (x, y)) { fprintf (stderr, "Error in mpfr_mul_ui: 1*y != y\n"); - printf ("y= "); mpfr_print_raw (y); putchar ('\n'); - printf ("1*y="); mpfr_print_raw (x); putchar ('\n'); + printf ("y= "); mpfr_print_binary (y); putchar ('\n'); + printf ("1*y="); mpfr_print_binary (x); putchar ('\n'); exit (1); } @@ -145,7 +147,7 @@ main (int argc, char *argv[]) mpfr_mul_ui(x, y, 4, GMP_RNDZ); if (mpfr_cmp_ui(x, 0) <= 0) { fprintf(stderr, "Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n"); - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0)); exit(1); } @@ -158,7 +160,7 @@ main (int argc, char *argv[]) if (mpfr_cmp (x, y)) { fprintf (stderr, "Error in mul_ui for 1335*(0.100001111E9)\n"); - printf ("got "); mpfr_print_raw (x); putchar ('\n'); + printf ("got "); mpfr_print_binary (x); putchar ('\n'); exit(1); } @@ -171,7 +173,7 @@ main (int argc, char *argv[]) mpfr_set_str_raw(y, "0.1111101111010101111111100011010010111010111110110011001E67"); if (mpfr_cmp(x, y)) { printf("Error for 121*y: expected result is:\n"); - mpfr_print_raw(y); putchar('\n'); + mpfr_print_binary(y); putchar('\n'); } mpfr_set_prec (x, 32); @@ -198,8 +200,8 @@ main (int argc, char *argv[]) if (mpfr_cmp (x, y)) { printf ("Error for 23 * 2143861251406875.0\n"); - printf ("expected "); mpfr_print_raw (x); putchar ('\n'); - printf ("got "); mpfr_print_raw (y); putchar ('\n'); + printf ("expected "); mpfr_print_binary (x); putchar ('\n'); + printf ("got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -215,13 +217,26 @@ main (int argc, char *argv[]) if (mpfr_get_d (x) != mpfr_get_d (y)) { fprintf (stderr, "multiplication by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec); - printf ("expected "); mpfr_print_raw (x); putchar ('\n'); - printf ("got "); mpfr_print_raw (y); putchar ('\n'); + printf ("expected "); mpfr_print_binary (x); putchar ('\n'); + printf ("got "); mpfr_print_binary (y); putchar ('\n'); exit (1); } } } + mpfr_set_prec (x, 128); + mpfr_set_ui (x, 17, GMP_RNDN); + mpfr_mul_ui (x, x, MP_LIMB_T_HIGHBIT, GMP_RNDN); + mpfr_set_prec (y, 128); + mpfr_set_ui (y, MP_LIMB_T_HIGHBIT, GMP_RNDN); + mpfr_mul_ui (y, y, 17, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for 17 * 2^MP_LIMB_T_HIGHBIT\n"); + exit (1); + } + + mpfr_clear(x); mpfr_clear(y); return 0; diff --git a/mpfr/tests/tout_str.c b/mpfr/tests/tout_str.c index 7138ce62d..7269a5017 100644 --- a/mpfr/tests/tout_str.c +++ b/mpfr/tests/tout_str.c @@ -50,53 +50,57 @@ check4(double d, mp_rnd_t rnd, int base, int prec) } void -check_large () +check_large (void) { mpfr_t x; mp_exp_t e; char *s; mpfr_init(x); - mpfr_set_prec(x, 7); - mpfr_set_str_raw(x, "0.1010101E10"); - s = mpfr_get_str(NULL, &e, 10, 2, x, GMP_RNDU); - free(s); + mpfr_set_prec (x, 7); + mpfr_set_str_raw (x, "0.1010101E10"); + s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDU); + free (s); /* checks rounding of negative numbers */ - mpfr_set_d(x, -1.5, GMP_RNDN); - s = mpfr_get_str(NULL, &e, 10, 1, x, GMP_RNDD); - if (strcmp(s, "-2")) { - fprintf(stderr, "Error in mpfr_get_str for x=-1.5 and rnd=GMP_RNDD\n"); - free(s); mpfr_clear(x); - exit(1); + mpfr_set_prec (x, 7); + mpfr_set_d (x, -11.5, GMP_RNDN); + s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDD); + if (strcmp (s, "-12")) + { + fprintf (stderr, "Error in mpfr_get_str for x=-11.5 and rnd=GMP_RNDD\n"); + free (s); + mpfr_clear (x); + exit (1); } - free(s); - - s = mpfr_get_str(NULL, &e, 10, 1, x, GMP_RNDU); - if (strcmp(s, "-1")) { - fprintf(stderr, "Error in mpfr_get_str for x=-1.5 and rnd=GMP_RNDU\n"); - free(s); - mpfr_clear(x); - exit(1); - } - - free(s); + free (s); + + s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDU); + if (strcmp (s, "-11")) + { + fprintf (stderr, "Error in mpfr_get_str for x=-11.5 and rnd=GMP_RNDU\n"); + free (s); + mpfr_clear (x); + exit (1); + } + free (s); /* bug found by Jean-Pierre Merlet, produced error in mpfr_get_str */ - mpfr_set_prec(x, 128); - mpfr_set_str_raw(x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3"); - s = mpfr_get_str(NULL, &e, 10, 0, x, GMP_RNDU); - free(s); + mpfr_set_prec (x, 128); + mpfr_set_str_raw (x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3"); + s = mpfr_get_str (NULL, &e, 10, 0, x, GMP_RNDU); + free (s); - mpfr_set_prec(x, 381); - mpfr_set_str_raw(x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010"); + mpfr_set_prec (x, 381); + mpfr_set_str_raw (x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010"); s = mpfr_get_str (NULL, &e, 10, 0, x, GMP_RNDD); - if (e != 0) { - fprintf(stderr, "Error in mpfr_get_str for x=0.999999..., exponent is %d instead of 0\n", (int) e); - exit(1); - } - free(s); - - mpfr_clear(x); + if (e != 0) + { + fprintf (stderr, "Error in mpfr_get_str for x=0.999999..., exponent is %d instead of 0\n", (int) e); + exit (1); + } + free (s); + + mpfr_clear (x); } int @@ -128,12 +132,16 @@ main (int argc, char *argv[]) /* random tests */ srand(getpid()); - for (i=0;i<N;i++) { - do { d = drand(); } while (isnan(d)); - r = rand()%4; - p = 2 + rand()%35; - check(d, r, p); - } + for (i=0;i<N;i++) + { + do + { + d = drand(); + } while (isnan(d)); + r = rand() % 4; + p = 2 + rand() % 35; + check (d, r, p); + } return 0; } diff --git a/mpfr/tests/tpow.c b/mpfr/tests/tpow.c index 5a8727a95..b54a53679 100644 --- a/mpfr/tests/tpow.c +++ b/mpfr/tests/tpow.c @@ -28,7 +28,7 @@ void check_pow_ui _PROTO ((void)); void check_inexact _PROTO ((mp_prec_t)); void -check_pow_ui () +check_pow_ui (void) { mpfr_t a, b; @@ -78,7 +78,7 @@ check_inexact (mp_prec_t p) mpfr_init (t); mpfr_random (x); u = lrand48() % 2; - for (q=1; q<=p; q++) + for (q=2; q<=p; q++) for (rnd=0; rnd<4; rnd++) { mpfr_set_prec (y, q); @@ -93,10 +93,10 @@ check_inexact (mp_prec_t p) { fprintf (stderr, "results differ for u=%lu rnd=%s\n", u, mpfr_print_rnd_mode(rnd)); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("t="); mpfr_print_raw (t); putchar ('\n'); - printf ("z="); mpfr_print_raw (z); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("t="); mpfr_print_binary (t); putchar ('\n'); + printf ("z="); mpfr_print_binary (z); putchar ('\n'); exit (1); } if (((inexact == 0) && (cmp != 0)) || @@ -105,8 +105,8 @@ check_inexact (mp_prec_t p) fprintf (stderr, "Wrong inexact flag for p=%u, q=%u, rnd=%s\n", (unsigned) p, (unsigned) q, mpfr_print_rnd_mode (rnd)); printf ("expected %d, got %d\n", cmp, inexact); - printf ("u=%lu x=", u); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("u=%lu x=", u); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); exit (1); } } @@ -125,7 +125,7 @@ main (void) check_pow_ui (); - for (p=1; p<100; p++) + for (p=2; p<100; p++) check_inexact (p); return 0; diff --git a/mpfr/tests/tpow3.c b/mpfr/tests/tpow3.c index 52fcba886..12b945e55 100644 --- a/mpfr/tests/tpow3.c +++ b/mpfr/tests/tpow3.c @@ -338,7 +338,7 @@ main (int argc, char *argv[]) int inexact, compare, compare2; unsigned int n, err; - int p0=1; + int p0=2; int p1=100; int N=100; @@ -385,7 +385,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf ("approx "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -402,9 +402,9 @@ main (int argc, char *argv[]) { fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", mpfr_print_rnd_mode (rnd), compare, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("t="); mpfr_print_raw (t); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("t="); mpfr_print_binary (t); putchar ('\n'); exit (1); } } diff --git a/mpfr/tests/trint.c b/mpfr/tests/trint.c new file mode 100644 index 000000000..9c5935490 --- /dev/null +++ b/mpfr/tests/trint.c @@ -0,0 +1,92 @@ +/* Test file for mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round. + +Copyright (C) 2002 Free Software Foundation. + +This file is part of the MPFR Library. + +The MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" + +int +main (void) +{ + mp_size_t s; + mpz_t z; + mp_prec_t p; + mpfr_t x, y, t; + mp_rnd_t r; + int inexact, sign_t; + + mpfr_init (x); + mpfr_init (y); + mpz_init (z); + mpfr_init (t); + mpz_set_ui (z, 1); + for (s = 2; s < 100; s++) + { + /* z has exactly s bits */ + + mpz_mul_2exp (z, z, 1); + if (rand () % 2) + mpz_add_ui (z, z, 1); + mpfr_set_prec (x, s); + mpfr_set_prec (t, s); + if (mpfr_set_z (x, z, GMP_RNDN)) + { + fprintf (stderr, "Error: mpfr_set_z should be exact (s = %u)\n", + (unsigned int) s); + exit (1); + } + for (p=2; p<100; p++) + { + mpfr_set_prec (y, p); + for (r=0; r<4; r++) + { + if (r == GMP_RNDN) + inexact = mpfr_round (y, x); + else if (r == GMP_RNDZ) + inexact = mpfr_trunc (y, x); + else if (r == GMP_RNDU) + inexact = mpfr_ceil (y, x); + else /* r = GMP_RNDD */ + inexact = mpfr_floor (y, x); + if (mpfr_sub (t, y, x, GMP_RNDN)) + { + fprintf (stderr, "Error: subtraction should be exact\n"); + exit (1); + } + sign_t = mpfr_cmp_ui (t, 0); + if (((inexact == 0) && (sign_t != 0)) || + ((inexact < 0) && (sign_t >= 0)) || + ((inexact > 0) && (sign_t <= 0))) + { + fprintf (stderr, "Wrong inexact flag\n"); + exit (1); + } + } + } + } + mpfr_clear (x); + mpfr_clear (y); + mpz_clear (z); + mpfr_clear (t); + + return 0; +} diff --git a/mpfr/tests/tround.c b/mpfr/tests/tround_prec.c index 315884ad4..72437f26a 100644 --- a/mpfr/tests/tround.c +++ b/mpfr/tests/tround_prec.c @@ -1,6 +1,6 @@ -/* Test file for mpfr_round. +/* Test file for mpfr_round_prec. -Copyright (C) 1999-2001 Free Software Foundation. +Copyright (C) 1999-2002 Free Software Foundation. This file is part of the MPFR Library. @@ -32,7 +32,7 @@ main (void) mpfr_init2 (x, 3); mpfr_set_ui (x, 5, GMP_RNDN); - mpfr_round (x, GMP_RNDN, 2); + mpfr_round_prec (x, GMP_RNDN, 2); if (mpfr_cmp_ui(x, 4)) { fprintf (stderr, "Error in tround: got %1.1f instead of 4\n", @@ -43,7 +43,7 @@ main (void) /* check case when reallocation is needed */ mpfr_set_prec (x, 3); mpfr_set_ui (x, 5, GMP_RNDN); /* exact */ - mpfr_round (x, GMP_RNDN, mp_bits_per_limb + 1); + mpfr_round_prec (x, GMP_RNDN, mp_bits_per_limb + 1); if (mpfr_cmp_ui(x, 5)) { fprintf (stderr, "Error in tround: got %1.1f instead of 5\n", @@ -51,10 +51,21 @@ main (void) exit (1); } + mpfr_clear(x); + mpfr_init2 (x, 3); + mpfr_set_si (x, -5, GMP_RNDN); /* exact */ + mpfr_round_prec (x, GMP_RNDN, mp_bits_per_limb + 1); + if (mpfr_cmp_si(x, -5)) + { + fprintf (stderr, "Error in tround: got %1.1f instead of -5\n", + mpfr_get_d (x)); + exit (1); + } + /* check case when new precision needs less limbs */ mpfr_set_prec (x, mp_bits_per_limb + 1); mpfr_set_ui (x, 5, GMP_RNDN); /* exact */ - mpfr_round (x, GMP_RNDN, 3); /* exact */ + mpfr_round_prec (x, GMP_RNDN, 3); /* exact */ if (mpfr_cmp_ui(x, 5)) { fprintf (stderr, "Error in tround: got %1.1f instead of 5\n", diff --git a/mpfr/tests/tset.c b/mpfr/tests/tset.c index cca6611e6..1ae5951d6 100644 --- a/mpfr/tests/tset.c +++ b/mpfr/tests/tset.c @@ -26,7 +26,7 @@ MA 02111-1307, USA. */ #include "mpfr.h" int -main () +main (void) { mp_prec_t p, q; mpfr_t x, y, z, u; @@ -41,22 +41,22 @@ main () mpfr_set_prec (y, 11); mpfr_set_str_raw (y, "0.11111111100E-8"); - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); mpfr_set (x, y, GMP_RNDN); mpfr_set_str_raw (y, "1.0E-8"); if (mpfr_cmp (x, y)) { - fprintf (stderr, "Error for y=0.11111111100E-8, prec=1, rnd=GMP_RNDN\n"); + fprintf (stderr, "Error for y=0.11111111100E-8, prec=2, rnd=GMP_RNDN\n"); exit (1); } - for (p=1; p<500; p++) + for (p=2; p<500; p++) { mpfr_set_prec (x, p); mpfr_random (x); if (rand () % 2) mpfr_neg (x, x, GMP_RNDN); - for (q=1; q<2*p; q++) + for (q=2; q<2*p; q++) { mpfr_set_prec (y, q); for (rnd=0; rnd<4; rnd++) diff --git a/mpfr/tests/tset_d.c b/mpfr/tests/tset_d.c index eae93a2c8..3a1ace898 100644 --- a/mpfr/tests/tset_d.c +++ b/mpfr/tests/tset_d.c @@ -1,6 +1,6 @@ /* Test file for mpfr_set_d and mpfr_get_d. -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -26,8 +26,6 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-test.h" -extern int isnan(); - int main (int argc, char *argv[]) { @@ -40,18 +38,43 @@ main (int argc, char *argv[]) set_fpc_csr(exp.fc_word); #endif - mpfr_init(x); + mpfr_init2 (x, 2); + + /* checks that rounds to nearest sets the last + bit to zero in case of equal distance */ + mpfr_set_d (x, 5.0, GMP_RNDN); + if (mpfr_get_d (x) != 4.0) + { + fprintf (stderr, "Error in tset_d: got %g instead of 4.0\n", + mpfr_get_d (x)); + exit (1); + } + mpfr_set_d (x, -5.0, GMP_RNDN); + if (mpfr_get_d (x) != -4.0) + { + fprintf (stderr, "Error in tset_d: got %g instead of -4.0\n", + mpfr_get_d (x)); + exit (1); + } + + mpfr_set_d (x, 9.84891017624509146344e-01, GMP_RNDU); + if (mpfr_get_d (x) != 1.0) + { + fprintf (stderr, "Error in tset_d: got %g instead of 1.0\n", + mpfr_get_d (x)); + exit (1); + } mpfr_init2(z, 32); mpfr_set_d(z, 1.0, 0); if (mpfr_get_d(z) != 1.0) { - mpfr_print_raw(z); putchar('\n'); + mpfr_print_binary(z); putchar('\n'); 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, 0); if (mpfr_get_d(x) != d) { - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); printf("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",d, mpfr_get_d(x)); exit(1); } @@ -60,7 +83,7 @@ main (int argc, char *argv[]) d = -6.72658901114033715233e-165; mpfr_set_d(x, d, 0); if (d != mpfr_get_d(x)) { - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); printf("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",d, mpfr_get_d(x)); exit(1); } @@ -74,7 +97,7 @@ main (int argc, char *argv[]) { fprintf(stderr, "Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d(x)); - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); exit(1); } } diff --git a/mpfr/tests/tset_f.c b/mpfr/tests/tset_f.c index a6d16e6f9..59af6a940 100644 --- a/mpfr/tests/tset_f.c +++ b/mpfr/tests/tset_f.c @@ -71,15 +71,15 @@ main (void) for (k = 1; k <= 100000; k++) { - pr = 1 + (rand()&255); - mpf_set_prec(z, pr); - mpf_random2(z, z->_mp_prec, 0); - mpfr_init2(x, pr); - mpfr_set_f(x, z, 0); - mpfr_clear(x); + pr = 2 + (rand()&255); + mpf_set_prec (z, pr); + mpf_random2 (z, z->_mp_prec, 0); + mpfr_init2 (x, pr); + mpfr_set_f (x, z, 0); + mpfr_clear (x); } - mpf_clear(y); - mpf_clear(z); + mpf_clear (y); + mpf_clear (z); return 0; } diff --git a/mpfr/tests/tset_si.c b/mpfr/tests/tset_si.c index cb74a51a4..17ef0af63 100644 --- a/mpfr/tests/tset_si.c +++ b/mpfr/tests/tset_si.c @@ -75,14 +75,14 @@ main (int argc, char *argv[]) } } - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); if (mpfr_set_si (x, 5, GMP_RNDZ) >= 0) { fprintf (stderr, "Wrong inexact flag for x=5, rnd=GMP_RNDZ\n"); exit (1); } - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); if (mpfr_set_si (x, -5, GMP_RNDZ) <= 0) { fprintf (stderr, "Wrong inexact flag for x=-5, rnd=GMP_RNDZ\n"); @@ -95,7 +95,7 @@ main (int argc, char *argv[]) || inex >= 0) { fprintf(stderr, "Error in mpfr_set_si(x:3, 77617, GMP_RNDD)\n"); - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); exit(1); } inex = mpfr_set_ui(x, 77617, GMP_RNDD); /* should be 65536 */ @@ -103,22 +103,22 @@ main (int argc, char *argv[]) || inex >= 0) { fprintf(stderr, "Error in mpfr_set_ui(x:3, 77617, GMP_RNDD)\n"); - mpfr_print_raw(x); putchar('\n'); + mpfr_print_binary(x); putchar('\n'); exit(1); } - mpfr_set_prec(x, 1); + mpfr_set_prec(x, 2); inex = mpfr_set_si(x, 33096, GMP_RNDU); - if (mpfr_get_d(x) != 65536.0 || inex <= 0) + if (mpfr_get_d(x) != 49152.0 || inex <= 0) { - fprintf(stderr, "Error in mpfr_set_si, expected 65536, got %lu, inex %d\n", + fprintf(stderr, "Error in mpfr_set_si, expected 49152, got %lu, inex %d\n", (unsigned long) mpfr_get_d(x), inex); exit(1); } inex = mpfr_set_ui(x, 33096, GMP_RNDU); - if (mpfr_get_d(x) != 65536.0) + if (mpfr_get_d(x) != 49152.0) { - fprintf(stderr, "Error in mpfr_set_ui, expected 65536, got %lu, inex %d\n", + fprintf(stderr, "Error in mpfr_set_ui, expected 49152, got %lu, inex %d\n", (unsigned long) mpfr_get_d(x), inex); exit(1); } diff --git a/mpfr/tests/tset_str.c b/mpfr/tests/tset_str.c index 18c3b5f61..0477fcef3 100644 --- a/mpfr/tests/tset_str.c +++ b/mpfr/tests/tset_str.c @@ -84,9 +84,9 @@ main (int argc, char *argv[]) if (mpfr_cmp (x, y)) { fprintf (stderr, "Error in mpfr_set_str\n"); - mpfr_print_raw(x); + mpfr_print_binary(x); putchar('\n'); - mpfr_print_raw(y); + mpfr_print_binary(y); putchar('\n'); mpfr_clear(x); mpfr_clear(y); @@ -150,11 +150,11 @@ main (int argc, char *argv[]) fprintf (stderr, "mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n", mpfr_print_rnd_mode (k)); printf ("x="); - mpfr_print_raw (x); + mpfr_print_binary (x); putchar('\n'); printf ("s=%s, exp=%d, base=%d\n", str, (int) e, base); printf ("y="); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar('\n'); mpfr_clear (x); mpfr_clear (y); diff --git a/mpfr/tests/tset_z.c b/mpfr/tests/tset_z.c index 221605a3e..c76c624c5 100644 --- a/mpfr/tests/tset_z.c +++ b/mpfr/tests/tset_z.c @@ -44,7 +44,7 @@ check(long i, unsigned char rnd) } void -check_large () +check_large (void) { mpz_t z; mpfr_t x,y; diff --git a/mpfr/tests/tsin.c b/mpfr/tests/tsin.c index 51cba7e62..ec063a136 100644 --- a/mpfr/tests/tsin.c +++ b/mpfr/tests/tsin.c @@ -71,17 +71,30 @@ main (int argc, char *argv[]) check53 (1.00591265847407274059, 8.446508805292128885e-1, GMP_RNDN); - mpfr_init2 (x, 1); + mpfr_init2 (x, 2); + mpfr_set_d (x, 0.5, GMP_RNDN); mpfr_sin (x, x, GMP_RNDD); - if (mpfr_get_d(x) != 0.25) + if (mpfr_get_d(x) != 0.375) + { + fprintf (stderr, "mpfr_sin(0.5, GMP_RNDD) failed with precision=2\n"); + exit (1); + } + + /* bug found by Kevin Ryde */ + mpfr_const_pi (x, GMP_RNDN); + mpfr_mul_ui (x, x, 3L, GMP_RNDN); + mpfr_div_ui (x, x, 2L, GMP_RNDN); + mpfr_sin (x, x, GMP_RNDN); + if (mpfr_cmp_ui (x, 0) >= 0) { - fprintf (stderr, "mpfr_sin(0.5, GMP_RNDD) failed\n"); + fprintf (stderr, "Error: wrong sign for sin(3*Pi/2)\n"); exit (1); } + mpfr_clear (x); - test_generic (1, 100, 80); + test_generic (2, 100, 80); return 0; } diff --git a/mpfr/tests/tsinh.c b/mpfr/tests/tsinh.c index 9468585d0..d1cd127cd 100644 --- a/mpfr/tests/tsinh.c +++ b/mpfr/tests/tsinh.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/tsqrt.c b/mpfr/tests/tsqrt.c index 2c4df61eb..366e62c53 100644 --- a/mpfr/tests/tsqrt.c +++ b/mpfr/tests/tsqrt.c @@ -90,8 +90,8 @@ check4 (double a, mp_rnd_t rnd_mode, char *Q) if (mpfr_cmp(q, res)) { printf("mpfr_sqrt failed for a=%1.20e, rnd_mode=%s\n", a, mpfr_print_rnd_mode(rnd_mode)); - printf("expected "); mpfr_print_raw(res); putchar('\n'); - printf("got "); mpfr_print_raw(q); putchar('\n'); + printf("expected "); mpfr_print_binary(res); putchar('\n'); + printf("got "); mpfr_print_binary(q); putchar('\n'); mpfr_clear(q); mpfr_clear(res); exit(1); } @@ -120,7 +120,7 @@ check24 (float a, mp_rnd_t rnd_mode, float Q) /* the following examples come from the paper "Number-theoretic Test Generation for Directed Rounding" from Michael Parks, Table 3 */ void -check_float () +check_float (void) { float b = 8388608.0; /* 2^23 */ @@ -170,7 +170,7 @@ check_float () } void -special () +special (void) { mpfr_t x, z; int inexact; @@ -187,17 +187,17 @@ special () exit (1); } - mpfr_set_prec (x, 1); - for (p=1; p<1000; p++) + mpfr_set_prec (x, 2); + for (p=2; p<1000; p++) { mpfr_set_prec (z, p); mpfr_set_ui (z, 1, GMP_RNDN); - mpfr_add_one_ulp (z); + mpfr_add_one_ulp (z, GMP_RNDN); mpfr_sqrt (x, z, GMP_RNDU); - if (mpfr_cmp_ui (x, 2)) + if (mpfr_get_d (x) != 1.5) { - fprintf (stderr, "Error: sqrt(1+ulp(1), up) should give 2 (prec=%u)\n", (unsigned) p); - printf ("got "); mpfr_print_raw (x); putchar ('\n'); + fprintf (stderr, "Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n", (unsigned) p); + printf ("got "); mpfr_print_binary (x); putchar ('\n'); exit (1); } } @@ -211,8 +211,8 @@ special () exit (1); } - mpfr_set_prec (x, 1); - mpfr_set_prec (z, 1); + mpfr_set_prec (x, 2); + mpfr_set_prec (z, 2); /* checks the sign is correctly set */ mpfr_set_d (x, 1.0, GMP_RNDN); @@ -227,7 +227,7 @@ special () mpfr_set_prec (x, 192); mpfr_set_prec (z, 160); mpfr_set_str_raw (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1"); - mpfr_set_prec(x, 160); + mpfr_set_prec (x, 160); mpfr_sqrt(x, z, GMP_RNDN); mpfr_sqrt(z, x, GMP_RNDN); @@ -262,9 +262,9 @@ check_inexact (mp_prec_t p) fprintf (stderr, "Error: wrong inexact flag, expected %d, got %d\n", sign, inexact); printf ("x="); - mpfr_print_raw (x); + mpfr_print_binary (x); printf (" rnd=%s\n", mpfr_print_rnd_mode (rnd)); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); exit (1); } mpfr_clear (x); @@ -295,7 +295,7 @@ main (void) check(a, rand() % 4); } #endif - for (p=1; p<200; p++) + for (p=2; p<200; p++) for (k=0; k<200; k++) check_inexact (p); special (); diff --git a/mpfr/tests/tsub.c b/mpfr/tests/tsub.c index a5319063d..282b1a0af 100644 --- a/mpfr/tests/tsub.c +++ b/mpfr/tests/tsub.c @@ -33,7 +33,7 @@ void check_two_sum _PROTO((mp_prec_t)); void check_inexact _PROTO((void)); void -check_diverse () +check_diverse (void) { mpfr_t x, y, z; double res, got; @@ -53,8 +53,8 @@ check_diverse () if (mpfr_cmp (z, y)) { fprintf (stderr, "Error in mpfr_sub (5)\n"); - printf ("expected "); mpfr_print_raw (y); putchar ('\n'); - printf ("got "); mpfr_print_raw (z); putchar ('\n'); + printf ("expected "); mpfr_print_binary (y); putchar ('\n'); + printf ("got "); mpfr_print_binary (z); putchar ('\n'); exit (1); } @@ -66,8 +66,8 @@ check_diverse () if (mpfr_cmp (z, y)) { fprintf (stderr, "Error in mpfr_sub (7)\n"); - printf ("expected "); mpfr_print_raw (y); putchar ('\n'); - printf ("got "); mpfr_print_raw (z); putchar ('\n'); + printf ("expected "); mpfr_print_binary (y); putchar ('\n'); + printf ("got "); mpfr_print_binary (z); putchar ('\n'); exit (1); } @@ -79,8 +79,8 @@ check_diverse () if (mpfr_cmp (z, y)) { fprintf (stderr, "Error in mpfr_sub (6)\n"); - printf ("expected "); mpfr_print_raw (y); putchar ('\n'); - printf ("got "); mpfr_print_raw (z); putchar ('\n'); + printf ("expected "); mpfr_print_binary (y); putchar ('\n'); + printf ("got "); mpfr_print_binary (z); putchar ('\n'); exit (1); } @@ -115,8 +115,8 @@ check_diverse () if (mpfr_cmp (x, y)) { fprintf (stderr, "Error in mpfr_sub (1 - 1E-33) with prec=33\n"); - printf ("Expected "); mpfr_print_raw (y); putchar ('\n'); - printf ("got "); mpfr_print_raw (x); putchar ('\n'); + printf ("Expected "); mpfr_print_binary (y); putchar ('\n'); + printf ("got "); mpfr_print_binary (x); putchar ('\n'); exit (1); } @@ -128,7 +128,7 @@ check_diverse () if (mpfr_cmp_ui (x, 1)) { fprintf (stderr, "Error in mpfr_sub (1 - 1E-33) with prec=32\n"); - printf ("Expected 1.0, got "); mpfr_print_raw (x); putchar ('\n'); + printf ("Expected 1.0, got "); mpfr_print_binary (x); putchar ('\n'); exit (1); } @@ -198,8 +198,8 @@ check_diverse () mpfr_sub (z, x, y, GMP_RNDN); if (mpfr_cmp (z, x)) { fprintf (stderr, "mpfr_sub(z, x, y) failed for prec(x)=112, prec(y)=98\n"); - printf ("expected "); mpfr_print_raw (x); putchar('\n'); - printf ("got "); mpfr_print_raw (z); putchar('\n'); + printf ("expected "); mpfr_print_binary (x); putchar('\n'); + printf ("got "); mpfr_print_binary (z); putchar('\n'); exit (1); } @@ -232,7 +232,7 @@ check_diverse () exit (1); } - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); mpfr_set_prec (y, 10); mpfr_set_prec (z, 10); mpfr_set_ui (y, 0, GMP_RNDN); @@ -254,7 +254,7 @@ check_diverse () } void -bug_ddefour() +bug_ddefour(void) { mpfr_t ex, ex1, ex2, ex3, tot, tot1; @@ -276,8 +276,8 @@ bug_ddefour() if (mpfr_cmp(ex2, ex3)) { fprintf (stderr, "Error in ddefour test.\n"); - printf ("ex2="); mpfr_print_raw (ex2); putchar ('\n'); - printf ("ex3="); mpfr_print_raw (ex3); putchar ('\n'); + printf ("ex2="); mpfr_print_binary (ex2); putchar ('\n'); + printf ("ex3="); mpfr_print_binary (ex3); putchar ('\n'); exit (1); } @@ -318,11 +318,11 @@ check_two_sum (mp_prec_t p) { fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, mpfr_print_rnd_mode (rnd)); - printf ("x="); mpfr_print_raw(x); putchar('\n'); - printf ("y="); mpfr_print_raw(y); putchar('\n'); - printf ("u="); mpfr_print_raw(u); putchar('\n'); - printf ("v="); mpfr_print_raw(v); putchar('\n'); - printf ("w="); mpfr_print_raw(w); putchar('\n'); + printf ("x="); mpfr_print_binary(x); putchar('\n'); + printf ("y="); mpfr_print_binary(y); putchar('\n'); + printf ("u="); mpfr_print_binary(u); putchar('\n'); + printf ("v="); mpfr_print_binary(v); putchar('\n'); + printf ("w="); mpfr_print_binary(w); putchar('\n'); printf ("inexact = %d\n", inexact); exit (1); } @@ -336,7 +336,7 @@ check_two_sum (mp_prec_t p) #define MAX_PREC 100 void -check_inexact () +check_inexact (void) { mpfr_t x, y, z, u; mp_prec_t px, py, pu, pz; @@ -348,15 +348,15 @@ check_inexact () mpfr_init (z); mpfr_init (u); - for (px=1; px<MAX_PREC; px++) + for (px=2; px<MAX_PREC; px++) { mpfr_set_prec (x, px); mpfr_random (x); - for (pu=1; pu<MAX_PREC; pu++) + for (pu=2; pu<MAX_PREC; pu++) { mpfr_set_prec (u, pu); mpfr_random (u); - for (py=1; py<MAX_PREC; py++) + for (py=2; py<MAX_PREC; py++) { mpfr_set_prec (y, py); pz = (mpfr_cmp_abs (x, u) >= 0) ? MPFR_EXP(x)-MPFR_EXP(u) @@ -380,10 +380,10 @@ check_inexact () fprintf (stderr, "Wrong inexact flag for rnd=%s\n", mpfr_print_rnd_mode(rnd)); printf ("expected %d, got %d\n", cmp, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("u="); mpfr_print_raw (u); putchar ('\n'); - printf ("y= "); mpfr_print_raw (y); putchar ('\n'); - printf ("x-u="); mpfr_print_raw (z); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("u="); mpfr_print_binary (u); putchar ('\n'); + printf ("y= "); mpfr_print_binary (y); putchar ('\n'); + printf ("x-u="); mpfr_print_binary (z); putchar ('\n'); exit (1); } } @@ -398,7 +398,7 @@ check_inexact () } int -main() +main(void) { mp_prec_t p; unsigned i; @@ -407,7 +407,7 @@ main() check_inexact (); bug_ddefour (); - for (p=1; p<200; p++) + for (p=2; p<200; p++) for (i=0; i<200; i++) check_two_sum (p); diff --git a/mpfr/tests/tsub_ui.c b/mpfr/tests/tsub_ui.c index e0c4974e3..5436f3b17 100644 --- a/mpfr/tests/tsub_ui.c +++ b/mpfr/tests/tsub_ui.c @@ -99,10 +99,10 @@ check_two_sum (mp_prec_t p) fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, mpfr_print_rnd_mode (rnd)); printf ("x=%u\n", x); - printf ("y="); mpfr_print_raw(y); putchar('\n'); - printf ("u="); mpfr_print_raw(u); putchar('\n'); - printf ("v="); mpfr_print_raw(v); putchar('\n'); - printf ("w="); mpfr_print_raw(w); putchar('\n'); + printf ("y="); mpfr_print_binary(y); putchar('\n'); + printf ("u="); mpfr_print_binary(u); putchar('\n'); + printf ("v="); mpfr_print_binary(v); putchar('\n'); + printf ("w="); mpfr_print_binary(w); putchar('\n'); printf ("inexact = %d\n", inexact); exit (1); } @@ -141,7 +141,7 @@ main (int argc, char *argv[]) } #endif - for (p=1; p<200; p++) + for (p=2; p<200; p++) for (k=0; k<200; k++) check_two_sum (p); check3(0.9999999999, 1, GMP_RNDN, -1.000000082740370999e-10); diff --git a/mpfr/tests/ttan.c b/mpfr/tests/ttan.c index b74a72a7f..eb2cf3859 100644 --- a/mpfr/tests/ttan.c +++ b/mpfr/tests/ttan.c @@ -61,17 +61,17 @@ main(int argc, char *argv[]) check53(-1.0/0.0, 0.0/0.0, GMP_RNDN); mpfr_init (x); - mpfr_set_prec (x, 1); + mpfr_set_prec (x, 2); mpfr_set_d (x, 0.5, GMP_RNDN); mpfr_tan (x, x, GMP_RNDD); - if (mpfr_get_d(x) != 0.50) + if (mpfr_get_d(x) != 0.5) { fprintf (stderr, "mpfr_tan(0.5, GMP_RNDD) failed\n"); exit (1); } mpfr_clear (x); - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/ttanh.c b/mpfr/tests/ttanh.c index d89a69d5f..0a1fad746 100644 --- a/mpfr/tests/ttanh.c +++ b/mpfr/tests/ttanh.c @@ -32,7 +32,7 @@ MA 02111-1307, USA. */ int main (int argc, char *argv[]) { - test_generic (1, 100, 100); + test_generic (2, 100, 100); return 0; } diff --git a/mpfr/tests/ttrunc.c b/mpfr/tests/ttrunc.c index 754dce02b..1f5338409 100644 --- a/mpfr/tests/ttrunc.c +++ b/mpfr/tests/ttrunc.c @@ -64,9 +64,9 @@ main (void) for (j=0;j<1000;j++) { mpfr_random(x); - MPFR_EXP(x) = 1; + MPFR_EXP(x) = 2; - for (k = 1; k <= SIZEX; k++) + for (k = 2; k <= SIZEX; k++) { mpfr_set_prec(y, k); mpfr_set_prec(y2, k); @@ -86,9 +86,9 @@ main (void) if (!mpfr_eq(y, y2, k)) { - printf("Error in floor, x = "); mpfr_print_raw(x); printf("\n"); - printf("floor(x) = "); mpfr_print_raw(y); printf("\n"); - printf("round(x, RNDD) = "); mpfr_print_raw(y2); printf("\n"); + 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"); mpfr_clear(x); mpfr_clear(y); mpfr_clear(y2); @@ -101,9 +101,9 @@ main (void) if (!mpfr_eq(z, z2, k)) { - printf("Error in trunc, x = "); mpfr_print_raw(x); printf("\n"); - printf("trunc(x) = "); mpfr_print_raw(z); printf("\n"); - printf("round(x, RNDZ) = "); mpfr_print_raw(z2); printf("\n"); + 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"); mpfr_clear(x); mpfr_clear(y); mpfr_clear(y2); @@ -116,9 +116,9 @@ main (void) if (!mpfr_eq(y, y2, k)) { - printf("Error in ceil, x = "); mpfr_print_raw(x); printf("\n"); - printf("ceil(x) = "); mpfr_print_raw(t); printf("\n"); - printf("round(x, RNDU) = "); mpfr_print_raw(t2); printf("\n"); + 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"); mpfr_clear(x); mpfr_clear(y); mpfr_clear(y2); diff --git a/mpfr/tests/tui_div.c b/mpfr/tests/tui_div.c index e6af5f3a5..7b1df1bad 100644 --- a/mpfr/tests/tui_div.c +++ b/mpfr/tests/tui_div.c @@ -58,7 +58,7 @@ check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1) } void -check_inexact () +check_inexact (void) { mpfr_t x, y, z; mp_prec_t px, py; @@ -70,12 +70,12 @@ check_inexact () mpfr_init (y); mpfr_init (z); - for (px=1; px<300; px++) + for (px=2; px<300; px++) { mpfr_set_prec (x, px); mpfr_random (x); u = lrand48 (); - for (py=1; py<300; py++) + for (py=2; py<300; py++) { mpfr_set_prec (y, py); mpfr_set_prec (z, py + px); @@ -95,9 +95,9 @@ check_inexact () fprintf (stderr, "Wrong inexact flag for u=%lu, rnd=%s\n", u, mpfr_print_rnd_mode(rnd)); printf ("expected %d, got %d\n", cmp, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("y*x="); mpfr_print_raw (z); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("y*x="); mpfr_print_binary (z); putchar ('\n'); exit (1); } } diff --git a/mpfr/tests/tui_pow.c b/mpfr/tests/tui_pow.c index 6b2f023e7..058c5b1c7 100644 --- a/mpfr/tests/tui_pow.c +++ b/mpfr/tests/tui_pow.c @@ -38,13 +38,14 @@ main (int argc, char *argv[]) mpfr_init (x); mpfr_init (y); - n=abs(random()); + n = abs(random()); + MPFR_CLEAR_NAN(x); MPFR_SET_INF(x); - mpfr_ui_pow (y, n,x, GMP_RNDN); + mpfr_ui_pow (y, n, x, GMP_RNDN); if(!MPFR_IS_INF(y)) { - printf ("evaluation of function in INF does not return INF"); + printf ("evaluation of function in INF does not return INF\n"); exit (1); } @@ -71,7 +72,7 @@ main (int argc, char *argv[]) int inexact, compare, compare2; unsigned int n, err; - int p0=1; + int p0=2; int p1=100; int N=100; @@ -113,7 +114,7 @@ main (int argc, char *argv[]) mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); putchar ('\n'); printf ("approx "); - mpfr_print_raw (y); + mpfr_print_binary (y); putchar ('\n'); exit (1); } @@ -130,9 +131,9 @@ main (int argc, char *argv[]) { fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", mpfr_print_rnd_mode (rnd), compare, inexact); - printf ("x="); mpfr_print_raw (x); putchar ('\n'); - printf ("y="); mpfr_print_raw (y); putchar ('\n'); - printf ("t="); mpfr_print_raw (t); putchar ('\n'); + printf ("x="); mpfr_print_binary (x); putchar ('\n'); + printf ("y="); mpfr_print_binary (y); putchar ('\n'); + printf ("t="); mpfr_print_binary (t); putchar ('\n'); exit (1); } } diff --git a/mpfr/tests/tui_sub.c b/mpfr/tests/tui_sub.c index 6e8ccbdda..c51a48207 100644 --- a/mpfr/tests/tui_sub.c +++ b/mpfr/tests/tui_sub.c @@ -33,7 +33,7 @@ void check _PROTO ((unsigned long, double, mp_rnd_t, double)); void check_two_sum _PROTO ((mp_prec_t)); void -special () +special (void) { mpfr_t x, y, res; int inexact; @@ -186,10 +186,10 @@ check_two_sum (mp_prec_t p) fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, mpfr_print_rnd_mode (rnd)); printf ("x=%u\n", x); - printf ("y="); mpfr_print_raw(y); putchar('\n'); - printf ("u="); mpfr_print_raw(u); putchar('\n'); - printf ("v="); mpfr_print_raw(v); putchar('\n'); - printf ("w="); mpfr_print_raw(w); putchar('\n'); + printf ("y="); mpfr_print_binary(y); putchar('\n'); + printf ("u="); mpfr_print_binary(u); putchar('\n'); + printf ("v="); mpfr_print_binary(v); putchar('\n'); + printf ("w="); mpfr_print_binary(w); putchar('\n'); printf ("inexact = %d\n", inexact); exit (1); } @@ -230,7 +230,7 @@ main (int argc, char *argv[]) } #endif special (); - for (p=1; p<100; p++) + for (p=2; p<100; p++) for (k=0; k<100; k++) check_two_sum (p); check(1, 1.0/0.0, GMP_RNDN, -1.0/0.0); diff --git a/mpfr/trunc.c b/mpfr/trunc.c deleted file mode 100644 index 63af13808..000000000 --- a/mpfr/trunc.c +++ /dev/null @@ -1,186 +0,0 @@ -/* mpf_trunc, mpf_floor, mpf_ceil -- Assign a float from another float while - rounding it to an integer. - -Copyright (C) 1999, 2001 Free Software Foundation, Inc. - -This file is part of the MPFR Library. - -The MPFR Library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or (at your -option) any later version. - -The MPFR Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with the MPFR Library; see the file COPYING.LIB. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA. */ - -#include <stdio.h> -#include "gmp.h" -#include "gmp-impl.h" -#include "mpfr.h" -#include "mpfr-impl.h" - -#if ! defined (MPFR_FLOOR) && ! defined (MPFR_CEIL) -#define MPFR_TRUNC 1 -#endif - -#if MPFR_FLOOR -#define _MPFR_FLOOR_OR_CEIL -#define FUNC_NAME mpfr_floor -#undef MPFR_FLOOR -#define MPFR_FLOOR 1 -#define MPFR_CEIL 0 -#endif - -#if MPFR_CEIL -#define _MPFR_FLOOR_OR_CEIL -#define FUNC_NAME mpfr_ceil -#undef MPFR_CEIL -#define MPFR_CEIL 1 -#define MPFR_FLOOR 0 -#endif - -#if MPFR_TRUNC -#undef FUNC_NAME -#define FUNC_NAME mpfr_trunc -#endif - -#ifdef _MPFR_FLOOR_OR_CEIL -static int -mpn_zero_p (p, n) - mp_ptr p; - mp_size_t n; -{ - mp_size_t i; - - for (i = 0; i < n; i++) - { - if (p[i] != 0) - return 0; - } - - return 1; -} -#endif - -void -FUNC_NAME (mpfr_ptr r, mpfr_srcptr u) -{ - mp_ptr rp, up; - mp_size_t usize; - mp_size_t rsize, rw; -#ifdef _MPFR_FLOOR_OR_CEIL - mp_size_t ignored_n; -#endif - mp_exp_t exp; - int signu; long diff; - - if (MPFR_IS_NAN(u)) { - MPFR_SET_NAN(r); - return; - } - - MPFR_CLEAR_NAN(r); - - if (MPFR_IS_INF(u)) { - MPFR_SET_INF(r); - if (MPFR_SIGN(r) != MPFR_SIGN(u)) MPFR_CHANGE_SIGN(r); - return; - } - - MPFR_CLEAR_INF(r); - - if (!MPFR_NOTZERO(u)) { - MPFR_SET_ZERO(r); - return; - } - - signu = MPFR_SIZE(u); - rp = MPFR_MANT(r); - exp = MPFR_EXP(u); - rsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1; - - /* Single out the case where |u| < 1. */ - if (exp <= 0) - { -#ifdef _MPFR_FLOOR_OR_CEIL - if ((MPFR_FLOOR && signu < 0) || (MPFR_CEIL && signu >= 0)) - { - rp[rsize-1] = MP_LIMB_T_HIGHBIT; - MPN_ZERO(rp, rsize-1); - /* sign of result is that of u */ - if (MPFR_SIGN(r) * signu < 0) MPFR_CHANGE_SIGN(r); - MPFR_EXP(r) = 1; - return; - } -#endif - MPFR_SET_ZERO(r); - return; - } - - usize = (MPFR_PREC(u) - 1)/BITS_PER_MP_LIMB + 1; - -#ifdef _MPFR_FLOOR_OR_CEIL - ignored_n = 0; -#endif - up = MPFR_MANT(u); - - if (usize > rsize) - { -#ifdef _MPFR_FLOOR_OR_CEIL - ignored_n = usize - rsize; -#endif - up += usize - rsize; - usize = rsize; - } - - diff = BITS_PER_MP_LIMB * usize - exp; - if (diff > 0) - { - diff = diff/BITS_PER_MP_LIMB; -#ifdef _MPFR_FLOOR_OR_CEIL - ignored_n += diff; -#endif - up += diff; - usize -= diff; - } - - /* number of non significant bits in low limb of r */ - rw = usize * BITS_PER_MP_LIMB - exp; - MPN_ZERO(rp, rsize-usize); - rp += rsize-usize; - -#ifdef _MPFR_FLOOR_OR_CEIL - if (((MPFR_FLOOR && signu < 0) || (MPFR_CEIL && signu >= 0)) - && (!mpn_zero_p (up - ignored_n, ignored_n) - || (rw && (up[0] << (BITS_PER_MP_LIMB-rw))))) - { - mp_limb_t cy; - cy = mpn_add_1 (rp, up, usize, MP_LIMB_T_ONE << rw); - if (cy != 0) - { - /* all the bits from "1<<rw" upwards are zero */ - rp[usize-1] = MP_LIMB_T_HIGHBIT; - exp++; - } - } - else -#endif - { - if (rp != up) - MPN_COPY (rp, up, usize); - } - - /* Put to 0 the remaining bits */ - if (rw) rp[0] &= - ~((MP_LIMB_T_ONE << rw) - MP_LIMB_T_ONE); - - MPFR_EXP(r) = exp; - if (MPFR_SIGN(r) * signu < 0) MPFR_CHANGE_SIGN(r); -} diff --git a/mpfr/ui_pow.c b/mpfr/ui_pow.c index ac3cb52dd..a247166fe 100644 --- a/mpfr/ui_pow.c +++ b/mpfr/ui_pow.c @@ -1,6 +1,6 @@ /* mpfr_ui_pow -- power of n function n^x -Copyright (C) 2001 Free Software Foundation, Inc. +Copyright (C) 2001-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -31,14 +31,14 @@ MA 02111-1307, USA. */ */ int -mpfr_ui_pow (mpfr_ptr y, unsigned long int n,mpfr_srcptr x, mp_rnd_t rnd_mode) -{ +mpfr_ui_pow (mpfr_ptr y, unsigned long int n, mpfr_srcptr x, mp_rnd_t rnd_mode) +{ int inexact; if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); - return 1; + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); @@ -47,22 +47,19 @@ mpfr_ui_pow (mpfr_ptr y, unsigned long int n,mpfr_srcptr x, mp_rnd_t rnd_mode) { if (MPFR_SIGN(x) < 0) { + MPFR_CLEAR_INF(y); MPFR_SET_ZERO(y); - if (MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 0; } else { MPFR_SET_INF(y); - if(MPFR_SIGN(y) < 0) - MPFR_CHANGE_SIGN(y); - return 0; } + MPFR_SET_POS(y); + MPFR_RET(0); } /* n^0 = 1 */ - if(mpfr_cmp_ui(x,0)==0) + if (MPFR_IS_ZERO(x)) { return mpfr_set_ui(y,1,rnd_mode); } diff --git a/mpfr/ui_pow_ui.c b/mpfr/ui_pow_ui.c index 494d7c44d..07f52472c 100644 --- a/mpfr/ui_pow_ui.c +++ b/mpfr/ui_pow_ui.c @@ -1,6 +1,6 @@ /* mpfr_ui_pow_ui -- compute the power beetween two machine integer -Copyright (C) 1999, 2001 Free Software Foundation, Inc. +Copyright (C) 1999-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,17 +19,15 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-impl.h" - int mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n, - mp_rnd_t rnd) + mp_rnd_t rnd) { - long int i, err; + long int err; unsigned long m; mpfr_t res; mp_prec_t prec; @@ -37,20 +35,24 @@ mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n, MPFR_CLEAR_FLAGS(x); - if (n == 0) /* x^0 = 1 for any x */ - { - mpfr_set_ui (x, 1, rnd); - return 0; - } + if (n == 0) /* y^0 = 1 for any y */ + return mpfr_set_ui (x, 1, rnd); + if (y == 0) /* 0^n = 0 for any n > 0 */ + return mpfr_set_ui (x, 0, rnd); + + mpfr_save_emin_emax (); mpfr_init (res); prec = MPFR_PREC(x); do { + int i; + prec += 3; - for (m=n, i=0; m; i++, m>>=1, prec++); + for (i = 0, m = n; m; i++, m >>= 1) + prec++; mpfr_set_prec (res, prec); inexact = mpfr_set_ui (res, y, GMP_RNDU); err = 1; @@ -69,12 +71,12 @@ mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n, err = 0; } while (inexact && (mpfr_can_round (res, err, - (MPFR_SIGN(res) > 0) ? GMP_RNDU : GMP_RNDD, rnd, MPFR_PREC(x)) == 0)); + MPFR_SIGN(res) > 0 ? GMP_RNDU : GMP_RNDD, rnd, MPFR_PREC(x)) == 0)); if (mpfr_set (x, res, rnd)) inexact = 1; mpfr_clear (res); - return inexact; + MPFR_RESTORE_RET(inexact, x, rnd); } diff --git a/mpfr/ui_sub.c b/mpfr/ui_sub.c index 144a9b942..65e96456c 100644 --- a/mpfr/ui_sub.c +++ b/mpfr/ui_sub.c @@ -1,6 +1,6 @@ -/* mpfr_ui_sub -- divide a machine integer by a floating-point number +/* mpfr_ui_sub -- subtract a floating-point number from an integer -Copyright (C) 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 2000-2002 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -19,7 +19,6 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" @@ -36,7 +35,7 @@ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_IS_NAN(x)) { MPFR_SET_NAN(y); - return 1; /* a NaN is inexact */ + MPFR_RET_NAN; } MPFR_CLEAR_NAN(y); @@ -46,7 +45,7 @@ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mp_rnd_t rnd_mode) MPFR_SET_INF(y); if (MPFR_SIGN(x) == MPFR_SIGN(y)) MPFR_CHANGE_SIGN(y); - return 0; /* +/-infinity is exact */ + MPFR_RET(0); /* +/-infinity is exact */ } if (u) { |