summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Ryde <user42@zip.com.au>2003-01-03 01:07:42 +0100
committerKevin Ryde <user42@zip.com.au>2003-01-03 01:07:42 +0100
commit67119c6ac0a54e762dbfd855a808c8de8c8b2f9d (patch)
tree992a5d93e830607ebd5220704efb887c86411f08
parent67bc637ee70b73d8b1fa788003a28af59adb8663 (diff)
downloadgmp-67119c6ac0a54e762dbfd855a808c8de8c8b2f9d.tar.gz
* mpfr/*: Update to mpfr cvs 2003-01-03.
-rw-r--r--mpfr/BUGS25
-rw-r--r--mpfr/ChangeLog826
-rw-r--r--mpfr/Makefile.am2
-rw-r--r--mpfr/Makefile.in173
-rw-r--r--mpfr/README11
-rw-r--r--mpfr/TODO177
-rw-r--r--mpfr/acinclude.m422
-rw-r--r--mpfr/acos.c4
-rw-r--r--mpfr/acosh.c78
-rw-r--r--mpfr/add.c2
-rw-r--r--mpfr/add1.c26
-rw-r--r--mpfr/add_one_ulp.c8
-rw-r--r--mpfr/add_ui.c5
-rw-r--r--mpfr/agm.c32
-rw-r--r--mpfr/asin.c4
-rw-r--r--mpfr/asinh.c137
-rw-r--r--mpfr/atan.c16
-rw-r--r--mpfr/atanh.c4
-rw-r--r--mpfr/cbrt.c148
-rw-r--r--mpfr/cmp2.c2
-rw-r--r--mpfr/cmp_abs.c17
-rw-r--r--mpfr/cmp_si.c93
-rw-r--r--mpfr/cmp_ui.c113
-rw-r--r--mpfr/comparisons.c71
-rw-r--r--mpfr/const_euler.c4
-rw-r--r--mpfr/const_log2.c20
-rw-r--r--mpfr/const_pi.c22
-rw-r--r--mpfr/cos.c2
-rw-r--r--mpfr/cosh.c2
-rw-r--r--mpfr/div.c10
-rw-r--r--mpfr/div_2si.c21
-rw-r--r--mpfr/div_2ui.c21
-rw-r--r--mpfr/div_ui.c3
-rw-r--r--mpfr/dump.c4
-rw-r--r--mpfr/exceptions.c93
-rw-r--r--mpfr/exp.c39
-rw-r--r--mpfr/exp2.c10
-rw-r--r--mpfr/exp3.c8
-rw-r--r--mpfr/exp_2.c10
-rw-r--r--mpfr/expm1.c4
-rw-r--r--mpfr/factorial.c4
-rw-r--r--mpfr/frac.c121
-rw-r--r--mpfr/gamma.c217
-rw-r--r--mpfr/generic.c2
-rw-r--r--mpfr/get_d.c5
-rw-r--r--mpfr/get_exp.c (renamed from mpfr/tests/dummy.c)14
-rw-r--r--mpfr/get_ld.c121
-rw-r--r--mpfr/get_str.c997
-rw-r--r--mpfr/get_z_exp.c8
-rw-r--r--mpfr/hypot.c147
-rw-r--r--mpfr/init.c4
-rw-r--r--mpfr/init2.c3
-rw-r--r--mpfr/inp_str.c10
-rw-r--r--mpfr/isinteger.c39
-rw-r--r--mpfr/isnum.c4
-rw-r--r--mpfr/log.c8
-rw-r--r--mpfr/log10.c2
-rw-r--r--mpfr/log1p.c4
-rw-r--r--mpfr/log2.c2
-rw-r--r--mpfr/mpf2mpfr.h72
-rw-r--r--mpfr/mpfr-impl.h71
-rw-r--r--mpfr/mpfr-math.h77
-rw-r--r--mpfr/mpfr-test.h115
-rw-r--r--mpfr/mpfr.h64
-rw-r--r--mpfr/mpfr.texi597
-rw-r--r--mpfr/mul.c88
-rw-r--r--mpfr/mul_2si.c27
-rw-r--r--mpfr/mul_2ui.c4
-rw-r--r--mpfr/mul_ui.c7
-rw-r--r--mpfr/next.c150
-rw-r--r--mpfr/out_str.c2
-rw-r--r--mpfr/pow.c159
-rw-r--r--mpfr/pow_si.c2
-rw-r--r--mpfr/powerof2.c (renamed from mpfr/rnd_mode.c)35
-rw-r--r--mpfr/print_raw.c4
-rw-r--r--mpfr/random.c27
-rw-r--r--mpfr/random2.c25
-rw-r--r--mpfr/rint.c12
-rw-r--r--mpfr/round_prec.c4
-rw-r--r--mpfr/save_expo.c18
-rw-r--r--mpfr/set.c41
-rw-r--r--mpfr/set_d.c27
-rw-r--r--mpfr/set_dfl_prec.c6
-rw-r--r--mpfr/set_exp.c39
-rw-r--r--mpfr/set_ld.c141
-rw-r--r--mpfr/set_nan.c2
-rw-r--r--mpfr/set_prec.c6
-rw-r--r--mpfr/set_q.c5
-rw-r--r--mpfr/set_rnd.c4
-rw-r--r--mpfr/set_si.c11
-rw-r--r--mpfr/set_str.c128
-rw-r--r--mpfr/set_str_raw.c4
-rw-r--r--mpfr/set_ui.c9
-rw-r--r--mpfr/set_z.c50
-rw-r--r--mpfr/setmax.c44
-rw-r--r--mpfr/setmin.c41
-rw-r--r--mpfr/sin.c84
-rw-r--r--mpfr/sin_cos.c4
-rw-r--r--mpfr/sinh.c4
-rw-r--r--mpfr/sqrt.c4
-rw-r--r--mpfr/sqrt_ui.c4
-rw-r--r--mpfr/strcasecmp.c35
-rw-r--r--mpfr/strncasecmp.c59
-rw-r--r--mpfr/sub.c4
-rw-r--r--mpfr/sub1.c34
-rw-r--r--mpfr/sub_one_ulp.c10
-rw-r--r--mpfr/sub_ui.c4
-rw-r--r--mpfr/tan.c2
-rw-r--r--mpfr/tanh.c4
-rw-r--r--mpfr/tests/Makefile.am4
-rw-r--r--mpfr/tests/Makefile.in142
-rw-r--r--mpfr/tests/memory.c185
-rw-r--r--mpfr/tests/reuse.c5
-rw-r--r--mpfr/tests/rnd_mode.c79
-rw-r--r--mpfr/tests/tabs.c6
-rw-r--r--mpfr/tests/tacos.c5
-rw-r--r--mpfr/tests/tacosh.c5
-rw-r--r--mpfr/tests/tadd.c186
-rw-r--r--mpfr/tests/tadd_ui.c26
-rw-r--r--mpfr/tests/tagm.c24
-rw-r--r--mpfr/tests/tasin.c3
-rw-r--r--mpfr/tests/tasinh.c5
-rw-r--r--mpfr/tests/tatan.c3
-rw-r--r--mpfr/tests/tatanh.c5
-rw-r--r--mpfr/tests/tcan_round.c4
-rw-r--r--mpfr/tests/tcbrt.c96
-rw-r--r--mpfr/tests/tcmp.c3
-rw-r--r--mpfr/tests/tcmp2.c2
-rw-r--r--mpfr/tests/tcmp_ui.c6
-rw-r--r--mpfr/tests/tconst_euler.c4
-rw-r--r--mpfr/tests/tconst_log2.c8
-rw-r--r--mpfr/tests/tconst_pi.c6
-rw-r--r--mpfr/tests/tcos.c3
-rw-r--r--mpfr/tests/tcosh.c5
-rw-r--r--mpfr/tests/tdiv.c57
-rw-r--r--mpfr/tests/tdiv_ui.c21
-rw-r--r--mpfr/tests/tdump.c4
-rw-r--r--mpfr/tests/teq.c4
-rw-r--r--mpfr/tests/tests.c178
-rw-r--r--mpfr/tests/texceptions.c10
-rw-r--r--mpfr/tests/texp.c45
-rw-r--r--mpfr/tests/texp2.c5
-rw-r--r--mpfr/tests/texpm1.c5
-rw-r--r--mpfr/tests/tfactorial.c4
-rw-r--r--mpfr/tests/tfma.c6
-rw-r--r--mpfr/tests/tfrac.c185
-rw-r--r--mpfr/tests/tgamma.c103
-rw-r--r--mpfr/tests/tget_d.c95
-rw-r--r--mpfr/tests/tget_str.c383
-rw-r--r--mpfr/tests/thyperbolic.c3
-rw-r--r--mpfr/tests/thypot.c46
-rw-r--r--mpfr/tests/tisnan.c4
-rw-r--r--mpfr/tests/tlog.c27
-rw-r--r--mpfr/tests/tlog10.c3
-rw-r--r--mpfr/tests/tlog1p.c5
-rw-r--r--mpfr/tests/tlog2.c5
-rw-r--r--mpfr/tests/tmul.c44
-rw-r--r--mpfr/tests/tmul_2exp.c3
-rw-r--r--mpfr/tests/tmul_ui.c3
-rw-r--r--mpfr/tests/tout_str.c63
-rw-r--r--mpfr/tests/tpow.c72
-rw-r--r--mpfr/tests/tpow3.c6
-rw-r--r--mpfr/tests/trandom.c68
-rw-r--r--mpfr/tests/trint.c3
-rw-r--r--mpfr/tests/tround_prec.c4
-rw-r--r--mpfr/tests/tset.c6
-rw-r--r--mpfr/tests/tset_d.c6
-rw-r--r--mpfr/tests/tset_f.c3
-rw-r--r--mpfr/tests/tset_ld.c144
-rw-r--r--mpfr/tests/tset_q.c27
-rw-r--r--mpfr/tests/tset_si.c3
-rw-r--r--mpfr/tests/tset_str.c27
-rw-r--r--mpfr/tests/tset_z.c3
-rw-r--r--mpfr/tests/tsin.c51
-rw-r--r--mpfr/tests/tsinh.c5
-rw-r--r--mpfr/tests/tsqrt.c62
-rw-r--r--mpfr/tests/tsqrt_ui.c44
-rw-r--r--mpfr/tests/tsub.c22
-rw-r--r--mpfr/tests/tsub_ui.c28
-rw-r--r--mpfr/tests/tswap.c6
-rw-r--r--mpfr/tests/ttan.c3
-rw-r--r--mpfr/tests/ttanh.c5
-rw-r--r--mpfr/tests/ttrunc.c6
-rw-r--r--mpfr/tests/tui_div.c26
-rw-r--r--mpfr/tests/tui_pow.c13
-rw-r--r--mpfr/tests/tui_sub.c29
-rw-r--r--mpfr/uceil_exp2.c4
-rw-r--r--mpfr/uceil_log2.c4
-rw-r--r--mpfr/ufloor_log2.c4
-rw-r--r--mpfr/ui_div.c3
-rw-r--r--mpfr/ui_pow.c105
-rw-r--r--mpfr/ui_pow_ui.c4
-rw-r--r--mpfr/ui_sub.c19
-rw-r--r--mpfr/urandomb.c31
194 files changed, 6766 insertions, 2562 deletions
diff --git a/mpfr/BUGS b/mpfr/BUGS
index a17393680..d013e482a 100644
--- a/mpfr/BUGS
+++ b/mpfr/BUGS
@@ -4,12 +4,29 @@ Known bugs:
* The overflows/underflows are not yet implemented in all functions.
+* problem with tsqrt on ia64-hpux (problem is that variable a in check4 has
+ a different value than in the call, may be a memory problem, since
+ it disappears when we remove the mpfr_set_str instruction, and
+ disappears without -O2)
+mpfr_sqrt failed for a=4.15383748682786210282e+34, rnd_mode=GMP_RNDZ
+expected 0.10010010111100001100100110000001011110111111001010000[00000000000]E53
+got 0.10110101000001001111001100110011111110011101111001100[00000000000]E58
+
+* texp fails on ia64-hpux: mpfr_exp_2 and mpfr_exp3 for prec=601
+
+* acosh is wrong near EMAX (idem asinh):
+ rounding mode GMP_RNDU:
+ 6096987078287.281250 ulp(s) for x=1.75062535692767808555e+308
+ [mpfr: 7.097561817130842e2 libm: 7.10449328893644064919e+02]
+
+Potential bugs:
+
* Possible integer overflows on some machines.
* mpfr_set_d may give wrong results on some architectures.
-Potential bugs:
+* Error analysis in mpfr_sin is incorrect. A test has been added to
+ show the bug. Check the other functions too...
-* get_str.c: condition len != n + 1 is always satisfied at the end.
- This means that there are too many reallocations (possibly useless
- ones) and a possible bug.
+* mpfr_hypot may fail for x very large, y very small and a very large
+ target precision.
diff --git a/mpfr/ChangeLog b/mpfr/ChangeLog
index 96bc11467..a4086901c 100644
--- a/mpfr/ChangeLog
+++ b/mpfr/ChangeLog
@@ -1,14 +1,830 @@
-2002-04-15 Vincent Lefevre <lefevre@greux.loria.fr>
+2002-12-13 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mpfr.texi: IEEE 754 / IEEE P754 -> IEEE 754-1985.
+
+ * mpfr.texi: Correction.
+
+ * mpfr.texi: Added a note about the signed zero.
+
+ * set_d.c: Assertion re-added.
+
+ * missing: Update for new version of automake/autoconf.
+
+ * depcomp: depcomp script added for new version of automake.
+
+2002-12-12 Kevin Ryde <user42@zip.com.au>
+
+ * configure.in:
+ Don't -D define PACKAGE_VERSION etc, to avoid conflict with gmp config.h.
+
+2002-12-12 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr.texi: added paragraph about accuracy
+
+ * mpfr.texi: rewritten unclear paragraph about precision
+
+ * TODO: added one item
+
+ * set_d.c: use MPN_NORMALIZE_NOT_ZERO instead of loop
+
+2002-12-11 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * tests/memory.c:
+ Added #include "mpfr.h" (needed by mpfr-test.h as it uses
+ mp_rnd_t in one of the prototypes).
+
+2002-12-10 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * set_d.c:
+ Patch by Torbjorn Granlund <tege@swox.com>: Don't use TMP_ allocation
+ mechanism for fixed size objects. Resulting streamlining. Misc
+ addressing changes to work around GNUPro bugs.
+ Patch by VL: Some other changes in mpfr_set_d.
+
+2002-12-07 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * const_euler.c: (mpfr_const_euler_S, mpfr_const_euler_R)
+ Make declaration match prototype (patch by Torbjorn Granlund).
+
+2002-12-04 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * config.guess, config.sub:
+ Update from ftp://ftp.gnu.org/pub/gnu/config/
+
+2002-12-03 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr.texi: Use @ifnottex/@end iffnotex instead of @ifinfo/@end ifinfo
+
+2002-12-02 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mpfr-test.h, tests/rnd_mode.c: Fix rnd_mode.c (again).
+
+2002-12-02 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr-impl.h, mpfr.h:
+ put redefinitions of external symbols just before prototypes
+
+ * TODO: updated
+
+ * BUGS: added new known bugs
+
+2002-11-29 Kevin Ryde <user42@zip.com.au>
+
+ * TODO: Add notes on mpf_t maintaining actual size for efficiency.
+
+ * TODO: Remove mpfr_set_machine_rnd_mode task.
+
+ * mpfr.texi: Tweak some math formatting for tex.
+
+ * mpfr-test.h, mpfr.h (mpfr_set_machine_rnd_mode):
+ Move prototype to mpfr-test.h.
+
+ * tests/Makefile.am (libfrtests_a_SOURCES): Add rnd_mode.c.
+
+ * Makefile.am (libmpfr_a_SOURCES): Remove rnd_mode.c.
+
+ * rnd_mode.c: Remove file, moved to tests directory.
+
+ * tests/rnd_mode.c: New file, moved from top-level directory.
+
+ * mpfr.texi (Rounding Modes): Remove mpfr_set_machine_rnd_mode.
+
+ * setmin.c, setmax.c: Use GNU style code layout.
+
+2002-11-29 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr-impl.h, mpfr.h:
+ redefined external symbols in the __gmpfr namespace
+
+2002-11-25 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/tout_str.c: added one fprintf in case of error
+
+2002-11-25 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mpfr.texi, rnd_mode.c, mpfr.h:
+ mpfr_set_machine_rnd_mode fixed to compile on some architectures
+ (e.g. ARM). Now returns an int.
+
+ * tests/tmul.c: Bug fixed.
+
+2002-11-25 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/tadd.c, tests/tadd_ui.c, tests/tagm.c, tests/tdiv.c, tests/tdiv_ui.c, tests/texp.c, tests/tget_d.c, tests/tlog.c, tests/tmul.c, tests/tset_q.c, tests/tsqrt.c, tests/tsqrt_ui.c, tests/tsub_ui.c, tests/tui_div.c, tests/tui_sub.c:
+ removed all tests that compare to libm
+
+ * tests/tdiv.c: changed to distinguish mpfr failures from libm failures
+
+ * tests/tdiv.c: added 3 tests that make libm fail under HP-PA
+
+2002-11-23 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * ChangeLog: Update.
+
+2002-11-22 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * ui_pow.c: forgot to remove debug statement
+
+ * pow.c, tests/tui_pow.c, ui_pow.c:
+ fixed bug (infinite loop) for exact powers
+
+2002-11-21 Kevin Ryde <user42@zip.com.au>
+
+ * TODO:
+ More on tuned thresholds, more on config.h etc, new section on mpf/mpfr
+ integration.
+
+2002-11-20 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * get_str.c: Code clean-up.
+
+2002-11-20 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * gamma.c, log.c, set_ld.c: fixed some problems found by insure
+
+ * tests/tout_str.c: forgotten fclose() call
+
+ * tests/tget_str.c: fixed array bound write
+
+2002-11-19 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * get_str.c: fixed non-ansi features
+
+ * div.c, div_ui.c: added explicit cast
+
+2002-10-24 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr.texi: added mpfr_cbrt
+
+2002-10-20 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * BUGS: Update.
+
+2002-10-20 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * sin.c: fixed bug with wrong sign detection
+
+2002-10-19 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * hypot.c: Some fixes to avoid overflows.
+
+2002-10-19 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * hypot.c: fixed bug for large arguments
+
+ * cbrt.c: improved code for rounding to nearest
+
+ * asinh.c: fixed bug for EXP(x) > EMAX/2
+
+ * algorithms.tex: modified description of hypot and cbrt
+
+ * acosh.c: fixed bug for EXP(x) > EMAX/2
+
+2002-10-18 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * BUGS: Update.
+
+ * tests/tsin.c: Added test showing bug in sign detection.
+
+ * tests/thypot.c: Added newline.
+
+ * BUGS: Bug in mpfr_hypot.
+
+ * tests/thypot.c: Added test that makes mpfr_hypot fail.
+
+ * hypot.c: Precision Nt: int -> mp_prec_t.
+
+ * tests/tcbrt.c: Added some tests.
+
+ * tests/tcbrt.c: main () -> main (void).
+
+2002-10-18 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/Makefile.am, tests/tcbrt.c:
+ added tcbrt.c, test file for mpfr_cbrt
+
+ * hypot.c: fixed overflow problem
+
+ * cbrt.c: completely rewritten using mpz_root
+
+ * Makefile.am: added cbrt
+
+2002-10-17 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mpfr.texi: C9X -> ISO/IEC 9899:1999 (ISO C99).
+
+ * set_ld.c: Cases NaN and -0.0 taken into account.
+
+2002-10-17 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/tset_ld.c: added check for +0 and -0
+
+ * tests/tset_ld.c: added one test (2^1024)
+
+ * set_ld.c: fixed bug when overflow for double type
+
+ * mpfr.texi: added mpfr_set_ld and mpfr_get_ld
+
+2002-10-16 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * get_ld.c: Fix for -0.0.
+
+2002-10-16 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * log_b2.h: constants for mpfr_get_str and mpfr_set_str
+
+2002-10-16 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * tests/tset_ld.c: Obsolete comment removed.
+
+ * Makefile.am: Removed log_b2.h as it doesn't seem to be necessary.
+
+2002-10-16 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr.h: added prototype for mpfr_get_ld
+
+ * Makefile.am, get_ld.c, tests/tset_ld.c:
+ added mpfr_get_ld and tests for set_ld/get_ld
+
+ * set_ld.c: added cast to long double
+
+2002-10-16 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * TODO: Update (tset_ld).
+
+ * tests/tset_ld.c:
+ Test removed as the minimal precision for a long double is something
+ like 10 decimal digits. Anyway, there are implementations for which
+ long double = double = IEEE double precision.
+
+ * set_ld.c:
+ DBL_MANT_DIG and LDBL_MANT_DIG are normally defined by <float.h>.
+
+2002-10-15 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * Makefile.am, mpfr.h, set_ld.c, tests/Makefile.am, tests/tset_ld.c:
+ added mpfr_set_ld and test file
+
+2002-10-13 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * BUGS: Bug in mpfr_sin (and perhaps other functions): error analysis.
+
+ * atan.c:
+ Bug fixed (found by Dmitrii Baksheyev): atan(1) cannot be exact.
+
+2002-10-08 Kevin Ryde <user42@zip.com.au>
+
+ * TODO: Remove mpfr_get_str using mpn_get_str (done).
+ Remove no grepping for __setfpucw, done (near enough).
+ New thread-safety section, add const_pi and const_log2 caching.
+ New portability section, add mingw random and _mpfr_ceil_log2 IEEE-ism.
+
+ * acinclude.m4 (AC_MY_LIBS): Show the filename in the error message.
+
+2002-10-04 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpf2mpfr.h: mpfr_get_default_prec was missing (thanks to F. Morain)
+
+2002-09-30 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * BUGS: Removed get_str.c bug, as the mpfr_get_str function has
+ completely been rewritten.
+
+2002-09-26 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * sub.c:
+ fixed wrong inexact flag for a - b where a and b are of different signs
+ and EXP(a) < EXP(b)
+
+ * tests/tsub.c: added test for inexact flag (bug found by Andreas Enge)
+
+2002-09-23 Kevin Ryde <user42@zip.com.au>
+
+ * mpfr.texi, set_prec.c, init2.c, init.c, mpfr.h (mpfr_init, mpfr_init2, mpfr_set_prec):
+ Make void return, these always
+ succeed.
+
+2002-09-23 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * urandomb.c: fixed various tiny problems
+
+ * tests/trandom.c:
+ added more tests for mpfr_urandomb, and for small precision
+
+ * random2.c, tests/trandom.c:
+ fixed bugs in mpfr_random2 (wrong exponent, invalid numbers)
+
+ * tests/trandom.c: added checks for mpfr_random2
+
+ * tests/tadd.c, tests/tsub.c, cmp_abs.c, mpfr.h, mpfr.texi, pow.c:
+ cmp_abs -> cmpabs (for compatibility with mpz)
+
+2002-09-21 Kevin Ryde <user42@zip.com.au>
+
+ * mpfr.texi (Converting Floats):
+ Don't refer to the internal _mp_free_func with
+ mpfr_get_str.
+
+ * mpfr.texi (Special Functions, Internals): Make these into nodes.
+
+2002-09-20 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * set_str.c: now accept uppercase letters too
+
+ * tests/tset_str.c: added test for uppercase letters
+
+2002-09-18 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * agm.c, mpfr.h, mpfr.texi: now mpfr_agm returns an int (inexact flag)
+
+2002-09-13 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * prepare, README.dev: Some more information.
+
+2002-09-12 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * configure.in:
+ On HP-UX, use the +allowunsats switch for ld, otherwise ld complains
+ that some GMP symbols are unsatisfied.
+
+2002-09-12 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/tgamma.c, gamma.c: fixed bug in reflection formula for x<1
+
+2002-08-23 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * INSTALL, mpfr.texi: MPFR now needs GMP 4.1 or higher.
+
+2002-08-22 Kevin Ryde <user42@zip.com.au>
+
+ * mpfr-math.h (__mpfr_nan): Clarify comments about HP C and alpha.
+
+ * mpfr-math.h: (_MPFR_NAN_BYTES, _MPFR_INFP_BYTES, _MPFR_INFM_BYTES):
+ Use HAVE_DOUBLE_IEEE_LITTLE_ENDIAN etc to select endianness, not a big
+ block of #ifdefs.
+
+2002-08-12 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * acinclude.m4, strcasecmp.c, strncasecmp.c:
+ strcasecmp.c -> strcasecmp.c & strncasecmp.c
+
+2002-08-07 Kevin Ryde <user42@zip.com.au>
+
+ * tests/Makefile.am:
+ Use $(top_builddir) consistently with libmpfr.a, for the benefit of
+ srcdir!=builddir.
+
+2002-08-02 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * configure.in:
+ Don't touch user specified flags (CFLAGS). [patch by Kevin Ryde]
+
+2002-07-30 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * acinclude.m4, mpfr-impl.h, set_str.c:
+ Better check for strcasecmp and strncasecmp. Bug fixed.
+
+2002-07-28 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * Makefile.am, TODO, comparisons.c, mpfr.h:
+ Functions mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p,
+ mpfr_lessequal_p, mpfr_lessgreater_p, mpfr_equal_p, mpfr_unordered_p.
+
+ * prepare, tests/Makefile.am, Makefile.am:
+ Use AUTOMAKE_OPTIONS = gnu [suggested by Kevin Ryde]
+
+ * tests/Makefile.am:
+ check target -> TESTS = $(check_PROGRAMS) [suggested by Kevin Ryde]
+
+ * mpfr-impl.h, strcasecmp.c:
+ strcasecmp and strncasecmp -> mpfr_strcasecmp and mpfr_strncasecmp
+ if they are provided by MPFR.
+
+ * get_str.c: TMP_MARK missing (patch by Kevin Ryde).
+
+2002-07-26 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * ChangeLog: Update.
+
+ * README, README.dev: Update (mainly concerning CVS use).
+
+ * TODO, exceptions.c, exp.c, mpfr-impl.h, next.c, setmax.c, setmin.c:
+ Prototype of mpfr_setmax and mpfr_setmin changed (exponent given).
+ In mpfr_exp for x ~= 0, add_one_ulp and sub_one_ulp are no longer
+ used (sub_one_ulp was incorrect). These cases should now be faster.
+ Small fix in mpfr_nextabove, mpfr_nextbelow and mpfr_nexttoward.
+
+ * next.c, setmax.c, setmin.c, sub_one_ulp.c, Makefile.am, TODO, exceptions.c, mpfr-impl.h, mpfr.h, mpfr.texi:
+ New internal functions mpfr_setmin and mpfr_setmax.
+ New functions mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward.
+ Small fix in mpfr_sub_one_ulp.
+
+2002-07-26 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * get_str.c:
+ improved the computation of g = ceil((e-1)/log_2(beta)), using two tables
+
+2002-07-25 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mpfr-impl.h, mpfr.texi, save_expo.c, set_q.c, sqrt_ui.c, sub_ui.c, ui_pow_ui.c, add_ui.c, exceptions.c:
+ Function mpfr_check_range now propagates the inexact ternary value.
+ Function mpfr_restore_emin_emax OR's the saved flags with the current
+ flags, as this is more useful in general.
+ Macro MPFR_RESTORE_RET removed (no longer useful).
+
+2002-07-24 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * frac.c: Change concerning an assertion, due to GMP limitation.
+
+2002-07-24 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/tout_str.c: gnu indentation
+
+ * tests/tgamma.c: reduce range of tests (did take too much time)
+
+ * tests/tget_str.c:
+ added plenty of new cases, now covers all lines of get_str.c
+
+ * mpfr.texi: updated documentation of mpfr_get_str
+
+ * get_str.c:
+ completely new version, written by Alain Delplanque and Paul Zimmermann.
+ It now directly uses mpn_get_str, with subquadratic complexity.
+ About 3 times faster than previous version in most cases.
+
+2002-07-24 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * frac.c:
+ Bug fixed: unsigned int variables changed to int to avoid operations
+ with mixed signed/unsigned variables and unwanted casts.
+
+ * Makefile.am, frac.c, mpfr.h, mpfr.texi, tests/Makefile.am, tests/tfrac.c:
+ Function mpfr_frac and tests added.
+
+ * set.c: Bug fixed (0 was forgotten).
+
+ * isinteger.c: Optimization: mpfr_trunc no longer used!
+
+ * isinteger.c: mpfr_isinteger extended to non-fp numbers and to zero.
+
+ * isnum.c: Simpler test.
+
+2002-07-23 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mul.c: Re-adding mul.c with fixed permissions.
+
+ * mul.c:
+ Temporarily removing mul.c in order to try to fix its permissions.
+
+ * mul.c: Fixed permissions.
+
+ * exceptions.c, mpfr-impl.h, mpfr.h, mpfr.texi, set_si.c, set_ui.c, tests/texceptions.c:
+ Function mpfr_check_range improved in the underflow case.
+
+2002-07-22 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * ChangeLog: Update.
+
+2002-07-22 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * dump.c: now dump in base 2
+
+ * tests/tget_str.c: forgot one free() call
+
+2002-07-22 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * BUGS: mpfr_pow bug removed.
+
+ * pow.c: Reindentation.
+
+ * pow.c, tests/tpow.c:
+ pow.c: bug fixed (in the call to mpfr_can_round).
+ tpow.c: mpfr_clear added.
- * set_d.c: Rewrite.
+ * tests/tpow.c: Modified the two tests to make the bug appear.
-2002-12-07 Torbjorn Granlund <tege@swox.com>
+2002-07-22 Paul Zimmermann <Paul.Zimmermann@loria.fr>
- * const_euler.c (mpfr_const_euler_S, mpfr_const_euler_R):
- Make declaration match prototype.
+ * tests/tpow.c: added two tests
+
+2002-07-19 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * README.dev: Updated note concerning rcs2log.
+
+ * TODO: Line mpfr_get_exp / mpfr_set_exp removed.
+
+2002-07-16 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * tests/tget_str.c: added function check_large
+
+2002-07-15 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * config.guess, config.sub:
+ Update from ftp://ftp.gnu.org/pub/gnu/config/
+
+2002-07-14 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * mpfr-math.h: Add __sparc__ (patch by Nix <nix@esperi.demon.co.uk>).
+
+ * TODO: Note about randomized tests.
+
+2002-07-04 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * BUGS: Bug concerning the rounding of pow().
+
+ * pow.c:
+ mpfr_pow() didn't work when the exponent was a negative integer.
+
+ * get_z_exp.c:
+ mpfr_get_z_exp() didn't work when the MPFR number was negative.
+
+ * Makefile.am, get_exp.c, mpfr.h, mpfr.texi, set_exp.c:
+ New functions mpfr_get_exp and mpfr_set_exp.
+
+2002-06-27 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * TODO: removed duplicated entry (thread-safe)
+
+ * TODO: added new items
+
+ * tests/tpow.c: added special cases
+
+ * algorithms.tex: added one reference (nocite)
+
+ * algorithms.bib: added one reference
+
+ * inp_str.c: fixed bug in return value
+
+ * TODO: new additions
+
+ * mpfr.texi: added pointer to mpfr_inp_str in mpfr_set_str
+
+2002-06-26 Vincent Lefevre <Vincent.Lefevre@loria.fr>
+
+ * ChangeLog: Update.
+
+ * exceptions.c, mpfr-impl.h, mul.c, mul_ui.c, print_raw.c, rint.c, round_prec.c, set.c, set_si.c, set_ui.c, set_z.c, sqrt.c, sub1.c, add1.c, add_one_ulp.c, div.c:
+ MP_LIMB_T_HIGHBIT -> MPFR_LIMB_HIGHBIT.
+ MPFR is now compatible with GMP 4.1.
+
+2002-06-15 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * TODO: Added: make MPFR thread-safe.
+
+2002-06-14 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * set_q.c: fixed bug found by Gerardo Ballabio
+
+ * tests/tset_q.c:
+ added one test (bug in mpfr-2.0.1 found by Gerardo Ballabio)
+
+2002-06-13 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * TODO: added mpfr_modf
+
+2002-06-12 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * TODO: Added modf (to implement).
+
+2002-06-08 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * tests/tmul.c, tests/tadd.c:
+ check: Apply a hack to the parameter order to make sparc gcc 2.95.2
+ happy (patch by Kevin Ryde) + static added.
+
+ * mpfr.texi: Patch by Kevin Ryde.
+
+ * tests/tsqrt.c, tests/tsqrt_ui.c:
+ Suppress tests if sqrt is not affected by mpfr_set_machine_rnd_mode
+ (patch by Kevin Ryde).
+
+ * ChangeLog: Update.
+
+ * README: fdl.texi added.
+
+ * Makefile.am, README.dev, fdl.texi, mpfr.texi, texinfo.tex:
+ Patch by Kevin Ryde (and Vincent Lefevre).
+ mpfr.texi: Change license to FDL, use @copying per texinfo 4.2.
+ Use @dircategory, @direntry, @documentdescription.
+ Move @contents to start of file.
+ (VERSION, UPDATED): New variables.
+ (m, GMPtimes, times): New macros.
+ (Float Arithmetic): Fix html output. Reported by Richard Dawe.
+ (GNU Free Documentation License): New appendix.
+
+2002-06-06 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * rnd_mode.c:
+ Use gmp-impl.h to get MPFR_HAVE_FESETROUND (reported by Kevin Ryde).
+
+2002-06-05 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * ChangeLog: patch for mpfr.texi
+
+ * mpfr.texi:
+ patch from Richard Dawe <richdawe@bigfoot.com> to generate HTML
+
+ * tests/Makefile.am, tests/tgamma.c, Makefile.am, gamma.c, mpfr.h, mpfr.texi:
+ added mpfr_gamma in libmpfr
+
+2002-06-05 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * tests/tests.c, acinclude.m4, mpfr-test.h: Check for isnan.
+
+2002-05-29 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * rint.c, sub_one_ulp.c, add_one_ulp.c, sub1.c, add1.c:
+ Bug fixed (possible integer overflow).
+
+ * exceptions.c: Note added for mpfr_check_range. Bug fixed.
+
+ * urandomb.c: Sign wasn't set (reported by Dmitrii Baksheyev).
+ Types fixed and code clean-up.
+
+ * random.c: Types fixed and code clean-up.
+
+2002-05-27 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * tests/tset_si.c, tests/tset_str.c, tests/tset_z.c, tests/tsin.c, tests/tsinh.c, tests/tsqrt_ui.c, tests/tsub.c, tests/tsub_ui.c, tests/tswap.c, tests/ttan.c, tests/ttanh.c, tests/ttrunc.c, tests/tui_pow.c, tests/tui_sub.c, tests/thyperbolic.c, tests/thypot.c, tests/tisnan.c, tests/tlog.c, tests/tlog10.c, tests/tlog1p.c, tests/tlog2.c, tests/tmul.c, tests/tmul_2exp.c, tests/tmul_ui.c, tests/tpow.c, tests/tpow3.c, tests/trandom.c, tests/trint.c, tests/tround_prec.c, tests/tset.c, tests/tset_d.c, tests/tset_f.c, tests/tset_q.c, tests/tatanh.c, tests/tcan_round.c, tests/tcmp.c, tests/tcmp2.c, tests/tcmp_ui.c, tests/tconst_euler.c, tests/tconst_log2.c, tests/tconst_pi.c, tests/tcos.c, tests/tcosh.c, tests/tdiv_ui.c, tests/tdump.c, tests/teq.c, tests/tests.c, tests/texceptions.c, tests/texp.c, tests/texp2.c, tests/texpm1.c, tests/tfactorial.c, tests/tfma.c, tests/tget_str.c, tests/Makefile.am, tests/memory.c, tests/reuse.c, tests/tabs.c, tests/tacos.c, tests/tacosh.c, tests/tadd.c, tests/tadd_ui.c, tests/tagm.c, tests/tasin.c, tests/tasinh.c, tests/tatan.c, TODO, const_log2.c, const_pi.c, mpfr-impl.h, mpfr-test.h:
+ Patch by Kevin Ryde for memory leak checking + misc declaration fixes.
+ Code moved from mpfr-test.h to tests.c.
+
+2002-05-14 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * TODO: Ternary flag for mpfr_agm.
+
+ * tests/texceptions.c, tests/texp2.c, tests/texpm1.c, tests/tfma.c, tests/tgamma.c, tests/thypot.c, tests/tlog1p.c, tests/tlog2.c, tests/tpow3.c, tests/tset.c, tests/tsinh.c, tests/tsub.c, tests/tswap.c, tests/ttanh.c, tests/ttrunc.c, tests/tui_pow.c, tests/tzeta.c, tests/tacos.c, tests/tacosh.c, tests/tasinh.c, tests/tatanh.c, tests/tcmp_ui.c, tests/tconst_log2.c, tests/tconst_pi.c, tests/tcosh.c, div.c, exceptions.c, gamma.c, generic.c, init.c, init2.c, isinteger.c, mpfi.h, out_str.c, set_si.c, set_str_raw.c, set_ui.c, sub.c, ui_div.c, zeta.c, acos.c, add.c, asin.c, atan.c, cmp2.c, const_euler.c, const_log2.c, const_pi.c:
+ Copyright line updated.
+
+2002-05-14 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * TODO: ternary flag for mpfr_agm?
+
+ * TODO: update wrt mpfr_set_machine_rnd_mode
+
+ * mpfr.texi:
+ added mathematical description of arithmetico-geometric mean
+
+2002-05-08 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * INSTALL, acinclude.m4:
+ The problem on a G4 PowerPC was a bug in gcc; this is now tested
+ in configure (float-conversion bug) and -ffloat-store is used if
+ need be.
+
+2002-05-06 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * INSTALL: Problem on the G4 PowerPC.
+
+2002-04-30 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * tests/tpow.c, algorithms.tex, pow.c:
+ fixed problem (infinite loop) in mpfr_pow for exact powers
+
+ * mpfr.texi: fixed errors found by Sylvain Pion
+
+2002-04-27 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * mpfr.texi: not relevant -> undefined.
+
+ * mpfr.texi: Some changes concerning the internals and zeros
+ (including remarks by Kevin Ryde).
+
+2002-04-25 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * acinclude.m4, mpfr-math.h: Check if HUGE_VAL is supported.
+
+ * TODO: Changes in mpfr_set_str.
+
+2002-04-25 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * TODO: update
+
+ * mpfr.texi, set_str.c:
+ mpfr_set_str doesn't require any more a final '\0'
+ and return the number of characters read
+
+ * tests/tset_str.c: modified tests for special values
+
+2002-04-24 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * cmp_abs.c: Description updated.
+
+ * mpfr-impl.h, mpfr.h, mpfr.texi:
+ mpfr_cmp_abs no longer an internal function and described in mpfr.texi.
+ In mpfr.texi, a @var{} was forgotten.
+
+ * cmp_abs.c: mpfr_cmp_abs can now be called on zero numbers.
+
+ * mpfr-math.h: Structures are used to get correct alignment.
+
+2002-04-23 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * mpfr-math.h:
+ _MPFR_INF*_BYTES fix. On alpha, use a "double" for the bytes,
+ to avoid a mis-conversion on alpha gcc 3.0.2. (Kevin Ryde)
+
+ * Makefile.am, div_2si.c, div_2ui.c, exceptions.c, mpfr-impl.h, mul.c, mul_2si.c, powerof2.c, set_z.c, sub1.c, sub_one_ulp.c:
+ Underflow semantics changed (not tested).
+
+ * mul.c: Code simplified due to change in the maximum exponent range.
+
+2002-04-23 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * algorithms.tex: modifs from Andreas
+
+2002-04-22 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * mpfr-math.h: Union -> array + cast because of the HP compiler.
+
+2002-04-20 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * get_d.c:
+ Avoid constant floating expression, as this doesn't give the correct
+ result with gcc on some Alpha machines. (patch by Paul Zimmermann)
+
+2002-04-19 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * mpfr-test.h:
+ RAND_MAX defined if not already defined (as it should be).
+
+ * mpfr-test.h:
+ Include config.h, for the benefit of test programs not using
+ gmp-impl.h (Kevin Ryde).
+
+2002-04-19 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * mpfr-test.h:
+ added tests in mpfr_test_init for denorms and extended precision
+
+ * init.c, init2.c, mpfr.h, mpfr.texi:
+ mpfr_init and mpfr_init2 now return an int
+
+2002-04-19 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * set_q.c:
+ Exponent range saved/restored. Returns NaN when the numerator
+ or the denominator is too large for MPFR.
+
+ * sqrt_ui.c, sub_ui.c, ui_div.c, ui_sub.c, add_ui.c, div_ui.c, mul_ui.c, set_si.c, set_ui.c:
+ Added some assertions (any unsigned long must be representable
+ in a mp_limb_t).
+
+ * cmp_si.c, mpfr-impl.h, set_si.c:
+ SAFE_ABS changed so that it can be used for any unsigned type.
+
+2002-04-18 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * set_z.c:
+ Added code to prevent possible integer overflow when the input number
+ is very large.
+
+ * mpfr.h: New values for exponent range.
+
+2002-04-18 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * tests/tadd.c:
+ call get_d with rounding mode in check2, to avoid problems near +Inf
+
+ * mpfr-test.h: 2147483647 -> INT_MAX
+
+ * tests/tadd.c, mpfr-test.h: improved ulp() to deal with infinities
+ and fixed tadd/check2 to deal with infinities
+
+2002-04-17 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * mpfr.texi: improved documentation of mpfr_set_precset_prec.
+
+2002-04-16 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * mpfr.texi: fixed documentation of cosh/sinh/tanh
+
+2002-04-16 Vincent Lefevre <lefevre@greux.loria.fr>
+
+ * Makefile.am, cmp_si.c, cmp_ui.c, mpfr.h, mpfr.texi:
+ mpfr_cmp_ui_2exp and mpfr_cmp_si_2exp rewritten.
+ Prototype changed.
+
+ * acinclude.m4, configure.in:
+ Use AC_CANONICAL_HOST and $host instead of $OS_TYPE and $MACHTYPE
+ (patch suggested by Kevin Ryde).
+
+ * config.guess, config.sub:
+ Added files from ftp.gnu.org for automake and AC_CANONICAL_HOST.
+
+2002-04-15 Paul Zimmermann <zimmerma@greux.loria.fr>
+
+ * tests/tabs.c, tests/tadd.c, tests/tadd_ui.c, tests/tdiv_ui.c, tests/tout_str.c, tests/tset_d.c, tests/tsub_ui.c, tests/tui_sub.c:
+ replaced 2.2e-307 by DBL_MIN
2002-04-15 Vincent Lefevre <lefevre@greux.loria.fr>
+ * README: Typo: Gnu -> GNU.
+
+ * VERSION, mpfr.texi: Update for future 2.0.2.
+
+ * ChangeLog: Update for mpfr 2.0.1.
+
* VERSION, mpfr.texi, README.dev:
Back to version 2.0.1, updated documentation.
diff --git a/mpfr/Makefile.am b/mpfr/Makefile.am
index abf096cd6..fd8c160d3 100644
--- a/mpfr/Makefile.am
+++ b/mpfr/Makefile.am
@@ -44,7 +44,7 @@ TEXINFO_TEX = ../texinfo.tex
# Override automake default AR=ar with the value from GMP_PROG_AR.
AR = @AR@
-libmpfr_a_SOURCES = mpfr.h mpf2mpfr.h mpfr-impl.h mpfr-math.h mpfr-test.h exceptions.c save_expo.c extract.c uceil_exp2.c uceil_log2.c ufloor_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_d.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 get_z_exp.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 sin_cos.c set_nan.c set_inf.c
+libmpfr_a_SOURCES = mpfr.h mpf2mpfr.h mpfr-impl.h mpfr-math.h mpfr-test.h exceptions.c save_expo.c extract.c uceil_exp2.c uceil_log2.c ufloor_log2.c add.c add1.c add_one_ulp.c add_ui.c agm.c clear.c cmp.c cmp_abs.c cmp_si.c cmp_ui.c comparisons.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 frac.c get_d.c get_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 next.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 round_prec.c set.c setmax.c setmin.c set_d.c set_dfl_prec.c set_exp.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 get_z_exp.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 sin_cos.c set_nan.c set_inf.c powerof2.c gamma.c set_ld.c get_ld.c cbrt.c
libmpfr_a_LIBADD = @LIBOBJS@
diff --git a/mpfr/Makefile.in b/mpfr/Makefile.in
index ea437585f..ad247eb27 100644
--- a/mpfr/Makefile.in
+++ b/mpfr/Makefile.in
@@ -214,7 +214,7 @@ mpfr_TEXINFOS = ../fdl.texi
AM_MAKEINFOFLAGS = -I$(top_srcdir)
TEXINFO_TEX = ../texinfo.tex
-libmpfr_a_SOURCES = mpfr.h mpf2mpfr.h mpfr-impl.h mpfr-math.h mpfr-test.h exceptions.c save_expo.c extract.c uceil_exp2.c uceil_log2.c ufloor_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_d.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 get_z_exp.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 sin_cos.c set_nan.c set_inf.c
+libmpfr_a_SOURCES = mpfr.h mpf2mpfr.h mpfr-impl.h mpfr-math.h mpfr-test.h exceptions.c save_expo.c extract.c uceil_exp2.c uceil_log2.c ufloor_log2.c add.c add1.c add_one_ulp.c add_ui.c agm.c clear.c cmp.c cmp_abs.c cmp_si.c cmp_ui.c comparisons.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 frac.c get_d.c get_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 next.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 round_prec.c set.c setmax.c setmin.c set_d.c set_dfl_prec.c set_exp.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 get_z_exp.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 sin_cos.c set_nan.c set_inf.c powerof2.c gamma.c set_ld.c get_ld.c cbrt.c
libmpfr_a_LIBADD = @LIBOBJS@
@@ -232,39 +232,43 @@ am_libmpfr_a_OBJECTS = exceptions$U.$(OBJEXT) save_expo$U.$(OBJEXT) \
uceil_log2$U.$(OBJEXT) ufloor_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) \
+ cmp_abs$U.$(OBJEXT) cmp_si$U.$(OBJEXT) cmp_ui$U.$(OBJEXT) \
+ comparisons$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_d$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) \
+ frac$U.$(OBJEXT) get_d$U.$(OBJEXT) get_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) \
+ next$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_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_one_ulp$U.$(OBJEXT) sub_ui$U.$(OBJEXT) \
- rint$U.$(OBJEXT) ui_div$U.$(OBJEXT) ui_sub$U.$(OBJEXT) \
- urandomb$U.$(OBJEXT) get_z_exp$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) \
+ round_prec$U.$(OBJEXT) set$U.$(OBJEXT) setmax$U.$(OBJEXT) \
+ setmin$U.$(OBJEXT) set_d$U.$(OBJEXT) set_dfl_prec$U.$(OBJEXT) \
+ set_exp$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_one_ulp$U.$(OBJEXT) sub_ui$U.$(OBJEXT) rint$U.$(OBJEXT) \
+ ui_div$U.$(OBJEXT) ui_sub$U.$(OBJEXT) urandomb$U.$(OBJEXT) \
+ get_z_exp$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) \
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) \
acos$U.$(OBJEXT) sin_cos$U.$(OBJEXT) set_nan$U.$(OBJEXT) \
- set_inf$U.$(OBJEXT)
+ set_inf$U.$(OBJEXT) powerof2$U.$(OBJEXT) gamma$U.$(OBJEXT) \
+ set_ld$U.$(OBJEXT) get_ld$U.$(OBJEXT) cbrt$U.$(OBJEXT)
libmpfr_a_OBJECTS = $(am_libmpfr_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -294,7 +298,9 @@ RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
check-recursive installcheck-recursive
DIST_COMMON = README $(include_HEADERS) $(mpfr_TEXINFOS) AUTHORS \
COPYING COPYING.LIB ChangeLog Makefile.am Makefile.in NEWS TODO \
- acinclude.m4 strcasecmp.c
+ acinclude.m4 config.guess config.sub configure depcomp \
+ install-sh missing mkinstalldirs strcasecmp.c strncasecmp.c \
+ texinfo.tex
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(libmpfr_a_SOURCES)
@@ -385,6 +391,8 @@ 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) > $@ || rm -f $@
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) > $@ || rm -f $@
+cbrt_.c: cbrt.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/cbrt.c; then echo $(srcdir)/cbrt.c; else echo cbrt.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
cmp_.c: cmp.c $(ANSI2KNR)
@@ -393,8 +401,12 @@ cmp2_.c: cmp2.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/cmp2.c; then echo $(srcdir)/cmp2.c; else echo cmp2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
+cmp_si_.c: cmp_si.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/cmp_si.c; then echo $(srcdir)/cmp_si.c; else echo cmp_si.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
+comparisons_.c: comparisons.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/comparisons.c; then echo $(srcdir)/comparisons.c; else echo comparisons.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
const_log2_.c: const_log2.c $(ANSI2KNR)
@@ -441,8 +453,16 @@ 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) > $@ || rm -f $@
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) > $@ || rm -f $@
+frac_.c: frac.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/frac.c; then echo $(srcdir)/frac.c; else echo frac.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+gamma_.c: gamma.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/gamma.c; then echo $(srcdir)/gamma.c; else echo gamma.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
get_d_.c: get_d.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/get_d.c; then echo $(srcdir)/get_d.c; else echo get_d.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+get_exp_.c: get_exp.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/get_exp.c; then echo $(srcdir)/get_exp.c; else echo get_exp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+get_ld_.c: get_ld.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/get_ld.c; then echo $(srcdir)/get_ld.c; else echo get_ld.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
get_str_.c: get_str.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/get_str.c; then echo $(srcdir)/get_str.c; else echo get_str.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
get_z_exp_.c: get_z_exp.c $(ANSI2KNR)
@@ -487,6 +507,8 @@ 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) > $@ || rm -f $@
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) > $@ || rm -f $@
+next_.c: next.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/next.c; then echo $(srcdir)/next.c; else echo next.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
pow_.c: pow.c $(ANSI2KNR)
@@ -495,6 +517,8 @@ pow_si_.c: pow_si.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/pow_si.c; then echo $(srcdir)/pow_si.c; else echo pow_si.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
pow_ui_.c: pow_ui.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/pow_ui.c; then echo $(srcdir)/pow_ui.c; else echo pow_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+powerof2_.c: powerof2.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/powerof2.c; then echo $(srcdir)/powerof2.c; else echo powerof2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
print_raw_.c: print_raw.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/print_raw.c; then echo $(srcdir)/print_raw.c; else echo print_raw.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
print_rnd_mode_.c: print_rnd_mode.c $(ANSI2KNR)
@@ -507,8 +531,6 @@ 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) > $@ || rm -f $@
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) > $@ || rm -f $@
-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) > $@ || rm -f $@
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) > $@ || rm -f $@
save_expo_.c: save_expo.c $(ANSI2KNR)
@@ -519,10 +541,14 @@ set_d_.c: set_d.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_d.c; then echo $(srcdir)/set_d.c; else echo set_d.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
set_dfl_prec_.c: set_dfl_prec.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_dfl_prec.c; then echo $(srcdir)/set_dfl_prec.c; else echo set_dfl_prec.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+set_exp_.c: set_exp.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_exp.c; then echo $(srcdir)/set_exp.c; else echo set_exp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
set_f_.c: set_f.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_f.c; then echo $(srcdir)/set_f.c; else echo set_f.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
set_inf_.c: set_inf.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_inf.c; then echo $(srcdir)/set_inf.c; else echo set_inf.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+set_ld_.c: set_ld.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_ld.c; then echo $(srcdir)/set_ld.c; else echo set_ld.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
set_nan_.c: set_nan.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_nan.c; then echo $(srcdir)/set_nan.c; else echo set_nan.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
set_prc_raw_.c: set_prc_raw.c $(ANSI2KNR)
@@ -543,6 +569,10 @@ set_ui_.c: set_ui.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_ui.c; then echo $(srcdir)/set_ui.c; else echo set_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
set_z_.c: set_z.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/set_z.c; then echo $(srcdir)/set_z.c; else echo set_z.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+setmax_.c: setmax.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/setmax.c; then echo $(srcdir)/setmax.c; else echo setmax.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+setmin_.c: setmin.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/setmin.c; then echo $(srcdir)/setmin.c; else echo setmin.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
sin_.c: sin.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sin.c; then echo $(srcdir)/sin.c; else echo sin.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
sin_cos_.c: sin_cos.c $(ANSI2KNR)
@@ -555,6 +585,8 @@ sqrt_ui_.c: sqrt_ui.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sqrt_ui.c; then echo $(srcdir)/sqrt_ui.c; else echo sqrt_ui.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
strcasecmp_.c: strcasecmp.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/strcasecmp.c; then echo $(srcdir)/strcasecmp.c; else echo strcasecmp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+strncasecmp_.c: strncasecmp.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/strncasecmp.c; then echo $(srcdir)/strncasecmp.c; else echo strncasecmp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
sub1_.c: sub1.c $(ANSI2KNR)
@@ -589,52 +621,59 @@ 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 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_d_.$(OBJEXT) get_d_.lo \
-get_str_.$(OBJEXT) get_str_.lo get_z_exp_.$(OBJEXT) get_z_exp_.lo \
-gmp_op_.$(OBJEXT) gmp_op_.lo hypot_.$(OBJEXT) hypot_.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 log10_.$(OBJEXT) log10_.lo log1p_.$(OBJEXT) log1p_.lo \
-log2_.$(OBJEXT) log2_.lo minmax_.$(OBJEXT) minmax_.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) \
+atanh_.$(OBJEXT) atanh_.lo cbrt_.$(OBJEXT) cbrt_.lo clear_.$(OBJEXT) \
+clear_.lo cmp_.$(OBJEXT) cmp_.lo cmp2_.$(OBJEXT) cmp2_.lo \
+cmp_abs_.$(OBJEXT) cmp_abs_.lo cmp_si_.$(OBJEXT) cmp_si_.lo \
+cmp_ui_.$(OBJEXT) cmp_ui_.lo comparisons_.$(OBJEXT) comparisons_.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 frac_.$(OBJEXT) frac_.lo gamma_.$(OBJEXT) \
+gamma_.lo get_d_.$(OBJEXT) get_d_.lo get_exp_.$(OBJEXT) get_exp_.lo \
+get_ld_.$(OBJEXT) get_ld_.lo get_str_.$(OBJEXT) get_str_.lo \
+get_z_exp_.$(OBJEXT) get_z_exp_.lo gmp_op_.$(OBJEXT) gmp_op_.lo \
+hypot_.$(OBJEXT) hypot_.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 log10_.$(OBJEXT) \
+log10_.lo log1p_.$(OBJEXT) log1p_.lo log2_.$(OBJEXT) log2_.lo \
+minmax_.$(OBJEXT) minmax_.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 \
+next_.$(OBJEXT) next_.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 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_inf_.$(OBJEXT) set_inf_.lo \
+powerof2_.$(OBJEXT) powerof2_.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 rint_.$(OBJEXT) rint_.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_exp_.$(OBJEXT) set_exp_.lo set_f_.$(OBJEXT) \
+set_f_.lo set_inf_.$(OBJEXT) set_inf_.lo set_ld_.$(OBJEXT) set_ld_.lo \
set_nan_.$(OBJEXT) set_nan_.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 sin_cos_.$(OBJEXT) sin_cos_.lo sinh_.$(OBJEXT) sinh_.lo \
-sqrt_.$(OBJEXT) sqrt_.lo sqrt_ui_.$(OBJEXT) sqrt_ui_.lo \
-strcasecmp_.$(OBJEXT) strcasecmp_.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 uceil_exp2_.$(OBJEXT) uceil_exp2_.lo \
-uceil_log2_.$(OBJEXT) uceil_log2_.lo ufloor_log2_.$(OBJEXT) \
-ufloor_log2_.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)
+set_ui_.$(OBJEXT) set_ui_.lo set_z_.$(OBJEXT) set_z_.lo \
+setmax_.$(OBJEXT) setmax_.lo setmin_.$(OBJEXT) setmin_.lo \
+sin_.$(OBJEXT) sin_.lo sin_cos_.$(OBJEXT) sin_cos_.lo sinh_.$(OBJEXT) \
+sinh_.lo sqrt_.$(OBJEXT) sqrt_.lo sqrt_ui_.$(OBJEXT) sqrt_ui_.lo \
+strcasecmp_.$(OBJEXT) strcasecmp_.lo strncasecmp_.$(OBJEXT) \
+strncasecmp_.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 uceil_exp2_.$(OBJEXT) uceil_exp2_.lo uceil_log2_.$(OBJEXT) \
+uceil_log2_.lo ufloor_log2_.$(OBJEXT) ufloor_log2_.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)
mostlyclean-libtool:
-rm -f *.lo
diff --git a/mpfr/README b/mpfr/README
index 44e6dc490..1325a2950 100644
--- a/mpfr/README
+++ b/mpfr/README
@@ -18,11 +18,12 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
The MPFR distribution contains the following files:
+(This does not apply to code retrieved by CVS.)
AUTHORS - the authors of the library
BUGS - bugs in MPFR - please read this file!
COPYING - the GNU General Public License, version 2
-COPYING.LIB - the Gnu Lesser General Public License, version 2.1
+COPYING.LIB - the GNU Lesser General Public License, version 2.1
ChangeLog - the log of changes
INSTALL - how to install MPFR (see also mpfr.texi)
Makefile* - files for building the library
@@ -33,6 +34,7 @@ VERSION - version of MPFR (next release version if taken from CVS)
ac*.m4 - automatic configuration files
*.c - source files
configure* - configuration files
+fdl.texi - the GNU Free Documentation License
install* - installation files
missing - auxiliary installation file
mkinst* - auxiliary installation file
@@ -45,3 +47,10 @@ mpfr.info - info file for MPFR
mpfr.texi - texinfo documentation for MPFR
tests/ - test directory
texinfo.tex - TeX macros to handle mpfr.texi
+
+
+You can get the latest source code by CVS:
+
+ cvs -d :pserver:cvs@cvs-sop.inria.fr:/CVS/spaces checkout mpfr
+
+(empty password). CVS users should read the file "README.dev".
diff --git a/mpfr/TODO b/mpfr/TODO
index 37db7b2e6..1552eaca4 100644
--- a/mpfr/TODO
+++ b/mpfr/TODO
@@ -5,21 +5,112 @@ Documentation:
Installation:
- from Kevin Ryde <user42@zip.com.au>:
- Determine the exp2/exp3 thresholds using tune/tuneup.c.
-
-- problems when mpfr uses a different compiler (gcc) than gmp (for example
- cc under Solaris 2.7).
+ Determine the exp2/exp3 thresholds using tune/tuneup.c.
+ A start has been made on this, but there's a noticable step-effect
+ in the times making them cross back and forward between which is
+ faster. Hopefully this will go away with improvements to the exp
+ code.
+- install config.h gmp-impl.h gmp-mparam.h longlong.h only in the mpfr
+ build directory ["Nelson H. F. Beebe" <beebe@math.utah.edu>]
+ Alternately, insist on having a gmp build tree for the mpfr build to
+ access.
+
+Changes in existing functions:
+
+- allow the ISO C "P" exponent separator for base 16 in input functions
+- invert 2nd and 3rd arguments of mpfr_round_prec (to be coherent with
+ mpfr_set_prec)
+- merge mpfr_inp_str and mpfr_set_str (cf glibc sscanf/fscanf)
+ [mpfr_set_str -> with final '\0',
+ mpfr_strtofr -> without final '\0', returns the number of characters
+ read (or name mpfr_strtod suggested by Kevin, see below)]
+ Suggestion from Kevin:
+ - Function: char * mpf_strto (mpz_t ROP, const char *STR)
+ Read a floating point number from a string. If successful the
+ result is stored in ROP and the return value points to the
+ character after those parsed. If STR doesn't start with a valid
+ number then the return value is `NULL' and the value in ROP is
+ undefined.
+
+ Parsing follows the standard C `strtod' function (*note Parsing of
+ Integers: (libc)Parsing of Integers.). This means optional
+ leading whitespace, an optional `+' or `-', mantissa digits, and an
+ optional exponent consisting of an `e' or `E', an optional sign,
+ and digits. A hex mantissa can be given with a leading `0x' or
+ `0X', in which case `p' or `P' introduces the exponent (still in
+ decimal). In addition `inf' or `infinity' with an optional sign,
+ or `nan' or `nan(..chars..)', all non case significant, can be
+ given.
+
+ There must be at least one digit in the mantissa for the number to
+ be valid. If an exponent has no digits it's ignored and parsing
+ stops after the mantissa. If an `0x' or `0X' is not followed by
+ hexadecimal digits, parsing stops after the `0'.
+
+ Note that in the hex format the exponent represents a power of 2,
+ ie. the result is MANTISSA*2^EXPONENT. This is as per the `%a'
+ format in `printf' (*note Formatted Output Strings::).
+
+ `mpf_t' does not currently support NaNs or infinities. The value
+ stored to ROP for these is undefined.
+
+ The decimal point character, or string, expected is taken from the
+ current locale on systems providing `localeconv'. [end of suggestion]
+- remove mpfr_set_machine_rnd_mode from the documentation,
+ and move it to the test directory
+- in mpfr_set_str, make string comparisons case insensitive and use @Inf@
+ and @NaN@ instead of the possibly ambiguous Inf and NaN in bases > 10.
+ Modify the other functions to make them consistent with this choice.
+ Possibly accept other strings, like those accepted by strtod.
+- implement ternary flag for mpfr_agm: result is exact when u=v, or u=0,
+ or v=0.
New functions to implement:
+- functions in mpf and not in mpfr (for compatibility)
+- modf (to extract integer and fractional parts), suggested by
+ Dmitry Antipov <dmitry.antipov@mail.ru> Thu, 13 Jun 2002
+- mpz_set_fr (to set a mpz from a mpfr, with a rounding mode)
+ -> cf code in leibniz:mpfr/mpz_set_fr.c
- those from LIA: missing secant, cosecant, cotangent (trigo/hyperbolic)
-- nextafter/nextforward : X + epsilon if X < Y, X - epsilon if X > Y
-- nextabove/nextbelow ?
+- atan2
+- mpfr_set_f (MPF -> float) or mpfr_strtof, mpfr_set_ld or mpfr_strtold
+ (idem for mpfr_get_*)
+- implement accurate summation algorithms from Demmel
+ (http://www.cs.berkeley.edu/~demmel/AccurateSummation.ps)
+- mpfr_cmp_d (for Gerardo)
Rounding:
+- mpfr_pow isn't completely specified (concerning signed zeros).
+
Efficiency:
+- implement range reduction in sin/cos/tan for large arguments
+ (currently too slow for 2^1024)
+- mpfr_asin/acos are too slow for small values (2^(-1021) for example)
+- idem for mpfr_atanh (2^(-1021) for example)
+- improve generic.c to work for number of terms <> 2^k
+- rewrite mpfr_greater_p...
+- combine tests for singular values [from Torbjorn Granlund]:
+ For example, mpfr_add could have this structure:
+ if (MPFR_SINGULAR (a))
+ ...
+ else if (MPFR_SINGULAR (b)
+ ...
+ else
+ plain operands
+- mpf_t uses a scheme where the number of limbs actually present can
+ be less than the selected precision, thereby allowing low precision
+ values (for instance small integers) to be stored and manipulated in
+ an mpf_t efficiently.
+
+ Perhaps mpfr should get something similar, especially if looking to
+ replace mpf with mpfr, though it'd be a major change. Alternately
+ perhaps those mpfr routines like mpfr_mul where optimizations are
+ possible through stripping low zero bits or limbs could check for
+ that (this would be less efficient but easier).
+
Miscellaneous:
- rename mpf2mpfr.h to gmp-mpf2mpfr.h?
@@ -27,6 +118,7 @@ Miscellaneous:
- add mpfr_get_ld for 'long double' [asked by J-C Fauge`re] ?
(exists since K&R, but has not necessarily a greater precision than double)
cf http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/
+ [cf above]
- from Kevin Ryde <user42@zip.com.au>:
Also for pi.c, a pre-calculated compiled-in pi to a few thousand
@@ -37,13 +129,78 @@ Miscellaneous:
- problem when reading a float followed by a character, for example 1.5*x
[from Fabrice.Rouillier@loria.fr, Mon, 04 Dec 2000]
-- rewrite mpfr_get_str and mpfr_set_str to use mpn_get_str and mpn_set_str.
+- rewrite mpfr_set_str to use mpn_set_str.
(Torbjorn Granlund <tege@swox.com>, 30 Jan 2002)
- mpfr_pow isn't completely specified (concerning signed zeros).
-- rename mpfr_isinteger to mpfr_integer_p.
+- rename (and rewrite) mpfr_isinteger to mpfr_integer_p.
(Kevin Ryde, 05 Mar 2002)
-- some comparison functions aren't completely specified (concerning NaN).
- Add new comparison functions (eq, ne, lt, gt, le, ge)?
+- use GMP rand/srand functions instead for SEED_RAND (time(NULL)). Kevin:
+ GMP tests/misc.c has a scheme to print the seed chosen and allow for a
+ re-run with a given seed. If you moved towards _gmp_rand and friends
+ at some stage you could probably use that scheme almost unchanged.
+ An advantage of _gmp_rand of course is that it's the same on all
+ systems, apart from limb size, so you're not at the mercy of random or
+ lrand48, etc.
+
+- randomized tests: do like GMP (see misc.c), but using MPFR_CHECK_RANDOMIZE
+
+- add tests for nextabove/nextbelow/nexttoward.
+
+- documentation and tests for:
+ = < > unordered
+mpfr_greater_p 0 0 1 0
+mpfr_greaterequal_p 1 0 1 0
+mpfr_less_p 0 1 0 0
+mpfr_lessequal_p 1 1 0 0
+mpfr_lessgreater_p 0 1 1 0
+mpfr_equal_p 1 0 0 0
+mpfr_unordered_p 0 0 0 1
+
+
+Reentrancy / Thread-Safety:
+
+- Temporary changes to emin/emax are not safe (all uses of
+ mpfr_save_emin_emax, eg. mpfr_set_q).
+
+- Global variables for caching in mpfr_const_log2 and mpfr_const_pi
+ are not safe.
+
+
+Portability:
+
+- MINGW has neither random() nor rand48(), making the setups in
+ mpfr-test.h fail. It does have rand(), returning just 15 bits.
+ Switching to gmp_randstate_t etc would be better.
+
+- _mpfr_ceil_log2 is IEEE specific. Many callers only seem to want
+ this operation on an integer, which could be done with
+ count_leading_zeros from longlong.h.
+
+- test set_ld for special values (+/- 0, LDBL_MAX, LDBL_MIN...)
+
+
+Possible future MPF / MPFR integration:
+
+- mpf routines can become "extern inline"s calling mpfr equivalents,
+ probably just with GMP_RNDZ hard coded, since that's what mpf has
+ always done.
+
+- Want to preserve the mpf_t size, for binary compatibility. Breaking
+ compatibility would cause lots of pain and potential subtle breakage
+ for users. If the fields in mpf_t are not enough then extra space
+ under _mp_d can be used.
+
+- mpf_sgn has been a macro directly accessing the _mp_size field, so a
+ compatible representation would be required. At worst that field
+ could be maintained for mpf_sgn, but not otherwise used internally.
+
+ mpf_sgn should probably throw an exception if called with NaN, since
+ there's no useful value it can return, so it might want to become a
+ function. Inlined copies in existing binaries would hopefully never
+ see a NaN, if they only do old-style mpf things.
+
+- mpfr routines replacing mpf routines must be reentrant and thread
+ safe, since of course that's what has been documented for mpf.
diff --git a/mpfr/acinclude.m4 b/mpfr/acinclude.m4
index 1cc53c19b..e5f613142 100644
--- a/mpfr/acinclude.m4
+++ b/mpfr/acinclude.m4
@@ -8,7 +8,7 @@ then
then
LDADD="$LDADD $1/lib$2.a"
else
- AC_MSG_ERROR($2 not found)
+ AC_MSG_ERROR($1/lib$2.a not found)
fi
AC_MSG_RESULT(yes)
else
@@ -53,7 +53,7 @@ case $host in
;;
esac
-AC_REPLACE_FUNCS(strcasecmp)
+AC_REPLACE_FUNCS(strcasecmp strncasecmp)
dnl Check for IEEE-754 switches on Alpha
case $host in
@@ -90,6 +90,15 @@ if test "$mpfr_cv_have_fesetround" = "yes"; then
AC_DEFINE(MPFR_HAVE_FESETROUND,1,[Define if you have the `fesetround' function via the <fenv.h> header file.])
fi
+dnl Check for isnan
+AC_CACHE_CHECK([for isnan], mpfr_cv_have_isnan, [
+AC_TRY_LINK([#include <math.h>], [isnan(0.0);],
+ mpfr_cv_have_isnan=yes, mpfr_cv_have_isnan=no)
+])
+if test "$mpfr_cv_have_isnan" = "yes"; then
+ AC_DEFINE(MPFR_HAVE_ISNAN,1,[Define if you have the `isnan' function via the <math.h> header file.])
+fi
+
dnl Check random functions
AC_CHECK_FUNCS(lrand48)
@@ -165,4 +174,13 @@ if test "$mpfr_cv_have_denorms" = "yes"; then
AC_DEFINE(HAVE_DENORMS,1,[Define if denormalized floats work.])
fi
+dnl Check if HUGE_VAL is supported without the need of a specific library
+AC_CACHE_CHECK([for HUGE_VAL], mpfr_cv_have_huge_val, [
+AC_TRY_LINK([#include <math.h>], [HUGE_VAL;],
+ mpfr_cv_have_huge_val=yes, mpfr_cv_have_huge_val=no)
+])
+if test "$mpfr_cv_have_huge_val" = "yes"; then
+ AC_DEFINE(HAVE_HUGE_VAL,1,[Define if HUGE_VAL can be used without the need of a specific library.])
+fi
+
])
diff --git a/mpfr/acos.c b/mpfr/acos.c
index ce95b43f3..f5a88931e 100644
--- a/mpfr/acos.c
+++ b/mpfr/acos.c
@@ -1,6 +1,6 @@
/* mpfr_acos -- arc-cosinus of a floating-point number
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library, and was contributed by Mathieu Dutour.
@@ -116,7 +116,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode)
good = 1;
}
else
- realprec += _mpfr_ceil_log2 ((double) realprec);
+ realprec += __gmpfr_ceil_log2 ((double) realprec);
mpfr_clear (tmp);
mpfr_clear (arcc);
diff --git a/mpfr/acosh.c b/mpfr/acosh.c
index 9a0e8622a..5f0c8476e 100644
--- a/mpfr/acosh.c
+++ b/mpfr/acosh.c
@@ -1,4 +1,4 @@
-/* mpfr_acosh -- Inverse Hyperbolic Cosine of Unsigned Integer Number
+/* mpfr_acosh -- inverse hyperbolic cosine
Copyright 2001, 2002 Free Software Foundation.
@@ -26,32 +26,25 @@ MA 02111-1307, USA. */
/* The computation of acosh is done by
- acosh= ln(x+sqrt(x-1)*sqrt(x+1))
+ acosh= ln(x + sqrt(x^2-1))
*/
int
mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode)
{
- int inexact =0;
+ int inexact = 0;
int comp;
- if (MPFR_IS_NAN(x))
+ if (MPFR_IS_NAN(x) || (comp = mpfr_cmp_ui (x, 1)) < 0)
{
MPFR_SET_NAN(y);
MPFR_RET_NAN;
}
- comp=mpfr_cmp_ui(x,1);
-
- if(comp < 0)
- {
- MPFR_SET_NAN(y);
- MPFR_RET_NAN;
- }
MPFR_CLEAR_NAN(y);
- if(comp == 0)
+ if (comp == 0)
{
MPFR_SET_ZERO(y); /* acosh(1) = 0 */
MPFR_SET_POS(y);
@@ -69,57 +62,62 @@ mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode)
/* General case */
{
- /* Declaration of the intermediary variable */
- mpfr_t t, te,ti;
+ /* Declaration of the intermediary variables */
+ mpfr_t t, te, ti;
- /* Declaration of the size variable */
+ /* Declaration of the size variables */
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 Ny = MPFR_PREC(y); /* Precision of output variable */
mp_prec_t Nt; /* Precision of the intermediary variable */
int err; /* Precision of error */
/* compute the precision of intermediary variable */
- Nt=MAX(Nx,Ny);
+ Nt = MAX(Nx, Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+4+_mpfr_ceil_log2(Nt);
+ Nt = Nt + 4 + __gmpfr_ceil_log2 (Nt);
+
+ /* initialization of intermediary variables */
+ mpfr_init (t);
+ mpfr_init (te);
+ mpfr_init (ti);
- /* initialise of intermediary variable */
- mpfr_init(t);
- mpfr_init(te);
- mpfr_init(ti);
+ mpfr_save_emin_emax ();
- /* First computation of cosh */
+ /* First computation of acosh */
do {
/* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(te,Nt);
- mpfr_set_prec(ti,Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ti, Nt);
/* compute acosh */
- mpfr_mul(te,x,x,GMP_RNDD); /* (x^2) */
- mpfr_sub_ui(ti,te,1,GMP_RNDD); /* (x^2-1) */
- mpfr_sqrt(t,ti,GMP_RNDN); /* sqrt(x^2-1) */
- mpfr_add(t,t,x,GMP_RNDN); /* sqrt(x^2-1)+x */
- mpfr_log(t,t,GMP_RNDN); /* ln(sqrt(x^2-1)+x)*/
+ mpfr_mul (te, x, x, GMP_RNDD); /* x^2 */
+ mpfr_sub_ui (ti, te, 1, GMP_RNDD); /* x^2-1 */
+ mpfr_sqrt (t, ti, GMP_RNDN); /* sqrt(x^2-1) */
+ mpfr_add (t, t, x, GMP_RNDN); /* sqrt(x^2-1)+x */
+ mpfr_log (t, t, GMP_RNDN); /* ln(sqrt(x^2-1)+x)*/
- /* estimation of the error see- algorithms.ps*/
- /*err=Nt-_mpfr_ceil_log2(0.5+pow(2,2-MPFR_EXP(t))+pow(2,1+MPFR_EXP(te)-MPFR_EXP(ti)-MPFR_EXP(t)));*/
- err=Nt-(-1+2*MAX(2+MAX(2-MPFR_EXP(t),1+MPFR_EXP(te)-MPFR_EXP(ti)-MPFR_EXP(t)),0));
+ /* estimation of the error -- see algorithms.ps */
+ err = Nt - (-1 + 2 * MAX(2 + MAX(2 - MPFR_EXP(t),
+ 1 + MPFR_EXP(te) - MPFR_EXP(ti) - MPFR_EXP(t)), 0));
/* actualisation of the precision */
Nt += 10;
- } while ((err<0) ||!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
+ } while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny));
- inexact = mpfr_set(y,t,rnd_mode);
+ inexact = mpfr_set (y, t, rnd_mode);
- mpfr_clear(t);
- mpfr_clear(ti);
- mpfr_clear(te);
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
}
- return inexact;
+
+ mpfr_restore_emin_emax ();
+
+ return mpfr_check_range (y, inexact, rnd_mode);
}
diff --git a/mpfr/add.c b/mpfr/add.c
index 31b3377fa..c4dee53ec 100644
--- a/mpfr/add.c
+++ b/mpfr/add.c
@@ -1,6 +1,6 @@
/* mpfr_add -- add two floating-point numbers
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
Contributed by the Spaces project, INRIA Lorraine.
This file is part of the MPFR Library.
diff --git a/mpfr/add1.c b/mpfr/add1.c
index 1118d663f..35c603d08 100644
--- a/mpfr/add1.c
+++ b/mpfr/add1.c
@@ -1,6 +1,6 @@
/* mpfr_add1 -- internal function to perform a "real" addition
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
Contributed by the Spaces project, INRIA Lorraine.
This file is part of the MPFR Library.
@@ -66,7 +66,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
cq = MPFR_PREC(c);
an = (aq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of a */
- aq2 = an * BITS_PER_MP_LIMB;
+ aq2 = (mp_prec_t) an * BITS_PER_MP_LIMB;
sh = aq2 - aq; /* non-significant bits in low limb */
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 */
@@ -160,7 +160,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
if (cc) /* carry */
{
mp_exp_t exp = MPFR_EXP(a);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
{
inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a));
goto end_of_add;
@@ -180,7 +180,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
fb = 1;
}
mpn_rshift(ap, ap, an, 1);
- ap[an-1] += GMP_LIMB_HIGHBIT;
+ ap[an-1] += MPFR_LIMB_HIGHBIT;
if (sh && fb < 0)
goto rounding;
} /* cc */
@@ -247,7 +247,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
if (rb < 0) /* rb not initialized yet */
{
rb = bb >> (BITS_PER_MP_LIMB - 1);
- bb |= GMP_LIMB_HIGHBIT;
+ bb |= MPFR_LIMB_HIGHBIT;
}
fb = 1;
if (bb != MP_LIMB_T_MAX)
@@ -302,13 +302,13 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
&& mpn_add_1(ap, ap, an, MP_LIMB_T_ONE << sh))
{
mp_exp_t exp = MPFR_EXP(a);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
{
inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a));
goto end_of_add;
}
MPFR_EXP(a)++;
- ap[an-1] = GMP_LIMB_HIGHBIT;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
rb = 0;
}
@@ -356,13 +356,13 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
if (rb == 0 && mpn_add_1(ap, ap, an, MP_LIMB_T_ONE << sh))
{
mp_exp_t exp = MPFR_EXP(a);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
{
inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a));
goto end_of_add;
}
MPFR_EXP(a)++;
- ap[an-1] = GMP_LIMB_HIGHBIT;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
}
} /* bb < cc */
@@ -405,7 +405,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
if (rb < 0) /* rb not initialized yet */
{
rb = bb >> (BITS_PER_MP_LIMB - 1);
- bb &= ~GMP_LIMB_HIGHBIT;
+ bb &= ~MPFR_LIMB_HIGHBIT;
}
fb = bb != 0;
} /* fb < 0 */
@@ -459,7 +459,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
if (rb < 0)
{
rb = cc >> (BITS_PER_MP_LIMB - 1);
- cc &= ~GMP_LIMB_HIGHBIT;
+ cc &= ~MPFR_LIMB_HIGHBIT;
}
while (cc == 0)
{
@@ -533,12 +533,12 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c,
if (mpn_add_1(ap, ap, an, MP_LIMB_T_ONE << sh))
{
mp_exp_t exp = MPFR_EXP(a);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
inex = mpfr_set_overflow(a, rnd_mode, MPFR_SIGN(a));
else
{
MPFR_EXP(a)++;
- ap[an-1] = GMP_LIMB_HIGHBIT;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
}
}
diff --git a/mpfr/add_one_ulp.c b/mpfr/add_one_ulp.c
index c4c5c2754..b831c254f 100644
--- a/mpfr/add_one_ulp.c
+++ b/mpfr/add_one_ulp.c
@@ -1,6 +1,6 @@
/* mpfr_add_one_ulp -- add one unit in last place
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -39,17 +39,17 @@ mpfr_add_one_ulp (mpfr_ptr x, mp_rnd_t rnd_mode)
return 0;
xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
- sh = xn * BITS_PER_MP_LIMB - MPFR_PREC(x);
+ sh = (mp_prec_t) 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)
+ if (exp == __gmpfr_emax)
return mpfr_set_overflow(x, rnd_mode, MPFR_SIGN(x));
else
{
MPFR_EXP(x)++;
- xp[xn-1] = GMP_LIMB_HIGHBIT;
+ xp[xn-1] = MPFR_LIMB_HIGHBIT;
}
}
return 0;
diff --git a/mpfr/add_ui.c b/mpfr/add_ui.c
index a5da63b8c..85908f67a 100644
--- a/mpfr/add_ui.c
+++ b/mpfr/add_ui.c
@@ -28,7 +28,6 @@ MA 02111-1307, USA. */
int
mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
{
-
if (u) /* if u=0, do nothing */
{
mpfr_t uu;
@@ -37,6 +36,7 @@ mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
int inex;
MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
count_leading_zeros(cnt, (mp_limb_t) u);
*up = (mp_limb_t) u << cnt;
MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt;
@@ -45,7 +45,8 @@ mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
if mpfr_add works even when uu is out-of-range. */
mpfr_save_emin_emax();
inex = mpfr_add(y, x, uu, rnd_mode);
- MPFR_RESTORE_RET(inex, y, rnd_mode);
+ mpfr_restore_emin_emax();
+ return mpfr_check_range(y, inex, rnd_mode);
}
else
return mpfr_set (y, x, rnd_mode);
diff --git a/mpfr/agm.c b/mpfr/agm.c
index 72ab12b21..9bfde443c 100644
--- a/mpfr/agm.c
+++ b/mpfr/agm.c
@@ -24,7 +24,7 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
-void
+int
mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
{
int s, go_on, compare;
@@ -38,16 +38,16 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
if (MPFR_IS_NAN(op1) || MPFR_IS_NAN(op2))
{
MPFR_SET_NAN(r);
- __mpfr_flags |= MPFR_FLAGS_NAN;
- return;
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ MPFR_RET_NAN;
}
/* If a or b is negative (including -Infinity), the result is NaN */
if ((MPFR_SIGN(op1) < 0) || (MPFR_SIGN(op2) < 0))
{
MPFR_SET_NAN(r);
- __mpfr_flags |= MPFR_FLAGS_NAN;
- return;
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ MPFR_RET_NAN;
}
MPFR_CLEAR_NAN(r);
@@ -57,7 +57,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
{
MPFR_SET_INF(r);
MPFR_SET_SAME_SIGN(r, op1);
- return;
+ MPFR_RET(0); /* exact */
}
MPFR_CLEAR_INF(r);
@@ -66,7 +66,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
if ((MPFR_NOTZERO(op1) && MPFR_NOTZERO(op2)) == 0)
{
MPFR_SET_ZERO(r);
- return;
+ MPFR_RET(0); /* exact */
}
/* precision of the following calculus */
@@ -98,7 +98,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
{
mpfr_set (r, op1, rnd_mode);
TMP_FREE(marker);
- return;
+ MPFR_RET(0); /* exact */
}
else
{
@@ -118,13 +118,13 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
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)));
+ err=1 + (int) ((3.0/2.0*(double)__gmpfr_ceil_log2((double)p)+1.0)*__gmpfr_ceil_exp2(-(double)p)
+ +3.0*__gmpfr_ceil_exp2(-2.0*(double)p*uo/(vo-uo)));
if(p-err-3<=q) {
p=q+err+4;
err= 1 +
- (int) ((3.0/2.0*_mpfr_ceil_log2((double)p)+1.0)*_mpfr_ceil_exp2(-(double)p)
- +3.0*_mpfr_ceil_exp2(-2.0*(double)p*uo/(vo-uo)));
+ (int) ((3.0/2.0*__gmpfr_ceil_log2((double)p)+1.0)*__gmpfr_ceil_exp2(-(double)p)
+ +3.0*__gmpfr_ceil_exp2(-2.0*(double)p*uo/(vo-uo)));
}
/* Calculus of un and vn */
@@ -167,5 +167,11 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mp_rnd_t rnd_mode)
/* Let's clean */
TMP_FREE(marker);
- return ;
+ return 1; /* agm(u,v) can be exact for u, v rational only for u=v.
+ Proof (due to Nicolas Brisebarre): it suffices to consider
+ u=1 and v<1. Then 1/AGM(1,v) = 2F1(1/2,1/2,1;1-v^2),
+ and a theorem due to G.V. Chudnovsky states that for x a
+ non-zero algebraic number with |x|<1, then
+ 2F1(1/2,1/2,1;x) and 2F1(-1/2,1/2,1;x) are algebraically
+ independent over Q. */
}
diff --git a/mpfr/asin.c b/mpfr/asin.c
index eb1b0f75a..f124b6447 100644
--- a/mpfr/asin.c
+++ b/mpfr/asin.c
@@ -1,6 +1,6 @@
/* mpfr_asin -- arc-sinus of a floating-point number
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library, and was contributed by Mathieu Dutour.
@@ -162,7 +162,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
else
{
- realprec += _mpfr_ceil_log2 ((double) realprec);
+ realprec += __gmpfr_ceil_log2 ((double) realprec);
#ifdef DEBUG
printf("RETRY\n");
#endif
diff --git a/mpfr/asinh.c b/mpfr/asinh.c
index 048a01db0..8ca8f41d7 100644
--- a/mpfr/asinh.c
+++ b/mpfr/asinh.c
@@ -1,4 +1,4 @@
-/* mpfr_asinh -- Inverse Hyperbolic Sinus of Unsigned Integer Number
+/* mpfr_asinh -- inverse hyperbolic sine
Copyright 2001, 2002 Free Software Foundation.
@@ -26,17 +26,18 @@ MA 02111-1307, USA. */
/* The computation of asinh is done by
- asinh= ln(x+sqrt(x^2+1))
+ 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 x, mp_rnd_t rnd_mode)
{
int inexact;
- mpfr_t x;
- int flag_neg=0;
- mp_prec_t Nx;
+ int neg = 0;
+ mp_prec_t Nx, Ny, Nt;
+ mpfr_t t, te, ti; /* auxiliary variables */
+ long int err;
- if (MPFR_IS_NAN(xt))
+ if (MPFR_IS_NAN(x))
{
MPFR_SET_NAN(y);
MPFR_RET_NAN;
@@ -44,87 +45,75 @@ mpfr_asinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
MPFR_CLEAR_NAN(y);
- if (MPFR_IS_INF(xt))
+ if (MPFR_IS_INF(x))
{
MPFR_SET_INF(y);
- MPFR_SET_SAME_SIGN(y, xt);
+ MPFR_SET_SAME_SIGN(y, x);
MPFR_RET(0);
}
MPFR_CLEAR_INF(y);
- if (MPFR_IS_ZERO(xt))
+ if (MPFR_IS_ZERO(x))
{
MPFR_SET_ZERO(y); /* asinh(0) = 0 */
- MPFR_SET_SAME_SIGN(y, xt);
+ MPFR_SET_SAME_SIGN(y, x);
MPFR_RET(0);
}
- Nx = MPFR_PREC(xt); /* Precision of input variable */
- mpfr_init2(x, Nx);
- mpfr_set(x, xt, GMP_RNDN);
+ Nx = MPFR_PREC(x); /* Precision of input variable */
+ Ny = MPFR_PREC(y); /* Precision of output variable */
- if (MPFR_SIGN(x) < 0)
- {
- MPFR_CHANGE_SIGN(x);
- flag_neg=1;
- }
+ neg = MPFR_SIGN(x) < 0;
/* General case */
- {
- /* Declaration of the intermediary variable */
- mpfr_t t, te,ti;
- /* 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 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+4+_mpfr_ceil_log2(Nt);
-
- /* initialise of intermediary variable */
- mpfr_init(t);
- mpfr_init(te);
- mpfr_init(ti);
-
- /* First computation of cosh */
- do {
-
- /* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(te,Nt);
- mpfr_set_prec(ti,Nt);
-
- /* compute asinh */
- mpfr_mul(te,x,x,GMP_RNDD); /* (x^2) */
- mpfr_add_ui(ti,te,1,GMP_RNDD); /* (x^2+1) */
- mpfr_sqrt(t,ti,GMP_RNDN); /* sqrt(x^2+1) */
- mpfr_add(t,t,x,GMP_RNDN); /* sqrt(x^2+1)+x */
- mpfr_log(t,t,GMP_RNDN); /* ln(sqrt(x^2+1)+x)*/
-
- /* estimation of the error see- algorithms.ps*/
- /*err=Nt-_mpfr_ceil_log2(1+pow(2,3-MPFR_EXP(t)));*/
- err=Nt-(MAX(3-MPFR_EXP(t),0)+1);
-
- /* actualisation of the precision */
- Nt += 10;
-
- } while ((err < 0) || (!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny) || (MPFR_IS_ZERO(t))));
-
- if(flag_neg)
- MPFR_CHANGE_SIGN(t);
-
- inexact = mpfr_set(y,t,rnd_mode);
-
- mpfr_clear(t);
- mpfr_clear(ti);
- mpfr_clear(te);
- }
- mpfr_clear(x);
- MPFR_RET(inexact);
+ /* compute the precision of intermediary variable */
+ Nt = MAX(Nx, Ny);
+
+ /* the optimal number of bits : see algorithms.ps */
+ Nt = Nt + 4 + __gmpfr_ceil_log2 (Nt);
+
+ /* initialize intermediary variables */
+ mpfr_init2 (t, 2);
+ mpfr_init2 (te, 2);
+ mpfr_init2 (ti, 2);
+
+ mpfr_save_emin_emax ();
+
+ /* First computation of asinh */
+ do {
+
+ /* reactualisation of the precision */
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ti, Nt);
+
+ /* compute asinh */
+ mpfr_mul (te, x, x, GMP_RNDD); /* x^2 */
+ mpfr_add_ui (ti, te, 1, GMP_RNDD); /* x^2+1 */
+ mpfr_sqrt (t, ti, GMP_RNDN); /* sqrt(x^2+1) */
+ ((neg) ? mpfr_sub : mpfr_add) (t, t, x, GMP_RNDN); /* sqrt(x^2+1)+x */
+ mpfr_log (t, t, GMP_RNDN); /* ln(sqrt(x^2+1)+x)*/
+
+ /* estimation of the error -- see algorithms.ps */
+ err = Nt - (MAX(3 - MPFR_EXP(t), 0) + 1);
+
+ /* actualisation of the precision */
+ Nt += 10;
+
+ } while ((err < 0) || (!mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny) || (MPFR_IS_ZERO(t))));
+
+ mpfr_restore_emin_emax ();
+
+ if (neg)
+ MPFR_CHANGE_SIGN(t);
+
+ inexact = mpfr_set (y, t, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
+
+ return mpfr_check_range (y, inexact, rnd_mode);
}
diff --git a/mpfr/atan.c b/mpfr/atan.c
index 34d75738f..73f34336c 100644
--- a/mpfr/atan.c
+++ b/mpfr/atan.c
@@ -1,6 +1,6 @@
/* mpfr_atan -- arc-tangent of a floating-point number
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library, and was contributed by Mathieu Dutour.
@@ -133,24 +133,24 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode)
MPFR_CHANGE_SIGN(arctangent);
mpfr_clear(Pisur2);
mpfr_clear(xp);
- return 0; /* Result correct */
+ return 1; /* inexact result */
}
if (comparaison > 0)
suplement = 2;
else
suplement = 2-MPFR_EXP(xp);
- prec_x = _mpfr_ceil_log2 ((double) MPFR_PREC(x) / BITS_PER_MP_LIMB);
- logn = _mpfr_ceil_log2 ((double) prec_x);
+ prec_x = __gmpfr_ceil_log2 ((double) MPFR_PREC(x) / BITS_PER_MP_LIMB);
+ logn = __gmpfr_ceil_log2 ((double) prec_x);
if (logn < 2) logn = 2;
- realprec = prec_arctan + _mpfr_ceil_log2((double) prec_arctan) + 4;
+ realprec = prec_arctan + __gmpfr_ceil_log2((double) prec_arctan) + 4;
mpz_init(ukz);
mpz_init(square);
while (!good){
- N0 = _mpfr_ceil_log2((double) realprec + suplement + CST);
- estimated_delta = 1 + suplement + _mpfr_ceil_log2((double) (3*N0-2));
+ N0 = __gmpfr_ceil_log2((double) realprec + suplement + CST);
+ estimated_delta = 1 + suplement + __gmpfr_ceil_log2((double) (3*N0-2));
Prec = realprec+estimated_delta;
/* Initialisation */
@@ -236,7 +236,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
else
{
- realprec += _mpfr_ceil_log2 ((double) realprec);
+ realprec += __gmpfr_ceil_log2 ((double) realprec);
}
mpfr_clear(sk);
diff --git a/mpfr/atanh.c b/mpfr/atanh.c
index c56b65e8f..9623c1c78 100644
--- a/mpfr/atanh.c
+++ b/mpfr/atanh.c
@@ -92,7 +92,7 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode)
/* compute the precision of intermediary variable */
Nt=MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+4+_mpfr_ceil_log2(Nt);
+ Nt=Nt+4+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
mpfr_init(t);
@@ -115,7 +115,7 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode)
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)));*/
+ /* err=Nt-__gmpfr_ceil_log2(1+5*pow(2,1-MPFR_EXP(t)));*/
err=Nt-(MAX(4-MPFR_EXP(t),0)+1);
/* actualisation of the precision */
diff --git a/mpfr/cbrt.c b/mpfr/cbrt.c
new file mode 100644
index 000000000..0a5da638b
--- /dev/null
+++ b/mpfr/cbrt.c
@@ -0,0 +1,148 @@
+/* mpfr_cbrt -- cube root function.
+
+Copyright 2002 Free Software Foundation.
+Contributed by the Spaces project, INRIA Lorraine.
+
+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 "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+ /* The computation of y = x^(1/3) is done as follows:
+
+ Let x = sign * m * 2^(3*e) where m is an integer
+
+ with 2^(3n-3) <= m < 2^(3n) where n = PREC(y)
+
+ and m = s^3 + r where 0 <= r and m < (s+1)^3
+
+ we want that s has n bits i.e. s >= 2^(n-1), or m >= 2^(3n-3)
+ i.e. m must have at least 3n-2 bits
+
+ then x^(1/3) = s * 2^e if r=0
+ x^(1/3) = (s+1) * 2^e if round up
+ x^(1/3) = (s-1) * 2^e if round down
+ x^(1/3) = s * 2^e if nearest and r < 3/2*s^2+3/4*s+1/8
+ (s+1) * 2^e otherwise
+ */
+
+int
+mpfr_cbrt (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
+{
+
+ mpz_t m;
+ mp_exp_t e, r, sh;
+ mp_prec_t n, size_m;
+ int inexact, sign_x;
+
+ /* special values */
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+
+ MPFR_CLEAR_NAN(y);
+
+ if (MPFR_IS_INF(x))
+ {
+ MPFR_SET_INF(y);
+ MPFR_SET_SAME_SIGN (y, x);
+ return 0;
+ }
+
+ MPFR_CLEAR_INF(y);
+
+ /* case 0: cbrt(+/- 0) = +/- 0 */
+ if (MPFR_IS_ZERO(x))
+ {
+ MPFR_SET_ZERO(y);
+ MPFR_SET_SAME_SIGN (y, x);
+ return 0;
+ }
+
+ sign_x = MPFR_SIGN(x);
+
+ mpz_init (m);
+
+ e = mpfr_get_z_exp (m, x); /* x = m * 2^e */
+ if (sign_x < 0)
+ mpz_neg (m, m);
+ r = e % 3;
+ if (r < 0)
+ r += 3;
+ /* x = (m*2^r) * 2^(e-r) = (m*2^r) * 2^(3*q) */
+
+ size_m = mpz_sizeinbase (m, 2);
+ n = MPFR_PREC(y);
+ if (rnd_mode == GMP_RNDN)
+ n ++;
+
+ /* we want 3*n-2 <= size_m + 3*sh + r <= 3*n
+ i.e. 3*sh + size_m + r <= 3*n */
+ sh = (3 * n - size_m - r) / 3;
+ sh = 3 * sh + r;
+ if (sh >= 0)
+ {
+ mpz_mul_2exp (m, m, sh);
+ e = e - sh;
+ }
+
+ /* invariant: x = m*2^e */
+
+ /* we reuse the variable m to store the cube root, since it is not needed
+ any more: we just need to know if the root is exact */
+ inexact = mpz_root (m, m, 3) == 0;
+
+ sh = mpz_sizeinbase (m, 2) - n;
+ if (sh > 0) /* we have to flush to 0 the last sh bits from m */
+ {
+ inexact = inexact || (mpz_scan1 (m, 0) < sh);
+ mpz_div_2exp (m, m, sh);
+ e += 3 * sh;
+ }
+
+ if (inexact)
+ {
+ if ((rnd_mode == GMP_RNDU) ||
+ ((rnd_mode == GMP_RNDN) && mpz_tstbit (m, 0)))
+ mpz_add_ui (m, m, inexact = 1);
+ else
+ inexact = -1;
+ }
+
+ /* either inexact is not zero, and the conversion is exact, i.e. inexact
+ is not changed; or inexact=0, and inexact is set only when
+ rnd_mode=GMP_RNDN and bit (n+1) from m is 1 */
+ inexact += mpfr_set_z (y, m, GMP_RNDN);
+ MPFR_EXP(y) += e / 3;
+
+ if (sign_x < 0)
+ {
+ mpfr_neg (y, y, GMP_RNDN);
+ inexact = -inexact;
+ }
+
+ mpz_clear (m);
+
+ return inexact;
+}
diff --git a/mpfr/cmp2.c b/mpfr/cmp2.c
index 42928ea47..57399b836 100644
--- a/mpfr/cmp2.c
+++ b/mpfr/cmp2.c
@@ -1,6 +1,6 @@
/* mpfr_cmp2 -- exponent shift when subtracting two numbers.
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
diff --git a/mpfr/cmp_abs.c b/mpfr/cmp_abs.c
index 5fa1d1cc7..d27ccd91d 100644
--- a/mpfr/cmp_abs.c
+++ b/mpfr/cmp_abs.c
@@ -1,6 +1,6 @@
-/* mpfr_cmp_abs -- compare the absolute values of two nonzero FP numbers
+/* mpfr_cmpabs -- compare the absolute values of two FP numbers
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -25,17 +25,22 @@ MA 02111-1307, USA. */
#include "mpfr-impl.h"
/* returns sign(abs(b) - abs(c))
- b and c must be nonzero real numbers */
+ b and c must be real numbers */
int
-mpfr_cmp_abs (mpfr_srcptr b, mpfr_srcptr c)
+mpfr_cmpabs (mpfr_srcptr b, mpfr_srcptr c)
{
mp_exp_t be, ce;
mp_size_t bn, cn;
mp_limb_t *bp, *cp;
- MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_NOTZERO(b));
- MPFR_ASSERTN(MPFR_IS_FP(c) && MPFR_NOTZERO(c));
+ MPFR_ASSERTN(MPFR_IS_FP(b));
+ MPFR_ASSERTN(MPFR_IS_FP(c));
+
+ if (MPFR_IS_ZERO(b))
+ return MPFR_IS_ZERO(c) ? 0 : -1;
+ if (MPFR_IS_ZERO(c))
+ return 1;
be = MPFR_EXP(b);
ce = MPFR_EXP(c);
diff --git a/mpfr/cmp_si.c b/mpfr/cmp_si.c
new file mode 100644
index 000000000..5666a102e
--- /dev/null
+++ b/mpfr/cmp_si.c
@@ -0,0 +1,93 @@
+/* mpfr_cmp_si_2exp -- compare a floating-point number with a signed
+machine integer multiplied by a power of 2
+
+Copyright 1999, 2001, 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 "longlong.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+/* returns a positive value if b > i*2^f,
+ a negative value if b < i*2^f,
+ zero if b = i*2^f.
+ b must not be NaN.
+*/
+
+int
+mpfr_cmp_si_2exp (mpfr_srcptr b, long int i, mp_exp_t f)
+{
+ int si;
+
+ MPFR_ASSERTN(!MPFR_IS_NAN(b));
+
+ si = i < 0 ? -1 : 1; /* sign of i */
+ if (MPFR_IS_INF(b) || (MPFR_NOTZERO(b) && MPFR_SIGN(b) != si))
+ return MPFR_SIGN(b);
+ /* both signs differ or b = 0 */
+ else if (MPFR_IS_ZERO(b))
+ return i != 0 ? -si : 0;
+ else if (i == 0)
+ return MPFR_SIGN(b);
+ else /* b and i are of same sign si */
+ {
+ mp_exp_t e;
+ unsigned long ai;
+ int k;
+ mp_size_t bn;
+ mp_limb_t c, *bp;
+
+ ai = SAFE_ABS(unsigned long, i);
+
+ /* ai must be representable in a mp_limb_t */
+ MPFR_ASSERTN(ai == (mp_limb_t) ai);
+
+ e = MPFR_EXP(b); /* 2^(e-1) <= b < 2^e */
+ if (e <= f)
+ return -si;
+ if (f < MPFR_EMAX_MAX - BITS_PER_MP_LIMB &&
+ e > f + BITS_PER_MP_LIMB)
+ return si;
+
+ /* now f < e <= f + BITS_PER_MP_LIMB */
+ c = (mp_limb_t) ai;
+ count_leading_zeros(k, c);
+ if ((int) (e - f) > BITS_PER_MP_LIMB - k)
+ return si;
+ if ((int) (e - f) < BITS_PER_MP_LIMB - k)
+ return -si;
+
+ /* now b and i*2^f have the same exponent */
+ c <<= k;
+ bn = (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB;
+ bp = MPFR_MANT(b);
+ if (bp[bn] > c)
+ return si;
+ if (bp[bn] < c)
+ return -si;
+
+ /* most significant limbs agree, check remaining limbs from b */
+ while (bn > 0)
+ if (bp[--bn])
+ return si;
+ return 0;
+ }
+}
diff --git a/mpfr/cmp_ui.c b/mpfr/cmp_ui.c
index 86d8ae55d..1e48bd618 100644
--- a/mpfr/cmp_ui.c
+++ b/mpfr/cmp_ui.c
@@ -1,4 +1,5 @@
-/* mpfr_cmp_ui -- compare a floating-point number with a machine integer
+/* mpfr_cmp_ui_2exp -- compare a floating-point number with an unsigned
+machine integer multiplied by a power of 2
Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
@@ -19,24 +20,21 @@ 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"
-/* returns a positive value if b>i*2^f,
- a negative value if b<i*2^f,
- zero if b=i*2^f
+/* returns a positive value if b > i*2^f,
+ a negative value if b < i*2^f,
+ zero if b = i*2^f.
+ b must not be NaN
*/
int
-mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, int f)
+mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, mp_exp_t f)
{
- int e, k, bn;
- mp_limb_t c, *bp;
-
MPFR_ASSERTN(!MPFR_IS_NAN(b));
if (MPFR_IS_INF(b))
@@ -44,85 +42,50 @@ mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, int f)
/* now b is neither NaN nor +/-Infinity */
if (MPFR_IS_ZERO(b))
- return i ? -1 : 0;
+ return i != 0 ? -1 : 0;
else if (MPFR_SIGN(b) < 0)
return -1;
- /* now b>0 */
+ /* now b > 0 */
else if (i == 0)
return 1;
- else
- { /* b>0, i>0 */
- e = MPFR_EXP(b); /* 2^(e-1) <= b < 2^e */
- if (e > f + BITS_PER_MP_LIMB)
- return 1;
-
- c = (mp_limb_t) i;
- count_leading_zeros(k, c);
- k = f + BITS_PER_MP_LIMB - k; /* 2^(k-1) <= i*2^f < 2^k */
- if (k != e)
- return e - k;
-
- /* now k=e */
- c <<= f + BITS_PER_MP_LIMB - k;
- bn = (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB;
- bp = MPFR_MANT(b) + bn;
- if (*bp > c)
- return 1;
- if (*bp < c)
- return -1;
+ else /* b > 0, i > 0 */
+ {
+ mp_exp_t e;
+ int k;
+ mp_size_t bn;
+ mp_limb_t c, *bp;
- /* most significant limbs agree, check remaining limbs from b */
- while (--bn >= 0)
- if (*--bp)
- return 1;
- return 0;
- }
-}
-
-/* returns a positive value if b>i*2^f,
- a negative value if b<i*2^f,
- zero if b=i*2^f
-*/
+ /* i must be representable in a mp_limb_t */
+ MPFR_ASSERTN(i == (mp_limb_t) i);
-int
-mpfr_cmp_si_2exp (mpfr_srcptr b, long int i, int f)
-{
- int e, k, bn, si;
- mp_limb_t c, *bp;
-
- MPFR_ASSERTN(!MPFR_IS_NAN(b));
-
- si = i < 0 ? -1 : 1; /* sign of i */
- if (MPFR_IS_INF(b) || (MPFR_NOTZERO(b) && MPFR_SIGN(b) != si))
- return MPFR_SIGN(b);
- /* both signs differ */
- else if (MPFR_IS_ZERO(b) || i == 0)
- return i == 0 ? (MPFR_IS_ZERO(b) ? 0 : MPFR_SIGN(b)) : -si;
- else
- { /* b and i are of same sign */
e = MPFR_EXP(b); /* 2^(e-1) <= b < 2^e */
- if (e > f + BITS_PER_MP_LIMB)
- return si;
+ if (e <= f)
+ return -1;
+ if (f < MPFR_EMAX_MAX - BITS_PER_MP_LIMB &&
+ e > f + BITS_PER_MP_LIMB)
+ return 1;
- c = i < 0 ? - (mp_limb_t) i : (mp_limb_t) i;
+ /* now f < e <= f + BITS_PER_MP_LIMB */
+ c = (mp_limb_t) i;
count_leading_zeros(k, c);
- k = f + BITS_PER_MP_LIMB - k; /* 2^(k-1) <= i*2^f < 2^k */
- if (k != e)
- return si * (e - k);
+ if ((int) (e - f) > BITS_PER_MP_LIMB - k)
+ return 1;
+ if ((int) (e - f) < BITS_PER_MP_LIMB - k)
+ return -1;
- /* now k = e */
- c <<= f + BITS_PER_MP_LIMB - k;
+ /* now b and i*2^f have the same exponent */
+ c <<= k;
bn = (MPFR_PREC(b) - 1) / BITS_PER_MP_LIMB;
- bp = MPFR_MANT(b) + bn;
- if (*bp > c)
- return si;
- if (*bp < c)
- return -si;
+ bp = MPFR_MANT(b);
+ if (bp[bn] > c)
+ return 1;
+ if (bp[bn] < c)
+ return -1;
/* most significant limbs agree, check remaining limbs from b */
- while (--bn >= 0)
- if (*--bp)
- return si;
+ while (bn > 0)
+ if (bp[--bn] != 0)
+ return 1;
return 0;
}
}
diff --git a/mpfr/comparisons.c b/mpfr/comparisons.c
new file mode 100644
index 000000000..5b861d229
--- /dev/null
+++ b/mpfr/comparisons.c
@@ -0,0 +1,71 @@
+/* comparison predicates
+
+Copyright 2002 Free Software Foundation.
+
+This file is part of the MPFR Library.
+Contributed by the Spaces project (LORIA/LIP6).
+
+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"
+
+/* Note: these functions currently use mpfr_cmp; they could have their
+ own code to be faster. */
+
+int
+mpfr_greater_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) > 0);
+}
+
+int
+mpfr_greaterequal_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) >= 0);
+}
+
+int
+mpfr_less_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) < 0);
+}
+
+int
+mpfr_lessequal_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) <= 0);
+}
+
+int
+mpfr_lessgreater_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) != 0);
+}
+
+int
+mpfr_equal_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) == 0);
+}
+
+int
+mpfr_unordered_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y);
+}
diff --git a/mpfr/const_euler.c b/mpfr/const_euler.c
index 91e55c8b3..0334f328b 100644
--- a/mpfr/const_euler.c
+++ b/mpfr/const_euler.c
@@ -37,7 +37,7 @@ mpfr_const_euler (mpfr_t x, mp_rnd_t rnd)
mpfr_t y, z;
unsigned long n;
- log2m = _mpfr_ceil_log2 ((double) prec);
+ log2m = __gmpfr_ceil_log2 ((double) prec);
m = prec + log2m;
mpfr_init (y);
@@ -83,7 +83,7 @@ mpfr_const_euler_S (mpfr_t x, unsigned long n)
N = (long) (ALPHA * (double) n + 1.0); /* ceil(alpha * n) */
m = MPFR_PREC(x) + (unsigned long) ((double) n / LOG2)
- + _mpfr_ceil_log2 ((double) N) + 1;
+ + __gmpfr_ceil_log2 ((double) N) + 1;
mpz_init_set_ui (a, 1);
mpz_mul_2exp (a, a, m); /* a=-2^m where m is the precision of x */
diff --git a/mpfr/const_log2.c b/mpfr/const_log2.c
index 73a946585..df7f29e59 100644
--- a/mpfr/const_log2.c
+++ b/mpfr/const_log2.c
@@ -1,6 +1,6 @@
/* mpfr_const_log2 -- compute natural logarithm of 2
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -27,8 +27,8 @@ MA 02111-1307, USA. */
#include "mpfr-impl.h"
mpfr_t __mpfr_const_log2; /* stored value of log(2) */
-mp_prec_t __mpfr_const_log2_prec=0; /* precision of stored value */
-mp_rnd_t __mpfr_const_log2_rnd; /* rounding mode of stored value */
+mp_prec_t __gmpfr_const_log2_prec = 0; /* precision of stored value */
+static 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));
@@ -65,10 +65,10 @@ mpfr_const_aux_log2 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
mp_prec_t prec_x;
mpz_init(cst);
- logn = _mpfr_ceil_log2 ((double) MPFR_PREC(mylog));
+ logn = __gmpfr_ceil_log2 ((double) MPFR_PREC(mylog));
prec_x = prec_i_want + logn;
while (!good){
- prec = _mpfr_ceil_log2 ((double) prec_x);
+ prec = __gmpfr_ceil_log2 ((double) prec_x);
mpfr_init2(tmp1, prec_x);
mpfr_init2(result, prec_x);
mpfr_init2(tmp2, prec_x);
@@ -134,10 +134,10 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
MPFR_CLEAR_FLAGS(x);
/* has stored value enough precision ? */
- if (precx <= __mpfr_const_log2_prec)
+ if (precx <= __gmpfr_const_log2_prec)
{
if ((rnd_mode == __mpfr_const_log2_rnd) ||
- mpfr_can_round (__mpfr_const_log2, __mpfr_const_log2_prec - 1,
+ mpfr_can_round (__mpfr_const_log2, __gmpfr_const_log2_prec - 1,
__mpfr_const_log2_rnd, rnd_mode, precx))
{
mpfr_set (x, __mpfr_const_log2, rnd_mode);
@@ -150,7 +150,7 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
{
/* 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;
+ N = precx + 2 * __gmpfr_ceil_log2 ((double) precx) + 1;
mpz_init (s); /* set to zero */
mpz_init (u);
@@ -176,12 +176,12 @@ mpfr_const_log2 (mpfr_ptr x, mp_rnd_t rnd_mode)
mpfr_const_aux_log2(x, rnd_mode);
/* store computed value */
- if (__mpfr_const_log2_prec == 0)
+ if (__gmpfr_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;
+ __gmpfr_const_log2_prec = precx;
__mpfr_const_log2_rnd = rnd_mode;
}
diff --git a/mpfr/const_pi.c b/mpfr/const_pi.c
index 88dc7300c..faad71abf 100644
--- a/mpfr/const_pi.c
+++ b/mpfr/const_pi.c
@@ -1,6 +1,6 @@
/* mpfr_const_pi -- compute Pi
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -53,11 +53,11 @@ mpfr_pi_machin3 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
mpz_t cst;
MPFR_CLEAR_FLAGS(mylog);
- logn = _mpfr_ceil_log2 ((double) MPFR_PREC(mylog));
+ logn = __gmpfr_ceil_log2 ((double) MPFR_PREC(mylog));
prec_x = prec_i_want + logn + 5;
mpz_init(cst);
while (!good){
- prec = _mpfr_ceil_log2 ((double) prec_x);
+ prec = __gmpfr_ceil_log2 ((double) prec_x);
mpfr_init2(tmp1, prec_x);
mpfr_init2(tmp2, prec_x);
@@ -149,8 +149,8 @@ so Pi*16^N-S'(N) <= N+1 (as 1/4/N^2 < 1)
*/
mpfr_t __mpfr_const_pi; /* stored value of Pi */
-int __mpfr_const_pi_prec=0; /* precision of stored value */
-mp_rnd_t __mpfr_const_pi_rnd; /* rounding mode of stored value */
+mp_prec_t __gmpfr_const_pi_prec = 0; /* precision of stored value */
+static mp_rnd_t __mpfr_const_pi_rnd; /* rounding mode of stored value */
void
mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
@@ -160,9 +160,9 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
prec=MPFR_PREC(x);
/* has stored value enough precision ? */
- if ((prec==__mpfr_const_pi_prec && rnd_mode==__mpfr_const_pi_rnd) ||
- (prec<=__mpfr_const_pi_prec &&
- mpfr_can_round(__mpfr_const_pi, __mpfr_const_pi_prec,
+ if ((prec==__gmpfr_const_pi_prec && rnd_mode==__mpfr_const_pi_rnd) ||
+ (prec<=__gmpfr_const_pi_prec &&
+ mpfr_can_round(__mpfr_const_pi, __gmpfr_const_pi_prec,
__mpfr_const_pi_rnd, rnd_mode, prec)))
{
mpfr_set(x, __mpfr_const_pi, rnd_mode); return;
@@ -173,7 +173,7 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
N=1;
do {
oldN = N;
- N = (prec+3)/4 + _mpfr_ceil_log2((double) N + 1.0);
+ N = (prec+3)/4 + __gmpfr_ceil_log2((double) N + 1.0);
} while (N != oldN);
mpz_init(pi); mpz_init(num); mpz_init(den); mpz_init(d3); mpz_init(d2);
mpz_init(tmp);
@@ -212,9 +212,9 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
} else
mpfr_pi_machin3(x, rnd_mode);
/* store computed value */
- if (__mpfr_const_pi_prec==0) mpfr_init2(__mpfr_const_pi, prec);
+ if (__gmpfr_const_pi_prec==0) mpfr_init2(__mpfr_const_pi, prec);
else mpfr_set_prec(__mpfr_const_pi, prec);
mpfr_set(__mpfr_const_pi, x, rnd_mode);
- __mpfr_const_pi_prec=prec;
+ __gmpfr_const_pi_prec=prec;
__mpfr_const_pi_rnd=rnd_mode;
}
diff --git a/mpfr/cos.c b/mpfr/cos.c
index 2d6b392fb..0e50df88e 100644
--- a/mpfr/cos.c
+++ b/mpfr/cos.c
@@ -47,7 +47,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
precy = MPFR_PREC(y);
- K0 = _mpfr_isqrt(precy / 2);
+ K0 = __gmpfr_isqrt(precy / 2);
/* we need at least K + log2(precy/K) extra bits */
m = precy + 3 * K0 + 3;
diff --git a/mpfr/cosh.c b/mpfr/cosh.c
index 8c95ea66e..98a40913d 100644
--- a/mpfr/cosh.c
+++ b/mpfr/cosh.c
@@ -77,7 +77,7 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode)
/* 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);
+ Nt=Nt+3+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
diff --git a/mpfr/div.c b/mpfr/div.c
index 9ece931a6..d8e4c3542 100644
--- a/mpfr/div.c
+++ b/mpfr/div.c
@@ -1,6 +1,6 @@
/* mpfr_div -- divide two floating-point numbers
-Copyright 1999, 2001 Free Software Foundation.
+Copyright 1999, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -249,8 +249,8 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode)
[eg. HI(vlo*q) = r => compare LO(vlo*q) with b.]
*/
- rem = TMP_ALLOC(rsize * BYTES_PER_MP_LIMB);
- rem2 = TMP_ALLOC(rsize * BYTES_PER_MP_LIMB);
+ rem = (mp_ptr) TMP_ALLOC(rsize * BYTES_PER_MP_LIMB);
+ rem2 = (mp_ptr) TMP_ALLOC(rsize * BYTES_PER_MP_LIMB);
rem[rsize - 1] = rem2 [rsize - 1] = 0;
@@ -337,7 +337,7 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode)
/* Hack : qp[qsize] is 0, 1 or 2, hence if not 0, = 2^(qp[qsize] - 1). */
{
near = mpn_rshift(qp, qp, qsize, qp[qsize]);
- qp[qsize - 1] |= GMP_LIMB_HIGHBIT; qexp += qp[qsize];
+ qp[qsize - 1] |= MPFR_LIMB_HIGHBIT; qexp += qp[qsize];
}
else
{
@@ -430,7 +430,7 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode)
if (cc)
{
mpn_rshift (qp, qp, qsize, 1);
- qp[qsize-1] |= GMP_LIMB_HIGHBIT;
+ qp[qsize-1] |= MPFR_LIMB_HIGHBIT;
qexp++;
}
}
diff --git a/mpfr/div_2si.c b/mpfr/div_2si.c
index f72f20eee..207f6e4b0 100644
--- a/mpfr/div_2si.c
+++ b/mpfr/div_2si.c
@@ -1,6 +1,6 @@
/* mpfr_div_2si -- divide a floating-point number by a power of two
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -33,12 +33,19 @@ mpfr_div_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
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))
+ if (n > 0 && (__gmpfr_emin > MPFR_EMAX_MAX - n ||
+ MPFR_EXP(y) < __gmpfr_emin + n))
+ {
+ if (rnd_mode == GMP_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX - (n - 1) ||
+ MPFR_EXP(y) < __gmpfr_emin + (n - 1) ||
+ mpfr_powerof2_raw (y)))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
+
+ if (n < 0 && (__gmpfr_emax < MPFR_EMIN_MIN - n ||
+ MPFR_EXP(y) > __gmpfr_emax + n))
return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y));
MPFR_EXP(y) -= n;
diff --git a/mpfr/div_2ui.c b/mpfr/div_2ui.c
index e95a8a74e..294ee85ab 100644
--- a/mpfr/div_2ui.c
+++ b/mpfr/div_2ui.c
@@ -1,6 +1,6 @@
/* mpfr_div_2ui -- divide a floating-point number by a power of two
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -45,12 +45,19 @@ mpfr_div_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mp_rnd_t rnd_mode)
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_EMAX_MAX - (long) n is signed and doesn't lead to an integer
+ overflow; the first test useful so that the real test can't lead
+ to an integer overflow. */
+ if (__gmpfr_emin > MPFR_EMAX_MAX - (long) n ||
+ MPFR_EXP(y) < __gmpfr_emin + (long) n)
+ {
+ if (rnd_mode == GMP_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX - (long) (n - 1) ||
+ MPFR_EXP(y) < __gmpfr_emin + (long) (n - 1) ||
+ mpfr_powerof2_raw (y)))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
MPFR_EXP(y) -= (long) n;
}
diff --git a/mpfr/div_ui.c b/mpfr/div_ui.c
index 0979ff75d..f263aa9c3 100644
--- a/mpfr/div_ui.c
+++ b/mpfr/div_ui.c
@@ -86,9 +86,10 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
/* we need to store yn+1 = xn + dif limbs of the quotient */
/* don't use tmp=yp since the mpn_lshift call below requires yp >= tmp+1 */
- tmp = TMP_ALLOC((yn + 1) * BYTES_PER_MP_LIMB);
+ tmp = (mp_limb_t*) TMP_ALLOC((yn + 1) * BYTES_PER_MP_LIMB);
c = (mp_limb_t) u;
+ MPFR_ASSERTN(u == c);
if (dif >= 0)
c = mpn_divrem_1 (tmp, dif, xp, xn, c); /* used all the dividend */
else /* dif < 0 i.e. xn > yn, don't use the (-dif) low limbs from x */
diff --git a/mpfr/dump.c b/mpfr/dump.c
index b6ff24cee..e6786c295 100644
--- a/mpfr/dump.c
+++ b/mpfr/dump.c
@@ -48,10 +48,10 @@ mpfr_dump (mpfr_srcptr u, mp_rnd_t rnd_mode)
return;
}
- str = mpfr_get_str (NULL, &exp, 10, 0, u, rnd_mode);
+ str = mpfr_get_str (NULL, &exp, 2, MPFR_PREC(u), u, rnd_mode);
if (str[0] == '-')
printf ("-0.%se%ld\n", str + 1, exp);
else
printf ("0.%se%ld\n", str, exp);
- (*__gmp_free_func) (str, strlen(str)+1);
+ (*__gmp_free_func) (str, strlen(str) + 1);
}
diff --git a/mpfr/exceptions.c b/mpfr/exceptions.c
index 63adb5a7c..c2bf923a7 100644
--- a/mpfr/exceptions.c
+++ b/mpfr/exceptions.c
@@ -1,6 +1,6 @@
/* Exception flags and utilities.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -24,17 +24,17 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
-unsigned int __mpfr_flags = 0;
+unsigned int __gmpfr_flags = 0;
-mp_exp_t __mpfr_emin = MPFR_EMIN_DEFAULT;
-mp_exp_t __mpfr_emax = MPFR_EMAX_DEFAULT;
+mp_exp_t __gmpfr_emin = MPFR_EMIN_DEFAULT;
+mp_exp_t __gmpfr_emax = MPFR_EMAX_DEFAULT;
#undef mpfr_get_emin
mp_exp_t
mpfr_get_emin (void)
{
- return __mpfr_emin;
+ return __gmpfr_emin;
}
#undef mpfr_set_emin
@@ -44,7 +44,7 @@ mpfr_set_emin (mp_exp_t exponent)
{
if (exponent >= MPFR_EMIN_MIN && exponent <= MPFR_EMIN_MAX)
{
- __mpfr_emin = exponent;
+ __gmpfr_emin = exponent;
return 0;
}
else
@@ -58,7 +58,7 @@ mpfr_set_emin (mp_exp_t exponent)
mp_exp_t
mpfr_get_emax (void)
{
- return __mpfr_emax;
+ return __gmpfr_emax;
}
#undef mpfr_set_emax
@@ -68,7 +68,7 @@ mpfr_set_emax (mp_exp_t exponent)
{
if (exponent >= MPFR_EMAX_MIN && exponent <= MPFR_EMAX_MAX)
{
- __mpfr_emax = exponent;
+ __gmpfr_emax = exponent;
return 0;
}
else
@@ -82,7 +82,7 @@ mpfr_set_emax (mp_exp_t exponent)
void
mpfr_clear_flags (void)
{
- __mpfr_flags = 0;
+ __gmpfr_flags = 0;
}
#undef mpfr_clear_underflow
@@ -90,7 +90,7 @@ mpfr_clear_flags (void)
void
mpfr_clear_underflow (void)
{
- __mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW;
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW;
}
#undef mpfr_clear_overflow
@@ -98,7 +98,7 @@ mpfr_clear_underflow (void)
void
mpfr_clear_overflow (void)
{
- __mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW;
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW;
}
#undef mpfr_clear_nanflag
@@ -106,7 +106,7 @@ mpfr_clear_overflow (void)
void
mpfr_clear_nanflag (void)
{
- __mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN;
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN;
}
#undef mpfr_clear_inexflag
@@ -114,23 +114,37 @@ mpfr_clear_nanflag (void)
void
mpfr_clear_inexflag (void)
{
- __mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT;
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT;
}
#undef mpfr_check_range
int
-mpfr_check_range (mpfr_ptr x, mp_rnd_t rnd_mode)
+mpfr_check_range (mpfr_ptr x, int t, mp_rnd_t rnd_mode)
{
if (MPFR_IS_FP(x) && MPFR_NOTZERO(x))
{ /* x is a non-zero FP */
mp_exp_t exp = MPFR_EXP(x);
- if (exp < __mpfr_emin)
- return mpfr_set_underflow(x, rnd_mode, MPFR_SIGN(x));
- if (exp > __mpfr_emax)
+ if (exp < __gmpfr_emin)
+ {
+ /* The following test is necessary because in the rounding to the
+ * nearest mode, mpfr_set_underflow always rounds away from 0. In
+ * this rounding mode, we need to round to 0 if:
+ * _ |x| < 2^(emin-2), or
+ * _ |x| = 2^(emin-2) and the absolute value of the exact
+ * result is <= 2^(emin-2).
+ */
+ if (rnd_mode == GMP_RNDN &&
+ (exp + 1 < __gmpfr_emin ||
+ (mpfr_powerof2_raw(x) &&
+ (MPFR_SIGN(x) < 0 ? t <= 0 : t >= 0))))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow(x, rnd_mode, MPFR_SIGN(x));
+ }
+ if (exp > __gmpfr_emax)
return mpfr_set_overflow(x, rnd_mode, MPFR_SIGN(x));
}
- return 0;
+ return t; /* propagate inexact ternary value, unlike most functions */
}
#undef mpfr_underflow_p
@@ -138,7 +152,7 @@ mpfr_check_range (mpfr_ptr x, mp_rnd_t rnd_mode)
int
mpfr_underflow_p (void)
{
- return __mpfr_flags & MPFR_FLAGS_UNDERFLOW;
+ return __gmpfr_flags & MPFR_FLAGS_UNDERFLOW;
}
#undef mpfr_overflow_p
@@ -146,7 +160,7 @@ mpfr_underflow_p (void)
int
mpfr_overflow_p (void)
{
- return __mpfr_flags & MPFR_FLAGS_OVERFLOW;
+ return __gmpfr_flags & MPFR_FLAGS_OVERFLOW;
}
#undef mpfr_nanflag_p
@@ -154,7 +168,7 @@ mpfr_overflow_p (void)
int
mpfr_nanflag_p (void)
{
- return __mpfr_flags & MPFR_FLAGS_NAN;
+ return __gmpfr_flags & MPFR_FLAGS_NAN;
}
#undef mpfr_inexflag_p
@@ -162,28 +176,27 @@ mpfr_nanflag_p (void)
int
mpfr_inexflag_p (void)
{
- return __mpfr_flags & MPFR_FLAGS_INEXACT;
+ return __gmpfr_flags & MPFR_FLAGS_INEXACT;
}
#undef mpfr_set_underflow
+/* Note: In the rounding to the nearest mode, mpfr_set_underflow
+ always rounds away from 0. In this rounding mode, you must call
+ mpfr_set_underflow with rnd_mode = GMP_RNDZ if the exact result
+ is <= 2^(emin-2) in absolute value. */
+
int
mpfr_set_underflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign)
{
int inex;
MPFR_CLEAR_FLAGS(x);
- if ((rnd_mode == GMP_RNDU && sign > 0)
- || (rnd_mode == GMP_RNDD && sign < 0))
+ if (rnd_mode == GMP_RNDN
+ || (rnd_mode == GMP_RNDU && sign > 0)
+ || (rnd_mode == GMP_RNDD && sign < 0))
{
- mp_size_t xn;
- mp_limb_t *xp;
-
- MPFR_EXP(x) = __mpfr_emin;
- xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB;
- xp = MPFR_MANT(x);
- xp[xn] = GMP_LIMB_HIGHBIT;
- MPN_ZERO(xp, xn);
+ mpfr_setmin (x, __gmpfr_emin);
inex = 1;
}
else
@@ -193,7 +206,7 @@ mpfr_set_underflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign)
}
if (MPFR_SIGN(x) != sign)
MPFR_CHANGE_SIGN(x);
- __mpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
+ __gmpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
return sign > 0 ? inex : -inex;
}
@@ -208,17 +221,7 @@ mpfr_set_overflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign)
if ((rnd_mode == GMP_RNDU && sign < 0)
|| (rnd_mode == GMP_RNDD && sign > 0))
{
- mp_size_t xn, i;
- int sh;
- mp_limb_t *xp;
-
- MPFR_EXP(x) = __mpfr_emax;
- xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
- sh = xn * BITS_PER_MP_LIMB - MPFR_PREC(x);
- xp = MPFR_MANT(x);
- xp[0] = MP_LIMB_T_MAX << sh;
- for (i = 1; i < xn; i++)
- xp[i] = MP_LIMB_T_MAX;
+ mpfr_setmax (x, __gmpfr_emax);
inex = -1;
}
else
@@ -228,6 +231,6 @@ mpfr_set_overflow (mpfr_ptr x, mp_rnd_t rnd_mode, int sign)
}
if (MPFR_SIGN(x) != sign)
MPFR_CHANGE_SIGN(x);
- __mpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
+ __gmpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
return sign > 0 ? inex : -inex;
}
diff --git a/mpfr/exp.c b/mpfr/exp.c
index 32d35ec8c..651c2ca32 100644
--- a/mpfr/exp.c
+++ b/mpfr/exp.c
@@ -69,15 +69,15 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
expx = MPFR_EXP(x);
precy = MPFR_PREC(y);
- /* result is +Inf when exp(x) >= 2^(__mpfr_emax), i.e.
- x >= __mpfr_emax * log(2) */
+ /* result is +Inf when exp(x) >= 2^(__gmpfr_emax), i.e.
+ x >= __gmpfr_emax * log(2) */
d = mpfr_get_d1 (x);
- if (d >= (double) __mpfr_emax * LOG2)
+ if (d >= (double) __gmpfr_emax * LOG2)
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)
+ /* result is 0 when exp(x) < 1/2*2^(__gmpfr_emin), i.e.
+ x < (__gmpfr_emin-1) * LOG2 */
+ if (d < ((double) __gmpfr_emin - 1.0) * LOG2)
return mpfr_set_underflow(y, rnd_mode, 1);
/* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */
@@ -85,17 +85,24 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
int signx = MPFR_SIGN(x);
- mpfr_set_ui (y, 1, rnd_mode);
+ if (signx < 0 && (rnd_mode == GMP_RNDD || rnd_mode == GMP_RNDZ))
+ {
+ MPFR_CLEAR_FLAGS(y);
+ MPFR_SET_POS(y);
+ mpfr_setmax (y, 0); /* y = 1 - epsilon */
+ return -1;
+ }
+ mpfr_setmin (y, 1); /* y = 1 */
if (signx > 0 && rnd_mode == GMP_RNDU)
- {
- 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, rnd_mode);
- return -1;
- }
+ {
+ mp_size_t yn;
+ int sh;
+
+ yn = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB;
+ sh = (mp_prec_t) yn * BITS_PER_MP_LIMB - MPFR_PREC(y);
+ MPFR_MANT(y)[0] += MP_LIMB_T_ONE << sh;
+ return 1;
+ }
return -signx;
}
diff --git a/mpfr/exp2.c b/mpfr/exp2.c
index 48cc8b95c..6f93c8eec 100644
--- a/mpfr/exp2.c
+++ b/mpfr/exp2.c
@@ -62,9 +62,9 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
if (MPFR_IS_ZERO(x))
return mpfr_set_ui (y, 1, rnd_mode);
- /* since the smallest representable non-zero float is 1/2*2^__mpfr_emin,
- if x < __mpfr_emin - 1, the result is either 1/2*2^__mpfr_emin or 0 */
- if (mpfr_cmp_si_2exp (x, __mpfr_emin - 1, 0) < 0)
+ /* since the smallest representable non-zero float is 1/2*2^__gmpfr_emin,
+ if x < __gmpfr_emin - 1, the result is either 1/2*2^__gmpfr_emin or 0 */
+ if (mpfr_cmp_si_2exp (x, __gmpfr_emin - 1, 0) < 0)
return mpfr_set_underflow (y, rnd_mode, 1);
/* General case */
@@ -82,7 +82,7 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* compute the precision of intermediary variable */
Nt = MAX(Nx, Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt = Nt + 5 + _mpfr_ceil_log2 (Nt);
+ Nt = Nt + 5 + __gmpfr_ceil_log2 (Nt);
/* initialise of intermediary variable */
@@ -105,7 +105,7 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
err = Nt - (MPFR_EXP(te) + 2);
/* actualisation of the precision */
- Nt += _mpfr_isqrt (Nt) + 10;
+ Nt += __gmpfr_isqrt (Nt) + 10;
} while ((err < 0) || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny));
diff --git a/mpfr/exp3.c b/mpfr/exp3.c
index 5ec4b65ee..ce022126b 100644
--- a/mpfr/exp3.c
+++ b/mpfr/exp3.c
@@ -77,7 +77,7 @@ mpfr_exp_rational (mpfr_ptr y, mpz_srcptr p, int r, int m)
l = 0;
accu = 0;
while (k > 0){
- mpz_mul(S[k], S[k], ptoj[_mpfr_ceil_log2((double) nb_terms[k])]);
+ mpz_mul(S[k], S[k], ptoj[__gmpfr_ceil_log2((double) nb_terms[k])]);
mpz_mul(S[k-1], S[k-1], P[k]);
accu += nb_terms[k];
mpz_mul_2exp(S[k-1], S[k-1], r* accu);
@@ -139,9 +139,9 @@ mpfr_exp3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* decompose x */
/* we first write x = 1.xxxxxxxxxxxxx
----- k bits -- */
- prec_x = _mpfr_ceil_log2 ((double) (MPFR_PREC(x)) / BITS_PER_MP_LIMB);
+ prec_x = __gmpfr_ceil_log2 ((double) (MPFR_PREC(x)) / BITS_PER_MP_LIMB);
if (prec_x < 0) prec_x = 0;
- logn = _mpfr_ceil_log2 ((double) prec_x + MPFR_PREC(y));
+ logn = __gmpfr_ceil_log2 ((double) prec_x + MPFR_PREC(y));
if (logn < 2) logn = 2;
ttt = MPFR_EXP(x);
mpfr_init2(x_copy,MPFR_PREC(x));
@@ -157,7 +157,7 @@ mpfr_exp3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpz_init (uk);
while (!good){
Prec = realprec+shift+2+shift_x;
- k = _mpfr_ceil_log2 ((double) Prec / BITS_PER_MP_LIMB);
+ k = __gmpfr_ceil_log2 ((double) Prec / BITS_PER_MP_LIMB);
/* now we have to extract */
mpfr_init2 (t, Prec);
diff --git a/mpfr/exp_2.c b/mpfr/exp_2.c
index 135f1d04c..52af6ffd3 100644
--- a/mpfr/exp_2.c
+++ b/mpfr/exp_2.c
@@ -33,7 +33,7 @@ static int mpz_normalize2 _PROTO ((mpz_t, mpz_t, int, int));
/* returns floor(sqrt(n)) */
unsigned long
-_mpfr_isqrt (unsigned long n)
+__gmpfr_isqrt (unsigned long n)
{
unsigned long s;
@@ -46,7 +46,7 @@ _mpfr_isqrt (unsigned long n)
/* returns floor(n^(1/3)) */
unsigned long
-_mpfr_cuberoot (unsigned long n)
+__gmpfr_cuberoot (unsigned long n)
{
double s, is;
@@ -118,9 +118,9 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* for the O(n^(1/2)*M(n)) method, the Taylor series computation of
n/K terms costs about n/(2K) multiplications when computed in fixed
point */
- K = (precy<SWITCH) ? _mpfr_isqrt((precy + 1) / 2) : _mpfr_cuberoot (4*precy);
+ K = (precy<SWITCH) ? __gmpfr_isqrt((precy + 1) / 2) : __gmpfr_cuberoot (4*precy);
l = (precy-1)/K + 1;
- err = K + (int) _mpfr_ceil_log2 (2.0 * (double) l + 18.0);
+ err = K + (int) __gmpfr_ceil_log2 (2.0 * (double) l + 18.0);
/* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */
q = precy + err + K + 3;
mpfr_init2 (r, q);
@@ -284,7 +284,7 @@ mpfr_exp2_aux2 (mpz_t s, mpfr_srcptr r, int q, int *exps)
/* estimate value of l */
l = q / (-MPFR_EXP(r));
- m = (int) _mpfr_isqrt (l);
+ m = (int) __gmpfr_isqrt (l);
/* we access R[2], thus we need m >= 2 */
if (m < 2) m = 2;
TMP_MARK(marker);
diff --git a/mpfr/expm1.c b/mpfr/expm1.c
index 0fc5af169..3980a4110 100644
--- a/mpfr/expm1.c
+++ b/mpfr/expm1.c
@@ -79,7 +79,7 @@ mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode)
/* compute the precision of intermediary variable */
Nt=MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+5+_mpfr_ceil_log2(Nt);
+ Nt=Nt+5+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
mpfr_init(t);
@@ -97,7 +97,7 @@ mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mp_rnd_t rnd_mode)
mpfr_sub_ui(t,te,1,GMP_RNDN); /* exp(x)-1 */
/* estimation of the error */
- /*err=Nt-(_mpfr_ceil_log2(1+pow(2,MPFR_EXP(te)-MPFR_EXP(t))));*/
+ /*err=Nt-(__gmpfr_ceil_log2(1+pow(2,MPFR_EXP(te)-MPFR_EXP(t))));*/
err=Nt-(MAX(MPFR_EXP(te)-MPFR_EXP(t),0)+1);
/* actualisation of the precision */
diff --git a/mpfr/factorial.c b/mpfr/factorial.c
index 0980308bd..d4f1992b9 100644
--- a/mpfr/factorial.c
+++ b/mpfr/factorial.c
@@ -56,7 +56,7 @@ mpfr_fac_ui (mpfr_ptr y, unsigned long int x , mp_rnd_t rnd_mode)
/* Initialisation of the Precision */
Ny=MPFR_PREC(y);
- Nt=Ny+2*(int)_mpfr_ceil_log2((double)x)+10; /*compute the size of intermediary variable */
+ Nt=Ny+2*(int)__gmpfr_ceil_log2((double)x)+10; /*compute the size of intermediary variable */
mpfr_init2(t, Nt);/* initialise of intermediary variable */
@@ -74,7 +74,7 @@ mpfr_fac_ui (mpfr_ptr y, unsigned long int x , mp_rnd_t rnd_mode)
inexact = round;
}
- err = Nt - 1 - (int) _mpfr_ceil_log2 ((double) Nt);
+ err = Nt - 1 - (int) __gmpfr_ceil_log2 ((double) Nt);
round = !inexact || mpfr_can_round (t,err,GMP_RNDZ,rnd_mode,Ny);
diff --git a/mpfr/frac.c b/mpfr/frac.c
new file mode 100644
index 000000000..acae125f1
--- /dev/null
+++ b/mpfr/frac.c
@@ -0,0 +1,121 @@
+/* mpfr_frac -- Fractional part of a floating-point number.
+
+Copyright 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 "longlong.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+int
+mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
+{
+ mp_exp_t re, ue;
+ mp_prec_t uq, fq;
+ mp_size_t un, tn, t0;
+ mp_limb_t *up, *tp, k;
+ int sh;
+ mpfr_t tmp;
+ mpfr_ptr t;
+
+ if (MPFR_IS_NAN(u))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ if (MPFR_IS_INF(u) || mpfr_isinteger(u))
+ {
+ MPFR_CLEAR_FLAGS(r);
+ MPFR_SET_SAME_SIGN(r, u);
+ MPFR_SET_ZERO(r);
+ MPFR_RET(0); /* zero is exact */
+ }
+
+ ue = MPFR_EXP(u);
+ if (ue <= 0) /* |u| < 1 */
+ return mpfr_set(r, u, rnd_mode);
+
+ uq = MPFR_PREC(u);
+ un = (uq - 1) / BITS_PER_MP_LIMB; /* index of most significant limb */
+ un -= (mp_size_t) (ue / BITS_PER_MP_LIMB);
+ /* now the index of the MSL containing bits of the fractional part */
+
+ up = MPFR_MANT(u);
+ sh = ue % BITS_PER_MP_LIMB;
+ k = up[un] << sh;
+
+ if (k != 0)
+ {
+ int cnt;
+
+ count_leading_zeros(cnt, k);
+ re = -cnt;
+ sh += cnt;
+ k <<= cnt;
+ }
+ else
+ {
+ re = sh - BITS_PER_MP_LIMB;
+ while ((k = up[--un]) == 0)
+ re -= BITS_PER_MP_LIMB;
+ MPFR_ASSERTN(un >= 0);
+ count_leading_zeros(sh, k);
+ re -= sh;
+ k <<= sh;
+ }
+ /* The exponent of r will be re */
+
+ ue -= re; /* number of bits of u to discard */
+ fq = uq - ue; /* number of bits of the fractional part of u */
+
+ t = fq > MPFR_PREC(r) ?
+ (mpfr_init2(tmp, (un + 1) * BITS_PER_MP_LIMB), tmp) : r;
+ /* t has enough precision to contain the fractional part of u */
+ /* If we use a temporary variable, we take the non-significant bits
+ of u into account, because of the mpn_lshift below. */
+ MPFR_CLEAR_FLAGS(t);
+ MPFR_SET_SAME_SIGN(t, u);
+ MPFR_EXP(t) = re;
+
+ /* Put the fractional part of u into t */
+ tn = (MPFR_PREC(t) - 1) / BITS_PER_MP_LIMB;
+ MPFR_ASSERTN(tn >= un);
+ t0 = tn - un;
+ tp = MPFR_MANT(t);
+ if (sh == 0)
+ MPN_COPY_DECR(tp + t0, up, un + 1);
+ else
+ tp[tn] = k | mpn_lshift(tp + t0, up, un, sh);
+ if (t0 > 0)
+ MPN_ZERO(tp, t0);
+
+ if (t != r)
+ { /* t is tmp */
+ int inex;
+
+ inex = mpfr_set(r, t, rnd_mode);
+ mpfr_clear(t);
+ return inex;
+ }
+ else
+ MPFR_RET(0);
+}
diff --git a/mpfr/gamma.c b/mpfr/gamma.c
new file mode 100644
index 000000000..c92bf496a
--- /dev/null
+++ b/mpfr/gamma.c
@@ -0,0 +1,217 @@
+/* mpfr_gamma -- gamma function
+
+Copyright 2001, 2002 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 <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+int mpfr_gamma _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
+
+/* We use the reflection formula
+ Gamma(1+t) Gamma(1-t) = - Pi t / sin(Pi (1 + t))
+ in order to treat the case x <= 1,
+ i.e. if x = 1-t, then Gamma(x) = -Pi*(1-x)/sin(Pi*(2-x))/GAMMA(2-x)
+*/
+
+#define CST 0.38 /* CST=ln(2)/(ln(2*pi)) */
+#define zCST 0.26 /* zCST=1/(2*ln(2*pi)) */
+#define ecCST 1.84 /* {1+sup_{x\in [0,1]} x*ln((1-x)/x)}/ln(2) */
+
+int
+mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
+{
+ mpfr_t xp;
+ mpfr_t product;
+ mpfr_t the_pi;
+ mpfr_t GammaTrial;
+ mpfr_t tmp, tmp2;
+
+ int Prec;
+ int prec_gamma;
+ int prec_nec;
+ int good = 0;
+ double C;
+ long A, N, estimated_cancel;
+ int realprec;
+ int compared;
+ int k;
+ int sign;
+
+ /* Trivial cases */
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(gamma);
+ return 1;
+ }
+
+ if (!MPFR_NOTZERO(x))
+ {
+ MPFR_SET_INF(gamma);
+ return 1;
+ }
+
+ if (MPFR_IS_INF(x))
+ {
+ MPFR_SET_INF(gamma);
+ return 1;
+ }
+
+ /* Set x_p=x if x> 1 else set x_p=2-x */
+ prec_gamma = MPFR_PREC (gamma);
+ compared = mpfr_cmp_ui (x, 1);
+ if (compared == 0)
+ {
+ mpfr_set_ui (gamma, 1, rnd_mode);
+ return 1;
+ }
+ realprec = prec_gamma + 10;
+
+ mpfr_init2 (xp, 2);
+
+ while (!good)
+ {
+ /* Precision stuff */
+ if (compared < 0)
+ {
+ prec_nec = 2+realprec; /* We will use the reflexion formula! */
+ }
+ else
+ {
+ prec_nec = realprec;
+ }
+ C = (double)(((double) prec_nec)*CST-0.5);
+ A = (int)C;
+ N = A-1;
+#ifdef DEBUG
+ printf("C=%u", (int)C);
+ printf(" A=%u", (int)A);
+ printf(" N=%u", (int)N);
+ printf("\n");
+#endif
+
+ /* estimated_cancel is the amount of bit that will be flushed */
+ estimated_cancel= (long) ceil(ecCST*A);
+ Prec = prec_nec + estimated_cancel+20;
+
+
+ mpfr_set_prec (xp, Prec);
+ if (compared < 0)
+ {
+ mpfr_ui_sub (xp, 1, x, GMP_RNDN);
+ }
+ else
+ {
+ mpfr_sub_ui (xp, x, 1, GMP_RNDN);
+ }
+
+ /* Initialisation */
+ mpfr_init2(tmp, Prec);
+ mpfr_init2(tmp2, Prec);
+ mpfr_init2(the_pi, Prec);
+ mpfr_init2(product, Prec);
+ mpfr_init2(GammaTrial, Prec);
+
+
+ mpfr_set_ui(GammaTrial, 0, GMP_RNDN);
+ sign=1;
+ for (k = 1; k<=N; k++)
+ {
+ mpfr_set_ui(tmp, A-k, GMP_RNDN);
+ mpfr_exp(product, tmp, GMP_RNDN);
+ mpfr_ui_pow_ui(tmp, A-k, k-1, GMP_RNDN);
+ mpfr_mul(product, product, tmp, GMP_RNDN);
+ mpfr_sqrt_ui(tmp, A-k, GMP_RNDN);
+ mpfr_mul(product, product, tmp, GMP_RNDN);
+ mpfr_fac_ui(tmp, k-1, GMP_RNDN);
+ mpfr_div(product, product, tmp, GMP_RNDN);
+ mpfr_add_ui(tmp, xp, k, GMP_RNDN);
+ mpfr_div(product, product, tmp, GMP_RNDN);
+ sign=-sign;
+ if (sign == 1)
+ {
+ mpfr_neg(product, product, GMP_RNDN);
+#ifdef DEBUG
+ /* printf(" k=%u", k);
+ printf("\n");*/
+#endif
+ }
+ mpfr_add(GammaTrial, GammaTrial, product, GMP_RNDN);
+ }
+#ifdef DEBUG
+ printf("GammaTrial =");
+ mpfr_out_str (stdout, 10, 0, GammaTrial, GMP_RNDD);
+ printf ("\n");
+#endif
+ mpfr_const_pi(the_pi, GMP_RNDN);
+ mpfr_const_pi(tmp, GMP_RNDN);
+ mpfr_mul_2ui(tmp, tmp, 1, GMP_RNDN);
+ mpfr_sqrt(tmp, tmp, GMP_RNDN);
+ mpfr_add(GammaTrial, GammaTrial, tmp, GMP_RNDN);
+ mpfr_add_ui(tmp2, xp, A, GMP_RNDN);
+ mpfr_set_ui(tmp, 1, GMP_RNDN);
+ mpfr_div_2ui(tmp, tmp, 1, GMP_RNDN);
+ mpfr_add(tmp, tmp, xp, GMP_RNDN);
+ mpfr_pow(tmp, tmp2, tmp, GMP_RNDN);
+ mpfr_mul(GammaTrial, GammaTrial, tmp, GMP_RNDN);
+ mpfr_neg(tmp, tmp2, GMP_RNDN);
+ mpfr_exp(tmp, tmp, GMP_RNDN);
+ mpfr_mul(GammaTrial, GammaTrial, tmp, GMP_RNDN);
+ if (compared < 0)
+ {
+ mpfr_sub_ui (tmp, x, 1, GMP_RNDN);
+ mpfr_mul (tmp, the_pi, tmp, GMP_RNDN);
+ mpfr_div (GammaTrial, tmp, GammaTrial, GMP_RNDN);
+ mpfr_sin (tmp, tmp, GMP_RNDN);
+ mpfr_div (GammaTrial, GammaTrial, tmp, GMP_RNDN);
+ }
+#ifdef DEBUG
+ printf("GammaTrial =");
+ mpfr_out_str (stdout, 10, 0, GammaTrial, GMP_RNDD);
+ printf ("\n");
+#endif
+ if (mpfr_can_round (GammaTrial, realprec, GMP_RNDD, rnd_mode, MPFR_PREC(gamma)))
+ {
+ mpfr_set (gamma, GammaTrial, rnd_mode);
+ good = 1;
+ }
+ else
+ {
+ realprec += __gmpfr_ceil_log2 ((double) realprec);
+#ifdef DEBUG
+ printf("RETRY\n");
+#endif
+ }
+ mpfr_clear(tmp);
+ mpfr_clear(tmp2);
+ mpfr_clear(the_pi);
+ mpfr_clear(product);
+ mpfr_clear(GammaTrial);
+ }
+
+ mpfr_clear (xp);
+
+ return 1; /* inexact result */
+}
+
diff --git a/mpfr/generic.c b/mpfr/generic.c
index 4955046de..e983797bc 100644
--- a/mpfr/generic.c
+++ b/mpfr/generic.c
@@ -1,6 +1,6 @@
/* generic file for evaluation of hypergeometric series using binary splitting
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
diff --git a/mpfr/get_d.c b/mpfr/get_d.c
index 917e721f0..8ea226eaa 100644
--- a/mpfr/get_d.c
+++ b/mpfr/get_d.c
@@ -116,6 +116,9 @@ mpfr_get_d3 (mpfr_srcptr src, mp_exp_t e, mp_rnd_t rnd_mode)
subnormal is 2^(-1074)=0.1e-1073 */
if (e < -1073)
{
+ /* Note: Avoid using a constant expression DBL_MIN * DBL_EPSILON
+ as this gives 0 instead of the correct result with gcc on some
+ Alpha machines. */
d = negative ?
(rnd_mode == GMP_RNDD ||
(rnd_mode == GMP_RNDN && mpfr_cmp_si_2exp(src, -1, -1075) < 0)
@@ -190,5 +193,5 @@ double
mpfr_get_d1 (mpfr_srcptr src)
{
return mpfr_get_d3 (src, MPFR_IS_FP(src) && MPFR_NOTZERO(src) ?
- MPFR_EXP(src) : 0, __gmp_default_rounding_mode);
+ MPFR_EXP(src) : 0, __gmpfr_default_rounding_mode);
}
diff --git a/mpfr/tests/dummy.c b/mpfr/get_exp.c
index de313e84d..1f09b9dbb 100644
--- a/mpfr/tests/dummy.c
+++ b/mpfr/get_exp.c
@@ -1,4 +1,4 @@
-/* Dummy file to stop libfrtests.a being empty.
+/* mpfr_get_exp - get the exponent of a floating-point number
Copyright 2002 Free Software Foundation.
@@ -19,4 +19,14 @@ 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. */
-int libfrtests_dummy = 0;
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+mp_exp_t
+mpfr_get_exp (mpfr_srcptr x)
+{
+ MPFR_ASSERTN(MPFR_IS_FP(x) && MPFR_NOTZERO(x));
+ return MPFR_EXP(x);
+}
diff --git a/mpfr/get_ld.c b/mpfr/get_ld.c
new file mode 100644
index 000000000..9ca8b81ab
--- /dev/null
+++ b/mpfr/get_ld.c
@@ -0,0 +1,121 @@
+/* mpfr_get_ld -- convert a multiple precision floating-point number
+ to a machine long double
+
+Copyright 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 <float.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+#ifndef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 113 /* works also if long double == quad */
+#endif
+
+#ifndef DBL_MANT_DIG
+#define DBL_MANT_DIG 53
+#endif
+
+long double
+mpfr_get_ld (mpfr_srcptr x, mp_rnd_t rnd_mode)
+{
+
+ if (!mpfr_number_p (x)) /* NaN or Inf: check before 0.0 */
+ {
+ return (long double) mpfr_get_d (x, rnd_mode);
+ }
+ else if (MPFR_IS_ZERO(x))
+ {
+ return MPFR_SIGN(x) < 0 ? -0.0 : 0.0;
+ }
+ else /* now x is a normal non-zero number */
+ {
+ long double r; /* result */
+ long double m;
+ double s; /* part of result */
+ mp_exp_t e; /* exponent of x */
+ mp_exp_t sh; /* exponent shift, so that x/2^sh is in the double range */
+ int negative;
+ mpfr_t y, z;
+
+ /* first round x to the target long double precision, so that
+ all subsequent operations are exact (this avoids double rounding
+ problems) */
+ mpfr_init2 (y, LDBL_MANT_DIG);
+ mpfr_set (y, x, rnd_mode);
+ negative = MPFR_SIGN(y) < 0;
+ e = MPFR_EXP(y);
+ if (e > 1024)
+ {
+ sh = e - 1024;
+ MPFR_EXP(y) = 1024;
+ }
+ else if (e < -1021)
+ {
+ sh = e + 1021;
+ MPFR_EXP(y) = -1021;
+ }
+ else
+ {
+ sh = 0;
+ }
+ /* now -1021 <= e - sh = EXP(y) <= 1024 */
+ r = 0.0;
+ mpfr_init2 (z, DBL_MANT_DIG);
+
+ do
+ {
+ s = mpfr_get_d (y, GMP_RNDN); /* high part of y */
+ r += (long double) s;
+ mpfr_set_d (z, s, rnd_mode); /* exact */
+ mpfr_sub (y, y, z, rnd_mode); /* exact */
+ }
+ while (MPFR_NOTZERO(y));
+
+ /* we now have to multiply back by 2^sh */
+ if (sh != 0)
+ {
+ if (sh > 0)
+ m = 2.0;
+ else
+ {
+ m = 0.5;
+ sh = -sh;
+ }
+ e = 1; /* invariant: m = 2^e */
+ while (sh)
+ {
+ if (sh % 2)
+ r = r * m;
+ sh >>= 1;
+ m = m * m;
+ e = e + e;
+ }
+ }
+
+ mpfr_clear (z);
+ mpfr_clear (y);
+
+ return r;
+ }
+
+}
diff --git a/mpfr/get_str.c b/mpfr/get_str.c
index e5799a2fb..9fe3f9729 100644
--- a/mpfr/get_str.c
+++ b/mpfr/get_str.c
@@ -1,6 +1,7 @@
/* mpfr_get_str -- output a floating-point number to a string
Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+This function was contributed by Alain Delplanque and Paul Zimmermann.
This file is part of the MPFR Library.
@@ -19,333 +20,785 @@ 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 <ctype.h>
#include "gmp.h"
#include "gmp-impl.h"
#include "longlong.h"
#include "mpfr.h"
#include "mpfr-impl.h"
-#define ERR 5
+static double _mpfr_ceil _PROTO ((double));
+static long mpn_exp _PROTO ((mp_limb_t *, mp_exp_t *, int, mp_exp_t, size_t));
+static int mpfr_get_str_aux _PROTO ((char *, mp_exp_t *, mp_limb_t *,
+ mp_size_t, mp_exp_t, long, int, size_t, mp_rnd_t));
+static mp_exp_t mpfr_get_str_compute_g _PROTO ((int, mp_exp_t));
-/*
- Convert op to a string in base 'base' with 'n' digits and writes the
- mantissa in 'str', the exponent in 'expptr'.
- The result is rounded wrt 'rnd_mode'.
+static char num_to_text[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- For op = 3.1416 we get str = "31416" and expptr=1.
- */
-char*
-mpfr_get_str (char *str, mp_exp_t *expptr, int base, size_t n,
- mpfr_srcptr op, mp_rnd_t rnd_mode)
-{
- int neg;
+/* for 2 <= b <= 36, log_b2[b-2] + log_b2_low[b-2] is a 76-bit upper
+ approximation of log(2)/log(b), with log_b2[b-2] having 23 significative
+ bits only. These approximations were computed with the following program.
- if (base < 2 || base > 36)
- return NULL;
+#include <stdio.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+double log_b2[35], log_b2_low[35];
+
+main()
+{
+ int beta;
+ mpfr_t l, l0;
- if (n == 0) /* determine n from precision of op */
+ for (beta=2;beta<=36;beta++)
{
- n = __mp_bases[base].chars_per_bit_exactly * MPFR_PREC(op);
- if (n < 2)
- n = 2;
+ mpfr_init2 (l, 77);
+ mpfr_set_ui (l, beta, GMP_RNDD);
+ mpfr_log2 (l, l, GMP_RNDD);
+ mpfr_ui_div (l, 1, l, GMP_RNDU);
+ mpfr_init2 (l0, 23);
+ mpfr_set (l0, l, GMP_RNDD);
+ mpfr_sub (l, l, l0, GMP_RNDU);
+ mpfr_round_prec (l, GMP_RNDU, 53);
+ log_b2[beta-2] = mpfr_get_d (l0, GMP_RNDU);
+ log_b2_low[beta-2] = mpfr_get_d (l, GMP_RNDU);
+ mpfr_clear (l0);
+ mpfr_clear (l);
}
- /* 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;
+ printf ("static const double log_b2[35] = {");
+ for (beta=2;beta<=36;beta++)
+ {
+ printf ("\n%1.20e", log_b2[beta-2]);
+ if (beta < 36) printf (",");
+ }
+ printf ("\n};\n");
- if (MPFR_IS_NAN(op))
+ printf ("static const double log_b2_low[35] = {");
+ for (beta=2;beta<=36;beta++)
{
- if (str == NULL)
- str = (*__gmp_allocate_func)(4);
- str[0] = 'N';
- str[1] = 'a';
- str[2] = 'N';
- str[3] = '\0';
- return str;
+ printf ("\n%1.20e", log_b2_low[beta-2]);
+ if (beta < 36) printf (",");
+ }
+ printf ("\n};\n");
+}
+*/
+
+
+static const double log_b2[35] = {
+ 1.00000000000000000000e+00,
+ 6.30929708480834960938e-01,
+ 5.00000000000000000000e-01,
+ 4.30676519870758056641e-01,
+ 3.86852800846099853516e-01,
+ 3.56207132339477539062e-01,
+ 3.33333313465118408203e-01,
+ 3.15464854240417480469e-01,
+ 3.01029980182647705078e-01,
+ 2.89064824581146240234e-01,
+ 2.78942942619323730469e-01,
+ 2.70238101482391357422e-01,
+ 2.62649476528167724609e-01,
+ 2.55958020687103271484e-01,
+ 2.50000000000000000000e-01,
+ 2.44650512933731079102e-01,
+ 2.39812463521957397461e-01,
+ 2.35408902168273925781e-01,
+ 2.31378197669982910156e-01,
+ 2.27670222520828247070e-01,
+ 2.24243819713592529297e-01,
+ 2.21064716577529907227e-01,
+ 2.18104273080825805664e-01,
+ 2.15338259935379028320e-01,
+ 2.12746024131774902344e-01,
+ 2.10309892892837524414e-01,
+ 2.08014577627182006836e-01,
+ 2.05846816301345825195e-01,
+ 2.03795045614242553711e-01,
+ 2.01849073171615600586e-01,
+ 1.99999988079071044922e-01,
+ 1.98239862918853759766e-01,
+ 1.96561604738235473633e-01,
+ 1.94959014654159545898e-01,
+ 1.93426400423049926758e-01
+};
+
+static const double log_b2_low[35] = {
+ 0.00000000000000000000e+00,
+ 4.50906224761620348192e-08,
+ 0.00000000000000000000e+00,
+ 3.82026349940294905572e-08,
+ 6.38844173335462308442e-09,
+ 5.47685446374516835508e-08,
+ 1.98682149251302105391e-08,
+ 2.25453112380810174096e-08,
+ 1.54813334901356166450e-08,
+ 1.73674161903183898500e-09,
+ 3.03180611272229558617e-09,
+ 5.29449283838722401896e-08,
+ 5.85090258233695360801e-08,
+ 4.12271221790330610183e-09,
+ 0.00000000000000000000e+00,
+ 2.91844949512882013763e-08,
+ 3.04617404727474892263e-09,
+ 1.11983643106657188415e-08,
+ 1.54897762641074502508e-08,
+ 2.61761247509117662805e-08,
+ 4.50398291018069050027e-09,
+ 1.28799738389232369510e-08,
+ 1.89047057535652783545e-08,
+ 1.91013174970147452786e-08,
+ 2.94215882512624420131e-08,
+ 2.49643149546191168760e-08,
+ 2.00493274507626165734e-08,
+ 1.61590886321114899524e-08,
+ 1.47626363632181082532e-09,
+ 1.34104842501325808254e-08,
+ 1.19209289550781256617e-08,
+ 2.51706771840338761560e-10,
+ 2.74945871340834855649e-08,
+ 7.23962676182708790191e-09,
+ 3.19422086667731154221e-09
+};
+
+/* copy most important limbs of {op, n2} in {rp, n1} */
+/* if n1 > n2 put 0 in low limbs of {rp, n1} */
+#define MPN_COPY2(rp, n1, op, n2) \
+ if ((n1) <= (n2)) \
+ { \
+ MPN_COPY ((rp), (op) + (n2) - (n1), (n1)); \
+ } \
+ else \
+ { \
+ MPN_COPY ((rp) + (n1) - (n2), (op), (n2)); \
+ MPN_ZERO ((rp), (n1) - (n2)); \
}
- neg = MPFR_SIGN(op) < 0; /* 0 if positive, 1 if negative */
+static double
+_mpfr_ceil (double x)
+{
+ double y = (double) (long int) x;
+ return ((y < x) ? y + 1.0 : y);
+}
- if (MPFR_IS_INF(op))
- {
- char *str0;
+/* this function computes an approximation of b^e in {a, n}, with exponent
+ stored in exp_r. The computed value is rounded towards zero (truncated).
+ It returns an integer f such that the final error is bounded by 2^f ulps,
+ that is:
+ a*2^exp_r <= b^e <= 2^exp_r (a + 2^f),
+ where a represents {a, n}, i.e. the integer
+ a[0] + a[1]*B + ... + a[n-1]*B^(n-1) where B=2^BITS_PER_MP_LIMB */
+static long
+mpn_exp (mp_limb_t *a, mp_exp_t *exp_r, int b, mp_exp_t e, size_t n)
+{
+ mp_limb_t *c, B;
+ mp_exp_t f, h;
+ int i;
+ unsigned long t; /* number of bits in e */
+ unsigned long bits;
+ size_t n1;
+ unsigned int erreur; /* (number - 1) of loop a^2b inexact */
+ /* erreur == t meens no error */
+ int err_s_a2 = 0;
+ int err_s_ab = 0; /* number of error when shift A^2, AB */
+ TMP_DECL(marker);
- 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 */
- }
+ MPFR_ASSERTN(e > 0);
+ MPFR_ASSERTN((2 <= b) && (b <= 36));
+
+ TMP_MARK(marker);
+
+ /* initialization of a, b, f, h */
+
+ /* normalize the base */
+ B = (mp_limb_t) b;
+ count_leading_zeros (h, B);
- /* op is a floating-point number */
+ bits = BITS_PER_MP_LIMB - h;
- if (MPFR_IS_ZERO(op))
+ B = B << h;
+ h = - h;
+
+ /* allocate space for A and set it to B */
+ c = (mp_limb_t*) TMP_ALLOC(2 * n * BYTES_PER_MP_LIMB);
+ a [n - 1] = B;
+ MPN_ZERO (a, n - 1);
+ /* initial exponent for A: invariant is A = {a, n} * 2^f */
+ f = h - (n - 1) * BITS_PER_MP_LIMB;
+
+ /* determine number of bits in e */
+ count_leading_zeros (t, (mp_limb_t) e);
+
+ t = BITS_PER_MP_LIMB - t; /* number of bits of exponent e */
+
+ erreur = t;
+
+ MPN_ZERO (c, 2 * n);
+
+ for (i = t - 2; i >= 0; i--)
{
- 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 */
+ /* determine precision needed */
+ bits = n * BITS_PER_MP_LIMB - mpn_scan1 (a, 0);
+ n1 = (n * BITS_PER_MP_LIMB - bits) / BITS_PER_MP_LIMB;
+
+ /* square of A : {c+2n1, 2(n-n1)} = {a+n1, n-n1}^2 */
+ mpn_sqr_n (c + 2 * n1, a + n1, n - n1);
+
+ /* set {c+n, 2n1-n} to 0 : {c, n} = {a, n}^2*K^n */
+
+ f = 2 * f + n * BITS_PER_MP_LIMB;
+ if ((c[2*n - 1] & MPFR_LIMB_HIGHBIT) == 0)
+ {
+ /* shift A by one bit to the left */
+ mpn_lshift (a, c + n, n, 1);
+ a[0] |= mpn_lshift (c + n - 1, c + n - 1, 1, 1);
+ f --;
+ if (erreur != t)
+ err_s_a2 ++;
+ }
+ else
+ MPN_COPY (a, c + n, n);
+
+ if ((erreur == t) && (2 * n1 <= n) &&
+ (mpn_scan1 (c + 2 * n1, 0) < (n - 2 * n1) * BITS_PER_MP_LIMB))
+ erreur = i;
+
+ if (e & (1 << i))
+ {
+ /* multiply A by B */
+ c[2 * n - 1] = mpn_mul_1 (c + n - 1, a, n, B);
+ f += h + BITS_PER_MP_LIMB;
+ if ((c[2 * n - 1] & MPFR_LIMB_HIGHBIT) == 0)
+ { /* shift A by one bit to the left */
+ mpn_lshift (a, c + n, n, 1);
+ a[0] |= mpn_lshift (c + n - 1, c + n - 1, 1, 1);
+ f --;
+ }
+ else
+ {
+ MPN_COPY (a, c + n, n);
+ if (erreur != t)
+ err_s_ab ++;
+ }
+ if ((erreur == t) && (c[n - 1] != 0))
+ erreur = i;
+
+ }
}
+
+ TMP_FREE(marker);
+
+ *exp_r = f;
+
+ if (erreur == t)
+ erreur = -1; /* exact */
else
{
- int str_is_null;
- int pow2;
- mp_exp_t e, f;
- mpfr_t a, b;
- mpz_t bz;
- char *str0;
- size_t len;
+ /* if there are p loops after the first inexact result, with
+ j shifts in a^2 and l shifts in a*b, then the final error is
+ at most 2^(p+ceil((j+1)/2)+l+1)*ulp(res).
+ This is bounded by 2^(5/2*t-1/2) where t is the number of bits of e.
+ */
+ erreur = erreur + err_s_ab + err_s_a2 / 2 + 3;
+ if ((erreur - 1) >= ((n * BITS_PER_MP_LIMB - 1) / 2))
+ erreur = n * BITS_PER_MP_LIMB; /* completely wrong: this is very
+ unlikely to happen since erreur is
+ at most 5/2*log_2(e), and
+ n * BITS_PER_MP_LIMB is at least
+ 3*log_2(e) */
+ }
- str_is_null = str == NULL;
+ return erreur;
+}
- 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
+
+/* Input: an approximation r*2^f of an real Y, with |r*2^f-Y| <= 2^(e+f).
+ Returns if possible in the string s the mantissa corresponding to
+ the integer nearest to Y, within the direction rnd, and returns the
+ the exponent in exp.
+ n is the number of limbs of r.
+ e represents the maximal error in the approximation of Y
+ (e < 0 iff the approximation is exact, i.e. r*2^f = Y).
+ b is the wanted base (2 <= b <= 36).
+ m is the number of wanted digits in the mantissa.
+ rnd is the rounding mode.
+ It is assumed that b^(m-1) <= Y < b^(m+1), thus the returned value
+ satisfies b^(m-1) <= rnd(Y) < b^(m+1).
+
+ Return value:
+ - the direction of rounding (-1, 0, 1) if rounding is possible
+ - 2 otherwise (rounding is not possible)
+*/
+static int
+mpfr_get_str_aux (char *str, mp_exp_t *exp, mp_limb_t *r, mp_size_t n,
+ mp_exp_t f, long e, int b, size_t m, mp_rnd_t rnd)
+{
+ int dir; /* direction of the rounded result */
+ mp_limb_t ret = 0; /* possible carry in addition */
+ mp_size_t i0, j0; /* number of limbs and bits of Y */
+ unsigned char *str1; /* string of m+2 characters */
+ size_t size_s1; /* length of str1 */
+ mp_rnd_t rnd1;
+ size_t i;
+ int exact = (e < 0);
+ TMP_DECL(marker);
+
+ /* if f > 0, then the maximal error 2^(e+f) is larger than 2 so we can't
+ determine the integer Y */
+ MPFR_ASSERTN(f <= 0);
+ /* if f is too small, then r*2^f is smaller than 1 */
+ MPFR_ASSERTN(f > (-n * BITS_PER_MP_LIMB));
+
+ TMP_MARK(marker);
+
+ /* R = 2^f sum r[i]K^(i)
+ r[i] = (r_(i,k-1)...r_(i,0))_2
+ R = sum r(i,j)2^(j+ki+f)
+ the bits from R are referenced by pairs (i,j) */
+
+ /* check if is possible to round r with rnd mode
+ where |r*2^f-Y| <= 2^(e+f)
+ the exponent of R is: f + n*BITS_PER_MP_LIMB
+ we must have e + f == f + n*BITS_PER_MP_LIMB - err
+ err = n*BITS_PER_MP_LIMB - e
+ R contains exactly -f bits after the integer point:
+ to determine the nearest integer, we thus need a precision of
+ n * BITS_PER_MP_LIMB + f */
+
+ if (exact || mpfr_can_round_raw (r, n, (mp_size_t) 1,
+ n * BITS_PER_MP_LIMB - e, GMP_RNDN, rnd, n * BITS_PER_MP_LIMB + f))
+ {
+ /* compute the nearest integer to R */
+
+ /* bit of weight 0 in R has position j0 in limb r[i0] */
+ i0 = (-f) / BITS_PER_MP_LIMB;
+ j0 = (-f) % BITS_PER_MP_LIMB;
+
+ ret = mpfr_round_raw_generic (r + i0, r, n * BITS_PER_MP_LIMB, 0,
+ n * BITS_PER_MP_LIMB + f, rnd, &dir, 0);
+
+ /* warning: mpfr_round_raw_generic returns 2 or -2 in case of even
+ rounding */
+ if (dir > 0) /* when dir = MPFR_EVEN_INEX */
+ dir = 1;
+ else if (dir < 0) /* when dir = -MPFR_EVEN_INEX */
+ dir = -1;
+
+ if (ret) /* Y is a power of 2 */
+ {
+ if (j0)
+ r[n - 1] = MPFR_LIMB_HIGHBIT >> (j0 - 1);
+ else /* j0=0, necessarily i0 >= 1 otherwise f=0 and r is exact */
+ {
+ r[n - 1] = ret;
+ r[--i0] = 0; /* set to zero the new low limb */
+ }
+ }
+ else /* shift r to the right by (-f) bits (i0 already done) */
+ {
+ if (j0)
+ mpn_rshift (r + i0, r + i0, n - i0, j0);
+ }
+
+ /* now the rounded value Y is in {r+i0, n-i0} */
+
+ /* convert r+i0 into base b */
+ str1 = (unsigned char*) TMP_ALLOC (m + 3); /* need one extra character for mpn_get_str */
+ size_s1 = mpn_get_str (str1, b, r + i0, n - i0);
+
+ /* round str1 */
+ MPFR_ASSERTN(size_s1 >= m);
+ *exp = size_s1 - m; /* number of superfluous characters */
+
+ /* if size_s1 = m + 2, necessarily we have b^(m+1) as result,
+ and the result will not change */
+
+ /* so we have to double-round only when size_s1 = m + 1 and
+ (i) the result is inexact
+ (ii) or the last digit is non-zero */
+ if ((size_s1 == m + 1) && ((dir != 0) || (str1[size_s1 - 1] != 0)))
{
- double d;
-
- d = mpfr_get_d3(op, 0, GMP_RNDN);
- 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)
+ /* rounding mode */
+ rnd1 = rnd;
+
+ /* round to nearest case */
+ if (rnd == GMP_RNDN)
{
- MPFR_ASSERTN(f < MP_EXP_T_MAX);
- f++;
+ if (2 * str1[size_s1 - 1] == b)
+ {
+ if (dir == -1)
+ rnd1 = GMP_RNDU;
+ else if (dir == 0) /* exact: even rounding */
+ {
+ if (exact)
+ rnd1 = ((str1[size_s1-2] & 1) == 0)
+ ? GMP_RNDD : GMP_RNDU;
+ else
+ goto cannot_round;
+ }
+ else
+ rnd1 = GMP_RNDD;
+ }
+ else if (2 * str1[size_s1 - 1] < b)
+ rnd1 = GMP_RNDD;
+ else
+ rnd1 = GMP_RNDU;
}
+
+ /* now rnd1 is either GMP_RNDD or GMP_RNDZ -> truncate
+ or GMP_RDNU -> round towards infinity */
+
+ /* round away from zero */
+ if (rnd1 == GMP_RNDU)
+ {
+ if (str1[size_s1 - 1] != 0)
+ {
+ /* the carry cannot propagate to the whole string, since
+ Y = x*b^(m-g) < 2*b^m <= b^(m+1)-b
+ where x is the input float */
+ MPFR_ASSERTN(size_s1 >= 2);
+ i = size_s1 - 2;
+ while (str1[i] == b - 1)
+ {
+ MPFR_ASSERTD(i > 0);
+ str1[i--] = 0;
+ }
+ str1[i]++;
+ }
+ dir = 1;
+ }
+ /* round toward zero (truncate) */
+ else
+ dir = -1;
}
- mpfr_init (a);
- mpfr_init (b);
- mpz_init (bz);
+ /* copy str1 into str and convert to ASCII */
+ for (i = 0; i < m; i++)
+ str[i] = num_to_text[(int) str1[i]];
+ str[m] = 0;
+ }
+ /* mpfr_can_round_raw failed: rounding is not possible */
+ else
+ {
+ cannot_round:
+ dir = 2;
+ }
+
+ TMP_FREE(marker);
- str0 = str;
+ return (dir);
+}
- do
- {
- mp_prec_t prec, q;
+/* returns ceil(e/log_2(beta)) */
+static mp_exp_t
+mpfr_get_str_compute_g (int beta, mp_exp_t e)
+{
+ double g0, g1;
+ mp_exp_t g;
+
+ g0 = (double) e * log_b2[beta - 2];
+ g1 = (double) e * log_b2_low[beta - 2];
+ g = (mp_exp_t) _mpfr_ceil (g0);
+ g0 -= (double) g;
+ return g + (mp_exp_t) _mpfr_ceil (g0 + g1);
+}
- /* 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;
+/* prints the mantissa of x in the string s, and writes the corresponding
+ exponent in e.
+ x is rounded with direction rnd, m is the number of digits of the mantissa,
+ b is the given base (2 <= b <= 36).
- d = (double) n / __mp_bases[base].chars_per_bit_exactly;
- MPFR_ASSERTN(d <= MPFR_INTPREC_MAX - 1);
- prec = (mp_prec_t) d + 1;
- }
+ Return value:
+ if s=NULL, allocates a string to store the mantissa, with
+ m characters, plus a final '\0', plus a possible minus sign
+ (thus m+1 or m+2 characters).
- 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);
+ Important: when you call this function with s=NULL, don't forget to free
+ the memory space allocated, with free(s, strlen(s)).
+*/
+char*
+mpfr_get_str (char *s, mp_exp_t *e, int b, size_t m, mpfr_srcptr x, mp_rnd_t rnd)
+{
+ int exact; /* exact result */
+ mp_exp_t exp, g;
+ mp_exp_t prec, log_2prec; /* precision of the computation */
+ long err;
+ mp_limb_t *a;
+ mp_exp_t exp_a;
+ mp_limb_t *result;
+ mp_limb_t *xp, *x1;
+ mp_limb_t *reste;
+ size_t nx, nx1;
+ size_t n, i;
+ char *s0;
+ int neg;
- while (1)
- {
- mp_exp_unsigned_t p;
- int div;
+ /* if exact = 1 then err is undefined */
+ /* otherwise err is such that |x*b^(m-g)-a*2^exp_a| < 2^(err+exp_a) */
- 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;
- }
+ TMP_DECL(marker);
- 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);
- }
- }
+ /* is the base valid? */
+ if (b < 2 || b > 36)
+ return NULL;
- if (neg)
- MPFR_CHANGE_SIGN(b); /* put b positive */
+ if (m == 0)
+ {
+ m = (size_t) _mpfr_ceil (__mp_bases[b].chars_per_bit_exactly
+ * (double) MPFR_PREC(x));
+ if (m < 2)
+ m = 2;
+ }
- 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;
+ /* 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. */
+ MPFR_ASSERTN (m >= 2);
- MPFR_ASSERTN(q <= MPFR_INTPREC_MAX - BITS_PER_MP_LIMB);
- q += BITS_PER_MP_LIMB;
- }
+ if (MPFR_IS_NAN(x))
+ {
+ if (s == NULL)
+ s = (char*) (*__gmp_allocate_func) (4);
+ strcpy (s, "NaN");
+ return s;
+ }
- {
- mp_rnd_t rnd = rnd_mode;
+ neg = MPFR_SIGN(x) < 0; /* 0 if positive, 1 if negative */
- if (neg)
- switch (rnd_mode)
- {
- case GMP_RNDU: rnd = GMP_RNDZ; break;
- case GMP_RNDD: rnd = GMP_RNDU; break;
- }
+ if (MPFR_IS_INF(x))
+ {
+ if (s == NULL)
+ s = (char*) (*__gmp_allocate_func) (neg + 4);
+ strcpy (s, (neg) ? "-Inf" : "Inf");
+ return s;
+ }
- 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));
+ /* x is a floating-point number */
+
+ if (MPFR_IS_ZERO(x))
+ {
+ if (s == NULL)
+ s = (char*) (*__gmp_allocate_func) (neg + m + 1);
+ s0 = s;
+ if (neg)
+ *s++ = '-';
+ memset (s, '0', m);
+ s[m] = '\0';
+ *e = 0; /* a bit like frexp() in ISO C99 */
+ return s0; /* strlen(s0) = neg + m */
+ }
+
+ /* si x < 0, on se ram`ene au cas x > 0 */
+ if (neg)
+ {
+ switch (rnd)
+ {
+ case GMP_RNDU : rnd = GMP_RNDD; break;
+ case GMP_RNDD : rnd = GMP_RNDU; break;
+ }
+ }
- if (len == n - 1)
+ if (s == NULL)
+ s = (char*) (*__gmp_allocate_func) (neg + m + 1);
+ s0 = s;
+ if (neg)
+ *s++ = '-';
+
+ xp = MPFR_MANT(x);
+
+ if (IS_POW2(b))
+ {
+ int pow2;
+ mp_exp_t f, r;
+ mp_limb_t *x1;
+ mp_size_t nb;
+ int inexp;
+
+ count_leading_zeros (pow2, (mp_limb_t) b);
+ pow2 = BITS_PER_MP_LIMB - pow2 - 1; /* base = 2^pow2 */
+
+ /* set MPFR_EXP(x) = f*pow2 + r, 1 <= r <= pow2 */
+ f = (MPFR_EXP(x) - 1) / pow2;
+ r = MPFR_EXP(x) - f * pow2;
+ if (r <= 0)
+ {
+ f --;
+ r += pow2;
+ }
+
+ /* the first digit will contain only r bits */
+ prec = (m - 1) * pow2 + r;
+ n = (prec - 1) / BITS_PER_MP_LIMB + 1;
+
+ TMP_MARK (marker);
+ x1 = (mp_limb_t*) TMP_ALLOC((n + 1) * sizeof (mp_limb_t));
+ nb = n * BITS_PER_MP_LIMB - prec;
+ /* round xp to the precision prec, and put it into x1
+ put the carry into x1[n] */
+ if ((x1[n] = mpfr_round_raw_generic (x1, xp, MPFR_PREC(x), MPFR_ISNEG(x),
+ prec, rnd, &inexp, 0)))
{
- len++;
- f--;
- str[n-1]='0';
- str[n]='\0';
+ /* overflow when rounding x: x1 = 2^prec */
+ if (r == pow2) /* prec = m * pow2,
+ 2^prec will need (m+1) digits in base 2^pow2 */
+ {
+ /* divide x1 by 2^pow2, and increase the exponent */
+ mpn_rshift (x1, x1, n + 1, pow2);
+ f ++;
+ }
+ else /* 2^prec needs still m digits, but x1 may need n+1 limbs */
+ n ++;
}
+
+ /* it remains to shift x1 by nb limbs to the right, since mpn_get_str
+ expects a right-normalized number */
+ if (nb != 0)
+ {
+ mpn_rshift (x1, x1, n, nb);
+ /* the most significant word may be zero */
+ if (x1[n - 1] == 0)
+ n --;
+ }
+
+ mpn_get_str ((unsigned char*) s, b, x1, n);
+ for (i=0; i<m; i++)
+ s[i] = num_to_text[(int) s[i]];
+ s[m] = 0;
+
+ /* the exponent of s is f + 1 */
+ *e = f + 1;
+
+ TMP_FREE(marker);
+
+ return (s0);
+ }
+
+ g = mpfr_get_str_compute_g (b, MPFR_EXP(x) - 1);
+ exact = 1;
+ prec = (mp_exp_t) _mpfr_ceil ((double) m / log_b2[b-2]) + 1;
+ exp = ((mp_exp_t) m < g) ? g - (mp_exp_t) m : (mp_exp_t) m - g;
+ log_2prec = (mp_exp_t) __gmpfr_ceil_log2 ((double) prec);
+ prec += log_2prec; /* number of guard bits */
+ if (exp != 0) /* add maximal exponentiation error */
+ prec += 3 * (mp_exp_t) __gmpfr_ceil_log2 ((double) exp);
+
+ for (;;)
+ {
+ TMP_MARK(marker);
+
+ exact = 1;
- *expptr = f;
- mpfr_clear (a);
- mpfr_clear (b);
- mpz_clear (bz);
+ /* number of limbs */
+ n = 1 + (prec - 1) / BITS_PER_MP_LIMB;
+
+ /* a will contain the approximation of the mantissa */
+ a = (mp_limb_t*) TMP_ALLOC (n * sizeof (mp_limb_t));
+
+ nx = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
+
+ if ((mp_exp_t) m == g) /* final exponent is 0, no multiplication or
+ division to perform */
+ {
+ if (nx > n)
+ exact = mpn_scan1 (xp, 0) >= (nx - n) * BITS_PER_MP_LIMB;
+ err = !exact;
+ MPN_COPY2 (a, n, xp, nx);
+ exp_a = MPFR_EXP(x) - n * BITS_PER_MP_LIMB;
+ }
+ else if ((mp_exp_t) m > g) /* we have to multiply x by b^exp */
+ {
+ /* a2*2^exp_a = b^e */
+ err = mpn_exp (a, &exp_a, b, exp, n);
+ /* here, the error on a is at most 2^err ulps */
+ exact = (err == -1);
+
+ /* x = x1*2^(n*BITS_PER_MP_LIMB) */
+ x1 = (nx >= n) ? xp + nx - n : xp;
+ nx1 = (nx >= n) ? n : nx; /* nx1 = min(n, nx) */
+
+ /* test si exact */
+ if (nx > n)
+ exact = (exact &&
+ ((mpn_scan1 (xp, 0) >= (nx - n) * BITS_PER_MP_LIMB)));
+
+ /* we loose one more bit in the multiplication,
+ except when err=0 where we loose two bits */
+ err = (err <= 0) ? 2 : err + 1;
+
+ /* result = a * x */
+ result = (mp_limb_t*) TMP_ALLOC ((n + nx1) * sizeof (mp_limb_t));
+ mpn_mul (result, a, n, x1, nx1);
+ exp_a += MPFR_EXP (x);
+ if (mpn_scan1 (result, 0) < (nx1 * BITS_PER_MP_LIMB))
+ exact = 0;
+
+ /* normalize a and truncate */
+ if ((result[n + nx1 - 1] & MPFR_LIMB_HIGHBIT) == 0)
+ {
+ mpn_lshift (a, result + nx1, n , 1);
+ a[0] |= result[nx1 - 1] >> (BITS_PER_MP_LIMB - 1);
+ exp_a --;
+ }
+ else
+ MPN_COPY (a, result + nx1, n);
+ }
+ else
+ {
+ /* a2*2^exp_a = b^e */
+ err = mpn_exp (a, &exp_a, b, exp, n);
+ exact = (err == -1);
+
+ /* allocate memory for x1, result and reste */
+ x1 = (mp_limb_t*) TMP_ALLOC (2 * n * sizeof (mp_limb_t));
+ result = (mp_limb_t*) TMP_ALLOC ((n + 1) * sizeof (mp_limb_t));
+ reste = (mp_limb_t*) TMP_ALLOC (n * sizeof (mp_limb_t));
+
+ /* initialize x1 = x */
+ MPN_COPY2 (x1, 2 * n, xp, nx);
+ if ((exact) && (nx > 2 * n) &&
+ (mpn_scan1 (xp, 0) < (nx - 2 * n) * BITS_PER_MP_LIMB))
+ exact = 0;
+
+ /* result = x / a */
+ mpn_tdiv_qr (result, reste, 0, x1, 2 * n, a, n);
+ exp_a = MPFR_EXP (x) - exp_a - 2 * n * BITS_PER_MP_LIMB;
+
+ /* test if division was exact */
+ if (exact)
+ exact = mpn_popcount (reste, n) == 0;
+
+ /* normalize the result and copy into a */
+ if (result[n] == 1)
+ {
+ mpn_rshift (a, result, n, 1);
+ a[n - 1] |= MPFR_LIMB_HIGHBIT;;
+ exp_a ++;
+ }
+ else
+ MPN_COPY (a, result, n);
+
+ err = (err == -1) ? 2 : err + 2;
+ }
- /* 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) */
+ /* check if rounding is possible */
+ if (exact)
+ err = -1;
+ if (mpfr_get_str_aux (s, e, a, n, exp_a, err, b, m, rnd) != 2)
+ break;
- /* 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);
+ /* increment the working precision */
+ prec += log_2prec;
- return str0;
+ TMP_FREE(marker);
}
+
+ *e += g;
+
+ TMP_FREE(marker);
+
+ return s0;
+
}
diff --git a/mpfr/get_z_exp.c b/mpfr/get_z_exp.c
index c98b6bdd0..c409b9b59 100644
--- a/mpfr/get_z_exp.c
+++ b/mpfr/get_z_exp.c
@@ -29,8 +29,8 @@ MA 02111-1307, USA. */
/* 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],
+ * isn't really important. We choose to return __gmpfr_emin because
+ * 1) it is in the exponent range [__gmpfr_emin,__gmpfr_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.
@@ -48,7 +48,7 @@ mpfr_get_z_exp (mpz_ptr z, mpfr_srcptr f)
if (MPFR_IS_ZERO(f))
{
mpz_set_ui (z, 0);
- return __mpfr_emin;
+ return __gmpfr_emin;
}
fn = 1 + (MPFR_PREC(f) - 1) / BITS_PER_MP_LIMB;
@@ -63,7 +63,7 @@ mpfr_get_z_exp (mpz_ptr z, mpfr_srcptr f)
else
MPN_COPY (PTR(z), MPFR_MANT(f), fn);
- SIZ(z) = fn;
+ SIZ(z) = MPFR_SIGN(f) < 0 ? -fn : fn;
MPFR_ASSERTN((mp_exp_unsigned_t) MPFR_EXP(f) - MPFR_EMIN_MIN
>= (mp_exp_unsigned_t) MPFR_PREC(f));
diff --git a/mpfr/hypot.c b/mpfr/hypot.c
index 2eedddd24..b9ee05877 100644
--- a/mpfr/hypot.c
+++ b/mpfr/hypot.c
@@ -32,11 +32,16 @@ MA 02111-1307, USA. */
*/
int
-mpfr_hypot (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode)
+mpfr_hypot (mpfr_ptr z, mpfr_srcptr x , mpfr_srcptr y , mp_rnd_t rnd_mode)
{
int inexact;
- /* Flag calcul exacte */
- int not_exact=0;
+ /* Flag exact computation */
+ int not_exact;
+ mpfr_t t, te, ti; /* auxiliary variables */
+ mp_prec_t Nx, Ny, Nz; /* size variables */
+ mp_prec_t Nt; /* precision of the intermediary variable */
+ mp_exp_t Ex, Ey, sh;
+ mp_exp_unsigned_t diff_exp;
/* particular cases */
@@ -57,77 +62,109 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode)
MPFR_CLEAR_INF(z);
- if(MPFR_IS_ZERO(x))
+ if (MPFR_IS_ZERO(x))
return mpfr_abs (z, y, rnd_mode);
- if(MPFR_IS_ZERO(y))
+ if (MPFR_IS_ZERO(y))
return mpfr_abs (z, x, rnd_mode);
+ if (mpfr_cmpabs (x, y) < 0)
+ {
+ mpfr_srcptr t;
+ t = x;
+ x = y;
+ y = t;
+ }
+
+ /* now |x| >= |y| */
+
+ Ex = MPFR_EXP(x);
+ Ey = MPFR_EXP(y);
+ diff_exp = (mp_exp_unsigned_t) Ex - Ey;
+
+ Nz = MPFR_PREC(z); /* Precision of output variable */
+
+ /* we have x < 2^Ex thus x^2 < 2^(2*Ex),
+ and ulp(x) = 2^(Ex-Nx) thus ulp(x^2) >= 2^(2*Ex-2*Nx).
+ y does not overlap with the result when
+ x^2+y^2 < (|x| + 1/2*ulp(x,Nz))^2 = x^2 + |x|*ulp(x,Nz) + 1/4*ulp(x,Nz)^2,
+ i.e. a sufficient condition is y^2 < |x|*ulp(x,Nz),
+ or 2^(2*Ey) <= 2^(2*Ex-1-Nz), i.e. 2*diff_exp > Nz
+ */
+ if (diff_exp > Nz / 2) /* result is |x| or |x|+ulp(|x|,Nz) */
+ {
+ if (rnd_mode == GMP_RNDU)
+ {
+ /* if z > abs(x), then it was already rounded up */
+ if (mpfr_abs (z, x, rnd_mode) <= 0)
+ mpfr_add_one_ulp (z, rnd_mode);
+ return 1;
+ }
+ else /* GMP_RNDZ, GMP_RNDD, GMP_RNDN */
+ {
+ inexact = mpfr_abs (z, x, rnd_mode);
+ return (inexact) ? inexact : -1;
+ }
+ }
+
/* General case */
- {
- /* Declaration of the intermediary variable */
- mpfr_t t, te,ti;
- /* 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 */
+ Nx = MPFR_PREC(x); /* Precision of input variable */
+ Ny = MPFR_PREC(y); /* Precision of input variable */
- int Nt; /* Precision of the intermediary variable */
- long int err; /* Precision of error */
-
- /* compute the precision of intermediary variable */
- Nt=MAX(MAX(Nx,Ny),Nz);
+ /* compute the working precision -- see algorithms.ps */
+ Nt = MAX(MAX(MAX(Nx, Ny), Nz), 8);
+ Nt = Nt - 8 + __gmpfr_ceil_log2 (Nt);
+
+ /* initialise the intermediary variables */
+ mpfr_init (t);
+ mpfr_init (te);
+ mpfr_init (ti);
+
+ mpfr_save_emin_emax ();
- /* compute the size of intermediary variable -- see algorithms.ps */
- Nt=Nt+2+_mpfr_ceil_log2(Nt);
+ sh = MAX(0,MIN(Ex,Ey));
- /* initialise the intermediary variables */
- mpfr_init(t);
- mpfr_init(te);
- mpfr_init(ti);
+ do
+ {
+ Nt += 10;
- /* Hypot */
- do {
- not_exact=0;
- /* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(te,Nt);
- mpfr_set_prec(ti,Nt);
+ not_exact = 0;
+ /* reactualization of the precision */
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ti, Nt);
/* computations of hypot */
- if(mpfr_mul(te,x,x,GMP_RNDN)) /* x^2 */
- not_exact=1;
+ mpfr_div_2ui (te, x, sh, GMP_RNDZ); /* exact since Nt >= Nx */
+ if (mpfr_mul (te, te, te, GMP_RNDZ)) /* x^2 */
+ not_exact = 1;
- if(mpfr_mul(ti,y,y,GMP_RNDN)) /* y^2 */
- not_exact=1;
+ mpfr_div_2ui (ti, y, sh, GMP_RNDZ); /* exact since Nt >= Ny */
+ if (mpfr_mul (ti, ti, ti, GMP_RNDZ)) /* y^2 */
+ not_exact = 1;
- if(mpfr_add(t,te,ti,GMP_RNDD)) /*x^2+y^2*/
- not_exact=1;
+ if (mpfr_add (t, te, ti, GMP_RNDZ)) /* x^2+y^2 */
+ not_exact = 1;
- if(mpfr_sqrt(t,t,GMP_RNDN)) /* sqrt(x^2+y^2)*/
- not_exact=1;
+ if (mpfr_sqrt (t, t, GMP_RNDZ)) /* sqrt(x^2+y^2)*/
+ not_exact = 1;
- /* estimation of the error */
- err=Nt-(2);
-
- Nt += 10;
- if(Nt<0)Nt=0;
-
- } while ((err <0) || ((!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Nz)) && not_exact));
+ }
+ while (not_exact && mpfr_can_round (t, Nt - 2, GMP_RNDZ, rnd_mode, Nz) == 0);
- inexact = mpfr_set (z, t, rnd_mode);
- mpfr_clear(t);
- mpfr_clear(ti);
- mpfr_clear(te);
+ inexact = mpfr_mul_2ui (z, t, sh, rnd_mode);
- }
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
if (not_exact == 0 && inexact == 0)
- return 0;
-
- if (not_exact != 0 && inexact == 0)
- return 1;
+ inexact = 0;
+ else if (not_exact != 0 && inexact == 0)
+ inexact = -1;
+
+ mpfr_restore_emin_emax ();
- return inexact;
+ return mpfr_check_range (z, inexact, rnd_mode);
}
diff --git a/mpfr/init.c b/mpfr/init.c
index 202c9de67..dbc0c645f 100644
--- a/mpfr/init.c
+++ b/mpfr/init.c
@@ -1,6 +1,6 @@
/* mpfr_init -- initialize a floating-point number
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -27,5 +27,5 @@ MA 02111-1307, USA. */
void
mpfr_init (mpfr_ptr x)
{
- mpfr_init2 (x, __mpfr_default_fp_bit_precision);
+ mpfr_init2 (x, __gmpfr_default_fp_bit_precision);
}
diff --git a/mpfr/init2.c b/mpfr/init2.c
index 6b7df87b7..fd76177a5 100644
--- a/mpfr/init2.c
+++ b/mpfr/init2.c
@@ -1,6 +1,6 @@
/* mpfr_init2 -- initialize a floating-point number with given precision
-Copyright 2001 Free Software Foundation, Inc.
+Copyright 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -19,6 +19,7 @@ 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"
diff --git a/mpfr/inp_str.c b/mpfr/inp_str.c
index 6afa00e2f..3055a1089 100644
--- a/mpfr/inp_str.c
+++ b/mpfr/inp_str.c
@@ -1,7 +1,7 @@
/* mpf_inp_str(dest_float, stream, base) -- Input a number in base
BASE from stdio stream STREAM and store the result in DEST_FLOAT.
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
(Copied from GMP, file mpf/inp_str.c)
This file is part of the MPFR Library.
@@ -54,6 +54,8 @@ mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mp_rnd_t rnd_mode)
}
while (isspace (c));
+ /* number of characters read is nread */
+
for (;;)
{
if (str_size >= alloc_size)
@@ -69,13 +71,15 @@ mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mp_rnd_t rnd_mode)
}
ungetc (c, stream);
+ /* number of characters read is nread + str_size - 1 */
+
if (str_size >= alloc_size)
{
size_t old_alloc_size = alloc_size;
alloc_size = alloc_size * 3 / 2;
str = (char *) (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
}
- str[str_size] = 0;
+ str[str_size] = '\0';
retval = mpfr_set_str (rop, str, base, rnd_mode);
(*__gmp_free_func) (str, alloc_size);
@@ -83,5 +87,5 @@ mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mp_rnd_t rnd_mode)
if (retval == -1)
return 0; /* error */
- return str_size + nread;
+ return str_size + nread - 1;
}
diff --git a/mpfr/isinteger.c b/mpfr/isinteger.c
index 8c15a24b9..f79268eaf 100644
--- a/mpfr/isinteger.c
+++ b/mpfr/isinteger.c
@@ -1,6 +1,6 @@
/* mpfr_isinteger -- test if a mpfr variable is integer
-Copyright 2001 Free Software Foundation, Inc.
+Copyright 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -27,26 +27,37 @@ MA 02111-1307, USA. */
int
mpfr_isinteger (mpfr_srcptr x)
{
-
- mpfr_t u;
- int expo;
+ mp_exp_t expo;
mp_prec_t prec;
- int result;
+ mp_size_t xn;
+ mp_limb_t *xp;
- expo=(int)MPFR_EXP(x);
- prec=MPFR_PREC(x);
+ if (!MPFR_IS_FP(x))
+ return 0;
- if (expo<=0)
+ if (MPFR_IS_ZERO(x))
+ return 1;
+
+ expo = MPFR_EXP(x);
+ if (expo <= 0)
return 0;
- if (expo>=prec)
+ prec = MPFR_PREC(x);
+ if (expo >= prec)
return 1;
- mpfr_init2(u,prec);
- mpfr_trunc(u,x);
+ /* 0 < expo < prec */
- result = (mpfr_cmp (x,u) == 0);
+ xn = (prec - 1) / BITS_PER_MP_LIMB; /* index of last limb */
+ xn -= (mp_size_t) (expo / BITS_PER_MP_LIMB);
+ /* now the index of the last limb containing bits of the fractional part */
- mpfr_clear (u);
- return result;
+ xp = MPFR_MANT(x);
+ MPFR_ASSERTN(xn >= 0);
+ if (xp[xn] << (expo % BITS_PER_MP_LIMB) != 0)
+ return 0;
+ while (--xn >= 0)
+ if (xp[xn] != 0)
+ return 0;
+ return 1;
}
diff --git a/mpfr/isnum.c b/mpfr/isnum.c
index 581ee7ace..905b90041 100644
--- a/mpfr/isnum.c
+++ b/mpfr/isnum.c
@@ -1,6 +1,6 @@
/* mpfr_number_p -- check for ordinary numbers
-Copyright 2000, 2001 Free Software Foundation.
+Copyright 2000, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -27,5 +27,5 @@ MA 02111-1307, USA. */
int
mpfr_number_p (mpfr_srcptr x)
{
- return !MPFR_IS_NAN(x) && !MPFR_IS_INF(x);
+ return MPFR_IS_FP(x);
}
diff --git a/mpfr/log.c b/mpfr/log.c
index 8c823b23b..181d53a9e 100644
--- a/mpfr/log.c
+++ b/mpfr/log.c
@@ -44,7 +44,7 @@ MA 02111-1307, USA. */
int
mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
{
- int m, bool, size, cancel, inexact = 0;
+ int m, go_on, size, cancel, inexact = 0;
mp_prec_t p, q;
mpfr_t cst, rapport, agm, tmp1, tmp2, s, mm;
mp_limb_t *cstp, *rapportp, *agmp, *tmp1p, *tmp2p, *sp, *mmp;
@@ -113,9 +113,9 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
/* adjust to entire limb */
if (p%BITS_PER_MP_LIMB) p += BITS_PER_MP_LIMB - (p%BITS_PER_MP_LIMB);
- bool=1;
+ go_on=1;
- while (bool==1) {
+ while (go_on==1) {
#ifdef DEBUG
printf("a="); mpfr_print_binary(a); putchar('\n');
printf("p=%d\n", p);
@@ -164,7 +164,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
#ifdef DEBUG
printf("result="); mpfr_print_binary(r); putchar('\n');
#endif
- bool=0;
+ go_on=0;
}
/* else we increase the precision */
else {
diff --git a/mpfr/log10.c b/mpfr/log10.c
index 0d4dfbdbe..df8854da5 100644
--- a/mpfr/log10.c
+++ b/mpfr/log10.c
@@ -101,7 +101,7 @@ mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
/* compute the precision of intermediary variable */
Nt = MAX(Nx, Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt = Nt + 4+ _mpfr_ceil_log2 (Nt);
+ Nt = Nt + 4+ __gmpfr_ceil_log2 (Nt);
/* initialise of intermediary variables */
mpfr_init (t);
diff --git a/mpfr/log1p.c b/mpfr/log1p.c
index 92861ad02..89d767d5d 100644
--- a/mpfr/log1p.c
+++ b/mpfr/log1p.c
@@ -97,7 +97,7 @@ mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* compute the precision of intermediary variable */
Nt=MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+5+_mpfr_ceil_log2(Nt);
+ Nt=Nt+5+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
mpfr_init(t);
@@ -113,7 +113,7 @@ mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_log (t, t, GMP_RNDN); /* log(1+x)*/
/* estimation of the error */
- /*err=Nt-(_mpfr_ceil_log2(1+pow(2,1-MPFR_EXP(t))));*/
+ /*err=Nt-(__gmpfr_ceil_log2(1+pow(2,1-MPFR_EXP(t))));*/
err=Nt-(MAX(1-MPFR_EXP(t),0)+1);
/* actualisation of the precision */
diff --git a/mpfr/log2.c b/mpfr/log2.c
index 5205c328b..c245a8f5c 100644
--- a/mpfr/log2.c
+++ b/mpfr/log2.c
@@ -106,7 +106,7 @@ mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mp_rnd_t rnd_mode)
/* 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);
+ Nt=Nt+3+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
mpfr_init(t);
diff --git a/mpfr/mpf2mpfr.h b/mpfr/mpf2mpfr.h
index 35adbe1e3..723c9f3fb 100644
--- a/mpfr/mpf2mpfr.h
+++ b/mpfr/mpf2mpfr.h
@@ -49,8 +49,10 @@ MA 02111-1307, USA. */
#define mpf_random2 mpfr_random2
#undef mpf_set_default_prec
#define mpf_set_default_prec mpfr_set_default_prec
+#undef mpf_get_default_prec
+#define mpf_get_default_prec mpfr_get_default_prec
#undef mpf_set_prec
-#define mpf_set_prec(x,p) mpfr_round_prec(x, __gmp_default_rounding_mode, p)
+#define mpf_set_prec(x,p) mpfr_round_prec(x, __gmpfr_default_rounding_mode, p)
#undef mpf_set_prec_raw
#define mpf_set_prec_raw mpfr_set_prec_raw
#undef mpf_trunc
@@ -62,77 +64,77 @@ MA 02111-1307, USA. */
/* functions which take as argument the rounding mode */
#undef mpf_abs
-#define mpf_abs(x,y) mpfr_abs(x,y,__gmp_default_rounding_mode)
+#define mpf_abs(x,y) mpfr_abs(x,y,__gmpfr_default_rounding_mode)
#undef mpf_add
-#define mpf_add(x,y,z) mpfr_add(x,y,z,__gmp_default_rounding_mode)
+#define mpf_add(x,y,z) mpfr_add(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_add_ui
#define mpf_add_ui(x,y,z) \
- mpfr_add_ui(x,y,z,__gmp_default_rounding_mode)
+ mpfr_add_ui(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_div
-#define mpf_div(x,y,z) mpfr_div(x,y,z,__gmp_default_rounding_mode)
+#define mpf_div(x,y,z) mpfr_div(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_div_ui
#define mpf_div_ui(x,y,z) \
- mpfr_div_ui(x,y,z,__gmp_default_rounding_mode)
+ mpfr_div_ui(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_div_2exp
#define mpf_div_2exp(x,y,z) \
- mpfr_div_2exp(x,y,z,__gmp_default_rounding_mode)
+ mpfr_div_2exp(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_dump
#define mpf_dump(x,y,z) \
- mpfr_dump(x,y,z,__gmp_default_rounding_mode)
+ mpfr_dump(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_get_str
#define mpf_get_str(x,y,z,t,u) \
- mpfr_get_str(x,y,z,t,u,__gmp_default_rounding_mode)
+ mpfr_get_str(x,y,z,t,u,__gmpfr_default_rounding_mode)
#undef mpf_inp_str
-#define mpf_inp_str(x,y,z) mpfr_inp_str(x,y,z,__gmp_default_rounding_mode)
+#define mpf_inp_str(x,y,z) mpfr_inp_str(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_set_str
-#define mpf_set_str(x,y,z) mpfr_set_str(x,y,z,__gmp_default_rounding_mode)
+#define mpf_set_str(x,y,z) mpfr_set_str(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_init_set
-#define mpf_init_set(x,y) mpfr_init_set(x,y,__gmp_default_rounding_mode)
+#define mpf_init_set(x,y) mpfr_init_set(x,y,__gmpfr_default_rounding_mode)
#undef mpf_init_set_d
-#define mpf_init_set_d(x,y) mpfr_init_set_d(x,y,__gmp_default_rounding_mode)
+#define mpf_init_set_d(x,y) mpfr_init_set_d(x,y,__gmpfr_default_rounding_mode)
#undef mpf_init_set_si
-#define mpf_init_set_si(x,y) mpfr_init_set_si(x,y,__gmp_default_rounding_mode)
+#define mpf_init_set_si(x,y) mpfr_init_set_si(x,y,__gmpfr_default_rounding_mode)
#undef mpf_init_set_str
-#define mpf_init_set_str(x,y,z) mpfr_init_set_str(x,y,z,__gmp_default_rounding_mode)
+#define mpf_init_set_str(x,y,z) mpfr_init_set_str(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_init_set_ui
-#define mpf_init_set_ui(x,y) mpfr_init_set_ui(x,y,__gmp_default_rounding_mode)
+#define mpf_init_set_ui(x,y) mpfr_init_set_ui(x,y,__gmpfr_default_rounding_mode)
#undef mpf_mul
-#define mpf_mul(x,y,z) mpfr_mul(x,y,z,__gmp_default_rounding_mode)
+#define mpf_mul(x,y,z) mpfr_mul(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_mul_2exp
-#define mpf_mul_2exp(x,y,z) mpfr_mul_2exp(x,y,z,__gmp_default_rounding_mode)
+#define mpf_mul_2exp(x,y,z) mpfr_mul_2exp(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_mul_ui
-#define mpf_mul_ui(x,y,z) mpfr_mul_ui(x,y,z,__gmp_default_rounding_mode)
+#define mpf_mul_ui(x,y,z) mpfr_mul_ui(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_neg
-#define mpf_neg(x,y) mpfr_neg(x,y,__gmp_default_rounding_mode)
+#define mpf_neg(x,y) mpfr_neg(x,y,__gmpfr_default_rounding_mode)
#undef mpf_out_str
-#define mpf_out_str(x,y,z,t) mpfr_out_str(x,y,z,t,__gmp_default_rounding_mode)
+#define mpf_out_str(x,y,z,t) mpfr_out_str(x,y,z,t,__gmpfr_default_rounding_mode)
#undef mpf_pow_ui
-#define mpf_pow_ui(x,y,z) mpfr_pow_ui(x,y,z,__gmp_default_rounding_mode)
+#define mpf_pow_ui(x,y,z) mpfr_pow_ui(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_reldiff
-#define mpf_reldiff(x,y,z) mpfr_reldiff(x,y,z,__gmp_default_rounding_mode)
+#define mpf_reldiff(x,y,z) mpfr_reldiff(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_set
-#define mpf_set(x,y) mpfr_set(x,y,__gmp_default_rounding_mode)
+#define mpf_set(x,y) mpfr_set(x,y,__gmpfr_default_rounding_mode)
#undef mpf_set_d
-#define mpf_set_d(x,y) mpfr_set_d(x,y,__gmp_default_rounding_mode)
+#define mpf_set_d(x,y) mpfr_set_d(x,y,__gmpfr_default_rounding_mode)
#undef mpf_set_q
-#define mpf_set_q(x,y) mpfr_set_q(x,y,__gmp_default_rounding_mode)
+#define mpf_set_q(x,y) mpfr_set_q(x,y,__gmpfr_default_rounding_mode)
#undef mpf_set_si
-#define mpf_set_si(x,y) mpfr_set_si(x,y,__gmp_default_rounding_mode)
+#define mpf_set_si(x,y) mpfr_set_si(x,y,__gmpfr_default_rounding_mode)
#undef mpf_set_ui
-#define mpf_set_ui(x,y) mpfr_set_ui(x,y,__gmp_default_rounding_mode)
+#define mpf_set_ui(x,y) mpfr_set_ui(x,y,__gmpfr_default_rounding_mode)
#undef mpf_set_z
-#define mpf_set_z(x,y) mpfr_set_z(x,y,__gmp_default_rounding_mode)
+#define mpf_set_z(x,y) mpfr_set_z(x,y,__gmpfr_default_rounding_mode)
#undef mpf_sqrt
-#define mpf_sqrt(x,y) mpfr_sqrt(x,y,__gmp_default_rounding_mode)
+#define mpf_sqrt(x,y) mpfr_sqrt(x,y,__gmpfr_default_rounding_mode)
#undef mpf_sqrt_ui
-#define mpf_sqrt_ui(x,y) mpfr_sqrt_ui(x,y,__gmp_default_rounding_mode)
+#define mpf_sqrt_ui(x,y) mpfr_sqrt_ui(x,y,__gmpfr_default_rounding_mode)
#undef mpf_sub
-#define mpf_sub(x,y,z) mpfr_sub(x,y,z,__gmp_default_rounding_mode)
+#define mpf_sub(x,y,z) mpfr_sub(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_sub_ui
-#define mpf_sub_ui(x,y,z) mpfr_sub_ui(x,y,z,__gmp_default_rounding_mode)
+#define mpf_sub_ui(x,y,z) mpfr_sub_ui(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_ui_div
-#define mpf_ui_div(x,y,z) mpfr_ui_div(x,y,z,__gmp_default_rounding_mode)
+#define mpf_ui_div(x,y,z) mpfr_ui_div(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_ui_sub
-#define mpf_ui_sub(x,y,z) mpfr_ui_sub(x,y,z,__gmp_default_rounding_mode)
+#define mpf_ui_sub(x,y,z) mpfr_ui_sub(x,y,z,__gmpfr_default_rounding_mode)
#undef mpf_urandomb
#define mpf_urandomb(x,y,n) mpfr_urandomb(x,y)
diff --git a/mpfr/mpfr-impl.h b/mpfr/mpfr-impl.h
index 2739639c8..5c30036d3 100644
--- a/mpfr/mpfr-impl.h
+++ b/mpfr/mpfr-impl.h
@@ -19,6 +19,26 @@ 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. */
+#ifndef HAVE_STRCASECMP
+#define strcasecmp mpfr_strcasecmp
+#endif
+
+#ifndef HAVE_STRNCASECMP
+#define strncasecmp mpfr_strncasecmp
+#endif
+
+/* Definition of MPFR_LIMB_HIGHBIT */
+
+#ifdef GMP_LIMB_HIGHBIT
+#define MPFR_LIMB_HIGHBIT GMP_LIMB_HIGHBIT
+#else
+#define MPFR_LIMB_HIGHBIT MP_LIMB_T_HIGHBIT
+#endif
+
+#if GMP_NAIL_BITS != 0
+#error "MPFR doesn't support nonzero values of GMP_NAIL_BITS"
+#endif
+
/* Test if X (positive) is a power of 2 */
#define IS_POW2(X) (((X) & ((X) - 1)) == 0)
@@ -66,8 +86,9 @@ typedef unsigned long int mp_size_unsigned_t;
#define ALPHA 4.3191365662914471407 /* a+2 = a*log(a), rounded to +infinity */
/* Safe absolute value (to avoid possible integer overflow) */
+/* type is the target (unsigned) type */
-#define SAFE_ABS(type,x) ((x) >= 0 ? (unsigned type)(x) : -(unsigned type)(x))
+#define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
/* macros for doubles, based on gmp union ieee_double_extract */
@@ -129,23 +150,8 @@ typedef union ieee_double_extract Ieee_double_extract;
following two macros, unless the flag comes from another function
returning the ternary inexact value */
#define MPFR_RET(I) return \
- (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)
+ (I) ? ((__gmpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0
+#define MPFR_RET_NAN return (__gmpfr_flags |= MPFR_FLAGS_NAN), 0
/* Memory gestion */
@@ -172,7 +178,20 @@ typedef union ieee_double_extract Ieee_double_extract;
extern "C" {
#endif
-extern mp_prec_t __mpfr_const_log2_prec;
+extern mpfr_t __mpfr_const_log2;
+extern mp_prec_t __gmpfr_const_log2_prec;
+
+extern mpfr_t __mpfr_const_pi;
+extern mp_prec_t __gmpfr_const_pi_prec;
+
+#ifndef HAVE_STRCASECMP
+int mpfr_strcasecmp _PROTO ((const char *, const char *));
+#endif
+
+#ifndef HAVE_STRNCASECMP
+int mpfr_strncasecmp _PROTO ((const char *, const char *, size_t));
+#endif
+
int mpfr_set_underflow _PROTO ((mpfr_ptr, mp_rnd_t, int));
int mpfr_set_overflow _PROTO ((mpfr_ptr, mp_rnd_t, int));
void mpfr_save_emin_emax _PROTO ((void));
@@ -186,15 +205,17 @@ int mpfr_round_raw_generic _PROTO ((mp_limb_t *, mp_limb_t *, mp_prec_t, int,
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_d3 _PROTO ((mpfr_srcptr, mp_exp_t, mp_rnd_t));
-int mpfr_cmp_abs _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));
-unsigned long _mpfr_isqrt _PROTO ((unsigned long));
-unsigned long _mpfr_cuberoot _PROTO ((unsigned long));
+long __gmpfr_ceil_log2 _PROTO ((double));
+long __gmpfr_floor_log2 _PROTO ((double));
+double __gmpfr_ceil_exp2 _PROTO ((double));
+unsigned long __gmpfr_isqrt _PROTO ((unsigned long));
+unsigned long __gmpfr_cuberoot _PROTO ((unsigned long));
int mpfr_exp_2 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_exp3 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
+int mpfr_powerof2_raw _PROTO ((mpfr_srcptr));
+void mpfr_setmax _PROTO ((mpfr_ptr, mp_exp_t));
+void mpfr_setmin _PROTO ((mpfr_ptr, mp_exp_t));
#define mpfr_round_raw(yp, xp, xprec, neg, yprec, r, inexp) \
mpfr_round_raw_generic((yp), (xp), (xprec), (neg), (yprec), (r), (inexp), 0)
diff --git a/mpfr/mpfr-math.h b/mpfr/mpfr-math.h
index 668ad06c0..42ee0bae8 100644
--- a/mpfr/mpfr-math.h
+++ b/mpfr/mpfr-math.h
@@ -19,78 +19,51 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
-#if (defined (__arm__) && (defined (__ARMWEL__) || defined (__linux__)))
-/* little endian ARM */
-#define _MPFR_NAN_BYTES { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }
-#define _MPFR_INFP_BYTES { 0, 0, 0x80, 0x7f }
-#define _MPFR_INFM_BYTES { 0, 0, 0x80, 0xff }
-
-#else
-#if defined (_LITTLE_ENDIAN) || defined (__LITTLE_ENDIAN__) \
- || defined (__alpha) \
- || (defined (__arm__) && (defined (__ARMWEL__) || defined (__linux__)))\
- || defined (__clipper__) \
- || defined (__cris) \
- || defined (__i386__) \
- || defined (__i860__) \
- || defined (__i960__) \
- || defined (__ia64) \
- || defined (MIPSEL) || defined (_MIPSEL) \
- || defined (__ns32000__) \
- || defined (__WINNT) || defined (_WIN32)
-#define _MPFR_NAN_BYTES { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }
+#if HAVE_DOUBLE_IEEE_LITTLE_ENDIAN || HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
+#define _MPFR_NAN_BYTES { 0, 0, 0xc0, 0x7f }
#define _MPFR_INFP_BYTES { 0, 0, 0x80, 0x7f }
#define _MPFR_INFM_BYTES { 0, 0, 0x80, 0xff }
+#endif
-#else
-#if defined (_BIG_ENDIAN) || defined (__BIG_ENDIAN__) \
- || defined (__mc68000__) || defined (__mc68020__) || defined (__m68k__)\
- || defined (mc68020) \
- || defined (__a29k__) || defined (_AM29K) \
- || defined (__arm__) \
- || (defined (__convex__) && defined (_IEEE_FLOAT_)) \
- || defined (_CRAYMPP) || defined (_CRAYIEEE) \
- || defined (__i370__) || defined (__mvs__) \
- || defined (__m88000__) \
- || defined (MIPSEB) || defined (_MIPSEB) \
- || defined (__hppa) || defined (__hppa__) \
- || defined (__pyr__) \
- || defined (__ibm032__) \
- || defined (_IBMR2) || defined (_ARCH_PPC) \
- || defined (__sh__) \
- || defined (__sparc) || defined (sparc) \
- || defined (__sparc__) /* gcc 3.1 */ \
- || defined (__we32k__)
-#define _MPFR_NAN_BYTES { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }
+#if HAVE_DOUBLE_IEEE_BIG_ENDIAN
+#define _MPFR_NAN_BYTES { 0x7f, 0xc0, 0, 0 }
#define _MPFR_INFP_BYTES { 0x7f, 0x80, 0, 0 }
#define _MPFR_INFM_BYTES { 0xff, 0x80, 0, 0 }
#endif
-#endif
-#endif
#ifdef NAN
#define MPFR_DBL_NAN ((double) NAN)
#else
#ifdef _MPFR_NAN_BYTES
-static union { unsigned char c[8]; double d; } __mpfr_nan
-= { _MPFR_NAN_BYTES };
-#define MPFR_DBL_NAN ((double) __mpfr_nan.d)
+/* A struct is used here rather than a union of a float and a char array
+ since union initializers aren't available in K&R, in particular not in
+ the HP bundled cc. Alignment will hopefully be based on the structure
+ size, rather than it's contents, so we should be ok. */
+#ifdef __alpha
+/* gcc 3.0.2 on an alphaev56-unknown-freebsd4.3 doesn't seem to correctly
+ convert from a float NAN to a double NAN, use an 8-byte form instead as a
+ workaround. */
+static struct { unsigned char c[8]; } __mpfr_nan
+= { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } };
+#define MPFR_DBL_NAN (*((double *) __mpfr_nan.c))
+#else
+static struct { unsigned char c[4]; } __mpfr_nan = { _MPFR_NAN_BYTES };
+#define MPFR_DBL_NAN ((double) *((float *) __mpfr_nan.c))
+#endif
#else
#define MPFR_DBL_NAN (0./0.)
#endif
#endif
-#ifdef HUGE_VAL
+#ifdef HAVE_HUGE_VAL
#define MPFR_DBL_INFP HUGE_VAL
#define MPFR_DBL_INFM (-HUGE_VAL)
#else
#ifdef _MPFR_INFP_BYTES
-static union { unsigned char c[4]; float d; } __mpfr_infp
-= { _MPFR_INFP_BYTES };
-static union { unsigned char c[4]; float d; } __mpfr_infm
-= { _MPFR_INFM_BYTES };
-#define MPFR_DBL_INFP ((double) __mpfr_infp.d)
-#define MPFR_DBL_INFM ((double) __mpfr_infm.d)
+static struct { unsigned char c[4]; } __mpfr_infp = { _MPFR_INFP_BYTES };
+static struct { unsigned char c[4]; } __mpfr_infm = { _MPFR_INFM_BYTES };
+#define MPFR_DBL_INFP ((double) *((float *) __mpfr_infp.c))
+#define MPFR_DBL_INFM ((double) *((float *) __mpfr_infm.c))
#else
#define MPFR_DBL_INFP (1/0.)
#define MPFR_DBL_INFM (-1/0.)
diff --git a/mpfr/mpfr-test.h b/mpfr/mpfr-test.h
index 0fcfc3569..442d8c983 100644
--- a/mpfr/mpfr-test.h
+++ b/mpfr/mpfr-test.h
@@ -19,13 +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. */
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
+#include <stdlib.h>
+#include <limits.h>
+#include <float.h>
#include <math.h>
#ifdef __mips
#include <sys/fpu.h>
+#define HAVE_DENORMS
+#endif
+
+#if HAVE_CONFIG_H
+#include "config.h"
#endif
/* set precision control to double on x86 */
@@ -46,6 +50,11 @@ MA 02111-1307, USA. */
#endif /* ifndef __setfpucw */
#endif /* __i386__ */
+/* Because of the SunOS 4 compiler */
+#ifndef RAND_MAX
+#define RAND_MAX 0x7FFFFFFF
+#endif
+
/* generates a random long int, a random double,
and corresponding seed initializing */
#ifdef HAVE_LRAND48
@@ -63,12 +72,6 @@ MA 02111-1307, USA. */
#define random() (mrand48() & 0x7fffffff)
#endif
-void mpfr_test_init _PROTO ((void));
-double drand _PROTO ((void));
-int ulp _PROTO ((double, double));
-double dbl _PROTO ((double, int));
-double Ulp _PROTO ((double));
-
#define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
#define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */
@@ -83,84 +86,20 @@ double Ulp _PROTO ((double));
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define ABS(x) (((x)>0) ? (x) : -(x))
-/* initialization function for tests using the hardware floats */
-void
-mpfr_test_init ()
-{
-#ifdef __mips
- /* to get denormalized numbers on IRIX64 */
- union fpc_csr exp;
+void tests_memory_start _PROTO ((void));
+void tests_memory_end _PROTO ((void));
- exp.fc_word = get_fpc_csr();
- exp.fc_struct.flush = 0;
- set_fpc_csr(exp.fc_word);
-#endif
+void tests_start_mpfr _PROTO ((void));
+void tests_end_mpfr _PROTO ((void));
+
+int mpfr_set_machine_rnd_mode _PROTO ((mp_rnd_t));
+void mpfr_test_init _PROTO ((void));
+double drand _PROTO ((void));
+int ulp _PROTO ((double, double));
+double dbl _PROTO ((double, int));
+double Ulp _PROTO ((double));
-#ifdef HAVE_SETFPUCW
- /* sets the precision to double */
- __setfpucw((_FPU_DEFAULT & (~_FPU_EXTENDED)) | _FPU_DOUBLE);
+#if !defined(HAVE_ISNAN) && !defined(isnan)
+int Isnan _PROTO ((double));
+#define isnan(d) Isnan(d)
#endif
-}
-
-/* generate a random double using the whole range of possible values,
- including denormalized numbers, NaN, infinities, ... */
-double
-drand (void)
-{
- double d; int *i, expo;
-
- i = (int*) &d;
- d = 1.0;
- if (i[0] == 0)
- expo = 1; /* little endian, exponent in i[1] */
- else
- expo = 0;
- i[0] = LONG_RAND();
- i[1] = LONG_RAND();
- while (i[expo] >= 2146435072)
- i[expo] = LONG_RAND(); /* avoids NaNs */
- if ((LONG_RAND() % 2) && !isnan (d))
- d = -d; /* generates negative numbers */
- return d;
-}
-
-/* returns ulp(x) for x a 'normal' double-precision number */
-double
-Ulp (double x)
-{
- double y, eps;
-
- if (x < 0) x = -x;
-
- y = x * 2.220446049250313080847263336181640625e-16 ; /* x / 2^52 */
-
- /* as ulp(x) <= y = x/2^52 < 2*ulp(x),
- we have x + ulp(x) <= x + y <= x + 2*ulp(x),
- therefore o(x + y) = x + ulp(x) or x + 2*ulp(x) */
-
- eps = x + y;
- eps = eps - x; /* ulp(x) or 2*ulp(x) */
-
- return (eps > y) ? 0.5 * eps : eps;
-}
-
-/* returns the number of ulp's between a and b */
-int
-ulp (double a, double b)
-{
- if (a==0.0) {
- if (b==0.0) return 0;
- else if (b<0.0) return 2147483647;
- else return -2147483647;
- }
- return (a-b)/Ulp(a);
-}
-
-/* return double m*2^e */
-double
-dbl (double m, int e)
-{
- if (e>=0) while (e-->0) m *= 2.0;
- else while (e++<0) m /= 2.0;
- return m;
-}
diff --git a/mpfr/mpfr.h b/mpfr/mpfr.h
index 286ae0f34..57205d538 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 << 30) - 1))
#define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT))
#define MPFR_EMIN_MIN MPFR_EMIN_DEFAULT
@@ -118,9 +118,9 @@ typedef __gmp_const __mpfr_struct *mpfr_srcptr;
extern "C" {
#endif
-extern unsigned int __mpfr_flags;
-extern mp_exp_t __mpfr_emin;
-extern mp_exp_t __mpfr_emax;
+extern unsigned int __gmpfr_flags;
+extern mp_exp_t __gmpfr_emin;
+extern mp_exp_t __gmpfr_emax;
mp_exp_t mpfr_get_emin _PROTO ((void));
int mpfr_set_emin _PROTO ((mp_exp_t));
mp_exp_t mpfr_get_emax _PROTO ((void));
@@ -130,7 +130,7 @@ void mpfr_clear_underflow _PROTO ((void));
void mpfr_clear_overflow _PROTO ((void));
void mpfr_clear_nanflag _PROTO ((void));
void mpfr_clear_inexflag _PROTO ((void));
-int mpfr_check_range _PROTO ((mpfr_ptr, mp_rnd_t));
+int mpfr_check_range _PROTO ((mpfr_ptr, int, mp_rnd_t));
int mpfr_underflow_p _PROTO ((void));
int mpfr_overflow_p _PROTO ((void));
int mpfr_nanflag_p _PROTO ((void));
@@ -141,7 +141,10 @@ void mpfr_init _PROTO ((mpfr_ptr));
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));
+mp_exp_t mpfr_get_exp _PROTO ((mpfr_srcptr));
+int mpfr_set_exp _PROTO ((mpfr_ptr, mp_exp_t));
int mpfr_set_d _PROTO ((mpfr_ptr, double, mp_rnd_t));
+int mpfr_set_ld _PROTO ((mpfr_ptr, long double, mp_rnd_t));
int mpfr_set_z _PROTO ((mpfr_ptr, mpz_srcptr, mp_rnd_t));
void mpfr_set_nan _PROTO ((mpfr_ptr));
void mpfr_set_inf _PROTO ((mpfr_ptr, int));
@@ -149,6 +152,7 @@ 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_d1 _PROTO ((mpfr_srcptr));
double mpfr_get_d _PROTO ((mpfr_srcptr, mp_rnd_t));
+long double mpfr_get_ld _PROTO ((mpfr_srcptr, mp_rnd_t));
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));
@@ -157,6 +161,9 @@ 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));
void mpfr_clear _PROTO ((mpfr_ptr));
+void mpfr_nextabove _PROTO ((mpfr_ptr));
+void mpfr_nextbelow _PROTO ((mpfr_ptr));
+void mpfr_nexttoward _PROTO ((mpfr_ptr, mpfr_srcptr));
void mpfr_set_str_raw _PROTO ((mpfr_ptr, char *));
int mpfr_set_str _PROTO ((mpfr_ptr, __gmp_const char *, int, mp_rnd_t));
int mpfr_init_set_str _PROTO ((mpfr_ptr, char *, int, mp_rnd_t));
@@ -170,7 +177,7 @@ int mpfr_pow_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t));
int mpfr_ui_pow_ui _PROTO ((mpfr_ptr, unsigned long int, unsigned long int,
mp_rnd_t));
int mpfr_div _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
-void mpfr_agm _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
+int mpfr_agm _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
int mpfr_sqrt _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
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));
@@ -191,21 +198,20 @@ int mpfr_sin_cos _PROTO ((mpfr_ptr, mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_cos _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_tan _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_mul_ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t));
-void mpfr_set_machine_rnd_mode _PROTO ((mp_rnd_t));
-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_cmp_ui_2exp _PROTO ((mpfr_srcptr, unsigned long int, mp_exp_t));
+int mpfr_cmp_si_2exp _PROTO ((mpfr_srcptr, long int, mp_exp_t));
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 _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));
mp_prec_t mpfr_get_default_prec _PROTO((void));
-extern mp_prec_t __mpfr_default_fp_bit_precision;
-extern mp_rnd_t __gmp_default_rounding_mode;
+extern mp_prec_t __gmpfr_default_fp_bit_precision;
+extern mp_rnd_t __gmpfr_default_rounding_mode;
char * mpfr_print_rnd_mode _PROTO((mp_rnd_t));
int mpfr_neg _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_sub_one_ulp _PROTO((mpfr_ptr, mp_rnd_t));
@@ -219,11 +225,14 @@ 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));
+int mpfr_frac _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
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));
int mpfr_set4 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t, int));
int mpfr_cmp3 _PROTO ((mpfr_srcptr, mpfr_srcptr, int));
+int mpfr_cmpabs _PROTO ((mpfr_srcptr, mpfr_srcptr));
+#define mpfr_cmp_abs mpfr_cmpabs /* keep for compatibility with mpfr-2.0.1 */
int mpfr_nan_p _PROTO((mpfr_srcptr));
int mpfr_inf_p _PROTO((mpfr_srcptr));
int mpfr_number_p _PROTO((mpfr_srcptr));
@@ -256,6 +265,7 @@ int mpfr_log10 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_log1p _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_expm1 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_cbrt _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
+int mpfr_gamma _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t));
int mpfr_min _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
int mpfr_max _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
@@ -272,32 +282,40 @@ int mpfr_div_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t));
int mpfr_add_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t));
int mpfr_sub_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t));
+int mpfr_greater_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+int mpfr_greaterequal_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+int mpfr_less_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+int mpfr_lessequal_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+int mpfr_lessgreater_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+int mpfr_equal_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+int mpfr_unordered_p _PROTO ((mpfr_srcptr, mpfr_srcptr));
+
#if defined (__cplusplus)
}
#endif
/* prevent from using mpfr_get_e{min,max} as lvalues */
-#define mpfr_get_emin() (__mpfr_emin + 0)
-#define mpfr_get_emax() (__mpfr_emax + 0)
+#define mpfr_get_emin() (__gmpfr_emin + 0)
+#define mpfr_get_emax() (__gmpfr_emax + 0)
#define mpfr_clear_flags() \
- ((void) (__mpfr_flags = 0))
+ ((void) (__gmpfr_flags = 0))
#define mpfr_clear_underflow() \
- ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW))
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW))
#define mpfr_clear_overflow() \
- ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW))
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW))
#define mpfr_clear_nanflag() \
- ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN))
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN))
#define mpfr_clear_inexflag() \
- ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT))
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT))
#define mpfr_underflow_p() \
- ((int) (__mpfr_flags & MPFR_FLAGS_UNDERFLOW))
+ ((int) (__gmpfr_flags & MPFR_FLAGS_UNDERFLOW))
#define mpfr_overflow_p() \
- ((int) (__mpfr_flags & MPFR_FLAGS_OVERFLOW))
+ ((int) (__gmpfr_flags & MPFR_FLAGS_OVERFLOW))
#define mpfr_nanflag_p() \
- ((int) (__mpfr_flags & MPFR_FLAGS_NAN))
+ ((int) (__gmpfr_flags & MPFR_FLAGS_NAN))
#define mpfr_inexflag_p() \
- ((int) (__mpfr_flags & MPFR_FLAGS_INEXACT))
+ ((int) (__gmpfr_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)
diff --git a/mpfr/mpfr.texi b/mpfr/mpfr.texi
index fb2d16cee..bb7fb37ef 100644
--- a/mpfr/mpfr.texi
+++ b/mpfr/mpfr.texi
@@ -1,71 +1,70 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename mpfr.info
-@settitle MPFR 2.0.1
+@set VERSION 2.0.2
+@set UPDATED-MONTH June 2002
+@settitle MPFR @value{VERSION}
@synindex tp fn
@iftex
@afourpaper
@end iftex
@comment %**end of header
-@ifinfo
-@format
-START-INFO-DIR-ENTRY
-* mpfr: (mpfr.info). Multiple Precision Floating-Point Reliable Library.
-END-INFO-DIR-ENTRY
-@end format
-@end ifinfo
-
-@c smallbook
-
-@iftex
-@finalout
-@end iftex
+@copying
+This manual documents how to install and use the Multiple Precision
+Floating-Point Reliable Library, version @value{VERSION}.
-@c Note: the edition number is listed in *three* places; please update
-@c all three. Also, update the month and year where appropriate.
+Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
-@c ==> Update edition number for settitle and subtitle, and in the
-@c ==> following paragraph; update date, too.
+Permission is granted to copy, distribute and/or modify this document under
+the terms of the GNU Free Documentation License, Version 1.1 or any later
+version published by the Free Software Foundation; with no Invariant Sections,
+with the Front-Cover Texts being ``A GNU Manual'', and with the Back-Cover
+Texts being ``You have freedom to copy and modify this GNU Manual, like GNU
+software''. A copy of the license is included in @ref{GNU Free Documentation
+License}.
+@end copying
-@ifinfo
-This file documents MPFR, a library for reliable multiple precision floating-point arithmetic
+@c Texinfo version 4.2 or up will be needed to process this file.
+@c
+@c A suitable texinfo.tex is supplied, a newer one should work
+@c equally well.
+@c
+@c The edition number is in the VERSION variable above and should be
+@c updated where appropriate. Also, update the month and year in
+@c UPDATED-MONTH.
-Copyright (C) 1999-2002, Free Software Foundation.
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
+@dircategory GNU libraries
+@direntry
+* mpfr: (mpfr). Multiple Precision Floating-Point Reliable Library.
+@end direntry
-@ignore
-Permission is granted to process this file through TeX and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
+@c html <meta name=description content="...">
+@documentdescription
+How to install and use MPFR, a library for reliable multiple precision floating-point arithmetic, version @value{VERSION}.
+@end documentdescription
-@end ignore
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the entire
-resulting derived work is distributed under the terms of a permission
-notice identical to this one.
+@c smallbook
+@finalout
+@setchapternewpage on
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that this permission notice may be stated in a translation approved
-by the Foundation.
-@end ifinfo
+@ifnottex
+@node Top, Copying, (dir), (dir)
+@top MPFR
+@end ifnottex
-@setchapternewpage on
+@iftex
@titlepage
-@c use the new format for titles
-
@title MPFR
@subtitle The Multiple Precision Floating-Point Reliable Library
-@subtitle Edition 2.0.1
-@subtitle April 2002
+@subtitle Edition @value{VERSION}
+@subtitle @value{UPDATED-MONTH}
@author The MPFR team, LORIA/INRIA Lorraine
+@email{mpfr@@loria.fr}
@c Include the Distribution inside the titlepage so
@c that headings are turned off.
@@ -78,39 +77,22 @@ by the Foundation.
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1999-2002 Free Software Foundation
-
-@sp 2
-
-Published by the Free Software Foundation @*
-59 Temple Place - Suite 330 @*
-Boston, MA 02111-1307, USA @*
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
+@end iftex
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the entire
-resulting derived work is distributed under the terms of a permission
-notice identical to this one.
+@insertcopying
+@ifnottex
+@sp 1
+@end ifnottex
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that this permission notice may be stated in a translation approved
-by the Foundation.
+@iftex
@end titlepage
@headings double
+@end iftex
-@ifinfo
-@node Top, Copying, (dir), (dir)
-
-@top MPFR
-
-This manual documents how to install and use the Multiple Precision
-Floating-Point Reliable Library, version 2.0.1
-
-@end ifinfo
+@c Don't bother with contents for html, the menus seem adequate.
+@ifnothtml
+@contents
+@end ifnothtml
@menu
* Copying:: GMP Copying Conditions (LGPL).
@@ -122,10 +104,53 @@ Floating-Point Reliable Library, version 2.0.1
* Contributors::
* References::
+* GNU Free Documentation License::
* Concept Index::
* Function Index::
@end menu
+
+@c @m{T,N} is $T$ in tex or @math{N} otherwise. This is an easy way to give
+@c different forms for math in tex and info. Commas in N or T don't work,
+@c but @C{} can be used instead. \, works in info but not in tex.
+@iftex
+@macro m {T,N}
+@tex$\T\$@end tex
+@end macro
+@end iftex
+@ifnottex
+@macro m {T,N}
+@math{\N\}
+@end macro
+@end ifnottex
+
+@c Usage: @GMPtimes{}
+@c Give either \times or the word "times".
+@tex
+\gdef\GMPtimes{\times}
+@end tex
+@ifnottex
+@macro GMPtimes
+times
+@end macro
+@end ifnottex
+
+@c @times{} made available as a "*" in info and html (already works in tex).
+@ifnottex
+@macro times
+*
+@end macro
+@end ifnottex
+
+@c Math operators already available in tex, made available in info too.
+@c For example @log{} can be used in both tex and info.
+@ifnottex
+@macro log
+log
+@end macro
+@end ifnottex
+
+
@node Copying, Introduction to MPFR, Top, Top
@comment node-name, next, previous, up
@unnumbered MPFR Copying Conditions
@@ -179,7 +204,7 @@ 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 valid value
for each variable (including very small precision);
-@item @code{mpfr} provides the four rounding modes from the IEEE 754
+@item @code{mpfr} provides the four rounding modes from the IEEE 754-1985
standard.
@end itemize
@@ -209,7 +234,7 @@ probably a good idea to glance through it.
@cindex Installation
To build MPFR, you first have to install GNU MP
-(version 4.0.1 or higher) on your computer.
+(version 4.1 or higher) on your computer.
You need a C compiler, preferably GCC, but any reasonable compiler should
work. And you need a standard Unix @samp{make} program, plus some other
standard Unix utility programs.
@@ -360,6 +385,9 @@ is @code{mpfr_t}.
A floating-point number can have three special values: Not-a-Number (NaN)
or plus or minus Infinity. NaN represents a value which cannot be represented
in the floating-point format, like 0 divided by 0, or Infinity minus Infinity.
+Moreover, like in the IEEE 754-1985 standard, zero is signed, i.e. there are
+a +0 and a -0; the behavior is the same as in the IEEE 754-1985 standard and
+it is generalized to the other functions supported by MPFR.
@cindex Precision
@@ -469,39 +497,41 @@ integer functions. The function prefix for floating-point operations is
@code{mpfr_}.
There is one significant characteristic of floating-point numbers that has
-motivated a difference between this function class and other MPFR function
+motivated a difference between this function class and other GNU MP function
classes: the inherent inexactness of floating-point arithmetic. The user has
-to specify the precision of each variable. A computation that assigns a
+to specify the precision for each variable. A computation that assigns a
variable will take place with the precision of the assigned variable; the
cost of that computation should not depend from the
-precision of variables used as input on average.
-
-@cindex User-defined precision
-The precision of a calculation is defined as follows: Compute the requested
-operation exactly (with ``infinite precision''), and round the result to
-the destination variable precision with the given rounding mode.
-Even if the user has asked for a very
-high precision, MP will not calculate with superfluous digits. For example,
-if two low-precision numbers of nearly equal magnitude are added, the
-precision of the result will be limited to what is required to represent the
-result accurately.
+precision of variables used as input (on average).
+@cindex Precision
+The semantics of a calculation in MPFR is specified as follows: Compute the
+requested operation exactly (with ``infinite accuracy''), and round the result
+to the precision of the destination variable, with the given rounding mode.
The MPFR floating-point functions are intended to be a smooth extension
-of the IEEE P754 arithmetic. The results obtained on one
-computer should not differ from the results obtained on a computer with a
-different word size.
+of the IEEE 754-1985 arithmetic. The results obtained on one computer should
+not differ from the results obtained on a computer with a different word size.
+
+@cindex Accuracy
+MPFR does not keep track of the accuracy of a computation. This is left
+to the user or to a higher layer.
+As a consequence, if two variables are used to store
+only a few significant bits, and their product is stored in a variable with large
+precision, then MPFR will still compute the result with full precision.
@menu
-* Rounding Modes::
-* Exceptions::
-* Initializing Floats::
-* Assigning Floats::
-* Simultaneous Float Init & Assign::
-* Converting Floats::
-* Float Arithmetic::
-* Float Comparison::
-* I/O of Floats::
-* Miscellaneous Float Functions::
+* Rounding Modes::
+* Exceptions::
+* Initializing Floats::
+* Assigning Floats::
+* Simultaneous Float Init & Assign::
+* Converting Floats::
+* Float Arithmetic::
+* Float Comparison::
+* Special Functions::
+* I/O of Floats::
+* Miscellaneous Float Functions::
+* Internals::
@end menu
@node Rounding Modes, Exceptions, Floating-point Functions, Floating-point Functions
@@ -515,8 +545,8 @@ The following four rounding modes are supported:
@item @code{GMP_RNDU}: round towards plus infinity
@item @code{GMP_RNDD}: round towards minus infinity
@end itemize
-The @samp{round to nearest} mode works as in the IEEE P754 standard: in case
-the number to be rounded lies exactly in the middle of two representable
+The @samp{round to nearest} mode works as in the IEEE 754-1985 standard: in
+case the number to be rounded lies exactly in the middle of two representable
numbers, it is rounded to the one with the least significant bit set to zero.
For example, the number 5, which is represented by (101) in binary, is rounded
to (100)=4 with a precision of two bits, and not to (110)=6.
@@ -547,7 +577,7 @@ The default rounding mode is to nearest initially.
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
-space is allocated for the mantissa, and it is filled with zeroes.
+space is allocated for the mantissa, and it is filled with zeros.
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
@@ -556,13 +586,6 @@ The precision @var{prec} can be any integer between @code{MPFR_PREC_MIN} and
@code{MPFR_PREC_MAX}.
@end deftypefun
-@deftypefun void mpfr_set_machine_rnd_mode (mp_rnd_t @var{rnd})
-Set the machine rounding mode to @var{rnd}.
-This function is provided only when the operating system supports the
-ISOC9X standard interface for setting rounding modes (i.e. through the
-header file <fenv.h>).
-@end deftypefun
-
@deftypefun {char *} mpfr_print_rnd_mode (mp_rnd_t @var{rnd})
Returns the input string (GMP_RNDD, GMP_RNDU, GMP_RNDN, GMP_RNDZ)
corresponding to the rounding mode @var{rnd} or a null pointer if
@@ -591,18 +614,24 @@ implementation (in that case the smallest or largest exponent is not changed),
and zero otherwise.
If the user changes the exponent range, it is her/his responsibility to check
that all current floating-point variables are in the new allowed range
-(for example using @code{mpfr_check_range},
+(for example using @code{mpfr_check_range}),
otherwise the subsequent
behaviour will be undefined, in the sense of the ISO C standard.
@end deftypefun
-@deftypefun int mpfr_check_range (mpfr_t @var{x}, mp_rnd_t @var{rnd})
-Return zero if the exponent of @var{x} is in the current allowed range
-(see @code{mpfr_get_emin} and @code{mpfr_get_emax}),
-otherwise reset @var{x} according to the current floating-point system
-and the rounding mode @var{rnd}, and return a positive value if the
-rounded result is larger than the original one, a negative value otherwise
-(the result cannot be exact in that case).
+@deftypefun int mpfr_check_range (mpfr_t @var{x}, int @var{t}, mp_rnd_t @var{rnd})
+This function forces @var{x} to be in the current range of acceptable
+values, @var{t} being the current ternary value: negative if @var{x}
+is smaller than the exact value, positive if @var{x} is larger than
+the exact value and zero if @var{x} is exact (before the call). It
+generates an underflow or an overflow if the exponent of @var{x} is
+outside the current allowed range; the value of @var{t} may be used
+to avoid a double rounding. This function returns zero if the rounded
+result is equal to the exact one, a positive value if the rounded
+result is larger than the exact one, a negative value if the rounded
+result is smaller than the exact one. Note that unlike most functions,
+the results is compared to the exact one, not the original value of
+@var{x}, i.e. the ternary value is propagated.
@end deftypefun
@deftypefun void mpfr_clear_underflow (void)
@@ -648,7 +677,8 @@ it. The functions @code{mpfr_init} and @code{mpfr_init2} are used for that
purpose.
@deftypefun void mpfr_init (mpfr_t @var{x})
-Initialize @var{x}, and set its value to NaN.
+Initialize @var{x} and set its value to NaN.
+
Normally, a variable should be initialized once only
or at least be cleared, using @code{mpfr_clear}, between initializations. The
precision of @var{x} is the default precision, which can be changed
@@ -657,7 +687,8 @@ by a call to @code{mpfr_set_default_prec}.
@deftypefun void mpfr_init2 (mpfr_t @var{x}, mp_prec_t @var{prec})
Initialize @var{x}, set its precision to be @strong{exactly}
-@var{prec} bits, and set its value to NaN.
+@var{prec} bits and its value to NaN.
+
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,
@@ -673,6 +704,7 @@ Free the space occupied by @var{x}. Make sure to call this function for all
@need 2000
Here is an example on how to initialize floating-point variables:
+
@example
@{
mpfr_t x, y;
@@ -690,15 +722,15 @@ calculation. A typical use would be for adjusting the precision gradually in
iterative algorithms like Newton-Raphson, making the computation precision
closely match the actual accurate part of the numbers.
-@deftypefun int mpfr_set_prec (mpfr_t @var{x}, mp_prec_t @var{prec})
-Reset the precision of @var{x} to be @strong{exactly} @var{prec} bits.
+@deftypefun void mpfr_set_prec (mpfr_t @var{x}, mp_prec_t @var{prec})
+Reset the precision of @var{x} to be @strong{exactly} @var{prec} bits,
+and set its value to NaN.
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.
The precision @var{prec} can be any integer between @code{MPFR_PREC_MIN} and
@code{MPFR_PREC_MAX}.
-It returns a non-zero value iff the memory allocation failed.
In case you want to keep the previous value stored in @var{x},
use @code{mpfr_round_prec} instead.
@@ -726,8 +758,9 @@ These functions assign new values to already initialized floats
@deftypefun int mpfr_set (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_set_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mp_rnd_t @var{rnd})
-@deftypefunx int mpfr_set_si (mpfr_t @var{rop}, long int @var{op}, mp_rnd_t @var{rnd}
+@deftypefunx int mpfr_set_si (mpfr_t @var{rop}, long int @var{op}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_set_d (mpfr_t @var{rop}, double @var{op}, mp_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_ld (mpfr_t @var{rop}, long double @var{op}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_set_z (mpfr_t @var{rop}, mpz_t @var{op}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_set_q (mpfr_t @var{rop}, mpq_t @var{op}, mp_rnd_t @var{rnd})
Set the value of @var{rop} from @var{op}, rounded to the precision of @var{rop}
@@ -741,17 +774,24 @@ For @code{mpfr_set_d}, be careful that the input number @var{op}
may not be exactly representable as a double-precision number (this happens for
0.1 for instance), in which case it is first
rounded by the C compiler to a double-precision number, and then only
-to a mpfr floating-point number.
+to a @code{mpfr} floating-point number.
+
+Please note that the ISO/IEC 9899:1999 (ISO C99)
+standard does not specify exactly the mantissa
+width of the long double type; the @code{mpfr_set_ld} function assumes
+it has at most 113 bits, and an exponent of at most 15 bits.
@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} (between
2 and 36), rounded in direction @var{rnd} to the precision of @var{x}.
-The exponent is read in decimal.
-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.
+See the documentation of @code{mpfr_inp_str} for a detailed description
+of the valid string formats.
+This function returns 0 if the entire string up to the final '\0' is a
+valid number in base @var{base}; otherwise it returns @minus{}1.
+
+Special values can be read as follows: @code{NaN}, @code{Inf}, @code{+Inf}
+and @code{-Inf} (possibly in lower case when the base is less than 24).
@end deftypefun
@deftypefun void mpfr_set_str_raw (mpfr_t @var{x}, char *@var{s})
@@ -821,7 +861,13 @@ See @code{mpfr_set_str}.
@cindex Conversion functions
@deftypefun double mpfr_get_d (mpfr_t @var{op}, mp_rnd_t @var{rnd})
-Convert @var{op} to a double, using the rounding mode @var{rnd}.
+@deftypefunx {long double} mpfr_get_ld (mpfr_t @var{op}, mp_rnd_t @var{rnd})
+Convert @var{op} to a double (respectively long double),
+using the rounding mode @var{rnd}.
+Please note that the ISO/IEC 9899:1999 (ISO C99)
+standard does not specify exactly the mantissa
+width of the long double type; the @code{mpfr_get_ld} function assumes
+it has at most 113 bits, and an exponent of at most 15 bits.
@end deftypefun
@deftypefun double mpfr_get_d1 (mpfr_t @var{op})
@@ -831,27 +877,29 @@ Convert @var{op} to a double, using the default MPFR rounding mode
@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}.
+@var{exp} such that @var{op} equals
+@ifnottex
+@var{z} multiplied by two exponent @var{exp}.
+@end ifnottex
+@tex
+$z \times 2^{\rm exp}$.
+@end tex
@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.
+from 2 to 36. Generate exactly @var{n_digits} significant digits
+which must be at least 2.
-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 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{n_digits} is zero, the number of digits of the mantissa is determined
+automatically from the precision of @var{op} and the value of @var{base}.
+Warning: this functionality may disappear or change in future versions.
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)}.
+the current allocation function (@pxref{Custom Allocation,,, gmp, GNU
+MP}), and a pointer to the string is returned. The block will be
+@code{strlen(s)+1} bytes.
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
@@ -885,10 +933,10 @@ case a null pointer is returned.
@deftypefunx int mpfr_add_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_add_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_add_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1} @math{+} @var{op2} rounded in the direction @var{rnd}.
-The return value is zero if @var{rop} is exactly @var{op1} @math{+} @var{op2},
-positive if @var{rop} is larger than @var{op1} @math{+} @var{op2},
-and negative if @var{rop} is smaller than @var{op1} @math{+} @var{op2}.
+Set @var{rop} to @math{@var{op1} + @var{op2}} rounded in the direction @var{rnd}.
+The return value is zero if @var{rop} is exactly @math{@var{op1} + @var{op2}},
+positive if @var{rop} is larger than @math{@var{op1} + @var{op2}},
+and negative if @var{rop} is smaller than @math{@var{op1} + @var{op2}}.
@end deftypefun
@deftypefun int mpfr_sub (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
@@ -896,26 +944,20 @@ and negative if @var{rop} is smaller than @var{op1} @math{+} @var{op2}.
@deftypefunx int mpfr_sub_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_sub_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_sub_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1} @minus{} @var{op2} rounded in the direction @var{rnd}.
-The return value is zero if @var{rop} is exactly @var{op1} @minus{} @var{op2},
-positive if @var{rop} is larger than @var{op1} @minus{} @var{op2},
-and negative if @var{rop} is smaller than @var{op1} @minus{} @var{op2}.
+Set @var{rop} to @math{@var{op1} - @var{op2}} rounded in the direction @var{rnd}.
+The return value is zero if @var{rop} is exactly @math{@var{op1} - @var{op2}},
+positive if @var{rop} is larger than @math{@var{op1} - @var{op2}},
+and negative if @var{rop} is smaller than @math{@var{op1} - @var{op2}}.
@end deftypefun
@deftypefun int mpfr_mul (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_mul_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_mul_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_mul_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mp_rnd_t @var{rnd})
-@ifinfo
-Set @var{rop} to @var{op1} times @var{op2} rounded in the direction @var{rnd}.
-Return 0 if the result is exact, a positive value if
-@var{rop}>@var{op1}*@var{op2}, a negative value otherwise.
-@end ifinfo
-@tex
-Set @var{rop} to $@var{op1} \times @var{op2}$ rounded in the direction @var{rnd}.
-Return 0 if the result is exact, a positive value if
-$@var{rop} > @var{op1} \times @var{op2}$, a negative value otherwise.
-@end tex
+Set @var{rop} to @math{@var{op1} @GMPtimes{} @var{op2}} rounded in the
+direction @var{rnd}. Return 0 if the result is exact, a positive
+value if @math{@var{rop} > @var{op1}@times{}@var{op2}}, a
+negative value otherwise.
@end deftypefun
@deftypefun int mpfr_div (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
@@ -923,49 +965,53 @@ $@var{rop} > @var{op1} \times @var{op2}$, a negative value otherwise.
@deftypefunx int mpfr_div_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_div_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_div_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1}/@var{op2} rounded in the direction @var{rnd}.
+Set @var{rop} to @math{@var{op1}/@var{op2}} rounded in the direction @var{rnd}.
These functions return 0 if the division is exact,
-a positive value when @var{rop} is larger than @var{op1} divided by @var{op2},
+a positive value when @var{rop} is larger than @math{@var{op1}/@var{op2}},
and a negative value otherwise.
@end deftypefun
@deftypefun int mpfr_sqrt (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_sqrt_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mp_rnd_t @var{rnd})
-@ifinfo
-Set @var{rop} to the square root of @var{op} rounded in the direction @var{rnd}.
-@end ifinfo
-@tex
-Set @var{rop} to $\sqrt{@var{op}}$ rounded in the direction @var{rnd}.
-@end tex
+Set @var{rop} to @m{\sqrt{@var{op}}, the square root of @var{op}}
+rounded in the direction @var{rnd}.
Set @var{rop} to NaN if @var{op} is negative.
Return 0 if the operation is exact, a non-zero value otherwise.
@end deftypefun
+@deftypefun int mpfr_cbrt (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
+Set @var{rop} to @m{{@var{op}^{1/3}}, the cubic root of @var{op}}
+rounded in the direction @var{rnd}.
+Return 0 if the operation is exact, a positive value when the return value
+is larger than @m{{@var{op}^{1/3}}, the cubic root of @var{op}},
+a negative value otherwise.
+@end deftypefun
+
@deftypefun int mpfr_pow_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_ui_pow_ui (mpfr_t @var{rop}, unsigned long int @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1} raised to @var{op2}. The computation is done by
-binary exponentiation.
+Set @var{rop} to @m{@var{op1}^{op2}, @var{op1} raised to @var{op2}}. The
+computation is done by binary exponentiation.
Return 0 if the result is exact, a non-zero value otherwise (but the sign
of the return value has no meaning).
@end deftypefun
@deftypefun int mpfr_ui_pow (mpfr_t @var{rop}, unsigned long int @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1} raised to @var{op2},
+Set @var{rop} to @m{@var{op1}^{op2}, @var{op1} raised to @var{op2}},
rounded to the direction @var{rnd} with the precision of @var{rop}.
Return zero iff the result is exact, a positive value when the
-result is greater than @var{op1} to the power @var{op2}, and a negative value
-when it is smaller.
+result is greater than @m{@var{op1}^{op2}, @var{op1} to the power @var{op2}},
+and a negative value when it is smaller.
@end deftypefun
@deftypefun int mpfr_pow_si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1} raised to the power @var{op2},
+Set @var{rop} to @m{@var{op1}^{op2}, @var{op1} raised to the power @var{op2}},
rounded to the direction @var{rnd} with the
precision of @var{rop}.
Return zero iff the result is exact.
@end deftypefun
@deftypefun int mpfr_pow (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{op1} raised to the power @var{op2},
+Set @var{rop} to @m{@var{op1}^{op2}, @var{op1} raised to the power @var{op2}},
rounded to the direction @var{rnd} with the precision of @var{rop}.
If @var{op1} is negative then @var{rop} is set to NaN,
even if @var{op2} is an integer.
@@ -973,7 +1019,7 @@ Return zero iff the result is exact.
@end deftypefun
@deftypefun int mpfr_neg (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
-Set @var{rop} to @minus{}@var{op} rounded in the direction @var{rnd}.
+Set @var{rop} to @math{-@var{op}} rounded in the direction @var{rnd}.
Just changes the sign
if @var{rop} and @var{op} are the same variable.
@end deftypefun
@@ -988,16 +1034,12 @@ the absolute value of @var{op}, and a negative value otherwise.
@deftypefun int mpfr_mul_2exp (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_mul_2ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_mul_2si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mp_rnd_t @var{rnd})
-@ifinfo
-Set @var{rop} to @var{op1} times 2 raised to @var{op2}
-@end ifinfo
-@tex
-Set @var{rop} to $@var{op1} \times 2^{op2}$
-@end tex
+Set @var{rop} to @m{@var{op1} \times 2^{op2}, @var{op1} times 2 raised
+to @var{op2}}
rounded to the direction @var{rnd}. Just increases the exponent by @var{op2}
when @var{rop} and @var{op1} are identical.
-Return zero when @var{rop}=@var{op1}, a positive value when @var{rop}>@var{op1},
-and a negative value when @var{rop}<@var{op1}.
+Return zero when @math{@var{rop}=@var{op1}}, a positive value when @math{@var{rop}>@var{op1}},
+and a negative value when @math{@var{rop}<@var{op1}}.
Note: The @code{mpfr_mul_2exp} function is defined for compatibility reasons;
you should use @code{mpfr_mul_2ui} (or @code{mpfr_mul_2si}) instead.
@end deftypefun
@@ -1005,21 +1047,17 @@ you should use @code{mpfr_mul_2ui} (or @code{mpfr_mul_2si}) instead.
@deftypefun int mpfr_div_2exp (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_div_2ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_div_2si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mp_rnd_t @var{rnd})
-@ifinfo
-Set @var{rop} to @var{op1} divided by 2 raised to @var{op2}
-@end ifinfo
-@tex
-Set @var{rop} to $@var{op1}/2^{op2}$
-@end tex
+Set @var{rop} to @m{@var{op1}/2^{op2}, @var{op1} divided by 2 raised
+to @var{op2}}
rounded to the direction @var{rnd}. Just decreases the exponent by @var{op2}
when @var{rop} and @var{op1} are identical.
-Return zero when @var{rop}=@var{op1}, a positive value when @var{rop}>@var{op1},
-and a negative value when @var{rop}<@var{op1}.
+Return zero when @math{@var{rop}=@var{op1}}, a positive value when @math{@var{rop}>@var{op1}},
+and a negative value when @math{@var{rop}<@var{op1}}.
Note: The @code{mpfr_div_2exp} function is defined for compatibility reasons;
you should use @code{mpfr_div_2ui} (or @code{mpfr_div_2si}) instead.
@end deftypefun
-@node Float Comparison, I/O of Floats, Float Arithmetic, Floating-point Functions
+@node Float Comparison, Special Functions, Float Arithmetic, Floating-point Functions
@comment node-name, next, previous, up
@section Comparison Functions
@cindex Float comparisons functions
@@ -1028,16 +1066,9 @@ you should use @code{mpfr_div_2ui} (or @code{mpfr_div_2si}) instead.
@deftypefun int mpfr_cmp (mpfr_t @var{op1}, mpfr_t @var{op2})
@deftypefunx int mpfr_cmp_ui (mpfr_t @var{op1}, unsigned long int @var{op2})
@deftypefunx int mpfr_cmp_si (mpfr_t @var{op1}, signed long int @var{op2})
-@ifinfo
-Compare @var{op1} and @var{op2}. Return a positive value if @var{op1} >
-@var{op2}, zero if @var{op1} = @var{op2}, and a negative value if @var{op1} <
-@var{op2}.
-@end ifinfo
-@tex
-Compare @var{op1} and @var{op2}. Return a positive value if $@var{op1} >
-@var{op2}$, zero if $@var{op1} = @var{op2}$, and a negative value if $@var{op1}
-< @var{op2}$.
-@end tex
+Compare @var{op1} and @var{op2}. Return a positive value if @math{@var{op1} >
+@var{op2}}, zero if @math{@var{op1} = @var{op2}}, and a negative value if
+@math{@var{op1} < @var{op2}}.
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
@@ -1045,12 +1076,21 @@ one plus the absolute difference of their exponents.
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})
-@deftypefunx int mpfr_cmp_si_2exp (mpfr_t @var{op1}, long int @var{op2}, int @var{e})
-Compare @var{op1} and @var{op2} multiplied by two to the power @var{e}.
+@deftypefun int mpfr_cmp_ui_2exp (mpfr_t @var{op1}, unsigned long int @var{op2}, mp_exp_t @var{e})
+@deftypefunx int mpfr_cmp_si_2exp (mpfr_t @var{op1}, long int @var{op2}, mp_exp_t @var{e})
+Compare @var{op1} and @m{@var{op2} \times 2^e, @var{op2} multiplied by two to
+the power @var{e}}.
+@end deftypefun
+
+@deftypefun int mpfr_cmpabs (mpfr_t @var{op1}, mpfr_t @var{op2})
+Compare @math{|@var{op1}|} and @math{|@var{op2}|}. Return a positive value if
+@math{|@var{op1}| > |@var{op2}|}, zero if @math{|@var{op1}| = |@var{op2}|}, and
+a negative value if @math{|@var{op1}| < |@var{op2}|}.
+It is not allowed that one of the operands is NaN (Not-a-Number) or an
+infinity.
@end deftypefun
-@deftypefun int mpfr_eq (mpfr_t @var{op1}, mpfr_t @var{op2}, unsigned long int op3)
+@deftypefun int mpfr_eq (mpfr_t @var{op1}, mpfr_t @var{op2}, unsigned long int @var{op3})
Return non-zero if the first @var{op3} bits of @var{op1} and @var{op2} are
equal, zero otherwise. I.e., tests if @var{op1} and @var{op2} are
approximately equal.
@@ -1073,16 +1113,17 @@ nor plus or minus infinity.
Compute the relative difference between @var{op1} and @var{op2}
and store the result in @var{rop}.
This function does not guarantee the exact rounding on the relative difference;
-it just computes abs(@var{op1}@minus{}@var{op2})/@var{op1}, using the
+it just computes @math{|@var{op1}-@var{op2}|/@var{op1}}, using the
rounding mode @var{rnd} for all operations.
@end deftypefun
@deftypefun int mpfr_sgn (mpfr_t @var{op})
-Return a positive value if @var{op} > 0, zero if @var{op} = 0,
-and a negative value if @var{op} < 0.
+Return a positive value if @math{@var{op} > 0}, zero if @math{@var{op} = 0},
+and a negative value if @math{@var{op} < 0}.
Its result is not specified when @var{op} is NaN (Not-a-Number).
@end deftypefun
+@node Special Functions, I/O of Floats, Float Comparison, Floating-point Functions
@section Special Functions
@cindex Special functions
@@ -1092,7 +1133,7 @@ rounded to the direction @var{rnd} with the precision of @var{rop}.
Return zero when the result is exact
(this occurs in fact only when @var{op} is 0, 1, or +infinity)
and a non-zero value otherwise (except for rounding to nearest,
-the sign of the return value is that of @var{rop}-log(@var{op}).
+the sign of the return value is that of @math{@var{rop}-@log{}(@var{op})}.
@end deftypefun
@deftypefun int mpfr_exp (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
@@ -1105,7 +1146,7 @@ and a negative value when it is smaller.
@end deftypefun
@deftypefun int mpfr_exp2 (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
-Set @var{rop} to 2 power of @var{op},
+Set @var{rop} to @m{2^{op}, 2 power of @var{op}},
rounded to the direction @var{rnd} with the precision of @var{rop}.
Return zero iff the result is exact (this occurs in fact only when @var{op}
is -infinity, 0, or +infinity),
@@ -1138,15 +1179,13 @@ rounded to the direction @var{rnd} with the precision of @var{rop}.
Return 0 iff the result is exact.
@end deftypefun
-@deftypefun int mpfr_cosh (mpfr_t @var{cop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
-@deftypefunx int mpfr_sinh (mpfr_t @var{sop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
-@deftypefunx int mpfr_tanh (mpfr_t @var{top}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
-Set @var{cop} to the hyperbolic cosine of @var{op},
- @var{sop} to the hyperbolic sine of @var{op},
- @var{top} to the hyperbolic tangent of @var{op},
+@deftypefun int mpfr_cosh (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
+@deftypefunx int mpfr_sinh (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
+@deftypefunx int mpfr_tanh (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
+Set @var{rop} to the hyperbolic cosine, sine or 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 1).
+or infinite).
@end deftypefun
@deftypefun int mpfr_acosh (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
@@ -1179,19 +1218,33 @@ i.e. the result is 0).
@deftypefun int mpfr_log2 (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
@deftypefunx int mpfr_log10 (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
-Set @var{rop} to the log[t] (t=2 or 10)(log x / log t) of @var{op}, rounded to the direction @var{rnd} with the precision of @var{rop}. Return 0 iff the result is exact (this occurs in fact only when @var{op} is 1 i.e. the result is 0).
+Set @var{rop} to @m{\log_2 @var{op}, log2(@var{op})} or @m{\log_{10} @var{op},
+log10(@var{op})}, respectively, rounded to the direction @var{rnd} with the
+precision of @var{rop}. Return 0 iff the result is exact (this occurs in fact
+only when @var{op} is 1 i.e. the result is 0).
+@end deftypefun
+
+@deftypefun int mpfr_gamma (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
+Set @var{rop} to the value of the Gamma function on @var{op},
+rounded to the direction @var{rnd} with the precision of @var{rop}.
+Return 0 iff the result is exact.
@end deftypefun
@deftypefun int mpfr_fma (mpfr_t @var{rop}, mpfr_t @var{opx},mpfr_t @var{opy},mpfr_t @var{opz}, mp_rnd_t @var{rnd})
-Set @var{rop} to @var{opx} * @var{opy} + @var{opz}, rounded to the direction
+Set @var{rop} to @math{@var{opx} @GMPtimes{} @var{opy} + @var{opz}}, rounded to the direction
@var{rnd} with the precision of @var{rop}. Return 0 iff the result is exact,
-a positive value if @var{rop} is larger than @var{opx} * @var{opy} + @var{opz},
+a positive value if @var{rop} is larger than @math{@var{opx} @GMPtimes{} @var{opy} + @var{opz}},
and a negative value otherwise.
@end deftypefun
-@deftypefun void mpfr_agm (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
+@deftypefun int mpfr_agm (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mp_rnd_t @var{rnd})
Set @var{rop} to the arithmetic-geometric mean of @var{op1} and @var{op2},
rounded to the direction @var{rnd} with the precision of @var{rop}.
+The arithmetic-geometric mean is the common limit of the sequences
+u[n] and v[n], where u[0]=@var{op1}, v[0]=@var{op2}, u[n+1] is the
+arithmetic mean of u[n] and v[n], and v[n+1] is the geometric mean of
+u[n] and v[n].
+Return 0 iff the result is exact.
@end deftypefun
@deftypefun void mpfr_const_log2 (mpfr_t @var{rop}, mp_rnd_t @var{rnd})
@@ -1202,17 +1255,17 @@ requested.
@end deftypefun
@deftypefun void mpfr_const_pi (mpfr_t @var{rop}, mp_rnd_t @var{rnd})
-Set @var{rop} to the value of Pi rounded to the direction @var{rnd}
+Set @var{rop} to the value of @m{\pi,Pi} rounded to the direction @var{rnd}
with the precision of @var{rop}. This function uses the Borwein, Borwein,
-Plouffe formula which directly gives the expansion of Pi in base 16.
+Plouffe formula which directly gives the expansion of @m{\pi,Pi} in base 16.
@end deftypefun
@deftypefun void mpfr_const_euler (mpfr_t @var{rop}, mp_rnd_t @var{rnd})
-Set @var{rop} to the value of Euler's constant 0.577...
+Set @var{rop} to the value of Euler's constant 0.577@dots{}
rounded to the direction @var{rnd} with the precision of @var{rop}.
@end deftypefun
-@node I/O of Floats, Miscellaneous Float Functions, Float Comparison, Floating-point Functions
+@node I/O of Floats, Miscellaneous Float Functions, Special Functions, Floating-point Functions
@comment node-name, next, previous, up
@section Input and Output Functions
@cindex Float input and output functions
@@ -1254,14 +1307,8 @@ read float in @var{rop}. The string is of the form @samp{M@@N} or, if the
base is 10 or less, alternatively @samp{MeN} or @samp{MEN}.
@samp{M} is the mantissa and
@samp{N} is the exponent. The mantissa is always in the specified base. The
-exponent is
-@c either in the specified base or, if @var{base} is negative,
-in decimal.
-
+exponent is read in decimal.
The argument @var{base} may be in the range 2 to 36.
-@c , or @minus{}36 to
-@c @minus{}2. Negative values are used to specify that the exponent is in
-@c decimal.
Unlike the corresponding @code{mpz} function, the base will not be determined
from the leading characters of the string if @var{base} is 0. This is so that
@@ -1284,7 +1331,7 @@ they should always be zero.
@c @end deftypefun
-@node Miscellaneous Float Functions, , I/O of Floats, Floating-point Functions
+@node Miscellaneous Float Functions, Internals, I/O of Floats, Floating-point Functions
@comment node-name, next, previous, up
@section Miscellaneous Functions
@cindex Miscellaneous float functions
@@ -1308,6 +1355,31 @@ that is not representable in @var{rop}, 2 or @minus{}2 when @var{op} is
not an integer.
@end deftypefun
+@deftypefun int mpfr_frac (mpfr_t @var{rop}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
+Set @var{rop} to the fractional part of @var{op}, having the same sign as
+@var{op}.
+The returned value is zero when the result is exact, positive when it is
+greater than the exact value, and negative when it is smaller.
+@end deftypefun
+
+@deftypefun void mpfr_nexttoward (mpfr_t @var{x}, mpfr_t @var{y})
+If @var{x} or @var{y} is NaN, set @var{x} to NaN; the global invalid
+flag is set too. Otherwise, if @var{x} is different from @var{y},
+replace @var{x} by the next floating-point number (with the precision
+of @var{x} and the current exponent range) in the direction of @var{y}
+(the infinite values are seen as the smallest and largest floating-point
+numbers). If the result is zero, it keeps the same sign. No underflow or
+overflow is generated.
+@end deftypefun
+
+@deftypefun void mpfr_nextabove (mpfr_t @var{x})
+Equivalent to @code{mpfr_nexttoward} where @var{y} is plus infinity.
+@end deftypefun
+
+@deftypefun void mpfr_nextbelow (mpfr_t @var{x})
+Equivalent to @code{mpfr_nexttoward} where @var{y} is minus infinity.
+@end deftypefun
+
@deftypefun void mpfr_urandomb (mpfr_t @var{rop}, gmp_randstate_t @var{state})
Generate a uniformly distributed random float in the interval 0 <= X < 1.
@end deftypefun
@@ -1335,13 +1407,15 @@ Negative random numbers are generated when @var{max_size} is negative.
@c releases.}
@c @end deftypefun
+@node Internals, , Miscellaneous Float Functions, Floating-point Functions
@section Internals
+@cindex Internals
These types and
functions were mainly designed for the implementation of @code{mpfr},
but may be useful for users too.
However no upward compatibility is guaranteed.
-You need to include @code{mpfr-impl.h} to use them.
+You may need to include @code{mpfr-impl.h} to use them.
The @code{mpfr_t} type consists of four fields.
The @code{_mpfr_prec} field is used to store the precision of
@@ -1353,11 +1427,11 @@ the sign (bit 31), the NaN flag (bit 30),
and the Infinity flag (bit 29);
thus bits 0 to 28 remain for the number of allocated limbs, with a maximal
value of 536870911.
-A NaN is indicated by the NaN flag set, and no other fields are
-relevant.
+A NaN is indicated by the NaN flag set, and the other fields are
+undefined.
An Infinity is indicated by the NaN flag clear and the Inf flag set;
the sign bit of an Infinity indicates the sign, the limb data
-and the exponent are not relevant.
+and the exponent are undefined.
The @code{_mpfr_exp} field stores the exponent.
An exponent of 0 means a radix point just above the most significant
@@ -1366,16 +1440,12 @@ point.
Finally, the @code{_mpfr_d} is a pointer to the limbs, least
significant limbs stored first.
-The number zero is represented with its most significant limb set to zero,
-i.e. @code{_mpfr_d[n-1]} where
-n=ceil(@code{_mpfr_prec}/@code{BITS_PER_MP_LIMB}).
The number of limbs in use is controlled by @code{_mpfr_prec}, namely
ceil(@code{_mpfr_prec}/@code{BITS_PER_MP_LIMB}).
-Zero is represented by the most significant limb being zero, other
-limb data and the exponent are not relevant
-("not relevant" implies that the corresponding objects may contain
-invalid values, thus should not be evaluated even if
-they are not taken into account).
+Zeros are represented by the most significant limb being zero, other
+limb data and the exponent are undefined (this implies that the
+corresponding objects may contain invalid values, thus should not be
+evaluated even if they are not taken into account).
Non-zero values always have the most significant bit of the most
significant limb set to 1. When the precision is not a whole number
of limbs, the excess bits at the low end of the data are zero.
@@ -1407,6 +1477,17 @@ E(b)-@var{err} where E(b) is the exponent of
and 0 otherwise. This function @strong{does not modify} its arguments.
@end deftypefun
+@deftypefun mp_exp_t mpfr_get_exp (mpfr_srcptr @var{x})
+Get the exponent of @var{x}, assuming that @var{x} is a non-zero real
+number.
+@end deftypefun
+
+@deftypefun int mpfr_set_exp (mpfr_ptr @var{x}, mp_exp_t @var{e})
+Set the exponent of @var{x} if @var{e} is in the current exponent range,
+and return 0; otherwise, return 1. If @var{x} is not a real number or is
+equal to zero, nothing visible happens.
+@end deftypefun
+
@node Contributors, References, Floating-point Functions, Top
@comment node-name, next, previous, up
@unnumbered Contributors
@@ -1435,7 +1516,7 @@ the base-2 exponential, and the factorial function. Fabrice Rouillier
contributed the original version of @file{mul_ui.c}, the @file{gmp_op.c}
file, and helped to the Windows porting.
-@node References, Concept Index, Contributors, Top
+@node References, GNU Free Documentation License, Contributors, Top
@comment node-name, next, previous, up
@unnumbered References
@@ -1443,7 +1524,7 @@ file, and helped to the Windows porting.
@item
Torbjorn Granlund, "GNU MP: The GNU Multiple Precision Arithmetic Library",
- version 4.0.1, 2001.
+ version 4.0.1, 2002.
@item
IEEE standard for binary floating-point arithmetic, Technical Report
@@ -1457,7 +1538,14 @@ Donald E. Knuth, "The Art of Computer Programming", vol 2,
@end itemize
-@node Concept Index, Function Index, References, Top
+
+@node GNU Free Documentation License, Concept Index, References, Top
+@appendix GNU Free Documentation License
+@cindex GNU Free Documentation License
+@include fdl.texi
+
+
+@node Concept Index, Function Index, GNU Free Documentation License, Top
@comment node-name, next, previous, up
@unnumbered Concept Index
@printindex cp
@@ -1467,5 +1555,8 @@ Donald E. Knuth, "The Art of Computer Programming", vol 2,
@unnumbered Function and Type Index
@printindex fn
-@contents
@bye
+
+@c Local variables:
+@c fill-column: 78
+@c End:
diff --git a/mpfr/mul.c b/mpfr/mul.c
index 6b9ceb04a..66dcaf8a9 100644
--- a/mpfr/mul.c
+++ b/mpfr/mul.c
@@ -27,8 +27,8 @@ MA 02111-1307, USA. */
int
mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
{
- int sign_product, cc, inexact, ec, em = 0;
- mp_exp_t bx, cx;
+ int sign_product, cc, inexact;
+ mp_exp_t ax, bx, cx;
mp_limb_t *ap, *bp, *cp, *tmp;
mp_limb_t b1;
mp_prec_t aq, bq, cq;
@@ -90,39 +90,15 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
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;
- }
+ /* Note: the exponent of the exact result will be e = bx + cx + ec with
+ ec in {-1,0,1} and the following assumes that e is representable. */
+ MPFR_ASSERTN(MPFR_EMAX_MAX <= (MP_EXP_T_MAX >> 1));
+ MPFR_ASSERTN(MPFR_EMIN_MIN >= -(MP_EXP_T_MAX >> 1));
+ if (bx + cx > __gmpfr_emax + 1)
+ return mpfr_set_overflow (a, rnd_mode, sign_product);
+ if (bx + cx < __gmpfr_emin - 2)
+ return mpfr_set_underflow (a, rnd_mode == GMP_RNDN ? GMP_RNDZ : rnd_mode,
+ sign_product);
ap = MPFR_MANT(a);
bp = MPFR_MANT(b);
@@ -160,38 +136,26 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
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] = GMP_LIMB_HIGHBIT;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
TMP_FREE(marker);
- 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
+ ax = (bx + cx) + (mp_exp_t) (b1 - 1 + cc);
+ if (ax > __gmpfr_emax)
+ return mpfr_set_overflow (a, rnd_mode, sign_product);
+ if (ax < __gmpfr_emin)
{
- if (ec <= 0)
- return mpfr_set_underflow(a, rnd_mode, sign_product);
-
- MPFR_EXP(a) = __mpfr_emin;
+ /* In the rounding to the nearest mode, if the exponent of the exact
+ result (i.e. before rounding, i.e. without taking cc into account)
+ is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if
+ both arguments are powers of 2), then round to zero. */
+ if (rnd_mode == GMP_RNDN &&
+ ((bx + cx) + (mp_exp_t) b1 < __gmpfr_emin ||
+ (mpfr_powerof2_raw (b) && mpfr_powerof2_raw (c))))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow (a, rnd_mode, sign_product);
}
+ MPFR_EXP(a) = ax;
if (MPFR_SIGN(a) != sign_product)
MPFR_CHANGE_SIGN(a);
diff --git a/mpfr/mul_2si.c b/mpfr/mul_2si.c
index a71cf0581..ad0b29f27 100644
--- a/mpfr/mul_2si.c
+++ b/mpfr/mul_2si.c
@@ -24,12 +24,6 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
-
-/* In the overflow test "n > emax - emin" ensures "emax-n" doesn't wrap
- around if n is big. It used to done with "emax < MPFR_EMIN_MIN + n", but
- that provoked a compiler bug on mips gcc 2.95.3 in -O2 -mabi=n32.
- Similarly for the underflow test. */
-
int
mpfr_mul_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
{
@@ -39,17 +33,20 @@ mpfr_mul_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
if (MPFR_IS_FP(y) && MPFR_NOTZERO(y))
{
- if (n > 0
- && ((unsigned long) n >
- (unsigned long) (mp_exp_unsigned_t) (__mpfr_emax - __mpfr_emin)
- || MPFR_EXP(y) > __mpfr_emax - n))
+ if (n > 0 && (__gmpfr_emax < MPFR_EMIN_MIN + n ||
+ MPFR_EXP(y) > __gmpfr_emax - n))
return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y));
- if (n < 0
- && ((unsigned long) -n >
- (unsigned long) (mp_exp_unsigned_t) (__mpfr_emax - __mpfr_emin)
- || MPFR_EXP(y) < __mpfr_emin - n))
- return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y));
+ if (n < 0 && (__gmpfr_emin > MPFR_EMAX_MAX + n ||
+ MPFR_EXP(y) < __gmpfr_emin - n))
+ {
+ if (rnd_mode == GMP_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX + (n + 1) ||
+ MPFR_EXP(y) < __gmpfr_emin - (n + 1) ||
+ mpfr_powerof2_raw (y)))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
MPFR_EXP(y) += n;
}
diff --git a/mpfr/mul_2ui.c b/mpfr/mul_2ui.c
index 5ce0404e8..575e21f64 100644
--- a/mpfr/mul_2ui.c
+++ b/mpfr/mul_2ui.c
@@ -48,8 +48,8 @@ mpfr_mul_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mp_rnd_t rnd_mode)
/* 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)
+ if (__gmpfr_emax < MPFR_EMIN_MIN + (long) n ||
+ MPFR_EXP(y) > __gmpfr_emax - (long) n)
return mpfr_set_overflow (y, rnd_mode, MPFR_SIGN(y));
MPFR_EXP(y) += (long) n;
diff --git a/mpfr/mul_ui.c b/mpfr/mul_ui.c
index f655071a5..d248d1c55 100644
--- a/mpfr/mul_ui.c
+++ b/mpfr/mul_ui.c
@@ -78,6 +78,7 @@ mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
if (yn < xn + 1)
yp = (mp_ptr) TMP_ALLOC ((size_t) (xn + 1) * BYTES_PER_MP_LIMB);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
yp[xn] = mpn_mul_1 (yp, MPFR_MANT(x), xn, u);
/* x * u is stored in yp[xn], ..., yp[0] */
@@ -85,7 +86,7 @@ mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
/* since the case u=1 was treated above, we have u >= 2, thus
yp[xn] >= 1 since x was msb-normalized */
MPFR_ASSERTN(yp[xn] != 0);
- if ((yp[xn] & GMP_LIMB_HIGHBIT) == 0)
+ if ((yp[xn] & MPFR_LIMB_HIGHBIT) == 0)
{
count_leading_zeros(cnt, yp[xn]);
mpn_lshift (yp, yp, xn + 1, cnt);
@@ -105,13 +106,13 @@ mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
if (c) /* rounded result is 1.0000000000000000... */
{
- old_yp[yn-1] = GMP_LIMB_HIGHBIT;
+ old_yp[yn-1] = MPFR_LIMB_HIGHBIT;
cnt++;
}
TMP_FREE(marker);
- if (__mpfr_emax < MPFR_EMAX_MIN + cnt || MPFR_EXP(x) > __mpfr_emax - cnt)
+ if (__gmpfr_emax < MPFR_EMAX_MIN + cnt || MPFR_EXP(x) > __gmpfr_emax - cnt)
return mpfr_set_overflow(y, rnd_mode, MPFR_SIGN(x));
MPFR_EXP(y) = MPFR_EXP(x) + cnt;
diff --git a/mpfr/next.c b/mpfr/next.c
new file mode 100644
index 000000000..974c3bf76
--- /dev/null
+++ b/mpfr/next.c
@@ -0,0 +1,150 @@
+/* mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward -- next representable
+floating-point number
+
+Copyright 1999, 2001, 2002 Free Software Foundation.
+Contributed by the Spaces project, INRIA Lorraine.
+
+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"
+
+static void
+mpfr_nexttozero (mpfr_ptr x)
+{
+ if (MPFR_IS_INF(x))
+ {
+ MPFR_CLEAR_FLAGS(x);
+ mpfr_setmax (x, __gmpfr_emax);
+ return;
+ }
+
+ if (MPFR_IS_ZERO(x))
+ {
+ MPFR_CHANGE_SIGN(x);
+ mpfr_setmin (x, __gmpfr_emin);
+ }
+ else
+ {
+ mp_size_t xn;
+ int sh;
+ mp_limb_t *xp;
+
+ xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
+ sh = (mp_prec_t) 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 */
+ mp_exp_t exp = MPFR_EXP(x);
+ if (exp == __gmpfr_emin)
+ MPFR_SET_ZERO(x);
+ else
+ {
+ mp_size_t i;
+ MPFR_EXP(x)--;
+ xp[0] = MP_LIMB_T_MAX << sh;
+ for (i = 1; i < xn; i++)
+ xp[i] = MP_LIMB_T_MAX;
+ }
+ }
+ }
+}
+
+static void
+mpfr_nexttoinf (mpfr_ptr x)
+{
+ if (MPFR_IS_INF(x))
+ return;
+
+ if (MPFR_IS_ZERO(x))
+ mpfr_setmin (x, __gmpfr_emin);
+ else
+ {
+ mp_size_t xn;
+ int sh;
+ mp_limb_t *xp;
+
+ xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
+ sh = (mp_prec_t) 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 == __gmpfr_emax)
+ MPFR_SET_INF(x);
+ else
+ {
+ MPFR_EXP(x)++;
+ xp[xn-1] = MPFR_LIMB_HIGHBIT;
+ }
+ }
+ }
+}
+
+void
+mpfr_nextabove (mpfr_ptr x)
+{
+ if (MPFR_IS_NAN(x))
+ {
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+
+ if (MPFR_SIGN(x) < 0)
+ mpfr_nexttozero (x);
+ else
+ mpfr_nexttoinf (x);
+}
+
+void
+mpfr_nextbelow (mpfr_ptr x)
+{
+ if (MPFR_IS_NAN(x))
+ {
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+
+ if (MPFR_SIGN(x) < 0)
+ mpfr_nexttoinf (x);
+ else
+ mpfr_nexttozero (x);
+}
+
+void
+mpfr_nexttoward (mpfr_ptr x, mpfr_srcptr y)
+{
+ int s;
+
+ if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y))
+ {
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+
+ s = mpfr_cmp (x, y);
+ if (s == 0)
+ return;
+ if (s < 0)
+ mpfr_nextabove (x);
+ else
+ mpfr_nextbelow (x);
+}
diff --git a/mpfr/out_str.c b/mpfr/out_str.c
index a186eb6c3..df638ff7e 100644
--- a/mpfr/out_str.c
+++ b/mpfr/out_str.c
@@ -1,6 +1,6 @@
/* mpfr_out_str -- output a floating-point number to a stream
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
diff --git a/mpfr/pow.c b/mpfr/pow.c
index afc24fc0a..4433fb881 100644
--- a/mpfr/pow.c
+++ b/mpfr/pow.c
@@ -21,12 +21,73 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "gmp-impl.h"
+#include "longlong.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+static int mpfr_pow_is_exact _PROTO((mpfr_srcptr, mpfr_srcptr));
+
+/* return non zero iff x^y is exact.
+ Assumes x and y are ordinary numbers (neither NaN nor Inf),
+ and y is not zero.
+*/
+int
+mpfr_pow_is_exact (mpfr_srcptr x, mpfr_srcptr y)
+{
+ mp_exp_t d;
+ unsigned long i, c;
+ mp_limb_t *yp;
+ mp_size_t ysize;
+
+ if ((mpfr_sgn (x) < 0) && (mpfr_isinteger (y) == 0))
+ return 0;
+
+ if (mpfr_sgn (y) < 0)
+ return mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0;
+
+ /* compute d such that y = c*2^d with c odd integer */
+ ysize = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB;
+ d = MPFR_EXP(y) - ysize * BITS_PER_MP_LIMB;
+ /* since y is not zero, necessarily one of the mantissa limbs is not zero,
+ thus we can simply loop until we find a non zero limb */
+ yp = MPFR_MANT(y);
+ for (i = 0; yp[i] == 0; i++, d += BITS_PER_MP_LIMB);
+ /* now yp[i] is not zero */
+ count_trailing_zeros (c, yp[i]);
+ d += c;
+
+ if (d < 0)
+ {
+ mpz_t a;
+ mp_exp_t b;
+
+ mpz_init (a);
+ b = mpfr_get_z_exp (a, x); /* x = a * 2^b */
+ c = mpz_scan1 (a, 0);
+ mpz_div_2exp (a, a, c);
+ b += c;
+ /* now a is odd */
+ while (d != 0)
+ {
+ if (mpz_perfect_square_p (a))
+ {
+ d++;
+ mpz_sqrt (a, a);
+ }
+ else
+ {
+ mpz_clear (a);
+ return 0;
+ }
+ }
+ mpz_clear (a);
+ }
+
+ return 1;
+}
+
/* 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)
{
@@ -64,7 +125,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
}
mpfr_init2(one, BITS_PER_MP_LIMB);
mpfr_set_ui(one, 1, GMP_RNDN);
- cmp = mpfr_cmp_abs(x, one);
+ cmp = mpfr_cmpabs(x, one);
mpfr_clear(one);
if (cmp > 0)
{
@@ -104,7 +165,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
}
mpfr_init2(one, BITS_PER_MP_LIMB);
mpfr_set_ui(one, 1, GMP_RNDN);
- cmp = mpfr_cmp_abs(x, one);
+ cmp = mpfr_cmpabs(x, one);
mpfr_clear(one);
MPFR_CLEAR_FLAGS(z);
if (cmp > 0)
@@ -129,10 +190,10 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
if (MPFR_IS_ZERO(y))
{
- return mpfr_set_ui(z,1,GMP_RNDN);
+ return mpfr_set_ui (z, 1, GMP_RNDN);
}
- if(mpfr_isinteger(y))
+ if (mpfr_isinteger (y))
{
mpz_t zi;
long int zii;
@@ -146,10 +207,10 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
else
mpz_tdiv_q_2exp(zi, zi, (unsigned long int) (-exptol));
- zii=mpz_get_ui(zi);
-
+ zii=mpz_get_si(zi);
+
mpz_clear(zi);
- return mpfr_pow_si(z,x,zii,rnd_mode);
+ return mpfr_pow_si (z, x, zii, rnd_mode);
}
if (MPFR_IS_INF(x))
@@ -190,55 +251,61 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
/* General case */
{
/* Declaration of the intermediary variable */
- mpfr_t t, te, ti;
-
- /* 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 */
+ mpfr_t t, te, ti;
+ int loop = 0, ok;
- 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+5+_mpfr_ceil_log2(Nt);
+ /* 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 output variable */
- /* initialise of intermediary variable */
- mpfr_init(t);
- mpfr_init(ti);
- mpfr_init(te);
+ mp_prec_t Nt; /* Precision of the intermediary variable */
+ long int err; /* Precision of error */
- do {
+ /* compute the precision of intermediary variable */
+ Nt=MAX(Nx,Ny);
+ /* the optimal number of bits : see algorithms.ps */
+ Nt=Nt+5+__gmpfr_ceil_log2(Nt);
- /* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(ti,Nt);
- mpfr_set_prec(te,Nt);
+ /* initialise of intermediary variable */
+ mpfr_init(t);
+ mpfr_init(ti);
+ mpfr_init(te);
- /* compute exp(y*ln(x))*/
- mpfr_log(ti,x,GMP_RNDU); /* ln(n) */
- mpfr_mul(te,y,ti,GMP_RNDU); /* y*ln(n) */
- mpfr_exp(t,te,GMP_RNDN); /* exp(x*ln(n))*/
+ do
+ {
+ loop ++;
- /* estimation of the error -- see pow function in algorithms.ps*/
- err = Nt - (MPFR_EXP(te)+3);
+ /* reactualisation of the precision */
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (ti, Nt);
+ mpfr_set_prec (te, Nt);
- /* actualisation of the precision */
- Nt += 10;
-
- } while (err<0 || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
- inexact = mpfr_set(z,t,rnd_mode);
- mpfr_clear(t);
- mpfr_clear(ti);
- mpfr_clear(te);
- }
- return inexact;
-}
+ /* compute exp(y*ln(x)) */
+ mpfr_log (ti, x, GMP_RNDU); /* ln(n) */
+ mpfr_mul (te, y, ti, GMP_RNDU); /* y*ln(n) */
+ mpfr_exp (t, te, GMP_RNDN); /* exp(x*ln(n))*/
+ /* estimate of the error -- see pow function in algorithms.ps */
+ err = Nt - (MPFR_EXP(te) + 3);
+ /* actualisation of the precision */
+ Nt += 10;
+ ok = mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Nz);
+ /* check exact power */
+ if (ok == 0 && loop == 1)
+ ok = mpfr_pow_is_exact (x, y);
+ }
+ while (err < 0 || ok == 0);
+ inexact = mpfr_set (z, t, rnd_mode);
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
+ }
+ return inexact;
+}
diff --git a/mpfr/pow_si.c b/mpfr/pow_si.c
index 56d3ee69a..61474821f 100644
--- a/mpfr/pow_si.c
+++ b/mpfr/pow_si.c
@@ -90,7 +90,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode)
/* 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);
+ Nt=Nt+3+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
mpfr_init(t);
diff --git a/mpfr/rnd_mode.c b/mpfr/powerof2.c
index 3f4229f6e..f4bf0d3c6 100644
--- a/mpfr/rnd_mode.c
+++ b/mpfr/powerof2.c
@@ -1,6 +1,6 @@
-/* mpfr_set_machine_rnd_mode -- set the rounding mode for machine floats
+/* mpfr_powerof2_raw -- test whether a floating-point number is a power of 2
-Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
+Copyright 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -19,25 +19,26 @@ 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"
-#ifdef MPFR_HAVE_FESETROUND
-#include <fenv.h>
+/* This is an internal function and one assumes that x is a real number. */
-/* sets the machine rounding mode to the value rnd_mode */
-void
-mpfr_set_machine_rnd_mode (mp_rnd_t rnd_mode)
+int
+mpfr_powerof2_raw (mpfr_srcptr x)
{
- switch (rnd_mode) {
- case GMP_RNDN: fesetround(FE_TONEAREST); break;
- case GMP_RNDZ: fesetround(FE_TOWARDZERO); break;
- case GMP_RNDU: fesetround(FE_UPWARD); break;
- case GMP_RNDD: fesetround(FE_DOWNWARD); break;
- default: fprintf(stderr, "invalid rounding mode\n"); exit(1);
- }
+ mp_limb_t *xp;
+ mp_size_t xn;
+
+ MPFR_ASSERTN(MPFR_IS_FP(x));
+ xp = MPFR_MANT(x);
+ xn = (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
+ if (NOT_POW2(xp[xn]))
+ return 0;
+ while (xn > 0)
+ if (xp[--xn] != 0)
+ return 0;
+ return 1;
}
-#endif
diff --git a/mpfr/print_raw.c b/mpfr/print_raw.c
index 0fece2f70..06617fab4 100644
--- a/mpfr/print_raw.c
+++ b/mpfr/print_raw.c
@@ -1,7 +1,7 @@
/* mpfr_print_binary -- print the internal binary representation of a
floating-point number
-Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -44,7 +44,7 @@ mpfr_get_str_raw (char *digit_ptr, mpfr_srcptr x)
for (k = sx - 1; k >= 0 ; k--)
{
wd = mx[k];
- t = GMP_LIMB_HIGHBIT;
+ t = MPFR_LIMB_HIGHBIT;
for (l = BITS_PER_MP_LIMB - 1; l>=0; l--)
{
if (wd & t)
diff --git a/mpfr/random.c b/mpfr/random.c
index 50fa7fc5d..8347ae032 100644
--- a/mpfr/random.c
+++ b/mpfr/random.c
@@ -1,6 +1,6 @@
/* mpfr_random -- generate a random floating-point number
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 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 "longlong.h"
@@ -31,26 +30,30 @@ MA 02111-1307, USA. */
void
mpfr_random (mpfr_ptr x)
{
- mp_limb_t *xp; unsigned long xn, cnt, prec = MPFR_PREC(x);
+ mp_limb_t *xp;
+ mp_prec_t prec;
+ mp_size_t xn;
+ int cnt;
MPFR_CLEAR_FLAGS(x);
xp = MPFR_MANT(x);
- xn = (prec-1)/BITS_PER_MP_LIMB + 1;
+ prec = MPFR_PREC(x);
+ xn = (prec - 1) / BITS_PER_MP_LIMB + 1;
mpn_random (xp, xn);
if (xp[xn - 1] == 0)
xp[xn - 1] = 1;
- /* since count_leading_zeros doesn't like zeroes */
+ /* since count_leading_zeros doesn't like zeroes, but xp[xn - 1] = 1
+ will appear twice often. */
- count_leading_zeros (cnt, xp[xn - 1]);
- if (cnt)
- mpn_lshift (xp, xp, xn, cnt);
- MPFR_EXP(x) = -cnt;
- if (MPFR_SIGN(x) < 0)
- MPFR_CHANGE_SIGN(x);
+ count_leading_zeros (cnt, xp[xn - 1]);
+ if (cnt != 0)
+ mpn_lshift (xp, xp, xn, cnt);
+ MPFR_EXP(x) = -cnt;
+ MPFR_SET_POS(x);
- cnt = xn * BITS_PER_MP_LIMB - prec;
+ cnt = (mp_prec_t) xn * BITS_PER_MP_LIMB - prec;
/* cnt is the number of non significant bits in the low limb */
xp[0] &= ~((MP_LIMB_T_ONE << cnt) - MP_LIMB_T_ONE);
}
diff --git a/mpfr/random2.c b/mpfr/random2.c
index cbe88ebe4..af3643719 100644
--- a/mpfr/random2.c
+++ b/mpfr/random2.c
@@ -2,7 +2,7 @@
long runs of consecutive ones and zeros in the binary representation.
Intended for testing of other MP routines.
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
(Copied from the GNU MP Library.)
This file is part of the MPFR Library.
@@ -35,29 +35,26 @@ mpfr_random2 (mpfr_ptr x, mp_size_t size, mp_exp_t exp)
mp_size_t xn;
unsigned long cnt;
mp_ptr xp = MPFR_MANT(x), yp[1];
- mp_size_t prec = (MPFR_PREC(x) - 1)/BITS_PER_MP_LIMB;
+ mp_size_t prec = (MPFR_PREC(x) - 1)/BITS_PER_MP_LIMB;
MPFR_CLEAR_FLAGS(x);
xn = ABS (size);
if (xn != 0)
{
if (xn > prec + 1)
- xn = prec + 1;
+ xn = prec + 1;
mpn_random2 (xp, xn);
}
- if (exp != 0) {
- /* use mpn_random instead of random since that function is not
- available on all platforms (for example HPUX, DEC OSF, ...) */
- mpn_random ((mp_limb_t*) yp, 1);
- exp = (mp_exp_t) yp[0] % (2 * exp) - exp;
- }
-
- count_leading_zeros(cnt, xp[xn - 1]);
- if (cnt) mpn_lshift(xp, xp, xn, cnt);
- MPFR_EXP(x) = exp-cnt;
- cnt = xn*BITS_PER_MP_LIMB - prec;
+ count_leading_zeros (cnt, xp[xn - 1]);
+ if (cnt)
+ mpn_lshift (xp, xp, xn, cnt);
+
+ mpn_random ((mp_limb_t*) yp, 1);
+ MPFR_EXP(x) = ABS ((mp_exp_t) yp[0] % (2 * exp + 1)) - exp;
+
+ cnt = xn * BITS_PER_MP_LIMB - MPFR_PREC(x);
/* cnt is the number of non significant bits in the low limb */
xp[0] &= ~((MP_LIMB_T_ONE << cnt) - MP_LIMB_T_ONE);
}
diff --git a/mpfr/rint.c b/mpfr/rint.c
index f549ea40b..89ebc66fd 100644
--- a/mpfr/rint.c
+++ b/mpfr/rint.c
@@ -68,7 +68,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
rp = MPFR_MANT(r);
rm = (MPFR_PREC(r) - 1) / BITS_PER_MP_LIMB;
- rp[rm] = GMP_LIMB_HIGHBIT;
+ rp[rm] = MPFR_LIMB_HIGHBIT;
MPN_ZERO(rp, rm);
MPFR_EXP(r) = 1; /* |r| = 1 */
MPFR_RET(sign > 0 ? 2 : -2);
@@ -98,7 +98,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
un = MPFR_ESIZE(u);
rn = MPFR_ESIZE(r);
- sh = rn * BITS_PER_MP_LIMB - MPFR_PREC(r);
+ sh = (mp_prec_t) rn * BITS_PER_MP_LIMB - MPFR_PREC(r);
MPFR_EXP(r) = exp;
@@ -134,7 +134,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
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] & GMP_LIMB_HIGHBIT) == 0)))
+ (sh == 0 && (up[un - rn - 1] & MPFR_LIMB_HIGHBIT) == 0)))
rnd_mode = GMP_RNDZ;
if (uflags == 0)
{ /* u is an integer; determine if it is representable */
@@ -193,7 +193,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
((ush != 0 &&
(up[uj] & (MP_LIMB_T_ONE << (ush - 1))) == 0) ||
(ush == 0 &&
- (uj == 0 || (up[uj - 1] & GMP_LIMB_HIGHBIT) == 0))))
+ (uj == 0 || (up[uj - 1] & MPFR_LIMB_HIGHBIT) == 0))))
rnd_mode = GMP_RNDZ; /* rounding bit is 0 */
}
if (sh != 0)
@@ -212,13 +212,13 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
(rnd_mode == GMP_RNDU && sign > 0))
&& mpn_add_1(rp, rp, rn, MP_LIMB_T_ONE << sh))
{
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
return mpfr_set_overflow(r, rnd_mode, MPFR_SIGN(r)) >= 0 ?
uflags : -uflags;
else
{
MPFR_EXP(r)++;
- rp[rn-1] = GMP_LIMB_HIGHBIT;
+ rp[rn-1] = MPFR_LIMB_HIGHBIT;
}
}
diff --git a/mpfr/round_prec.c b/mpfr/round_prec.c
index 2ecf972d5..cfd066b7b 100644
--- a/mpfr/round_prec.c
+++ b/mpfr/round_prec.c
@@ -193,12 +193,12 @@ mpfr_round_prec (mpfr_ptr x, mp_rnd_t rnd_mode, mp_prec_t prec)
{
mp_exp_t exp = MPFR_EXP(x);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
(void) mpfr_set_overflow(x, rnd_mode, MPFR_SIGN(x));
else
{
MPFR_EXP(x)++;
- xp[nw - 1] = GMP_LIMB_HIGHBIT;
+ xp[nw - 1] = MPFR_LIMB_HIGHBIT;
if (nw - 1 > 0)
MPN_ZERO(xp, nw - 1);
}
diff --git a/mpfr/save_expo.c b/mpfr/save_expo.c
index 250ab078b..5f2a83651 100644
--- a/mpfr/save_expo.c
+++ b/mpfr/save_expo.c
@@ -1,6 +1,6 @@
/* Save/restore the minimum and maximum exponents.
-Copyright 2001 Free Software Foundation, Inc.
+Copyright 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -35,11 +35,11 @@ mpfr_save_emin_emax (void)
{
if (save_ctr++ == 0)
{
- saved_flags = __mpfr_flags;
- saved_emin = __mpfr_emin;
- saved_emax = __mpfr_emax;
- __mpfr_emin = MPFR_EMIN_MIN;
- __mpfr_emax = MPFR_EMAX_MAX;
+ saved_flags = __gmpfr_flags;
+ saved_emin = __gmpfr_emin;
+ saved_emax = __gmpfr_emax;
+ __gmpfr_emin = MPFR_EMIN_MIN;
+ __gmpfr_emax = MPFR_EMAX_MAX;
}
else if (save_ctr == 0)
{
@@ -55,8 +55,8 @@ mpfr_restore_emin_emax (void)
{
if (--save_ctr == 0)
{
- __mpfr_flags = saved_flags;
- __mpfr_emin = saved_emin;
- __mpfr_emax = saved_emax;
+ __gmpfr_flags |= saved_flags;
+ __gmpfr_emin = saved_emin;
+ __gmpfr_emax = saved_emax;
}
}
diff --git a/mpfr/set.c b/mpfr/set.c
index ca5822367..ce6a6c9af 100644
--- a/mpfr/set.c
+++ b/mpfr/set.c
@@ -1,6 +1,6 @@
/* mpfr_set -- copy of a floating-point number
-Copyright 1999, 2001 Free Software Foundation.
+Copyright 1999, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -45,28 +45,35 @@ mpfr_set4 (mpfr_ptr a, mpfr_srcptr b, mp_rnd_t rnd_mode, int signb)
}
else
{
- mp_limb_t *ap;
- mp_prec_t aq;
- int carry;
-
MPFR_CLEAR_FLAGS(a);
+ if (MPFR_IS_ZERO(b))
+ {
+ MPFR_SET_ZERO(a);
+ inex = 0;
+ }
+ else
+ {
+ mp_limb_t *ap;
+ mp_prec_t aq;
+ int carry;
- ap = MPFR_MANT(a);
- aq = MPFR_PREC(a);
+ ap = MPFR_MANT(a);
+ aq = MPFR_PREC(a);
- carry = mpfr_round_raw(ap, MPFR_MANT(b), MPFR_PREC(b), (signb < 0),
- aq, rnd_mode, &inex);
- MPFR_EXP(a) = MPFR_EXP(b);
+ carry = mpfr_round_raw(ap, MPFR_MANT(b), MPFR_PREC(b), (signb < 0),
+ aq, rnd_mode, &inex);
+ MPFR_EXP(a) = MPFR_EXP(b);
- if (carry)
- {
- mp_exp_t exp = MPFR_EXP(a);
+ if (carry)
+ {
+ mp_exp_t exp = MPFR_EXP(a);
- if (exp == __mpfr_emax)
- return mpfr_set_overflow(a, rnd_mode, signb);
+ if (exp == __gmpfr_emax)
+ return mpfr_set_overflow(a, rnd_mode, signb);
- MPFR_EXP(a)++;
- ap[(MPFR_PREC(a)-1)/BITS_PER_MP_LIMB] = GMP_LIMB_HIGHBIT;
+ MPFR_EXP(a)++;
+ ap[(MPFR_PREC(a)-1)/BITS_PER_MP_LIMB] = MPFR_LIMB_HIGHBIT;
+ }
}
}
diff --git a/mpfr/set_d.c b/mpfr/set_d.c
index 2605d1a99..7f290f613 100644
--- a/mpfr/set_d.c
+++ b/mpfr/set_d.c
@@ -205,23 +205,30 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode)
MPFR_EXP(tmp) = __mpfr_extract_double (tmpmant, d);
- /* determine the index i of the most significant non-zero limb
- and the number k of zero high limbs */
- i = MPFR_LIMBS_PER_DOUBLE - 1;
- k = 0;
+#ifndef NDEBUG
+ /* Failed assertion if the stored value is 0 (e.g., if the exponent range
+ has been reduced at the wrong moment and an underflow to 0 occurred).
+ Probably a bug in the C implementation if this happens. */
+ i = 0;
while (tmpmant[i] == 0)
{
- MPFR_ASSERTN(i > 0);
- i--;
- k++;
+ i++;
+ MPFR_ASSERTN(i < MPFR_LIMBS_PER_DOUBLE);
}
+#endif
+
+ /* determine the index i-1 of the most significant non-zero limb
+ and the number k of zero high limbs */
+ i = MPFR_LIMBS_PER_DOUBLE;
+ MPN_NORMALIZE_NOT_ZERO(tmpmant, i);
+ k = MPFR_LIMBS_PER_DOUBLE - i;
- count_leading_zeros (cnt, tmpmant[i]);
+ count_leading_zeros (cnt, tmpmant[i - 1]);
if (cnt)
- mpn_lshift (tmpmant + k, tmpmant, i + 1, cnt);
+ mpn_lshift (tmpmant + k, tmpmant, i, cnt);
else if (k)
- MPN_COPY (tmpmant + k, tmpmant, i + 1);
+ MPN_COPY (tmpmant + k, tmpmant, i);
if (k)
MPN_ZERO (tmpmant, k);
diff --git a/mpfr/set_dfl_prec.c b/mpfr/set_dfl_prec.c
index 69d6260c2..c61875793 100644
--- a/mpfr/set_dfl_prec.c
+++ b/mpfr/set_dfl_prec.c
@@ -25,17 +25,17 @@ MA 02111-1307, USA. */
#include "mpfr-impl.h"
/* default is 53 bits */
-mp_prec_t __mpfr_default_fp_bit_precision = 53;
+mp_prec_t __gmpfr_default_fp_bit_precision = 53;
void
mpfr_set_default_prec (mp_prec_t prec)
{
MPFR_ASSERTN(prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX);
- __mpfr_default_fp_bit_precision = prec;
+ __gmpfr_default_fp_bit_precision = prec;
}
mp_prec_t
mpfr_get_default_prec (void)
{
- return __mpfr_default_fp_bit_precision;
+ return __gmpfr_default_fp_bit_precision;
}
diff --git a/mpfr/set_exp.c b/mpfr/set_exp.c
new file mode 100644
index 000000000..e3793403a
--- /dev/null
+++ b/mpfr/set_exp.c
@@ -0,0 +1,39 @@
+/* mpfr_set_exp - set the exponent of a floating-point number
+
+Copyright 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"
+
+int
+mpfr_set_exp (mpfr_ptr x, mp_exp_t exponent)
+{
+ if (exponent >= __gmpfr_emin && exponent <= __gmpfr_emax)
+ {
+ MPFR_EXP(x) = exponent;
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
diff --git a/mpfr/set_ld.c b/mpfr/set_ld.c
new file mode 100644
index 000000000..93e658432
--- /dev/null
+++ b/mpfr/set_ld.c
@@ -0,0 +1,141 @@
+/* mpfr_set_ld -- convert a machine long double to
+ a multiple precision floating-point number
+
+Copyright 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 <float.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+
+#ifndef LDBL_MANT_DIG
+#define LDBL_MANT_DIG 113 /* works also if long double == quad */
+#endif
+
+#ifndef DBL_MANT_DIG
+#define DBL_MANT_DIG 53
+#endif
+
+int
+mpfr_set_ld (mpfr_ptr r, long double d, mp_rnd_t rnd_mode)
+{
+ mpfr_t t, u;
+ int inexact, shift_exp = 0, inexact2 = 0;
+ double x;
+
+ x = d;
+ if (DOUBLE_ISNAN(x))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ if (d == 0.0)
+ return mpfr_set_d (r, x, rnd_mode);
+
+ mpfr_init2 (t, LDBL_MANT_DIG);
+ mpfr_init2 (u, DBL_MANT_DIG);
+ mpfr_set_ui (t, 0, GMP_RNDN);
+ while (d != 0.0)
+ {
+ mpfr_set_d (u, (double) d, GMP_RNDN);
+ if (mpfr_inf_p (u) && (d + d != d))
+ { /* d is neither +Inf nor -Inf and u is Inf: this implies that an
+ overflow occured, i.e. the exponent of d is too large for the
+ double format */
+ long double div10, div11, div12, div13;
+
+ div10 = (long double) (double) 1.34078079299425971e154; /* 2^(2^9) */
+ div10 = div10 * div10;
+ div11 = div10 * div10; /* 2^(2^11) */
+ div12 = div11 * div11; /* 2^(2^12) */
+ div13 = div12 * div12; /* 2^(2^13) */
+ if (ABS(d) >= div13)
+ {
+ d = d / div13; /* exact */
+ shift_exp += 8192;
+ }
+ if (ABS(d) >= div12)
+ {
+ d = d / div12; /* exact */
+ shift_exp += 4096;
+ }
+ if (ABS(d) >= div11)
+ {
+ d = d / div11; /* exact */
+ shift_exp += 2048;
+ }
+ if (ABS(d) >= div10)
+ {
+ d = d / div10; /* exact */
+ shift_exp += 1024;
+ }
+ MPFR_CLEAR_INF(u);
+ MPFR_SET_ZERO(u);
+ }
+ /* warning: using MPFR_IS_ZERO will cause a READ_UNINIT_MEM if u=Inf */
+ else if (mpfr_cmp_ui (u, 0) == 0 && (d != (long double) 0.0)) /* underflow */
+ {
+ long double div10, div11, div12, div13;
+ div10 = (long double) (double) 5.5626846462680034577255e-309; /* 2^(-2^10) */
+ div11 = div10 * div10; /* 2^(-2^11) */
+ div12 = div11 * div11; /* 2^(-2^12) */
+ div13 = div12 * div12; /* 2^(-2^13) */
+ if (ABS(d) <= div13)
+ {
+ d = d / div13; /* exact */
+ shift_exp -= 8192;
+ }
+ if (ABS(d) <= div12)
+ {
+ d = d / div12; /* exact */
+ shift_exp -= 4096;
+ }
+ if (ABS(d) <= div11)
+ {
+ d = d / div11; /* exact */
+ shift_exp -= 2048;
+ }
+ if (ABS(d) <= div10)
+ {
+ d = d / div10; /* exact */
+ shift_exp -= 1024;
+ }
+ }
+ mpfr_add (t, t, u, GMP_RNDN); /* exact */
+ if (!mpfr_number_p (t))
+ break;
+ d = d - (long double) mpfr_get_d1 (u); /* exact */
+ }
+ /* now t is exactly the input value d */
+ inexact = mpfr_set (r, t, rnd_mode);
+ if (shift_exp > 0)
+ inexact2 = mpfr_mul_2exp (r, r, shift_exp, rnd_mode);
+ else if (shift_exp < 0)
+ inexact2 = mpfr_div_2exp (r, r, -shift_exp, rnd_mode);
+ if (inexact2) /* overflow */
+ inexact = inexact2;
+ mpfr_clear (t);
+ mpfr_clear (u);
+
+ return inexact;
+}
diff --git a/mpfr/set_nan.c b/mpfr/set_nan.c
index bc650561a..a32694487 100644
--- a/mpfr/set_nan.c
+++ b/mpfr/set_nan.c
@@ -28,5 +28,5 @@ void
mpfr_set_nan (mpfr_ptr x)
{
MPFR_SET_NAN (x);
- __mpfr_flags |= MPFR_FLAGS_NAN;
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
}
diff --git a/mpfr/set_prec.c b/mpfr/set_prec.c
index 6ef97f516..10e909e69 100644
--- a/mpfr/set_prec.c
+++ b/mpfr/set_prec.c
@@ -1,6 +1,6 @@
/* mpfr_set_prec -- reset the precision of a floating-point number
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -25,7 +25,7 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
-int
+void
mpfr_set_prec (mpfr_ptr x, mp_prec_t p)
{
mp_size_t xsize;
@@ -44,8 +44,6 @@ mpfr_set_prec (mpfr_ptr x, mp_prec_t p)
MPFR_PREC(x) = p;
MPFR_SET_NAN(x); /* initializes to NaN */
-
- return MPFR_MANT(x) == NULL;
}
mp_prec_t
diff --git a/mpfr/set_q.c b/mpfr/set_q.c
index c394d11c8..24bf35176 100644
--- a/mpfr/set_q.c
+++ b/mpfr/set_q.c
@@ -52,6 +52,7 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
if (mpfr_set_z (n, num, GMP_RNDZ)) /* result is exact unless overflow */
{
mpfr_clear (n);
+ mpfr_clear_flags ();
mpfr_restore_emin_emax ();
MPFR_SET_NAN (f);
MPFR_RET_NAN;
@@ -64,6 +65,7 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
{
mpfr_clear (d);
mpfr_clear (n);
+ mpfr_clear_flags ();
mpfr_restore_emin_emax ();
MPFR_SET_NAN (f);
MPFR_RET_NAN;
@@ -71,5 +73,6 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
inexact = mpfr_div (f, n, d, rnd);
mpfr_clear (n);
mpfr_clear (d);
- MPFR_RESTORE_RET (inexact, f, rnd);
+ mpfr_restore_emin_emax ();
+ return mpfr_check_range (f, inexact, rnd);
}
diff --git a/mpfr/set_rnd.c b/mpfr/set_rnd.c
index a80e06166..4cb43dbdd 100644
--- a/mpfr/set_rnd.c
+++ b/mpfr/set_rnd.c
@@ -23,10 +23,10 @@ MA 02111-1307, USA. */
#include "gmp-impl.h"
#include "mpfr.h"
-mp_rnd_t __gmp_default_rounding_mode = 0;
+mp_rnd_t __gmpfr_default_rounding_mode = 0;
void
mpfr_set_default_rounding_mode (mp_rnd_t rnd_mode)
{
- __gmp_default_rounding_mode = rnd_mode;
+ __gmpfr_default_rounding_mode = rnd_mode;
}
diff --git a/mpfr/set_si.c b/mpfr/set_si.c
index 965830c56..af8b4f83f 100644
--- a/mpfr/set_si.c
+++ b/mpfr/set_si.c
@@ -1,6 +1,6 @@
/* mpfr_set_si -- set a MPFR number from a machine signed integer
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -42,7 +42,8 @@ mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode)
}
xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB;
- ai = SAFE_ABS(long, i);
+ ai = SAFE_ABS(unsigned long, i);
+ MPFR_ASSERTN(SAFE_ABS(unsigned long, i) == ai);
count_leading_zeros(cnt, ai);
xp = MPFR_MANT(x);
@@ -54,7 +55,7 @@ mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode)
MPFR_CHANGE_SIGN(x);
MPFR_EXP(x) = nbits = BITS_PER_MP_LIMB - cnt;
- inex = mpfr_check_range(x, rnd_mode);
+ inex = mpfr_check_range(x, 0, rnd_mode);
if (inex)
return inex; /* underflow or overflow */
@@ -69,11 +70,11 @@ mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode)
{
mp_exp_t exp = MPFR_EXP(x);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
return mpfr_set_overflow(x, rnd_mode, (i < 0 ? -1 : 1));
MPFR_EXP(x)++;
- xp[xn] = GMP_LIMB_HIGHBIT;
+ xp[xn] = MPFR_LIMB_HIGHBIT;
}
}
diff --git a/mpfr/set_str.c b/mpfr/set_str.c
index b1b46d165..9b77440cd 100644
--- a/mpfr/set_str.c
+++ b/mpfr/set_str.c
@@ -23,13 +23,8 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
-#include <errno.h>
-
-#ifdef HAVE_STRCASECMP
#include <string.h>
-#else
-int strcasecmp (const char *, const char *);
-#endif
+#include <errno.h>
#include "gmp.h"
#include "gmp-impl.h"
@@ -37,33 +32,58 @@ int strcasecmp (const char *, const char *);
#include "mpfr.h"
#include "mpfr-impl.h"
+/* from mpf/set_str.c */
+static int
+digit_value_in_base (int c, int base)
+{
+ int digit;
+
+ if (isdigit (c))
+ digit = c - '0';
+ else if (islower (c))
+ digit = c - 'a' + 10;
+ else if (isupper (c))
+ digit = c - 'A' + 10;
+ else
+ return -1;
+
+ if (digit < base)
+ return digit;
+ return -1;
+}
+
int
mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode)
{
mpz_t mantissa;
- int negative, inex;
+ int negative, inex, value;
long k = 0;
unsigned char c;
long e;
mp_prec_t q;
mpfr_t y, z;
+ const char *str0 = str;
if (base < 2 || base > 36)
- return 1;
+ return -1;
- if (strcasecmp(str, "NaN") == 0)
+ /* be careful that 'nan' is a valid number in base >= 24,
+ since n=23, a=10, n=23 */
+ if (((base < 24) ? strncasecmp : strncmp) (str, "NaN", 3) == 0)
{
MPFR_SET_NAN(x);
/* MPFR_RET_NAN not used as the return value isn't a ternary value */
- __mpfr_flags |= MPFR_FLAGS_NAN;
- return 0;
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return 3;
}
negative = *str == '-';
if (negative || *str == '+')
str++;
- if (strcasecmp(str, "Inf") == 0)
+ /* be careful that 'inf' is a valid number in base >= 24,
+ since i=18, n=23, f=15 */
+ if (((base < 24) ? strncasecmp : strncmp) (str, "Inf", 3) == 0)
{
MPFR_CLEAR_NAN(x);
MPFR_SET_INF(x);
@@ -71,11 +91,11 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode)
MPFR_SET_NEG(x);
else
MPFR_SET_POS(x);
- return 0;
+ return 3 + (str - str0);
}
- mpz_init(mantissa);
- mpz_set_ui(mantissa, 0);
+ mpz_init (mantissa);
+ mpz_set_ui (mantissa, 0);
while (*str == '0')
str++; /* skip initial zeros */
@@ -83,12 +103,11 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode)
/* 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 (c = *str,
- (isdigit(c) && c < '0' + base) ||
- (islower(c) && c < 'a'-10 + base))
+ (value = digit_value_in_base (c, base)) >= 0)
{
str++;
- mpz_mul_ui(mantissa, mantissa, base);
- mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10));
+ mpz_mul_ui (mantissa, mantissa, base);
+ mpz_add_ui (mantissa, mantissa, value);
}
/* k is the number of non-zero digits before the decimal point */
@@ -102,37 +121,36 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode)
{
if (k == LONG_MAX)
{
- mpz_clear(mantissa);
+ 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));
+ mpz_mul_ui (mantissa, mantissa, base);
+ mpz_add_ui (mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a' - 10));
}
}
- if (*str == '\0') /* no exponent */
- {
- e = -k;
- }
- else if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@')
+ if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@')
{
char *endptr;
if (*++str == '\0') /* exponent character but no exponent */
{
- mpz_clear(mantissa);
- return 1;
+ mpz_clear (mantissa);
+ return -1;
}
errno = 0;
- e = strtol(str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */
+ e = strtol (str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */
+#ifdef REQUIRE_END_OF_STRING
if (*endptr != '\0')
{
- mpz_clear(mantissa);
- return 1;
+ mpz_clear (mantissa);
+ return -1;
}
+#endif
+ str = endptr;
if (errno)
{
mpz_clear(mantissa);
@@ -146,49 +164,55 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode)
}
e -= k;
}
- else /* unexpected character */
+ else /* no exponent */
{
- mpz_clear(mantissa);
- return 1;
+#ifdef REQUIRE_END_OF_STRING
+ if (*str != '\0')
+ {
+ mpz_clear (mantissa);
+ return -1;
+ }
+#endif
+ e = -k;
}
/* the number is mantissa*base^expn */
q = MPFR_PREC(x) & ~(mp_prec_t) (BITS_PER_MP_LIMB - 1);
- mpfr_init(y);
- mpfr_init(z);
+ 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 (y, q);
+ mpfr_set_z (y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */
- mpfr_set_prec(z, q);
+ 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);
+ 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);
+ 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);
+ mpfr_neg (y, y, GMP_RNDN);
}
- while (mpfr_can_round(y, q-inex, 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);
+ mpfr_set (x, y, rnd_mode);
- mpz_clear(mantissa);
- mpfr_clear(y);
- mpfr_clear(z);
- return 0;
+ mpz_clear (mantissa);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ return str - str0;
}
int
diff --git a/mpfr/set_str_raw.c b/mpfr/set_str_raw.c
index 3594a4774..b5a22dfe2 100644
--- a/mpfr/set_str_raw.c
+++ b/mpfr/set_str_raw.c
@@ -1,6 +1,6 @@
/* mpfr_set_str_raw -- set a floating-point number from a binary string
-Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -54,7 +54,7 @@ mpfr_set_str_raw (mpfr_ptr x, char *str)
if (*str == 'N')
{
MPFR_SET_NAN(x);
- __mpfr_flags |= MPFR_FLAGS_NAN;
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
return;
}
diff --git a/mpfr/set_ui.c b/mpfr/set_ui.c
index 9aead7e65..49188522d 100644
--- a/mpfr/set_ui.c
+++ b/mpfr/set_ui.c
@@ -1,6 +1,6 @@
/* mpfr_set_ui -- set a MPFR number from a machine unsigned integer
-Copyright 1999, 2000, 2001 Free Software Foundation.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -40,6 +40,7 @@ mpfr_set_ui (mpfr_ptr x, unsigned long i, mp_rnd_t rnd_mode)
mp_limb_t *xp;
xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB;
+ MPFR_ASSERTN(i == (mp_limb_t) i);
count_leading_zeros(cnt, (mp_limb_t) i);
xp = MPFR_MANT(x);
@@ -48,7 +49,7 @@ mpfr_set_ui (mpfr_ptr x, unsigned long i, mp_rnd_t rnd_mode)
MPN_ZERO(xp, xn);
MPFR_EXP(x) = nbits = BITS_PER_MP_LIMB - cnt;
- inex = mpfr_check_range(x, rnd_mode);
+ inex = mpfr_check_range(x, 0, rnd_mode);
if (inex)
return inex; /* underflow or overflow */
@@ -62,11 +63,11 @@ mpfr_set_ui (mpfr_ptr x, unsigned long i, mp_rnd_t rnd_mode)
{
mp_exp_t exp = MPFR_EXP(x);
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
return mpfr_set_overflow(x, rnd_mode, 1);
MPFR_EXP(x)++;
- xp[xn] = GMP_LIMB_HIGHBIT;
+ xp[xn] = MPFR_LIMB_HIGHBIT;
}
}
}
diff --git a/mpfr/set_z.c b/mpfr/set_z.c
index fff0c6818..642d4452c 100644
--- a/mpfr/set_z.c
+++ b/mpfr/set_z.c
@@ -48,16 +48,28 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
fp = MPFR_MANT(f);
fn = 1 + (MPFR_PREC(f) - 1) / BITS_PER_MP_LIMB;
zn = ABS(SIZ(z));
+ MPFR_ASSERTN(zn >= 1);
dif = zn - fn;
zp = PTR(z);
count_leading_zeros(k, zp[zn-1]);
+ if (zn > MPFR_EMAX_MAX / BITS_PER_MP_LIMB + 1)
+ return mpfr_set_overflow(f, rnd_mode, sign_z);
+ /* because zn >= __gmpfr_emax / BITS_PER_MP_LIMB + 2
+ and zn * BITS_PER_MP_LIMB >= __gmpfr_emax + BITS_PER_MP_LIMB + 1
+ and exp = zn * BITS_PER_MP_LIMB - k > __gmpfr_emax */
+
+ /* now zn <= MPFR_EMAX_MAX / BITS_PER_MP_LIMB + 1
+ thus zn * BITS_PER_MP_LIMB <= MPFR_EMAX_MAX + BITS_PER_MP_LIMB
+ and exp = zn * BITS_PER_MP_LIMB - k
+ <= MPFR_EMAX_MAX + BITS_PER_MP_LIMB */
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)
+ if (exp > __gmpfr_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 (exp + 1 < __gmpfr_emin)
+ return mpfr_set_underflow(f, rnd_mode == GMP_RNDN ? GMP_RNDZ : rnd_mode,
+ sign_z);
if (MPFR_SIGN(f) * sign_z < 0)
MPFR_CHANGE_SIGN(f);
@@ -65,7 +77,7 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
if (dif >= 0)
{
mp_limb_t cc;
- int sh;
+ int sh, to0;
/* number has to be truncated */
if (k != 0)
@@ -81,9 +93,9 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
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;
+ to0 = rnd_mode == GMP_RNDZ
+ || (rnd_mode == GMP_RNDU && sign_z < 0)
+ || (rnd_mode == GMP_RNDD && sign_z > 0);
/* remaining bits... */
if (rnd_mode == GMP_RNDN)
@@ -96,7 +108,7 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
rb = MP_LIMB_T_ONE << (sh - 1);
if ((cc & rb) == 0)
- rnd_mode = GMP_RNDZ; /* rounding bit is 0 */
+ to0 = 1; /* rounding bit is 0 */
else
cc &= ~rb;
if (cc == 0 && dif > 0)
@@ -107,8 +119,8 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
MPFR_ASSERTN(cc == 0);
if (dif > 0)
cc = zp[--dif] << k;
- if ((cc & GMP_LIMB_HIGHBIT) == 0)
- rnd_mode = GMP_RNDZ; /* rounding bit is 0 */
+ if ((cc & MPFR_LIMB_HIGHBIT) == 0)
+ to0 = 1; /* rounding bit is 0 */
else
cc <<= 1;
}
@@ -116,11 +128,11 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
while (cc == 0 && dif > 0)
cc = zp[--dif];
- if (rnd_mode == GMP_RNDN && cc == 0) /* even rounding */
+ if (!to0 && cc == 0) /* even rounding */
{
cc = 1;
if ((fp[0] & (MP_LIMB_T_ONE << sh)) == 0)
- rnd_mode = GMP_RNDZ;
+ to0 = 1;
}
} /* rnd_mode == GMP_RNDN */
else if (cc == 0 && dif > 0)
@@ -132,18 +144,18 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
if (cc == 0)
inex = 0;
- else if (rnd_mode == GMP_RNDZ)
+ else if (to0)
inex = -sign_z;
else
{
if (mpn_add_1(fp, fp, fn, MP_LIMB_T_ONE << sh))
{
- if (exp == __mpfr_emax)
+ if (exp == __gmpfr_emax)
return mpfr_set_overflow(f, rnd_mode, sign_z);
else
{
exp++;
- fp[fn-1] = GMP_LIMB_HIGHBIT;
+ fp[fn-1] = MPFR_LIMB_HIGHBIT;
}
}
inex = sign_z;
@@ -160,8 +172,12 @@ mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mp_rnd_t rnd_mode)
inex = 0; /* result is exact */
}
- if (exp < __mpfr_emin)
- return mpfr_set_underflow(f, rnd_mode, sign_z);
+ if (exp < __gmpfr_emin)
+ {
+ if (rnd_mode == GMP_RNDN && inex == 0 && mpfr_powerof2_raw (f))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow(f, rnd_mode, sign_z);
+ }
MPFR_EXP(f) = exp;
MPFR_RET(inex);
}
diff --git a/mpfr/setmax.c b/mpfr/setmax.c
new file mode 100644
index 000000000..1dd497288
--- /dev/null
+++ b/mpfr/setmax.c
@@ -0,0 +1,44 @@
+/* mpfr_setmax -- maximum representable floating-point number (raw version)
+
+Copyright 2002 Free Software Foundation.
+Contributed by the Spaces project, INRIA Lorraine.
+
+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"
+
+/* Note: the flags are not cleared and the current sign is kept. */
+
+void
+mpfr_setmax (mpfr_ptr x, mp_exp_t e)
+{
+ mp_size_t xn, i;
+ int sh;
+ mp_limb_t *xp;
+
+ MPFR_EXP(x) = e;
+ xn = 1 + (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
+ sh = (mp_prec_t) xn * BITS_PER_MP_LIMB - MPFR_PREC(x);
+ xp = MPFR_MANT(x);
+ xp[0] = MP_LIMB_T_MAX << sh;
+ for (i = 1; i < xn; i++)
+ xp[i] = MP_LIMB_T_MAX;
+}
diff --git a/mpfr/setmin.c b/mpfr/setmin.c
new file mode 100644
index 000000000..3f3057af8
--- /dev/null
+++ b/mpfr/setmin.c
@@ -0,0 +1,41 @@
+/* mpfr_setmin -- minimum representable floating-point number (raw version)
+
+Copyright 2002 Free Software Foundation.
+Contributed by the Spaces project, INRIA Lorraine.
+
+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"
+
+/* Note: the flags are not cleared and the current sign is kept. */
+
+void
+mpfr_setmin (mpfr_ptr x, mp_exp_t e)
+{
+ mp_size_t xn;
+ mp_limb_t *xp;
+
+ MPFR_EXP(x) = e;
+ xn = (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB;
+ xp = MPFR_MANT(x);
+ xp[xn] = MPFR_LIMB_HIGHBIT;
+ MPN_ZERO(xp, xn);
+}
diff --git a/mpfr/sin.c b/mpfr/sin.c
index e62774bdf..79e7fce49 100644
--- a/mpfr/sin.c
+++ b/mpfr/sin.c
@@ -24,11 +24,73 @@ MA 02111-1307, USA. */
#include "mpfr.h"
#include "mpfr-impl.h"
+int mpfr_sin_sign _PROTO((mpfr_srcptr));
+
+/* determine the sign of sin(x) using argument reduction.
+ Assumes x is not an exact multiple of Pi (this excludes x=0). */
+int
+mpfr_sin_sign (mpfr_srcptr x)
+{
+ mpfr_t c, k;
+ mp_exp_t K;
+ int sign = 0;
+ mp_prec_t m;
+ mpfr_srcptr y;
+
+ m = MPFR_PREC(x);
+
+ mpfr_init2 (c, 2);
+ mpfr_init2 (k, 2);
+
+ do
+ {
+ m += BITS_PER_MP_LIMB;
+
+ mpfr_set_prec (c, m);
+ mpfr_set_prec (k, m);
+
+ /* first determine round(x/(2*Pi)): does not have to be exact since
+ the result is an integer */
+ mpfr_const_pi (c, GMP_RNDN); /* err <= ulp(c) = 2^(2-m) */
+ mpfr_div (k, x, c, GMP_RNDN);
+ MPFR_EXP(k) --; /* x/(2Pi) = 1/2*(x/Pi) */
+ mpfr_rint (k, k, GMP_RNDN);
+
+ if (MPFR_NOTZERO(k))
+ {
+ K = MPFR_EXP(k); /* k is an integer, thus K >= 1 */
+ mpfr_mul (k, k, c, GMP_RNDN); /* err <= 2^(K+3-m) */
+ MPFR_EXP(k) ++;
+ mpfr_sub (k, x, k, GMP_RNDN); /* err<=2^(4-m)+2^(K+3-m)<=2^(K+4-m) */
+ y = k;
+ }
+ else
+ {
+ K = 1;
+ y = x;
+ }
+ if (mpfr_cmp (y, c) >= 0)
+ {
+ mpfr_sub (k, y, c, GMP_RNDN); /* err <= 2^(2-m)+2^(K+4-m)+2^(2-m)
+ = 2^(3-m) + 2^(K+4-m) */
+ y = k;
+ }
+ }
+ while (MPFR_IS_ZERO(y) || (MPFR_EXP(y) < K + 5 - (mp_exp_t) m));
+
+ sign = MPFR_SIGN(y);
+
+ mpfr_clear (k);
+ mpfr_clear (c);
+
+ return sign;
+}
+
int
mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
- int precy, m, ok, e, inexact, neg;
- mpfr_t c, k;
+ int precy, m, ok, e, inexact, sign;
+ mpfr_t c;
if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
{
@@ -45,21 +107,11 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
precy = MPFR_PREC(y);
- m = precy + _mpfr_ceil_log2 ((double) precy) + ABS(MPFR_EXP(x)) + 13;
+ m = precy + __gmpfr_ceil_log2 ((double) precy) + MAX(0,MPFR_EXP(x)) + 13;
+
+ sign = mpfr_sin_sign (x);
mpfr_init2 (c, m);
- mpfr_init2 (k, m);
-
- /* first determine sign */
- mpfr_const_pi (c, GMP_RNDN);
- 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);
- mpfr_sub (k, x, c, GMP_RNDN); /* 0 <= k < 2*Pi */
- mpfr_const_pi (c, GMP_RNDN); /* cached */
- neg = mpfr_cmp (k, c) > 0;
- mpfr_clear (k);
do
{
@@ -68,7 +120,7 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_ui_sub (c, 1, c, GMP_RNDN);
e = 2 + (-MPFR_EXP(c)) / 2;
mpfr_sqrt (c, c, GMP_RNDN);
- if (neg)
+ if (sign < 0)
mpfr_neg (c, c, GMP_RNDN);
/* the absolute error on c is at most 2^(e-m) = 2^(EXP(c)-err) */
diff --git a/mpfr/sin_cos.c b/mpfr/sin_cos.c
index 93968cf1f..9b6c23993 100644
--- a/mpfr/sin_cos.c
+++ b/mpfr/sin_cos.c
@@ -48,7 +48,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
prec = MAX(MPFR_PREC(y), MPFR_PREC(z));
- m = prec + _mpfr_ceil_log2 ((double) prec) + ABS(MPFR_EXP(x)) + 13;
+ m = prec + __gmpfr_ceil_log2 ((double) prec) + ABS(MPFR_EXP(x)) + 13;
mpfr_init2 (c, m);
mpfr_init2 (k, m);
@@ -85,7 +85,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mp_rnd_t rnd_mode)
if (ok == 0)
{
- m += _mpfr_ceil_log2 ((double) m);
+ m += __gmpfr_ceil_log2 ((double) m);
mpfr_set_prec (c, m);
}
}
diff --git a/mpfr/sinh.c b/mpfr/sinh.c
index dceaf14c7..7be49ebba 100644
--- a/mpfr/sinh.c
+++ b/mpfr/sinh.c
@@ -86,7 +86,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
/* compute the precision of intermediary variable */
Nt = MAX(Nx, Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt = Nt + _mpfr_ceil_log2 (5) + _mpfr_ceil_log2 (Nt);
+ Nt = Nt + __gmpfr_ceil_log2 (5) + __gmpfr_ceil_log2 (Nt);
/* initialise of intermediary variable */
mpfr_init (t);
@@ -119,7 +119,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mp_rnd_t rnd_mode)
d = MPFR_EXP(te) - MPFR_EXP(t) + 2;
/* estimation of the error */
- /* err = Nt-(_mpfr_ceil_log2(1+pow(2,d)));*/
+ /* err = Nt-(__gmpfr_ceil_log2(1+pow(2,d)));*/
err = Nt - (MAX(d,0) + 1);
}
diff --git a/mpfr/sqrt.c b/mpfr/sqrt.c
index 1f6baf0f7..c368ad5ed 100644
--- a/mpfr/sqrt.c
+++ b/mpfr/sqrt.c
@@ -117,7 +117,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
{
up = TMP_ALLOC((usize + 1) * BYTES_PER_MP_LIMB);
if (mpn_rshift(up + 1, MPFR_MANT(u), usize, 1))
- up[0] = GMP_LIMB_HIGHBIT;
+ up[0] = MPFR_LIMB_HIGHBIT;
else
up[0] = 0;
usize++;
@@ -263,7 +263,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
{
/* Is a shift necessary here? Isn't the result 1.0000...? */
mpn_rshift (rp, rp, rrsize, 1);
- rp[rrsize-1] |= GMP_LIMB_HIGHBIT;
+ rp[rrsize-1] |= MPFR_LIMB_HIGHBIT;
MPFR_EXP(r)++;
}
diff --git a/mpfr/sqrt_ui.c b/mpfr/sqrt_ui.c
index 46eff9f81..18f750fda 100644
--- a/mpfr/sqrt_ui.c
+++ b/mpfr/sqrt_ui.c
@@ -36,13 +36,15 @@ mpfr_sqrt_ui (mpfr_ptr r, unsigned long u, mp_rnd_t rnd_mode)
int inex;
MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
count_leading_zeros (cnt, (mp_limb_t) u);
*up = (mp_limb_t) u << cnt;
MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt;
mpfr_save_emin_emax();
inex = mpfr_sqrt(r, uu, rnd_mode);
- MPFR_RESTORE_RET(inex, r, rnd_mode);
+ mpfr_restore_emin_emax();
+ return mpfr_check_range(r, inex, rnd_mode);
}
else /* sqrt(0) = 0 */
{
diff --git a/mpfr/strcasecmp.c b/mpfr/strcasecmp.c
index c090b8677..03f0e4dd2 100644
--- a/mpfr/strcasecmp.c
+++ b/mpfr/strcasecmp.c
@@ -1,6 +1,7 @@
/* Copyright (C) 1991, 1992, 1995, 2002 Free Software Foundation, Inc.
This file was part of the GNU C Library. Modified by kb@mail.tug.org to
-avoid glibc-isms. Modified by Vincent Lefevre (-> ISO C prototypes).
+avoid glibc-isms. Modified by Vincent Lefevre (-> ISO C prototypes and
+mpfr_ prefix).
This file is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -31,14 +32,13 @@ Boston, MA 02111-1307, USA. */
#include <ctype.h>
-int strcasecmp (const char *, const char *);
-int strncasecmp (const char *, const char *, size_t);
+int mpfr_strcasecmp (const char *, const char *);
-/* Compare S1 and S2, ignoring case, returning less than, equal to or
- greater than zero if S1 is lexiographically less than,
- equal to or greater than S2. */
+/* Compare strings S1 and S2, ignoring case, returning less than,
+ equal to or greater than zero if S1 is lexiographically less
+ than, equal to or greater than S2. */
int
-strcasecmp (const char *s1, const char *s2)
+mpfr_strcasecmp (const char *s1, const char *s2)
{
register const unsigned char *p1 = (const unsigned char *) s1;
register const unsigned char *p2 = (const unsigned char *) s2;
@@ -58,24 +58,3 @@ strcasecmp (const char *s1, const char *s2)
return c1 - c2;
}
-
-int
-strncasecmp (const char *s1, const char *s2, size_t n)
-{
- register const unsigned char *p1 = (const unsigned char *) s1;
- register const unsigned char *p2 = (const unsigned char *) s2;
- unsigned char c1, c2;
-
- if (p1 == p2 || n == 0)
- return 0;
-
- do
- {
- c1 = tolower (*p1++);
- c2 = tolower (*p2++);
- if (c1 == '\0' || c1 != c2)
- return c1 - c2;
- } while (--n > 0);
-
- return c1 - c2;
-}
diff --git a/mpfr/strncasecmp.c b/mpfr/strncasecmp.c
new file mode 100644
index 000000000..7900b6e85
--- /dev/null
+++ b/mpfr/strncasecmp.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1991, 1992, 1995, 2002 Free Software Foundation, Inc.
+This file was part of the GNU C Library. Modified by kb@mail.tug.org to
+avoid glibc-isms. Modified by Vincent Lefevre (-> ISO C prototypes and
+mpfr_ prefix).
+
+This file is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+This file is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file COPYING.LIB. If not, write
+to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <ctype.h>
+
+int mpfr_strncasecmp (const char *, const char *, size_t);
+
+/* Compare no more than N characters of strings S1 and S2, ignoring
+ case, returning less than, equal to or greater than zero if S1 is
+ lexiographically less than, equal to or greater than S2. */
+int
+mpfr_strncasecmp (const char *s1, const char *s2, size_t n)
+{
+ register const unsigned char *p1 = (const unsigned char *) s1;
+ register const unsigned char *p2 = (const unsigned char *) s2;
+ unsigned char c1, c2;
+
+ if (p1 == p2 || n == 0)
+ return 0;
+
+ do
+ {
+ c1 = tolower (*p1++);
+ c2 = tolower (*p2++);
+ if (c1 == '\0' || c1 != c2)
+ return c1 - c2;
+ } while (--n > 0);
+
+ return c1 - c2;
+}
diff --git a/mpfr/sub.c b/mpfr/sub.c
index 50a6f9b30..37689c65f 100644
--- a/mpfr/sub.c
+++ b/mpfr/sub.c
@@ -1,6 +1,6 @@
/* mpfr_sub -- subtract two floating-point numbers
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Contributed by the Spaces project, INRIA Lorraine.
This file is part of the MPFR Library.
@@ -100,7 +100,7 @@ mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
inexact = mpfr_add1(a, c, b, rnd_mode,
(mp_exp_unsigned_t) MPFR_EXP(c) - MPFR_EXP(b));
MPFR_CHANGE_SIGN(a);
- return inexact;
+ return -inexact;
}
else
{
diff --git a/mpfr/sub1.c b/mpfr/sub1.c
index 0385a4f78..a97d03a95 100644
--- a/mpfr/sub1.c
+++ b/mpfr/sub1.c
@@ -1,6 +1,6 @@
/* mpfr_sub1 -- internal function to perform a "real" subtraction
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Contributed by the Spaces project, INRIA Lorraine.
This file is part of the MPFR Library.
@@ -207,7 +207,8 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode,
#endif
/* now perform rounding */
- sh = an * BITS_PER_MP_LIMB - MPFR_PREC(a); /* last unused bits from a */
+ sh = (mp_prec_t) an * BITS_PER_MP_LIMB - MPFR_PREC(a);
+ /* last unused bits from a */
carry = ap[0] & ((MP_LIMB_T_ONE << sh) - MP_LIMB_T_ONE);
ap[0] -= carry;
@@ -268,7 +269,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode,
if ((rnd_mode == GMP_RNDN) && !k && sh == 0)
{
- mp_limb_t half = GMP_LIMB_HIGHBIT;
+ mp_limb_t half = MPFR_LIMB_HIGHBIT;
is_exact = (bb == cc);
@@ -371,7 +372,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode,
add_one_ulp: /* add one unit in last place to a */
if (mpn_add_1 (ap, ap, an, MP_LIMB_T_ONE << sh)) /* result is a power of 2 */
{
- ap[an-1] = GMP_LIMB_HIGHBIT;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
add_exp = 1;
}
inexact = 1; /* result larger than exact value */
@@ -379,7 +380,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode,
truncate:
if ((ap[an-1] >> (BITS_PER_MP_LIMB - 1)) == 0) /* case 1 - epsilon */
{
- ap[an-1] = GMP_LIMB_HIGHBIT;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
add_exp = 1;
}
@@ -389,24 +390,27 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode,
exponent range */
if (cancel)
{
- mp_exp_t exp_b;
+ mp_exp_t exp_a;
cancel -= add_exp; /* still valid as unsigned long */
- exp_b = MPFR_EXP(b); /* save it in case a equals b */
- MPFR_EXP(a) = MPFR_EXP(b) - cancel;
- if ((MPFR_EXP(a) > exp_b) /* underflow in type mp_exp_t */
- || (MPFR_EXP(a) < __mpfr_emin))
- {
- TMP_FREE(marker);
- return mpfr_set_underflow (a, rnd_mode, MPFR_SIGN(a));
- }
+ exp_a = MPFR_EXP(b) - cancel;
+ if (exp_a < __gmpfr_emin)
+ {
+ TMP_FREE(marker);
+ if (rnd_mode == GMP_RNDN &&
+ (exp_a < __gmpfr_emin - 1 ||
+ (inexact >= 0 && mpfr_powerof2_raw (a))))
+ rnd_mode = GMP_RNDZ;
+ return mpfr_set_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_EXP(a) = exp_a;
}
else /* cancel = 0: MPFR_EXP(a) <- MPFR_EXP(b) + add_exp */
{
/* in case cancel = 0, add_exp can still be 1, in case b is just
below a power of two, c is very small, prec(a) < prec(b),
and rnd=away or nearest */
- if (add_exp && MPFR_EXP(b) == __mpfr_emax)
+ if (add_exp && MPFR_EXP(b) == __gmpfr_emax)
{
TMP_FREE(marker);
return mpfr_set_overflow (a, rnd_mode, MPFR_SIGN(a));
diff --git a/mpfr/sub_one_ulp.c b/mpfr/sub_one_ulp.c
index 36ed5620a..a14b35867 100644
--- a/mpfr/sub_one_ulp.c
+++ b/mpfr/sub_one_ulp.c
@@ -1,6 +1,6 @@
/* mpfr_sub_one_ulp -- subtract one unit in last place
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -41,17 +41,19 @@ mpfr_sub_one_ulp(mpfr_ptr x, mp_rnd_t rnd_mode)
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);
+ sh = (mp_prec_t) 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 */
mp_exp_t exp = MPFR_EXP(x);
- if (exp == __mpfr_emin)
+ /* Note: In case of underflow and rounding to the nearest mode,
+ x won't be changed. Beware of infinite loops! */
+ if (exp == __gmpfr_emin)
return mpfr_set_underflow(x, rnd_mode, MPFR_SIGN(x));
else
{
- int i;
+ mp_size_t 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++)
diff --git a/mpfr/sub_ui.c b/mpfr/sub_ui.c
index 55c69f3d8..497a50014 100644
--- a/mpfr/sub_ui.c
+++ b/mpfr/sub_ui.c
@@ -36,6 +36,7 @@ mpfr_sub_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
int inex;
MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
count_leading_zeros(cnt, (mp_limb_t) u);
*up = (mp_limb_t) u << cnt;
MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt;
@@ -44,7 +45,8 @@ mpfr_sub_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
if mpfr_sub works even when uu is out-of-range. */
mpfr_save_emin_emax();
inex = mpfr_sub(y, x, uu, rnd_mode);
- MPFR_RESTORE_RET(inex, y, rnd_mode);
+ mpfr_restore_emin_emax();
+ return mpfr_check_range(y, inex, rnd_mode);
}
else
return mpfr_set (y, x, rnd_mode);
diff --git a/mpfr/tan.c b/mpfr/tan.c
index 374a2fe12..091737ae2 100644
--- a/mpfr/tan.c
+++ b/mpfr/tan.c
@@ -46,7 +46,7 @@ mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
precy = MPFR_PREC(y);
- m = precy + _mpfr_ceil_log2 ((double) precy) + ABS(MPFR_EXP(x)) + 13;
+ m = precy + __gmpfr_ceil_log2 ((double) precy) + ABS(MPFR_EXP(x)) + 13;
mpfr_init2 (s, m);
mpfr_init2 (c, m);
diff --git a/mpfr/tanh.c b/mpfr/tanh.c
index b818ab4e2..6cc4195cd 100644
--- a/mpfr/tanh.c
+++ b/mpfr/tanh.c
@@ -96,7 +96,7 @@ mpfr_tanh (y, xt, rnd_mode)
/* compute the precision of intermediary variable */
Nt=MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt = Nt+_mpfr_ceil_log2(9)+_mpfr_ceil_log2(Nt);
+ Nt = Nt+__gmpfr_ceil_log2(9)+__gmpfr_ceil_log2(Nt);
/* initialise of intermediary variable */
mpfr_init(t);
@@ -126,7 +126,7 @@ mpfr_tanh (y, xt, rnd_mode)
d = MPFR_EXP(te)-MPFR_EXP(t);
/* estimation of the error */
- /*err = Nt-(_mpfr_ceil_log2(7+pow(2,d+1)));*/
+ /*err = Nt-(__gmpfr_ceil_log2(7+pow(2,d+1)));*/
err = Nt-(MAX(d+1,3)+1);
/* actualisation of the precision */
diff --git a/mpfr/tests/Makefile.am b/mpfr/tests/Makefile.am
index bb4aa2800..14477f997 100644
--- a/mpfr/tests/Makefile.am
+++ b/mpfr/tests/Makefile.am
@@ -26,10 +26,10 @@ LIBS = @MPFR_LIBS@
LDADD = libfrtests.a ../libmpfr.a $(top_builddir)/libgmp.la
-libfrtests_a_SOURCES = dummy.c
+libfrtests_a_SOURCES = memory.c rnd_mode.c tests.c
if WANT_MPFR
-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
+check_PROGRAMS = reuse tabs tadd tagm tcan_round tcmp tcmp2 tcmp_ui tdiv tdiv_ui tdump teq texp tfrac 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 tgamma tset_ld tcbrt
check_LIBRARIES = libfrtests.a
TESTS = $(check_PROGRAMS)
endif
diff --git a/mpfr/tests/Makefile.in b/mpfr/tests/Makefile.in
index 12dffbf52..a40d4ab16 100644
--- a/mpfr/tests/Makefile.in
+++ b/mpfr/tests/Makefile.in
@@ -199,9 +199,9 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mpfr
LDADD = libfrtests.a ../libmpfr.a $(top_builddir)/libgmp.la
-libfrtests_a_SOURCES = dummy.c
+libfrtests_a_SOURCES = memory.c rnd_mode.c tests.c
-@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@check_PROGRAMS = reuse tabs tadd tagm tcan_round tcmp tcmp2 tcmp_ui tdiv tdiv_ui tdump teq texp tfrac 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 tgamma tset_ld tcbrt
@WANT_MPFR_TRUE@check_LIBRARIES = libfrtests.a
@WANT_MPFR_TRUE@TESTS = $(check_PROGRAMS)
EXTRA_DIST = tgeneric.c
@@ -211,19 +211,21 @@ CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
libfrtests_a_AR = $(AR) cru
libfrtests_a_LIBADD =
-am_libfrtests_a_OBJECTS = dummy$U.$(OBJEXT)
+am_libfrtests_a_OBJECTS = memory$U.$(OBJEXT) rnd_mode$U.$(OBJEXT) \
+ tests$U.$(OBJEXT)
libfrtests_a_OBJECTS = $(am_libfrtests_a_OBJECTS)
@WANT_MPFR_TRUE@check_PROGRAMS = reuse$(EXEEXT) tabs$(EXEEXT) \
@WANT_MPFR_TRUE@ tadd$(EXEEXT) tagm$(EXEEXT) tcan_round$(EXEEXT) \
@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) 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@ teq$(EXEEXT) texp$(EXEEXT) tfrac$(EXEEXT) \
+@WANT_MPFR_TRUE@ tget_str$(EXEEXT) tlog$(EXEEXT) \
+@WANT_MPFR_TRUE@ tconst_log2$(EXEEXT) tmul$(EXEEXT) \
+@WANT_MPFR_TRUE@ tmul_2exp$(EXEEXT) tmul_ui$(EXEEXT) \
+@WANT_MPFR_TRUE@ tout_str$(EXEEXT) tconst_pi$(EXEEXT) \
+@WANT_MPFR_TRUE@ tpow$(EXEEXT) trandom$(EXEEXT) \
+@WANT_MPFR_TRUE@ tround_prec$(EXEEXT) tset_d$(EXEEXT) \
+@WANT_MPFR_TRUE@ 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) \
@@ -240,7 +242,8 @@ libfrtests_a_OBJECTS = $(am_libfrtests_a_OBJECTS)
@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_TRUE@ thypot$(EXEEXT) tacos$(EXEEXT) tgamma$(EXEEXT) \
+@WANT_MPFR_TRUE@ tset_ld$(EXEEXT) tcbrt$(EXEEXT)
@WANT_MPFR_FALSE@check_PROGRAMS =
reuse_SOURCES = reuse.c
reuse_OBJECTS = reuse$U.$(OBJEXT)
@@ -307,6 +310,11 @@ tcan_round_LDADD = $(LDADD)
tcan_round_DEPENDENCIES = libfrtests.a ../libmpfr.a \
$(top_builddir)/libgmp.la
tcan_round_LDFLAGS =
+tcbrt_SOURCES = tcbrt.c
+tcbrt_OBJECTS = tcbrt$U.$(OBJEXT)
+tcbrt_LDADD = $(LDADD)
+tcbrt_DEPENDENCIES = libfrtests.a ../libmpfr.a $(top_builddir)/libgmp.la
+tcbrt_LDFLAGS =
tcmp_SOURCES = tcmp.c
tcmp_OBJECTS = tcmp$U.$(OBJEXT)
tcmp_LDADD = $(LDADD)
@@ -405,6 +413,17 @@ tfma_OBJECTS = tfma$U.$(OBJEXT)
tfma_LDADD = $(LDADD)
tfma_DEPENDENCIES = libfrtests.a ../libmpfr.a $(top_builddir)/libgmp.la
tfma_LDFLAGS =
+tfrac_SOURCES = tfrac.c
+tfrac_OBJECTS = tfrac$U.$(OBJEXT)
+tfrac_LDADD = $(LDADD)
+tfrac_DEPENDENCIES = libfrtests.a ../libmpfr.a $(top_builddir)/libgmp.la
+tfrac_LDFLAGS =
+tgamma_SOURCES = tgamma.c
+tgamma_OBJECTS = tgamma$U.$(OBJEXT)
+tgamma_LDADD = $(LDADD)
+tgamma_DEPENDENCIES = libfrtests.a ../libmpfr.a \
+ $(top_builddir)/libgmp.la
+tgamma_LDFLAGS =
tget_d_SOURCES = tget_d.c
tget_d_OBJECTS = tget_d$U.$(OBJEXT)
tget_d_LDADD = $(LDADD)
@@ -524,6 +543,12 @@ tset_f_LDADD = $(LDADD)
tset_f_DEPENDENCIES = libfrtests.a ../libmpfr.a \
$(top_builddir)/libgmp.la
tset_f_LDFLAGS =
+tset_ld_SOURCES = tset_ld.c
+tset_ld_OBJECTS = tset_ld$U.$(OBJEXT)
+tset_ld_LDADD = $(LDADD)
+tset_ld_DEPENDENCIES = libfrtests.a ../libmpfr.a \
+ $(top_builddir)/libgmp.la
+tset_ld_LDFLAGS =
tset_q_SOURCES = tset_q.c
tset_q_OBJECTS = tset_q$U.$(OBJEXT)
tset_q_LDADD = $(LDADD)
@@ -632,18 +657,18 @@ LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libfrtests_a_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 \
+ tcan_round.c tcbrt.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
+ tfactorial.c tfma.c tfrac.c tgamma.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_ld.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 = $(libfrtests_a_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
+SOURCES = $(libfrtests_a_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 tcbrt.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 tfrac.c tgamma.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_ld.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
@@ -704,6 +729,9 @@ tatanh$(EXEEXT): $(tatanh_OBJECTS) $(tatanh_DEPENDENCIES)
tcan_round$(EXEEXT): $(tcan_round_OBJECTS) $(tcan_round_DEPENDENCIES)
@rm -f tcan_round$(EXEEXT)
$(LINK) $(tcan_round_LDFLAGS) $(tcan_round_OBJECTS) $(tcan_round_LDADD) $(LIBS)
+tcbrt$(EXEEXT): $(tcbrt_OBJECTS) $(tcbrt_DEPENDENCIES)
+ @rm -f tcbrt$(EXEEXT)
+ $(LINK) $(tcbrt_LDFLAGS) $(tcbrt_OBJECTS) $(tcbrt_LDADD) $(LIBS)
tcmp$(EXEEXT): $(tcmp_OBJECTS) $(tcmp_DEPENDENCIES)
@rm -f tcmp$(EXEEXT)
$(LINK) $(tcmp_LDFLAGS) $(tcmp_OBJECTS) $(tcmp_LDADD) $(LIBS)
@@ -758,6 +786,12 @@ tfactorial$(EXEEXT): $(tfactorial_OBJECTS) $(tfactorial_DEPENDENCIES)
tfma$(EXEEXT): $(tfma_OBJECTS) $(tfma_DEPENDENCIES)
@rm -f tfma$(EXEEXT)
$(LINK) $(tfma_LDFLAGS) $(tfma_OBJECTS) $(tfma_LDADD) $(LIBS)
+tfrac$(EXEEXT): $(tfrac_OBJECTS) $(tfrac_DEPENDENCIES)
+ @rm -f tfrac$(EXEEXT)
+ $(LINK) $(tfrac_LDFLAGS) $(tfrac_OBJECTS) $(tfrac_LDADD) $(LIBS)
+tgamma$(EXEEXT): $(tgamma_OBJECTS) $(tgamma_DEPENDENCIES)
+ @rm -f tgamma$(EXEEXT)
+ $(LINK) $(tgamma_LDFLAGS) $(tgamma_OBJECTS) $(tgamma_LDADD) $(LIBS)
tget_d$(EXEEXT): $(tget_d_OBJECTS) $(tget_d_DEPENDENCIES)
@rm -f tget_d$(EXEEXT)
$(LINK) $(tget_d_LDFLAGS) $(tget_d_OBJECTS) $(tget_d_LDADD) $(LIBS)
@@ -821,6 +855,9 @@ tset_d$(EXEEXT): $(tset_d_OBJECTS) $(tset_d_DEPENDENCIES)
tset_f$(EXEEXT): $(tset_f_OBJECTS) $(tset_f_DEPENDENCIES)
@rm -f tset_f$(EXEEXT)
$(LINK) $(tset_f_LDFLAGS) $(tset_f_OBJECTS) $(tset_f_LDADD) $(LIBS)
+tset_ld$(EXEEXT): $(tset_ld_OBJECTS) $(tset_ld_DEPENDENCIES)
+ @rm -f tset_ld$(EXEEXT)
+ $(LINK) $(tset_ld_LDFLAGS) $(tset_ld_OBJECTS) $(tset_ld_LDADD) $(LIBS)
tset_q$(EXEEXT): $(tset_q_OBJECTS) $(tset_q_DEPENDENCIES)
@rm -f tset_q$(EXEEXT)
$(LINK) $(tset_q_LDFLAGS) $(tset_q_OBJECTS) $(tset_q_LDADD) $(LIBS)
@@ -894,10 +931,12 @@ mostlyclean-kr:
.c.lo:
$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
-dummy_.c: dummy.c $(ANSI2KNR)
- $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/dummy.c; then echo $(srcdir)/dummy.c; else echo dummy.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+memory_.c: memory.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/memory.c; then echo $(srcdir)/memory.c; else echo memory.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
+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) > $@ || rm -f $@
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) > $@ || rm -f $@
tacos_.c: tacos.c $(ANSI2KNR)
@@ -920,6 +959,8 @@ tatanh_.c: tatanh.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tatanh.c; then echo $(srcdir)/tatanh.c; else echo tatanh.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tcan_round_.c: tcan_round.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tcan_round.c; then echo $(srcdir)/tcan_round.c; else echo tcan_round.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+tcbrt_.c: tcbrt.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tcbrt.c; then echo $(srcdir)/tcbrt.c; else echo tcbrt.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tcmp_.c: tcmp.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tcmp.c; then echo $(srcdir)/tcmp.c; else echo tcmp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tcmp2_.c: tcmp2.c $(ANSI2KNR)
@@ -944,6 +985,8 @@ 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) > $@ || rm -f $@
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) > $@ || rm -f $@
+tests_.c: tests.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tests.c; then echo $(srcdir)/tests.c; else echo tests.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
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) > $@ || rm -f $@
texp_.c: texp.c $(ANSI2KNR)
@@ -956,6 +999,10 @@ tfactorial_.c: tfactorial.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tfactorial.c; then echo $(srcdir)/tfactorial.c; else echo tfactorial.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tfma_.c: tfma.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tfma.c; then echo $(srcdir)/tfma.c; else echo tfma.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+tfrac_.c: tfrac.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tfrac.c; then echo $(srcdir)/tfrac.c; else echo tfrac.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+tgamma_.c: tgamma.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tgamma.c; then echo $(srcdir)/tgamma.c; else echo tgamma.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tget_d_.c: tget_d.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tget_d.c; then echo $(srcdir)/tget_d.c; else echo tget_d.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tget_str_.c: tget_str.c $(ANSI2KNR)
@@ -998,6 +1045,8 @@ tset_d_.c: tset_d.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tset_d.c; then echo $(srcdir)/tset_d.c; else echo tset_d.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tset_f_.c: tset_f.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tset_f.c; then echo $(srcdir)/tset_f.c; else echo tset_f.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+tset_ld_.c: tset_ld.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tset_ld.c; then echo $(srcdir)/tset_ld.c; else echo tset_ld.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tset_q_.c: tset_q.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tset_q.c; then echo $(srcdir)/tset_q.c; else echo tset_q.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
tset_si_.c: tset_si.c $(ANSI2KNR)
@@ -1032,21 +1081,24 @@ 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) > $@ || rm -f $@
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) > $@ || rm -f $@
-dummy_.$(OBJEXT) dummy_.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 \
+memory_.$(OBJEXT) memory_.lo reuse_.$(OBJEXT) reuse_.lo \
+rnd_mode_.$(OBJEXT) rnd_mode_.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 \
-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 \
+tcan_round_.$(OBJEXT) tcan_round_.lo tcbrt_.$(OBJEXT) tcbrt_.lo \
+tcmp_.$(OBJEXT) tcmp_.lo tcmp2_.$(OBJEXT) tcmp2_.lo tcmp_ui_.$(OBJEXT) \
+tcmp_ui_.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 tests_.$(OBJEXT) \
+tests_.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 \
+tfrac_.$(OBJEXT) tfrac_.lo tgamma_.$(OBJEXT) tgamma_.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 tlog10_.$(OBJEXT) \
tlog10_.lo tlog1p_.$(OBJEXT) tlog1p_.lo tlog2_.$(OBJEXT) tlog2_.lo \
@@ -1055,15 +1107,15 @@ tmul_ui_.$(OBJEXT) tmul_ui_.lo tout_str_.$(OBJEXT) tout_str_.lo \
tpow_.$(OBJEXT) tpow_.lo tpow3_.$(OBJEXT) tpow3_.lo trandom_.$(OBJEXT) \
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)
+tset_f_.$(OBJEXT) tset_f_.lo tset_ld_.$(OBJEXT) tset_ld_.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)
mostlyclean-libtool:
-rm -f *.lo
diff --git a/mpfr/tests/memory.c b/mpfr/tests/memory.c
new file mode 100644
index 000000000..c49aae70d
--- /dev/null
+++ b/mpfr/tests/memory.c
@@ -0,0 +1,185 @@
+/* Memory allocation used during tests.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU 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 GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h> /* for abort */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-test.h"
+
+
+/* Each block allocated is a separate malloc, for the benefit of a redzoning
+ malloc debugger during development or when bug hunting.
+
+ Sizes passed when reallocating or freeing are checked (the default
+ routines don't care about these).
+
+ Memory leaks are checked by requiring that all blocks have been freed
+ when tests_memory_end() is called. Test programs must be sure to have
+ "clear"s for all temporary variables used. */
+
+
+struct header {
+ void *ptr;
+ size_t size;
+ struct header *next;
+};
+
+struct header *tests_memory_list = NULL;
+
+/* Return a pointer to a pointer to the found block (so it can be updated
+ when unlinking). */
+static struct header **
+tests_memory_find (void *ptr)
+{
+ struct header **hp;
+
+ for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next))
+ if ((*hp)->ptr == ptr)
+ return hp;
+
+ return NULL;
+}
+
+static int
+tests_memory_valid (void *ptr)
+{
+ return (tests_memory_find (ptr) != NULL);
+}
+
+static void *
+tests_allocate (size_t size)
+{
+ struct header *h;
+
+ if (size == 0)
+ {
+ printf ("tests_allocate(): attempt to allocate 0 bytes\n");
+ abort ();
+ }
+
+ h = (struct header *) __gmp_default_allocate (sizeof (*h));
+ h->next = tests_memory_list;
+ tests_memory_list = h;
+
+ h->size = size;
+ h->ptr = __gmp_default_allocate (size);
+ return h->ptr;
+}
+
+static void *
+tests_reallocate (void *ptr, size_t old_size, size_t new_size)
+{
+ struct header **hp, *h;
+
+ if (new_size == 0)
+ {
+ printf ("tests_reallocate(): attempt to reallocate 0x%lX to 0 bytes\n",
+ (unsigned long) ptr);
+ abort ();
+ }
+
+ hp = tests_memory_find (ptr);
+ if (hp == NULL)
+ {
+ printf ("tests_reallocate(): attempt to reallocate bad pointer 0x%lX\n",
+ (unsigned long) ptr);
+ abort ();
+ }
+ h = *hp;
+
+ if (h->size != old_size)
+ {
+ printf ("tests_reallocate(): bad old size %u, should be %u\n",
+ old_size, h->size);
+ abort ();
+ }
+
+ h->size = new_size;
+ h->ptr = __gmp_default_reallocate (ptr, old_size, new_size);
+ return h->ptr;
+}
+
+static struct header **
+tests_free_find (void *ptr)
+{
+ struct header **hp = tests_memory_find (ptr);
+ if (hp == NULL)
+ {
+ printf ("tests_free(): attempt to free bad pointer 0x%lX\n",
+ (unsigned long) ptr);
+ abort ();
+ }
+ return hp;
+}
+
+static void
+tests_free_nosize (void *ptr)
+{
+ struct header **hp = tests_free_find (ptr);
+ struct header *h = *hp;
+
+ *hp = h->next; /* unlink */
+
+ __gmp_default_free (ptr, h->size);
+ __gmp_default_free (h, sizeof (*h));
+}
+
+static void
+tests_free (void *ptr, size_t size)
+{
+ struct header **hp = tests_free_find (ptr);
+ struct header *h = *hp;
+
+ if (h->size != size)
+ {
+ printf ("tests_free(): bad size %u, should be %u\n", size, h->size);
+ abort ();
+ }
+
+ tests_free_nosize (ptr);
+}
+
+void
+tests_memory_start (void)
+{
+ mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free);
+}
+
+void
+tests_memory_end (void)
+{
+ if (tests_memory_list != NULL)
+ {
+ struct header *h;
+ unsigned count;
+
+ printf ("tests_memory_end(): not all memory freed\n");
+
+ count = 0;
+ for (h = tests_memory_list; h != NULL; h = h->next)
+ count++;
+
+ printf (" %u blocks remaining\n", count);
+ abort ();
+ }
+}
diff --git a/mpfr/tests/reuse.c b/mpfr/tests/reuse.c
index e9ac63970..e9ea078a4 100644
--- a/mpfr/tests/reuse.c
+++ b/mpfr/tests/reuse.c
@@ -24,6 +24,7 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
typedef void (*fct_t)();
fct_t testfunc;
@@ -552,6 +553,8 @@ test3a (char *foo, mp_prec_t prec, mp_rnd_t rnd)
int
main (void)
{
+ tests_start_mpfr ();
+
testfunc = (fct_t) mpfr_add; test3 ("mpfr_add", 53, GMP_RNDN);
testfunc = (fct_t) mpfr_add_ui; test2ui ("mpfr_add_ui", 53, GMP_RNDN);
testfunc = (fct_t) mpfr_agm; test3 ("mpfr_agm", 53, GMP_RNDN);
@@ -591,5 +594,7 @@ main (void)
testfunc = (fct_t) mpfr_log2; test2 ("mpfr_log2", 53, GMP_RNDN);
testfunc = (fct_t) mpfr_pow; test3 ("mpfr_pow", 53, GMP_RNDN);
testfunc = (fct_t) mpfr_fma; test4 ("mpfr_fma", 53, GMP_RNDN);
+
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/rnd_mode.c b/mpfr/tests/rnd_mode.c
new file mode 100644
index 000000000..94f5981e5
--- /dev/null
+++ b/mpfr/tests/rnd_mode.c
@@ -0,0 +1,79 @@
+/* mpfr_set_machine_rnd_mode -- set the rounding mode for machine floats
+
+Copyright 1999, 2001, 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-test.h"
+
+/* Note: "gmp-impl.h" must be included because MPFR_HAVE_FESETROUND
+ may be defined from it (if MPFR is built with GMP). */
+
+#ifdef MPFR_HAVE_FESETROUND
+#include <fenv.h>
+#endif
+
+/* It is important to test each FE_* macro -- see the ISO C99 standard.
+ For instance, with some ARM implementations, only FE_TONEAREST may
+ be defined. */
+
+/* sets the machine rounding mode to the value rnd_mode */
+int
+mpfr_set_machine_rnd_mode (mp_rnd_t rnd_mode)
+{
+ switch (rnd_mode)
+ {
+ case GMP_RNDN:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_TONEAREST)
+ fesetround(FE_TONEAREST)
+#else
+ -1
+#endif
+ ;
+ case GMP_RNDZ:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_TOWARDZERO)
+ fesetround(FE_TOWARDZERO)
+#else
+ -1
+#endif
+ ;
+ case GMP_RNDU:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_UPWARD)
+ fesetround(FE_UPWARD)
+#else
+ -1
+#endif
+ ;
+ case GMP_RNDD:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_DOWNWARD)
+ fesetround(FE_DOWNWARD)
+#else
+ -1
+#endif
+ ;
+ default:
+ return -1;
+ }
+}
diff --git a/mpfr/tests/tabs.c b/mpfr/tests/tabs.c
index b586b8365..a767cda1f 100644
--- a/mpfr/tests/tabs.c
+++ b/mpfr/tests/tabs.c
@@ -21,6 +21,7 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include "gmp.h"
#include "mpfr.h"
#include "mpfr-impl.h"
@@ -36,6 +37,8 @@ check_inexact (void)
mp_rnd_t rnd;
int inexact, cmp;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
mpfr_init (absx);
@@ -130,7 +133,7 @@ main (int argc, char *argv[])
#ifdef HAVE_DENORMS
while (0);
#else
- while (absd <= 2.2e-307);
+ while (absd < DBL_MIN);
#endif
rnd = LONG_RAND() % 4;
mpfr_set_d (x, d, 0);
@@ -148,5 +151,6 @@ main (int argc, char *argv[])
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tacos.c b/mpfr/tests/tacos.c
index 6690d797d..cda4ebf7a 100644
--- a/mpfr/tests/tacos.c
+++ b/mpfr/tests/tacos.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_acos.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Contributed by Mathieu Dutour.
This file is part of the MPFR Library.
@@ -34,6 +34,8 @@ main (void)
mp_rnd_t rnd;
mpfr_t x, y, z;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
mpfr_init (z);
@@ -92,5 +94,6 @@ main (void)
mpfr_clear (y);
mpfr_clear (z);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tacosh.c b/mpfr/tests/tacosh.c
index bc154a243..35ec74b8f 100644
--- a/mpfr/tests/tacosh.c
+++ b/mpfr/tests/tacosh.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_acosh.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -33,8 +33,11 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 25);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tadd.c b/mpfr/tests/tadd.c
index 32edb9c49..48008c840 100644
--- a/mpfr/tests/tadd.c
+++ b/mpfr/tests/tadd.c
@@ -23,6 +23,7 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include <time.h>
#include "gmp.h"
#include "mpfr.h"
@@ -54,7 +55,7 @@ void check_inexact _PROTO((void));
/* checks that x+y gives the same results in double
and with mpfr with 53 bits of precision */
-void
+static void
_check (double x, double y, double z1, mp_rnd_t rnd_mode, unsigned int px,
unsigned int py, unsigned int pz)
{
@@ -66,11 +67,8 @@ _check (double x, double y, double z1, mp_rnd_t rnd_mode, unsigned int px,
mpfr_set_d(xx, x, rnd_mode);
mpfr_set_d(yy, y, rnd_mode);
mpfr_add(zz, xx, yy, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
- if (px==53 && py==53 && pz==53) cert=1;
-#endif
- if (z1==0.0) z1=x+y; else cert=1;
+ if (px==53 && py==53 && pz==53)
+ cert = 1;
z2 = mpfr_get_d1 (zz);
mpfr_set_d (yy, z2, GMP_RNDN);
if (!mpfr_cmp (zz, yy) && cert && z1!=z2 && !(isnan(z1) && isnan(z2))) {
@@ -94,9 +92,6 @@ checknan (double x, double y, mp_rnd_t rnd_mode, unsigned int px,
mpfr_set_d(xx, x, rnd_mode);
mpfr_set_d(yy, y, rnd_mode);
mpfr_add(zz, xx, yy, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
if (MPFR_IS_NAN(zz) == 0) { printf("Error, not an MPFR_NAN for xx = %1.20e, y = %1.20e\n", x, y); exit(1); }
z2 = mpfr_get_d1 (zz);
if (!isnan(z2)) { printf("Error, not a NaN after conversion, xx = %1.20e yy = %1.20e, got %1.20e\n", x, y, z2); exit(1); }
@@ -104,114 +99,6 @@ checknan (double x, double y, mp_rnd_t rnd_mode, unsigned int px,
mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
}
-#ifdef MPFR_HAVE_FESETROUND
-/* idem than check for mpfr_add(x, x, y) */
-void
-check3 (double x, double y, mp_rnd_t rnd_mode)
-{
- double z1,z2; mpfr_t xx,yy; int neg;
-
- neg = LONG_RAND() % 2;
- mpfr_init2(xx, 53);
- mpfr_init2(yy, 53);
- mpfr_set_d(xx, x, rnd_mode);
- mpfr_set_d(yy, y, rnd_mode);
- if (neg) mpfr_sub(xx, xx, yy, rnd_mode);
- else mpfr_add(xx, xx, yy, rnd_mode);
- mpfr_set_machine_rnd_mode(rnd_mode);
- z1 = (neg) ? x-y : x+y;
- z2 = mpfr_get_d1 (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,y) failed for x=%1.20e y=%1.20e with rnd_mode=%u\n",
- (neg) ? "sub" : "add",x,y,rnd_mode);
- exit(1);
- }
- mpfr_clear(xx); mpfr_clear(yy);
-}
-
-/* idem than check for mpfr_add(x, y, x) */
-void
-check4 (double x, double y, mp_rnd_t rnd_mode)
-{
- double z1, z2;
- mpfr_t xx, yy;
- int neg;
-
- neg = LONG_RAND() % 2;
- mpfr_init2(xx, 53);
- mpfr_init2(yy, 53);
- mpfr_set_d(xx, x, rnd_mode);
- mpfr_set_d(yy, y, rnd_mode);
- if (neg) mpfr_sub(xx, yy, xx, rnd_mode);
- else mpfr_add(xx, yy, xx, rnd_mode);
- mpfr_set_machine_rnd_mode(rnd_mode);
- z1 = (neg) ? y-x : x+y;
- z2 = mpfr_get_d1 (xx);
- mpfr_set_d (yy, z2, GMP_RNDN);
- /* check that xx is representable as a double and no overflow occurred */
- if ((mpfr_cmp (xx, yy) == 0) && (z1 != z2)) {
- printf("expected result is %1.20e, got %1.20e\n", z1, z2);
- printf("mpfr_%s(x,y,x) failed for x=%1.20e y=%1.20e with rnd_mode=%s\n",
- (neg) ? "sub" : "add", x, y, mpfr_print_rnd_mode(rnd_mode));
- exit(1);
- }
- mpfr_clear(xx); mpfr_clear(yy);
-}
-
-/* idem than check for mpfr_add(x, x, x) */
-void
-check5 (double x, mp_rnd_t rnd_mode)
-{
- double z1,z2; mpfr_t xx, yy; int neg;
-
- mpfr_init2(xx, 53);
- mpfr_init2(yy, 53);
- neg = LONG_RAND() % 2;
- mpfr_set_d(xx, x, rnd_mode);
- if (neg) mpfr_sub(xx, xx, xx, rnd_mode);
- else mpfr_add(xx, xx, xx, rnd_mode);
- mpfr_set_machine_rnd_mode(rnd_mode);
- z1 = (neg) ? x-x : x+x;
- z2 = mpfr_get_d1 (xx);
- mpfr_set_d (yy, z2, GMP_RNDN);
- /* 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);
-}
-
-void
-check2 (double x, int px, double y, int py, int pz, mp_rnd_t rnd_mode)
-{
- mpfr_t xx, yy, zz; double z,z2; int u;
-
- mpfr_init2(xx,px); mpfr_init2(yy,py); mpfr_init2(zz,pz);
- mpfr_set_d(xx, x, rnd_mode);
- mpfr_set_d(yy, y, rnd_mode);
- mpfr_add(zz, xx, yy, rnd_mode);
- mpfr_set_machine_rnd_mode(rnd_mode);
- z = x+y; z2=mpfr_get_d1 (zz); u=ulp(z,z2);
- /* one ulp difference is possible due to composed rounding */
- if (px>=53 && py>=53 && pz>=53 && ABS(u)>1) {
- printf("x=%1.20e,%d y=%1.20e,%d pz=%d,rnd=%s\n",
- x,px,y,py,pz,mpfr_print_rnd_mode(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_binary(zz); putchar('\n');
- exit(1); }
- mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
-}
-#endif
-
void
check2a (double x, int px, double y, int py, int pz, mp_rnd_t rnd_mode,
char *res)
@@ -604,7 +491,7 @@ check_inexact (void)
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)
+ pz = (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x)-MPFR_EXP(u)
: MPFR_EXP(u)-MPFR_EXP(x);
/* x + u is exactly representable with precision
abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */
@@ -650,14 +537,11 @@ check_inexact (void)
int
main (int argc, char *argv[])
{
-#ifdef MPFR_HAVE_FESETROUND
- int prec, rnd_mode;
- int rnd;
- double y;
-#endif
double x;
int i;
+ tests_start_mpfr ();
+
mpfr_test_init ();
check_inexact ();
check_case_1b ();
@@ -821,11 +705,9 @@ main (int argc, char *argv[])
check53(5.76707395945001907217e-58, 4.74752971449827687074e-51, GMP_RNDD,
4.747530291205672325e-51);
check53(277363943109.0, 11.0, GMP_RNDN, 277363943120.0);
-#if 0 /* disabled since it seems silly to use denorms */
/* test denormalized numbers too */
check53(8.06294740693074521573e-310, 6.95250701071929654575e-310, GMP_RNDU,
1.5015454417650041761e-309);
-#endif
#ifdef HAVE_INFS
/* the following check double overflow */
check53(6.27557402141211962228e+307, 1.32141396570101687757e+308,
@@ -847,58 +729,6 @@ main (int argc, char *argv[])
check53(9007199254740994.0, -1.0, GMP_RNDN, 9007199254740992.0);
check53(9007199254740996.0, -1.0, GMP_RNDN, 9007199254740996.0);
-#ifdef MPFR_HAVE_FESETROUND
- prec = (argc<2) ? 53 : atoi(argv[1]);
- rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
- /* Comparing to double precision using machine arithmetic */
- for (i=0;i<N;i++) {
- x = drand();
- y = drand();
- if (ABS(x)>2.2e-307 && ABS(y)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check(x, y, rnd, prec, prec, prec, 0.0);
- }
- }
- /* tests with random precisions */
- for (i=0;i<N;i++) {
- int px, py, pz;
- px = 53 + (LONG_RAND() % 64);
- py = 53 + (LONG_RAND() % 64);
- pz = 53 + (LONG_RAND() % 64);
- rnd_mode = LONG_RAND() % 4;
- do { x = drand(); } while (isnan(x));
- do { y = drand(); } while (isnan(y));
- check2 (x, px, y, py, pz, rnd_mode);
- }
- /* Checking mpfr_add(x, x, y) with prec=53 */
- for (i=0;i<N;i++) {
- x = drand();
- y = drand();
- if (ABS(x)>2.2e-307 && ABS(y)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check3(x, y, rnd);
- }
- }
- /* Checking mpfr_add(x, y, x) with prec=53 */
- for (i=0;i<N;i++) {
- x = drand();
- y = drand();
- if (ABS(x)>2.2e-307 && ABS(y)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check4(x, y, rnd);
- }
- }
- /* Checking mpfr_add(x, x, x) with prec=53 */
- for (i=0;i<N;i++) {
- do { x = drand(); } while ((ABS(x)<2.2e-307) || (ABS(x)>0.8e308));
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check5(x, rnd);
- }
-#endif
-
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tadd_ui.c b/mpfr/tests/tadd_ui.c
index c6ee4d538..f6563839d 100644
--- a/mpfr/tests/tadd_ui.c
+++ b/mpfr/tests/tadd_ui.c
@@ -25,6 +25,7 @@ MA 02111-1307, USA. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include <time.h>
#include "gmp.h"
#include "mpfr.h"
@@ -47,10 +48,6 @@ check3 (double x, unsigned long y, unsigned int rnd_mode, double z1)
mpfr_init2(zz, 53);
mpfr_set_d(xx, x, rnd_mode);
mpfr_add_ui(zz, xx, y, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (z1==0.0) z1 = x+y;
z2 = mpfr_get_d1 (zz);
if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
printf("expected sum is %1.20e, got %1.20e\n",z1,z2);
@@ -77,24 +74,8 @@ special (void)
int
main (int argc, char *argv[])
{
-#ifdef MPFR_HAVE_FESETROUND
- double x; unsigned long y, N; int i,rnd_mode,rnd;
-
- mpfr_test_init ();
-
- SEED_RAND (time(NULL));
- N = (argc<2) ? 1000000 : atoi(argv[1]);
- rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
- for (i=0;i<1000000;i++) {
- x = drand();
- y = LONG_RAND();
- if (ABS(x)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check(x, y, rnd);
- }
- }
-#endif
+ tests_start_mpfr ();
+
special ();
check3 (-1.716113812768534e-140, 1271212614, GMP_RNDZ,
1.27121261399999976e9);
@@ -109,6 +90,7 @@ main (int argc, char *argv[])
check3 (DBL_NAN, 2394875, GMP_RNDN, DBL_NAN);
#endif
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tagm.c b/mpfr/tests/tagm.c
index 830c98f8e..7b4a3bd69 100644
--- a/mpfr/tests/tagm.c
+++ b/mpfr/tests/tagm.c
@@ -79,7 +79,6 @@ check4 (double a, double b, mp_rnd_t rnd_mode, double res1)
{
mpfr_t ta, tb, tres;
double res2;
- int ck=0;
mpfr_init2(ta, 53);
mpfr_init2(tb, 53);
@@ -89,21 +88,19 @@ check4 (double a, double b, mp_rnd_t rnd_mode, double res1)
mpfr_set_d(tb, b, rnd_mode);
mpfr_agm(tres, ta, tb, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (res1==0.0) res1=dagm(a,b); else ck=1;
-if (ck==0) printf("%1.20e\n", res1);
res2 = mpfr_get_d1 (tres);
- if (ck && res1!=res2 && (!isnan(res1) || !isnan(res2))) {
- printf("mpfr_agm failed for a=%1.20e, b=%1.20e, rnd_mode=%d\n",a,b,rnd_mode);
- printf("expected result is %1.20e, got %1.20e (%d ulp)\n",res1,res2,
- ulp(res2,res1));
- /*exit(1);*/
+ if (res1!=res2 && (!isnan(res1) || !isnan(res2)))
+ {
+ printf ("mpfr_agm failed for a=%1.20e, b=%1.20e, rnd_mode=%d\n",a,b,rnd_mode);
+ printf ("expected result is %1.20e, got %1.20e (%d ulp)\n",res1,res2,
+ ulp(res2,res1));
+ exit (1);
}
- mpfr_clear(ta); mpfr_clear(tb); mpfr_clear(tres);
+ mpfr_clear (ta);
+ mpfr_clear (tb);
+ mpfr_clear (tres);
}
void
@@ -151,6 +148,8 @@ main (int argc, char* argv[])
SEED_RAND (time(NULL));
+ tests_start_mpfr ();
+
if (argc==3) { /* tagm N p : N calculus with precision p*/
printf("Doing %d random tests in %d precision\n",atoi(argv[1]),atoi(argv[2]));
slave(atoi(argv[1]),atoi(argv[2]));
@@ -184,5 +183,6 @@ main (int argc, char* argv[])
/* TODO : tests des infinis dans tagm.c */
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tasin.c b/mpfr/tests/tasin.c
index ec6119331..778c45f2c 100644
--- a/mpfr/tests/tasin.c
+++ b/mpfr/tests/tasin.c
@@ -33,6 +33,8 @@ main (void)
mp_rnd_t rnd;
mpfr_t x, y, z;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
mpfr_init (z);
@@ -88,5 +90,6 @@ main (void)
mpfr_clear (y);
mpfr_clear (z);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tasinh.c b/mpfr/tests/tasinh.c
index 540037c54..0603e3ade 100644
--- a/mpfr/tests/tasinh.c
+++ b/mpfr/tests/tasinh.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_asinh.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -34,6 +34,8 @@ main (int argc, char *argv[])
{
mpfr_t x, y;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
@@ -47,5 +49,6 @@ main (int argc, char *argv[])
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tatan.c b/mpfr/tests/tatan.c
index 4abd797b7..f2a6101ad 100644
--- a/mpfr/tests/tatan.c
+++ b/mpfr/tests/tatan.c
@@ -66,6 +66,8 @@ main (int argc, char *argv[])
mp_rnd_t rnd;
mpfr_t x, y, z, t;
+ tests_start_mpfr ();
+
worst_cases ();
mpfr_init (x);
@@ -124,5 +126,6 @@ main (int argc, char *argv[])
mpfr_clear (z);
mpfr_clear (t);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tatanh.c b/mpfr/tests/tatanh.c
index 5d719d7e2..3b7774623 100644
--- a/mpfr/tests/tatanh.c
+++ b/mpfr/tests/tatanh.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_atanh.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 25);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tcan_round.c b/mpfr/tests/tcan_round.c
index 4d5f7e332..a6b614f0d 100644
--- a/mpfr/tests/tcan_round.c
+++ b/mpfr/tests/tcan_round.c
@@ -23,12 +23,15 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
int
main (void)
{
mpfr_t x;
+ tests_start_mpfr ();
+
/* checks that rounds to nearest sets the last
bit to zero in case of equal distance */
mpfr_init2 (x, 59);
@@ -56,5 +59,6 @@ main (void)
mpfr_clear (x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tcbrt.c b/mpfr/tests/tcbrt.c
new file mode 100644
index 000000000..ed0b005bd
--- /dev/null
+++ b/mpfr/tests/tcbrt.c
@@ -0,0 +1,96 @@
+/* Test file for mpfr_cbrt.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "mpfr.h"
+
+int
+main (void)
+{
+ mpfr_t x;
+ mp_rnd_t r;
+ mp_prec_t p;
+
+ mpfr_init (x);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_d (x, 8.39005285514734966412e-01, GMP_RNDN);
+ mpfr_cbrt (x, x, GMP_RNDN);
+ if (mpfr_get_d1 (x) != 9.43166207799662426048e-01)
+ {
+ fprintf (stderr, "Error (1)\n");
+ exit (1);
+ }
+
+ for (p=2; p<100; p++)
+ {
+ mpfr_set_prec (x, p);
+ for (r=0; r<4; r++)
+ {
+ mpfr_set_ui (x, 1, GMP_RNDN);
+ mpfr_cbrt (x, x, r);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ fprintf (stderr, "Error in mpfr_cbrt for x=1, rnd=%s\ngot ",
+ mpfr_print_rnd_mode (r));
+ mpfr_out_str (stderr, 2, 0, x, GMP_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+ mpfr_set_si (x, -1, GMP_RNDN);
+ mpfr_cbrt (x, x, r);
+ if (mpfr_cmp_si (x, -1))
+ {
+ fprintf (stderr, "Error in mpfr_cbrt for x=-1, rnd=%s\ngot ",
+ mpfr_print_rnd_mode (r));
+ mpfr_out_str (stderr, 2, 0, x, GMP_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ if (p >= 5)
+ {
+ int i;
+ for (i = -12; i <= 12; i++)
+ {
+ mpfr_set_d (x, 27.0, GMP_RNDN);
+ mpfr_mul_2si (x, x, 3*i, GMP_RNDN);
+ mpfr_cbrt (x, x, GMP_RNDN);
+ if (mpfr_cmp_si_2exp (x, 3, i))
+ {
+ fprintf (stderr, "Error in mpfr_cbrt for "
+ "x = 27.0 * 2^(%d), rnd=%s\ngot ",
+ 3*i, mpfr_print_rnd_mode (r));
+ mpfr_out_str (stderr, 2, 0, x, GMP_RNDN);
+ fprintf (stderr, "\ninstead of 3 * 2^(%d)\n", i);
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+
+ return 0;
+}
diff --git a/mpfr/tests/tcmp.c b/mpfr/tests/tcmp.c
index 3db356ae4..e60fe18ad 100644
--- a/mpfr/tests/tcmp.c
+++ b/mpfr/tests/tcmp.c
@@ -35,6 +35,8 @@ main (void)
int i, c;
mp_prec_t p;
+ tests_start_mpfr ();
+
mpfr_init (xx);
mpfr_init (yy);
@@ -174,5 +176,6 @@ main (void)
mpfr_clear(xx); mpfr_clear(yy);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tcmp2.c b/mpfr/tests/tcmp2.c
index 2b82f92bd..d36350ef1 100644
--- a/mpfr/tests/tcmp2.c
+++ b/mpfr/tests/tcmp2.c
@@ -281,6 +281,7 @@ main (void)
{
int i,j; double x=1.0, y, z;
+ tests_start_mpfr ();
mpfr_test_init ();
worst_cases ();
@@ -303,5 +304,6 @@ main (void)
if (y != 0.0 && y != -0.0) tcmp2(x, y, -1);
}
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tcmp_ui.c b/mpfr/tests/tcmp_ui.c
index 3607c4f08..5b6b35a2c 100644
--- a/mpfr/tests/tcmp_ui.c
+++ b/mpfr/tests/tcmp_ui.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_cmp_ui.
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -24,12 +24,15 @@ MA 02111-1307, USA. */
#include <math.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
int
main (void)
{
mpfr_t x; unsigned long i; long s;
+ tests_start_mpfr ();
+
mpfr_init(x);
mpfr_set_ui(x, 3, GMP_RNDZ);
@@ -83,5 +86,6 @@ main (void)
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tconst_euler.c b/mpfr/tests/tconst_euler.c
index 364051ac4..a86b1154d 100644
--- a/mpfr/tests/tconst_euler.c
+++ b/mpfr/tests/tconst_euler.c
@@ -24,6 +24,7 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
int
main (int argc, char *argv[])
@@ -32,6 +33,8 @@ main (int argc, char *argv[])
unsigned int err, prec, yprec, p0 = 2, p1 = 200;
mp_rnd_t rnd;
+ tests_start_mpfr ();
+
prec = (argc < 2) ? 53 : atoi(argv[1]);
if (argc > 1)
@@ -86,5 +89,6 @@ main (int argc, char *argv[])
mpfr_clear (z);
mpfr_clear (t);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tconst_log2.c b/mpfr/tests/tconst_log2.c
index dce91d8b3..43b577ea0 100644
--- a/mpfr/tests/tconst_log2.c
+++ b/mpfr/tests/tconst_log2.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_const_log2.
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -25,6 +25,7 @@ MA 02111-1307, USA. */
#include "gmp-impl.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
/* tlog2 [prec] [rnd] [0 = no print] */
@@ -40,7 +41,7 @@ check (mp_prec_t p0, mp_prec_t p1)
mpfr_init (y);
mpfr_init2 (z, p1 + 10);
mpfr_const_log2 (z, GMP_RNDN);
- __mpfr_const_log2_prec = 1;
+ __gmpfr_const_log2_prec = 1;
for (; p0<=p1; p0++)
{
@@ -77,6 +78,8 @@ main (int argc, char *argv[])
int p;
mp_rnd_t rnd;
+ tests_start_mpfr ();
+
p = (argc>1) ? atoi(argv[1]) : 53;
rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ;
@@ -113,5 +116,6 @@ main (int argc, char *argv[])
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tconst_pi.c b/mpfr/tests/tconst_pi.c
index 45affb32f..fdf6f6d09 100644
--- a/mpfr/tests/tconst_pi.c
+++ b/mpfr/tests/tconst_pi.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_const_pi.
-Copyright 1999, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -23,6 +23,7 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
/* tpi [prec] [rnd] [0 = no print] */
@@ -31,6 +32,8 @@ main (int argc, char *argv[])
{
mpfr_t x; int p; unsigned char rnd;
+ tests_start_mpfr ();
+
p = (argc>1) ? atoi(argv[1]) : 53;
rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ;
mpfr_init2(x, p);
@@ -43,5 +46,6 @@ main (int argc, char *argv[])
}
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tcos.c b/mpfr/tests/tcos.c
index c87486fe9..aacfa0142 100644
--- a/mpfr/tests/tcos.c
+++ b/mpfr/tests/tcos.c
@@ -58,6 +58,8 @@ main (int argc, char *argv[])
{
mpfr_t x, y;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
@@ -127,5 +129,6 @@ main (int argc, char *argv[])
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tcosh.c b/mpfr/tests/tcosh.c
index 54ae3a759..bd431af8a 100644
--- a/mpfr/tests/tcosh.c
+++ b/mpfr/tests/tcosh.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_cosh.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tdiv.c b/mpfr/tests/tdiv.c
index 202ddac10..d0588dc6e 100644
--- a/mpfr/tests/tdiv.c
+++ b/mpfr/tests/tdiv.c
@@ -38,28 +38,31 @@ void check_lowr _PROTO((void));
void check_inexact _PROTO((void));
void check_nan _PROTO((void));
+/* if Q is not zero, then it is the correct result */
void
check4 (double N, double D, mp_rnd_t rnd_mode, int p, double Q)
{
- mpfr_t q, n, d; double Q2;
+ mpfr_t q, n, d;
+ double Q2;
- mpfr_init2(q, p); mpfr_init2(n, p); mpfr_init2(d, p);
+ mpfr_init2 (q, p);
+ mpfr_init2 (n, p);
+ mpfr_init2 (d, p);
mpfr_set_d(n, N, rnd_mode);
mpfr_set_d(d, D, rnd_mode);
mpfr_div(q, n, d, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (Q==0.0) Q = N/D;
Q2 = mpfr_get_d1 (q);
- if (p==53 && Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
- printf("mpfr_div failed for n=%1.20e, d=%1.20e, rnd_mode=%s\n",
- N, D, mpfr_print_rnd_mode(rnd_mode));
- printf("expected quotient is %1.20e, got %1.20e (%d ulp)\n", Q, Q2,
- ulp(Q2, Q));
- exit(1);
- }
- mpfr_clear(q); mpfr_clear(n); mpfr_clear(d);
+ if (p == 53 && Q != Q2 && (!isnan(Q) || !isnan(Q2)))
+ {
+ printf ("mpfr_div failed for n=%1.20e, d=%1.20e, rnd_mode=%s\n",
+ N, D, mpfr_print_rnd_mode(rnd_mode));
+ printf ("correct quotient is %1.20e, mpfr_div gives %1.20e (%d ulp)\n",
+ Q, Q2, ulp (Q2, Q));
+ exit (1);
+ }
+ mpfr_clear (q);
+ mpfr_clear (n);
+ mpfr_clear (d);
}
void
@@ -451,13 +454,6 @@ main (int argc, char *argv[])
{
mpfr_t x, y, z;
-#ifdef MPFR_HAVE_FESETROUND
- int N, i;
- double n, d, e;
-
- mpfr_test_init ();
-#endif
-
check_inexact();
mpfr_init2 (x, 64);
@@ -493,18 +489,13 @@ main (int argc, char *argv[])
-4.0250194961676020848e-258);
check53(1.04636807108079349236e-189, 3.72295730823253012954e-292, GMP_RNDZ,
2.810583051186143125e102);
-
-#ifdef MPFR_HAVE_FESETROUND
- N = (argc>1) ? atoi(argv[1]) : 10000;
- SEED_RAND (time(NULL));
- for (i=0;i<N;i++)
- {
- 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, LONG_RAND() % 4, 53, 0.0);
- }
-#endif
+ /* problems found by Kevin under HP-PA */
+ check53 (2.861044553323177e-136, -1.1120354257068143e+45, GMP_RNDZ,
+ -2.5727998292003016e-181);
+ check53 (-4.0559157245809205e-127, -1.1237723844524865e+77, GMP_RNDN,
+ 3.6091968273068081e-204);
+ check53 (-1.8177943561493235e-93, -8.51233984260364e-104, GMP_RNDU,
+ 2.1354814184595821e+10);
mpfr_clear (x);
mpfr_clear (y);
diff --git a/mpfr/tests/tdiv_ui.c b/mpfr/tests/tdiv_ui.c
index 95aef9630..85d08e03f 100644
--- a/mpfr/tests/tdiv_ui.c
+++ b/mpfr/tests/tdiv_ui.c
@@ -21,6 +21,7 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include <time.h>
#include "gmp.h"
#include "mpfr.h"
@@ -37,10 +38,6 @@ check (double d, unsigned long u, mp_rnd_t rnd, double e)
double f;
mpfr_init2(x, 53); mpfr_init2(y, 53);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd);
-#endif
- if (e==0.0) e = d / u;
mpfr_set_d(x, d, rnd);
mpfr_div_ui(y, x, u, rnd);
f = mpfr_get_d1 (y);
@@ -174,21 +171,8 @@ int
main (int argc, char **argv)
{
mpfr_t x;
-#ifdef MPFR_HAVE_FESETROUND
- int i;
- unsigned long u;
- double d;
- mpfr_test_init ();
-
- SEED_RAND (time(NULL));
- for (i=0;i<1000000;i++)
- {
- do { u = LONG_RAND(); } while (u==0);
- do { d = drand(); } while (ABS(d/u)<2.2e-307);
- check (d, u, LONG_RAND() % 4, 0.0);
- }
-#endif
+ tests_start_mpfr ();
check_inexact ();
@@ -211,5 +195,6 @@ main (int argc, char **argv)
}
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tdump.c b/mpfr/tests/tdump.c
index fbd1efc0c..9ab6d6372 100644
--- a/mpfr/tests/tdump.c
+++ b/mpfr/tests/tdump.c
@@ -23,17 +23,21 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
int
main (void)
{
mpfr_t z;
+ tests_start_mpfr ();
+
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);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/teq.c b/mpfr/tests/teq.c
index 834972b05..fa2c2857e 100644
--- a/mpfr/tests/teq.c
+++ b/mpfr/tests/teq.c
@@ -25,6 +25,7 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
void teq _PROTO ((mpfr_t));
@@ -66,6 +67,8 @@ main (void)
{
int j; mpfr_t x;
+ tests_start_mpfr ();
+
mpfr_init2 (x, 1000);
for (j=0;j<1000;j++) {
@@ -74,5 +77,6 @@ main (void)
}
mpfr_clear (x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tests.c b/mpfr/tests/tests.c
new file mode 100644
index 000000000..9419e21d9
--- /dev/null
+++ b/mpfr/tests/tests.c
@@ -0,0 +1,178 @@
+/* Miscellaneous support for test programs.
+
+Copyright 2001, 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 <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "mpfr.h"
+#include "mpfr-impl.h"
+#include "mpfr-test.h"
+
+
+void
+tests_start_mpfr (void)
+{
+ tests_memory_start ();
+}
+
+void
+tests_end_mpfr (void)
+{
+ if (__gmpfr_const_pi_prec != 0)
+ {
+ mpfr_clear (__mpfr_const_pi);
+ __gmpfr_const_pi_prec = 0;
+ }
+
+ if (__gmpfr_const_log2_prec != 0)
+ {
+ mpfr_clear (__mpfr_const_log2);
+ __gmpfr_const_log2_prec = 0;
+ }
+
+ if (__gmp_rands_initialized)
+ {
+ gmp_randclear (__gmp_rands);
+ __gmp_rands_initialized = 0;
+ }
+
+ tests_memory_end ();
+}
+
+/* initialization function for tests using the hardware floats */
+void
+mpfr_test_init ()
+{
+ double c, d;
+ int j;
+#ifdef __mips
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+#ifdef HAVE_DENORMS
+ d = DBL_MIN;
+ if (2.0 * (d / 2.0) != d)
+ {
+ fprintf (stderr, "Warning: no denormalized numbers\n");
+ exit (1);
+ }
+#endif
+
+#ifdef HAVE_SETFPUCW
+ /* sets the precision to double */
+ __setfpucw((_FPU_DEFAULT & (~_FPU_EXTENDED)) | _FPU_DOUBLE);
+#endif
+ c = 1.46484375e-3;
+ d = 1.0;
+ for (j=0; j<54; j++) d *= 0.5;
+ d = 0.75 + d;
+ d /= 1 << 9;
+ if (c != d)
+ {
+ fprintf (stderr, "Warning: extended precision not disabled\n");
+ exit (1);
+ }
+}
+
+/* generate a random double using the whole range of possible values,
+ including denormalized numbers, NaN, infinities, ... */
+double
+drand (void)
+{
+ double d; int *i, expo;
+
+ i = (int*) &d;
+ d = 1.0;
+ if (i[0] == 0)
+ expo = 1; /* little endian, exponent in i[1] */
+ else
+ expo = 0;
+ i[0] = LONG_RAND();
+ i[1] = LONG_RAND();
+ while (i[expo] >= 2146435072)
+ i[expo] = LONG_RAND(); /* avoids NaNs */
+ if ((LONG_RAND() % 2) && !isnan (d))
+ d = -d; /* generates negative numbers */
+ return d;
+}
+
+/* returns ulp(x) for x a 'normal' double-precision number */
+double
+Ulp (double x)
+{
+ double y, eps;
+
+ if (x < 0) x = -x;
+
+ y = x * 2.220446049250313080847263336181640625e-16 ; /* x / 2^52 */
+
+ /* as ulp(x) <= y = x/2^52 < 2*ulp(x),
+ we have x + ulp(x) <= x + y <= x + 2*ulp(x),
+ therefore o(x + y) = x + ulp(x) or x + 2*ulp(x) */
+
+ eps = x + y;
+ eps = eps - x; /* ulp(x) or 2*ulp(x) */
+
+ return (eps > y) ? 0.5 * eps : eps;
+}
+
+/* returns the number of ulp's between a and b,
+ where a and b can be any floating-point number, except NaN
+ */
+int
+ulp (double a, double b)
+{
+ double twoa;
+
+ if (a == b) return 0; /* also deals with a=b=inf or -inf */
+
+ twoa = a + a;
+ if (twoa == a) /* a is +/-0.0 or +/-Inf */
+ return ((b < a) ? INT_MAX : -INT_MAX);
+
+ return (a - b) / Ulp (a);
+}
+
+/* return double m*2^e */
+double
+dbl (double m, int e)
+{
+ if (e >=0 )
+ while (e-- > 0)
+ m *= 2.0;
+ else
+ while (e++ < 0)
+ m /= 2.0;
+ return m;
+}
+
+#ifndef HAVE_ISNAN
+int
+Isnan (double d)
+{
+ return (d) != (d);
+}
+#endif
diff --git a/mpfr/tests/texceptions.c b/mpfr/tests/texceptions.c
index 6e9018b6e..d822d7ddb 100644
--- a/mpfr/tests/texceptions.c
+++ b/mpfr/tests/texceptions.c
@@ -1,6 +1,6 @@
/* Test file for exceptions.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -23,6 +23,7 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
void mpfr_set_double_range _PROTO((void));
@@ -53,6 +54,8 @@ main (int argc, char *argv[])
mpfr_t x, y;
mp_exp_t emin, emax;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
@@ -67,7 +70,7 @@ main (int argc, char *argv[])
mpfr_set_ui (x, 1, GMP_RNDN);
mpfr_mul_2exp (x, x, 1024, GMP_RNDN);
mpfr_set_double_range ();
- mpfr_check_range (x, GMP_RNDN);
+ mpfr_check_range (x, 0, GMP_RNDN);
if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
{
fprintf (stderr, "Error: 2^1024 rounded to nearest should give +Inf\n");
@@ -78,7 +81,7 @@ main (int argc, char *argv[])
mpfr_set_ui (x, 1, GMP_RNDN);
mpfr_mul_2exp (x, x, 1024, GMP_RNDN);
mpfr_set_double_range ();
- mpfr_check_range (x, GMP_RNDD);
+ mpfr_check_range (x, 0, GMP_RNDD);
if (!mpfr_number_p (x))
{
fprintf (stderr, "Error: 2^1024 rounded down should give a normal number\n");
@@ -119,5 +122,6 @@ main (int argc, char *argv[])
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/texp.c b/mpfr/tests/texp.c
index b26c2b549..4bad0bac0 100644
--- a/mpfr/tests/texp.c
+++ b/mpfr/tests/texp.c
@@ -43,13 +43,9 @@ int maxu=0;
int
check3 (double d, mp_rnd_t rnd, double e)
{
- mpfr_t x, y; double f; int u=0, ck=0;
+ mpfr_t x, y; double f; int u=0;
mpfr_init2(x, 53); mpfr_init2(y, 53);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd);
-#endif
- if (e==0.0) e = exp(d); else ck=1; /* really check */
mpfr_set_d(x, d, rnd);
mpfr_exp(y, x, rnd);
f = mpfr_get_d1 (y);
@@ -60,18 +56,10 @@ check3 (double d, mp_rnd_t rnd, double e)
u=-u;
}
if (u!=0) {
- if (ck) {
- printf("mpfr_exp failed for x=%1.20e, rnd=%s\n", d,
- mpfr_print_rnd_mode(rnd));
- printf("expected result is %1.20e, got %1.20e, dif=%d ulp\n",e,f,u);
- exit(1);
- }
- else if (u>maxu) {
- maxu=u;
- printf("mpfr_exp differs from libm.a for x=%1.20e, rnd=%s\n",d,
- mpfr_print_rnd_mode(rnd));
- printf("libm.a gave %1.20e, mpfr_exp got %1.20e, dif=%d ulp\n",e,f,u);
- }
+ printf ("mpfr_exp failed for x=%1.20e, rnd=%s\n", d,
+ mpfr_print_rnd_mode(rnd));
+ printf ("expected result is %1.20e, got %1.20e, dif=%d ulp\n",e,f,u);
+ exit (1);
}
}
mpfr_clear(x); mpfr_clear(y);
@@ -216,12 +204,10 @@ compare_exp2_exp3 (int n)
int
main (int argc, char *argv[])
{
-#ifdef MPFR_HAVE_FESETROUND
- int i, N, s=0, e, maxe=0;
- double lo, hi;
-#endif
double d;
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
if (argc == 4)
@@ -272,22 +258,7 @@ main (int argc, char *argv[])
check3(5.30015757134837031117e+02, GMP_RNDD, 1.5237672861171573939e230);
check3(5.16239362447650933063e+02, GMP_RNDZ, 1.5845518406744492105e224);
check3(6.00812634798592370977e-01, GMP_RNDN, 1.823600119339019443);
-#ifdef MPFR_HAVE_FESETROUND
- SEED_RAND (time(NULL));
- N = (argc==1) ? 0 : atoi(argv[1]);
- lo = (argc>=3) ? atof(argv[2]) : -7.083964185e2;
- hi = (argc>=4) ? atof(argv[3]) : 7.097827129e2;
- for (i=0;i<N;i++) {
- /* select d such that exp(d) can be represented as a normalized
- machine double-precision number,
- i.e. 2^(-1022) <= exp(d) <= 2^(1023)*(2-2^(-52)) */
- d = lo + (hi-lo)*DBL_RAND();
- e = check(d, LONG_RAND() % 4);
- s += e;
- if (e>maxe) maxe=e;
- }
- if (N) printf("mean error=%1.2e max error=%d\n", (double)s/(double)N,maxe);
-#endif
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/texp2.c b/mpfr/tests/texp2.c
index 4f6819453..fe01821e1 100644
--- a/mpfr/tests/texp2.c
+++ b/mpfr/tests/texp2.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_exp2.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -36,6 +36,8 @@ main (int argc, char *argv[])
{
mpfr_t x, y;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
@@ -80,5 +82,6 @@ main (int argc, char *argv[])
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/texpm1.c b/mpfr/tests/texpm1.c
index b024e5a49..c1e1d54fa 100644
--- a/mpfr/tests/texpm1.c
+++ b/mpfr/tests/texpm1.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_expm1.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tsinh.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tfactorial.c b/mpfr/tests/tfactorial.c
index c68eb5ae3..712570a4a 100644
--- a/mpfr/tests/tfactorial.c
+++ b/mpfr/tests/tfactorial.c
@@ -26,6 +26,7 @@ MA 02111-1307, USA. */
#include "gmp-impl.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
#define TEST_FUNCTION mpfr_fac_ui
@@ -37,6 +38,8 @@ main (int argc, char *argv[])
mpfr_t x, y, z, t;
int inexact;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
mpfr_init (z);
@@ -114,5 +117,6 @@ main (int argc, char *argv[])
mpfr_clear (z);
mpfr_clear (t);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tfma.c b/mpfr/tests/tfma.c
index 880c87e01..4bbad6a35 100644
--- a/mpfr/tests/tfma.c
+++ b/mpfr/tests/tfma.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_fma.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -34,6 +34,9 @@ int
main (int argc, char *argv[])
{
mpfr_t x, y,z,s;
+
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (s);
mpfr_init (y);
@@ -327,5 +330,6 @@ main (int argc, char *argv[])
mpfr_clear (z);
mpfr_clear (s);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tfrac.c b/mpfr/tests/tfrac.c
new file mode 100644
index 000000000..b10e5e41c
--- /dev/null
+++ b/mpfr/tests/tfrac.c
@@ -0,0 +1,185 @@
+/* Test file for mpfr_frac.
+
+Copyright 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"
+#include "mpfr-test.h"
+
+#define PIP 150
+#define PFP 150
+#define PMAX (PIP+2*PFP)
+
+static void
+check0 (mpfr_ptr ip, mpfr_ptr fp, mp_prec_t prec, mp_rnd_t rnd)
+{
+ mpfr_t sum, tmp, dst, fp2;
+ int inex1, inex2;
+
+ mpfr_init2 (sum, PMAX);
+ mpfr_init2 (tmp, PMAX);
+ mpfr_init2 (dst, prec);
+ mpfr_init2 (fp2, prec);
+
+ if (MPFR_SIGN (ip) != MPFR_SIGN (fp))
+ {
+ fprintf (stderr, "Internal error (1)\n");
+ exit (1);
+ }
+ if (mpfr_add (sum, ip, fp, GMP_RNDZ))
+ {
+ fprintf (stderr, "Wrong inexact flag in mpfr_add\n");
+ exit (1);
+ }
+ if (MPFR_SIGN (sum) != MPFR_SIGN (fp))
+ {
+ fprintf (stderr, "Internal error (2)\n");
+ exit (1);
+ }
+
+ inex1 = mpfr_frac (dst, sum, rnd);
+ inex2 = mpfr_set (fp2, fp, rnd);
+ if (inex1 != inex2)
+ {
+ fprintf (stderr, "Wrong inexact flag in mpfr_frac for\n");
+ mpfr_out_str (stderr, 2, 0, sum, GMP_RNDN);
+ fprintf (stderr, "\nGot %d instead of %d\n", inex1, inex2);
+ exit (1);
+ }
+ if (!mpfr_number_p (dst) ||
+ MPFR_SIGN (dst) != MPFR_SIGN (fp2) ||
+ mpfr_cmp (dst, fp2))
+ {
+ fprintf (stderr, "Error in mpfr_frac (y, x, %s) with\nx = ",
+ mpfr_print_rnd_mode (rnd));
+ mpfr_out_str (stderr, 2, 0, sum, GMP_RNDN);
+ fprintf (stderr, "\nGot ");
+ mpfr_out_str (stderr, 2, 0, dst, GMP_RNDN);
+ fprintf (stderr, "\ninstead of ");
+ mpfr_out_str (stderr, 2, 0, fp2, GMP_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ if (prec == PMAX)
+ {
+ inex1 = mpfr_frac (sum, sum, rnd);
+ if (inex1)
+ {
+ fprintf (stderr, "Wrong inexact flag in mpfr_frac\n");
+ exit (1);
+ }
+ if (!mpfr_number_p (sum) ||
+ MPFR_SIGN (sum) != MPFR_SIGN (fp) ||
+ mpfr_cmp (sum, fp))
+ {
+ fprintf (stderr, "Error in mpfr_frac (x, x, %s) with\nx = ",
+ mpfr_print_rnd_mode (rnd));
+ mpfr_add (tmp, ip, fp, GMP_RNDZ);
+ mpfr_out_str (stderr, 2, 0, tmp, GMP_RNDN);
+ fprintf (stderr, "\nGot ");
+ mpfr_out_str (stderr, 2, 0, sum, GMP_RNDN);
+ fprintf (stderr, "\ninstead of ");
+ mpfr_out_str (stderr, 2, 0, fp, GMP_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (fp2);
+ mpfr_clear (dst);
+ mpfr_clear (tmp);
+ mpfr_clear (sum);
+}
+
+static void
+check1 (mpfr_ptr ip, mpfr_ptr fp)
+{
+ mp_rnd_t rnd;
+
+ for (rnd = 0; rnd < 4; rnd++)
+ {
+ check0 (ip, fp, PMAX, rnd);
+ check0 (ip, fp, 70, rnd);
+ mpfr_neg (fp, fp, GMP_RNDN);
+ mpfr_neg (ip, ip, GMP_RNDN);
+ check0 (ip, fp, PMAX, rnd);
+ check0 (ip, fp, 70, rnd);
+ mpfr_neg (fp, fp, GMP_RNDN);
+ mpfr_neg (ip, ip, GMP_RNDN);
+ }
+}
+
+int
+main (void)
+{
+ mpfr_t ip, fp;
+ int ni, nf1, nf2;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (ip, PIP);
+ mpfr_init2 (fp, PFP);
+
+ for (ni = -1; ni < PIP; ni++)
+ {
+ if (ni <= 0)
+ { /* ni + 1 */
+ mpfr_set_si (ip, ni, GMP_RNDN);
+ mpfr_add_ui (ip, ip, 1, GMP_RNDN);
+ }
+ else
+ { /* 2^ni + 1 */
+ mpfr_set_ui (ip, 1, GMP_RNDN);
+ mpfr_mul_2ui (ip, ip, ni, GMP_RNDN);
+ mpfr_add_ui (ip, ip, 1, GMP_RNDN);
+ }
+
+ mpfr_set_ui (fp, 0, GMP_RNDN);
+ check1 (ip, fp);
+
+ for (nf1 = 1; nf1 < PFP; nf1++)
+ {
+ mpfr_set_ui (fp, 1, GMP_RNDN);
+ mpfr_div_2ui (fp, fp, nf1, GMP_RNDN);
+ check1 (ip, fp);
+ for (nf2 = 1; nf2 < PFP; nf2 += 23)
+ {
+ mpfr_set_ui (fp, 1, GMP_RNDN);
+ mpfr_div_2ui (fp, fp, nf2, GMP_RNDN);
+ mpfr_add_ui (fp, fp, 1, GMP_RNDN);
+ mpfr_div_2ui (fp, fp, nf1, GMP_RNDN);
+ check1 (ip, fp);
+ }
+ }
+ }
+
+ mpfr_set_ui (ip, 1, GMP_RNDN);
+ mpfr_div_ui (ip, ip, 0, GMP_RNDN);
+ mpfr_set_ui (fp, 0, GMP_RNDN);
+ check1 (ip, fp); /* test infinities */
+
+ mpfr_clear (ip);
+ mpfr_clear (fp);
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tgamma.c b/mpfr/tests/tgamma.c
new file mode 100644
index 000000000..f863a2990
--- /dev/null
+++ b/mpfr/tests/tgamma.c
@@ -0,0 +1,103 @@
+/* mpfr_tgamma -- test file for gamma function
+
+Copyright 2001, 2002 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 "mpfr.h"
+#include "mpfr-test.h"
+
+int mpfr_gamma (mpfr_ptr, mpfr_srcptr, mp_rnd_t);
+
+int
+main (void)
+{
+ unsigned int prec, err, yprec, n;
+ mp_rnd_t rnd;
+ mpfr_t x, y, z;
+ double xd, yd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_d (x, xd = 1.0762904832837976166, GMP_RNDN);
+ mpfr_gamma (y, x, GMP_RNDN);
+ if (mpfr_get_d (y, GMP_RNDN) != (yd = 0.96134843256452096050))
+ {
+ fprintf (stderr, "mpfr_gamma(%1.20e) is wrong: expected %1.20e, got %1.20e\n",
+ xd, yd, mpfr_get_d (y, GMP_RNDN));
+ exit (1);
+ }
+
+
+ mpfr_set_d (x, xd = 9.23709516716202383435e-01, GMP_RNDN);
+ mpfr_gamma (y, x, GMP_RNDN);
+ if (mpfr_get_d (y, GMP_RNDN) != (yd = 1.0502315560291053398))
+ {
+ fprintf (stderr, "mpfr_gamma(%1.20e) is wrong: expected %1.20e, got %1.20e\n",
+ xd, yd, mpfr_get_d (y, GMP_RNDN));
+ 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_gamma (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_gamma (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/tget_d.c b/mpfr/tests/tget_d.c
index f6614cfef..3126fbea2 100644
--- a/mpfr/tests/tget_d.c
+++ b/mpfr/tests/tget_d.c
@@ -40,15 +40,7 @@ check_denorms ()
mpfr_init2 (x, BITS_PER_MP_LIMB);
- for (rnd_mode = 0; rnd_mode <= 3; rnd_mode++)
- {
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode (rnd_mode);
-#else
- if (rnd_mode)
- break; /* second iteration */
rnd_mode = GMP_RNDN;
-#endif
for (k = -17; k <= 17; k += 2)
{
d = k * DBL_MIN; /* k * 2^(-1022) */
@@ -71,7 +63,6 @@ check_denorms ()
mpfr_div_2exp (x, x, 1, GMP_RNDN);
}
}
- }
mpfr_clear (x);
return fail;
@@ -81,94 +72,8 @@ int
main (void)
{
-#ifdef MPFR_HAVE_FESETROUND
-
- mpfr_t half, x, y;
- mp_rnd_t rnd_mode;
-
-#endif
-
mpfr_test_init ();
-#ifdef MPFR_HAVE_FESETROUND
-
- mpfr_init2(half, 2);
- mpfr_set_ui(half, 1, GMP_RNDZ);
- mpfr_div_2ui(half, half, 1, GMP_RNDZ); /* has exponent 0 */
-
- mpfr_init2(x, 128);
- mpfr_init2(y, 128);
-
- for (rnd_mode = 0; rnd_mode <= 3; rnd_mode++)
- {
- 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);
- /* x = 1/2 +/- 1/2^(1+i) */
- 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);
- /* y = 1/2 +/- 1/2^(1+i) +/- 1/2^(1+j) */
- exp = (LONG_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 ((LONG_RAND() / 1024) & 1)
- {
- c = mpfr_get_d (y, rnd_mode);
- f = "mpfr_get_d";
- }
- else
- {
- exp = (LONG_RAND() % 47) - 23;
- c = mpfr_get_d3 (y, exp, rnd_mode);
- f = "mpfr_get_d3";
- 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 %.25Le instead of %.25Le\n"
- "Difference: %.19e\n",
- f, i, si, j, sj, rnd_mode, exp,
- (long double) c, (long double) d, d - c);
- exit (1);
- }
- }
- }
- }
-
- mpfr_clear(half);
- mpfr_clear(x);
- mpfr_clear(y);
-
-#endif
-
if (check_denorms ())
exit (1);
diff --git a/mpfr/tests/tget_str.c b/mpfr/tests/tget_str.c
index c0852741b..5a4353b14 100644
--- a/mpfr/tests/tget_str.c
+++ b/mpfr/tests/tget_str.c
@@ -25,42 +25,48 @@ MA 02111-1307, USA. */
#include <string.h>
#include <time.h>
#include "gmp.h"
+#include "gmp-impl.h"
#include "mpfr.h"
-#ifdef MPFR_HAVE_FESETROUND
#include "mpfr-test.h"
-#endif
-void check _PROTO((double, mp_rnd_t));
-void check3 _PROTO((double, mp_rnd_t, char *));
-void check_small _PROTO((void));
+void check _PROTO((double, mp_rnd_t));
+void check3 _PROTO((double, mp_rnd_t, char *));
+void check_small _PROTO((void));
+void check_large _PROTO((void));
+void check_special _PROTO((int, mp_prec_t));
void
check (double d, mp_rnd_t rnd)
{
- mpfr_t x; char *str; mp_exp_t e;
+ 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);
- 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);
+ mpfr_clear (x);
+ (*__gmp_free_func) (str, strlen (str) + 1);
}
void
check3 (double d, mp_rnd_t rnd, char *res)
{
- mpfr_t x; char *str; mp_exp_t e;
+ 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))
+ 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);
+ exit (1);
}
mpfr_clear (x);
- free (str);
+ (*__gmp_free_func) (str, strlen (str) + 1);
}
void
@@ -69,25 +75,111 @@ check_small (void)
mpfr_t x;
char *s;
mp_exp_t e;
+ mp_prec_t p;
- mpfr_init(x);
+ mpfr_init (x);
+
+ mpfr_set_prec (x, 20);
+ mpfr_set_ui (x, 2, GMP_RNDN);
+ mpfr_sub_one_ulp (x, GMP_RNDD);
+ s = mpfr_get_str (NULL, &e, 4, 2, x, GMP_RNDU);
+ if (strcmp (s, "20") || (e != 1))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 2- rounded up with 2 digits in base 4\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ /* check n_digits=0 */
+ mpfr_set_prec (x, 5);
+ mpfr_set_ui (x, 17, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 3, 0, x, GMP_RNDN);
+ (*__gmp_free_func) (s, strlen (s) + 1);
+ s = mpfr_get_str (NULL, &e, 36, 0, x, GMP_RNDN);
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_si (x, -1, GMP_RNDN);
+ mpfr_div_2exp (x, x, 63, GMP_RNDN); /* x = -2^(-63) */
+ mpfr_add_ui (x, x, 1, GMP_RNDN); /* x = 1 - 2^(-63) */
+ mpfr_mul_2exp (x, x, 32, GMP_RNDN); /* x = 2^32 - 2^(-31) */
+ s = mpfr_get_str (NULL, &e, 3, 21, x, GMP_RNDU);
+ if (strcmp (s, "102002022201221111211") || (e != 21))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 2^32-2^(-31) rounded up with 21 digits in base 3\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+ s = mpfr_get_str (NULL, &e, 3, 20, x, GMP_RNDU);
+ if (strcmp (s, "10200202220122111122") || (e != 21))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 2^32-2^(-31) rounded up with 20 digits in base 3\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ for (p=4; p<=200; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_d (x, 6.5, GMP_RNDN);
+
+ s = mpfr_get_str (NULL, &e, 6, 2, x, GMP_RNDN);
+ if (strcmp (s, "10") || (e != 2))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 6.5 rounded to nearest with 2 digits in base 6\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_add_one_ulp (x, GMP_RNDU);
+ s = mpfr_get_str (NULL, &e, 6, 2, x, GMP_RNDN);
+ if (strcmp (s, "11") || (e != 2))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 6.5+ rounded to nearest with 2 digits in base 6\n");
+ fprintf(stderr, "got %se%d instead of 11e2\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_set_d (x, 6.5, GMP_RNDN);
+ mpfr_sub_one_ulp (x, GMP_RNDU);
+ s = mpfr_get_str (NULL, &e, 6, 2, x, GMP_RNDN);
+ if (strcmp (s, "10") || (e != 2))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 6.5- rounded to nearest with 2 digits in base 6\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_ui (x, 7, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 2, 2, x, GMP_RNDU);
+ if (strcmp (s, "10") || (e != 4))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 7 rounded up with 2 bits should give 0.10e3 instead of 0.%s*2^%d\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
/* problem found by Fabrice Rouillier */
- mpfr_set_prec(x, 63);
- mpfr_set_d(x, 5e14, GMP_RNDN);
- s = mpfr_get_str(NULL, &e, 10, 18, x, GMP_RNDU);
- free(s);
+ mpfr_set_prec (x, 63);
+ mpfr_set_d (x, 5e14, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 18, x, GMP_RNDU);
+ (*__gmp_free_func) (s, strlen (s) + 1);
/* bug found by Johan Vervloet */
- mpfr_set_prec(x, 6);
- mpfr_set_d(x, 688.0, GMP_RNDN);
- s = mpfr_get_str(NULL, &e, 2, 4, x, GMP_RNDU);
- if (strcmp(s, "1011") || (e!=10)) {
- fprintf(stderr, "Error in mpfr_get_str: 688 printed up to 4 bits should give 1.011e9\ninstead of ");
- mpfr_out_str(stderr, 2, 4, x, GMP_RNDU); putchar('\n');
- exit(1);
+ mpfr_set_prec (x, 6);
+ mpfr_set_d (x, 688.0, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 2, 4, x, GMP_RNDU);
+ if (strcmp (s, "1011") || (e != 10))
+ {
+ fprintf(stderr, "Error in mpfr_get_str: 688 printed up to 4 bits should give 1.011e9\ninstead of ");
+ mpfr_out_str (stderr, 2, 4, x, GMP_RNDU);
+ putchar ('\n');
+ exit (1);
}
- free(s);
+ (*__gmp_free_func) (s, strlen (s) + 1);
mpfr_set_prec (x, 38);
mpfr_set_str_raw (x, "1.0001110111110100011010100010010100110e-6");
@@ -97,33 +189,228 @@ check_small (void)
fprintf (stderr, "Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e);
exit (1);
}
- free (s);
+ (*__gmp_free_func) (s, strlen (s) + 1);
- mpfr_clear(x);
+ mpfr_set_prec (x, 53);
+ mpfr_set_str_raw (x, "0.11010111011101100010000100010101110001000000010111001E454");
+ s = mpfr_get_str (NULL, &e, 19, 12, x, GMP_RNDU);
+ if (strcmp (s, "b1cgfa4gha0h") || (e != 107))
+ {
+ fprintf (stderr, "Error in mpfr_get_str (4): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_clear (x);
+}
+
+/* bugs found by Alain Delplanque */
+void
+check_large (void)
+{
+ mpfr_t x;
+ char *s, s1[5];
+ mp_exp_t e;
+
+ mpfr_init2 (x, 3322);
+
+ mpfr_set_str (x, "1191329373584454902963446991955720175286125252740279117456759314255666164381287629208894396284118106237638151734612401308413932016367151750198408279132283416239620735553421709762103354760976935178688281437433241547811421242765954526730340691899980570938762461672035935889779270816874853084356516609798927268594581372938379179977284655733836697143371494124951472644806260698117993938473190235354211767432206599326712003738743333323828631552259337062810367696590666369938765453594007585414315766344508757501018473199271112399659232815512649664511600328487149681659834297019266913593296230601165179075868421038664499758175796688586740720299441958650674273232702130590391453727085546110092041664691328503389878595591936541740247297124581446185876972120895955381254307651782007674810632305250114384523950982647480117154909223816904645463873617234552025814930741687826251074736645666685135716209232607981620388028775931067573127720041282084050501933636962829753889114577560279721743036737227562312131426923", 10, GMP_RNDN);
+ mpfr_div_2exp (x, x, 4343, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, GMP_RNDN);
+ if (s[999] != '1') /* s must be 5.04383...689071e-309 */
+ {
+ fprintf (stderr, "Error in check_large: expected '689071', got '%s'\n",
+ s + 994);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_mul_2exp (x, x, 4343, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDN);
+ if (strcmp (s, "12") || (e != 1000))
+ {
+ fprintf (stderr, "Error in check_large: expected 0.12e1000\n");
+ fprintf (stderr, "got %se%d\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_set_nan (x);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, GMP_RNDN);
+ if (strcmp (s, "NaN"))
+ {
+ fprintf (stderr, "Error for NaN\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_get_str (s1, &e, 10, 1000, x, GMP_RNDN);
+
+ mpfr_set_inf (x, 1);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, GMP_RNDN);
+ if (strcmp (s, "Inf"))
+ {
+ fprintf (stderr, "Error for Inf\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_get_str (s1, &e, 10, 1000, x, GMP_RNDN);
+
+ mpfr_set_inf (x, -1);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, GMP_RNDN);
+ if (strcmp (s, "-Inf"))
+ {
+ fprintf (stderr, "Error for -Inf\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_get_str (s1, &e, 10, 1000, x, GMP_RNDN);
+
+ mpfr_set_ui (x, 0, GMP_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDN);
+ if (e != 0 || strcmp (s, "00"))
+ {
+ fprintf (stderr, "Error for 0.0\n");
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+ mpfr_get_str (s1, &e, 10, 2, x, GMP_RNDN);
+
+ mpfr_neg (x, x, GMP_RNDN); /* -0.0 */
+ s = mpfr_get_str (NULL, &e, 10, 2, x, GMP_RNDN);
+ if (e != 0 || strcmp (s, "-00"))
+ {
+ fprintf (stderr, "Error for -0.0\n");
+ fprintf (stderr, "got %se%d\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+ mpfr_get_str (s1, &e, 10, 2, x, GMP_RNDN);
+
+ mpfr_clear (x);
+}
+
+#define MAX_DIGITS 100
+
+void
+check_special (int b, mp_prec_t p)
+{
+ mpfr_t x;
+ int i, j;
+ char s[MAX_DIGITS + 2], s2[MAX_DIGITS + 2], c;
+ mp_exp_t e;
+ mp_rnd_t r;
+ size_t m;
+
+ s2[0] = '1';
+ for (i=1; i<MAX_DIGITS+2; i++)
+ s2[i] = '0';
+
+ mpfr_init2 (x, p);
+ mpfr_set_ui (x, 1, GMP_RNDN);
+ for (i=1; i<100 && mpfr_mul_ui (x, x, b, GMP_RNDN) == 0; i++)
+ {
+ /* x = b^i (exact) */
+ for (r=0; r<4; r++)
+ for (m=(i < 3) ? 2 : i-1; m<=i+1; m++)
+ {
+ mpfr_get_str (s, &e, b, m, x, r);
+ /* s should be 1 followed by (m-1) zeros, and e should be i+1 */
+ if ((e != i+1) || strncmp (s, s2, m) != 0)
+ {
+ fprintf (stderr, "Error in mpfr_get_str for %u^%u\n", b, i);
+ exit (1);
+ }
+ }
+ if (mpfr_sub_ui (x, x, 1, GMP_RNDN) != 0)
+ break;
+ /* now x = b^i-1 (exact) */
+ for (r=0; r<4; r++)
+ if (i >= 2)
+ {
+ mpfr_get_str (s, &e, b, i, x, r);
+ /* should be i times (b-1) */
+ c = (b <= 10) ? '0' + b - 1 : 'a' + (b - 11);
+ for (j=0; (j < i) && (s[j] == c); j++);
+ if ((j < i) || (e != i))
+ {
+ fprintf (stderr, "Error in mpfr_get_str for %u^%u-1\n", b, i);
+ fprintf (stderr, "got 0.%s*2^%d\n", s, (int) e);
+ exit (1);
+ }
+ }
+ if (i >= 3)
+ {
+ mpfr_get_str (s, &e, b, i - 1, x, GMP_RNDU);
+ /* should be b^i */
+ if ((e != i+1) || strncmp (s, s2, i - 1) != 0)
+ {
+ fprintf (stderr, "Error in mpfr_get_str for %u^%u-1\n", b, i);
+ fprintf (stderr, "got 0.%s*2^%d\n", s, (int) e);
+ exit (1);
+ }
+ }
+
+ mpfr_add_ui (x, x, 1, GMP_RNDN);
+ }
+ mpfr_clear (x);
}
int
main (int argc, char *argv[])
{
-#ifdef MPFR_HAVE_FESETROUND
- int i;
- double d;
-
- SEED_RAND (time(NULL));
- for (i=0;i<100000;i++) {
- do { d = drand(); } while (isnan(d));
- check(d, GMP_RNDN);
- }
-#endif
- check_small();
- check3(4.059650008e-83, GMP_RNDN, "40597");
- check3(-6.606499965302424244461355e233, GMP_RNDN, "-66065");
- check3(-7.4, GMP_RNDN, "-74000");
- check3(0.997, GMP_RNDN, "99700");
- check3(-4.53063926135729747564e-308, GMP_RNDN, "-45306");
- check3(2.14478198760196000000e+16, GMP_RNDN, "21448");
- check3(7.02293374921793516813e-84, GMP_RNDN, "70229");
- check3(-6.7274500420134077e-87, GMP_RNDN, "-67275");
+ int b;
+ mpfr_t x;
+ mp_rnd_t r;
+ char s[MAX_DIGITS + 2];
+ mp_exp_t e, f;
+ size_t m;
+ mp_prec_t p;
+
+ tests_start_mpfr ();
+
+ check_small ();
+
+ for (p=2; p<=MAX_DIGITS; p++)
+ for (b=2; b<=36; b++)
+ check_special (b, p);
+
+ mpfr_init2 (x, MAX_DIGITS);
+ for (m=2; m<=MAX_DIGITS; m++)
+ {
+ mpfr_random (x);
+ for (e=-10; e<=10; e++)
+ {
+ mpfr_set_exp (x, (e == -10) ? mpfr_get_emin () :
+ ((e == 10) ? mpfr_get_emax () : e));
+ for (b=2; b<=36; b++)
+ for (r=0; r<4; r++)
+ mpfr_get_str (s, &f, b, m, x, r);
+ }
+ }
+ mpfr_clear (x);
+
+ check_large ();
+ check3 (4.059650008e-83, GMP_RNDN, "40597");
+ check3 (-6.606499965302424244461355e233, GMP_RNDN, "-66065");
+ check3 (-7.4, GMP_RNDN, "-74000");
+ check3 (0.997, GMP_RNDN, "99700");
+ check3 (-4.53063926135729747564e-308, GMP_RNDN, "-45306");
+ check3 (2.14478198760196000000e+16, GMP_RNDN, "21448");
+ check3 (7.02293374921793516813e-84, GMP_RNDN, "70229");
+
+ check3 (-6.7274500420134077e-87, GMP_RNDN, "-67275");
+ check3 (-6.7274500420134077e-87, GMP_RNDZ, "-67274");
+ check3 (-6.7274500420134077e-87, GMP_RNDU, "-67274");
+ check3 (-6.7274500420134077e-87, GMP_RNDD, "-67275");
+
+ check3 (6.7274500420134077e-87, GMP_RNDN, "67275");
+ check3 (6.7274500420134077e-87, GMP_RNDZ, "67274");
+ check3 (6.7274500420134077e-87, GMP_RNDU, "67275");
+ check3 (6.7274500420134077e-87, GMP_RNDD, "67274");
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/thyperbolic.c b/mpfr/tests/thyperbolic.c
index 3a0f4eba5..c827750db 100644
--- a/mpfr/tests/thyperbolic.c
+++ b/mpfr/tests/thyperbolic.c
@@ -23,6 +23,7 @@ MA 02111-1307, USA. */
#include "gmp-impl.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
int check_O _PROTO((void));
@@ -596,11 +597,13 @@ check_O (void)
int
main(void)
{
+tests_start_mpfr ();
if (check_INF())printf("Error in evaluation of INF\n");
if (check_NAN())printf("Error in evaluation of NAN\n");
/*if (check_O())printf("Error in evaluation of composition hyperbolic function\n");*/
+tests_end_mpfr ();
return(0);
diff --git a/mpfr/tests/thypot.c b/mpfr/tests/thypot.c
index e023f6d3f..c567f6c1d 100644
--- a/mpfr/tests/thypot.c
+++ b/mpfr/tests/thypot.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_hypot.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -31,6 +31,41 @@ MA 02111-1307, USA. */
#define TEST_FUNCTION mpfr_hypot
+static void
+test_large (void)
+{
+ mpfr_t x, y, z, t;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+
+ mpfr_set_ui (x, 21, GMP_RNDN);
+ mpfr_set_ui (y, 28, GMP_RNDN);
+ mpfr_set_ui (z, 35, GMP_RNDN);
+
+ mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, GMP_RNDN);
+ mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, GMP_RNDN);
+ mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, GMP_RNDN);
+
+ mpfr_hypot (t, x, y, GMP_RNDN);
+ if (mpfr_cmp (z, t))
+ {
+ fprintf (stderr, "Error in test_large: got\n");
+ mpfr_out_str (stderr, 2, 0, t, GMP_RNDN);
+ fprintf (stderr, "\ninstead of\n");
+ mpfr_out_str (stderr, 2, 0, z, GMP_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
int
main (int argc, char *argv[])
{
@@ -39,6 +74,8 @@ main (int argc, char *argv[])
mpfr_t x1, x2, y, z, t;
int inexact, compare, compare2;
+ tests_start_mpfr ();
+
mpfr_init (x1);
mpfr_init (x2);
mpfr_init (y);
@@ -124,9 +161,8 @@ main (int argc, char *argv[])
mpfr_clear (z);
mpfr_clear (t);
+ test_large ();
+
+ tests_end_mpfr ();
return 0;
}
-
-
-
-
diff --git a/mpfr/tests/tisnan.c b/mpfr/tests/tisnan.c
index 45478e9bd..bed502153 100644
--- a/mpfr/tests/tisnan.c
+++ b/mpfr/tests/tisnan.c
@@ -23,12 +23,15 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
int
main (void)
{
mpfr_t x;
+ tests_start_mpfr ();
+
mpfr_init (x);
/* check +infinity gives non-zero for mpfr_inf_p only */
@@ -94,5 +97,6 @@ main (void)
mpfr_clear (x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tlog.c b/mpfr/tests/tlog.c
index efed820ca..168d6d802 100644
--- a/mpfr/tests/tlog.c
+++ b/mpfr/tests/tlog.c
@@ -67,10 +67,6 @@ check1 (double a, mp_rnd_t rnd_mode, double res1, int ck, int max_ulp)
int diff=0;
/* ck=1 iff res1 is certified correct */
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (ck==0 && res1==0.0) res1=log(a);
mpfr_init2(ta, 53);
mpfr_init2(tres, 53);
mpfr_set_d(ta, a, GMP_RNDN);
@@ -80,17 +76,10 @@ check1 (double a, mp_rnd_t rnd_mode, double res1, int ck, int max_ulp)
if (res1!=res2 && (!isnan(res1) || !isnan(res2))) {
diff = ulp(res1,res2);
- if (ck) {
- printf("mpfr_log failed for a=%1.20e, rnd_mode=%s\n", a,
- mpfr_print_rnd_mode(rnd_mode));
- printf("correct result is %1.20e\n mpfr_log gives %1.20e (%d ulp)\n",res1,res2,ulp(res1,res2));
- exit(1);
- }
- else if (diff>max_ulp) {
- printf("mpfr_log differs from libm.a for a=%1.20e, rnd_mode=%s\n", a,
- mpfr_print_rnd_mode(rnd_mode));
- printf(" double calculus gives %1.20e\n mpfr_log gives %1.20e (%d ulp)\n",res1,res2,ulp(res1,res2));
- }
+ printf("mpfr_log failed for a=%1.20e, rnd_mode=%s\n", a,
+ mpfr_print_rnd_mode(rnd_mode));
+ printf("correct result is %1.20e\n mpfr_log gives %1.20e (%d ulp)\n",res1,res2,ulp(res1,res2));
+ exit(1);
}
if (!isnan(res1) || !isnan(res2))
return diff;
@@ -272,16 +261,18 @@ main (int argc, char *argv[])
int N = 0;
double d;
+ tests_start_mpfr ();
+
SEED_RAND (time(NULL));
if (argc==4) { /* tlog x prec rnd */
check3(atof(argv[1]), atoi(argv[2]), atoi(argv[3]));
- return 0;
+ goto done;
}
if (argc==3) { /* tlog N p : N calculus with precision p*/
printf("Doing %d random tests in %d precision\n",atoi(argv[1]),atoi(argv[2]));
slave(atoi(argv[1]),atoi(argv[2]));
- return 0;
+ goto done;
}
if (argc==2) { /* tlog N: N tests with random double's */
@@ -359,5 +350,7 @@ main (int argc, char *argv[])
test_generic (2, 100, 40);
+ done:
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tlog10.c b/mpfr/tests/tlog10.c
index 48874218e..b587b68c3 100644
--- a/mpfr/tests/tlog10.c
+++ b/mpfr/tests/tlog10.c
@@ -35,6 +35,8 @@ main (int argc, char *argv[])
mpfr_t x, y;
unsigned int n;
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
/* check log10(10^n)=n */
@@ -56,5 +58,6 @@ main (int argc, char *argv[])
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tlog1p.c b/mpfr/tests/tlog1p.c
index 673990267..5f63b5834 100644
--- a/mpfr/tests/tlog1p.c
+++ b/mpfr/tests/tlog1p.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_log1p.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tsinh.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tlog2.c b/mpfr/tests/tlog2.c
index c3ca6798a..77138586d 100644
--- a/mpfr/tests/tlog2.c
+++ b/mpfr/tests/tlog2.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_log2.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tsinh.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 30);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tmul.c b/mpfr/tests/tmul.c
index ea5f6ced6..c2d348747 100644
--- a/mpfr/tests/tmul.c
+++ b/mpfr/tests/tmul.c
@@ -42,11 +42,12 @@ void check_min _PROTO((void));
/* checks that x*y gives the same results in double
and with mpfr with 53 bits of precision */
-void
+static void
_check (double x, double y, double res, mp_rnd_t rnd_mode, unsigned int px,
unsigned int py, unsigned int pz)
{
- double z1, z2; mpfr_t xx, yy, zz;
+ double z2;
+ mpfr_t xx, yy, zz;
mpfr_init2 (xx, px);
mpfr_init2 (yy, py);
@@ -54,17 +55,11 @@ _check (double x, double y, double res, mp_rnd_t rnd_mode, unsigned int px,
mpfr_set_d(xx, x, rnd_mode);
mpfr_set_d(yy, y, rnd_mode);
mpfr_mul(zz, xx, yy, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- z1 = (res==0.0) ? x*y : res;
z2 = mpfr_get_d1 (zz);
- if (z1!=z2 && (z1>=MINNORM || z1<=-MINNORM)) {
- printf("mpfr_mul ");
- if (res==0.0) printf("differs from libm.a"); else printf("failed");
- printf(" for x=%1.20e y=%1.20e with rnd_mode=%s\n", x, y,
+ if (res != 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));
- printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
+ printf("correct is %1.20e, mpfr_mul gives %1.20e\n", res, z2);
if (res!=0.0) exit(1);
}
mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
@@ -85,7 +80,7 @@ check53 (double x, double y, mp_rnd_t rnd_mode, double z1)
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));
- printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
+ printf("correct result is %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
exit(1);
}
mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
@@ -110,7 +105,7 @@ check24 (float x, float y, mp_rnd_t rnd_mode, float z1)
{
fprintf (stderr, "mpfr_mul failed for x=%1.0f y=%1.0f with prec=24 and"
"rnd=%s\n", x, y, mpfr_print_rnd_mode(rnd_mode));
- fprintf (stderr, "libm.a gives %.10e, mpfr_mul gives %.10e\n", z1, z2);
+ fprintf (stderr, "correct result is gives %.10e, mpfr_mul gives %.10e\n", z1, z2);
exit (1);
}
mpfr_clear(xx);
@@ -351,12 +346,7 @@ check_min(void)
int
main (int argc, char *argv[])
{
-#ifdef MPFR_HAVE_FESETROUND
- double x, y, z;
- int i, prec, rnd_mode;
-
- mpfr_test_init ();
-#endif
+ tests_start_mpfr ();
check_exact ();
check_float ();
@@ -391,21 +381,7 @@ main (int argc, char *argv[])
49, 3, 2, 0.09375);
check_max();
check_min();
-#ifdef MPFR_HAVE_FESETROUND
- SEED_RAND (time(NULL));
- prec = (argc<2) ? 53 : atoi(argv[1]);
- rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
- for (i=0;i<1000000;) {
- x = drand();
- y = drand();
- z = x*y; if (z<0) z=-z;
- if (z<1e+308 && z>1e-308) /* don't test overflow/underflow for now */
- { i++;
- check(x, y, (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode,
- prec, prec, prec, 0.0);
- }
- }
-#endif
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tmul_2exp.c b/mpfr/tests/tmul_2exp.c
index ce3b4fcb3..9b1827bc6 100644
--- a/mpfr/tests/tmul_2exp.c
+++ b/mpfr/tests/tmul_2exp.c
@@ -35,6 +35,8 @@ main (int argc, char *argv[])
{
double x, z; mpfr_t w; unsigned long k;
+ tests_start_mpfr ();
+
mpfr_init2(w, 53);
mpfr_set_inf (w, 1);
@@ -68,5 +70,6 @@ main (int argc, char *argv[])
mpfr_clear(w);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tmul_ui.c b/mpfr/tests/tmul_ui.c
index 7430c05b7..54533d179 100644
--- a/mpfr/tests/tmul_ui.c
+++ b/mpfr/tests/tmul_ui.c
@@ -86,6 +86,8 @@ main (int argc, char *argv[])
unsigned int xprec, yprec, i;
mp_prec_t p;
+ tests_start_mpfr ();
+
for (p=2; p<100; p++)
for (i=1; i<50; i++)
check_inexact (p);
@@ -240,5 +242,6 @@ main (int argc, char *argv[])
mpfr_clear(x); mpfr_clear(y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tout_str.c b/mpfr/tests/tout_str.c
index 050348607..0f1a4cfe6 100644
--- a/mpfr/tests/tout_str.c
+++ b/mpfr/tests/tout_str.c
@@ -37,16 +37,16 @@ void check4 _PROTO((double, mp_rnd_t, int, int));
void check_large _PROTO((void));
void
-check4(double d, mp_rnd_t rnd, int base, int prec)
+check4 (double d, mp_rnd_t rnd, int base, int prec)
{
mpfr_t x;
- mpfr_init2(x, prec);
- mpfr_set_d(x, d, rnd);
- fprintf(fout, "%1.19e base %d rnd %d:\n ", d, base, rnd);
- mpfr_out_str(fout, base, (base==2) ? prec : 0, x, rnd);
- fputc('\n', fout);
- mpfr_clear(x);
+ mpfr_init2 (x, prec);
+ mpfr_set_d (x, d, rnd);
+ fprintf (fout, "%1.19e base %d rnd %d:\n ", d, base, rnd);
+ mpfr_out_str (fout, base, (base == 2) ? prec : 0, x, rnd);
+ fputc ('\n', fout);
+ mpfr_clear (x);
}
void
@@ -68,6 +68,7 @@ check_large (void)
if (strcmp (s, "-12"))
{
fprintf (stderr, "Error in mpfr_get_str for x=-11.5 and rnd=GMP_RNDD\n");
+ fprintf (stderr, "got %s instead of -12\n", s);
free (s);
mpfr_clear (x);
exit (1);
@@ -106,29 +107,35 @@ check_large (void)
int
main (int argc, char *argv[])
{
- int i,N=10000,r,p; double d;
+ int i, N=10000, r, p;
+ double d;
- check_large();
+ check_large ();
/* with no argument: prints to /dev/null,
tout_str N: prints N tests to stdout */
- if (argc==1) fout=fopen("/dev/null", "w");
- else { fout=stdout; N=atoi(argv[1]); }
- check(-1.37247529013405550000e+15, GMP_RNDN, 7);
- check(-1.5674376729569697500e+15, GMP_RNDN, 19);
- check(-5.71262771772792640000e-79, GMP_RNDU, 16);
- check(-0.0, GMP_RNDU, 7);
- check(-4.5306392613572974756e-308, GMP_RNDN, 8);
- check(-6.7265890111403371523e-165, GMP_RNDN, 4);
- check(-1.3242553591261807653e+156, GMP_RNDN, 16);
- check(-6.606499965302424244461355e233, GMP_RNDN, 10);
- check4(1.0, GMP_RNDN, 10, 120);
- check(1.0, GMP_RNDU, 10);
- check(4.059650008e-83, GMP_RNDN, 10);
- check(-7.4, GMP_RNDN, 10);
- check(0.997, GMP_RNDN, 10);
- check(-4.53063926135729747564e-308, GMP_RNDN, 10);
- check(2.14478198760196000000e+16, GMP_RNDN, 10);
- check(7.02293374921793516813e-84, GMP_RNDN, 10);
+ if (argc==1)
+ fout = fopen ("/dev/null", "w");
+ else
+ {
+ fout = stdout;
+ N = atoi (argv[1]);
+ }
+ check (-1.37247529013405550000e+15, GMP_RNDN, 7);
+ check (-1.5674376729569697500e+15, GMP_RNDN, 19);
+ check (-5.71262771772792640000e-79, GMP_RNDU, 16);
+ check (-0.0, GMP_RNDU, 7);
+ check (-4.5306392613572974756e-308, GMP_RNDN, 8);
+ check (-6.7265890111403371523e-165, GMP_RNDN, 4);
+ check (-1.3242553591261807653e+156, GMP_RNDN, 16);
+ check (-6.606499965302424244461355e233, GMP_RNDN, 10);
+ check4 (1.0, GMP_RNDN, 10, 120);
+ check (1.0, GMP_RNDU, 10);
+ check (4.059650008e-83, GMP_RNDN, 10);
+ check (-7.4, GMP_RNDN, 10);
+ check (0.997, GMP_RNDN, 10);
+ check (-4.53063926135729747564e-308, GMP_RNDN, 10);
+ check (2.14478198760196000000e+16, GMP_RNDN, 10);
+ check (7.02293374921793516813e-84, GMP_RNDN, 10);
/* random tests */
SEED_RAND (time(NULL));
@@ -148,5 +155,7 @@ main (int argc, char *argv[])
check (d, r, p);
}
+ fclose (fout);
+
return 0;
}
diff --git a/mpfr/tests/tpow.c b/mpfr/tests/tpow.c
index dd2a1202c..2d5d80c75 100644
--- a/mpfr/tests/tpow.c
+++ b/mpfr/tests/tpow.c
@@ -26,8 +26,9 @@ MA 02111-1307, USA. */
#include "mpfr-impl.h"
#include "mpfr-test.h"
-void check_pow_ui _PROTO ((void));
+void check_pow_ui _PROTO ((void));
void check_inexact _PROTO ((mp_prec_t));
+void special _PROTO ((void));
void
check_pow_ui (void)
@@ -118,6 +119,69 @@ check_inexact (mp_prec_t p)
}
}
+ /* check exact power */
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (y, p);
+ mpfr_set_prec (z, p);
+ mpfr_set_d (x, 4.0, GMP_RNDN);
+ mpfr_set_d (y, 0.5, GMP_RNDN);
+ mpfr_pow (z, x, y, GMP_RNDZ);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+void
+special ()
+{
+ mpfr_t x, y, z, t;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_init2 (z, 53);
+ mpfr_init2 (t, 2);
+ mpfr_set_d (t, -0.5, GMP_RNDN);
+
+ mpfr_set_d (x, 5.68824667828621954868e-01, GMP_RNDN);
+ mpfr_set_d (y, 9.03327850535952658895e-01, GMP_RNDN);
+ mpfr_pow (z, x, y, GMP_RNDZ);
+ if (mpfr_get_d1 (z) != 0.60071044650456473235)
+ {
+ fprintf (stderr, "Error in mpfr_pow for prec=53, rnd=GMP_RNDZ\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 30);
+ mpfr_set_prec (y, 30);
+ mpfr_set_prec (z, 30);
+ mpfr_set_str (x, "1.00000000001010111110001111011e1", 2, GMP_RNDN);
+ mpfr_pow (z, x, t, GMP_RNDN);
+ mpfr_set_str (y, "1.01101001111010101110000101111e-1", 2, GMP_RNDN);
+ if (mpfr_cmp (z, y))
+ {
+ fprintf (stderr, "Error in mpfr_pow for prec=30, rnd=GMP_RNDN\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 21);
+ mpfr_set_prec (y, 21);
+ mpfr_set_prec (z, 21);
+ mpfr_set_str (x, "1.11111100100001100101", 2, GMP_RNDN);
+ mpfr_pow (z, x, t, GMP_RNDZ);
+ mpfr_set_str (y, "1.01101011010001100000e-1", 2, GMP_RNDN);
+ if (mpfr_cmp (z, y))
+ {
+ fprintf (stderr, "Error in mpfr_pow for prec=21, rnd=GMP_RNDZ\n");
+ fprintf (stderr, "Expected ");
+ 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);
@@ -129,10 +193,16 @@ main (void)
{
mp_prec_t p;
+ tests_start_mpfr ();
+
+ special ();
+
check_pow_ui ();
for (p=2; p<100; p++)
check_inexact (p);
+ tests_end_mpfr ();
return 0;
}
+
diff --git a/mpfr/tests/tpow3.c b/mpfr/tests/tpow3.c
index b9cb9013a..50a1e18ff 100644
--- a/mpfr/tests/tpow3.c
+++ b/mpfr/tests/tpow3.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_pow.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -35,6 +35,9 @@ main (int argc, char *argv[])
{
mpfr_t x, y, z, ax;
long int iy;
+
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (ax);
mpfr_init2 (y,sizeof(unsigned long int)*CHAR_BIT);
@@ -420,5 +423,6 @@ main (int argc, char *argv[])
mpfr_clear (z);
mpfr_clear (ax);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/trandom.c b/mpfr/tests/trandom.c
index 70e30a4f2..eb452a82d 100644
--- a/mpfr/tests/trandom.c
+++ b/mpfr/tests/trandom.c
@@ -26,6 +26,7 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
void test_random _PROTO ((unsigned long, unsigned long, int));
void test_random2 _PROTO ((unsigned long, unsigned long, int));
@@ -40,7 +41,7 @@ test_random (unsigned long nbtests, unsigned long prec, int verbose)
mpfr_init2(x, prec);
- size_tab = (nbtests < 1000 ? nbtests / 50 : 20);
+ size_tab = (nbtests >= 1000 ? nbtests / 50 : 20);
tab = (int *) malloc (size_tab * sizeof(int));
for (k = 0; k < size_tab; ++k) tab[k] = 0;
@@ -56,7 +57,7 @@ test_random (unsigned long nbtests, unsigned long prec, int verbose)
av /= nbtests;
var = (var /nbtests) - av*av;
- th = (double)nbtests / size_tab;
+ th = (double) nbtests / size_tab;
printf("Average = %.5f\nVariance = %.5f\n", av, var);
printf("Repartition for random. Each integer should be close to %d.\n",
@@ -80,24 +81,40 @@ test_random (unsigned long nbtests, unsigned long prec, int verbose)
void
test_random2 (unsigned long nbtests, unsigned long prec, int verbose)
{
- mpfr_t x;
- int *tab, size_tab, k;
+ mpfr_t x;
+ int *tab, size_tab, k, sh, xn;
double d, av = 0, var = 0, chi2 = 0, th;
- mpfr_init2(x, prec);
+ mpfr_init2 (x, prec);
+ xn = 1 + (prec - 1) / mp_bits_per_limb;
+ sh = xn * mp_bits_per_limb - prec;
- size_tab = (nbtests < 1000 ? nbtests / 50 : 20);
+ size_tab = (nbtests >= 1000 ? nbtests / 50 : 20);
tab = (int *) malloc (size_tab * sizeof(int));
for (k = 0; k < size_tab; ++k) tab[k] = 0;
for (k = 0; k < nbtests; k++) {
- mpfr_random2 (x, MPFR_ABSSIZE(x), 0);
+ mpfr_random2 (x, xn, 0);
+ /* check that lower bits are zero */
+ if (MPFR_MANT(x)[0] & ((MP_LIMB_T_ONE << sh) - MP_LIMB_T_ONE))
+ {
+ fprintf (stderr, "Error: mpfr_random2() returns invalid numbers:\n");
+ mpfr_print_binary (x); putchar ('\n');
+ exit (1);
+ }
+ /* check that exponent is in correct range */
+ if (mpfr_get_exp (x) != 0)
+ {
+ fprintf (stderr, "Error: mpfr_random2 (.., .., 0) does not return a 0 exponent:\n");
+ mpfr_print_binary (x); putchar ('\n');
+ exit (1);
+ }
d = mpfr_get_d1 (x); av += d; var += d*d;
if (d < 1)
tab[(int)(size_tab * d)]++;
}
- mpfr_clear(x);
+ mpfr_clear (x);
if (!verbose) { free(tab); return; }
av /= nbtests;
@@ -124,13 +141,15 @@ void
test_urandomb (unsigned long nbtests, unsigned long prec, int verbose)
{
mpfr_t x;
- int *tab, size_tab, k;
+ int *tab, size_tab, k, sh, xn;
gmp_randstate_t state;
double d, av = 0, var = 0, chi2 = 0, th;
- mpfr_init2(x, prec);
+ mpfr_init2 (x, prec);
+ xn = 1 + (prec - 1) / mp_bits_per_limb;
+ sh = xn * mp_bits_per_limb - prec;
- size_tab = (nbtests < 1000 ? nbtests / 50 : 20);
+ size_tab = (nbtests >= 1000 ? nbtests / 50 : 20);
tab = (int *) malloc (size_tab * sizeof(int));
for (k = 0; k < size_tab; ++k) tab[k] = 0;
@@ -138,7 +157,14 @@ test_urandomb (unsigned long nbtests, unsigned long prec, int verbose)
gmp_randseed_ui (state, time(NULL));
for (k = 0; k < nbtests; k++) {
- mpfr_urandomb(x, state);
+ mpfr_urandomb (x, state);
+ /* check that lower bits are zero */
+ if (MPFR_MANT(x)[0] & ((MP_LIMB_T_ONE << sh) - MP_LIMB_T_ONE))
+ {
+ fprintf (stderr, "Error: mpfr_urandomb() returns invalid numbers:\n");
+ mpfr_print_binary (x); putchar ('\n');
+ exit (1);
+ }
d = mpfr_get_d1 (x); av += d; var += d*d;
tab[(int)(size_tab * d)]++;
}
@@ -173,14 +199,24 @@ main (int argc, char *argv[])
{
unsigned long nbtests, prec; int verbose = 0;
+ tests_start_mpfr ();
+
if (argc > 1) verbose = 1;
if (argc == 1) { nbtests = 10000; } else nbtests = atoi(argv[1]);
if (argc <= 2) { prec = 1000; } else prec = atoi(argv[2]);
- test_random(nbtests, prec, verbose);
- test_random2(nbtests, prec, verbose);
- test_urandomb(nbtests, prec, verbose);
-
+ test_random (nbtests, prec, verbose);
+ test_random2 (nbtests, prec, verbose);
+ test_urandomb (nbtests, prec, verbose);
+
+ if (argc == 1) /* check also small precision */
+ {
+ test_random (nbtests, 2, 0);
+ test_random2 (nbtests, 2, 0);
+ test_urandomb (nbtests, 2, 0);
+ }
+
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/trint.c b/mpfr/tests/trint.c
index e454c5cd3..0f07b22b9 100644
--- a/mpfr/tests/trint.c
+++ b/mpfr/tests/trint.c
@@ -35,6 +35,8 @@ main (void)
mp_rnd_t r;
int inexact, sign_t;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
mpz_init (z);
@@ -89,5 +91,6 @@ main (void)
mpz_clear (z);
mpfr_clear (t);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tround_prec.c b/mpfr/tests/tround_prec.c
index 67334f64e..9d15abdec 100644
--- a/mpfr/tests/tround_prec.c
+++ b/mpfr/tests/tround_prec.c
@@ -23,12 +23,15 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
int
main (void)
{
mpfr_t x;
+ tests_start_mpfr ();
+
mpfr_init2 (x, 3);
mpfr_set_ui (x, 5, GMP_RNDN);
@@ -75,5 +78,6 @@ main (void)
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset.c b/mpfr/tests/tset.c
index 4d8be37fe..910185050 100644
--- a/mpfr/tests/tset.c
+++ b/mpfr/tests/tset.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_set.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -34,6 +34,8 @@ main (void)
mp_rnd_t rnd;
int inexact, cmp;
+ tests_start_mpfr ();
+
/* check prototypes of mpfr_init_set_* */
inexact = mpfr_init_set_si (x, -1, GMP_RNDN);
inexact = mpfr_init_set (y, x, GMP_RNDN);
@@ -79,5 +81,7 @@ main (void)
mpfr_clear (y);
mpfr_clear (z);
mpfr_clear (u);
+
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset_d.c b/mpfr/tests/tset_d.c
index 50153049c..5fab50807 100644
--- a/mpfr/tests/tset_d.c
+++ b/mpfr/tests/tset_d.c
@@ -19,9 +19,9 @@ 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 <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include <time.h>
#include "gmp.h"
#include "mpfr.h"
@@ -34,6 +34,7 @@ main (int argc, char *argv[])
unsigned long k, n;
double d, dd;
+ tests_start_mpfr ();
mpfr_test_init ();
mpfr_init2 (x, 2);
@@ -113,7 +114,7 @@ main (int argc, char *argv[])
#ifdef HAVE_DENORMS
while (0);
#else
- while (ABS(d) <= 2.2e-307);
+ while (ABS(d) < DBL_MIN);
#endif
mpfr_set_d (x, d, 0);
dd = mpfr_get_d1 (x);
@@ -128,5 +129,6 @@ main (int argc, char *argv[])
mpfr_clear(x); mpfr_clear(y); mpfr_clear(z);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset_f.c b/mpfr/tests/tset_f.c
index e6c5f2287..7506398cb 100644
--- a/mpfr/tests/tset_f.c
+++ b/mpfr/tests/tset_f.c
@@ -33,6 +33,8 @@ main (void)
mpf_t y, z;
unsigned long k, pr;
+ tests_start_mpfr ();
+
mpf_init(y);
mpf_init(z);
@@ -81,5 +83,6 @@ main (void)
mpf_clear (y);
mpf_clear (z);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset_ld.c b/mpfr/tests/tset_ld.c
new file mode 100644
index 000000000..6e62ca293
--- /dev/null
+++ b/mpfr/tests/tset_ld.c
@@ -0,0 +1,144 @@
+/* Test file for mpfr_set_ld and mpfr_get_ld.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+#include <time.h>
+#include "gmp.h"
+#include "mpfr.h"
+#include "mpfr-test.h"
+
+void check_set_get _PROTO((long double, mpfr_t));
+
+/* checks that a long double converted to a mpfr (with precision >=113),
+ then converted back to a long double gives the initial value,
+ or in other words mpfr_get_ld(mpfr_set_ld(d)) = d.
+*/
+void
+check_set_get (long double d, mpfr_t x)
+{
+ mp_rnd_t r;
+ long double e;
+
+ for (r=0; r<4; r++)
+ {
+ if (mpfr_set_ld (x, d, r))
+ {
+ fprintf (stderr, "Error: mpfr_set_ld should be exact\n");
+ exit (1);
+ }
+ e = mpfr_get_ld (x, r);
+ if (e != d && !(isnan(e) && isnan(d)))
+ {
+ fprintf (stderr, "Error: mpfr_get_ld o mpfr_set_ld <> Id\n");
+ fprintf (stderr, "d=%1.30Le get_ld(set_ld(d))=%1.30Le\n", d, e);
+ exit (1);
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ long double d, e;
+ double f;
+ mpfr_t x;
+ int i;
+
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+ mpfr_init2 (x, 113);
+
+ /* check +0.0 and -0.0 */
+ d = 0.0;
+ check_set_get (d, x);
+ d = -0.0;
+ check_set_get (d, x);
+
+ /* checks that sign of -0.0 is set */
+ mpfr_set_ld (x, -0.0, GMP_RNDN);
+ if (MPFR_SIGN(x) > 0)
+ {
+ fprintf (stderr, "Error: sign of -0.0 is not set correctly\n");
+ exit (1);
+ }
+
+ /* checks NaN, Inf and -Inf */
+ mpfr_set_nan (x);
+ d = mpfr_get_ld (x, GMP_RNDN);
+ check_set_get (d, x);
+
+ mpfr_set_inf (x, 1);
+ d = mpfr_get_ld (x, GMP_RNDN);
+ check_set_get (d, x);
+
+ mpfr_set_inf (x, -1);
+ d = mpfr_get_ld (x, GMP_RNDN);
+ check_set_get (d, x);
+
+ /* checks the largest power of two */
+ d = 1.0; while ((e = d + d) != d) d = e;
+ check_set_get (d, x);
+ check_set_get (-d, x);
+
+ /* checks largest long double */
+ d = 0.0; while ((e = 1.0 + d / 2.0) != (long double) 2.0) d = e;
+ /* now d is the machine number just before 2.0 */
+ while ((e = d + d) != d) d = e;
+ check_set_get (d, x);
+ check_set_get (-d, x);
+
+ /* checks the smallest power of two */
+ d = 1.0; while ((e = d / 2.0) != (long double) 0.0) d = e;
+ check_set_get (d, x);
+ check_set_get (-d, x);
+
+ /* checks 2^1024 */
+ f = 1.3407807929942597100e155; /* 2^512 */
+ d = (long double) f;
+ d = d * d; /* 2^1024 */
+ check_set_get (d, x);
+
+ /* checks that 2^i, 2^i+1 and 2^i-1 are correctly converted */
+ d = 1.0;
+ for (i=1; i<=113; i++)
+ {
+ d = 2.0 * d; /* d = 2^i */
+ check_set_get (d, x);
+ check_set_get (d + 1.0, x);
+ check_set_get (d - 1.0, x);
+ }
+
+ for (i=0; i<10000; i++)
+ {
+ mpfr_random (x);
+ d = mpfr_get_ld (x, GMP_RNDN);
+ check_set_get (d, x);
+ }
+
+ mpfr_clear (x);
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tset_q.c b/mpfr/tests/tset_q.c
index bb9ffc37e..a60b46b9d 100644
--- a/mpfr/tests/tset_q.c
+++ b/mpfr/tests/tset_q.c
@@ -40,10 +40,6 @@ check (long int n, long int d, mp_rnd_t rnd, double y)
mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb);
mpq_init (q);
mpq_set_si (q, n, d);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode (rnd);
- y = (double) n / d;
-#endif
inexact = mpfr_set_q (x, q, rnd);
z = mpfr_get_d1 (x);
@@ -52,7 +48,8 @@ check (long int n, long int d, mp_rnd_t rnd, double y)
{
fprintf (stderr, "Error for q=%ld/%lu and rnd=%s\n", n, d,
mpfr_print_rnd_mode (rnd));
- fprintf (stderr, "libm.a gives %1.20e, mpfr_set_q gives %1.20e\n", y, z);
+ fprintf (stderr, "correct result is %1.20e, mpfr_set_q gives %1.20e\n",
+ y, z);
exit (1);
}
@@ -80,24 +77,8 @@ check (long int n, long int d, mp_rnd_t rnd, double y)
int
main (void)
{
-#ifdef MPFR_HAVE_FESETROUND
- long int i, n;
- unsigned long int d;
- double y;
- unsigned char rnd;
+ tests_start_mpfr ();
- mpfr_test_init ();
-
- SEED_RAND(time(NULL));
- for (i=0;i<1000000;i++) {
- n = LONG_RAND();
- d = LONG_RAND();
- if (LONG_RAND()%2) n = -n;
- rnd = LONG_RAND() % 4;
- y = (double) n / d;
- check(n, d, rnd, y);
- }
-#endif
check(-1647229822, 40619231, GMP_RNDZ, -4.055295438754120596e1);
check(-148939696, 1673285490, GMP_RNDZ, -8.9010331404953485501e-2);
check(-441322590, 273662545, GMP_RNDZ, -1.6126525096812205362);
@@ -106,6 +87,8 @@ main (void)
check(75504803, 400207282, GMP_RNDU, 1.8866424074712365155e-1);
check(643562308, 23100894, GMP_RNDD, 2.7858762002890447462e1);
check(632549085, 1831935802, GMP_RNDN, 3.4528998467600230393e-1);
+ check (1, 1, GMP_RNDN, 1.0);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset_si.c b/mpfr/tests/tset_si.c
index ebe0e72b0..8a0c62a7a 100644
--- a/mpfr/tests/tset_si.c
+++ b/mpfr/tests/tset_si.c
@@ -35,6 +35,8 @@ main (int argc, char *argv[])
unsigned long zl, dl, N;
int inex;
+ tests_start_mpfr ();
+
mpfr_init2(x, 100);
SEED_RAND (time(NULL));
@@ -159,5 +161,6 @@ main (int argc, char *argv[])
mpfr_clear(x);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset_str.c b/mpfr/tests/tset_str.c
index da995f68d..acdf24cf9 100644
--- a/mpfr/tests/tset_str.c
+++ b/mpfr/tests/tset_str.c
@@ -24,6 +24,7 @@ MA 02111-1307, USA. */
#include <string.h>
#include <time.h>
#include "gmp.h"
+#include "gmp-impl.h"
#include "mpfr.h"
#include "mpfr-impl.h"
#include "mpfr-test.h"
@@ -37,6 +38,8 @@ main (int argc, char *argv[])
mp_exp_t e;
int base, logbase, prec, baseprec;
+ tests_start_mpfr ();
+
if (argc>=2) /* tset_str <string> <prec> */
{
prec = (argc>=3) ? atoi(argv[2]) : 53;
@@ -56,7 +59,7 @@ main (int argc, char *argv[])
bd = LONG_RAND() & 8;
- str2 = str = (char *) malloc (nc * sizeof(char));
+ str2 = str = (*__gmp_allocate_func) (nc * sizeof(char));
if (bd)
{
@@ -93,7 +96,7 @@ main (int argc, char *argv[])
exit(1);
}
- free(str);
+ (*__gmp_free_func) (str, nc * sizeof(char));
mpfr_set_prec (x, 53);
mpfr_set_str_raw (x, "+110101100.01010000101101000000100111001000101011101110E00");
@@ -160,38 +163,48 @@ main (int argc, char *argv[])
mpfr_clear (y);
exit (1);
}
- free (str);
+ (*__gmp_free_func) (str, strlen (str) + 1);
}
- if (mpfr_set_str (x, "NaN", 10, GMP_RNDN) != 0 || !mpfr_nan_p(x))
+ if (mpfr_set_str (x, "NaNgarbage", 10, GMP_RNDN) != 3 || !mpfr_nan_p(x))
{
fprintf (stderr, "mpfr_set_str failed on NaN\n");
exit (1);
}
- if (mpfr_set_str (x, "Inf", 10, GMP_RNDN) != 0 || !mpfr_inf_p(x) ||
+ if (mpfr_set_str (x, "Infgarbage", 10, GMP_RNDN) != 3 || !mpfr_inf_p(x) ||
MPFR_SIGN(x) < 0)
{
fprintf (stderr, "mpfr_set_str failed on Inf\n");
exit (1);
}
- if (mpfr_set_str (x, "-Inf", 10, GMP_RNDN) != 0 || !mpfr_inf_p(x) ||
+ if (mpfr_set_str (x, "-Infgarbage", 10, GMP_RNDN) != 4 || !mpfr_inf_p(x) ||
MPFR_SIGN(x) > 0)
{
fprintf (stderr, "mpfr_set_str failed on -Inf\n");
exit (1);
}
- if (mpfr_set_str (x, "+Inf", 10, GMP_RNDN) != 0 || !mpfr_inf_p(x) ||
+ if (mpfr_set_str (x, "+Infgarbage", 10, GMP_RNDN) != 4 || !mpfr_inf_p(x) ||
MPFR_SIGN(x) < 0)
{
fprintf (stderr, "mpfr_set_str failed on +Inf\n");
exit (1);
}
+ /* check that mpfr_set_str works for uppercase letters too */
+ mpfr_set_prec (x, 10);
+ mpfr_set_str (x, "B", 16, GMP_RNDN);
+ if (mpfr_cmp_ui (x, 11) != 0)
+ {
+ fprintf (stderr, "mpfr_set_str does not work for uppercase letters\n");
+ exit (1);
+ }
+
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tset_z.c b/mpfr/tests/tset_z.c
index 720302f80..f67a8ee45 100644
--- a/mpfr/tests/tset_z.c
+++ b/mpfr/tests/tset_z.c
@@ -66,11 +66,14 @@ main (int argc, char *argv[])
{
long j;
+ tests_start_mpfr ();
+
check_large();
SEED_RAND (time(NULL));
check(0, 0);
for (j=0; j<1000000; j++)
check(LONG_RAND(), LONG_RAND()%4);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tsin.c b/mpfr/tests/tsin.c
index a12b98779..5e04aee8a 100644
--- a/mpfr/tests/tsin.c
+++ b/mpfr/tests/tsin.c
@@ -27,9 +27,7 @@ MA 02111-1307, USA. */
#include "mpfr-impl.h"
#include "mpfr-test.h"
-void check53 _PROTO ((double, double, mp_rnd_t));
-
-void
+static void
check53 (double x, double sin_x, mp_rnd_t rnd_mode)
{
mpfr_t xx, s;
@@ -50,6 +48,49 @@ check53 (double x, double sin_x, mp_rnd_t rnd_mode)
mpfr_clear (s);
}
+static void
+test_sign (void)
+{
+ mpfr_t pid, piu, x, y;
+ int p, k;
+
+ mpfr_init2 (pid, 4096);
+ mpfr_const_pi (pid, GMP_RNDD);
+ mpfr_init2 (piu, 4096);
+ mpfr_const_pi (piu, GMP_RNDU);
+ mpfr_init (x);
+ mpfr_init2 (y, 2);
+ for (p = 8; p <= 128; p++)
+ for (k = 2; k <= 22; k += 2)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_mul_ui (x, pid, k, GMP_RNDD);
+ mpfr_sin (y, x, GMP_RNDN);
+ if (MPFR_SIGN(y) > 0)
+ {
+ fprintf (stderr,
+ "Error in test_sign for sin(%dpi-epsilon), prec = %d"
+ " for argument.\nResult should have been negative.\n",
+ k, p);
+ exit (1);
+ }
+ mpfr_mul_ui (x, piu, k, GMP_RNDU);
+ mpfr_sin (y, x, GMP_RNDN);
+ if (MPFR_SIGN(y) < 0)
+ {
+ fprintf (stderr,
+ "Error in test_sign for sin(%dpi+epsilon), prec = %d"
+ " for argument.\nResult should have been positive.\n",
+ k, p);
+ exit (1);
+ }
+ }
+ mpfr_clear (pid);
+ mpfr_clear (piu);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
#define TEST_FUNCTION mpfr_sin
#include "tgeneric.c"
@@ -58,6 +99,8 @@ main (int argc, char *argv[])
{
mpfr_t x;
+ tests_start_mpfr ();
+
#ifdef HAVE_INFS
check53 (DBL_NAN, DBL_NAN, GMP_RNDN);
check53 (DBL_POS_INF, DBL_NAN, GMP_RNDN);
@@ -99,6 +142,8 @@ main (int argc, char *argv[])
mpfr_clear (x);
test_generic (2, 100, 80);
+ test_sign ();
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tsinh.c b/mpfr/tests/tsinh.c
index 1315dc34a..5aae5d645 100644
--- a/mpfr/tests/tsinh.c
+++ b/mpfr/tests/tsinh.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_sinh.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tsqrt.c b/mpfr/tests/tsqrt.c
index 46123ad93..ada9f2b33 100644
--- a/mpfr/tests/tsqrt.c
+++ b/mpfr/tests/tsqrt.c
@@ -44,40 +44,19 @@ void check_nan _PROTO((void));
void
check3 (double a, mp_rnd_t rnd_mode, double Q)
{
- mpfr_t q; double Q2; int ck,u;
+ mpfr_t q; double Q2; int u;
- ck = (Q!=-1.0); /* if ck=1, then Q is certified correct */
mpfr_init2(q, 53);
mpfr_set_d(q, a, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
mpfr_sqrt(q, q, rnd_mode);
- if (ck==0) Q = sqrt(a);
- else {
- if (Q != sqrt(a) && (!isnan(Q) || !isnan(sqrt(a)))) {
- fprintf(stderr, "you've found a bug in your machine's sqrt for x=%1.20e\n", a);
- mpfr_clear(q);
- exit(1);
-
- }
- }
Q2 = mpfr_get_d1 (q);
if (Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
u = ulp(Q2,Q);
- if (ck) {
- printf("mpfr_sqrt failed for a=%1.20e, rnd_mode=%s\n",
- a, mpfr_print_rnd_mode(rnd_mode));
- printf("expected sqrt is %1.20e, got %1.20e (%d ulp)\n",Q,Q2,u);
- mpfr_clear(q);
- exit(1);
- }
- else if (u>maxulp || u<-maxulp) {
- maxulp = (u>maxulp) ? u : -u;
- printf("libm.a differs from mpfr_sqrt for a=%1.20e, rnd_mode=%s\n",
- a, mpfr_print_rnd_mode(rnd_mode));
- printf("libm.a gives %1.20e, mpfr_sqrt gives %1.20e (%d ulp)\n",Q,Q2,u);
- }
+ printf("mpfr_sqrt failed for a=%1.20e, rnd_mode=%s\n",
+ a, mpfr_print_rnd_mode(rnd_mode));
+ printf("expected sqrt is %1.20e, got %1.20e (%d ulp)\n",Q,Q2,u);
+ mpfr_clear(q);
+ exit(1);
}
mpfr_clear(q);
}
@@ -328,35 +307,6 @@ main (void)
double a;
mp_prec_t p;
int k;
-#ifdef MPFR_HAVE_FESETROUND
- int i;
-
- mpfr_test_init ();
-
- /* On Debian potato glibc 2.1.3-18, sqrt() doesn't seem to respect
- fesetround. */
- {
- double a, b;
- mpfr_set_machine_rnd_mode (GMP_RNDU);
- a = sqrt (five);
- mpfr_set_machine_rnd_mode (GMP_RNDD);
- b = sqrt (five);
- if (a == b)
- {
- printf ("Tests suppressed, mpfr_set_machine_rnd_mode doesn't affect sqrt()\n");
- goto nogood;
- }
- }
-
- SEED_RAND (time(NULL));
- for (i=0;i<100000;i++)
- {
- a = drand();
- if (a < 0.0) a = -a; /* ensures a is positive */
- check (a, LONG_RAND() % 4);
- }
- nogood:
-#endif
check_nan ();
diff --git a/mpfr/tests/tsqrt_ui.c b/mpfr/tests/tsqrt_ui.c
index cbb5f9d31..64f2239c9 100644
--- a/mpfr/tests/tsqrt_ui.c
+++ b/mpfr/tests/tsqrt_ui.c
@@ -34,21 +34,14 @@ int maxulp=0;
void
check (unsigned long a, mp_rnd_t rnd_mode, double Q)
{
- mpfr_t q; double Q2; int u, ck;
+ mpfr_t q; double Q2; int u;
mpfr_init2(q, 53);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
mpfr_sqrt_ui(q, a, rnd_mode);
- ck = (Q >= 0.0);
- if (!ck) Q = sqrt(1.0 * a);
Q2 = mpfr_get_d1 (q);
if (Q!=Q2 && (!isnan(Q) || !isnan(Q2))) {
u = ulp(Q2,Q);
- if (ck) printf("mpfr_sqrt_ui failed");
- else printf("mpfr_sqrt_ui differs from sqrt");
- printf(" for a=%lu, rnd_mode=%s\n",
+ printf("mpfr_sqrt_ui failed for a=%lu, rnd_mode=%s\n",
a, mpfr_print_rnd_mode(rnd_mode));
printf("sqrt gives %1.20e, mpfr_sqrt_ui gives %1.20e (%d ulp)\n",Q,Q2,u);
exit(1);
@@ -61,40 +54,11 @@ double five = 5.0;
int
main (void)
{
-#ifdef MPFR_HAVE_FESETROUND
- int i;
- unsigned long a;
-
- mpfr_test_init ();
-
- /* On Debian potato glibc 2.1.3-18, sqrt() doesn't seem to respect
- fesetround. */
- {
- double a, b;
- mpfr_set_machine_rnd_mode (GMP_RNDU);
- a = sqrt (five);
- mpfr_set_machine_rnd_mode (GMP_RNDD);
- b = sqrt (five);
- if (a == b)
- {
- printf ("Tests suppressed, mpfr_set_machine_rnd_mode doesn't affect sqrt()\n");
- goto nogood;
- }
- }
-
- SEED_RAND (time(NULL));
- for (i=0;i<1000000;i++)
- {
- a = LONG_RAND();
- /* machine arithmetic must agree if a <= 2.0^53 */
- if (1.0*a < 9007199254872064.0)
- check(a, LONG_RAND() % 4, -1.0);
- }
- nogood:
-#endif
+ tests_start_mpfr ();
check (0, GMP_RNDN, 0.0);
check (2116118, GMP_RNDU, 1.45468828276026215e3);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tsub.c b/mpfr/tests/tsub.c
index 09abf9578..5a7123ed7 100644
--- a/mpfr/tests/tsub.c
+++ b/mpfr/tests/tsub.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_sub.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
This file is part of the MPFR Library.
@@ -304,7 +304,7 @@ check_two_sum (mp_prec_t p)
mpfr_init2 (w, p);
mpfr_random (x);
mpfr_random (y);
- if (mpfr_cmp_abs (x, y) < 0)
+ if (mpfr_cmpabs (x, y) < 0)
mpfr_swap (x, y);
rnd = LONG_RAND() % 4;
rnd = GMP_RNDN;
@@ -348,6 +348,19 @@ check_inexact (void)
mpfr_init (z);
mpfr_init (u);
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 6, GMP_RNDN);
+ mpfr_div_2exp (x, x, 4, GMP_RNDN); /* x = 6/16 */
+ mpfr_set_prec (y, 2);
+ mpfr_set_si (y, -1, GMP_RNDN);
+ mpfr_div_2exp (y, y, 4, GMP_RNDN); /* y = -1/16 */
+ inexact = mpfr_sub (y, y, x, GMP_RNDN); /* y = round(-7/16) = -1/2 */
+ if (inexact >= 0)
+ {
+ fprintf (stderr, "Error: wrong inexact flag for -1/16 - (6/16)\n");
+ exit (1);
+ }
+
for (px=2; px<MAX_PREC; px++)
{
mpfr_set_prec (x, px);
@@ -359,7 +372,7 @@ check_inexact (void)
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)
+ pz = (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x)-MPFR_EXP(u)
: MPFR_EXP(u)-MPFR_EXP(x);
pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u));
mpfr_set_prec (z, pz);
@@ -403,6 +416,8 @@ main(void)
mp_prec_t p;
unsigned i;
+ tests_start_mpfr ();
+
check_diverse ();
check_inexact ();
bug_ddefour ();
@@ -411,5 +426,6 @@ main(void)
for (i=0; i<200; i++)
check_two_sum (p);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tsub_ui.c b/mpfr/tests/tsub_ui.c
index 34175d99b..5dd992d80 100644
--- a/mpfr/tests/tsub_ui.c
+++ b/mpfr/tests/tsub_ui.c
@@ -22,6 +22,7 @@ MA 02111-1307, USA. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include <time.h>
#include "gmp.h"
#include "mpfr.h"
@@ -47,10 +48,6 @@ check3 (double x, unsigned long y, mp_rnd_t rnd_mode, double z1)
mpfr_set_prec(zz, 53);
mpfr_set_d(xx, x, rnd_mode);
mpfr_sub_ui(zz, xx, y, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (z1==0.0) z1 = x-y;
z2 = mpfr_get_d1 (zz);
if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
printf("expected sum is %1.20e, got %1.20e\n",z1,z2);
@@ -114,25 +111,9 @@ main (int argc, char *argv[])
{
mp_prec_t p;
int k;
-#ifdef MPFR_HAVE_FESETROUND
- double x; unsigned long y, N; int i,rnd_mode,rnd;
-
- mpfr_test_init ();
-
- SEED_RAND (time(NULL));
- N = (argc<2) ? 1000000 : atoi(argv[1]);
- rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
- for (i=0;i<1000000;i++) {
- x = drand();
- y = LONG_RAND();
- if (ABS(x)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check(x, y, rnd);
- }
- }
-#endif
-
+
+ tests_start_mpfr ();
+
for (p=2; p<200; p++)
for (k=0; k<200; k++)
check_two_sum (p);
@@ -144,6 +125,7 @@ main (int argc, char *argv[])
check3 (DBL_NEG_INF, 1, GMP_RNDN, DBL_NEG_INF);
#endif
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tswap.c b/mpfr/tests/tswap.c
index 5ea61da35..80b75e251 100644
--- a/mpfr/tests/tswap.c
+++ b/mpfr/tests/tswap.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_swap.
-Copyright 2000, 2001 Free Software Foundation, Inc.
+Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -23,12 +23,15 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include "gmp.h"
#include "mpfr.h"
+#include "mpfr-test.h"
int
main (void)
{
mpfr_t u, v;
+ tests_start_mpfr ();
+
mpfr_init2 (u, 24);
mpfr_init2 (v, 53);
mpfr_set_ui (u, 16777215, GMP_RNDN); /* 2^24 - 1 */
@@ -42,5 +45,6 @@ main (void)
mpfr_clear (u);
mpfr_clear (v);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/ttan.c b/mpfr/tests/ttan.c
index ec4b26ebb..f0efd5eb9 100644
--- a/mpfr/tests/ttan.c
+++ b/mpfr/tests/ttan.c
@@ -60,6 +60,8 @@ main(int argc, char *argv[])
unsigned int prec[10] = {14, 15, 19, 22, 23, 24, 25, 40, 41, 52};
unsigned int prec2[10] = {4, 5, 6, 19, 70, 95, 100, 106, 107, 108};
+ tests_start_mpfr ();
+
#ifdef HAVE_INFS
check53 (DBL_NAN, DBL_NAN, GMP_RNDN);
check53 (DBL_POS_INF, DBL_NAN, GMP_RNDN);
@@ -112,5 +114,6 @@ main(int argc, char *argv[])
test_generic (2, 100, 100);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/ttanh.c b/mpfr/tests/ttanh.c
index 8c947c4f7..5d3bd173c 100644
--- a/mpfr/tests/ttanh.c
+++ b/mpfr/tests/ttanh.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_tanh.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -32,7 +32,10 @@ MA 02111-1307, USA. */
int
main (int argc, char *argv[])
{
+ tests_start_mpfr ();
+
test_generic (2, 100, 100);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/ttrunc.c b/mpfr/tests/ttrunc.c
index 6cb344eb6..a28828482 100644
--- a/mpfr/tests/ttrunc.c
+++ b/mpfr/tests/ttrunc.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_trunc, mpfr_ceil, mpfr_floor.
-Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -24,6 +24,7 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+#include "mpfr-test.h"
#define SIZEX 100
@@ -32,6 +33,8 @@ main (void)
{
int j, k; mpfr_t x, y, z, t, y2, z2, t2;
+ tests_start_mpfr ();
+
mpfr_init2(x, SIZEX);
mpfr_init2(y, SIZEX);
mpfr_init2(z, SIZEX);
@@ -140,5 +143,6 @@ main (void)
mpfr_clear(t);
mpfr_clear(t2);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tui_div.c b/mpfr/tests/tui_div.c
index ed01976ae..9c7fd6c51 100644
--- a/mpfr/tests/tui_div.c
+++ b/mpfr/tests/tui_div.c
@@ -44,10 +44,6 @@ check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1)
mpfr_init2(zz, 53);
mpfr_set_d(xx, x, rnd_mode);
mpfr_ui_div(zz, y, xx, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (z1==0.0) z1 = y/x;
z2 = mpfr_get_d1 (zz);
if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
printf("expected quotient is %1.20e, got %1.20e\n",z1,z2);
@@ -152,28 +148,6 @@ check_nan (void)
int
main (int argc, char *argv[])
{
-#ifdef MPFR_HAVE_FESETROUND
- double x;
- unsigned long y, N;
- int i, rnd_mode, rnd;
-
- mpfr_test_init ();
-
- SEED_RAND(time(NULL));
- N = (argc<2) ? 1000000 : atoi(argv[1]);
- rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
- for (i=0;i<1000000;i++)
- {
- x = drand();
- y = LONG_RAND();
- if (ABS(x)>4e-286)
- {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check(y, x, rnd, 0.0);
- }
- }
-#endif
check_inexact ();
check(948002822, 1.22191250737771397120e+20, GMP_RNDN,
7.758352715731357946e-12);
diff --git a/mpfr/tests/tui_pow.c b/mpfr/tests/tui_pow.c
index 33db9abce..fbde84e2f 100644
--- a/mpfr/tests/tui_pow.c
+++ b/mpfr/tests/tui_pow.c
@@ -1,6 +1,6 @@
/* Test file for mpfr_ui_pow.
-Copyright 2001 Free Software Foundation.
+Copyright 2001, 2002 Free Software Foundation.
Adapted from tarctan.c.
This file is part of the MPFR Library.
@@ -35,6 +35,8 @@ main (int argc, char *argv[])
mpfr_t x, y;
unsigned long int n;
+ tests_start_mpfr ();
+
mpfr_init (x);
mpfr_init (y);
@@ -76,8 +78,12 @@ main (int argc, char *argv[])
int p1=100;
int N=100;
- mpfr_init (z);
- mpfr_init (t);
+ mpfr_init2 (z, 38);
+ mpfr_init2 (t, 6);
+
+ /* check exact power */
+ mpfr_set_str_raw (t, "0.110000E5");
+ mpfr_ui_pow (z, 3, t, GMP_RNDN);
/* generic test */
for (prec = p0; prec <= p1; prec++)
@@ -147,5 +153,6 @@ main (int argc, char *argv[])
mpfr_clear (x);
mpfr_clear (y);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/tests/tui_sub.c b/mpfr/tests/tui_sub.c
index 40f814534..1a2c67421 100644
--- a/mpfr/tests/tui_sub.c
+++ b/mpfr/tests/tui_sub.c
@@ -22,6 +22,7 @@ MA 02111-1307, USA. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <float.h>
#include <time.h>
#include "gmp.h"
#include "mpfr.h"
@@ -140,10 +141,6 @@ check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1)
mpfr_init2(zz, 53);
mpfr_set_d(xx, x, rnd_mode);
mpfr_ui_sub(zz, y, xx, rnd_mode);
-#ifdef MPFR_HAVE_FESETROUND
- mpfr_set_machine_rnd_mode(rnd_mode);
-#endif
- if (z1==0.0) z1 = y-x;
z2 = mpfr_get_d1 (zz);
if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
printf("expected difference is %1.20e, got %1.20e\n",z1,z2);
@@ -204,26 +201,9 @@ main (int argc, char *argv[])
{
mp_prec_t p;
unsigned k;
-#ifdef MPFR_HAVE_FESETROUND
- double x;
- unsigned long y, N;
- int i, rnd_mode, rnd;
-
- mpfr_test_init ();
-
- SEED_RAND (time(NULL));
- N = (argc<2) ? 1000000 : atoi(argv[1]);
- rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
- for (i=0;i<1000000;i++) {
- x = drand ();
- y = LONG_RAND ();
- if (ABS(x)>2.2e-307) {
- /* avoid denormalized numbers and overflows */
- rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
- check(y, x, rnd, 0.0);
- }
- }
-#endif
+
+ tests_start_mpfr ();
+
special ();
for (p=2; p<100; p++)
for (k=0; k<100; k++)
@@ -246,5 +226,6 @@ main (int argc, char *argv[])
check(293607738, -1.9967571564050541e-5, GMP_RNDU, 2.9360773800002003e8);
check(354270183, 2.9469161763489528e3, GMP_RNDN, 3.5426723608382362e8);
+ tests_end_mpfr ();
return 0;
}
diff --git a/mpfr/uceil_exp2.c b/mpfr/uceil_exp2.c
index 231369f38..8003a5164 100644
--- a/mpfr/uceil_exp2.c
+++ b/mpfr/uceil_exp2.c
@@ -1,4 +1,4 @@
-/* _mpfr_ceil_exp2 - returns y >= 2^d
+/* __gmpfr_ceil_exp2 - returns y >= 2^d
Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
@@ -26,7 +26,7 @@ MA 02111-1307, USA. */
/* returns y >= 2^d, assuming that d <= 1024 */
double
-_mpfr_ceil_exp2 (double d)
+__gmpfr_ceil_exp2 (double d)
{
long exp;
union ieee_double_extract x;
diff --git a/mpfr/uceil_log2.c b/mpfr/uceil_log2.c
index 9decc009f..f7ba603cd 100644
--- a/mpfr/uceil_log2.c
+++ b/mpfr/uceil_log2.c
@@ -1,4 +1,4 @@
-/* _mpfr_ceil_log2 - returns ceil(log(d)/log(2))
+/* __gmpfr_ceil_log2 - returns ceil(log(d)/log(2))
Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
@@ -26,7 +26,7 @@ MA 02111-1307, USA. */
/* returns ceil(log(d)/log(2)) */
long
-_mpfr_ceil_log2 (double d)
+__gmpfr_ceil_log2 (double d)
{
long exp;
union ieee_double_extract x;
diff --git a/mpfr/ufloor_log2.c b/mpfr/ufloor_log2.c
index 48ee49283..7d8e05494 100644
--- a/mpfr/ufloor_log2.c
+++ b/mpfr/ufloor_log2.c
@@ -1,4 +1,4 @@
-/* _mpfr_floor_log2 - returns floor(log(d)/log(2))
+/* __gmpfr_floor_log2 - returns floor(log(d)/log(2))
Copyright 1999, 2000, 2001, 2002 Free Software Foundation.
@@ -26,7 +26,7 @@ MA 02111-1307, USA. */
/* returns floor(log(d)/log(2)) */
long
-_mpfr_floor_log2 (double d)
+__gmpfr_floor_log2 (double d)
{
union ieee_double_extract x;
diff --git a/mpfr/ui_div.c b/mpfr/ui_div.c
index d0e8b15ef..cb9421911 100644
--- a/mpfr/ui_div.c
+++ b/mpfr/ui_div.c
@@ -1,6 +1,6 @@
/* mpfr_ui_div -- divide a machine integer by a floating-point number
-Copyright 2000, 2001 Free Software Foundation, Inc.
+Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -55,6 +55,7 @@ mpfr_ui_div (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mp_rnd_t rnd_mode)
if (u)
{
MPFR_INIT1(up, uu, BITS_PER_MP_LIMB, 1);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
count_leading_zeros(cnt, (mp_limb_t) u);
*up = (mp_limb_t) u << cnt;
MPFR_EXP(uu) = BITS_PER_MP_LIMB-cnt;
diff --git a/mpfr/ui_pow.c b/mpfr/ui_pow.c
index 241863b35..d1364f41e 100644
--- a/mpfr/ui_pow.c
+++ b/mpfr/ui_pow.c
@@ -21,10 +21,72 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "gmp-impl.h"
+#include "longlong.h"
#include "mpfr.h"
#include "mpfr-impl.h"
+static int mpfr_ui_pow_is_exact _PROTO((unsigned long int, mpfr_srcptr));
+
+/* return non zero iff x^y is exact.
+ Assumes y is a non-zero ordinary number (neither NaN nor Inf).
+*/
+int
+mpfr_ui_pow_is_exact (unsigned long int x, mpfr_srcptr y)
+{
+ mp_exp_t d;
+ unsigned long i, c;
+ mp_limb_t *yp;
+ mp_size_t ysize;
+
+ if (mpfr_sgn (y) < 0) /* exact iff x = 2^k */
+ {
+ count_leading_zeros(c, x);
+ c = BITS_PER_MP_LIMB - c; /* number of bits of x */
+ return x == 1UL << (c - 1);
+ }
+
+ /* compute d such that y = c*2^d with c odd integer */
+ ysize = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB;
+ d = MPFR_EXP(y) - ysize * BITS_PER_MP_LIMB;
+ /* since y is not zero, necessarily one of the mantissa limbs is not zero,
+ thus we can simply loop until we find a non zero limb */
+ yp = MPFR_MANT(y);
+ for (i = 0; yp[i] == 0; i++, d += BITS_PER_MP_LIMB);
+ /* now yp[i] is not zero */
+ count_trailing_zeros (c, yp[i]);
+ d += c;
+
+ if (d < 0)
+ {
+ mpz_t a;
+ mp_exp_t b;
+
+ mpz_init_set_ui (a, x);
+ b = 0; /* x = a * 2^b */
+ c = mpz_scan1 (a, 0);
+ mpz_div_2exp (a, a, c);
+ b += c;
+ /* now a is odd */
+ while (d != 0)
+ {
+ if (mpz_perfect_square_p (a))
+ {
+ d++;
+ mpz_sqrt (a, a);
+ }
+ else
+ {
+ mpz_clear (a);
+ return 0;
+ }
+ }
+ mpz_clear (a);
+ }
+
+ return 1;
+}
+
/* The computation of y=pow(n,z) is done by
y=exp(z*log(n))=n^z
@@ -33,7 +95,7 @@ MA 02111-1307, USA. */
int
mpfr_ui_pow (mpfr_ptr y, unsigned long int n, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
- int inexact;
+ int inexact = 1;
if (MPFR_IS_NAN(x))
{
@@ -60,9 +122,9 @@ mpfr_ui_pow (mpfr_ptr y, unsigned long int n, mpfr_srcptr x, mp_rnd_t rnd_mode)
/* n^0 = 1 */
if (MPFR_IS_ZERO(x))
- {
- return mpfr_set_ui(y,1,rnd_mode);
- }
+ return mpfr_set_ui (y, 1, rnd_mode);
+
+ inexact = mpfr_ui_pow_is_exact (n, x) == 0;
/* General case */
{
@@ -77,39 +139,40 @@ mpfr_ui_pow (mpfr_ptr y, unsigned long int n, mpfr_srcptr x, mp_rnd_t rnd_mode)
long int err; /* Precision of error */
/* compute the precision of intermediary variable */
- Nt=MAX(Nx,Ny);
+ Nt = MAX(Nx,Ny);
/* the optimal number of bits : see algorithms.ps */
- Nt=Nt+5+_mpfr_ceil_log2(Nt);
+ Nt = Nt + 5 + __gmpfr_ceil_log2 (Nt);
/* initialise of intermediary variable */
- mpfr_init(t);
- mpfr_init2(ti,sizeof(unsigned long int)*8); /* 8 = CHAR_BIT */
- mpfr_init(te);
+ mpfr_init2 (t, MPFR_PREC_MIN);
+ mpfr_init2 (ti, sizeof(unsigned long int) * 8); /* 8 = CHAR_BIT */
+ mpfr_init2 (te, MPFR_PREC_MIN);
do {
/* reactualisation of the precision */
- mpfr_set_prec(t,Nt);
- mpfr_set_prec(te,Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
/* compute exp(x*ln(n))*/
- mpfr_set_ui(ti,n,GMP_RNDN); /* ti <- n*/
- mpfr_log(t,ti,GMP_RNDU); /* ln(n) */
- mpfr_mul(te,x,t,GMP_RNDU); /* x*ln(n) */
- mpfr_exp(t,te,GMP_RNDN); /* exp(x*ln(n))*/
+ mpfr_set_ui (ti, n, GMP_RNDN); /* ti <- n*/
+ mpfr_log (t, ti, GMP_RNDU); /* ln(n) */
+ mpfr_mul (te, x, t, GMP_RNDU); /* x*ln(n) */
+ mpfr_exp (t, te, GMP_RNDN); /* exp(x*ln(n))*/
/* estimation of the error -- see pow function in algorithms.ps*/
- err = Nt - (MPFR_EXP(te)+3);
+ err = Nt - (MPFR_EXP(te) + 3);
/* actualisation of the precision */
Nt += 10;
- } while (err<0 || !mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Ny));
+ } while (inexact && (err < 0 || !mpfr_can_round (t, err, GMP_RNDN, rnd_mode, Ny)));
- inexact = mpfr_set(y,t,rnd_mode);
- mpfr_clear(t);
- mpfr_clear(ti);
- mpfr_clear(te);
+ inexact = mpfr_set (y, t, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
}
return inexact;
diff --git a/mpfr/ui_pow_ui.c b/mpfr/ui_pow_ui.c
index a13d511be..d04852704 100644
--- a/mpfr/ui_pow_ui.c
+++ b/mpfr/ui_pow_ui.c
@@ -54,6 +54,7 @@ mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n,
for (i = 0, m = n; m; i++, m >>= 1)
prec++;
mpfr_set_prec (res, prec);
+ mpfr_clear_flags ();
inexact = mpfr_set_ui (res, y, GMP_RNDU);
err = 1;
/* now 2^(i-1) <= n < 2^i */
@@ -78,5 +79,6 @@ mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n,
mpfr_clear (res);
- MPFR_RESTORE_RET(inexact, x, rnd);
+ mpfr_restore_emin_emax ();
+ return mpfr_check_range (x, inexact, rnd);
}
diff --git a/mpfr/ui_sub.c b/mpfr/ui_sub.c
index 5cc94df76..10f356d8d 100644
--- a/mpfr/ui_sub.c
+++ b/mpfr/ui_sub.c
@@ -32,7 +32,7 @@ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mp_rnd_t rnd_mode)
mp_limb_t up[1];
unsigned long cnt;
- if (MPFR_IS_NAN(x))
+ if (MPFR_IS_NAN(x))
{
MPFR_SET_NAN(y);
MPFR_RET_NAN;
@@ -48,14 +48,15 @@ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mp_rnd_t rnd_mode)
MPFR_RET(0); /* +/-infinity is exact */
}
- if (u) {
- 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_sub (y, uu, x, rnd_mode);
- }
+ if (u)
+ {
+ MPFR_INIT1 (up, uu, BITS_PER_MP_LIMB, 1);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ *up = (mp_limb_t) u << cnt;
+ MPFR_EXP(uu) = BITS_PER_MP_LIMB - cnt;
+ return mpfr_sub (y, uu, x, rnd_mode);
+ }
else
return mpfr_neg (y, x, rnd_mode); /* if u=0, then set y to -x */
}
diff --git a/mpfr/urandomb.c b/mpfr/urandomb.c
index 2592fb1a1..a81ea31ed 100644
--- a/mpfr/urandomb.c
+++ b/mpfr/urandomb.c
@@ -3,7 +3,7 @@
using STATE as the random state previously initialized by a call to
gmp_randinit().
-Copyright 2000, 2001 Free Software Foundation, Inc.
+Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -22,7 +22,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"
@@ -33,9 +32,10 @@ void
mpfr_urandomb (mpfr_ptr rop, gmp_randstate_t rstate)
{
mp_ptr rp;
+ mp_prec_t nbits;
mp_size_t nlimbs;
mp_exp_t exp;
- unsigned long cnt, nbits;
+ int cnt;
MPFR_CLEAR_FLAGS(rop);
@@ -46,12 +46,8 @@ mpfr_urandomb (mpfr_ptr rop, gmp_randstate_t rstate)
_gmp_rand (rp, rstate, nbits);
/* If nbits isn't a multiple of BITS_PER_MP_LIMB, shift up. */
- if (nlimbs != 0)
- {
- if (nbits % BITS_PER_MP_LIMB != 0)
- mpn_lshift (rp, rp, nlimbs,
- BITS_PER_MP_LIMB - nbits % BITS_PER_MP_LIMB);
- }
+ if (nbits % BITS_PER_MP_LIMB != 0)
+ mpn_lshift (rp, rp, nlimbs, BITS_PER_MP_LIMB - nbits % BITS_PER_MP_LIMB);
exp = 0;
while (nlimbs != 0 && rp[nlimbs - 1] == 0)
@@ -60,13 +56,18 @@ mpfr_urandomb (mpfr_ptr rop, gmp_randstate_t rstate)
exp--;
}
- count_leading_zeros (cnt, rp[nlimbs - 1]);
- if (cnt) mpn_lshift (rp, rp, nlimbs, cnt);
- exp -= cnt;
+ if (nlimbs != 0) /* otherwise value is zero */
+ {
+ count_leading_zeros (cnt, rp[nlimbs - 1]);
+ if (cnt != 0)
+ mpn_lshift (rp, rp, nlimbs, cnt);
+ exp -= cnt;
- cnt = nlimbs*BITS_PER_MP_LIMB - nbits;
- /* cnt is the number of non significant bits in the low limb */
- rp[0] &= ~((MP_LIMB_T_ONE << cnt) - 1);
+ cnt = (mp_prec_t) nlimbs * BITS_PER_MP_LIMB - nbits;
+ /* cnt is the number of non significant bits in the low limb */
+ rp[0] &= ~((MP_LIMB_T_ONE << cnt) - 1);
+ }
MPFR_EXP (rop) = exp;
+ MPFR_SET_POS (rop);
}