summaryrefslogtreecommitdiff
path: root/Build/source/libs/mpfr/mpfr-src/src
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src')
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/Makefile.am47
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/abort_prec_max.c5
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/acos.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/acosh.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/add.c33
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/add1.c104
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/add1sp.c805
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/add_d.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/add_ui.c70
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/agm.c11
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ai.c71
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/asinh.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/atan.c196
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/atan2.c9
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/atanh.c117
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/bernoulli.c265
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/beta.c345
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/buildopt.c25
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cache.c75
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/check.c65
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/clear.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/clears.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp2.c45
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp_abs.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp_d.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp_ld.c12
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp_si.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cmp_ui.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/const_euler.c341
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/const_log2.c44
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/const_pi.c25
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/constant.c37
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cos.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cosh.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cot.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/coth.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/csc.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/csch.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/d_div.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/d_sub.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/digamma.c45
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/div.c861
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/div_2si.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/div_d.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/div_ui.c73
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/dump.c112
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/eint.c157
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/erandom.c105
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/erf.c38
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/erfc.c14
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/exceptions.c187
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/exp.c129
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/exp2.c63
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/exp3.c28
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/exp_2.c177
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/expm1.c16
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/extract.c12
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/factorial.c7
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fits_intmax.c10
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fits_s.h5
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fits_u.h5
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fits_uintmax.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fma.c209
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fmma.c91
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fms.c274
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/fpif.c651
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/frac.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/free_cache.c77
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/frexp.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/gamma.c109
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/gamma_inc.c504
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/generic/coverage/mparam.h225
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_d.c3
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_d64.c222
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_f.c9
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_float128.c129
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_flt.c5
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_ld.c227
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_q.c63
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_si.c19
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_sj.c31
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_str.c404
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_ui.c11
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_uj.c15
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_z.c12
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/get_z_exp.c11
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/gmp_op.c44
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/grandom.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/hypot.c42
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ieee_floats.h39
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/init2.c33
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/inits.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/inits2.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/inp_str.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/invert_limb.h233
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/invsqrt_limb.h365
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/jn.c15
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/jyn_asympt.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/li2.c35
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/lngamma.c233
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/log.c44
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/log10.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/log1p.c117
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/log2.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/log_ui.c234
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/logging.c10
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mips/mparam.h234
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mp_clz_tab.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mparam_h.in13
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpf2mpfr.h15
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-cvers.h62
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.c86
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h552
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h1313
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-intmax.h32
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-longlong.h706
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.c211
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.h141
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-sassert.h75
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr-thread.h219
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpfr.h1122
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mpn_exp.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mul.c589
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mul_d.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mul_ui.c21
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/mulders.c63
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/neg.c11
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/next.c53
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/nrandom.c183
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/odd_p.c73
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/out_str.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/pool.c117
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/pow.c207
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/pow_si.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/pow_z.c14
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/print_raw.c109
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/print_rnd_mode.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/printf.c69
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/random_deviate.c384
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/random_deviate.h86
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/rec_sqrt.c25
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/rem1.c7
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/rint.c46
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/rndna.c193
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/root.c68
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/round_near_x.c11
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/round_p.c16
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/round_prec.c50
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/round_raw_generic.c117
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/scale2.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set.c127
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_d.c145
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_d64.c225
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_dfl_prec.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_exp.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_f.c12
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_float128.c139
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_ld.c271
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_prc_raw.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_prec.c13
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_q.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_si_2exp.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_sj.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_uj.c58
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_z_exp.c10
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/setmax.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sgn.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/si_op.c123
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/signbit.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sin.c32
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sin_cos.c103
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sinh.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sinh_cosh.c4
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sqr.c505
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sqrt.c482
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sqrt_ui.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/strtofr.c15
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sub.c26
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sub1.c226
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sub1sp.c1418
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sub_d.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sub_ui.c78
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/subnormal.c11
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/sum.c1582
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/tanh.c88
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ubf.c242
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/uceil_exp2.c8
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/uceil_log2.c22
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ufloor_log2.c20
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ui_div.c20
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ui_pow.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ui_pow_ui.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ui_sub.c64
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/urandom.c156
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/urandomb.c14
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/vasprintf.c787
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/version.c2
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/yn.c6
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/zeta.c271
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/zeta_ui.c8
203 files changed, 18988 insertions, 5382 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/Makefile.am b/Build/source/libs/mpfr/mpfr-src/src/Makefile.am
index 982f2db1445..a25aba626a3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/Makefile.am
+++ b/Build/source/libs/mpfr/mpfr-src/src/Makefile.am
@@ -13,7 +13,8 @@ EXTRA_DIST = round_raw_generic.c jyn_asympt.c x86/core2/mparam.h \
x86/mparam.h x86_64/core2/mparam.h x86_64/pentium4/mparam.h \
ia64/mparam.h arm/mparam.h powerpc64/mparam.h sparc64/mparam.h \
generic/mparam.h amd/athlon/mparam.h amd/k8/mparam.h \
- amd/amdfam10/mparam.h powerpc32/mparam.h hppa/mparam.h
+ amd/amdfam10/mparam.h powerpc32/mparam.h hppa/mparam.h \
+ mips/mparam.h generic/coverage/mparam.h
include_HEADERS = mpfr.h mpf2mpfr.h
@@ -22,8 +23,9 @@ BUILT_SOURCES = mparam.h
lib_LTLIBRARIES = libmpfr.la
-libmpfr_la_SOURCES = mpfr.h mpf2mpfr.h mpfr-gmp.h mpfr-impl.h mpfr-intmax.h \
-mpfr-longlong.h mpfr-thread.h exceptions.c extract.c uceil_exp2.c \
+libmpfr_la_SOURCES = mpfr.h mpf2mpfr.h mpfr-cvers.h mpfr-gmp.h \
+mpfr-impl.h mpfr-intmax.h mpfr-longlong.h mpfr-sassert.h mpfr-thread.h \
+exceptions.c extract.c uceil_exp2.c \
uceil_log2.c ufloor_log2.c add.c add1.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 exp10.c exp2.c exp3.c exp.c \
@@ -55,7 +57,10 @@ zeta_ui.c set_d64.c get_d64.c jn.c yn.c rem1.c get_patches.c add_d.c \
sub_d.c d_sub.c mul_d.c div_d.c d_div.c li2.c rec_sqrt.c min_prec.c \
buildopt.c digamma.c bernoulli.c isregular.c set_flt.c get_flt.c \
scale2.c set_z_exp.c ai.c gammaonethird.c ieee_floats.h \
-grandom.c
+grandom.c fpif.c set_float128.c get_float128.c rndna.c nrandom.c \
+random_deviate.h random_deviate.c erandom.c mpfr-mini-gmp.c \
+mpfr-mini-gmp.h fmma.c log_ui.c gamma_inc.c ubf.c invert_limb.h \
+invsqrt_limb.h beta.c odd_p.c get_q.c pool.c
libmpfr_la_LIBADD = @LIBOBJS@
@@ -75,7 +80,8 @@ libmpfr_la_LIBADD = @LIBOBJS@
# 2.4.x 3:x:2
# 3.0.x 4:x:0
# 3.1.x 5:x:1
-libmpfr_la_LDFLAGS = $(MPFR_LDFLAGS) $(LIBMPFR_LDFLAGS) -version-info 5:6:1
+# 4.0.x 6:x:0
+libmpfr_la_LDFLAGS = $(MPFR_LDFLAGS) $(LIBMPFR_LDFLAGS) -version-info 6:0:0
# Important note: If for some reason, srcdir is read-only at build time
# (and you use objdir != srcdir), then you need to rebuild get_patches.c
@@ -91,3 +97,34 @@ $(srcdir)/get_patches.c: $(top_srcdir)/PATCHES $(top_srcdir)/tools/get_patches.s
# and "make clean" shouldn't remove it, just like it doesn't remove
# what has been changed by "patch".
#CLEANFILES = get_patches.c
+
+GMPC = $(top_builddir)/src/gmp.c
+GMPI = $(top_builddir)/src/gmp.i
+
+# Check that MPFR does not use GMP internal symbols. Of course, do not run
+# this rule if you use --with-gmp-build or --enable-gmp-internals. This
+# test does nothing if --disable-shared has been used.
+# Note: we use a temporary file $(GMPC) instead of "| $(COMPILE) -E -"
+# because the latter is not supported by all compilers (at least under
+# MS Windows).
+check-gmp-symbols: $(LTLIBRARIES)
+ printf "#include <%s.h>\n" stdarg stdio gmp > $(GMPC)
+ $(COMPILE) -E $(GMPC) > $(GMPI)
+ libmpfrso=$(top_builddir)/src/.libs/libmpfr.so; \
+ if [ -f "$$libmpfrso" ]; then \
+ internals=`$(NM) -u "$$libmpfrso" | \
+ $(SED) -n 's/^ *U \(__gmp.*\)/\1/p' | \
+ while read s; \
+ do \
+ $(GREP) -q "$$s[ (;]" $(GMPI) || echo "$$s"; \
+ done`; \
+ if [ -n "$$internals" ]; then \
+ echo "Internal GMP symbols:" $$internals; \
+ exit 1; \
+ fi; \
+ fi
+ rm $(GMPC) $(GMPI)
+
+CLEANFILES = $(GMPC) $(GMPI)
+
+.PHONY: check-gmp-symbols
diff --git a/Build/source/libs/mpfr/mpfr-src/src/abort_prec_max.c b/Build/source/libs/mpfr/mpfr-src/src/abort_prec_max.c
index 85cbcae8aaf..928e7c68d9c 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/abort_prec_max.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/abort_prec_max.c
@@ -20,11 +20,10 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <stdlib.h>
-
#include "mpfr-impl.h"
-void mpfr_abort_prec_max (void)
+MPFR_COLD_FUNCTION_ATTR MPFR_NORETURN void
+mpfr_abort_prec_max (void)
{
fprintf (stderr, "MPFR: Maximal precision overflow\n");
abort ();
diff --git a/Build/source/libs/mpfr/mpfr-src/src/acos.c b/Build/source/libs/mpfr/mpfr-src/src/acos.c
index 574727dca0e..7be589aea56 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/acos.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/acos.c
@@ -75,7 +75,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
else
{
- if (MPFR_IS_POS_SIGN (sign)) /* acos(+1) = 0 */
+ if (MPFR_IS_POS_SIGN (sign)) /* acos(+1) = +0 */
return mpfr_set_ui (acos, 0, rnd_mode);
else /* acos(-1) = Pi */
return mpfr_const_pi (acos, rnd_mode);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/acosh.c b/Build/source/libs/mpfr/mpfr-src/src/acosh.c
index a9d422548be..2377860dcd8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/acosh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/acosh.c
@@ -62,7 +62,7 @@ mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mpfr_rnd_t rnd_mode)
}
else if (MPFR_UNLIKELY (comp == 0))
{
- MPFR_SET_ZERO (y); /* acosh(1) = 0 */
+ MPFR_SET_ZERO (y); /* acosh(1) = +0 */
MPFR_SET_POS (y);
MPFR_RET (0);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/add.c b/Build/source/libs/mpfr/mpfr-src/src/add.c
index 690f76f5c7a..0d499d67b4d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/add.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/add.c
@@ -22,7 +22,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
MPFR_LOG_FUNC
@@ -31,7 +31,7 @@ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
("a[%Pu]=%.*Rg", mpfr_get_prec (a), mpfr_log_prec, a));
- if (MPFR_ARE_SINGULAR(b,c))
+ if (MPFR_ARE_SINGULAR_OR_UBF (b, c))
{
if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
{
@@ -59,7 +59,7 @@ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_SET_SAME_SIGN(a, c);
MPFR_RET(0); /* exact */
}
- /* now either b or c is zero */
+ /* now both b and c are finite numbers */
else if (MPFR_IS_ZERO(b))
{
if (MPFR_IS_ZERO(c))
@@ -69,18 +69,32 @@ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
except (-0) + (-0) = -0. */
MPFR_SET_SIGN(a,
(rnd_mode != MPFR_RNDD ?
- ((MPFR_IS_NEG(b) && MPFR_IS_NEG(c)) ? -1 : 1) :
- ((MPFR_IS_POS(b) && MPFR_IS_POS(c)) ? 1 : -1)));
+ (MPFR_IS_NEG(b) && MPFR_IS_NEG(c) ?
+ MPFR_SIGN_NEG : MPFR_SIGN_POS) :
+ (MPFR_IS_POS(b) && MPFR_IS_POS(c) ?
+ MPFR_SIGN_POS : MPFR_SIGN_NEG)));
MPFR_SET_ZERO(a);
MPFR_RET(0); /* 0 + 0 is exact */
}
return mpfr_set (a, c, rnd_mode);
}
- else
+ else if (MPFR_IS_ZERO(c))
{
- MPFR_ASSERTD(MPFR_IS_ZERO(c));
return mpfr_set (a, b, rnd_mode);
}
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (c));
+ /* mpfr_sub1sp and mpfr_add1sp are not intended to support UBF,
+ for which optimization is less important. */
+ if (MPFR_SIGN(b) != MPFR_SIGN(c))
+ return mpfr_sub1 (a, b, c, rnd_mode);
+ else if (MPFR_UBF_EXP_LESS_P (b, c))
+ return mpfr_add1 (a, c, b, rnd_mode);
+ else
+ return mpfr_add1 (a, b, c, rnd_mode);
+ }
}
MPFR_ASSERTD (MPFR_IS_PURE_FP (b));
@@ -98,10 +112,7 @@ mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{ /* signs are equal, it's an addition */
if (MPFR_LIKELY(MPFR_PREC(a) == MPFR_PREC(b)
&& MPFR_PREC(b) == MPFR_PREC(c)))
- if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
- return mpfr_add1sp(a, c, b, rnd_mode);
- else
- return mpfr_add1sp(a, b, c, rnd_mode);
+ return mpfr_add1sp(a, b, c, rnd_mode);
else
if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
return mpfr_add1(a, c, b, rnd_mode);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/add1.c b/Build/source/libs/mpfr/mpfr-src/src/add1.c
index 7ed4fb1e7c7..c4b053dd032 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/add1.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/add1.c
@@ -22,27 +22,39 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-/* compute sign(b) * (|b| + |c|), assuming b and c have same sign,
- and are not NaN, Inf, nor zero. */
-int
+/* compute sign(b) * (|b| + |c|), assuming that b and c
+ are not NaN, Inf, nor zero. Assumes EXP(b) >= EXP(c).
+*/
+MPFR_HOT_FUNCTION_ATTR int
mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
mp_limb_t *ap, *bp, *cp;
mpfr_prec_t aq, bq, cq, aq2;
mp_size_t an, bn, cn;
- mpfr_exp_t difw, exp;
+ mpfr_exp_t difw, exp, diff_exp;
int sh, rb, fb, inex;
- mpfr_uexp_t diff_exp;
MPFR_TMP_DECL(marker);
- MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
- MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (c));
+ MPFR_ASSERTD (! MPFR_UBF_EXP_LESS_P (b, c));
+
+ if (MPFR_UNLIKELY (MPFR_IS_UBF (b)))
+ {
+ exp = mpfr_ubf_zexp2exp (MPFR_ZEXP (b));
+ if (exp > __gmpfr_emax)
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN (b));;
+ }
+ else
+ exp = MPFR_GET_EXP (b);
+
+ MPFR_ASSERTD (exp <= __gmpfr_emax);
MPFR_TMP_MARK(marker);
- aq = MPFR_PREC(a);
- bq = MPFR_PREC(b);
- cq = MPFR_PREC(c);
+ aq = MPFR_GET_PREC (a);
+ bq = MPFR_GET_PREC (b);
+ cq = MPFR_GET_PREC (c);
an = MPFR_PREC2LIMBS (aq); /* number of limbs of a */
aq2 = (mpfr_prec_t) an * GMP_NUMB_BITS;
@@ -62,19 +74,24 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
if (ap == cp)
{ cp = bp; }
}
- else if (MPFR_UNLIKELY(ap == cp))
+ else if (ap == cp)
{
cp = MPFR_TMP_LIMBS_ALLOC (cn);
MPN_COPY(cp, ap, cn);
}
- exp = MPFR_GET_EXP (b);
MPFR_SET_SAME_SIGN(a, b);
MPFR_UPDATE2_RND_MODE(rnd_mode, MPFR_SIGN(b));
- /* now rnd_mode is either MPFR_RNDN, MPFR_RNDZ or MPFR_RNDA */
- /* Note: exponents can be negative, but the unsigned subtraction is
- a modular subtraction, so that one gets the correct result. */
- diff_exp = (mpfr_uexp_t) exp - MPFR_GET_EXP(c);
+ /* now rnd_mode is either MPFR_RNDN, MPFR_RNDZ, MPFR_RNDA or MPFR_RNDF. */
+ if (MPFR_UNLIKELY (MPFR_IS_UBF (c)))
+ {
+ MPFR_STAT_STATIC_ASSERT (MPFR_EXP_MAX > MPFR_PREC_MAX);
+ diff_exp = mpfr_ubf_diff_exp (b, c);
+ }
+ else
+ diff_exp = exp - MPFR_GET_EXP (c);
+
+ MPFR_ASSERTD (diff_exp >= 0);
/*
* 1. Compute the significant part A', the non-significant bits of A
@@ -153,7 +170,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPN_COPY(a2p - difn, cp + (cn - difn), difn);
/* add b to a */
- cc = MPFR_UNLIKELY(an > bn)
+ cc = an > bn
? mpn_add_n(ap + (an - bn), ap + (an - bn), bp, bn)
: mpn_add_n(ap, ap, bp + (bn - an), an);
@@ -185,7 +202,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
} /* cc */
} /* aq2 > diff_exp */
- /* non-significant bits of a */
+ /* zero the non-significant bits of a */
if (MPFR_LIKELY(rb < 0 && sh))
{
mp_limb_t mask, bb;
@@ -207,7 +224,11 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
}
- /* determine rounding and sticky bits (and possible carry) */
+ /* Determine rounding and sticky bits (and possible carry).
+ In faithful rounding, we may stop two bits after ulp(a):
+ the approximation is regarded as the number formed by a,
+ the rounding bit rb and an additional bit fb; and the
+ corresponding error is < 1/2 ulp of the unrounded result. */
difw = (mpfr_exp_t) an - (mpfr_exp_t) (diff_exp / GMP_NUMB_BITS);
/* difw is the number of limbs from b (regarded as having an infinite
@@ -234,12 +255,13 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD(fb != 0);
if (fb > 0)
{
- if (bb != MP_LIMB_T_MAX)
- {
- fb = 1; /* c hasn't been taken into account
- ==> sticky bit != 0 */
- goto rounding;
- }
+ /* Note: Here, we can round to nearest, but the loop may still
+ be necessary to determine whether there is a carry from c,
+ which will have an effect on the ternary value. However, in
+ faithful rounding, we do not have to determine the ternary
+ value, so that we can end the loop here. */
+ if (bb != MPFR_LIMB_MAX || rnd_mode == MPFR_RNDF)
+ goto rounding;
}
else /* fb not initialized yet */
{
@@ -249,7 +271,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
bb |= MPFR_LIMB_HIGHBIT;
}
fb = 1;
- if (bb != MP_LIMB_T_MAX)
+ if (bb != MPFR_LIMB_MAX)
goto rounding;
}
@@ -318,10 +340,16 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
fb = bb != 0;
- if (fb && bb != MP_LIMB_T_MAX)
+ if (fb && bb != MPFR_LIMB_MAX)
goto rounding;
} /* fb < 0 */
+ /* At least two bits after ulp(a) have been read, which is
+ sufficient for faithful rounding, as we do not need to
+ determine on which side of a breakpoint the result is. */
+ if (rnd_mode == MPFR_RNDF)
+ goto rounding;
+
while (bk > 0)
{
mp_limb_t bb, cc;
@@ -368,7 +396,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
fb = 1;
goto rounding;
}
- if (fb && bb != MP_LIMB_T_MAX)
+ if (fb && bb != MPFR_LIMB_MAX)
goto rounding;
} /* while */
@@ -406,7 +434,7 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
fb = bb != 0;
} /* fb < 0 */
- if (fb)
+ if (fb || rnd_mode == MPFR_RNDF)
goto rounding;
while (bk)
{
@@ -458,6 +486,11 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
rb = cc >> (GMP_NUMB_BITS - 1);
cc &= ~MPFR_LIMB_HIGHBIT;
}
+ if (cc == 0 && rnd_mode == MPFR_RNDF)
+ {
+ fb = 0;
+ goto rounding;
+ }
while (cc == 0)
{
if (ck == 0)
@@ -473,8 +506,8 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
} /* fb != 1 */
rounding:
- /* rnd_mode should be one of MPFR_RNDN, MPFR_RNDZ or MPFR_RNDA */
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ /* rnd_mode should be one of MPFR_RNDN, MPFR_RNDF, MPFR_RNDZ or MPFR_RNDA */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN || rnd_mode == MPFR_RNDF))
{
if (fb == 0)
{
@@ -530,6 +563,15 @@ mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
set_exponent:
+ if (MPFR_UNLIKELY (exp < __gmpfr_emin)) /* possible if b and c are UBF's */
+ {
+ if (rnd_mode == MPFR_RNDN &&
+ (exp < __gmpfr_emin - 1 ||
+ (inex >= 0 && mpfr_powerof2_raw (a))))
+ rnd_mode = MPFR_RNDZ;
+ inex = mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ goto end_of_add;
+ }
MPFR_SET_EXP (a, exp);
end_of_add:
diff --git a/Build/source/libs/mpfr/mpfr-src/src/add1sp.c b/Build/source/libs/mpfr/mpfr-src/src/add1sp.c
index 2ffb9a002fc..3dee9df791e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/add1sp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/add1sp.c
@@ -25,15 +25,20 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
/* Check if we have to check the result of mpfr_add1sp with mpfr_add1 */
-#ifdef MPFR_WANT_ASSERT
-# if MPFR_WANT_ASSERT >= 2
+#if MPFR_WANT_ASSERT >= 2
-int mpfr_add1sp2 (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+int mpfr_add1sp_ref (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
int mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
- mpfr_t tmpa, tmpb, tmpc;
+ mpfr_t tmpa, tmpb, tmpc, tmpd;
+ mpfr_flags_t old_flags, flags, flags2;
int inexb, inexc, inexact, inexact2;
+ if (rnd_mode == MPFR_RNDF)
+ return mpfr_add1sp_ref (a, b, c, rnd_mode);
+
+ old_flags = __gmpfr_flags;
+
mpfr_init2 (tmpa, MPFR_PREC (a));
mpfr_init2 (tmpb, MPFR_PREC (b));
mpfr_init2 (tmpc, MPFR_PREC (c));
@@ -44,10 +49,26 @@ int mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
inexc = mpfr_set (tmpc, c, MPFR_RNDN);
MPFR_ASSERTN (inexc == 0);
- inexact2 = mpfr_add1 (tmpa, tmpb, tmpc, rnd_mode);
- inexact = mpfr_add1sp2 (a, b, c, rnd_mode);
+ MPFR_ASSERTN (__gmpfr_flags == old_flags);
+
+ if (MPFR_GET_EXP (tmpb) < MPFR_GET_EXP (tmpc))
+ {
+ /* The sign for the result will be taken from the second argument
+ (= first input value, which is tmpb). */
+ MPFR_ALIAS (tmpd, tmpc, MPFR_SIGN (tmpb), MPFR_EXP (tmpc));
+ inexact2 = mpfr_add1 (tmpa, tmpd, tmpb, rnd_mode);
+ }
+ else
+ {
+ inexact2 = mpfr_add1 (tmpa, tmpb, tmpc, rnd_mode);
+ }
+ flags2 = __gmpfr_flags;
+
+ __gmpfr_flags = old_flags;
+ inexact = mpfr_add1sp_ref (a, b, c, rnd_mode);
+ flags = __gmpfr_flags;
- if (mpfr_cmp (tmpa, a) || inexact != inexact2)
+ if (! mpfr_equal_p (tmpa, a) || inexact != inexact2 || flags != flags2)
{
fprintf (stderr, "add1 & add1sp return different values for %s\n"
"Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
@@ -55,37 +76,549 @@ int mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
(unsigned long) MPFR_PREC (a),
(unsigned long) MPFR_PREC (b),
(unsigned long) MPFR_PREC (c));
- mpfr_fprint_binary (stderr, tmpb);
- fprintf (stderr, "\nC = ");
- mpfr_fprint_binary (stderr, tmpc);
- fprintf (stderr, "\n\nadd1 : ");
- mpfr_fprint_binary (stderr, tmpa);
- fprintf (stderr, "\nadd1sp: ");
- mpfr_fprint_binary (stderr, a);
- fprintf (stderr, "\nInexact sp = %d | Inexact = %d\n",
- inexact, inexact2);
+ mpfr_fdump (stderr, tmpb);
+ fprintf (stderr, "C = ");
+ mpfr_fdump (stderr, tmpc);
+ fprintf (stderr, "\nadd1 : ");
+ mpfr_fdump (stderr, tmpa);
+ fprintf (stderr, "add1sp: ");
+ mpfr_fdump (stderr, a);
+ fprintf (stderr, "Inexact sp = %d | Inexact = %d\n"
+ "Flags sp = %u | Flags = %u\n",
+ inexact, inexact2, flags, flags2);
MPFR_ASSERTN (0);
}
mpfr_clears (tmpa, tmpb, tmpc, (mpfr_ptr) 0);
return inexact;
}
-# define mpfr_add1sp mpfr_add1sp2
-# endif
-#endif
+# define mpfr_add1sp mpfr_add1sp_ref
+#endif /* MPFR_WANT_ASSERT >= 2 */
-/* Debugging support */
-#ifdef DEBUG
-# undef DEBUG
-# define DEBUG(x) (x)
-#else
-# define DEBUG(x) /**/
-#endif
+#if !defined(MPFR_GENERIC_ABI)
+
+/* same as mpfr_add1sp, but for p < GMP_NUMB_BITS */
+static int
+mpfr_add1sp1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t sh = GMP_NUMB_BITS - p;
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t a0; /* to store the result */
+ mp_limb_t mask;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(p < GMP_NUMB_BITS);
+
+ if (bx == cx)
+ {
+ /* The following line is probably better than
+ a0 = MPFR_LIMB_HIGHBIT | ((bp[0] + cp[0]) >> 1);
+ as it has less dependency and doesn't need a long constant on some
+ processors. On ARM, it can also probably benefit from shift-and-op
+ in a better way. Timings cannot be conclusive. */
+ a0 = (bp[0] >> 1) + (cp[0] >> 1);
+ bx ++;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ ap[0] = a0 ^ rb;
+ sb = 0; /* since b + c fits on p+1 bits, the sticky bit is zero */
+ }
+ else if (bx > cx)
+ {
+ BGreater1:
+ d = (mpfr_uexp_t) bx - cx;
+ mask = MPFR_LIMB_MASK(sh);
+ /* TODO: Should the case d < sh be removed, i.e. seen as a particular
+ case of d < GMP_NUMB_BITS? This case would do a bit more operations
+ but a test would be removed, avoiding pipeline stall issues. */
+ if (d < sh)
+ {
+ /* we can shift c by d bits to the right without losing any bit,
+ moreover we can shift one more if there is an exponent increase */
+ a0 = bp[0] + (cp[0] >> d);
+ if (a0 < bp[0]) /* carry */
+ {
+ MPFR_ASSERTD ((a0 & 1) == 0);
+ a0 = MPFR_LIMB_HIGHBIT | (a0 >> 1);
+ bx ++;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb = (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else if (d < GMP_NUMB_BITS) /* sh <= d < GMP_NUMB_BITS */
+ {
+ sb = cp[0] << (GMP_NUMB_BITS - d); /* bits from cp[-1] after shift */
+ a0 = bp[0] + (cp[0] >> d);
+ if (a0 < bp[0]) /* carry */
+ {
+ sb |= a0 & 1;
+ a0 = MPFR_LIMB_HIGHBIT | (a0 >> 1);
+ bx ++;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else /* d >= GMP_NUMB_BITS */
+ {
+ ap[0] = bp[0];
+ rb = 0; /* since p < GMP_NUMB_BITS */
+ sb = 1; /* since c <> 0 */
+ }
+ }
+ else /* bx < cx: swap b and c */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ goto BGreater1;
+ }
+
+ /* Note: we could keep the output significand in a0 for the rounding,
+ and only store it in ap[0] at the very end, but this seems slower
+ on average (but better for the worst case). */
+
+ /* now perform rounding */
+ if (MPFR_UNLIKELY(bx > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET(0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* the condition below should be rb == 0 || (rb != 0 && ...), but this
+ is equivalent to rb == 0 || (...) */
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ if (MPFR_UNLIKELY(ap[0] == 0))
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ /* no need to have MPFR_LIKELY here, since we are in a rare branch */
+ if (bx + 1 <= __gmpfr_emax)
+ MPFR_SET_EXP (a, bx + 1);
+ else /* overflow */
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
-/* compute sign(b) * (|b| + |c|)
+/* same as mpfr_add1sp, but for p = GMP_NUMB_BITS */
+static int
+mpfr_add1sp1n (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t a0; /* to store the result */
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(MPFR_PREC (a) == GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC (b) == GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC (c) == GMP_NUMB_BITS);
+
+ if (bx == cx)
+ {
+ a0 = bp[0] + cp[0];
+ rb = a0 & MPFR_LIMB_ONE;
+ ap[0] = MPFR_LIMB_HIGHBIT | (a0 >> 1);
+ bx ++;
+ sb = 0; /* since b + c fits on p+1 bits, the sticky bit is zero */
+ }
+ else if (bx > cx)
+ {
+ BGreater1:
+ d = (mpfr_uexp_t) bx - cx;
+ if (d < GMP_NUMB_BITS) /* 1 <= d < GMP_NUMB_BITS */
+ {
+ a0 = bp[0] + (cp[0] >> d);
+ sb = cp[0] << (GMP_NUMB_BITS - d); /* bits from cp[-1] after shift */
+ if (a0 < bp[0]) /* carry */
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT | (a0 >> 1);
+ rb = a0 & 1;
+ bx ++;
+ }
+ else /* no carry */
+ {
+ ap[0] = a0;
+ rb = sb & MPFR_LIMB_HIGHBIT;
+ sb &= ~MPFR_LIMB_HIGHBIT;
+ }
+ }
+ else /* d >= GMP_NUMB_BITS */
+ {
+ sb = d != GMP_NUMB_BITS || cp[0] != MPFR_LIMB_HIGHBIT;
+ ap[0] = bp[0];
+ rb = d == GMP_NUMB_BITS;
+ }
+ }
+ else /* bx < cx: swap b and c */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ goto BGreater1;
+ }
+
+ /* Note: we could keep the output significand in a0 for the rounding,
+ and only store it in ap[0] at the very end, but this seems slower
+ on average (but better for the worst case). */
+
+ /* now perform rounding */
+ if (MPFR_UNLIKELY(bx > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET(0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* the condition below should be rb == 0 || (rb != 0 && ...), but this
+ is equivalent to rb == 0 || (...) */
+ if (rb == 0 || (sb == 0 && (ap[0] & MPFR_LIMB_ONE) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE;
+ if (MPFR_UNLIKELY(ap[0] == 0))
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ /* no need to have MPFR_LIKELY here, since we are in a rare branch */
+ if (bx + 1 <= __gmpfr_emax)
+ MPFR_SET_EXP (a, bx + 1);
+ else /* overflow */
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* same as mpfr_add1sp, but for GMP_NUMB_BITS < p < 2*GMP_NUMB_BITS */
+static int
+mpfr_add1sp2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t sh = 2*GMP_NUMB_BITS - p;
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t a1, a0;
+ mp_limb_t mask;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(GMP_NUMB_BITS < p && p < 2 * GMP_NUMB_BITS);
+
+ if (bx == cx)
+ {
+ /* since bp[1], cp[1] >= MPFR_LIMB_HIGHBIT, a carry always occurs */
+ a0 = bp[0] + cp[0];
+ a1 = bp[1] + cp[1] + (a0 < bp[0]);
+ a0 = (a0 >> 1) | (a1 << (GMP_NUMB_BITS - 1));
+ bx ++;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ ap[1] = MPFR_LIMB_HIGHBIT | (a1 >> 1);
+ ap[0] = a0 ^ rb;
+ sb = 0; /* since b + c fits on p+1 bits, the sticky bit is zero */
+ }
+ else if (bx > cx)
+ {
+ BGreater2:
+ d = (mpfr_uexp_t) bx - cx;
+ mask = MPFR_LIMB_MASK(sh);
+ if (d < GMP_NUMB_BITS) /* 0 < d < GMP_NUMB_BITS */
+ {
+ sb = cp[0] << (GMP_NUMB_BITS - d); /* bits from cp[-1] after shift */
+ a0 = bp[0] + ((cp[1] << (GMP_NUMB_BITS - d)) | (cp[0] >> d));
+ a1 = bp[1] + (cp[1] >> d) + (a0 < bp[0]);
+ if (a1 < bp[1]) /* carry in high word */
+ {
+ exponent_shift:
+ sb |= a0 & 1;
+ /* shift a by 1 */
+ a0 = (a1 << (GMP_NUMB_BITS - 1)) | (a0 >> 1);
+ ap[1] = MPFR_LIMB_HIGHBIT | (a1 >> 1);
+ bx ++;
+ }
+ else
+ ap[1] = a1;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else if (d < 2*GMP_NUMB_BITS) /* GMP_NUMB_BITS <= d < 2*GMP_NUMB_BITS */
+ {
+ sb = (d == GMP_NUMB_BITS) ? cp[0]
+ : cp[0] | (cp[1] << (2*GMP_NUMB_BITS-d));
+ a0 = bp[0] + (cp[1] >> (d - GMP_NUMB_BITS));
+ a1 = bp[1] + (a0 < bp[0]);
+ if (a1 == 0)
+ goto exponent_shift;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ ap[1] = a1;
+ }
+ else /* d >= 2*GMP_NUMB_BITS */
+ {
+ ap[0] = bp[0];
+ ap[1] = bp[1];
+ rb = 0; /* since p < 2*GMP_NUMB_BITS */
+ sb = 1; /* since c <> 0 */
+ }
+ }
+ else /* bx < cx: swap b and c */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ goto BGreater2;
+ }
+
+ /* now perform rounding */
+ if (MPFR_UNLIKELY(bx > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET(0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ if (MPFR_UNLIKELY(ap[1] == 0))
+ {
+ ap[1] = MPFR_LIMB_HIGHBIT;
+ /* no need to have MPFR_LIKELY here, since we are in a rare branch */
+ if (bx + 1 <= __gmpfr_emax)
+ MPFR_SET_EXP (a, bx + 1);
+ else /* overflow */
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* same as mpfr_add1sp, but for 2*GMP_NUMB_BITS < p < 3*GMP_NUMB_BITS */
+static int
+mpfr_add1sp3 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t sh = 3*GMP_NUMB_BITS - p;
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t a2, a1, a0;
+ mp_limb_t mask;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(2 * GMP_NUMB_BITS < p && p < 3 * GMP_NUMB_BITS);
+
+ if (bx == cx)
+ {
+ /* since bp[2], cp[2] >= MPFR_LIMB_HIGHBIT, a carry always occurs */
+ a0 = bp[0] + cp[0];
+ a1 = bp[1] + cp[1] + (a0 < bp[0]);
+ a2 = bp[2] + cp[2] + (a1 < bp[1] || (a1 == bp[1] && a0 < bp[0]));
+ /* since p < 3 * GMP_NUMB_BITS, we lose no bit in a0 >> 1 */
+ a0 = (a1 << (GMP_NUMB_BITS - 1)) | (a0 >> 1);
+ bx ++;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ ap[2] = MPFR_LIMB_HIGHBIT | (a2 >> 1);
+ ap[1] = (a2 << (GMP_NUMB_BITS - 1)) | (a1 >> 1);
+ ap[0] = a0 ^ rb;
+ sb = 0; /* since b + c fits on p+1 bits, the sticky bit is zero */
+ }
+ else if (bx > cx)
+ {
+ BGreater2:
+ d = (mpfr_uexp_t) bx - cx;
+ mask = MPFR_LIMB_MASK(sh);
+ if (d < GMP_NUMB_BITS) /* 0 < d < GMP_NUMB_BITS */
+ {
+ mp_limb_t cy;
+ sb = cp[0] << (GMP_NUMB_BITS - d); /* bits from cp[-1] after shift */
+ a0 = bp[0] + ((cp[1] << (GMP_NUMB_BITS - d)) | (cp[0] >> d));
+ a1 = bp[1] + ((cp[2] << (GMP_NUMB_BITS - d)) | (cp[1] >> d))
+ + (a0 < bp[0]);
+ cy = a1 < bp[1] || (a1 == bp[1] && a0 < bp[0]); /* carry in a1 */
+ a2 = bp[2] + (cp[2] >> d) + cy;
+ if (a2 < bp[2] || (a2 == bp[2] && cy)) /* carry in high word */
+ {
+ exponent_shift:
+ sb |= a0 & 1;
+ /* shift a by 1 */
+ a0 = (a1 << (GMP_NUMB_BITS - 1)) | (a0 >> 1);
+ ap[1] = (a2 << (GMP_NUMB_BITS - 1)) | (a1 >> 1);
+ ap[2] = MPFR_LIMB_HIGHBIT | (a2 >> 1);
+ bx ++;
+ }
+ else
+ {
+ ap[1] = a1;
+ ap[2] = a2;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else if (d < 2*GMP_NUMB_BITS) /* GMP_NUMB_BITS <= d < 2*GMP_NUMB_BITS */
+ {
+ mp_limb_t c0shifted;
+ sb = (d == GMP_NUMB_BITS) ? cp[0]
+ : (cp[1] << (2*GMP_NUMB_BITS - d)) | cp[0];
+ c0shifted = (d == GMP_NUMB_BITS) ? cp[1]
+ : (cp[2] << (2*GMP_NUMB_BITS-d)) | (cp[1] >> (d - GMP_NUMB_BITS));
+ a0 = bp[0] + c0shifted;
+ a1 = bp[1] + (cp[2] >> (d - GMP_NUMB_BITS)) + (a0 < bp[0]);
+ /* if a1 < bp[1], there was a carry in the above addition,
+ or when a1 = bp[1] and one of the added terms is nonzero
+ (the sum of cp[2] >> (d - GMP_NUMB_BITS) and a0 < bp[0]
+ is at most 2^GMP_NUMB_BITS-d) */
+ a2 = bp[2] + ((a1 < bp[1]) || (a1 == bp[1] && a0 < bp[0]));
+ if (a2 == 0)
+ goto exponent_shift;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ ap[1] = a1;
+ ap[2] = a2;
+ }
+ else if (d < 3*GMP_NUMB_BITS) /* 2*GMP_NUMB_BITS<=d<3*GMP_NUMB_BITS */
+ {
+ MPFR_ASSERTD (2*GMP_NUMB_BITS <= d && d < 3*GMP_NUMB_BITS);
+ sb = (d == 2*GMP_NUMB_BITS ? 0 : cp[2] << (3*GMP_NUMB_BITS - d))
+ | cp[1] | cp[0];
+ a0 = bp[0] + (cp[2] >> (d - 2*GMP_NUMB_BITS));
+ a1 = bp[1] + (a0 < bp[0]);
+ a2 = bp[2] + (a1 < bp[1]);
+ if (a2 == 0)
+ goto exponent_shift;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ ap[1] = a1;
+ ap[2] = a2;
+ }
+ else /* d >= 2*GMP_NUMB_BITS */
+ {
+ ap[0] = bp[0];
+ ap[1] = bp[1];
+ ap[2] = bp[2];
+ rb = 0; /* since p < 3*GMP_NUMB_BITS */
+ sb = 1; /* since c <> 0 */
+ }
+ }
+ else /* bx < cx: swap b and c */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ goto BGreater2;
+ }
+
+ /* now perform rounding */
+ if (MPFR_UNLIKELY(bx > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET(0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ ap[2] += (ap[1] == 0 && ap[0] == 0);
+ if (MPFR_UNLIKELY(ap[2] == 0))
+ {
+ ap[2] = MPFR_LIMB_HIGHBIT;
+ /* no need to have MPFR_LIKELY here, since we are in a rare branch */
+ if (bx + 1 <= __gmpfr_emax)
+ MPFR_SET_EXP (a, bx + 1);
+ else /* overflow */
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+#endif /* !defined(MPFR_GENERIC_ABI) */
+
+/* compute sign(b) * (|b| + |c|).
Returns 0 iff result is exact,
a negative value when the result is less than the exact value,
a positive value otherwise. */
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
mpfr_uexp_t d;
@@ -96,6 +629,7 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpfr_exp_t bx;
mp_limb_t limb;
int inexact;
+ int neg;
MPFR_TMP_DECL(marker);
MPFR_TMP_MARK(marker);
@@ -103,59 +637,101 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD(MPFR_PREC(a) == MPFR_PREC(b) && MPFR_PREC(b) == MPFR_PREC(c));
MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
- MPFR_ASSERTD(MPFR_GET_EXP(b) >= MPFR_GET_EXP(c));
+
+ MPFR_SET_SAME_SIGN (a, b);
/* Read prec and num of limbs */
- p = MPFR_PREC(b);
+ p = MPFR_GET_PREC (b);
+
+#if !defined(MPFR_GENERIC_ABI)
+ if (p < GMP_NUMB_BITS)
+ return mpfr_add1sp1 (a, b, c, rnd_mode, p);
+
+ if (GMP_NUMB_BITS < p && p < 2 * GMP_NUMB_BITS)
+ return mpfr_add1sp2 (a, b, c, rnd_mode, p);
+
+ /* we put this test after the mpfr_add1sp2() call, to avoid slowing down
+ the more frequent case GMP_NUMB_BITS < p < 2 * GMP_NUMB_BITS */
+ if (p == GMP_NUMB_BITS)
+ return mpfr_add1sp1n (a, b, c, rnd_mode);
+
+ if (2 * GMP_NUMB_BITS < p && p < 3 * GMP_NUMB_BITS)
+ return mpfr_add1sp3 (a, b, c, rnd_mode, p);
+#endif
+
+ /* We need to get the sign before the possible exchange. */
+ neg = MPFR_IS_NEG (b);
+
+ bx = MPFR_GET_EXP(b);
+ if (bx < MPFR_GET_EXP(c))
+ {
+ mpfr_srcptr t = b;
+ bx = MPFR_GET_EXP(c);
+ b = c;
+ c = t;
+ }
+ MPFR_ASSERTD(bx >= MPFR_GET_EXP(c));
+
n = MPFR_PREC2LIMBS (p);
MPFR_UNSIGNED_MINUS_MODULO(sh, p);
- bx = MPFR_GET_EXP(b);
d = (mpfr_uexp_t) (bx - MPFR_GET_EXP(c));
- DEBUG (printf ("New add1sp with diff=%lu\n", (unsigned long) d));
+ /* printf ("New add1sp with diff=%lu\n", (unsigned long) d); */
- if (MPFR_UNLIKELY(d == 0))
+ if (d == 0)
{
/* d==0 */
- DEBUG( mpfr_print_mant_binary("C= ", MPFR_MANT(c), p) );
- DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
+ /* mpfr_print_mant_binary("C= ", MPFR_MANT(c), p); */
+ /* mpfr_print_mant_binary("B= ", MPFR_MANT(b), p); */
bx++; /* exp + 1 */
ap = MPFR_MANT(a);
- limb = mpn_add_n(ap, MPFR_MANT(b), MPFR_MANT(c), n);
- DEBUG( mpfr_print_mant_binary("A= ", ap, p) );
+ limb = mpn_add_n (ap, MPFR_MANT(b), MPFR_MANT(c), n);
+ /* mpfr_print_mant_binary("A= ", ap, p); */
MPFR_ASSERTD(limb != 0); /* There must be a carry */
limb = ap[0]; /* Get LSB (In fact, LSW) */
- mpn_rshift(ap, ap, n, 1); /* Shift mantissa A */
+ mpn_rshift (ap, ap, n, 1); /* Shift mantissa A */
ap[n-1] |= MPFR_LIMB_HIGHBIT; /* Set MSB */
ap[0] &= ~MPFR_LIMB_MASK(sh); /* Clear LSB bit */
- if (MPFR_LIKELY((limb&(MPFR_LIMB_ONE<<sh)) == 0)) /* Check exact case */
+
+
+ /* Fast track for faithful rounding: since b and c have the same
+ precision and the same exponent, the neglected value is either
+ 0 or 1/2 ulp(a), thus returning a is fine. */
+ if (rnd_mode == MPFR_RNDF)
{ inexact = 0; goto set_exponent; }
+
+ if ((limb & (MPFR_LIMB_ONE << sh)) == 0) /* Check exact case */
+ { inexact = 0; goto set_exponent; }
+
/* Zero: Truncate
Nearest: Even Rule => truncate or add 1
Away: Add 1 */
- if (MPFR_LIKELY(rnd_mode==MPFR_RNDN))
+ if (MPFR_LIKELY (rnd_mode == MPFR_RNDN))
{
- if (MPFR_LIKELY((ap[0]&(MPFR_LIMB_ONE<<sh))==0))
+ if ((ap[0] & (MPFR_LIMB_ONE << sh)) == 0)
{ inexact = -1; goto set_exponent; }
else
goto add_one_ulp;
}
- MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(b));
- if (rnd_mode==MPFR_RNDZ)
+ MPFR_UPDATE_RND_MODE(rnd_mode, neg);
+ if (rnd_mode == MPFR_RNDZ)
{ inexact = -1; goto set_exponent; }
else
goto add_one_ulp;
}
else if (MPFR_UNLIKELY (d >= p))
{
+ /* fast track for RNDF */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDF))
+ goto copy_set_exponent;
+
if (MPFR_LIKELY (d > p))
{
/* d > p : Copy B in A */
/* Away: Add 1
Nearest: Trunc
Zero: Trunc */
- if (MPFR_LIKELY (rnd_mode==MPFR_RNDN
- || MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (b))))
+ if (rnd_mode == MPFR_RNDN || MPFR_IS_LIKE_RNDZ (rnd_mode, neg))
{
copy_set_exponent:
ap = MPFR_MANT (a);
@@ -174,34 +750,34 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
{
/* d==p : Copy B in A */
- /* Away: Add 1
- Nearest: Even Rule if C is a power of 2, else Add 1
- Zero: Trunc */
- if (MPFR_LIKELY(rnd_mode==MPFR_RNDN))
+ /* Away: Add 1
+ Nearest: Even Rule if C is a power of 2, else Add 1
+ Zero: Trunc */
+ if (rnd_mode == MPFR_RNDN)
{
/* Check if C was a power of 2 */
cp = MPFR_MANT(c);
- if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
+ if (MPFR_UNLIKELY (cp[n-1] == MPFR_LIMB_HIGHBIT))
{
mp_size_t k = n-1;
- do {
+ do
k--;
- } while (k>=0 && cp[k]==0);
- if (MPFR_UNLIKELY(k<0))
+ while (k >= 0 && cp[k] == 0);
+ if (MPFR_UNLIKELY (k < 0))
/* Power of 2: Even rule */
- if ((MPFR_MANT (b)[0]&(MPFR_LIMB_ONE<<sh))==0)
+ if (((MPFR_MANT (b))[0] & (MPFR_LIMB_ONE << sh)) == 0)
goto copy_set_exponent;
}
/* Not a Power of 2 */
goto copy_add_one_ulp;
}
- else if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (b)))
+ else if (MPFR_IS_LIKE_RNDZ (rnd_mode, neg))
goto copy_set_exponent;
else
goto copy_add_one_ulp;
}
}
- else
+ else /* 0 < d < p */
{
mp_limb_t mask;
mp_limb_t bcp, bcp1; /* Cp and C'p+1 */
@@ -216,10 +792,10 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
dm = d % GMP_NUMB_BITS;
m = d / GMP_NUMB_BITS;
- if (MPFR_UNLIKELY(dm == 0))
+ if (MPFR_UNLIKELY (dm == 0))
{
/* dm = 0 and m > 0: Just copy */
- MPFR_ASSERTD(m!=0);
+ MPFR_ASSERTD (m != 0);
MPN_COPY(cp, MPFR_MANT(c)+m, n-m);
MPN_ZERO(cp+n-m, m);
}
@@ -237,34 +813,44 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
}
- DEBUG( mpfr_print_mant_binary("Before", MPFR_MANT(c), p) );
- DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
- DEBUG( mpfr_print_mant_binary("After ", cp, p) );
+ /* mpfr_print_mant_binary("Before", MPFR_MANT(c), p);
+ mpfr_print_mant_binary("B= ", MPFR_MANT(b), p);
+ mpfr_print_mant_binary("After ", cp, p); */
- /* Compute bcp=Cp and bcp1=C'p+1 */
- if (MPFR_LIKELY (sh > 0))
+ /* fast track for RNDF */
+ if (rnd_mode == MPFR_RNDF)
+ {
+ /* The bcp and bcp1 values will not matter for MPFR_RNDF, but
+ let's set them to 0 to avoid undefined behavior. */
+ bcp1 = bcp = 0;
+ goto clean;
+ }
+
+ /* Compute bcp=Cp and bcp1=C'p+1: bcp is the first neglected bit
+ (round bit), and bcp1 corresponds to the remaining bits (sticky bit).
+ */
+ if (sh > 0)
{
/* Try to compute them from C' rather than C */
- bcp = (cp[0] & (MPFR_LIMB_ONE<<(sh-1))) ;
- if (MPFR_LIKELY(cp[0]&MPFR_LIMB_MASK(sh-1)))
+ bcp = (cp[0] & (MPFR_LIMB_ONE<<(sh-1)));
+ if (MPFR_LIKELY (cp[0] & MPFR_LIMB_MASK (sh - 1)))
bcp1 = 1;
else
{
/* We can't compute C'p+1 from C'. Compute it from C */
/* Start from bit x=p-d+sh in mantissa C
(+sh since we have already looked sh bits in C'!) */
- mpfr_prec_t x = p-d+sh-1;
- if (MPFR_LIKELY(x>p))
+ mpfr_prec_t x = p - d + sh - 1;
+ if (MPFR_LIKELY (x > p))
/* We are already looked at all the bits of c, so C'p+1 = 0*/
bcp1 = 0;
else
{
mp_limb_t *tp = MPFR_MANT(c);
- mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
- mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
- DEBUG (printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
- (unsigned long) x, (long) kx,
- (unsigned long) sx));
+ mp_size_t kx = n - 1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS - 1 - (x % GMP_NUMB_BITS);
+ /* printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
+ (unsigned long) x, (long) kx, (unsigned long) sx); */
/* Looks at the last bits of limb kx (if sx=0 does nothing)*/
if (tp[kx] & MPFR_LIMB_MASK(sx))
bcp1 = 1;
@@ -272,9 +858,9 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
/*kx += (sx==0);*/
/*If sx==0, tp[kx] hasn't been checked*/
- do {
+ do
kx--;
- } while (kx>=0 && tp[kx]==0);
+ while (kx >= 0 && tp[kx] == 0);
bcp1 = (kx >= 0);
}
}
@@ -285,25 +871,26 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Compute Cp and C'p+1 from C with sh=0 */
mp_limb_t *tp = MPFR_MANT(c);
/* Start from bit x=p-d in mantissa C */
- mpfr_prec_t x = p-d;
- mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
- mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
- MPFR_ASSERTD(p >= d);
- bcp = tp[kx] & (MPFR_LIMB_ONE<<sx);
+ mpfr_prec_t x = p - d;
+ mp_size_t kx = n - 1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS - 1 - (x % GMP_NUMB_BITS);
+ MPFR_ASSERTD (p >= d);
+ bcp = tp[kx] & (MPFR_LIMB_ONE << sx);
/* Looks at the last bits of limb kx (If sx=0, does nothing)*/
- if (tp[kx]&MPFR_LIMB_MASK(sx))
+ if (tp[kx] & MPFR_LIMB_MASK(sx))
bcp1 = 1;
else
{
- do {
+ do
kx--;
- } while (kx>=0 && tp[kx]==0);
- bcp1 = (kx>=0);
+ while (kx >= 0 && tp[kx] == 0);
+ bcp1 = (kx >= 0);
}
}
- DEBUG (printf("sh=%u Cp=%lu C'p+1=%lu\n", sh,
- (unsigned long) bcp, (unsigned long) bcp1));
+ /* printf("sh=%u Cp=%lu C'p+1=%lu\n", sh,
+ (unsigned long) bcp, (unsigned long) bcp1); */
+ clean:
/* Clean shifted C' */
mask = ~MPFR_LIMB_MASK(sh);
cp[0] &= mask;
@@ -311,21 +898,21 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Add the mantissa c from b in a */
ap = MPFR_MANT(a);
limb = mpn_add_n (ap, MPFR_MANT(b), cp, n);
- DEBUG( mpfr_print_mant_binary("Add= ", ap, p) );
+ /* mpfr_print_mant_binary("Add= ", ap, p); */
/* Check for overflow */
if (MPFR_UNLIKELY (limb))
{
limb = ap[0] & (MPFR_LIMB_ONE<<sh); /* Get LSB */
- mpn_rshift (ap, ap, n, 1); /* Shift mantissa*/
+ mpn_rshift (ap, ap, n, 1); /* Shift mantissa */
bx++; /* Fix exponent */
ap[n-1] |= MPFR_LIMB_HIGHBIT; /* Set MSB */
ap[0] &= mask; /* Clear LSB bit */
bcp1 |= bcp; /* Recompute C'p+1 */
bcp = limb; /* Recompute Cp */
- DEBUG (printf ("(Overflow) Cp=%lu C'p+1=%lu\n",
- (unsigned long) bcp, (unsigned long) bcp1));
- DEBUG (mpfr_print_mant_binary ("Add= ", ap, p));
+ /* printf ("(Overflow) Cp=%lu C'p+1=%lu\n",
+ (unsigned long) bcp, (unsigned long) bcp1);
+ mpfr_print_mant_binary ("Add= ", ap, p); */
}
/* Round:
@@ -334,38 +921,34 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
Nearest: Truncate but could be exact if Cp==0
Add 1 if C'p+1 !=0,
Even rule else */
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDF))
+ { inexact = 0; goto set_exponent; }
+ else if (rnd_mode == MPFR_RNDN)
{
- if (MPFR_LIKELY(bcp == 0))
- { inexact = MPFR_LIKELY(bcp1) ? -1 : 0; goto set_exponent; }
+ inexact = - (bcp1 != 0);
+ if (bcp == 0)
+ goto set_exponent;
else if (MPFR_UNLIKELY(bcp1==0) && (ap[0]&(MPFR_LIMB_ONE<<sh))==0)
{ inexact = -1; goto set_exponent; }
else
goto add_one_ulp;
}
- MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(b));
- if (rnd_mode == MPFR_RNDZ)
- {
- inexact = MPFR_LIKELY(bcp || bcp1) ? -1 : 0;
- goto set_exponent;
- }
+ MPFR_UPDATE_RND_MODE(rnd_mode, neg);
+ inexact = -(bcp != 0 || bcp1 != 0);
+ if (rnd_mode == MPFR_RNDZ || inexact == 0)
+ goto set_exponent;
else
- {
- if (MPFR_UNLIKELY(bcp==0 && bcp1==0))
- { inexact = 0; goto set_exponent; }
- else
- goto add_one_ulp;
- }
+ goto add_one_ulp;
}
- MPFR_ASSERTN(0);
+ MPFR_RET_NEVER_GO_HERE();
add_one_ulp:
/* add one unit in last place to a */
- DEBUG( printf("AddOneUlp\n") );
+ /* printf("AddOneUlp\n"); */
if (MPFR_UNLIKELY( mpn_add_1(ap, ap, n, MPFR_LIMB_ONE<<sh) ))
{
/* Case 100000x0 = 0x1111x1 + 1*/
- DEBUG( printf("Pow of 2\n") );
+ /* printf("Pow of 2\n"); */
bx++;
ap[n-1] = MPFR_LIMB_HIGHBIT;
}
@@ -374,13 +957,11 @@ mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
set_exponent:
if (MPFR_UNLIKELY(bx > __gmpfr_emax)) /* Check for overflow */
{
- DEBUG( printf("Overflow\n") );
+ /* printf("Overflow\n"); */
MPFR_TMP_FREE(marker);
- MPFR_SET_SAME_SIGN(a,b);
- return mpfr_overflow(a, rnd_mode, MPFR_SIGN(a));
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
}
MPFR_SET_EXP (a, bx);
- MPFR_SET_SAME_SIGN(a,b);
MPFR_TMP_FREE(marker);
MPFR_RET (inexact * MPFR_INT_SIGN (a));
diff --git a/Build/source/libs/mpfr/mpfr-src/src/add_d.c b/Build/source/libs/mpfr/mpfr-src/src/add_d.c
index fff08a188f6..8ab2028e45e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/add_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/add_d.c
@@ -28,6 +28,7 @@ mpfr_add_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t d;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_LOG_FUNC
@@ -38,15 +39,14 @@ mpfr_add_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, d, IEEE_DBL_MANT_DIG);
inexact = mpfr_set_d (d, c, rnd_mode);
- MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTD (inexact == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_add (a, b, d, rnd_mode);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear (d);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (a, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/add_ui.c b/Build/source/libs/mpfr/mpfr-src/src/add_ui.c
index ef3b5ec923f..e6ad5db7831 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/add_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/add_ui.c
@@ -23,7 +23,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
{
MPFR_LOG_FUNC
@@ -31,29 +31,51 @@ mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
- if (MPFR_LIKELY(u != 0) ) /* if u=0, do nothing */
+ /* (unsigned long) 0 is assumed to be a real 0 (unsigned) */
+ if (MPFR_UNLIKELY (u == 0))
+ return mpfr_set (y, x, rnd_mode);
+
+ /* This block is actually useless, but this is a minor optimization. */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
{
- mpfr_t uu;
- mp_limb_t up[1];
- unsigned long cnt;
- int inex;
- MPFR_SAVE_EXPO_DECL (expo);
-
- MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
- MPFR_ASSERTD (u == (mp_limb_t) u);
- count_leading_zeros(cnt, (mp_limb_t) u);
- up[0] = (mp_limb_t) u << cnt;
-
- /* Optimization note: Exponent save/restore operations may be
- removed if mpfr_add works even when uu is out-of-range. */
- MPFR_SAVE_EXPO_MARK (expo);
- MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
- inex = mpfr_add(y, x, uu, rnd_mode);
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_check_range(y, inex, rnd_mode);
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0); /* +/-infinity is exact */
+ }
+ MPFR_ASSERTD (MPFR_IS_ZERO (x) && u != 0);
+ /* Note: the fact that u != 0 is important due to signed zeros. */
+ return mpfr_set_ui (y, u, rnd_mode);
}
- else
- /* (unsigned long) 0 is assumed to be a real 0 (unsigned) */
- return mpfr_set (y, x, rnd_mode);
+
+ /* Main code */
+ {
+ mpfr_t uu;
+ mp_limb_t up[1];
+ int cnt;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_STAT_STATIC_ASSERT (MPFR_LIMB_MAX >= ULONG_MAX);
+ /* So, u fits in a mp_limb_t, which justifies the casts below. */
+ MPFR_ASSERTD (u != 0);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ up[0] = (mp_limb_t) u << cnt;
+
+ /* Optimization note: Exponent save/restore operations may be
+ removed if mpfr_add works even when uu is out-of-range. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ inex = mpfr_add (y, x, uu, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd_mode);
+ }
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/agm.c b/Build/source/libs/mpfr/mpfr-src/src/agm.c
index 4e13fb3faa5..bef101c52df 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/agm.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/agm.c
@@ -72,7 +72,10 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mpfr_rnd_t rnd_mode)
}
}
else /* a and b are neither NaN nor Inf, and one is zero */
- { /* If a or b is 0, the result is +0 since a sqrt is positive */
+ { /* If a or b is 0, the result is +0, in particular because the
+ result is always >= 0 with our definition (Maple sometimes
+ chooses a different sign for GaussAGM, but it uses another
+ definition, with possible negative results). */
MPFR_ASSERTD (MPFR_IS_ZERO (op1) || MPFR_IS_ZERO (op2));
MPFR_SET_POS (r);
MPFR_SET_ZERO (r);
@@ -201,7 +204,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mpfr_rnd_t rnd_mode)
goto retry;
}
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
mpfr_sqrt (u, u, MPFR_RNDN);
mpfr_div_2ui (v, v, 1, MPFR_RNDN);
@@ -245,7 +248,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mpfr_rnd_t rnd_mode)
method. */
MPFR_LOG_MSG (("4*eq > p -> underflow\n", 0));
mpfr_clear (w);
- mpfr_clear_underflow ();
+ MPFR_CLEAR_UNDERFLOW ();
}
/* U(k) increases, so that U.V can overflow (but not underflow). */
MPFR_BLOCK (flags2, mpfr_mul (uf, u, v, MPFR_RNDN););
@@ -261,7 +264,7 @@ mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mpfr_rnd_t rnd_mode)
MPFR_LOG_MSG (("Overflow in iteration n = %lu, scaleit = %"
MPFR_EXP_FSPEC "d (%" MPFR_EXP_FSPEC "d)\n",
n, scaleit, scale2));
- mpfr_clear_overflow ();
+ MPFR_CLEAR_OVERFLOW ();
goto retry2;
}
mpfr_sqrt (u, uf, MPFR_RNDN);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ai.c b/Build/source/libs/mpfr/mpfr-src/src/ai.c
index ba65851e3a5..f24e4a4933a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ai.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/ai.c
@@ -45,7 +45,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
*/
-/* Airy function Ai evaluated by the most naive algorithm */
+/* Airy function Ai evaluated by the most naive algorithm.
+ Assume that x is a finite number. */
static int
mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
@@ -72,26 +73,13 @@ mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y) );
- /* Special cases */
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
- {
- if (MPFR_IS_NAN (x))
- {
- MPFR_SET_NAN (y);
- MPFR_RET_NAN;
- }
- else if (MPFR_IS_INF (x))
- return mpfr_set_ui (y, 0, rnd);
- }
-
-
/* Save current exponents range */
MPFR_SAVE_EXPO_MARK (expo);
if (MPFR_UNLIKELY (MPFR_IS_ZERO (x)))
{
mpfr_t y1, y2;
- prec = MPFR_PREC (y) + 3;
+ prec = MPFR_ADD_PREC (MPFR_PREC (y), 3);
mpfr_init2 (y1, prec);
mpfr_init2 (y2, prec);
MPFR_ZIV_INIT (loop, prec);
@@ -133,7 +121,7 @@ mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
/* if x<=0, ????? */
/* We begin with 11 guard bits */
- prec = MPFR_PREC (y)+11;
+ prec = MPFR_ADD_PREC (MPFR_PREC (y), 11);
MPFR_ZIV_INIT (loop, prec);
/* The working precision is heuristically chosen in order to obtain */
@@ -178,7 +166,11 @@ mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
assumed_exponent = 10;
}
- wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 5 + cond + assumed_exponent;
+ {
+ mpfr_prec_t incr =
+ MPFR_INT_CEIL_LOG2 (prec) + 5 + cond + assumed_exponent;
+ wprec = MPFR_ADD_PREC (prec, incr);
+ }
mpfr_init (ti);
mpfr_init (tip1);
@@ -276,8 +268,9 @@ mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
if (correct_bits < prec)
{ /* The precision was badly chosen */
- MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)", 0));
- MPFR_LOG_MSG ((" (E=%ld)\n", (long) MPFR_GET_EXP (s)));
+ MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)"
+ " (E=%" MPFR_EXP_FSPEC "d)\n",
+ (mpfr_eexp_t) MPFR_GET_EXP (s)));
wprec = prec + err + 1;
}
else
@@ -311,7 +304,8 @@ mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
}
-/* Airy function Ai evaluated by Smith algorithm */
+/* Airy function Ai evaluated by Smith algorithm.
+ Assume that x is a finite number. */
static int
mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
@@ -339,18 +333,6 @@ mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
- /* Special cases */
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
- {
- if (MPFR_IS_NAN (x))
- {
- MPFR_SET_NAN (y);
- MPFR_RET_NAN;
- }
- else if (MPFR_IS_INF (x))
- return mpfr_set_ui (y, 0, rnd);
- }
-
/* Save current exponents range */
MPFR_SAVE_EXPO_MARK (expo);
@@ -407,7 +389,7 @@ mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
L = __gmpfr_isqrt (prec);
MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
- z = (mpfr_t *) (*__gmp_allocate_func) ( (L + 1) * sizeof (mpfr_t) );
+ z = (mpfr_t *) mpfr_allocate_func ( (L + 1) * sizeof (mpfr_t) );
MPFR_ASSERTN (z != NULL);
for (j=0; j<=L; j++)
mpfr_init (z[j]);
@@ -557,10 +539,10 @@ mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
for (j=0; j<=L; j++)
mpfr_clear (z[j]);
- (*__gmp_free_func) (z, (L + 1) * sizeof (mpfr_t));
+ mpfr_free_func (z, (L + 1) * sizeof (mpfr_t));
L = __gmpfr_isqrt (t);
MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
- z = (mpfr_t *) (*__gmp_allocate_func) ( (L + 1) * sizeof (mpfr_t));
+ z = (mpfr_t *) mpfr_allocate_func ( (L + 1) * sizeof (mpfr_t));
MPFR_ASSERTN (z != NULL);
for (j=0; j<=L; j++)
mpfr_init (z[j]);
@@ -576,8 +558,9 @@ mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
if (correctBits < prec)
{ /* The precision was badly chosen */
- MPFR_LOG_MSG (("Bad assumption on the exponent of Ai (x)", 0));
- MPFR_LOG_MSG ((" (E=%ld)\n", (long) (MPFR_GET_EXP (result))));
+ MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)"
+ " (E=%" MPFR_EXP_FSPEC "d)\n",
+ (mpfr_eexp_t) MPFR_GET_EXP (result)));
wprec = prec + err + 1;
}
else
@@ -601,7 +584,7 @@ mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
mpfr_clear (tmp2_sp);
for (j=0; j<=L; j++)
mpfr_clear (z[j]);
- (*__gmp_free_func) (z, (L + 1) * sizeof (mpfr_t));
+ mpfr_free_func (z, (L + 1) * sizeof (mpfr_t));
mpfr_clear (s);
mpfr_clear (u0); mpfr_clear (u1);
@@ -636,6 +619,18 @@ mpfr_ai (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
int use_ai2;
MPFR_SAVE_EXPO_DECL (expo);
+ /* Special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ return mpfr_set_ui (y, 0, rnd);
+ }
+
/* The exponent range must be large enough for the computation of temp1. */
MPFR_SAVE_EXPO_MARK (expo);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/asinh.c b/Build/source/libs/mpfr/mpfr-src/src/asinh.c
index 3e79bdbbc7a..aacac89dfa4 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/asinh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/asinh.c
@@ -104,7 +104,7 @@ mpfr_asinh (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
break;
}
- /* actualisation of the precision */
+ /* actualization of the precision */
MPFR_ZIV_NEXT (loop, Nt);
mpfr_set_prec (t, Nt);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/atan.c b/Build/source/libs/mpfr/mpfr-src/src/atan.c
index c6df3c7af54..8fa4f6c178f 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/atan.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/atan.c
@@ -23,31 +23,114 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
+#if GMP_NUMB_BITS == 64
+/* for each pair (r,p), we store a 192-bit approximation of atan(x)/x for
+ x=p/2^r, with lowest limb first.
+ Sage code:
+ for p in range(1,2^ceil(r/2)):
+ x=p/2^r
+ l=floor(2^192*n(atan(x)/x, 300)).digits(2^64)
+ print ("{0x%x, 0x%x, 0x%x}, /"+"* (%d,%d) *"+"/") % (l[0],l[1],l[2],r,p)
+*/
+static const mp_limb_t atan_table[][3] = {
+ {0x6e141587261cdf00, 0x6fe445ecbc3a8d03, 0xed63382b0dda7b45}, /* (1,1) */
+ {0xaa7fa90388b3836b, 0x6dc79ef5f7a217e5, 0xfadbafc96406eb15}, /* (2,1) */
+ {0x319c12cf59d4b2dc, 0xcb2792dc0e2e0d51, 0xffaaddb967ef4e36}, /* (4,1) */
+ {0x8b3957d95d9ad922, 0xc897989f3e888ef7, 0xfeadd4d5617b6e32}, /* (4,2) */
+ {0xc4e6abc8af62e439, 0x4eb9bf602625f0b4, 0xfd0fcdd343cac19b}, /* (4,3) */
+ {0x7c18baeb9bc95789, 0xb12afb6b6d4f7e16, 0xffffaaaaddddb94b}, /* (8,1) */
+ {0x6856a0171a2f001a, 0x62351fbbe60af47, 0xfffeaaadddd4b968}, /* (8,2) */
+ {0x69164c094f49da06, 0xd517294f7373d07a, 0xfffd001032cb1179}, /* (8,3) */
+ {0x20ef65c10deef460, 0xe78c564015f76048, 0xfffaaadddb94d5bb}, /* (8,4) */
+ {0x3ce233aa002f0344, 0x9dd8ea342a65d4cc, 0xfff7ab27a1f32f95}, /* (8,5) */
+ {0xa37f403c7279c5cb, 0x13ab53a1c8db8497, 0xfff40103192ce74d}, /* (8,6) */
+ {0xe5a85657103c1aa8, 0xb8409e6c914191d3, 0xffefac8a9c40a26b}, /* (8,7) */
+ {0x806d0294c0db8816, 0x779d776dda8c6213, 0xffeaaddd4bb12542}, /* (8,8) */
+ {0x5545d1914ef21478, 0x3aea58d6660f5a12, 0xffe5051f0aebf73a}, /* (8,9) */
+ {0x6e47a91d015f4133, 0xc085ab6b490b7f02, 0xffdeb2787d4adac1}, /* (8,10) */
+ {0x4efc1f931f7ec9b3, 0xb7f43cd16195ef4b, 0xffd7b61702b09aad}, /* (8,11) */
+ {0xd27d1dbf55fed60d, 0xd812c11d7d473e5e, 0xffd0102cb3c1bfbe}, /* (8,12) */
+ {0xca629e927383fe97, 0x8c61aedf58e42206, 0xffc7c0f05db9d1b6}, /* (8,13) */
+ {0x4eff0b53d4e905b7, 0x28ac1e800ca31e9d, 0xffbec89d7dddd7e9}, /* (8,14) */
+ {0xb0a7931deec6fe60, 0xb46feea78588554b, 0xffb527743c8cdd8f} /* (8,15) */
+ };
+
+static void
+set_table (mpfr_t y, const mp_limb_t x[3])
+{
+ mpfr_prec_t p = MPFR_PREC(y);
+ mp_size_t n = MPFR_PREC2LIMBS(p);
+ mpfr_prec_t sh;
+ mp_limb_t *yp = MPFR_MANT(y);
+
+ MPFR_UNSIGNED_MINUS_MODULO (sh, p);
+ mpn_copyi (yp, x + 3 - n, n);
+ yp[0] &= ~MPFR_LIMB_MASK(sh);
+ MPFR_SET_EXP(y, 0);
+}
+#endif
+
/* If x = p/2^r, put in y an approximation of atan(x)/x using 2^m terms
for the series expansion, with an error of at most 1 ulp.
- Assumes |x| < 1.
+ Assumes 0 < x < 1, thus 1 <= p < 2^r.
+ More precisely, p consists of the floor(r/2) bits of the binary expansion
+ of a number 0 < s < 1:
+ * the bit of weight 2^-1 is for r=1, thus p <= 1
+ * the bit of weight 2^-2 is for r=2, thus p <= 1
+ * the two bits of weight 2^-3 and 2^-4 are for r=4, thus p <= 3
+ * more generally p < 2^(r/2).
If X=x^2, we want 1 - X/3 + X^2/5 - ... + (-1)^k*X^k/(2k+1) + ...
- Assume p is non-zero.
-
When we sum terms up to x^k/(2k+1), the denominator Q[0] is
3*5*7*...*(2k+1) ~ (2k/e)^k.
+
+ The tab[] array should have at least 3*(m+1) entries.
*/
static void
-mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
+mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, unsigned long r, int m, mpz_t *tab)
{
mpz_t *S, *Q, *ptoj;
- unsigned long n, i, k, j, l;
+ mp_bitcnt_t n, h, j; /* unsigned type, which is >= unsigned long */
mpfr_exp_t diff, expo;
- int im, done;
- mpfr_prec_t mult, *accu, *log2_nb_terms;
+ int im, i, k, l, done;
+ mpfr_prec_t mult;
+ mpfr_prec_t accu[MPFR_PREC_BITS], log2_nb_terms[MPFR_PREC_BITS];
mpfr_prec_t precy = MPFR_PREC(y);
MPFR_ASSERTD(mpz_cmp_ui (p, 0) != 0);
+ MPFR_ASSERTD (m+1 <= MPFR_PREC_BITS);
- accu = (mpfr_prec_t*) (*__gmp_allocate_func) ((2 * m + 2) * sizeof (mpfr_prec_t));
- log2_nb_terms = accu + m + 1;
+#if GMP_NUMB_BITS == 64
+ /* tabulate values for small precision and small value of r (which are the
+ most expensive to compute) */
+ if (precy <= 192)
+ {
+ switch (r)
+ {
+ case 1:
+ /* p has 1 bit: necessarily p=1 */
+ MPFR_ASSERTD(mpz_cmp_ui (p, 1) == 0);
+ set_table (y, atan_table[0]);
+ return;
+ case 2:
+ /* p has 1 bit: necessarily p=1 too */
+ MPFR_ASSERTD(mpz_cmp_ui (p, 1) == 0);
+ set_table (y, atan_table[1]);
+ return;
+ case 4:
+ /* p has at most 2 bits: 1 <= p <= 3 */
+ MPFR_ASSERTD(1 <= mpz_get_ui (p) && mpz_get_ui (p) <= 3);
+ set_table (y, atan_table[1 + mpz_get_ui (p)]);
+ return;
+ case 8:
+ /* p has at most 4 bits: 1 <= p <= 15 */
+ MPFR_ASSERTD(1 <= mpz_get_ui (p) && mpz_get_ui (p) <= 15);
+ set_table (y, atan_table[4 + mpz_get_ui (p)]);
+ return;
+ }
+ }
+#endif
/* Set Tables */
S = tab; /* S */
@@ -61,9 +144,12 @@ mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
/* Normalize p */
n = mpz_scan1 (p, 0);
- mpz_tdiv_q_2exp (p, p, n); /* exact */
- MPFR_ASSERTD (r > n);
- r -= n;
+ if (n > 0)
+ {
+ mpz_tdiv_q_2exp (p, p, n); /* exact */
+ MPFR_ASSERTD (r > n);
+ r -= n;
+ }
/* since |p/2^r| < 1, and p is a non-zero integer, necessarily r > 0 */
MPFR_ASSERTD (mpz_sgn (p) > 0);
@@ -90,6 +176,7 @@ mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
mpz_mul (ptoj[im], ptoj[im - 1], ptoj[im - 1]);
/* main loop */
n = 1UL << m;
+ MPFR_ASSERTN (n != 0); /* no overflow */
/* the ith term being X^i/(2i+1) with X=p/2^r, we can stop when
p^i/2^(r*i) < 2^(-precy), i.e. r*i > precy + log2(p^i) */
for (i = k = done = 0; (i < n) && (done == 0); i += 2, k ++)
@@ -115,7 +202,6 @@ mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
log2_nb_terms[k-1] = l + 1;
/* now S[k-1]/Q[k-1] corresponds to 2^(l+1) terms */
MPFR_MPZ_SIZEINBASE2(mult, ptoj[l+1]);
- /* FIXME: precompute bits(ptoj[l+1]) outside the loop? */
mult = (r << (l + 1)) - mult - 1;
accu[k-1] = (k == 1) ? mult : accu[k-2] + mult;
if (accu[k-1] > precy)
@@ -127,7 +213,10 @@ mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
we can stop when r*i > precy i.e. i > precy/r */
{
n = 1UL << m;
- for (i = k = 0; (i < n) && (i <= precy / r); i += 2, k ++)
+ if (precy / r <= n)
+ n = (precy / r) + 1;
+ MPFR_ASSERTN (n != 0); /* no overflow */
+ for (i = k = 0; i < n; i += 2, k ++)
{
mpz_set_ui (Q[k + 1], 2 * i + 3);
mpz_mul_2exp (S[k], Q[k+1], r);
@@ -148,22 +237,20 @@ mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
}
/* we need to combine S[0]/Q[0]...S[k-1]/Q[k-1] */
- l = 0; /* number of terms accumulated in S[k]/Q[k] */
+ h = 0; /* number of terms accumulated in S[k]/Q[k] */
while (k > 1)
{
k --;
/* combine S[k-1]/Q[k-1] and S[k]/Q[k] */
- j = log2_nb_terms[k-1];
mpz_mul (S[k], S[k], Q[k-1]);
if (mpz_cmp_ui (p, 1) != 0)
- mpz_mul (S[k], S[k], ptoj[j]);
+ mpz_mul (S[k], S[k], ptoj[log2_nb_terms[k-1]]);
mpz_mul (S[k-1], S[k-1], Q[k]);
- l += 1 << log2_nb_terms[k];
- mpz_mul_2exp (S[k-1], S[k-1], r * l);
+ h += (mp_bitcnt_t) 1 << log2_nb_terms[k];
+ mpz_mul_2exp (S[k-1], S[k-1], r * h);
mpz_add (S[k-1], S[k-1], S[k]);
mpz_mul (Q[k-1], Q[k-1], Q[k]);
}
- (*__gmp_free_func) (accu, (2 * m + 2) * sizeof (mpfr_prec_t));
MPFR_MPZ_SIZEINBASE2 (diff, S[0]);
diff -= 2 * precy;
@@ -183,7 +270,9 @@ mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
mpz_tdiv_q (S[0], S[0], Q[0]);
mpfr_set_z (y, S[0], MPFR_RNDD);
- MPFR_SET_EXP (y, MPFR_EXP(y) + expo - r * (i - 1));
+ /* TODO: Check/prove that the following expression doesn't overflow. */
+ expo = MPFR_GET_EXP (y) + expo - r * (i - 1);
+ MPFR_SET_EXP (y, expo);
}
int
@@ -191,7 +280,7 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
mpfr_t xp, arctgt, sk, tmp, tmp2;
mpz_t ukz;
- mpz_t *tabz;
+ mpz_t tabz[3*(MPFR_PREC_BITS+1)];
mpfr_exp_t exptol;
mpfr_prec_t prec, realprec, est_lost, lost;
unsigned long twopoweri, log2p, red;
@@ -270,10 +359,9 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
prec = realprec + GMP_NUMB_BITS;
/* Initialisation */
- mpz_init (ukz);
+ mpz_init2 (ukz, prec); /* ukz will need 'prec' bits below */
MPFR_GROUP_INIT_4 (group, prec, sk, tmp, tmp2, arctgt);
oldn0 = 0;
- tabz = (mpz_t *) 0;
MPFR_ZIV_INIT (loop, prec);
for (;;)
@@ -301,21 +389,13 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
/* Initialisation */
MPFR_GROUP_REPREC_4 (group, prec, sk, tmp, tmp2, arctgt);
- if (MPFR_LIKELY (oldn0 == 0))
- {
- oldn0 = 3 * (n0 + 1);
- tabz = (mpz_t *) (*__gmp_allocate_func) (oldn0 * sizeof (mpz_t));
- for (i = 0; i < oldn0; i++)
- mpz_init (tabz[i]);
- }
- else if (MPFR_UNLIKELY (oldn0 < 3 * (n0 + 1)))
- {
- tabz = (mpz_t *) (*__gmp_reallocate_func)
- (tabz, oldn0 * sizeof (mpz_t), 3 * (n0 + 1)*sizeof (mpz_t));
- for (i = oldn0; i < 3 * (n0 + 1); i++)
- mpz_init (tabz[i]);
- oldn0 = 3 * (n0 + 1);
- }
+ MPFR_ASSERTD (n0 <= MPFR_PREC_BITS);
+ /* Note: the tabz[] entries are used to get a rational approximation
+ of atan(x) to precision 'prec', thus allocating them to 'prec' bits
+ should be good enough. */
+ for (i = oldn0; i < 3 * (n0 + 1); i++)
+ mpz_init2 (tabz[i], prec);
+ oldn0 = 3 * (n0 + 1);
/* The mpfr_ui_div below mustn't underflow. This is guaranteed by
MPFR_SAVE_EXPO_MARK, but let's check that for maintainability. */
@@ -334,7 +414,7 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
for (red = 0; MPFR_GET_EXP(sk) > - (mpfr_exp_t) log2p; red ++)
{
lost = 9 - 2 * MPFR_EXP(sk);
- mpfr_mul (tmp, sk, sk, MPFR_RNDN);
+ mpfr_sqr (tmp, sk, MPFR_RNDN);
mpfr_add_ui (tmp, tmp, 1, MPFR_RNDN);
mpfr_sqrt (tmp, tmp, MPFR_RNDN);
mpfr_sub_ui (tmp, tmp, 1, MPFR_RNDN);
@@ -345,25 +425,25 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_div (sk, tmp, sk, MPFR_RNDN);
}
- /* we started from x0 = 1/|x| if |x| > 1, and |x| otherwise, thus
+ /* We started from x0 = 1/|x| if |x| > 1, and |x| otherwise, thus
we had x0 = min(|x|, 1/|x|) <= 1, and applied 'red' times the
- argument reduction x -> (sqrt(1+x^2)-1)/x, which keeps 0 < x < 1,
- thus 0 < sk <= 1, and sk=1 can occur only if red=0 */
-
- /* If sk=1, then if |x| < 1, we have 1 - 2^(-prec-1) <= |x| < 1,
- or if |x| > 1, we have 1 - 2^(-prec-1) <= 1/|x| < 1, thus in all
- cases ||x| - 1| <= 2^(-prec), from which it follows
- |atan|x| - Pi/4| <= 2^(-prec), given the Taylor expansion
- atan(1+x) = Pi/4 + x/2 - x^2/4 + ...
- Since Pi/4 = 0.785..., the error is at most one ulp.
+ argument reduction x -> (sqrt(1+x^2)-1)/x, which keeps 0 < x <= 1 */
+
+ /* We first show that if the for-loop is executed at least once, then
+ sk < 1 after the loop. Indeed for 1/2 <= x <= 1, interval
+ arithmetic with precision 5 shows that (sqrt(1+x^2)-1)/x,
+ when evaluated with rounding to nearest, gives a value <= 0.875.
+ Now assume 2^(-k-1) <= x <= 2^(-k) for k >= 1.
+ Then o(x^2) <= 2^(-2k), o(1+x^2) <= 1+2^(-2k),
+ o(sqrt(1+x^2)) <= 1+2^(-2k-1), o(sqrt(1+x^2)-1) <= 2^(-2k-1),
+ and o((sqrt(1+x^2)-1)/x) <= 2^(-k) <= 1/2.
+
+ Now if sk=1 before the loop, then EXP(sk)=1 and since log2p >= 0,
+ the loop is performed at least once, thus the case sk=1 cannot
+ happen below.
*/
- if (MPFR_UNLIKELY(mpfr_cmp_ui (sk, 1) == 0))
- {
- mpfr_const_pi (arctgt, MPFR_RNDN); /* 1/2 ulp extra error */
- mpfr_div_2ui (arctgt, arctgt, 2, MPFR_RNDN); /* exact */
- realprec = prec - 2;
- goto can_round;
- }
+
+ MPFR_ASSERTD(mpfr_cmp_ui (sk, 1) < 0);
/* Assignation */
MPFR_SET_ZERO (arctgt);
@@ -416,7 +496,6 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
MPFR_SET_POS (arctgt);
- can_round:
if (MPFR_LIKELY (MPFR_CAN_ROUND (arctgt, realprec + est_lost - lost,
MPFR_PREC (atan), rnd_mode)))
break;
@@ -429,7 +508,6 @@ mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
for (i = 0 ; i < oldn0 ; i++)
mpz_clear (tabz[i]);
mpz_clear (ukz);
- (*__gmp_free_func) (tabz, oldn0 * sizeof (mpz_t));
MPFR_GROUP_CLEAR (group);
MPFR_SAVE_EXPO_FREE (expo);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/atan2.c b/Build/source/libs/mpfr/mpfr-src/src/atan2.c
index 41d49f25068..57bc14f798e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/atan2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/atan2.c
@@ -130,9 +130,8 @@ mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_const_pi (tmp2, MPFR_RNDN);
mpfr_mul_ui (tmp2, tmp2, 3, MPFR_RNDN); /* Error <= 2 */
mpfr_div_2ui (tmp2, tmp2, 2, MPFR_RNDN);
- if (mpfr_round_p (MPFR_MANT (tmp2), MPFR_LIMB_SIZE (tmp2),
- MPFR_PREC (tmp2) - 2,
- MPFR_PREC (dest) + (rnd_mode == MPFR_RNDN)))
+ if (MPFR_CAN_ROUND (tmp2, MPFR_PREC (tmp2) - 2,
+ MPFR_PREC (dest), rnd_mode))
break;
MPFR_ZIV_NEXT (loop2, prec2);
mpfr_set_prec (tmp2, prec2);
@@ -155,11 +154,11 @@ mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
/* When x is a power of two, we call directly atan(y/x) since y/x is
exact. */
- if (MPFR_UNLIKELY (MPFR_IS_POWER_OF_2 (x)))
+ if (MPFR_UNLIKELY (MPFR_IS_POS (x) && mpfr_powerof2_raw (x)))
{
int r;
mpfr_t yoverx;
- unsigned int saved_flags = __gmpfr_flags;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
mpfr_init2 (yoverx, MPFR_PREC (y));
if (MPFR_LIKELY (mpfr_div_2si (yoverx, y, MPFR_GET_EXP (x) - 1,
diff --git a/Build/source/libs/mpfr/mpfr-src/src/atanh.c b/Build/source/libs/mpfr/mpfr-src/src/atanh.c
index ec5a6cf6f1f..5f9953c4e7c 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/atanh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/atanh.c
@@ -23,11 +23,84 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
- /* The computation of atanh is done by
- atanh= 1/2*ln(x+1)-1/2*ln(1-x) */
+/* Put in y an approximation of atanh(x) for x small.
+ We assume x <= 1/2, in which case:
+ x <= y ~ atanh(x) = x + x^3/3 + x^5/5 + x^7/7 + ... <= 2*x.
+ Return k such that the error is bounded by 2^k*ulp(y).
+*/
+static int
+mpfr_atanh_small (mpfr_ptr y, mpfr_srcptr x)
+{
+ mpfr_prec_t p = MPFR_PREC(y), err;
+ mpfr_t x2, t, u;
+ unsigned long i;
+ int k;
+
+ MPFR_ASSERTD(MPFR_GET_EXP (x) <= -1);
+
+ /* in the following, theta represents a value with |theta| <= 2^(1-p)
+ (might be a different value each time) */
+
+ mpfr_init2 (t, p);
+ mpfr_init2 (u, p);
+ mpfr_init2 (x2, p);
+ mpfr_set (t, x, MPFR_RNDF); /* t = x * (1 + theta) */
+ mpfr_set (y, t, MPFR_RNDF); /* exact */
+ mpfr_mul (x2, x, x, MPFR_RNDF); /* x2 = x^2 * (1 + theta) */
+ for (i = 3; ; i += 2)
+ {
+ mpfr_mul (t, t, x2, MPFR_RNDF); /* t = x^i * (1 + theta)^i */
+ mpfr_div_ui (u, t, i, MPFR_RNDF); /* u = x^i/i * (1 + theta)^(i+1) */
+ if (MPFR_GET_EXP (u) <= MPFR_GET_EXP (y) - p) /* |u| < ulp(y) */
+ break;
+ mpfr_add (y, y, u, MPFR_RNDF); /* error <= ulp(y) */
+ }
+ /* We assume |(1 + theta)^(i+1)| <= 2.
+ The neglected part is at most |u| + |u|/4 + |u|/16 + ... <= 4/3*|u|,
+ which has to be multiplied by |(1 + theta)^(i+1)| <= 2, thus at most
+ 3 ulp(y).
+ The rounding error on y is bounded by:
+ * for the (i-3)/2 add/sub, each error is bounded by ulp(y_i),
+ where y_i is the current value of y, which is bounded by ulp(y)
+ for y the final value (since it increases in absolute value),
+ this yields (i-3)/2*ulp(y)
+ * from Lemma 3.1 from [Higham02] (see algorithms.tex),
+ the relative error on u at step i is bounded by:
+ (i+1)*epsilon/(1-(i+1)*epsilon) where epsilon = 2^(1-p).
+ If (i+1)*epsilon <= 1/2, then the relative error on u at
+ step i is bounded by 2*(i+1)*epsilon, and since |u| <= 1/2^(i+1)
+ at step i, this gives an absolute error bound of;
+ 2*epsilon*x*(4/2^4 + 6/2^6 + 8/2^8 + ...) = 2*2^(1-p)*x*(7/18) =
+ 14/9*2^(-p)*x <= 2*ulp(x).
+
+ If (i+1)*epsilon <= 1/2, then the relative error on u at step i
+ is bounded by (i+1)*epsilon/(1-(i+1)*epsilon) <= 1, thus it follows
+ |(1 + theta)^(i+1)| <= 2.
+
+ Finally the total error is bounded by 3*ulp(y) + (i-3)/2*ulp(y) +2*ulp(x).
+ Since x <= 2*y, we have ulp(x) <= 2*ulp(y), thus the error is bounded by:
+ (i+7)/2*ulp(y).
+ */
+ err = (i + 8) / 2; /* ceil((i+7)/2) */
+ k = __gmpfr_int_ceil_log2 (err);
+ MPFR_ASSERTN(k + 2 < p);
+ /* if k + 2 < p, since k = ceil(log2(err)), we have err <= 2^k <= 2^(p-3),
+ thus i+7 <= 2*err <= 2^(p-2), thus (i+7)*epsilon <= 1/2, which implies
+ our assumption (i+1)*epsilon <= 1/2. */
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpfr_clear (x2);
+ return k;
+}
+
+/* The computation of atanh is done by:
+ atanh = ln((1+x)/(1-x)) / 2
+ except when x is very small, in which case atanh = x + tiny error,
+ and when x is small, where we use directly the Taylor expansion.
+*/
int
-mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
+mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t x, t, te;
@@ -67,7 +140,7 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
{
MPFR_SET_INF (y);
MPFR_SET_SAME_SIGN (y, xt);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0);
}
MPFR_SET_NAN (y);
@@ -85,29 +158,42 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
MPFR_TMP_INIT_ABS (x, xt);
Ny = MPFR_PREC (y);
Nt = MAX (Nx, Ny);
- /* the optimal number of bits : see algorithms.ps */
Nt = Nt + MPFR_INT_CEIL_LOG2 (Nt) + 4;
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
mpfr_init2 (te, Nt);
- /* First computation of cosh */
MPFR_ZIV_INIT (loop, Nt);
for (;;)
{
+ int k;
+
+ /* small case: assuming the AGM algorithm used by mpfr_log uses
+ log2(p) steps for a precision of p bits, we try the special
+ variant whenever EXP(x) <= -p/log2(p). */
+ k = 1 + __gmpfr_int_ceil_log2 (Ny); /* the +1 avoids a division by 0
+ when Ny=1 */
+ if (MPFR_GET_EXP (x) <= - 1 - (mpfr_exp_t) (Ny / k))
+ /* this implies EXP(x) <= -1 thus x < 1/2 */
+ {
+ err = Nt - mpfr_atanh_small (t, x);
+ goto round;
+ }
+
/* compute atanh */
- mpfr_ui_sub (te, 1, x, MPFR_RNDU); /* (1-xt)*/
- mpfr_add_ui (t, x, 1, MPFR_RNDD); /* (xt+1)*/
- mpfr_div (t, t, te, MPFR_RNDN); /* (1+xt)/(1-xt)*/
- mpfr_log (t, t, MPFR_RNDN); /* ln((1+xt)/(1-xt))*/
- mpfr_div_2ui (t, t, 1, MPFR_RNDN); /* (1/2)*ln((1+xt)/(1-xt))*/
+ mpfr_ui_sub (te, 1, x, MPFR_RNDU); /* (1-x) with x = |xt| */
+ mpfr_add_ui (t, x, 1, MPFR_RNDD); /* (1+x) */
+ mpfr_div (t, t, te, MPFR_RNDN); /* (1+x)/(1-x) */
+ mpfr_log (t, t, MPFR_RNDN); /* ln((1+x)/(1-x)) */
+ mpfr_div_2ui (t, t, 1, MPFR_RNDN); /* ln((1+x)/(1-x)) / 2 */
/* error estimate: see algorithms.tex */
/* FIXME: this does not correspond to the value in algorithms.tex!!! */
- /* err=Nt-__gmpfr_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_GET_EXP (t), 0) + 1);
+ round:
if (MPFR_LIKELY (MPFR_IS_ZERO (t)
|| MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
break;
@@ -121,10 +207,9 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt));
- mpfr_clear(t);
- mpfr_clear(te);
+ mpfr_clear (t);
+ mpfr_clear (te);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (y, inexact, rnd_mode);
}
-
diff --git a/Build/source/libs/mpfr/mpfr-src/src/bernoulli.c b/Build/source/libs/mpfr/mpfr-src/src/bernoulli.c
index 26ecf25bd7c..399d31c729d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/bernoulli.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/bernoulli.c
@@ -22,59 +22,234 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-/* assuming b[0]...b[2(n-1)] are computed, computes and stores B[2n]*(2n+1)!
-
- t/(exp(t)-1) = sum(B[j]*t^j/j!, j=0..infinity)
- thus t = (exp(t)-1) * sum(B[j]*t^j/j!, n=0..infinity).
- Taking the coefficient of degree n+1 > 1, we get:
- 0 = sum(1/(n+1-k)!*B[k]/k!, k=0..n)
- which gives:
- B[n] = -sum(binomial(n+1,k)*B[k], k=0..n-1)/(n+1).
-
- Let C[n] = B[n]*(n+1)!.
- Then C[n] = -sum(binomial(n+1,k)*C[k]*n!/(k+1)!, k=0..n-1),
- which proves that the C[n] are integers.
-*/
-mpz_t*
+/* assume p >= 5 and is odd */
+static int
+is_prime (unsigned long p)
+{
+ unsigned long q;
+
+ MPFR_ASSERTD (p >= 5 && (p & 1) != 0);
+ for (q = 3; q * q <= p; q += 2)
+ if ((p % q) == 0)
+ return 0;
+ return 1;
+}
+
+/* Computes and stores B[2n]*(2n+1)! in b[n]
+ using Von Staudt–Clausen theorem, which says that the denominator of B[n]
+ divides the product of all primes p such that p-1 divides n.
+ Since B[n] = zeta(n) * 2*n!/(2pi)^n, we compute an approximation of
+ d * zeta(n) * 2*n!/(2pi)^n and round it to the nearest integer. */
+static void
mpfr_bernoulli_internal (mpz_t *b, unsigned long n)
{
+ unsigned long p, err, zn;
+ mpz_t s, t, u, den;
+ mpz_ptr num;
+ mpfr_t y, z;
+ int ok;
+ /* Prec[n/2] is minimal precision so that result is correct for B[n] */
+ mpfr_prec_t prec;
+ mpfr_prec_t Prec[] = {0, 5, 5, 6, 6, 9, 16, 10, 19, 23, 25, 27, 35, 31,
+ 42, 51, 51, 50, 73, 60, 76, 79, 83, 87, 101, 97,
+ 108, 113, 119, 125, 149, 133, 146};
+
+ mpz_init (b[n]);
+
if (n == 0)
{
- b = (mpz_t *) (*__gmp_allocate_func) (sizeof (mpz_t));
- mpz_init_set_ui (b[0], 1);
+ mpz_set_ui (b[0], 1);
+ return;
+ }
+
+ /* compute denominator */
+ num = b[n];
+ n = 2 * n;
+ mpz_init_set_ui (den, 6);
+ for (p = 5; p <= n+1; p += 2)
+ {
+ if ((n % (p-1)) == 0 && is_prime (p))
+ mpz_mul_ui (den, den, p);
+ }
+ if (n <= 64)
+ prec = Prec[n >> 1];
+ else
+ {
+ /* evaluate the needed precision: zeta(n)*2*den*n!/(2*pi)^n <=
+ 3.3*den*(n/e/2/pi)^n*sqrt(2*pi*n) */
+ prec = __gmpfr_ceil_log2 (7.0 * (double) n); /* bound 2*pi by 7 */
+ prec = (prec + 1) >> 1; /* sqrt(2*pi*n) <= 2^prec */
+ mpfr_init2 (z, 53);
+ mpfr_set_ui_2exp (z, 251469612, -32, MPFR_RNDU); /* 1/e/2/pi <= z */
+ mpfr_mul_ui (z, z, n, MPFR_RNDU);
+ mpfr_log2 (z, z, MPFR_RNDU);
+ mpfr_mul_ui (z, z, n, MPFR_RNDU);
+ p = mpfr_get_ui (z, MPFR_RNDU); /* (n/e/2/pi)^n <= 2^p */
+ mpfr_clear (z);
+ /* the +14 term ensures no rounding failure up to n=10000 */
+ prec += p + mpz_sizeinbase (den, 2) + 14;
+ }
+
+ try_again:
+ mpz_init (s);
+ mpz_init (t);
+ mpz_init (u);
+ mpz_set_ui (u, 1);
+ mpz_mul_2exp (u, u, prec); /* u = 2^prec */
+ mpz_ui_pow_ui (t, 3, n);
+ mpz_fdiv_q (s, u, t); /* multiply all terms by 2^prec */
+ /* we compute a lower bound of the series, thus the final result cannot
+ be too large */
+ for (p = 4; mpz_cmp_ui (t, 0) > 0; p++)
+ {
+ mpz_ui_pow_ui (t, p, n);
+ mpz_fdiv_q (t, u, t);
+ /* 2^prec/p^n-1 < t <= 2^prec/p^n */
+ mpz_add (s, s, t);
}
+ /* sum(2^prec/q^n-1, q=3..p) < t <= sum(2^prec/q^n, q=3..p)
+ thus the error on the truncated series is at most p-2.
+ The neglected part of the series is R = sum(1/x^n, x=p+1..infinity)
+ with int(1/x^n, x=p+1..infinity) <= R <= int(1/x^n, x=p..infinity)
+ thus 1/(n-1)/(p+1)^(n-1) <= R <= 1/(n-1)/p^(n-1). The difference between
+ the lower and upper bound is bounded by p^(-n), which is bounded by
+ 2^(-prec) since t=0 in the above loop */
+ mpz_ui_pow_ui (t, p, n - 1);
+ mpz_mul_ui (t, t, n - 1);
+ mpz_cdiv_q (t, u, t);
+ mpz_add (s, s, t);
+ /* now 2^prec * (zeta(n)-1-1/2^n) - p < s <= 2^prec * (zeta(n)-1-1/2^n) */
+ /* add 1 which is 2^prec */
+ mpz_add (s, s, u);
+ /* add 1/2^n which is 2^(prec-n) */
+ mpz_cdiv_q_2exp (u, u, n);
+ mpz_add (s, s, u);
+ /* now 2^prec * zeta(n) - p < s <= 2^prec * zeta(n) */
+ /* multiply by n! */
+ mpz_fac_ui (t, n);
+ mpz_mul (s, s, t);
+ /* multiply by 2*den */
+ mpz_mul (s, s, den);
+ mpz_mul_2exp (s, s, 1);
+ /* now convert to mpfr */
+ mpfr_init2 (z, prec);
+ mpfr_set_z (z, s, MPFR_RNDZ);
+ /* now (2^prec * zeta(n) - p) * 2*den*n! - ulp(z) < z <=
+ 2^prec * zeta(n) * 2*den*n!.
+ Since z <= 2^prec * zeta(n) * 2*den*n!,
+ ulp(z) <= 2*zeta(n) * 2*den*n!, thus
+ (2^prec * zeta(n)-(p+1)) * 2*den*n! < z <= 2^prec * zeta(n) * 2*den*n! */
+ mpfr_div_2exp (z, z, prec, MPFR_RNDZ);
+ /* now (zeta(n) - (p+1)/2^prec) * 2*den*n! < z <= zeta(n) * 2*den*n! */
+ /* divide by (2pi)^n */
+ mpfr_init2 (y, prec);
+ mpfr_const_pi (y, MPFR_RNDU);
+ /* pi <= y <= pi * (1 + 2^(1-prec)) */
+ mpfr_mul_2exp (y, y, 1, MPFR_RNDU);
+ /* 2pi <= y <= 2pi * (1 + 2^(1-prec)) */
+ mpfr_pow_ui (y, y, n, MPFR_RNDU);
+ /* (2pi)^n <= y <= (2pi)^n * (1 + 2^(1-prec))^(n+1) */
+ mpfr_div (z, z, y, MPFR_RNDZ);
+ /* now (zeta(n) - (p+1)/2^prec) * 2*den*n! / (2pi)^n / (1+2^(1-prec))^(n+1)
+ <= z <= zeta(n) * 2*den*n! / (2pi)^n, and since zeta(n) >= 1:
+ den * B[n] * (1 - (p+1)/2^prec) / (1+2^(1-prec))^(n+1)
+ <= z <= den * B[n]
+ Since 1 / (1+2^(1-prec))^(n+1) >= (1 - 2^(1-prec))^(n+1) >=
+ 1 - (n+1) * 2^(1-prec):
+ den * B[n] / (2pi)^n * (1 - (p+1)/2^prec) * (1-(n+1)*2^(1-prec))
+ <= z <= den * B[n] thus
+ den * B[n] * (1 - (2n+p+3)/2^prec) <= z <= den * B[n] */
+
+ /* the error is bounded by 2^(EXP(z)-prec) * (2n+p+3) */
+ for (err = 0, p = 2 * n + p + 3; p > 1; err++, p = (p + 1) >> 1);
+ zn = MPFR_LIMB_SIZE(z) * GMP_NUMB_BITS; /* total number of bits of z */
+ if (err >= prec)
+ ok = 0;
else
{
- mpz_t t;
- unsigned long k;
-
- b = (mpz_t *) (*__gmp_reallocate_func)
- (b, n * sizeof (mpz_t), (n + 1) * sizeof (mpz_t));
- mpz_init (b[n]);
- /* b[n] = -sum(binomial(2n+1,2k)*C[k]*(2n)!/(2k+1)!, k=0..n-1) */
- mpz_init_set_ui (t, 2 * n + 1);
- mpz_mul_ui (t, t, 2 * n - 1);
- mpz_mul_ui (t, t, 2 * n);
- mpz_mul_ui (t, t, n);
- mpz_fdiv_q_ui (t, t, 3); /* exact: t=binomial(2*n+1,2*k)*(2*n)!/(2*k+1)!
- for k=n-1 */
- mpz_mul (b[n], t, b[n-1]);
- for (k = n - 1; k-- > 0;)
+ err = prec - err;
+ /* now the absolute error is bounded by 2^(EXP(z) - err):
+ den * B[n] - 2^(EXP(z) - err) <= z <= den * B[n]
+ thus if subtracting 2^(EXP(z) - err) does not change the rounding
+ (up) we are ok */
+ err = mpn_scan1 (MPFR_MANT(z), zn - err);
+ /* weight of this 1 bit is 2^(EXP(z) - zn + err) */
+ ok = MPFR_EXP(z) < zn - err;
+ }
+ mpfr_get_z (num, z, MPFR_RNDU);
+ if ((n & 2) == 0)
+ mpz_neg (num, num);
+
+ /* multiply by (n+1)! */
+ mpz_mul_ui (t, t, n + 1);
+ mpz_divexact (t, t, den); /* t was still n! */
+ mpz_mul (num, num, t);
+ mpz_set_ui (den, 1);
+
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpz_clear (s);
+ mpz_clear (t);
+ mpz_clear (u);
+
+ if (!ok)
+ {
+ prec += prec / 10;
+ goto try_again;
+ }
+
+ mpz_clear (den);
+}
+
+static MPFR_THREAD_ATTR mpz_t *bernoulli_table = NULL;
+static MPFR_THREAD_ATTR unsigned long bernoulli_size = 0;
+static MPFR_THREAD_ATTR unsigned long bernoulli_alloc = 0;
+
+mpz_srcptr
+mpfr_bernoulli_cache (unsigned long n)
+{
+ unsigned long i;
+
+ if (n >= bernoulli_size)
+ {
+ if (bernoulli_alloc == 0)
+ {
+ bernoulli_alloc = MAX(16, n + n/4);
+ bernoulli_table = (mpz_t *)
+ mpfr_allocate_func (bernoulli_alloc * sizeof (mpz_t));
+ bernoulli_size = 0;
+ }
+ else if (n >= bernoulli_alloc)
+ {
+ bernoulli_table = (mpz_t *) mpfr_reallocate_func
+ (bernoulli_table, bernoulli_alloc * sizeof (mpz_t),
+ (n + n/4) * sizeof (mpz_t));
+ bernoulli_alloc = n + n/4;
+ }
+ MPFR_ASSERTD (bernoulli_alloc > n);
+ MPFR_ASSERTD (bernoulli_size >= 0);
+ for (i = bernoulli_size; i <= n; i++)
+ mpfr_bernoulli_internal (bernoulli_table, i);
+ bernoulli_size = n+1;
+ }
+ MPFR_ASSERTD (bernoulli_size > n);
+ return bernoulli_table[n];
+}
+
+void
+mpfr_bernoulli_freecache (void)
+{
+ unsigned long i;
+
+ if (bernoulli_table != NULL)
+ {
+ for (i = 0; i < bernoulli_size; i++)
{
- mpz_mul_ui (t, t, 2 * k + 1);
- mpz_mul_ui (t, t, 2 * k + 2);
- mpz_mul_ui (t, t, 2 * k + 2);
- mpz_mul_ui (t, t, 2 * k + 3);
- mpz_fdiv_q_ui (t, t, 2 * (n - k) + 1);
- mpz_fdiv_q_ui (t, t, 2 * (n - k));
- mpz_addmul (b[n], t, b[k]);
+ mpz_clear (bernoulli_table[i]);
}
- /* take into account C[1] */
- mpz_mul_ui (t, t, 2 * n + 1);
- mpz_fdiv_q_2exp (t, t, 1);
- mpz_sub (b[n], b[n], t);
- mpz_neg (b[n], b[n]);
- mpz_clear (t);
+ mpfr_free_func (bernoulli_table, bernoulli_alloc * sizeof (mpz_t));
+ bernoulli_table = NULL;
+ bernoulli_alloc = 0;
+ bernoulli_size = 0;
}
- return b;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/beta.c b/Build/source/libs/mpfr/mpfr-src/src/beta.c
new file mode 100644
index 00000000000..3fb9b9a774c
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/beta.c
@@ -0,0 +1,345 @@
+/* mpfr_beta -- beta function
+
+Copyright 2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H /* for MPFR_INT_CEIL_LOG2 */
+#include "mpfr-impl.h"
+
+/* use formula (6.2.2) from Abramowitz & Stegun:
+ beta(z,w) = gamma(z)*gamma(w)/gamma(z+w) */
+int
+mpfr_beta (mpfr_ptr r, mpfr_srcptr z, mpfr_srcptr w, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t emin, emax;
+ mpfr_uexp_t pmin;
+ mpfr_prec_t prec;
+ mpfr_t z_plus_w, tmp, tmp2;
+ int inex, w_integer;
+ MPFR_GROUP_DECL (group);
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (mpfr_less_p (z, w))
+ return mpfr_beta (r, w, z, rnd_mode);
+
+ /* Now, either z and w are unordered (at least one is a NaN), or z >= w. */
+
+ if (MPFR_ARE_SINGULAR (z, w))
+ {
+ /* if z or w is NaN, return NaN */
+ if (MPFR_IS_NAN (z) || MPFR_IS_NAN (w))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (z) || MPFR_IS_INF (w))
+ {
+ /* Since we have z >= w:
+ if z = +Inf and w > 0, then r = +0 (including w = +Inf);
+ if z = +Inf and w = 0, then r = NaN
+ [beta(z,1/log(z)) tends to +Inf whereas
+ beta(z,1/log(log(z))) tends to +0]
+ if z = +Inf and w < 0:
+ if w is an integer or -Inf: r = NaN
+ if -2k-1 < w < -2k: r = -Inf
+ if -2k-2 < w < -2k-1: r = +Inf
+ if w = -Inf and z is finite and not an integer:
+ beta(z,t) for t going to -Inf oscillates between positive and
+ negative values, with poles around integer values of t, thus
+ beta(z,w) gives NaN;
+ if w = -Inf and z is an integer:
+ beta(z,w) gives +0 for z even > 0, -0 for z odd > 0,
+ NaN for z <= 0;
+ if z = -Inf (then w = -Inf too): r = NaN */
+ if (MPFR_IS_INF (z) && MPFR_IS_POS(z)) /* z = +Inf */
+ {
+ if (mpfr_cmp_ui (w, 0) > 0)
+ {
+ MPFR_SET_ZERO(r);
+ MPFR_SET_POS(r);
+ MPFR_RET(0);
+ }
+ else if (MPFR_IS_ZERO(w) || MPFR_IS_INF(w) || mpfr_integer_p (w))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ long q;
+ mpfr_t t;
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (t, MPFR_PREC_MIN);
+ mpfr_set_ui (t, 1, MPFR_RNDN);
+ mpfr_fmodquo (t, &q, w, t, MPFR_RNDD);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ /* q contains the low bits of trunc(w) where trunc() rounds
+ towards zero, thus if q is odd, then -2k-2 < w < -2k-1 */
+ MPFR_SET_INF(r);
+ if ((unsigned long) q & 1)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+ MPFR_RET(0);
+ }
+ }
+ else if (MPFR_IS_INF(w)) /* w = -Inf */
+ {
+ if (mpfr_cmp_ui (z, 0) <= 0 || !mpfr_integer_p (z))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_SET_ZERO(r);
+ if (mpfr_odd_p (z))
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+ MPFR_RET(0);
+ }
+ }
+ }
+ else /* z or w is 0 */
+ {
+ /* If x is not a nonpositive integer, Gamma(x) is regular, so that
+ when y -> 0 with either y >= 0 or y <= 0,
+ Beta(x,y) ~ Gamma(x) * Gamma(y) / Gamma(x) = Gamma(y)
+ Gamma(y) tends to an infinity of the same sign as y.
+ Thus Beta(x,y) should be an infinity of the same sign as y.
+ */
+ if (mpfr_cmp_ui (z, 0) != 0) /* then w is +0 or -0 and z > 0 */
+ {
+ /* beta(z,+0) = +Inf, beta(z,-0) = -Inf (see above) */
+ MPFR_SET_INF(r);
+ MPFR_SET_SAME_SIGN(r,w);
+ MPFR_SET_DIVBY0 ();
+ MPFR_RET(0);
+ }
+ else if (mpfr_cmp_ui (w, 0) != 0) /* then z is +0 or -0 and w < 0 */
+ {
+ if (mpfr_integer_p (w))
+ {
+ /* For small u > 0, Beta(2u,w+u) and Beta(2u,w-u) have
+ opposite signs, so that they tend to infinities of
+ opposite signs when u -> 0. Thus the result is NaN. */
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ /* beta(+0,w) = +Inf, beta(-0,w) = -Inf (see above) */
+ MPFR_SET_INF(r);
+ MPFR_SET_SAME_SIGN(r,z);
+ MPFR_SET_DIVBY0 ();
+ MPFR_RET(0);
+ }
+ }
+ else /* w = z = 0:
+ beta(+0,+0) = +Inf
+ beta(-0,-0) = -Inf
+ beta(+0,-0) = NaN */
+ {
+ if (MPFR_SIGN(z) == MPFR_SIGN(w))
+ {
+ MPFR_SET_INF(r);
+ MPFR_SET_SAME_SIGN(r,z);
+ MPFR_SET_DIVBY0 ();
+ MPFR_RET(0);
+ }
+ else
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ }
+ }
+ }
+
+ /* special case when w is a negative integer */
+ w_integer = mpfr_integer_p (w);
+ if (w_integer && MPFR_IS_NEG(w))
+ {
+ /* if z < 0 or z+w > 0, or z is not an integer, return NaN */
+ if (MPFR_IS_NEG(z) || mpfr_cmpabs (z, w) > 0 || !mpfr_integer_p (z))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ /* If z+w = 0, the result is 1/z. */
+ if (mpfr_cmpabs (z, w) == 0)
+ return mpfr_ui_div (r, 1, z, rnd_mode);
+ /* Now z is an integer and z+w <= 0: return (-1)^z*beta(z,1-w-z).
+ Since z and w are of opposite signs, |z+w| <= max(|z|,|w|). */
+ emax = MAX (MPFR_EXP(z), MPFR_EXP(w));
+ mpfr_init2 (z_plus_w, (mpfr_prec_t) emax);
+ inex = mpfr_add (z_plus_w, z, w, MPFR_RNDN);
+ MPFR_ASSERTN(inex == 0);
+ inex = mpfr_ui_sub (z_plus_w, 1, z_plus_w, MPFR_RNDN);
+ MPFR_ASSERTN(inex == 0);
+ if (mpfr_odd_p (z))
+ {
+ inex = -mpfr_beta (r, z, z_plus_w, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN(r);
+ }
+ else
+ inex = mpfr_beta (r, z, z_plus_w, rnd_mode);
+ mpfr_clear (z_plus_w);
+ return inex;
+ }
+
+ /* special case when z is a negative integer: here w < z and w is not an
+ integer */
+ if (mpfr_integer_p (z) && MPFR_IS_NEG(z))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* compute the smallest precision such that z + w is exact */
+ emax = MAX (MPFR_EXP(z), MPFR_EXP(w));
+ emin = MIN (MPFR_EXP(z) - MPFR_PREC(z), MPFR_EXP(w) - MPFR_PREC(w));
+ MPFR_ASSERTD (emax >= emin);
+ /* Thus the math value of emax - emin is representable in mpfr_uexp_t. */
+ pmin = (mpfr_uexp_t) emax - emin;
+ /* If z and w have same sign, their sum can have exponent emax + 1. */
+ pmin += 1;
+ if (pmin > MPFR_PREC_MAX) /* FIXME: check if result can differ from NaN. */
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ MPFR_ASSERTN (pmin <= MPFR_PREC_MAX); /* detect integer overflow */
+ mpfr_init2 (z_plus_w, (mpfr_prec_t) pmin);
+ inex = mpfr_add (z_plus_w, z, w, MPFR_RNDN);
+ /* if z+w overflows with rounding to nearest, then w must be larger than
+ 1/2*ulp(z), thus we have an underflow. */
+ if (MPFR_IS_INF(z_plus_w))
+ {
+ mpfr_clear (z_plus_w);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (r, rnd_mode, 1);
+ }
+ MPFR_ASSERTN(inex == 0);
+
+ /* If z+w is 0 or a negative integer, return +0 when w (and thus z) is not
+ an integer. Indeed, gamma(z) and gamma(w) are regular numbers, and
+ gamma(z+w) is Inf, thus 1/gamma(z+w) is zero. Unless there is a rule
+ to choose the sign of 0, we choose +0. */
+ if (mpfr_cmp_ui (z_plus_w, 0) <= 0 && !w_integer
+ && mpfr_integer_p (z_plus_w))
+ {
+ mpfr_clear (z_plus_w);
+ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_SET_ZERO(r);
+ MPFR_SET_POS(r);
+ MPFR_RET(0);
+ }
+
+ prec = MPFR_PREC(r);
+ prec += MPFR_INT_CEIL_LOG2 (prec);
+ MPFR_GROUP_INIT_2 (group, prec, tmp, tmp2);
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ unsigned int inex2; /* unsigned due to bitwise operations */
+
+ MPFR_GROUP_REPREC_2 (group, prec, tmp, tmp2);
+ inex2 = mpfr_gamma (tmp, z, MPFR_RNDN);
+ /* tmp = gamma(z) * (1 + theta) with |theta| <= 2^-prec */
+ inex2 |= mpfr_gamma (tmp2, w, MPFR_RNDN);
+ /* tmp2 = gamma(w) * (1 + theta2) with |theta2| <= 2^-prec */
+ inex2 |= mpfr_mul (tmp, tmp, tmp2, MPFR_RNDN);
+ /* tmp = gamma(z)*gamma(w) * (1 + theta3)^3 with |theta3| <= 2^-prec */
+ inex2 |= mpfr_gamma (tmp2, z_plus_w, MPFR_RNDN);
+ /* tmp2 = gamma(z+w) * (1 + theta4) with |theta4| <= 2^-prec */
+ inex2 |= mpfr_div (tmp, tmp, tmp2, MPFR_RNDN);
+ /* tmp = gamma(z)*gamma(w)/gamma(z+w) * (1 + theta5)^5
+ with |theta5| <= 2^-prec. For prec >= 3, we have
+ |(1 + theta5)^5 - 1| <= 7 * 2^(-prec), thus the error is bounded
+ by 7 ulps */
+
+ if (MPFR_IS_NAN(tmp)) /* FIXME: most probably gamma(z)*gamma(w) = +-Inf,
+ and gamma(z+w) = +-Inf, can we do better? */
+ {
+ mpfr_clear (z_plus_w);
+ MPFR_ZIV_FREE (loop);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ MPFR_ASSERTN(mpfr_regular_p (tmp));
+
+ /* if inex2 = 0, then tmp is exactly beta(z,w) */
+ if (inex2 == 0 ||
+ MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - 3, MPFR_PREC(r), rnd_mode)))
+ break;
+
+ /* beta(1,+/-2^(-k)) = +/-2^k is exact, and cannot be detected above
+ since gamma(+/-2^(-k)) is not exact */
+ if (mpfr_cmp_ui (z, 1) == 0)
+ {
+ mpfr_exp_t expw = mpfr_get_exp (w);
+ if (mpfr_cmp_ui_2exp (w, 1, expw - 1) == 0)
+ {
+ /* since z >= w, this will only match w <= 1 */
+ mpfr_set_ui_2exp (tmp, 1, 1 - expw, MPFR_RNDN);
+ break;
+ }
+ else if (mpfr_cmp_si_2exp (w, -1, expw - 1) == 0)
+ {
+ mpfr_set_si_2exp (tmp, -1, 1 - expw, MPFR_RNDN);
+ break;
+ }
+ }
+
+ /* beta(2^k,1) = 1/2^k for k > 0 (k <= 0 was already tested above) */
+ if (mpfr_cmp_ui (w, 1) == 0 &&
+ mpfr_cmp_ui_2exp (z, 1, MPFR_EXP(z) - 1) == 0)
+ {
+ mpfr_set_ui_2exp (tmp, 1, 1 - MPFR_EXP(z), MPFR_RNDN);
+ break;
+ }
+
+ /* beta(2,-0.5) = -4 */
+ if (mpfr_cmp_ui (z, 2) == 0 && mpfr_cmp_si_2exp (w, -1, -1) == 0)
+ {
+ mpfr_set_si_2exp (tmp, -1, 2, MPFR_RNDN);
+ break;
+ }
+
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+ inex = mpfr_set (r, tmp, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ mpfr_clear (z_plus_w);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inex, rnd_mode);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/buildopt.c b/Build/source/libs/mpfr/mpfr-src/src/buildopt.c
index 471f9e0282a..1386c311afd 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/buildopt.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/buildopt.c
@@ -34,6 +34,16 @@ mpfr_buildopt_tls_p (void)
}
int
+mpfr_buildopt_float128_p (void)
+{
+#ifdef MPFR_WANT_FLOAT128
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int
mpfr_buildopt_decimal_p (void)
{
#ifdef MPFR_WANT_DECIMAL_FLOATS
@@ -53,11 +63,18 @@ mpfr_buildopt_gmpinternals_p (void)
#endif
}
-const char *mpfr_buildopt_tune_case (void)
+int
+mpfr_buildopt_sharedcache_p (void)
{
-#ifdef MPFR_TUNE_CASE
- return MPFR_TUNE_CASE;
+#if defined (WANT_SHARED_CACHE)
+ return 1;
#else
- return "Generic thresholds";
+ return 0;
#endif
}
+
+const char *mpfr_buildopt_tune_case (void)
+{
+ /* MPFR_TUNE_CASE is always defined (can be "default"). */
+ return MPFR_TUNE_CASE;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cache.c b/Build/source/libs/mpfr/mpfr-src/src/cache.c
index 9c5b73f8dfb..a48de9967ba 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cache.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cache.c
@@ -37,37 +37,76 @@ mpfr_init_cache (mpfr_cache_t cache, int (*func)(mpfr_ptr, mpfr_rnd_t))
void
mpfr_clear_cache (mpfr_cache_t cache)
{
- if (MPFR_PREC (cache->x) != 0)
- mpfr_clear (cache->x);
- MPFR_PREC (cache->x) = 0;
+ if (MPFR_UNLIKELY (MPFR_PREC (cache->x) != 0))
+ {
+ /* Get the cache in read-write mode */
+ MPFR_LOCK_WRITE(cache->lock);
+
+ if (MPFR_LIKELY (MPFR_PREC (cache->x) != 0))
+ {
+ mpfr_clear (cache->x);
+ MPFR_PREC (cache->x) = 0;
+ }
+
+ /* Free the cache in read-write mode */
+ MPFR_UNLOCK_WRITE(cache->lock);
+ }
}
int
mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
{
mpfr_prec_t prec = MPFR_PREC (dest);
- mpfr_prec_t pold = MPFR_PREC (cache->x);
+ mpfr_prec_t pold;
int inexact, sign;
MPFR_SAVE_EXPO_DECL (expo);
+ /* Call the initialisation function of the cache if it's needed */
+ MPFR_DEFERRED_INIT_CALL(cache);
+
MPFR_SAVE_EXPO_MARK (expo);
+ /* Get the cache in read-only mode */
+ MPFR_LOCK_READ(cache->lock);
+ /* Read the precision within the cache */
+ pold = MPFR_PREC (cache->x);
if (MPFR_UNLIKELY (prec > pold))
{
- /* No previous result in the cache or the precision of the
- previous result is not sufficient. */
-
- if (MPFR_UNLIKELY (pold == 0)) /* No previous result. */
- mpfr_init2 (cache->x, prec);
+ /* Free the cache in read-only mode */
+ /* And get the cache in read-write mode */
+ MPFR_LOCK_READ2WRITE(cache->lock);
+
+ /* Retest the precision once we get the lock.
+ If there is no lock, there is no harm in this code */
+ pold = MPFR_PREC (cache->x);
+ if (MPFR_LIKELY (prec > pold))
+ {
+ /* No previous result in the cache or the precision of the previous
+ result is not sufficient. We increase the cache size by at least
+ 10% to avoid invalidating the cache many times if one performs
+ several computations with small increase of precision. */
+ if (MPFR_UNLIKELY (pold == 0)) /* No previous result. */
+ mpfr_init2 (cache->x, prec); /* as pold = prec below */
+ else
+ pold += pold / 10;
+
+ /* Update the cache. */
+ if (pold < prec)
+ pold = prec;
+
+ /* no need to keep the previous value */
+ mpfr_set_prec (cache->x, pold);
+ cache->inexact = (*cache->func) (cache->x, MPFR_RNDN);
+ }
- /* Update the cache. */
- pold = prec;
- /* no need to keep the previous value */
- mpfr_set_prec (cache->x, pold);
- cache->inexact = (*cache->func) (cache->x, MPFR_RNDN);
+ /* Free the cache in read-write mode */
+ /* Get the cache in read-only mode */
+ MPFR_LOCK_WRITE2READ(cache->lock);
}
/* now pold >= prec is the precision of cache->x */
+ MPFR_ASSERTD (pold >= prec);
+ MPFR_ASSERTD (MPFR_PREC (cache->x) == pold);
/* First, check if the cache has the exact value (unlikely).
Else the exact value is between (assuming x=cache->x > 0):
@@ -78,7 +117,7 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
/* we assume all cached constants are positive */
MPFR_ASSERTN (MPFR_IS_POS (cache->x)); /* TODO... */
sign = MPFR_SIGN (cache->x);
- MPFR_SET_EXP (dest, MPFR_GET_EXP (cache->x));
+ MPFR_EXP (dest) = MPFR_GET_EXP (cache->x);
MPFR_SET_SIGN (dest, sign);
/* round cache->x from precision pold down to precision prec */
@@ -105,6 +144,8 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
mpfr_overflow (dest, rnd, sign);
);
+ /* Rather a likely, this is a 100% succes rate for
+ all constants of MPFR */
if (MPFR_LIKELY (cache->inexact != 0))
{
switch (rnd)
@@ -141,5 +182,9 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
}
MPFR_SAVE_EXPO_FREE (expo);
+
+ /* Free the cache in read-only mode */
+ MPFR_UNLOCK_READ(cache->lock);
+
return mpfr_check_range (dest, inexact, rnd);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/check.c b/Build/source/libs/mpfr/mpfr-src/src/check.c
index 475e2b06f30..f91e1d2d764 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/check.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/check.c
@@ -25,6 +25,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
/*
* Check if x is a valid mpfr_t initializes by mpfr_init
* Returns 0 if isn't valid
+ *
+ * Note: Due to the MPFR_GET_ALLOC_SIZE test, this function must not
+ * be called on statically allocated numbers (only used inside MPFR).
+ * Anyway, this test should not be useful on such numbers.
*/
int
mpfr_check (mpfr_srcptr x)
@@ -32,49 +36,46 @@ mpfr_check (mpfr_srcptr x)
mp_size_t s, i;
mp_limb_t tmp;
volatile mp_limb_t *xm;
+ mpfr_prec_t prec;
int rw;
- /* Check Sign */
- if (MPFR_SIGN(x) != MPFR_SIGN_POS && MPFR_SIGN(x) != MPFR_SIGN_NEG)
+ /* Check sign */
+ if (MPFR_SIGN(x) != MPFR_SIGN_POS &&
+ MPFR_SIGN(x) != MPFR_SIGN_NEG)
return 0;
- /* Check Precision */
- if ( (MPFR_PREC(x) < MPFR_PREC_MIN) || (MPFR_PREC(x) > MPFR_PREC_MAX))
+ /* Check precision */
+ prec = MPFR_PREC(x);
+ if (! MPFR_PREC_COND (prec))
return 0;
- /* Check Mantissa */
+ /* Check mantissa */
xm = MPFR_MANT(x);
- if (!xm)
+ if (xm == NULL)
return 0;
/* Check size of mantissa */
s = MPFR_GET_ALLOC_SIZE(x);
- if (s<=0 || s > MP_SIZE_T_MAX ||
- MPFR_PREC(x) > ((mpfr_prec_t)s*GMP_NUMB_BITS))
+ if (s <= 0 || s > MP_SIZE_T_MAX ||
+ prec > (mpfr_prec_t) s * GMP_NUMB_BITS)
return 0;
- /* Acces all the mp_limb of the mantissa: may do a seg fault */
- for(i = 0 ; i < s ; i++)
+ /* Access all the mp_limb of the mantissa: may do a seg fault */
+ for (i = 0 ; i < s ; i++)
tmp = xm[i];
- /* Check if it isn't singular*/
- if (! MPFR_IS_SINGULAR (x))
+ /* Check singular numbers (do not use MPFR_IS_PURE_FP() in order to avoid
+ any assertion checking, as this function mpfr_check() does something
+ similar by returning a Boolean instead of doing an abort if the format
+ is incorrect). */
+ if (MPFR_IS_SINGULAR (x))
+ return MPFR_IS_ZERO(x) || MPFR_IS_NAN(x) || MPFR_IS_INF(x);
+ /* Check the most significant limb (its MSB must be 1) */
+ if (! MPFR_IS_NORMALIZED (x))
+ return 0;
+ /* Check the least significant limb (the trailing bits must be 0) */
+ rw = prec % GMP_NUMB_BITS;
+ if (rw != 0)
{
- /* Check first mp_limb of mantissa (Must start with a 1 bit) */
- if ( ((xm[MPFR_LIMB_SIZE(x)-1])>>(GMP_NUMB_BITS-1)) == 0)
- return 0;
- /* Check last mp_limb of mantissa */
- rw = (MPFR_PREC(x) % GMP_NUMB_BITS);
- if (rw != 0)
- {
- tmp = MPFR_LIMB_MASK (GMP_NUMB_BITS - rw);
- if ((xm[0] & tmp) != 0)
- return 0;
- }
- /* Check exponent range */
- if ((MPFR_EXP (x) < __gmpfr_emin) || (MPFR_EXP (x) > __gmpfr_emax))
+ tmp = MPFR_LIMB_MASK (GMP_NUMB_BITS - rw);
+ if ((xm[0] & tmp) != 0)
return 0;
}
- else
- {
- /* Singular value is zero, inf or nan */
- MPFR_ASSERTD(MPFR_IS_ZERO(x) || MPFR_IS_NAN(x) || MPFR_IS_INF(x));
- }
- return 1;
+ /* Check exponent range */
+ return MPFR_EXP_IN_RANGE (MPFR_EXP (x));
}
-
diff --git a/Build/source/libs/mpfr/mpfr-src/src/clear.c b/Build/source/libs/mpfr/mpfr-src/src/clear.c
index 135a08ab50d..9157a820eb6 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/clear.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/clear.c
@@ -22,10 +22,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-void
+MPFR_HOT_FUNCTION_ATTR void
mpfr_clear (mpfr_ptr m)
{
- (*__gmp_free_func) (MPFR_GET_REAL_PTR (m),
+ mpfr_free_func (MPFR_GET_REAL_PTR (m),
MPFR_MALLOC_SIZE (MPFR_GET_ALLOC_SIZE (m)));
MPFR_MANT (m) = (mp_limb_t *) 0;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/clears.c b/Build/source/libs/mpfr/mpfr-src/src/clears.c
index 2f96459eefa..e442e0f03de 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/clears.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/clears.c
@@ -22,8 +22,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-#undef HAVE_STDARG
-#include "config.h" /* for a build within gmp */
+# undef HAVE_STDARG
+# include "config.h"
#endif
#if HAVE_STDARG
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp.c b/Build/source/libs/mpfr/mpfr-src/src/cmp.c
index 9dd4db8f6c8..102af1683e2 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp.c
@@ -28,7 +28,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
returns 0 and sets erange flag if b and/or c is NaN.
*/
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_cmp3 (mpfr_srcptr b, mpfr_srcptr c, int s)
{
mpfr_exp_t be, ce;
@@ -41,7 +41,7 @@ mpfr_cmp3 (mpfr_srcptr b, mpfr_srcptr c, int s)
{
if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return 0;
}
else if (MPFR_IS_INF(b))
@@ -73,8 +73,8 @@ mpfr_cmp3 (mpfr_srcptr b, mpfr_srcptr c, int s)
/* both signs and exponents are equal */
- bn = (MPFR_PREC(b)-1)/GMP_NUMB_BITS;
- cn = (MPFR_PREC(c)-1)/GMP_NUMB_BITS;
+ bn = MPFR_LAST_LIMB (b);
+ cn = MPFR_LAST_LIMB (c);
bp = MPFR_MANT(b);
cp = MPFR_MANT(c);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp2.c b/Build/source/libs/mpfr/mpfr-src/src/cmp2.c
index 4e5c290178d..7b58859c7d0 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp2.c
@@ -38,6 +38,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
{
mp_limb_t *bp, *cp, bb, cc = 0, lastc = 0, dif, high_dif = 0;
mp_size_t bn, cn;
+ mpfr_exp_t sdiff_exp;
mpfr_uexp_t diff_exp;
mpfr_prec_t res = 0;
int sign;
@@ -48,13 +49,21 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
/* the cases b=0 or c=0 are also treated apart in agm and sub
(which calls sub1) */
- MPFR_ASSERTD (MPFR_IS_PURE_FP(b));
- MPFR_ASSERTD (MPFR_IS_PURE_FP(c));
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (c));
- if (MPFR_GET_EXP (b) >= MPFR_GET_EXP (c))
+ sdiff_exp = MPFR_UNLIKELY (MPFR_IS_UBF (b) || MPFR_IS_UBF (c)) ?
+ mpfr_ubf_diff_exp (b, c) : MPFR_GET_EXP (b) - MPFR_GET_EXP (c);
+
+ /* The returned result is restricted to [MPFR_EXP_MIN,MPFR_EXP_MAX],
+ which is the range of the mpfr_exp_t type. But under the condition
+ below, the value of cancel will not be affected. */
+ MPFR_STAT_STATIC_ASSERT (MPFR_EXP_MAX > MPFR_PREC_MAX);
+
+ if (sdiff_exp >= 0)
{
sign = 1;
- diff_exp = (mpfr_uexp_t) MPFR_GET_EXP (b) - MPFR_GET_EXP (c);
+ diff_exp = sdiff_exp;
bp = MPFR_MANT(b);
cp = MPFR_MANT(c);
@@ -62,7 +71,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
bn = (MPFR_PREC(b) - 1) / GMP_NUMB_BITS;
cn = (MPFR_PREC(c) - 1) / GMP_NUMB_BITS; /* # of limbs of c minus 1 */
- if (MPFR_UNLIKELY( diff_exp == 0 ))
+ if (diff_exp == 0)
{
while (bn >= 0 && cn >= 0 && bp[bn] == cp[cn])
{
@@ -73,30 +82,32 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
if (MPFR_UNLIKELY (bn < 0))
{
- if (MPFR_LIKELY (cn < 0)) /* b = c */
+ if (MPFR_LIKELY (cn < 0)) /* |b| = |c| */
return 0;
+ /* b has been read entirely, but not c. Replace b by c for the
+ symmetric case below (only the sign differs if not 0). */
bp = cp;
bn = cn;
- cn = -1;
+ cn = -1; /* to enter the following "if" */
sign = -1;
}
if (MPFR_UNLIKELY (cn < 0))
/* c discards exactly the upper part of b */
{
- unsigned int z;
+ int z;
MPFR_ASSERTD (bn >= 0);
while (bp[bn] == 0)
{
- if (--bn < 0) /* b = c */
+ if (--bn < 0) /* |b| = |c| */
return 0;
res += GMP_NUMB_BITS;
}
- count_leading_zeros(z, bp[bn]); /* bp[bn] <> 0 */
+ count_leading_zeros (z, bp[bn]); /* bp[bn] <> 0 */
*cancel = res + z;
return sign;
}
@@ -118,7 +129,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
else /* MPFR_EXP(b) < MPFR_EXP(c) */
{
sign = -1;
- diff_exp = (mpfr_uexp_t) MPFR_GET_EXP (c) - MPFR_GET_EXP (b);
+ diff_exp = - (mpfr_uexp_t) sdiff_exp;
bp = MPFR_MANT(c);
cp = MPFR_MANT(b);
@@ -136,7 +147,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
if (MPFR_LIKELY (diff_exp < GMP_NUMB_BITS))
{
cc = cp[cn] >> diff_exp;
- /* warning: a shift by GMP_NUMB_BITS may give wrong results */
+ /* warning: a shift by GMP_NUMB_BITS is not allowed by ISO C */
if (diff_exp)
lastc = cp[cn] << (GMP_NUMB_BITS - diff_exp);
cn--;
@@ -152,6 +163,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
while (MPFR_UNLIKELY ((cn >= 0 || lastc != 0)
&& (high_dif == 0) && (dif == 1)))
{ /* dif=1 implies diff_exp = 0 or 1 */
+ MPFR_ASSERTD (diff_exp <= 1);
bb = (bn >= 0) ? bp[bn] : 0;
cc = lastc;
if (cn >= 0)
@@ -160,8 +172,9 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
{
cc += cp[cn];
}
- else /* diff_exp = 1 */
+ else
{
+ MPFR_ASSERTD (diff_exp == 1);
cc += cp[cn] >> 1;
lastc = cp[cn] << (GMP_NUMB_BITS - 1);
}
@@ -188,9 +201,9 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
}
else /* high_dif == 0 */
{
- unsigned int z;
+ int z;
- count_leading_zeros(z, dif); /* dif > 1 here */
+ count_leading_zeros (z, dif); /* dif > 1 here */
res += z;
if (MPFR_LIKELY(dif != (MPFR_LIMB_ONE << (GMP_NUMB_BITS - z - 1))))
{ /* dif is not a power of two */
@@ -200,7 +213,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
}
/* now result is res + (low(b) < low(c)) */
- while (MPFR_UNLIKELY (bn >= 0 && (cn >= 0 || lastc != 0)))
+ while (bn >= 0 && (cn >= 0 || lastc != 0))
{
if (diff_exp >= GMP_NUMB_BITS)
diff_exp -= GMP_NUMB_BITS;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp_abs.c b/Build/source/libs/mpfr/mpfr-src/src/cmp_abs.c
index ca05493fc7e..12ab6371561 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp_abs.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp_abs.c
@@ -36,7 +36,7 @@ mpfr_cmpabs (mpfr_srcptr b, mpfr_srcptr c)
{
if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return 0;
}
else if (MPFR_IS_INF (b))
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp_d.c b/Build/source/libs/mpfr/mpfr-src/src/cmp_d.c
index 04a20238a85..cb3c7cbd008 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp_d.c
@@ -27,19 +27,19 @@ mpfr_cmp_d (mpfr_srcptr b, double d)
{
mpfr_t tmp;
int res;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (tmp, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, tmp, IEEE_DBL_MANT_DIG);
res = mpfr_set_d (tmp, d, MPFR_RNDN);
MPFR_ASSERTD (res == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
res = mpfr_cmp (b, tmp);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear (tmp);
MPFR_SAVE_EXPO_FREE (expo);
return res;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp_ld.c b/Build/source/libs/mpfr/mpfr-src/src/cmp_ld.c
index d2eda97d09d..536316a182c 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp_ld.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp_ld.c
@@ -20,6 +20,8 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#include <float.h> /* needed so that MPFR_LDBL_MANT_DIG is correctly defined */
+
#include "mpfr-impl.h"
int
@@ -33,9 +35,17 @@ mpfr_cmp_ld (mpfr_srcptr b, long double d)
mpfr_init2 (tmp, MPFR_LDBL_MANT_DIG);
res = mpfr_set_ld (tmp, d, MPFR_RNDN);
+ if (res != 0) /* can happen when "long double" is double-double */
+ {
+ /* since the smallest value is 2^(-1074) and the largest is
+ < 2^1024, every double-double is exactly representable with
+ 1024 + 1074 bits */
+ mpfr_set_prec (tmp, 1024 + 1074);
+ res = mpfr_set_ld (tmp, d, MPFR_RNDN);
+ }
MPFR_ASSERTD (res == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
res = mpfr_cmp (b, tmp);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp_si.c b/Build/source/libs/mpfr/mpfr-src/src/cmp_si.c
index 8991949df68..d053e819d07 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp_si.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp_si.c
@@ -43,7 +43,7 @@ mpfr_cmp_si_2exp (mpfr_srcptr b, long int i, mpfr_exp_t f)
else if (MPFR_IS_ZERO(b))
return i != 0 ? -si : 0;
/* NAN */
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return 0;
}
else if (MPFR_SIGN(b) != si || i == 0)
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cmp_ui.c b/Build/source/libs/mpfr/mpfr-src/src/cmp_ui.c
index f922623a7cf..3732fc983c3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cmp_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cmp_ui.c
@@ -37,7 +37,7 @@ mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, mpfr_exp_t f)
{
if (MPFR_IS_NAN (b))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return 0;
}
else if (MPFR_IS_INF(b))
diff --git a/Build/source/libs/mpfr/mpfr-src/src/const_euler.c b/Build/source/libs/mpfr/mpfr-src/src/const_euler.c
index 7bd879d4b81..44af5b82375 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/const_euler.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/const_euler.c
@@ -1,7 +1,7 @@
/* mpfr_const_euler -- Euler's constant
Copyright 2001-2017 Free Software Foundation, Inc.
-Contributed by the AriC and Caramba projects, INRIA.
+Contributed by Fredrik Johansson.
This file is part of the GNU MPFR Library.
@@ -20,6 +20,9 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+/* The approximation error bound uses Theorem 1 and Remark 2 in
+ http://arxiv.org/pdf/1312.0039v1.pdf */
+
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
@@ -34,188 +37,240 @@ mpfr_const_euler (mpfr_ptr x, mpfr_rnd_t rnd_mode) {
}
-static void mpfr_const_euler_S2 (mpfr_ptr, unsigned long);
-static void mpfr_const_euler_R (mpfr_ptr, unsigned long);
-
-int
-mpfr_const_euler_internal (mpfr_t x, mpfr_rnd_t rnd)
+typedef struct
{
- mpfr_prec_t prec = MPFR_PREC(x), m, log2m;
- mpfr_t y, z;
- unsigned long n;
- int inexact;
- MPFR_ZIV_DECL (loop);
+ mpz_t P;
+ mpz_t Q;
+ mpz_t T;
+ mpz_t C;
+ mpz_t D;
+ mpz_t V;
+} mpfr_const_euler_bs_struct;
+
+typedef mpfr_const_euler_bs_struct mpfr_const_euler_bs_t[1];
- log2m = MPFR_INT_CEIL_LOG2 (prec);
- m = prec + 2 * log2m + 23;
+static void
+mpfr_const_euler_bs_init (mpfr_const_euler_bs_t s)
+{
+ mpz_init (s->P);
+ mpz_init (s->Q);
+ mpz_init (s->T);
+ mpz_init (s->C);
+ mpz_init (s->D);
+ mpz_init (s->V);
+}
- mpfr_init2 (y, m);
- mpfr_init2 (z, m);
+static void
+mpfr_const_euler_bs_clear (mpfr_const_euler_bs_t s)
+{
+ mpz_clear (s->P);
+ mpz_clear (s->Q);
+ mpz_clear (s->T);
+ mpz_clear (s->C);
+ mpz_clear (s->D);
+ mpz_clear (s->V);
+}
- MPFR_ZIV_INIT (loop, m);
- for (;;)
+static void
+mpfr_const_euler_bs_1 (mpfr_const_euler_bs_t s,
+ unsigned long n1, unsigned long n2, unsigned long N,
+ int cont)
+{
+ if (n2 - n1 == 1)
{
- mpfr_exp_t exp_S, err;
- /* since prec >= 1, we have m >= 24 here, which ensures n >= 9 below */
- n = 1 + (unsigned long) ((double) m * LOG2 / 2.0);
- MPFR_ASSERTD (n >= 9);
- mpfr_const_euler_S2 (y, n); /* error <= 3 ulps */
- exp_S = MPFR_EXP(y);
- mpfr_set_ui (z, n, MPFR_RNDN);
- mpfr_log (z, z, MPFR_RNDD); /* error <= 1 ulp */
- mpfr_sub (y, y, z, MPFR_RNDN); /* S'(n) - log(n) */
- /* the error is less than 1/2 + 3*2^(exp_S-EXP(y)) + 2^(EXP(z)-EXP(y))
- <= 1/2 + 2^(exp_S+2-EXP(y)) + 2^(EXP(z)-EXP(y))
- <= 1/2 + 2^(1+MAX(exp_S+2,EXP(z))-EXP(y)) */
- err = 1 + MAX(exp_S + 2, MPFR_EXP(z)) - MPFR_EXP(y);
- err = (err >= -1) ? err + 1 : 0; /* error <= 2^err ulp(y) */
- exp_S = MPFR_EXP(y);
- mpfr_const_euler_R (z, n); /* err <= ulp(1/2) = 2^(-m) */
- mpfr_sub (y, y, z, MPFR_RNDN);
- /* err <= 1/2 ulp(y) + 2^(-m) + 2^(err + exp_S - EXP(y)) ulp(y).
- Since the result is between 0.5 and 1, ulp(y) = 2^(-m).
- So we get 3/2*ulp(y) + 2^(err + exp_S - EXP(y)) ulp(y).
- 3/2 + 2^e <= 2^(e+1) for e>=1, and <= 2^2 otherwise */
- err = err + exp_S - MPFR_EXP(y);
- err = (err >= 1) ? err + 1 : 2;
- if (MPFR_LIKELY (MPFR_CAN_ROUND (y, m - err, prec, rnd)))
- break;
- MPFR_ZIV_NEXT (loop, m);
- mpfr_set_prec (y, m);
- mpfr_set_prec (z, m);
+ mpz_set_ui (s->P, N);
+ mpz_mul (s->P, s->P, s->P);
+ mpz_set_ui (s->Q, n1 + 1);
+ mpz_mul (s->Q, s->Q, s->Q);
+ mpz_set_ui (s->C, 1);
+ mpz_set_ui (s->D, n1 + 1);
+ mpz_set (s->T, s->P);
+ mpz_set (s->V, s->P);
}
- MPFR_ZIV_FREE (loop);
+ else
+ {
+ mpfr_const_euler_bs_t L, R;
+ mpz_t t, u, v;
+ unsigned long m = (n1 + n2) / 2;
- inexact = mpfr_set (x, y, rnd);
+ mpfr_const_euler_bs_init (L);
+ mpfr_const_euler_bs_init (R);
+ mpfr_const_euler_bs_1 (L, n1, m, N, 1);
+ mpfr_const_euler_bs_1 (R, m, n2, N, 1);
- mpfr_clear (y);
- mpfr_clear (z);
+ mpz_init (t);
+ mpz_init (u);
+ mpz_init (v);
- return inexact; /* always inexact */
+ if (cont)
+ mpz_mul (s->P, L->P, R->P);
+
+ mpz_mul (s->Q, L->Q, R->Q);
+ mpz_mul (s->D, L->D, R->D);
+
+ /* T = LP RT + RQ LT*/
+ mpz_mul (t, L->P, R->T);
+ mpz_mul (v, R->Q, L->T);
+ mpz_add (s->T, t, v);
+
+ /* C = LC RD + RC LD */
+ if (cont)
+ {
+ mpz_mul (s->C, L->C, R->D);
+ mpz_addmul (s->C, R->C, L->D);
+ }
+
+ /* V = RD (RQ LV + LC LP RT) + LD LP RV */
+ mpz_mul (u, L->P, R->V);
+ mpz_mul (u, u, L->D);
+ mpz_mul (v, R->Q, L->V);
+ mpz_addmul (v, t, L->C);
+ mpz_mul (v, v, R->D);
+ mpz_add (s->V, u, v);
+
+ mpfr_const_euler_bs_clear (L);
+ mpfr_const_euler_bs_clear (R);
+ mpz_clear (t);
+ mpz_clear (u);
+ mpz_clear (v);
+ }
}
static void
-mpfr_const_euler_S2_aux (mpz_t P, mpz_t Q, mpz_t T, unsigned long n,
- unsigned long a, unsigned long b, int need_P)
+mpfr_const_euler_bs_2 (mpz_t P, mpz_t Q, mpz_t T,
+ unsigned long n1, unsigned long n2, unsigned long N,
+ int cont)
{
- if (a + 1 == b)
+ if (n2 - n1 == 1)
{
- mpz_set_ui (P, n);
- if (a > 1)
- mpz_mul_si (P, P, 1 - (long) a);
+ if (n1 == 0)
+ {
+ mpz_set_ui (P, 1);
+ mpz_set_ui (Q, 4 * N);
+ }
+ else
+ {
+ mpz_set_ui (P, 2 * n1 - 1);
+ mpz_pow_ui (P, P, 3);
+ mpz_set_ui (Q, 32 * n1);
+ mpz_mul_ui (Q, Q, N);
+ mpz_mul_ui (Q, Q, N);
+ }
mpz_set (T, P);
- mpz_set_ui (Q, a);
- mpz_mul_ui (Q, Q, a);
}
else
{
- unsigned long c = (a + b) / 2;
mpz_t P2, Q2, T2;
- mpfr_const_euler_S2_aux (P, Q, T, n, a, c, 1);
+ unsigned long m = (n1 + n2) / 2;
+
mpz_init (P2);
mpz_init (Q2);
mpz_init (T2);
- mpfr_const_euler_S2_aux (P2, Q2, T2, n, c, b, 1);
+ mpfr_const_euler_bs_2 (P, Q, T, n1, m, N, 1);
+ mpfr_const_euler_bs_2 (P2, Q2, T2, m, n2, N, 1);
mpz_mul (T, T, Q2);
mpz_mul (T2, T2, P);
mpz_add (T, T, T2);
- if (need_P)
+ if (cont)
mpz_mul (P, P, P2);
mpz_mul (Q, Q, Q2);
mpz_clear (P2);
mpz_clear (Q2);
mpz_clear (T2);
- /* divide by 2 if possible */
- {
- unsigned long v2;
- v2 = mpz_scan1 (P, 0);
- c = mpz_scan1 (Q, 0);
- if (c < v2)
- v2 = c;
- c = mpz_scan1 (T, 0);
- if (c < v2)
- v2 = c;
- if (v2)
- {
- mpz_tdiv_q_2exp (P, P, v2);
- mpz_tdiv_q_2exp (Q, Q, v2);
- mpz_tdiv_q_2exp (T, T, v2);
- }
- }
}
}
-/* computes S(n) = sum(n^k*(-1)^(k-1)/k!/k, k=1..ceil(4.319136566 * n))
- using binary splitting.
- We have S(n) = sum(f(k), k=1..N) with N=ceil(4.319136566 * n)
- and f(k) = n^k*(-1)*(k-1)/k!/k,
- thus f(k)/f(k-1) = -n*(k-1)/k^2
-*/
-static void
-mpfr_const_euler_S2 (mpfr_t x, unsigned long n)
-{
- mpz_t P, Q, T;
- unsigned long N = (unsigned long) (ALPHA * (double) n + 1.0);
- mpz_init (P);
- mpz_init (Q);
- mpz_init (T);
- mpfr_const_euler_S2_aux (P, Q, T, n, 1, N + 1, 0);
- mpfr_set_z (x, T, MPFR_RNDN);
- mpfr_div_z (x, x, Q, MPFR_RNDN);
- mpz_clear (P);
- mpz_clear (Q);
- mpz_clear (T);
-}
-
-/* computes R(n) = exp(-n)/n * sum(k!/(-n)^k, k=0..n-2)
- with error at most 4*ulp(x). Assumes n>=2.
- Since x <= exp(-n)/n <= 1/8, then 4*ulp(x) <= ulp(1).
-*/
-static void
-mpfr_const_euler_R (mpfr_t x, unsigned long n)
+int
+mpfr_const_euler_internal (mpfr_t x, mpfr_rnd_t rnd)
{
- unsigned long k, m;
- mpz_t a, s;
+ mpfr_const_euler_bs_t sum;
+ mpz_t t, u, v;
+ unsigned long n, N;
+ mpfr_prec_t prec, wp, magn;
mpfr_t y;
+ int inexact;
+ MPFR_ZIV_DECL (loop);
- MPFR_ASSERTN (n >= 2); /* ensures sum(k!/(-n)^k, k=0..n-2) >= 2/3 */
-
- /* as we multiply the sum by exp(-n), we need only PREC(x) - n/LOG2 bits */
- m = MPFR_PREC(x) - (unsigned long) ((double) n / LOG2);
+ prec = mpfr_get_prec (x);
+ wp = prec + 24;
- mpz_init_set_ui (a, 1);
- mpz_mul_2exp (a, a, m);
- mpz_init_set (s, a);
+ mpfr_init2 (y, wp);
+ mpfr_const_euler_bs_init (sum);
+ mpz_init (t);
+ mpz_init (u);
+ mpz_init (v);
- for (k = 1; k <= n; k++)
+ MPFR_ZIV_INIT (loop, wp);
+ for (;;)
{
- mpz_mul_ui (a, a, k);
- mpz_fdiv_q_ui (a, a, n);
- /* the error e(k) on a is e(k) <= 1 + k/n*e(k-1) with e(0)=0,
- i.e. e(k) <= k */
- if (k % 2)
- mpz_sub (s, s, a);
- else
- mpz_add (s, s, a);
+ /* The approximation error is bounded by 24 exp(-8n) when
+ n > 1, which is smaller than 2^-wp if
+ n > (wp + log_2(24)) * (log(2)/8).
+ Note log2(24) < 5 and log(2)/8 < 866434 / 10000000. */
+ mpz_set_ui (t, wp + 5);
+ mpz_mul_ui (t, t, 866434);
+ mpz_cdiv_q_ui (t, t, 10000000);
+ n = mpz_get_ui (t);
+
+ /* It is sufficient to take N >= alpha*n + 1
+ where alpha = 3/LambertW(3/e) = 4.970625759544... */
+ mpz_set_ui (t, n);
+ mpz_mul_ui (t, t, 4970626);
+ mpz_cdiv_q_ui (t, t, 1000000);
+ mpz_add_ui (t, t, 1);
+ N = mpz_get_ui (t);
+
+ /* V / ((T + Q) * D) = S / I
+ where S = sum_{k=0}^{N-1} H_k n^(2k) / (k!)^2,
+ I = sum_{k=0}^{N-1} n^(2k) / (k!)^2 */
+ mpfr_const_euler_bs_1 (sum, 0, N, n, 0);
+ mpz_add (sum->T, sum->T, sum->Q);
+ mpz_mul (t, sum->T, sum->D);
+ mpz_mul_2exp (u, sum->V, wp);
+ mpz_tdiv_q (v, u, t);
+ /* v * 2^-wp = S/I with error < 1 */
+
+ /* C / (D * V) = U where
+ U = (1/(4n)) sum_{k=0}^{2n-1} [(2k)!]^3 / ((k!)^4 8^(2k) (2n)^(2k)) */
+ mpfr_const_euler_bs_2 (sum->C, sum->D, sum->V, 0, 2*n, n, 0);
+ mpz_mul (t, sum->Q, sum->Q);
+ mpz_mul (t, t, sum->V);
+ mpz_mul (u, sum->T, sum->T);
+ mpz_mul (u, u, sum->D);
+ mpz_mul_2exp (t, t, wp);
+ mpz_tdiv_q (t, t, u);
+ /* t * 2^-wp = U/I^2 with error < 1 */
+
+ /* gamma = S/I - U/I^2 - log(n) with error at most 2^-wp */
+ mpz_sub (v, v, t);
+ /* v * 2^-wp now equals gamma + log(n) with error at most 3*2^-wp */
+
+ /* log(n) < 2^ceil(log2(n)) */
+ magn = MPFR_INT_CEIL_LOG2(n);
+ mpfr_set_prec (y, wp + magn);
+ mpfr_set_ui (y, n, MPFR_RNDZ); /* exact */
+ mpfr_log (y, y, MPFR_RNDZ); /* error < 2^-wp */
+
+ mpfr_mul_2exp (y, y, wp, MPFR_RNDZ);
+ mpfr_z_sub (y, v, y, MPFR_RNDZ);
+ mpfr_div_2exp (y, y, wp, MPFR_RNDZ);
+ /* rounding error from the last subtraction < 2^-wp */
+ /* so y = gamma with error < 5*2^-wp */
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (y, wp - 3, prec, rnd)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, wp);
}
- /* the error on s is at most 1+2+...+n = n*(n+1)/2 */
- mpz_fdiv_q_ui (s, s, n); /* err <= 1 + (n+1)/2 */
- MPFR_ASSERTN (MPFR_PREC(x) >= mpz_sizeinbase(s, 2));
- mpfr_set_z (x, s, MPFR_RNDD); /* exact */
- mpfr_div_2ui (x, x, m, MPFR_RNDD);
- /* now x = 1/n * sum(k!/(-n)^k, k=0..n-2) <= 1/n */
- /* err(x) <= (n+1)/2^m <= (n+1)*exp(n)/2^PREC(x) */
-
- mpfr_init2 (y, m);
- mpfr_set_si (y, -(long)n, MPFR_RNDD); /* assumed exact */
- mpfr_exp (y, y, MPFR_RNDD); /* err <= ulp(y) <= exp(-n)*2^(1-m) */
- mpfr_mul (x, x, y, MPFR_RNDD);
- /* err <= ulp(x) + (n + 1 + 2/n) / 2^prec(x)
- <= ulp(x) + (n + 1 + 2/n) ulp(x)/x since x*2^(-prec(x)) < ulp(x)
- <= ulp(x) + (n + 1 + 2/n) 3/(2n) ulp(x) since x >= 2/3*n for n >= 2
- <= 4 * ulp(x) for n >= 2 */
+
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (x, y, rnd);
+
mpfr_clear (y);
+ mpz_clear (t);
+ mpz_clear (u);
+ mpz_clear (v);
+ mpfr_const_euler_bs_clear (sum);
- mpz_clear (a);
- mpz_clear (s);
+ return inexact; /* always inexact */
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/const_log2.c b/Build/source/libs/mpfr/mpfr-src/src/const_log2.c
index 8c46de2d95a..8ae1ee99b25 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/const_log2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/const_log2.c
@@ -117,33 +117,23 @@ mpfr_const_log2_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
mpz_t *T, *P, *Q;
mpfr_t t, q;
int inexact;
- int ok = 1; /* ensures that the 1st try will give correct rounding */
unsigned long lgN, i;
- MPFR_ZIV_DECL (loop);
+ MPFR_GROUP_DECL(group);
+ MPFR_TMP_DECL(marker);
+ MPFR_ZIV_DECL(loop);
MPFR_LOG_FUNC (
("rnd_mode=%d", rnd_mode),
("x[%Pu]=%.*Rg inex=%d", mpfr_get_prec(x), mpfr_log_prec, x, inexact));
- mpfr_init2 (t, MPFR_PREC_MIN);
- mpfr_init2 (q, MPFR_PREC_MIN);
-
- if (n < 1253)
- w = n + 10; /* ensures correct rounding for the four rounding modes,
+ if (n < 1069)
+ w = n + 9; /* ensures correct rounding for the four rounding modes,
together with N = w / 3 + 1 (see below). */
- else if (n < 2571)
- w = n + 11; /* idem */
- else if (n < 3983)
- w = n + 12;
- else if (n < 4854)
- w = n + 13;
- else if (n < 26248)
- w = n + 14;
else
- {
- w = n + 15;
- ok = 0;
- }
+ w = n + 10; /* idem at least for prec < 300000 */
+
+ MPFR_TMP_MARK(marker);
+ MPFR_GROUP_INIT_2(group, w, t, q);
MPFR_ZIV_INIT (loop, w);
for (;;)
@@ -156,7 +146,7 @@ mpfr_const_log2_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD(w >= 3 && N >= 2);
lgN = MPFR_INT_CEIL_LOG2 (N) + 1;
- T = (mpz_t *) (*__gmp_allocate_func) (3 * lgN * sizeof (mpz_t));
+ T = (mpz_t *) MPFR_TMP_ALLOC (3 * lgN * sizeof (mpz_t));
P = T + lgN;
Q = T + 2*lgN;
for (i = 0; i < lgN; i++)
@@ -168,9 +158,6 @@ mpfr_const_log2_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
S (T, P, Q, 0, N, 0);
- mpfr_set_prec (t, w);
- mpfr_set_prec (q, w);
-
mpfr_set_z (t, T[0], MPFR_RNDN);
mpfr_set_z (q, Q[0], MPFR_RNDN);
mpfr_div (t, t, q, MPFR_RNDN);
@@ -181,20 +168,21 @@ mpfr_const_log2_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
mpz_clear (P[i]);
mpz_clear (Q[i]);
}
- (*__gmp_free_func) (T, 3 * lgN * sizeof (mpz_t));
- if (MPFR_LIKELY (ok != 0
- || mpfr_can_round (t, w - 2, MPFR_RNDN, rnd_mode, n)))
+ /* for prec < 300000 and all rounding modes we checked by exhaustive
+ search that the rounding is correct */
+ if (MPFR_LIKELY (n < 300000 || MPFR_CAN_ROUND (t, w - 2, n, rnd_mode)))
break;
MPFR_ZIV_NEXT (loop, w);
+ MPFR_GROUP_REPREC_2(group, w, t, q);
}
MPFR_ZIV_FREE (loop);
inexact = mpfr_set (x, t, rnd_mode);
- mpfr_clear (t);
- mpfr_clear (q);
+ MPFR_GROUP_CLEAR(group);
+ MPFR_TMP_FREE(marker);
return inexact;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/const_pi.c b/Build/source/libs/mpfr/mpfr-src/src/const_pi.c
index ba9fced04f5..77d8df01e33 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/const_pi.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/const_pi.c
@@ -44,6 +44,7 @@ mpfr_const_pi_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
{
mpfr_t a, A, B, D, S;
mpfr_prec_t px, p, cancel, k, kmax;
+ MPFR_GROUP_DECL (group);
MPFR_ZIV_DECL (loop);
int inex;
@@ -58,11 +59,7 @@ mpfr_const_pi_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
p = px + 3 * kmax + 14; /* guarantees no recomputation for px <= 10000 */
- mpfr_init2 (a, p);
- mpfr_init2 (A, p);
- mpfr_init2 (B, p);
- mpfr_init2 (D, p);
- mpfr_init2 (S, p);
+ MPFR_GROUP_INIT_5 (group, p, a, A, B, D, S);
MPFR_ZIV_INIT (loop, p);
for (;;) {
@@ -87,13 +84,13 @@ mpfr_const_pi_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
mpfr_sub (Bp, Ap, S, MPFR_RNDN); /* -1/4 <= Bp <= 3/4 */
mpfr_mul_2ui (Bp, Bp, 1, MPFR_RNDN); /* -1/2 <= Bp <= 3/2 */
mpfr_sub (S, Ap, Bp, MPFR_RNDN);
- MPFR_ASSERTN (mpfr_cmp_ui (S, 1) < 0);
- cancel = mpfr_cmp_ui (S, 0) ? (mpfr_uexp_t) -mpfr_get_exp(S) : p;
+ MPFR_ASSERTD (mpfr_cmp_ui (S, 1) < 0);
+ cancel = MPFR_NOTZERO (S) ? (mpfr_uexp_t) -mpfr_get_exp(S) : p;
/* MPFR_ASSERTN (cancel >= px || cancel >= 9 * (1 << k) - 4); */
mpfr_mul_2ui (S, S, k, MPFR_RNDN);
mpfr_sub (D, D, S, MPFR_RNDN);
/* stop when |A_k - B_k| <= 2^(k-p) i.e. cancel >= p-k */
- if (cancel + k >= p)
+ if (cancel >= p - k)
break;
}
#undef b
@@ -109,20 +106,12 @@ mpfr_const_pi_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
p += kmax;
MPFR_ZIV_NEXT (loop, p);
- mpfr_set_prec (a, p);
- mpfr_set_prec (A, p);
- mpfr_set_prec (B, p);
- mpfr_set_prec (D, p);
- mpfr_set_prec (S, p);
+ MPFR_GROUP_REPREC_5 (group, p, a, A, B, D, S);
}
MPFR_ZIV_FREE (loop);
inex = mpfr_set (x, A, rnd_mode);
- mpfr_clear (a);
- mpfr_clear (A);
- mpfr_clear (B);
- mpfr_clear (D);
- mpfr_clear (S);
+ MPFR_GROUP_CLEAR (group);
return inex;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/constant.c b/Build/source/libs/mpfr/mpfr-src/src/constant.c
index 4c41cdc9aa2..96b7f742976 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/constant.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/constant.c
@@ -26,3 +26,40 @@ static const mp_limb_t __gmpfr_limb1[1] = {MPFR_LIMB_HIGHBIT};
const mpfr_t __gmpfr_one = {{2, MPFR_SIGN_POS, 1, (mp_limb_t*)__gmpfr_limb1}};
const mpfr_t __gmpfr_two = {{2, MPFR_SIGN_POS, 2, (mp_limb_t*)__gmpfr_limb1}};
const mpfr_t __gmpfr_four ={{2, MPFR_SIGN_POS, 3, (mp_limb_t*)__gmpfr_limb1}};
+const mpfr_t __gmpfr_mone ={{2, MPFR_SIGN_NEG, 1, (mp_limb_t*)__gmpfr_limb1}};
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+static const mp_limb_t mpfr_l2_dd__tab[] = { 0x79ab, 0xd1cf, 0x17f7, 0xb172 };
+#elif GMP_NUMB_BITS == 32
+static const mp_limb_t mpfr_l2_dd__tab[] = { 0xd1cf79ab, 0xb17217f7};
+#elif GMP_NUMB_BITS == 64
+static const mp_limb_t mpfr_l2_dd__tab[] = { 0xb17217f7d1cf79ab };
+#elif GMP_NUMB_BITS == 96
+static const mp_limb_t mpfr_l2_dd__tab[] = { 0xb17217f7d1cf79ab00000000 };
+#elif GMP_NUMB_BITS == 128
+static const mp_limb_t mpfr_l2_dd__tab[] = { 0xb17217f7d1cf79ab0000000000000000 };
+#elif GMP_NUMB_BITS == 256
+static const mp_limb_t mpfr_l2_dd__tab[] = { 0xb17217f7d1cf79ab000000000000000000000000000000000000000000000000 };
+#endif
+
+const mpfr_t __gmpfr_const_log2_RNDD =
+ {{64, MPFR_SIGN_POS, 0, (mp_limb_t*)mpfr_l2_dd__tab}};
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+static const mp_limb_t mpfr_l2_du__tab[] = { 0x79ac, 0xd1cf, 0x17f7, 0xb172 };
+#elif GMP_NUMB_BITS == 32
+static const mp_limb_t mpfr_l2_du__tab[] = { 0xd1cf79ac, 0xb17217f7};
+#elif GMP_NUMB_BITS == 64
+static const mp_limb_t mpfr_l2_du__tab[] = { 0xb17217f7d1cf79ac };
+#elif GMP_NUMB_BITS == 96
+static const mp_limb_t mpfr_l2_du__tab[] = { 0xb17217f7d1cf79ac00000000 };
+#elif GMP_NUMB_BITS == 128
+static const mp_limb_t mpfr_l2_du__tab[] = { 0xb17217f7d1cf79ac0000000000000000 };
+#elif GMP_NUMB_BITS == 256
+static const mp_limb_t mpfr_l2_du__tab[] = { 0xb17217f7d1cf79ac000000000000000000000000000000000000000000000000 };
+#endif
+
+const mpfr_t __gmpfr_const_log2_RNDU =
+ {{64, MPFR_SIGN_POS, 0, (mp_limb_t*)mpfr_l2_du__tab}};
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cos.c b/Build/source/libs/mpfr/mpfr-src/src/cos.c
index 18968e83231..d5a77159496 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cos.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cos.c
@@ -49,7 +49,7 @@ mpfr_cos2_aux (mpfr_ptr f, mpfr_srcptr r)
/* compute minimal i such that i*(i+1) does not fit in an unsigned long,
assuming that there are no padding bits. */
- maxi = 1UL << (CHAR_BIT * sizeof(unsigned long) / 2);
+ maxi = 1UL << (sizeof(unsigned long) * CHAR_BIT / 2);
if (maxi * (maxi / 2) == 0) /* test checked at compile time */
{
/* can occur only when there are padding bits. */
@@ -174,7 +174,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
K0 = __gmpfr_isqrt (precy / 3);
- m = precy + 2 * MPFR_INT_CEIL_LOG2 (precy) + 2 * K0;
+ m = precy + 2 * MPFR_INT_CEIL_LOG2 (precy) + 2 * K0 + 4;
if (expx >= 3)
{
@@ -245,7 +245,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
l = 2 * l + 1;
if (reduce)
l += (K == 0) ? 4 : 1;
- k = MPFR_INT_CEIL_LOG2 (l) + 2*K;
+ k = MPFR_INT_CEIL_LOG2 (l) + 2 * K;
/* now the error is bounded by 2^(k-m) = 2^(EXP(s)-err) */
exps = MPFR_GET_EXP (s);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cosh.c b/Build/source/libs/mpfr/mpfr-src/src/cosh.c
index 3d408cb840e..88ac0fc1af7 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cosh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cosh.c
@@ -82,7 +82,7 @@ mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
/* The optimal number of bits : see algorithms.tex */
Nt = Ny + 3 + MPFR_INT_CEIL_LOG2 (Ny);
- /* initialise of intermediary variables */
+ /* initialize of intermediary variables */
MPFR_GROUP_INIT_2 (group, Nt, t, te);
/* First computation of cosh */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cot.c b/Build/source/libs/mpfr/mpfr-src/src/cot.c
index eba86c0c2e7..f743f6919da 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cot.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cot.c
@@ -32,7 +32,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
- mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+ MPFR_SET_DIVBY0 (); MPFR_RET(0); } while (1)
/* (This analysis is adapted from that for mpfr_coth.)
Near x=0, cot(x) = 1/x - x/3 + ..., more precisely we have
@@ -54,7 +54,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
{ \
int two2emin; \
int signx = MPFR_SIGN(x); \
- MPFR_ASSERTN (MPFR_EMIN_MIN + MPFR_EMAX_MAX == 0); \
+ MPFR_STAT_STATIC_ASSERT (MPFR_EMIN_MIN + MPFR_EMAX_MAX == 0); \
if ((two2emin = mpfr_get_exp (x) == __gmpfr_emin + 1 && \
mpfr_powerof2_raw (x))) \
{ \
diff --git a/Build/source/libs/mpfr/mpfr-src/src/coth.c b/Build/source/libs/mpfr/mpfr-src/src/coth.c
index 9d1544b8fe8..c6163b6e751 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/coth.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/coth.c
@@ -33,7 +33,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_INF(y) return mpfr_set_si (y, MPFR_IS_POS(x) ? 1 : -1, rnd_mode)
#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
- mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+ MPFR_SET_DIVBY0 (); MPFR_RET(0); } while (1)
/* We know |coth(x)| > 1, thus if the approximation z is such that
1 <= z <= 1 + 2^(-p) where p is the target precision, then the
@@ -42,10 +42,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
if (MPFR_GET_EXP(z) == 1) /* 1 <= |z| < 2 */ \
{ \
/* the following is exact by Sterbenz theorem */ \
- mpfr_sub_si (z, z, MPFR_SIGN(z) > 0 ? 1 : -1, MPFR_RNDN); \
+ mpfr_sub_si (z, z, MPFR_SIGN (z), MPFR_RNDN); \
if (MPFR_IS_ZERO(z) || MPFR_GET_EXP(z) <= - (mpfr_exp_t) precy) \
{ \
- mpfr_add_si (z, z, MPFR_SIGN(z) > 0 ? 1 : -1, MPFR_RNDN); \
+ mpfr_add_si (z, z, MPFR_SIGN (z), MPFR_RNDN); \
break; \
} \
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/csc.c b/Build/source/libs/mpfr/mpfr-src/src/csc.c
index cd0a274da9f..9852083e9f7 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/csc.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/csc.c
@@ -32,7 +32,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
- mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+ MPFR_SET_DIVBY0 (); MPFR_RET(0); } while (1)
/* near x=0, we have csc(x) = 1/x + x/6 + ..., more precisely we have
|csc(x) - 1/x| <= 0.2 for |x| <= 1. The analysis is similar to that for
gamma(x) near x=0 (see gamma.c), except here the error term has the same
diff --git a/Build/source/libs/mpfr/mpfr-src/src/csch.c b/Build/source/libs/mpfr/mpfr-src/src/csch.c
index 2f76fedffd7..d899d1f0c2b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/csch.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/csch.c
@@ -34,7 +34,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define ACTION_INF(y) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_ZERO (y); \
MPFR_RET(0); } while (1)
#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
- mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+ MPFR_SET_DIVBY0 (); MPFR_RET(0); } while (1)
/* (This analysis is adapted from that for mpfr_csc.)
Near x=0, we have csch(x) = 1/x - x/6 + ..., more precisely we have
diff --git a/Build/source/libs/mpfr/mpfr-src/src/d_div.c b/Build/source/libs/mpfr/mpfr-src/src/d_div.c
index 9c1ea0487a9..726b95104c7 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/d_div.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/d_div.c
@@ -28,6 +28,7 @@ mpfr_d_div (mpfr_ptr a, double b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t d;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_LOG_FUNC (
@@ -36,15 +37,14 @@ mpfr_d_div (mpfr_ptr a, double b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, d, IEEE_DBL_MANT_DIG);
inexact = mpfr_set_d (d, b, rnd_mode);
- MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTD (inexact == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_div (a, d, c, rnd_mode);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear(d);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (a, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/d_sub.c b/Build/source/libs/mpfr/mpfr-src/src/d_sub.c
index d9b9685859c..392faf7a84d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/d_sub.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/d_sub.c
@@ -28,6 +28,7 @@ mpfr_d_sub (mpfr_ptr a, double b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t d;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_LOG_FUNC (
@@ -36,15 +37,14 @@ mpfr_d_sub (mpfr_ptr a, double b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, d, IEEE_DBL_MANT_DIG);
inexact = mpfr_set_d (d, b, rnd_mode);
- MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTD (inexact == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_sub (a, d, c, rnd_mode);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear(d);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (a, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/digamma.c b/Build/source/libs/mpfr/mpfr-src/src/digamma.c
index 319eaf22e8b..91e66c54469 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/digamma.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/digamma.c
@@ -34,8 +34,7 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
mpfr_prec_t p = MPFR_PREC (s);
mpfr_t t, u, invxx;
mpfr_exp_t e, exps, f, expu;
- mpz_t *INITIALIZED(B); /* variable B declared as initialized */
- unsigned long n0, n; /* number of allocated B[] */
+ unsigned long n;
MPFR_ASSERTN(MPFR_IS_POS(x) && (MPFR_EXP(x) >= 2));
@@ -59,12 +58,9 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
/* in the following we note err=xxx when the ratio between the approximation
and the exact result can be written (1 + theta)^xxx for |theta| <= 2^(-p),
following Higham's method */
- B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
mpfr_set_ui (t, 1, MPFR_RNDN); /* err = 0 */
for (n = 1;; n++)
{
- /* compute next Bernoulli number */
- B = mpfr_bernoulli_internal (B, n);
/* The main term is Bernoulli[2n]/(2n)/x^(2n) = B[n]/(2n+1)!(2n)/x^(2n)
= B[n]*t[n]/(2n) where t[n]/t[n-1] = 1/(2n)/(2n+1)/x^2. */
mpfr_mul (t, t, invxx, MPFR_RNDU); /* err = err + 3 */
@@ -72,7 +68,7 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
mpfr_div_ui (t, t, 2 * n + 1, MPFR_RNDU); /* err = err + 1 */
/* we thus have err = 5n here */
mpfr_div_ui (u, t, 2 * n, MPFR_RNDU); /* err = 5n+1 */
- mpfr_mul_z (u, u, B[n], MPFR_RNDU); /* err = 5n+2, and the
+ mpfr_mul_z (u, u, mpfr_bernoulli_cache(n), MPFR_RNDU);/* err = 5n+2, and the
absolute error is bounded
by 10n+4 ulp(u) [Rule 11] */
/* if the terms 'u' are decreasing by a factor two at least,
@@ -92,14 +88,9 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
f = (1 + f) / 2;
expu ++;
}
- e += f; /* total rouding error coming from 'u' term */
+ e += f; /* total rounding error coming from 'u' term */
}
- n0 = ++n;
- while (n--)
- mpz_clear (B[n]);
- (*__gmp_free_func) (B, n0 * sizeof (mpz_t));
-
mpfr_clear (t);
mpfr_clear (u);
mpfr_clear (invxx);
@@ -126,6 +117,10 @@ mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
int inex;
MPFR_ZIV_DECL (loop);
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inex));
+
/* we want that 1-x is exact with precision q: if 0 < x < 1/2, then
q = PREC(x)-EXP(x) is ok, otherwise if -1 <= x < 0, q = PREC(x)-EXP(x)
is ok, otherwise for x < -1, PREC(x) is ok if EXP(x) <= PREC(x),
@@ -137,7 +132,8 @@ mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
else
q = MPFR_EXP(x);
mpfr_init2 (u, q);
- MPFR_ASSERTN(mpfr_ui_sub (u, 1, x, MPFR_RNDN) == 0);
+ MPFR_DBGRES(inex = mpfr_ui_sub (u, 1, x, MPFR_RNDN));
+ MPFR_ASSERTN(inex == 0);
/* if x is half an integer, cot(Pi*x) = 0, thus Digamma(x) = Digamma(1-x) */
mpfr_mul_2exp (u, u, 1, MPFR_RNDN);
@@ -208,11 +204,31 @@ mpfr_digamma_positive (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
unsigned long j = 0, min;
MPFR_ZIV_DECL (loop);
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inex));
+
/* compute a precision q such that x+1 is exact */
if (MPFR_PREC(x) < MPFR_EXP(x))
q = MPFR_EXP(x);
else
q = MPFR_PREC(x) + 1;
+
+ /* for very large x, use |digamma(x) - log(x)| < 1/x < 2^(1-EXP(x)) */
+ if (MPFR_PREC(y) + 10 < MPFR_EXP(x))
+ {
+ /* this ensures EXP(x) >= 3, thus x >= 4, thus log(x) > 1 */
+ mpfr_init2 (t, MPFR_PREC(y) + 10);
+ mpfr_log (t, x, MPFR_RNDZ);
+ if (MPFR_CAN_ROUND (t, MPFR_PREC(y) + 10, MPFR_PREC(y), rnd_mode))
+ {
+ inex = mpfr_set (y, t, rnd_mode);
+ mpfr_clear (t);
+ return inex;
+ }
+ mpfr_clear (t);
+ }
+
mpfr_init2 (x_plus_j, q);
mpfr_init2 (t, p);
@@ -285,7 +301,6 @@ mpfr_digamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
(("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inex));
-
if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
{
if (MPFR_IS_NAN(x))
@@ -312,7 +327,7 @@ mpfr_digamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
/* the following works also in case of overlap */
MPFR_SET_INF(y);
MPFR_SET_OPPOSITE_SIGN(y, x);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET(0);
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/div.c b/Build/source/libs/mpfr/mpfr-src/src/div.c
index 120df1bbfb7..7d208621f24 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/div.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/div.c
@@ -24,30 +24,639 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
[1] Short Division of Long Integers, David Harvey and Paul Zimmermann,
Proceedings of the 20th Symposium on Computer Arithmetic (ARITH-20),
July 25-27, 2011, pages 7-14.
+ [2] Improved Division by Invariant Integers, Niels Möller and Torbjörn Granlund,
+ IEEE Transactions on Computers, volume 60, number 2, pages 165-175, 2011.
*/
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-#ifdef DEBUG2
-#define mpfr_mpn_print(ap,n) mpfr_mpn_print3 (ap,n,MPFR_LIMB_ZERO)
+#if !defined(MPFR_GENERIC_ABI)
+
+#if GMP_NUMB_BITS == 64
+
+#include "invert_limb.h"
+
+/* Given u = u1*B+u0 < v = v1*B+v0 with v normalized (high bit of v1 set),
+ put in q = Q1*B+Q0 an approximation of floor(u*B^2/v), with:
+ B = 2^GMP_NUMB_BITS and q <= floor(u*B^2/v) <= q + 21.
+ Note: this function requires __gmpfr_invert_limb_approx (from invert_limb.h)
+ which is only provided so far for 64-bit limb.
+ Note: __gmpfr_invert_limb_approx can be replaced by __gmpfr_invert_limb,
+ in that case the bound 21 reduces to 16. */
static void
-mpfr_mpn_print3 (mpfr_limb_ptr ap, mp_size_t n, mp_limb_t cy)
+mpfr_div2_approx (mpfr_limb_ptr Q1, mpfr_limb_ptr Q0,
+ mp_limb_t u1, mp_limb_t u0,
+ mp_limb_t v1, mp_limb_t v0)
+{
+ mp_limb_t inv, q1, q0, r1, r0, cy, xx, yy;
+
+ /* first compute an approximation of q1, using a lower approximation of
+ B^2/(v1+1) - B */
+ if (MPFR_UNLIKELY(v1 == MPFR_LIMB_MAX))
+ inv = MPFR_LIMB_ZERO;
+ else
+ __gmpfr_invert_limb_approx (inv, v1 + 1);
+ /* now inv <= B^2/(v1+1) - B */
+ umul_ppmm (q1, q0, u1, inv);
+ q1 += u1;
+ /* now q1 <= u1*B/(v1+1) < (u1*B+u0)*B/(v1*B+v0) */
+
+ /* compute q1*(v1*B+v0) into r1:r0:yy and subtract from u1:u0:0 */
+ umul_ppmm (r1, r0, q1, v1);
+ umul_ppmm (xx, yy, q1, v0);
+
+ ADD_LIMB (r0, xx, cy);
+ r1 += cy;
+
+ /* we ignore yy below, but first increment r0, to ensure we get a lower
+ approximation of the remainder */
+ r0 += yy != 0;
+ r1 += r0 == 0 && yy != 0;
+ r0 = u0 - r0;
+ r1 = u1 - r1 - (r0 > u0);
+
+ /* r1:r0 should be nonnegative */
+ MPFR_ASSERTD((r1 & MPFR_LIMB_HIGHBIT) == 0);
+
+ /* the second quotient limb is approximated by (r1*B^2+r0*B) / v1,
+ and since (B+inv)/B approximates B/v1, this is in turn approximated
+ by (r1*B+r0)*(B+inv)/B = r1*B*r1*inv+r0+(r0*inv/B) */
+
+ q0 = r0;
+ q1 += r1;
+ /* add floor(r0*inv/B) to q0 */
+ umul_ppmm (xx, yy, r0, inv);
+ ADD_LIMB (q0, xx, cy);
+ q1 += cy;
+ MPFR_ASSERTD (r1 <= 4);
+ /* TODO: use value coverage on r1 to check that the 5 cases are tested. */
+ while (r1) /* the number of loops is at most 4 */
+ {
+ /* add inv to q0 */
+ ADD_LIMB (q0, inv, cy);
+ q1 += cy;
+ r1 --;
+ }
+
+ *Q1 = q1;
+ *Q0 = q0;
+}
+
+#endif /* GMP_NUMB_BITS == 64 */
+
+/* Special code for PREC(q) = PREC(u) = PREC(v) = p < GMP_NUMB_BITS */
+static int
+mpfr_div_1 (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
{
- mp_size_t i;
- for (i = 0; i < n; i++)
- printf ("+%lu*2^%lu", (unsigned long) ap[i], (unsigned long)
- (GMP_NUMB_BITS * i));
- if (cy)
- printf ("+2^%lu", (unsigned long) (GMP_NUMB_BITS * n));
- printf ("\n");
+ mpfr_prec_t p = MPFR_GET_PREC(q);
+ mpfr_limb_ptr qp = MPFR_MANT(q);
+ mpfr_exp_t qx = MPFR_GET_EXP(u) - MPFR_GET_EXP(v);
+ mpfr_prec_t sh = GMP_NUMB_BITS - p;
+ mp_limb_t u0 = MPFR_MANT(u)[0];
+ mp_limb_t v0 = MPFR_MANT(v)[0];
+ mp_limb_t q0, rb, sb, mask = MPFR_LIMB_MASK(sh);
+ int extra;
+
+ if ((extra = (u0 >= v0)))
+ u0 -= v0;
+
+#if GMP_NUMB_BITS == 64 /* __gmpfr_invert_limb_approx only exists for 64-bit */
+ /* First try with an approximate quotient.
+ FIXME: for p<=62 we have sh-1<2 and will never be able to round correctly.
+ Even for p=61 we have sh-1=2 and we can round correctly only when the two
+ last bist of q0 are 01, which happens with probability 25% only. */
+ {
+ mp_limb_t inv;
+ __gmpfr_invert_limb_approx (inv, v0);
+ umul_ppmm (rb, sb, u0, inv);
+ }
+ rb += u0;
+ q0 = rb >> extra;
+ /* rb does not exceed the true quotient floor(u0*2^GMP_NUMB_BITS/v0),
+ with error at most 2, which means the rational quotient q satisfies
+ rb <= q < rb + 3. We can round correctly except when the last sh-1 bits
+ of q0 are 000..000 or 111..111 or 111..110. */
+ if (MPFR_LIKELY(((q0 + 2) & (mask >> 1)) > 2))
+ {
+ rb = q0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb = 1; /* result cannot be exact in this case */
+ }
+ else /* the true quotient is rb, rb+1 or rb+2 */
+ {
+ mp_limb_t h, l;
+ q0 = rb;
+ umul_ppmm (h, l, q0, v0);
+ MPFR_ASSERTD(h < u0 || (h == u0 && l == MPFR_LIMB_ZERO));
+ /* subtract {h,l} from {u0,0} */
+ sub_ddmmss (h, l, u0, 0, h, l);
+ /* the remainder {h, l} should be < v0 */
+ /* This while loop is executed at most two times, but does not seem
+ slower than two consecutive identical if-statements. */
+ while (h || l >= v0)
+ {
+ q0 ++;
+ h -= (l < v0);
+ l -= v0;
+ }
+ MPFR_ASSERTD(h == 0 && l < v0);
+ sb = l | (q0 & extra);
+ q0 >>= extra;
+ rb = q0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= q0 & (mask >> 1);
+ }
+#else
+ udiv_qrnnd (q0, sb, u0, 0, v0);
+ sb |= q0 & extra;
+ q0 >>= extra;
+ rb = q0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= q0 & (mask >> 1);
+#endif
+
+ qp[0] = (MPFR_LIMB_HIGHBIT | q0) & ~mask;
+ qx += extra;
+ MPFR_SIGN(q) = MPFR_MULT_SIGN (MPFR_SIGN (u), MPFR_SIGN (v));
+
+ /* rounding */
+ if (MPFR_UNLIKELY(qx > __gmpfr_emax))
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when q > 0.111...111*2^(emin-1), or when rounding to nearest and
+ q >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(qx < __gmpfr_emin))
+ {
+ /* Note: the case 0.111...111*2^(emin-1) < q < 2^(emin-1) is not possible
+ here since (up to exponent) this would imply 1 - 2^(-p) < u/v < 1,
+ thus v - 2^(-p)*v < u < v, and since we can assume 1/2 <= v < 1, it
+ would imply v - 2^(-p) = v - ulp(v) < u < v, which has no solution. */
+
+ /* For RNDN, mpfr_underflow always rounds away, thus for |q|<=2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either qx < emin - 1
+ (b) or qx = emin - 1 and qp[0] = 1000....000 and rb = sb = 0.
+ Note: in case (b), it suffices to check whether sb = 0, since rb = 1
+ and sb = 0 is not possible (the exact quotient would have p+1 bits,
+ thus u would need at least p+1 bits). */
+ if (rnd_mode == MPFR_RNDN &&
+ (qx < __gmpfr_emin - 1 || (qp[0] == MPFR_LIMB_HIGHBIT && sb == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (q, rnd_mode, MPFR_SIGN(q));
+ }
+
+ MPFR_EXP (q) = qx; /* Don't use MPFR_SET_EXP since qx might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(qx >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* It is not possible to have rb <> 0 and sb = 0 here, since it would
+ mean a n-bit by n-bit division gives an exact (n+1)-bit number.
+ And since the case rb = sb = 0 was already dealt with, we cannot
+ have sb = 0. Thus we cannot be in the middle of two numbers. */
+ MPFR_ASSERTD(sb != 0);
+ if (rb == 0)
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(q)))
+ {
+ truncate:
+ MPFR_ASSERTD(qx >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(q));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ qp[0] += MPFR_LIMB_ONE << sh;
+ if (qp[0] == 0)
+ {
+ qp[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(qx + 1 > __gmpfr_emax))
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+ MPFR_ASSERTD(qx + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(qx + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (q, qx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(q));
+ }
}
+
+/* Special code for PREC(q) = GMP_NUMB_BITS,
+ with PREC(u), PREC(v) <= GMP_NUMB_BITS. */
+static int
+mpfr_div_1n (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
+{
+ mpfr_limb_ptr qp = MPFR_MANT(q);
+ mpfr_exp_t qx = MPFR_GET_EXP(u) - MPFR_GET_EXP(v);
+ mp_limb_t u0 = MPFR_MANT(u)[0];
+ mp_limb_t v0 = MPFR_MANT(v)[0];
+ mp_limb_t q0, rb, sb, l;
+ int extra;
+
+ MPFR_ASSERTD(MPFR_PREC(q) == GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC(u) <= GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC(v) <= GMP_NUMB_BITS);
+
+ if ((extra = (u0 >= v0)))
+ u0 -= v0;
+
+#if GMP_NUMB_BITS == 64 /* __gmpfr_invert_limb_approx only exists for 64-bit */
+ {
+ mp_limb_t inv, h;
+
+ /* First compute an approximate quotient. */
+ __gmpfr_invert_limb_approx (inv, v0);
+ umul_ppmm (rb, sb, u0, inv);
+ q0 = u0 + rb;
+ /* rb does not exceed the true quotient floor(u0*2^GMP_NUMB_BITS/v0),
+ with error at most 2, which means the rational quotient q satisfies
+ rb <= q < rb + 3, thus the true quotient is rb, rb+1 or rb+2 */
+ umul_ppmm (h, l, q0, v0);
+ MPFR_ASSERTD(h < u0 || (h == u0 && l == MPFR_LIMB_ZERO));
+ /* subtract {h,l} from {u0,0} */
+ sub_ddmmss (h, l, u0, 0, h, l);
+ /* the remainder {h, l} should be < v0 */
+ /* This while loop is executed at most two times, but does not seem
+ slower than two consecutive identical if-statements. */
+ while (h || l >= v0)
+ {
+ q0 ++;
+ h -= (l < v0);
+ l -= v0;
+ }
+ MPFR_ASSERTD(h == 0 && l < v0);
+ }
+#else
+ udiv_qrnnd (q0, l, u0, 0, v0);
+#endif
+
+ /* now (u0 - extra*v0) * 2^GMP_NUMB_BITS = q0*v0 + l with 0 <= l < v0 */
+
+ /* If extra=0, the quotient is q0, the round bit is 1 if l >= v0/2,
+ and sb are the remaining bits from l.
+ If extra=1, the quotient is MPFR_LIMB_HIGHBIT + (q0 >> 1), the round bit
+ is the least significant bit of q0, and sb is l. */
+
+ if (extra == 0)
+ {
+ qp[0] = q0;
+ /* If "l + l < l", then there is a carry in l + l, thus 2*l > v0.
+ Otherwise if there is no carry, we check whether 2*l >= v0. */
+ rb = (l + l < l) || (l + l >= v0);
+ sb = (rb) ? l + l - v0 : l;
+ }
+ else
+ {
+ qp[0] = MPFR_LIMB_HIGHBIT | (q0 >> 1);
+ rb = q0 & MPFR_LIMB_ONE;
+ sb = l;
+ qx ++;
+ }
+
+ MPFR_SIGN(q) = MPFR_MULT_SIGN (MPFR_SIGN (u), MPFR_SIGN (v));
+
+ /* rounding */
+ if (MPFR_UNLIKELY(qx > __gmpfr_emax))
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when q > 0.111...111*2^(emin-1), or when rounding to nearest and
+ q >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(qx < __gmpfr_emin))
+ {
+ /* Note: the case 0.111...111*2^(emin-1) < q < 2^(emin-1) is not possible
+ here since (up to exponent) this would imply 1 - 2^(-p) < u/v < 1,
+ thus v - 2^(-p)*v < u < v, and since we can assume 1/2 <= v < 1, it
+ would imply v - 2^(-p) = v - ulp(v) < u < v, which has no solution. */
+
+ /* For RNDN, mpfr_underflow always rounds away, thus for |q|<=2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either qx < emin - 1
+ (b) or qx = emin - 1 and qp[0] = 1000....000 and rb = sb = 0.
+ Note: in case (b), it suffices to check whether sb = 0, since rb = 1
+ and sb = 0 is not possible (the exact quotient would have p+1 bits,
+ thus u would need at least p+1 bits). */
+ if (rnd_mode == MPFR_RNDN &&
+ (qx < __gmpfr_emin - 1 || (qp[0] == MPFR_LIMB_HIGHBIT && sb == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (q, rnd_mode, MPFR_SIGN(q));
+ }
+
+ MPFR_EXP (q) = qx; /* Don't use MPFR_SET_EXP since qx might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(qx >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* It is not possible to have rb <> 0 and sb = 0 here, since it would
+ mean a n-bit by n-bit division gives an exact (n+1)-bit number.
+ And since the case rb = sb = 0 was already dealt with, we cannot
+ have sb = 0. Thus we cannot be in the middle of two numbers. */
+ MPFR_ASSERTD(sb != 0);
+ if (rb == 0)
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(q)))
+ {
+ truncate:
+ MPFR_ASSERTD(qx >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(q));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ qp[0] += MPFR_LIMB_ONE;
+ if (qp[0] == 0)
+ {
+ qp[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(qx + 1 > __gmpfr_emax))
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+ MPFR_ASSERTD(qx + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(qx + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (q, qx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(q));
+ }
+}
+
+/* Special code for GMP_NUMB_BITS < PREC(q) < 2*GMP_NUMB_BITS and
+ PREC(u) = PREC(v) = PREC(q) */
+static int
+mpfr_div_2 (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t p = MPFR_GET_PREC(q);
+ mpfr_limb_ptr qp = MPFR_MANT(q);
+ mpfr_exp_t qx = MPFR_GET_EXP(u) - MPFR_GET_EXP(v);
+ mpfr_prec_t sh = 2*GMP_NUMB_BITS - p;
+ mp_limb_t h, rb, sb, mask = MPFR_LIMB_MASK(sh);
+ mp_limb_t v1 = MPFR_MANT(v)[1], v0 = MPFR_MANT(v)[0];
+ mp_limb_t q1, q0, r3, r2, r1, r0, l, t;
+ int extra;
+
+ r3 = MPFR_MANT(u)[1];
+ r2 = MPFR_MANT(u)[0];
+ extra = r3 > v1 || (r3 == v1 && r2 >= v0);
+ if (extra)
+ sub_ddmmss (r3, r2, r3, r2, v1, v0);
+
+ MPFR_ASSERTD(r3 < v1 || (r3 == v1 && r2 < v0));
+
+#if GMP_NUMB_BITS == 64
+ mpfr_div2_approx (&q1, &q0, r3, r2, v1, v0);
+ /* we know q1*B+q0 is smaller or equal to the exact quotient, with
+ difference at most 21 */
+ if (MPFR_LIKELY(((q0 + 21) & (mask >> 1)) > 21))
+ sb = 1; /* result is not exact when we can round with an approximation */
+ else
+ {
+ /* we know q1:q0 is a good-enough approximation, use it! */
+ mp_limb_t s0, s1, s2, h, l;
+
+ /* Since we know the difference should be at most 21*(v1:v0) after the
+ subtraction below, thus at most 21*2^128, it suffices to compute the
+ lower 3 limbs of (q1:q0) * (v1:v0). */
+ umul_ppmm (s1, s0, q0, v0);
+ umul_ppmm (s2, l, q0, v1);
+ s1 += l;
+ s2 += (s1 < l);
+ umul_ppmm (h, l, q1, v0);
+ s1 += l;
+ s2 += h + (s1 < l);
+ s2 += q1 * v1;
+ /* Subtract s2:s1:s0 from r2:0:0, with result in s2:s1:s0. */
+ s2 = r2 - s2;
+ /* now negate s1:s0 */
+ s0 = -s0;
+ s1 = -s1 - (s0 != 0);
+ /* there is a borrow in s2 when s0 and s1 are not both zero */
+ s2 -= (s1 != 0 || s0 != 0);
+ while (s2 > 0 || (s1 > v1) || (s1 == v1 && s0 >= v0))
+ {
+ /* add 1 to q1:q0 */
+ q0 ++;
+ q1 += (q0 == 0);
+ /* subtract v1:v0 to s2:s1:s0 */
+ s2 -= (s1 < v1) || (s1 == v1 && s0 < v0);
+ sub_ddmmss (s1, s0, s1, s0, v1, v0);
+ }
+ sb = s1 | s0;
+ }
+ goto round_div2;
+#endif
+
+ /* now r3:r2 < v1:v0 */
+ if (MPFR_UNLIKELY(r3 == v1)) /* can occur in some rare cases */
+ {
+ /* This can only occur in case extra=0, since otherwise we would have
+ u_old >= u_new + v >= B^2/2 + B^2/2 = B^2. In this case we have
+ r3 = u1 and r2 = u0, thus the remainder u*B-q1*v is
+ v1*B^2+u0*B-(B-1)*(v1*B+v0) = (u0-v0+v1)*B+v0.
+ Warning: in this case q1 = B-1 can be too large, for example with
+ u = B^2/2 and v = B^2/2 + B - 1, then u*B-(B-1)*u = -1/2*B^2+2*B-1. */
+ MPFR_ASSERTD(extra == 0);
+ q1 = MPFR_LIMB_MAX;
+ r1 = v0;
+ t = v0 - r2; /* t > 0 since r3:r2 < v1:v0 */
+ r2 = v1 - t;
+ if (t > v1) /* q1 = B-1 is too large, we need q1 = B-2, which is ok
+ since u*B - q1*v >= v1*B^2-(B-2)*(v1*B+B-1) =
+ -B^2 + 2*B*v1 + 3*B - 2 >= 0 since v1>=B/2 and B>=2 */
+ {
+ q1 --;
+ /* add v to r2:r1 */
+ r1 += v0;
+ r2 += v1 + (r1 < v0);
+ }
+ }
+ else
+ {
+ /* divide r3:r2 by v1: requires r3 < v1 */
+ udiv_qrnnd (q1, r2, r3, r2, v1);
+ /* u-extra*v = q1 * v1 + r2 */
+
+ /* now subtract q1*v0 to r2:0 */
+ umul_ppmm (h, l, q1, v0);
+ t = r2; /* save old value of r2 */
+ r1 = -l;
+ r2 -= h + (l != 0);
+ /* Note: h + (l != 0) < 2^GMP_NUMB_BITS. */
+
+ /* we have r2:r1 = oldr2:0 - q1*v0 mod 2^(2*GMP_NUMB_BITS)
+ thus (u-extra*v)*B = q1 * v + r2:r1 mod 2^(2*GMP_NUMB_BITS) */
+
+ /* this while loop should be run at most twice */
+ while (r2 > t) /* borrow when subtracting h + (l != 0), q1 too large */
+ {
+ q1 --;
+ /* add v1:v0 to r2:r1 */
+ t = r2;
+ r1 += v0;
+ r2 += v1 + (r1 < v0);
+ /* note: since 2^(GMP_NUMB_BITS-1) <= v1 + (r1 < v0)
+ <= 2^GMP_NUMB_BITS, it suffices to check if r2 <= t to see
+ if there was a carry or not. */
+ }
+ }
+
+ /* now (u-extra*v)*B = q1 * v + r2:r1 with 0 <= r2:r1 < v */
+
+ MPFR_ASSERTD(r2 < v1 || (r2 == v1 && r1 < v0));
+
+ if (MPFR_UNLIKELY(r2 == v1))
+ {
+ q0 = MPFR_LIMB_MAX;
+ /* r2:r1:0 - q0*(v1:v0) = v1:r1:0 - (B-1)*(v1:v0)
+ = r1:0 - v0:0 + v1:v0 */
+ r0 = v0;
+ t = v0 - r1; /* t > 0 since r2:r1 < v1:v0 */
+ r1 = v1 - t;
+ if (t > v1)
+ {
+ q0 --;
+ /* add v to r1:r0 */
+ r0 += v0;
+ r1 += v1 + (r0 < v0);
+ }
+ }
+ else
+ {
+ /* divide r2:r1 by v1: requires r2 < v1 */
+ udiv_qrnnd (q0, r1, r2, r1, v1);
+
+ /* r2:r1 = q0*v1 + r1 */
+
+ /* subtract q0*v0 to r1:0 */
+ umul_ppmm (h, l, q0, v0);
+ t = r1;
+ r0 = -l;
+ r1 -= h + (l != 0);
+
+ /* this while loop should be run at most twice */
+ while (r1 > t) /* borrow when subtracting h + (l != 0),
+ q0 was too large */
+ {
+ q0 --;
+ /* add v1:v0 to r1:r0 */
+ t = r1;
+ r0 += v0;
+ r1 += v1 + (r0 < v0);
+ /* note: since 2^(GMP_NUMB_BITS-1) <= v1 + (r0 < v0)
+ <= 2^GMP_NUMB_BITS, it suffices to check if r1 <= t to see
+ if there was a carry or not. */
+ }
+ }
+
+ MPFR_ASSERTD(r1 < v1 || (r1 == v1 && r0 < v0));
+
+ /* now (u-extra*v)*B^2 = (q1:q0) * v + r1:r0 */
+
+ sb = r1 | r0;
+
+ /* here, q1:q0 should be an approximation of the quotient (or the exact
+ quotient), and sb the sticky bit */
+
+#if GMP_NUMB_BITS == 64
+ round_div2:
#endif
+ if (extra)
+ {
+ qx ++;
+ sb |= q0 & 1;
+ q0 = (q1 << (GMP_NUMB_BITS - 1)) | (q0 >> 1);
+ q1 = MPFR_LIMB_HIGHBIT | (q1 >> 1);
+ }
+ rb = q0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (q0 & mask) ^ rb;
+ qp[1] = q1;
+ qp[0] = q0 & ~mask;
+
+ MPFR_SIGN(q) = MPFR_MULT_SIGN (MPFR_SIGN (u), MPFR_SIGN (v));
+
+ /* rounding */
+ if (qx > __gmpfr_emax)
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when q > 0.111...111*2^(emin-1), or when rounding to nearest and
+ q >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (qx < __gmpfr_emin)
+ {
+ /* Note: the case 0.111...111*2^(emin-1) < q < 2^(emin-1) is not possible
+ here since (up to exponent) this would imply 1 - 2^(-p) < u/v < 1,
+ thus v - 2^(-p)*v < u < v, and since we can assume 1/2 <= v < 1, it
+ would imply v - 2^(-p) = v - ulp(v) < u < v, which has no solution. */
+
+ /* For RNDN, mpfr_underflow always rounds away, thus for |q|<=2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either qx < emin - 1
+ (b) or qx = emin - 1 and qp[1] = 100....000, qp[0] = 0 and rb = sb = 0.
+ Note: in case (b), it suffices to check whether sb = 0, since rb = 1
+ and sb = 0 is not possible (the exact quotient would have p+1 bits, thus
+ u would need at least p+1 bits). */
+ if (rnd_mode == MPFR_RNDN &&
+ (qx < __gmpfr_emin - 1 ||
+ (qp[1] == MPFR_LIMB_HIGHBIT && qp[0] == MPFR_LIMB_ZERO && sb == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (q, rnd_mode, MPFR_SIGN(q));
+ }
+
+ MPFR_EXP (q) = qx; /* Don't use MPFR_SET_EXP since qx might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(qx >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* See the comment in mpfr_div_1. */
+ MPFR_ASSERTD(sb != 0);
+ if (rb == 0)
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(q)))
+ {
+ truncate:
+ MPFR_ASSERTD(qx >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(q));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ qp[0] += MPFR_LIMB_ONE << sh;
+ qp[1] += (qp[0] == 0);
+ if (qp[1] == 0)
+ {
+ qp[1] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(qx + 1 > __gmpfr_emax))
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+ MPFR_ASSERTD(qx + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(qx + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (q, qx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(q));
+ }
+}
+
+#endif /* !defined(MPFR_GENERIC_ABI) */
/* check if {ap, an} is zero */
static int
mpfr_mpn_cmpzero (mpfr_limb_ptr ap, mp_size_t an)
{
+ MPFR_ASSERTD (an >= 0);
while (an > 0)
if (MPFR_LIKELY(ap[--an] != MPFR_LIMB_ZERO))
return 1;
@@ -66,6 +675,10 @@ mpfr_mpn_cmp_aux (mpfr_limb_ptr ap, mp_size_t an,
mp_size_t k;
mp_limb_t bb;
+ MPFR_ASSERTD (an >= 0);
+ MPFR_ASSERTD (bn >= 0);
+ MPFR_ASSERTD (extra == 0 || extra == 1);
+
if (an >= bn)
{
k = an - bn;
@@ -122,6 +735,8 @@ mpfr_mpn_sub_aux (mpfr_limb_ptr ap, mpfr_limb_ptr bp, mp_size_t n,
mp_limb_t bb, rp;
MPFR_ASSERTD (cy <= 1);
+ MPFR_ASSERTD (n >= 0);
+
while (n--)
{
bb = (extra) ? ((bp[1] << (GMP_NUMB_BITS-1)) | (bp[0] >> 1)) : bp[0];
@@ -136,27 +751,130 @@ mpfr_mpn_sub_aux (mpfr_limb_ptr ap, mpfr_limb_ptr bp, mp_size_t n,
return cy;
}
-int
+/* For large precision, mpz_tdiv_q (which computes only quotient)
+ is faster than mpn_divrem (which computes also the remainder).
+ Unfortunately as of GMP 6.0.0 the corresponding mpn_div_q function
+ is not in the public interface, thus we call mpz_tdiv_q.
+
+ If this function succeeds in computing the correct rounding, return 1,
+ and put the ternary value in inex.
+
+ Otherwise return 0 (and inex is undefined).
+*/
+static int
+mpfr_div_with_mpz_tdiv_q (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v,
+ mpfr_rnd_t rnd_mode, int *inex)
+{
+ mpz_t qm, um, vm;
+ mpfr_exp_t ue, ve;
+ mpfr_prec_t qp = MPFR_PREC(q), wp = qp + GMP_NUMB_BITS;
+ mp_size_t up, vp, k;
+ int ok;
+
+ mpz_init (qm);
+ mpz_init (um);
+ mpz_init (vm);
+
+ ue = mpfr_get_z_2exp (um, u); /* u = um * 2^ue */
+ ve = mpfr_get_z_2exp (vm, v); /* v = vm * 2^ve */
+
+ vp = mpz_sizeinbase (vm, 2);
+ if (vp > wp)
+ {
+ k = vp - wp; /* truncate k bits of vm */
+ mpz_tdiv_q_2exp (vm, vm, k);
+ ve += k;
+ vp -= k;
+ }
+
+ /* we want about qp + GMP_NUMB_BITS bits of the quotient, thus um should
+ have qp + GMP_NUMB_BITS more bits than vm */
+
+ up = mpz_sizeinbase (um, 2);
+ if (up > vp + wp)
+ {
+ k = up - (vp + wp); /* truncate k bits of um */
+ mpz_tdiv_q_2exp (um, um, k);
+ ue += k;
+ up -= k;
+ }
+ else if (up < vp + wp) /* we need more bits */
+ {
+ k = (vp + wp) - up;
+ mpz_mul_2exp (um, um, k);
+ ue -= k;
+ up += k;
+ }
+
+ /* now um has exactly wp more bits than vp */
+ mpz_tdiv_q (qm, um, vm);
+ /* qm has either wp or wp+1 bits, and we have:
+ (a) um = u/2^ue*(1-tu) with tu=0 if no truncation of um,
+ and 0 <= tu < 2^(1-wp) otherwise;
+ (b) vm = v/2^ve*(1-tv) with tv=0 if no truncation of vm,
+ and 0 <= tv < 2^(1-wp) otherwise;
+ (c) um/vm - 1 < qm <= um/vm, thus qm = um/vm*(1-tq) with
+ 0 <= tw < 2^(1-wp) since um/vm >= 2^(wp-1)
+ Altogether we have:
+ q = u/v*2^(ve-ue)*(1-tu)/(1-tv)*(1-tq)
+ Thus:
+ u/v*2^(ve-ue)*(1-2^(2-wp)) < q < u/v*2^(ve-ue)*(1+2^(2-wp)).
+ If q has wp bits, the error is less than 2^(wp-1)*2^(2-wp) <= 2.
+ If q has wp+1 bits, the error is less than 2^wp*2^(2-wp) <= 4.
+ */
+
+ k = mpz_sizeinbase (qm, 2) - wp; /* 0 or 1 */
+ /* Assume qm has wp bits (i.e. k=0) and a directed rounding: if the first
+ set bit after position 1 has position less than GMP_NUMB_BITS, then
+ subtracting 2 to qm will not change the bits beyond the GMP_NUMB_BITS
+ low ones, thus we get correct rounding.
+ For k=1, we need to start at position 2, and the first set bit has to be
+ in posiiton less than GMP_NUMB_BITS+1.
+ For rounding to nearest, the first set bit has to be in position less
+ than GMP_NUMB_BITS-1 for k=0 (or less than GMP_NUMB_BITS for k=1).
+ */
+ if (mpz_scan1 (qm, k + 1) < GMP_NUMB_BITS + k - (rnd_mode == MPFR_RNDN) &&
+ mpz_scan0 (qm, k + 1) < GMP_NUMB_BITS + k - (rnd_mode == MPFR_RNDN))
+ {
+ MPFR_SAVE_EXPO_DECL (expo);
+ ok = 1;
+ MPFR_SAVE_EXPO_MARK (expo);
+ *inex = mpfr_set_z (q, qm, rnd_mode);
+ MPFR_SAVE_EXPO_FREE (expo);
+ /* if we got an underflow or overflow, the result is not valid */
+ if (MPFR_IS_SINGULAR(q) || MPFR_EXP(q) == MPFR_EXT_EMIN ||
+ MPFR_EXP(q) == MPFR_EXT_EMAX)
+ ok = 0;
+ MPFR_EXP(q) += ue - ve;
+ *inex = mpfr_check_range (q, *inex, rnd_mode);
+ }
+ else
+ ok = 0;
+
+ mpz_clear (qm);
+ mpz_clear (um);
+ mpz_clear (vm);
+
+ return ok;
+}
+
+MPFR_HOT_FUNCTION_ATTR int
mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
{
- mp_size_t q0size = MPFR_LIMB_SIZE(q); /* number of limbs of destination */
- mp_size_t usize = MPFR_LIMB_SIZE(u);
- mp_size_t vsize = MPFR_LIMB_SIZE(v);
+ mp_size_t q0size, usize, vsize;
mp_size_t qsize; /* number of limbs wanted for the computed quotient */
mp_size_t qqsize;
mp_size_t k;
- mpfr_limb_ptr q0p = MPFR_MANT(q), qp;
- mpfr_limb_ptr up = MPFR_MANT(u);
- mpfr_limb_ptr vp = MPFR_MANT(v);
+ mpfr_limb_ptr q0p, qp;
+ mpfr_limb_ptr up, vp;
mpfr_limb_ptr ap;
mpfr_limb_ptr bp;
mp_limb_t qh;
- mp_limb_t sticky_u = MPFR_LIMB_ZERO;
+ mp_limb_t sticky_u, sticky_v;
mp_limb_t low_u;
- mp_limb_t sticky_v = MPFR_LIMB_ZERO;
mp_limb_t sticky;
mp_limb_t sticky3;
- mp_limb_t round_bit = MPFR_LIMB_ZERO;
+ mp_limb_t round_bit;
mpfr_exp_t qexp;
int sign_quotient;
int extra_bit;
@@ -215,7 +933,7 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
{
MPFR_ASSERTD (! MPFR_IS_INF (u));
MPFR_SET_INF(q);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET(0);
}
}
@@ -227,12 +945,72 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
}
}
+ /* When MPFR_GENERIC_ABI is defined, we don't use special code. */
+#if !defined(MPFR_GENERIC_ABI)
+ if (MPFR_GET_PREC(u) == MPFR_GET_PREC(q) &&
+ MPFR_GET_PREC(v) == MPFR_GET_PREC(q))
+ {
+ if (MPFR_GET_PREC(q) < GMP_NUMB_BITS)
+ return mpfr_div_1 (q, u, v, rnd_mode);
+
+ if (GMP_NUMB_BITS < MPFR_GET_PREC(q) &&
+ MPFR_GET_PREC(q) < 2 * GMP_NUMB_BITS)
+ return mpfr_div_2 (q, u, v, rnd_mode);
+
+ if (MPFR_GET_PREC(q) == GMP_NUMB_BITS)
+ return mpfr_div_1n (q, u, v, rnd_mode);
+ }
+#endif /* !defined(MPFR_GENERIC_ABI) */
+
+ usize = MPFR_LIMB_SIZE(u);
+ vsize = MPFR_LIMB_SIZE(v);
+ q0size = MPFR_LIMB_SIZE(q); /* number of limbs of destination */
+ q0p = MPFR_MANT(q);
+ up = MPFR_MANT(u);
+ vp = MPFR_MANT(v);
+ sticky_u = MPFR_LIMB_ZERO;
+ sticky_v = MPFR_LIMB_ZERO;
+ round_bit = MPFR_LIMB_ZERO;
+
/**************************************************************************
* *
* End of the part concerning special values. *
* *
**************************************************************************/
+ /* when the divisor has one limb, we can use mpfr_div_ui, which should be
+ faster, assuming there is no intermediate overflow or underflow.
+ The divisor interpreted as an integer satisfies
+ 2^(GMP_NUMB_BITS-1) <= vm < 2^GMP_NUMB_BITS, thus the quotient
+ satisfies 2^(EXP(u)-1-GMP_NUMB_BITS) < u/vm < 2^(EXP(u)-GMP_NUMB_BITS+1)
+ and its exponent is either EXP(u)-GMP_NUMB_BITS or one more. */
+ if (vsize <= 1 && __gmpfr_emin <= MPFR_EXP(u) - GMP_NUMB_BITS
+ && MPFR_EXP(u) - GMP_NUMB_BITS + 1 <= __gmpfr_emax
+ && vp[0] <= ULONG_MAX)
+ {
+ mpfr_exp_t exp_v = MPFR_EXP(v); /* save it in case q=v */
+ if (MPFR_IS_POS (v))
+ inex = mpfr_div_ui (q, u, vp[0], rnd_mode);
+ else
+ {
+ inex = -mpfr_div_ui (q, u, vp[0], MPFR_INVERT_RND(rnd_mode));
+ MPFR_CHANGE_SIGN(q);
+ }
+ /* q did not under/overflow */
+ MPFR_EXP(q) -= exp_v;
+ /* The following test is needed, otherwise the next addition
+ on the exponent may overflow, e.g. when dividing the
+ largest finite MPFR number by the smallest positive one. */
+ if (MPFR_UNLIKELY (MPFR_EXP(q) > __gmpfr_emax - GMP_NUMB_BITS))
+ return mpfr_overflow (q, rnd_mode, MPFR_SIGN(q));
+ MPFR_EXP(q) += GMP_NUMB_BITS;
+ return mpfr_check_range (q, inex, rnd_mode);
+ }
+
+ /* for large precisions, try using truncated division first */
+ if (q0size >= 32 && mpfr_div_with_mpz_tdiv_q (q, u, v, rnd_mode, &inex))
+ return inex;
+
MPFR_TMP_MARK(marker);
/* set sign */
@@ -252,19 +1030,14 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
l = vsize - 1;
while (k != 0 && l != 0 && up[--k] == vp[--l]);
/* now k=0 or l=0 or up[k] != vp[l] */
- if (up[k] > vp[l])
- extra_bit = 1;
- else if (up[k] < vp[l])
- extra_bit = 0;
+ if (up[k] != vp[l])
+ extra_bit = (up[k] > vp[l]);
/* now up[k] = vp[l], thus either k=0 or l=0 */
else if (l == 0) /* no more divisor limb */
extra_bit = 1;
else /* k=0: no more dividend limb */
extra_bit = mpfr_mpn_cmpzero (vp, l) == 0;
}
-#ifdef DEBUG
- printf ("extra_bit=%d\n", extra_bit);
-#endif
/* set exponent */
qexp = MPFR_GET_EXP (u) - MPFR_GET_EXP (v) + extra_bit;
@@ -338,6 +1111,9 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
round_bit = (qp[1] >> (sh - 1)) & 1;
else
round_bit = qp[0] >> (GMP_NUMB_BITS - 1);
+ /* TODO: add value coverage tests in tdiv to check that
+ we reach this part with different values of qh and
+ round_bit (4 cases). */
if (round_bit == 0)
{
inex = -1;
@@ -346,10 +1122,9 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
else /* round_bit = 1 */
goto add_one_ulp;
}
- else if (like_rndz == 0) /* round away */
+ else if (! like_rndz) /* round away */
goto add_one_ulp;
- /* else round to zero: nothing to do */
- else
+ else /* round to zero: nothing to do */
{
inex = -1;
goto truncate;
@@ -433,10 +1208,6 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
/* if Mulders' short division failed, we revert to division with remainder */
qh = mpn_divrem (qp, 0, ap + k, qqsize - k, bp, qsize - k);
/* warning: qh may be 1 if u1 == v1, but u < v */
-#ifdef DEBUG2
- printf ("q="); mpfr_mpn_print (qp, qsize);
- printf ("r="); mpfr_mpn_print (ap, qsize);
-#endif
k = qsize;
sticky_u = sticky_u || mpfr_mpn_cmpzero (ap, k);
@@ -464,20 +1235,12 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
including the round bit, and 1 <= sh2 <= GMP_NUMB_BITS
is the number of bits in sticky3 */
inex = (sticky != MPFR_LIMB_ZERO) || (sticky3 != MPFR_LIMB_ZERO);
-#ifdef DEBUG
- printf ("sticky=%lu sticky3=%lu inex=%d\n",
- (unsigned long) sticky, (unsigned long) sticky3, inex);
-#endif
/* to round, we distinguish two cases:
(a) vsize <= qsize: we used the full divisor
(b) vsize > qsize: the divisor was truncated
*/
-#ifdef DEBUG
- printf ("vsize=%lu qsize=%lu\n",
- (unsigned long) vsize, (unsigned long) qsize);
-#endif
if (MPFR_LIKELY(vsize <= qsize)) /* use the full divisor */
{
if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
@@ -510,10 +1273,6 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
{
round_bit = sticky3 & (MPFR_LIMB_ONE << (sh2 - 1));
sticky3 = sticky3 ^ round_bit;
-#ifdef DEBUG
- printf ("rb=%lu sb=%lu\n",
- (unsigned long) round_bit, (unsigned long) sticky3);
-#endif
}
if (sticky3 != MPFR_LIMB_ZERO && sticky3 != MPFR_LIMB_ONE)
{
@@ -540,7 +1299,7 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
if (qh)
qh2 = mpn_add_n (sp + qsize, sp + qsize, vp, k);
else
- qh2 = (mp_limb_t) 0;
+ qh2 = MPFR_LIMB_ZERO;
qp[0] ^= sticky3orig; /* restore truncated quotient */
/* compare qh2 + {sp, k + qsize} to {ap, qsize} + low(u) */
@@ -551,9 +1310,6 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
mpfr_mpn_cmp_aux (sp, k, up, usize - qqsize, extra_bit) :
mpfr_mpn_cmpzero (sp, k);
}
-#ifdef DEBUG
- printf ("cmp(q*v0,r+u0)=%d\n", cmp_s_r);
-#endif
/* now cmp_s_r > 0 if {sp, vsize} > {ap, qsize} + low(u)
cmp_s_r = 0 if {sp, vsize} = {ap, qsize} + low(u)
cmp_s_r < 0 if {sp, vsize} < {ap, qsize} + low(u) */
@@ -611,9 +1367,6 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
cmp_s_r = 1; /* since in fact we subtracted
less than 1 */
}
-#ifdef DEBUG
- printf ("cmp(q*v0-(r+u0),v)=%d\n", cmp_s_r);
-#endif
if (cmp_s_r <= 0) /* q1-1 <= u/v < q1 */
{
if (sticky3 == MPFR_LIMB_ONE)
diff --git a/Build/source/libs/mpfr/mpfr-src/src/div_2si.c b/Build/source/libs/mpfr/mpfr-src/src/div_2si.c
index e4b5d53a0a3..1552383642e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/div_2si.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/div_2si.c
@@ -22,7 +22,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_div_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd_mode)
{
int inexact;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/div_d.c b/Build/source/libs/mpfr/mpfr-src/src/div_d.c
index 81aae1f1dd5..05178cdb970 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/div_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/div_d.c
@@ -28,6 +28,7 @@ mpfr_div_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t d;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_LOG_FUNC (
@@ -37,15 +38,14 @@ mpfr_div_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, d, IEEE_DBL_MANT_DIG);
inexact = mpfr_set_d (d, c, rnd_mode);
- MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTD (inexact == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_div (a, b, d, rnd_mode);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear(d);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (a, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/div_ui.c b/Build/source/libs/mpfr/mpfr-src/src/div_ui.c
index e826a807a32..633c8c04f90 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/div_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/div_ui.c
@@ -1,4 +1,4 @@
-/* mpfr_div_{ui,si} -- divide a floating-point number by a machine integer
+/* mpfr_div_ui -- divide a floating-point number by a machine integer
Copyright 1999-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -24,7 +24,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
/* returns 0 if result exact, non-zero otherwise */
-int
+#undef mpfr_div_ui
+MPFR_HOT_FUNCTION_ATTR int
mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
{
long i;
@@ -32,7 +33,11 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
mp_size_t xn, yn, dif;
mp_limb_t *xp, *yp, *tmp, c, d;
mpfr_exp_t exp;
- int inexact, middle = 1, nexttoinf;
+ int inexact, nexttoinf;
+ int middle = 1; /* middle = 0 if the next bit after {yp, yn} is 1 and others are
+ zero, middle = -1 if the next bit after {yp, yn} is 0, and
+ middle = 1 if the next bit after {yp, yn} is 1, and next bits
+ are not all zero */
MPFR_TMP_DECL(marker);
MPFR_LOG_FUNC
@@ -77,7 +82,7 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
/* x/0 is Inf since x != 0*/
MPFR_SET_INF (y);
MPFR_SET_SAME_SIGN (y, x);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0);
}
else /* y = x/1 = x */
@@ -102,12 +107,14 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
/* don't use tmp=yp since the mpn_lshift call below requires yp >= tmp+1 */
tmp = MPFR_TMP_LIMBS_ALLOC (yn + 1);
- c = (mp_limb_t) u;
- MPFR_ASSERTN (u == c);
+ MPFR_STAT_STATIC_ASSERT (MPFR_LIMB_MAX >= ULONG_MAX);
if (dif >= 0)
- c = mpn_divrem_1 (tmp, dif, xp, xn, c); /* used all the dividend */
+ c = mpn_divrem_1 (tmp, dif, xp, xn, u); /* used all the dividend */
else /* dif < 0 i.e. xn > yn, don't use the (-dif) low limbs from x */
- c = mpn_divrem_1 (tmp, 0, xp - dif, yn + 1, c);
+ c = mpn_divrem_1 (tmp, 0, xp - dif, yn + 1, u);
+
+ /* the quotient x/u is formed by {tmp, yn+1}
+ + (c + {xp, dif}/B^dif) / u, where B = 2^GMP_NUMB_BITS */
inexact = (c != 0);
@@ -130,7 +137,7 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
/* If we believe that we are right in the middle or exact, we should check
that we did not neglect any word of x (division large / 1 -> small). */
- for (i=0; ((inexact == 0) || (middle == 0)) && (i < -dif); i++)
+ for (i = 0; (inexact == 0 || middle == 0) && i < -dif; i++)
if (xp[i])
inexact = middle = 1; /* larger than middle */
@@ -159,11 +166,12 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
mp_limb_t w = tmp[0] << shlz;
mpn_lshift (yp, tmp + 1, yn, shlz);
- yp[0] += tmp[0] >> (GMP_NUMB_BITS - shlz);
+ yp[0] |= tmp[0] >> (GMP_NUMB_BITS - shlz);
+ /* now {yp, yn} is the approximate quotient, w is the next limb */
- if (w > (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1)))
+ if (w > MPFR_LIMB_HIGHBIT)
{ middle = 1; }
- else if (w < (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1)))
+ else if (w < MPFR_LIMB_HIGHBIT)
{ middle = -1; }
else
{ middle = (c != 0); }
@@ -173,10 +181,9 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
}
else
{ /* this happens only if u == 1 and xp[xn-1] >=
- 1<<(GMP_NUMB_BITS-1). It might be better to handle the
- u == 1 case separately?
+ MPFR_LIMB_ONE << (GMP_NUMB_BITS-1). It might be better to
+ handle the u == 1 case separately?
*/
-
MPN_COPY (yp, tmp + 1, yn);
}
}
@@ -184,12 +191,12 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (y));
/* it remains sh bits in less significant limb of y */
- d = *yp & MPFR_LIMB_MASK (sh);
- *yp ^= d; /* set to zero lowest sh bits */
+ d = yp[0] & MPFR_LIMB_MASK (sh);
+ yp[0] ^= d; /* set to zero lowest sh bits */
MPFR_TMP_FREE (marker);
- if (exp < __gmpfr_emin - 1)
+ if (MPFR_UNLIKELY (exp < __gmpfr_emin - 1))
return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
MPFR_SIGN (y));
@@ -201,6 +208,7 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
switch (rnd_mode)
{
case MPFR_RNDZ:
+ case MPFR_RNDF:
inexact = - MPFR_INT_SIGN (y); /* result is inexact */
nexttoinf = 0;
break;
@@ -229,10 +237,13 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
indicate even rounding, but the result is inexact, so up) ;
The second case is the case where middle should be used to
decide the direction of rounding (no further bit computed) ;
- The third is the true even rounding.
+ The third is the true even rounding:
+ (a) either sh > 0 and inexact = 0
+ (a) or sh = 0 and middle = 0
*/
if ((sh && inexact) || (!sh && middle > 0) ||
- (!inexact && *yp & (MPFR_LIMB_ONE << sh)))
+ (((sh && !inexact) || (!sh && middle == 0))
+ && (yp[0] & (MPFR_LIMB_ONE << sh))))
{
inexact = MPFR_INT_SIGN (y);
nexttoinf = 1;
@@ -258,25 +269,3 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
return mpfr_check_range (y, inexact, rnd_mode);
}
-
-int
-mpfr_div_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
-{
- int res;
-
- MPFR_LOG_FUNC
- (("x[%Pu]=%.*Rg u=%ld rnd=%d",
- mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
- ("y[%Pu]=%.*Rg inexact=%d",
- mpfr_get_prec(y), mpfr_log_prec, y, res));
-
- if (u >= 0)
- res = mpfr_div_ui (y, x, u, rnd_mode);
- else
- {
- res = - mpfr_div_ui (y, x, - (unsigned long) u,
- MPFR_INVERT_RND (rnd_mode));
- MPFR_CHANGE_SIGN (y);
- }
- return res;
-}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/dump.c b/Build/source/libs/mpfr/mpfr-src/src/dump.c
index b427f80bfcd..d88dca2b520 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/dump.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/dump.c
@@ -1,6 +1,6 @@
-/* mpfr_dump -- Dump a float to stdout.
+/* mpfr_dump, mpfr_fdump -- dump a float (for the tests and debugging purpose)
-Copyright 1999, 2001, 2004, 2006-2017 Free Software Foundation, Inc.
+Copyright 1999-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
This file is part of the GNU MPFR Library.
@@ -22,9 +22,111 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
+/* mpfr_dump is mainly for debugging purpose. It outputs a MPFR number
+ * in some unspecified format, then a newline character. This function
+ * is part of the API, but the output format may change without breaking
+ * the ABI.
+ *
+ * Since this is for debugging, it can detect invalid data (or UBF), and
+ * in such a case, it outputs information between exclamation marks:
+ * - 'N': the number is not normalized (MSB = 0);
+ * - 'T': there are non-zero trailing bits (output in square brackets);
+ * - 'U': this is a UBF number (internal use only);
+ * - '<': the exponent is < the current emin;
+ * - '>': the exponent is > the current emax.
+ *
+ * The format may depend on MPFR_* environment variables. For instance,
+ * in the future, some environment variables could specify prefix and
+ * suffix strings to colorize parts of the output that correspond to
+ * invalid data.
+ */
+
+void
+mpfr_fdump (FILE *stream, mpfr_srcptr x)
+{
+ if (MPFR_IS_NEG (x))
+ fprintf (stream, "-");
+
+ if (MPFR_IS_NAN (x))
+ fprintf (stream, "@NaN@");
+ else if (MPFR_IS_INF (x))
+ fprintf (stream, "@Inf@");
+ else if (MPFR_IS_ZERO (x))
+ fprintf (stream, "0");
+ else
+ {
+ mp_limb_t *mx;
+ mpfr_prec_t px;
+ mp_size_t n;
+ char invalid[4];
+ int first = 1, i = 0;
+
+ mx = MPFR_MANT (x);
+ px = MPFR_PREC (x);
+
+ fprintf (stream, "0.");
+ for (n = (px - 1) / GMP_NUMB_BITS; n >= 0; n--)
+ {
+ mp_limb_t wd, t;
+
+ wd = mx[n];
+ if (first)
+ {
+ if (! MPFR_LIMB_MSB (wd))
+ invalid[i++] = 'N';
+ first = 0;
+ }
+ for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
+ {
+ putc ((wd & t) == 0 ? '0' : '1', stream);
+ if (--px == 0)
+ {
+ MPFR_ASSERTD (n == 0);
+ if (t != 0 && (wd & (t - 1)) != 0)
+ {
+ putc ('[', stream);
+ invalid[i++] = 'T';
+ }
+ else
+ break; /* the trailing bits (all 0's) are not output */
+ }
+ }
+ }
+ if (px < 0) /* there are non-zero trailing bits */
+ putc (']', stream);
+
+ if (MPFR_IS_UBF (x))
+ {
+#ifndef MPFR_USE_MINI_GMP
+ gmp_fprintf (stream, "E%Zd", MPFR_ZEXP (x));
+#else /* mini-gmp has no gmp_fprintf */
+ fprintf (stream, "E");
+ mpz_out_str (stream, 10, MPFR_ZEXP (x));
+#endif
+ invalid[i++] = 'U';
+ }
+ else
+ {
+ mpfr_exp_t e = MPFR_EXP (x);
+
+ fprintf (stream, "E%" MPFR_EXP_FSPEC "d", (mpfr_eexp_t) e);
+ if (e < __gmpfr_emin)
+ invalid[i++] = '<';
+ else if (e > __gmpfr_emax)
+ invalid[i++] = '>';
+ }
+
+ if (i != 0)
+ {
+ invalid[i] = '\0';
+ fprintf (stream, "!!!%s!!!", invalid);
+ }
+ }
+ putc ('\n', stream);
+}
+
void
-mpfr_dump (mpfr_srcptr u)
+mpfr_dump (mpfr_srcptr x)
{
- mpfr_print_binary(u);
- putchar('\n');
+ mpfr_fdump (stdout, x);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/eint.c b/Build/source/libs/mpfr/mpfr-src/src/eint.c
index c09efe94143..cd9588e5064 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/eint.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/eint.c
@@ -30,8 +30,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
eint (x) is undefined for x < 0.
*/
-/* compute in y an approximation of sum(x^k/k/k!, k=1..infinity),
- and return e such that the absolute error is bound by 2^e ulp(y) */
+/* Compute in y an approximation of sum(x^k/k/k!, k=1..infinity),
+ and return e such that the absolute error is bound by 2^e ulp(y).
+ Return PREC(y) when the truncated series does not converge.
+*/
static mpfr_exp_t
mpfr_eint_aux (mpfr_t y, mpfr_srcptr x)
{
@@ -44,7 +46,7 @@ mpfr_eint_aux (mpfr_t y, mpfr_srcptr x)
MPFR_GROUP_DECL (group);
/* for |x| <= 1, we have S := sum(x^k/k/k!, k=1..infinity) = x + R(x)
- where |R(x)| <= (x/2)^2/(1-x/2) <= 2*(x/2)^2
+ where |R(x)| <= (x/2)^2/(1-|x|/2) <= 2*(x/2)^2
thus |R(x)/x| <= |x|/2
thus if |x| <= 2^(-PREC(y)) we have |S - o(x)| <= ulp(y) */
@@ -75,16 +77,19 @@ mpfr_eint_aux (mpfr_t y, mpfr_srcptr x)
mpz_set_ui (t, 1);
mpz_mul_2exp (t, t, w);
mpfr_set_ui (eps, 0, MPFR_RNDN); /* eps[0] = 0 */
- mpfr_set_ui (errs, 0, MPFR_RNDN);
+ mpfr_set_ui (errs, 0, MPFR_RNDN); /* maximal error on s */
for (k = 1;; k++)
{
- /* let eps[k] be the absolute error on t[k]:
+ /* let t[k] = x^k/k/k!, and eps[k] be the absolute error on t[k]:
since t[k] = trunc(t[k-1]*m*2^e/k), we have
- eps[k+1] <= 1 + eps[k-1]*m*2^e/k + t[k-1]*m*2^(1-w)*2^e/k
- = 1 + (eps[k-1] + t[k-1]*2^(1-w))*m*2^e/k
- = 1 + (eps[k-1]*2^(w-1) + t[k-1])*2^(1-w)*m*2^e/k */
+ eps[k+1] <= 1 + eps[k-1]*|m|*2^e/k + |t[k-1]|*|m|*2^(1-w)*2^e/k
+ = 1 + (eps[k-1] + |t[k-1]|*2^(1-w))*|m|*2^e/k
+ = 1 + (eps[k-1]*2^(w-1) + |t[k-1]|)*2^(1-w)*|m|*2^e/k */
mpfr_mul_2ui (eps, eps, w - 1, MPFR_RNDU);
- mpfr_add_z (eps, eps, t, MPFR_RNDU);
+ if (mpz_sgn (t) >= 0)
+ mpfr_add_z (eps, eps, t, MPFR_RNDU);
+ else
+ mpfr_sub_z (eps, eps, t, MPFR_RNDU);
MPFR_MPZ_SIZEINBASE2 (sizeinbase, m);
mpfr_mul_2si (eps, eps, sizeinbase - (w - 1) + e, MPFR_RNDU);
mpfr_div_ui (eps, eps, k, MPFR_RNDU);
@@ -145,7 +150,7 @@ mpfr_eint_aux (mpfr_t y, mpfr_srcptr x)
/* Return in y an approximation of Ei(x) using the asymptotic expansion:
Ei(x) = exp(x)/x * (1 + 1/x + 2/x^2 + ... + k!/x^k + ...)
- Assumes x >= PREC(y) * log(2).
+ Assumes |x| >= PREC(y) * log(2).
Returns the error bound in terms of ulp(y).
*/
static mpfr_exp_t
@@ -190,11 +195,13 @@ mpfr_eint_asympt (mpfr_ptr y, mpfr_srcptr x)
return err_exp;
}
+/* mpfr_eint returns Ei(x) for x >= 0,
+ and -E1(-x) for x < 0, following http://dlmf.nist.gov/6.2 */
int
mpfr_eint (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
int inex;
- mpfr_t tmp, ump;
+ mpfr_t tmp, ump, x_abs;
mpfr_exp_t err, te;
mpfr_prec_t prec;
MPFR_SAVE_EXPO_DECL (expo);
@@ -206,80 +213,104 @@ mpfr_eint (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
{
- /* eint(NaN) = eint(-Inf) = NaN */
- if (MPFR_IS_NAN (x) || (MPFR_IS_INF (x) && MPFR_IS_NEG(x)))
+ if (MPFR_IS_NAN (x))
{
MPFR_SET_NAN (y);
MPFR_RET_NAN;
}
- /* eint(+inf) = +inf */
else if (MPFR_IS_INF (x))
{
- MPFR_SET_INF(y);
- MPFR_SET_POS(y);
+ /* eint(+inf) = +inf and eint(-inf) = -0 */
+ if (MPFR_IS_POS (x))
+ {
+ MPFR_SET_INF(y);
+ MPFR_SET_POS(y);
+ }
+ else
+ {
+ MPFR_SET_ZERO(y);
+ MPFR_SET_NEG(y);
+ }
MPFR_RET(0);
}
else /* eint(+/-0) = -Inf */
{
MPFR_SET_INF(y);
MPFR_SET_NEG(y);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET(0);
}
}
- /* eint(x) = NaN for x < 0 */
- if (MPFR_IS_NEG(x))
- {
- MPFR_SET_NAN (y);
- MPFR_RET_NAN;
- }
+ MPFR_TMP_INIT_ABS (x_abs, x);
MPFR_SAVE_EXPO_MARK (expo);
+ /* Init stuff */
+ prec = MPFR_PREC (y) + 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 6;
+ mpfr_init2 (tmp, 64);
+ mpfr_init2 (ump, 64);
+
/* Since eint(x) >= exp(x)/x, we have log2(eint(x)) >= (x-log(x))/log(2).
Let's compute k <= (x-log(x))/log(2) in a low precision. If k >= emax,
then log2(eint(x)) >= emax, and eint(x) >= 2^emax, i.e. it overflows. */
- mpfr_init2 (tmp, 64);
- mpfr_init2 (ump, 64);
- mpfr_log (tmp, x, MPFR_RNDU);
- mpfr_sub (ump, x, tmp, MPFR_RNDD);
- mpfr_const_log2 (tmp, MPFR_RNDU);
- mpfr_div (ump, ump, tmp, MPFR_RNDD);
- /* FIXME: We really need mpfr_set_exp_t and mpfr_cmpfr_exp_t functions. */
- MPFR_ASSERTN (MPFR_EMAX_MAX <= LONG_MAX);
- if (mpfr_cmp_ui (ump, __gmpfr_emax) >= 0)
+ if (MPFR_IS_POS(x))
{
- mpfr_clear (tmp);
- mpfr_clear (ump);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_overflow (y, rnd, 1);
+ mpfr_log (tmp, x, MPFR_RNDU);
+ mpfr_sub (ump, x, tmp, MPFR_RNDD);
+ mpfr_div (ump, ump, __gmpfr_const_log2_RNDU, MPFR_RNDD);
+ /* FIXME: We really need a mpfr_cmp_exp_t function. */
+ MPFR_ASSERTN (MPFR_EMAX_MAX <= LONG_MAX);
+ if (mpfr_cmp_ui (ump, __gmpfr_emax) >= 0)
+ {
+ mpfr_clear (tmp);
+ mpfr_clear (ump);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_overflow (y, rnd, 1);
+ }
}
- /* Init stuff */
- prec = MPFR_PREC (y) + 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 6;
+ /* Since E1(x) <= exp(-x) for x >= 1, we have log2(E1(x)) <= -x/log(2).
+ Let's compute k >= -x/log(2) in a low precision. If k < emin
+ then log2(E1(x)) <= emin-1, and E1(x) <= 2^(emin-1): it underflows. */
+ if (MPFR_IS_NEG(x) && MPFR_GET_EXP(x) >= 1)
+ {
+ mpfr_div (ump, x, __gmpfr_const_log2_RNDD, MPFR_RNDU);
+ MPFR_ASSERTN (MPFR_EMIN_MIN >= LONG_MIN);
+ if (mpfr_cmp_si (ump, __gmpfr_emin) < 0)
+ {
+ mpfr_clear (tmp);
+ mpfr_clear (ump);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (y, rnd, -1);
+ }
+ }
- /* eint() has a root 0.37250741078136663446..., so if x is near,
- already take more bits */
- /* FIXME: do not use native floating-point here. */
- if (MPFR_GET_EXP(x) == -1) /* 1/4 <= x < 1/2 */
+ /* eint() has a root 0.37250741078136663446...,
+ so if x is near, already take more bits */
+ if (MPFR_IS_POS(x) && MPFR_GET_EXP(x) == -1) /* 1/4 <= x < 1/2 */
{
- double d;
- d = mpfr_get_d (x, MPFR_RNDN) - 0.37250741078136663;
- d = (d == 0.0) ? -53 : __gmpfr_ceil_log2 (d);
- prec += -d;
+ mpfr_t y;
+ mpfr_init2 (y, 32);
+ /* 1599907147/2^32 is a 32-bit approximation of 0.37250741078136663446 */
+ mpfr_set_ui_2exp (y, 1599907147UL, -32, MPFR_RNDN);
+ mpfr_sub (y, x, y, MPFR_RNDN);
+ prec += (mpfr_zero_p (y)) ? 32
+ : mpfr_get_exp (y) < 0 ? -mpfr_get_exp (y) : 0;
+ mpfr_clear (y);
}
mpfr_set_prec (tmp, prec);
mpfr_set_prec (ump, prec);
- MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controler */
- for (;;) /* Infinite loop */
+ MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controller */
+ for (;;) /* Infinite loop */
{
- /* We need that the smallest value of k!/x^k is smaller than 2^(-p).
- The minimum is obtained for x=k, and it is smaller than e*sqrt(x)/e^x
- for x>=1. */
- if (MPFR_GET_EXP (x) > 0 && mpfr_cmp_d (x, ((double) prec +
+ /* For the asymptotic expansion to work, we need that the smallest
+ value of k!/|x|^k is smaller than 2^(-p). The minimum is obtained for
+ x=k, and it is smaller than e*sqrt(x)/e^x for x>=1. */
+ if (MPFR_GET_EXP (x) > 0 &&
+ mpfr_cmp_d (x_abs, ((double) prec +
0.5 * (double) MPFR_GET_EXP (x)) * LOG2 + 1.0) > 0)
err = mpfr_eint_asympt (tmp, x);
else
@@ -288,20 +319,27 @@ mpfr_eint (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
te = MPFR_GET_EXP(tmp);
mpfr_const_euler (ump, MPFR_RNDN); /* 0.577 -> EXP(ump)=0 */
mpfr_add (tmp, tmp, ump, MPFR_RNDN);
- /* error <= 1/2 + 1/2*2^(EXP(ump)-EXP(tmp)) + 2^(te-EXP(tmp)+err)
+ /* If tmp <> 0:
+ error <= 1/2 + 1/2*2^(EXP(ump)-EXP(tmp)) + 2^(te-EXP(tmp)+err)
<= 1/2 + 2^(MAX(EXP(ump), te+err+1) - EXP(tmp))
- <= 2^(MAX(0, 1 + MAX(EXP(ump), te+err+1) - EXP(tmp))) */
- err = MAX(1, te + err + 2) - MPFR_GET_EXP(tmp);
+ <= 2^(MAX(0, 1 + MAX(EXP(ump), te+err+1) - EXP(tmp))).
+ If tmp = 0 we can use the same bound, replacing
+ EXP(tmp) by EXP(ump). */
+ err = MAX(1, te + err + 2);
+ te = MPFR_IS_ZERO(tmp) ? MPFR_GET_EXP(ump) : MPFR_GET_EXP(tmp);
+ err = err - te;
err = MAX(0, err);
- te = MPFR_GET_EXP(tmp);
- mpfr_log (ump, x, MPFR_RNDN);
+ mpfr_log (ump, x_abs, MPFR_RNDN);
mpfr_add (tmp, tmp, ump, MPFR_RNDN);
/* same formula as above, except now EXP(ump) is not 0 */
err += te + 1;
if (MPFR_LIKELY (!MPFR_IS_ZERO (ump)))
err = MAX (MPFR_GET_EXP (ump), err);
- err = MAX(0, err - MPFR_GET_EXP (tmp));
+ /* if tmp is zero, we surely cannot round correctly */
+ err = (MPFR_IS_ZERO(tmp)) ? prec : MAX(0, err - MPFR_GET_EXP (tmp));
}
+ /* Note: we assume here that MPFR_CAN_ROUND returns the same result
+ for rnd and MPFR_INVERT_RND(rnd) */
if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - err, MPFR_PREC (y), rnd)))
break;
MPFR_ZIV_NEXT (loop, prec); /* Increase used precision */
@@ -310,7 +348,8 @@ mpfr_eint (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
}
MPFR_ZIV_FREE (loop); /* Free the ZivLoop Controller */
- inex = mpfr_set (y, tmp, rnd); /* Set y to the computed value */
+ /* Set y to the computed value */
+ inex = mpfr_set (y, tmp, rnd);
mpfr_clear (tmp);
mpfr_clear (ump);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/erandom.c b/Build/source/libs/mpfr/mpfr-src/src/erandom.c
new file mode 100644
index 00000000000..b423bf4ec07
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/erandom.c
@@ -0,0 +1,105 @@
+/* mpfr_erandom (rop, state, rnd_mode) -- Generate an exponential deviate with
+ mean 1 and round it to the precision of rop according to the given rounding
+ mode.
+
+Copyright 2013-2017 Free Software Foundation, Inc.
+Contributed by Charles Karney <charles@karney.com>, SRI International.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/*
+ * Sampling from the exponential distribution with unit mean using the method
+ * given in John von Neumann, Various techniques used in connection with random
+ * digits, in A. S. Householder, G. E. Forsythe, and H. H. Germond, editors,
+ * "Monte Carlo Method", number 12 in Applied Mathematics Series, pp. 36-38
+ * (NBS, Washington, DC, 1951), Proceedings of a symposium held June 29-July 1,
+ * 1949, in Los Angeles.
+ *
+ * A modification to this algorithm is given in:
+ * Charles F. F. Karney,
+ * "Sampling exactly from the normal distribution",
+ * ACM Trans. Math. Software 42(1), 3:1-14 (Jan. 2016).
+ * https://dx.doi.org/10.1145/2710016
+ * http://arxiv.org/abs/1303.6257
+ * Although this improves the bit efficiency, in practice, it results in
+ * a slightly slower algorithm for MPFR. So here the original von Neumann
+ * algorithm is used.
+ *
+ * There are a few "weasel words" regarding the accuracy of this
+ * implementation. The algorithm produces exactly rounded exponential deviates
+ * provided that gmp's random number engine delivers truly random bits. If it
+ * did, the algorithm would be perfect; however, this implementation would have
+ * problems, e.g., in that the integer part of the exponential deviate is
+ * represented by an unsigned long, whereas in reality the integer part in
+ * unbounded. In this implementation, asserts catch overflow in the integer
+ * part and similar (very, very) unlikely events. In reality, of course, gmp's
+ * random number engine has a finite internal state (19937 bits in the case of
+ * the MT19937 method). This means that these unlikely events in fact won't
+ * occur. If the asserts are triggered, then this is an indication that the
+ * random number engine is defective. (Even if a hardware random number
+ * generator were used, the most likely explanation for the triggering of the
+ * asserts would be that the hardware generator was broken.)
+ */
+
+#include "random_deviate.h"
+
+/* true with prob exp(-x) */
+static int
+E (mpfr_random_deviate_t x, gmp_randstate_t r,
+ mpfr_random_deviate_t p, mpfr_random_deviate_t q)
+{
+ /* p and q are temporaries */
+ mpfr_random_deviate_reset (p);
+ if (!mpfr_random_deviate_less (p, x, r))
+ return 1;
+ for (;;)
+ {
+ mpfr_random_deviate_reset (q);
+ if (!mpfr_random_deviate_less (q, p, r))
+ return 0;
+ mpfr_random_deviate_reset (p);
+ if (!mpfr_random_deviate_less (p, q, r))
+ return 1;
+ }
+}
+
+/* return an exponential random deviate with mean 1 as a MPFR */
+int
+mpfr_erandom (mpfr_t z, gmp_randstate_t r, mpfr_rnd_t rnd)
+{
+ mpfr_random_deviate_t x, p, q;
+ int inex;
+ unsigned long k = 0;
+
+ mpfr_random_deviate_init (x);
+ mpfr_random_deviate_init (p);
+ mpfr_random_deviate_init (q);
+ while (!E(x, r, p, q))
+ {
+ ++k;
+ /* Catch k wrapping around to 0; for a 32-bit unsigned long, the
+ * probability of this is exp(-2^32)). */
+ MPFR_ASSERTN (k != 0UL);
+ mpfr_random_deviate_reset (x);
+ }
+ mpfr_random_deviate_clear (q);
+ mpfr_random_deviate_clear (p);
+ inex = mpfr_random_deviate_value (0, k, x, z, r, rnd);
+ mpfr_random_deviate_clear (x);
+ return inex;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/erf.c b/Build/source/libs/mpfr/mpfr-src/src/erf.c
index 24538a6d57c..12f3b9f5cac 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/erf.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/erf.c
@@ -23,14 +23,13 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-#define EXP1 2.71828182845904523536 /* exp(1) */
-
static int mpfr_erf_0 (mpfr_ptr, mpfr_srcptr, double, mpfr_rnd_t);
int
mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
mpfr_t xf;
+ mp_limb_t xf_limb[(53 - 1) / GMP_NUMB_BITS + 1];
int inex, large;
MPFR_SAVE_EXPO_DECL (expo);
@@ -110,13 +109,11 @@ mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
the error term x^2/3 is not that small. */
}
- mpfr_init2 (xf, 53);
- mpfr_const_log2 (xf, MPFR_RNDU);
- mpfr_div (xf, x, xf, MPFR_RNDZ); /* round to zero ensures we get a lower
- bound of |x/log(2)| */
+ MPFR_TMP_INIT1(xf_limb, xf, 53);
+ mpfr_div (xf, x, __gmpfr_const_log2_RNDU, MPFR_RNDZ); /* round to zero
+ ensures we get a lower bound of |x/log(2)| */
mpfr_mul (xf, xf, x, MPFR_RNDZ);
large = mpfr_cmp_ui (xf, MPFR_PREC (y) + 1) > 0;
- mpfr_clear (xf);
/* when x goes to infinity, we have erf(x) = 1 - 1/sqrt(Pi)/exp(x^2)/x + ...
and |erf(x) - 1| <= exp(-x^2) is true for any x >= 0, thus if
@@ -157,15 +154,21 @@ mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
static double
mul_2exp (double x, mpfr_exp_t e)
{
- if (e > 0)
+ /* Most of the times, the argument is negative */
+ if (MPFR_UNLIKELY (e > 0))
{
while (e--)
x *= 2.0;
}
else
{
+ while (e <= -16)
+ {
+ x *= (1.0 / 65536.0);
+ e += 16;
+ }
while (e++)
- x /= 2.0;
+ x *= 0.5;
}
return x;
@@ -188,6 +191,7 @@ mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, double xf2, mpfr_rnd_t rnd_mode)
unsigned int k;
int log2tauk;
int inex;
+ MPFR_GROUP_DECL (group);
MPFR_ZIV_DECL (loop);
n = MPFR_PREC (res); /* target precision */
@@ -195,10 +199,7 @@ mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, double xf2, mpfr_rnd_t rnd_mode)
/* initial working precision */
m = n + (mpfr_prec_t) (xf2 / LOG2) + 8 + MPFR_INT_CEIL_LOG2 (n);
- mpfr_init2 (y, m);
- mpfr_init2 (s, m);
- mpfr_init2 (t, m);
- mpfr_init2 (u, m);
+ MPFR_GROUP_INIT_4(group, m, y, s, t, u);
MPFR_ZIV_INIT (loop, m);
for (;;)
@@ -243,20 +244,13 @@ mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, double xf2, mpfr_rnd_t rnd_mode)
/* Actualisation of the precision */
MPFR_ZIV_NEXT (loop, m);
- mpfr_set_prec (y, m);
- mpfr_set_prec (s, m);
- mpfr_set_prec (t, m);
- mpfr_set_prec (u, m);
-
+ MPFR_GROUP_REPREC_4 (group, m, y, s, t, u);
}
MPFR_ZIV_FREE (loop);
inex = mpfr_set (res, s, rnd_mode);
- mpfr_clear (y);
- mpfr_clear (t);
- mpfr_clear (u);
- mpfr_clear (s);
+ MPFR_GROUP_CLEAR (group);
return inex;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/erfc.c b/Build/source/libs/mpfr/mpfr-src/src/erfc.c
index b2a7151ab0a..8424e8927b4 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/erfc.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/erfc.c
@@ -149,7 +149,7 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
return mpfr_set_ui (y, 1, rnd);
}
- if (MPFR_SIGN (x) > 0)
+ if (MPFR_IS_POS (x))
{
/* by default, emin = 1-2^30, thus the smallest representable
number is 1/2*2^emin = 2^(-2^30):
@@ -160,7 +160,7 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
mpfr_cmp_ui (x, 1787897414) >= 0)
{
/* May be incorrect if MPFR_EMAX_MAX >= 2^62. */
- MPFR_ASSERTN ((MPFR_EMAX_MAX >> 31) >> 31 == 0);
+ MPFR_STAT_STATIC_ASSERT ((MPFR_EMAX_MAX >> 31) >> 31 == 0);
return mpfr_underflow (y, (rnd == MPFR_RNDN) ? MPFR_RNDZ : rnd, 1);
}
}
@@ -168,7 +168,7 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
/* Init stuff */
MPFR_SAVE_EXPO_MARK (expo);
- if (MPFR_SIGN (x) < 0)
+ if (MPFR_IS_NEG (x))
{
mpfr_exp_t e = MPFR_EXP(x);
/* For x < 0 going to -infinity, erfc(x) tends to 2 by below.
@@ -185,7 +185,7 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
near_two:
mpfr_set_ui (y, 2, MPFR_RNDN);
- mpfr_set_inexflag ();
+ MPFR_SET_INEXFLAG ();
if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
{
mpfr_nextbelow (y);
@@ -220,7 +220,7 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
/* erfc(x) ~ 1, with error < 2^(EXP(x)+1) */
MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, __gmpfr_one, - MPFR_GET_EXP (x) - 1,
- 0, MPFR_SIGN(x) < 0,
+ 0, MPFR_IS_NEG (x),
rnd, inex = _inexact; goto end);
prec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 3;
@@ -229,12 +229,12 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
mpfr_init2 (tmp, prec);
- MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controler */
+ MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controller */
for (;;) /* Infinite loop */
{
/* use asymptotic formula only whenever x^2 >= p*log(2),
otherwise it will not converge */
- if (MPFR_SIGN (x) > 0 &&
+ if (MPFR_IS_POS (x) &&
2 * MPFR_GET_EXP (x) - 2 >= MPFR_INT_CEIL_LOG2 (prec))
/* we have x^2 >= p in that case */
{
diff --git a/Build/source/libs/mpfr/mpfr-src/src/exceptions.c b/Build/source/libs/mpfr/mpfr-src/src/exceptions.c
index e250be0a537..b457bbdf2eb 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/exceptions.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/exceptions.c
@@ -1,4 +1,4 @@
-/* Exception flags and utilities.
+/* Exception flags and utilities. Constructors and destructors (debug).
Copyright 2001-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -22,13 +22,13 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-MPFR_THREAD_VAR (unsigned int, __gmpfr_flags, 0)
+MPFR_THREAD_VAR (mpfr_flags_t, __gmpfr_flags, 0)
MPFR_THREAD_VAR (mpfr_exp_t, __gmpfr_emin, MPFR_EMIN_DEFAULT)
MPFR_THREAD_VAR (mpfr_exp_t, __gmpfr_emax, MPFR_EMAX_DEFAULT)
#undef mpfr_get_emin
-mpfr_exp_t
+MPFR_COLD_FUNCTION_ATTR mpfr_exp_t
mpfr_get_emin (void)
{
return __gmpfr_emin;
@@ -39,7 +39,7 @@ mpfr_get_emin (void)
int
mpfr_set_emin (mpfr_exp_t exponent)
{
- if (exponent >= MPFR_EMIN_MIN && exponent <= MPFR_EMIN_MAX)
+ if (MPFR_LIKELY (exponent >= MPFR_EMIN_MIN && exponent <= MPFR_EMIN_MAX))
{
__gmpfr_emin = exponent;
return 0;
@@ -50,13 +50,13 @@ mpfr_set_emin (mpfr_exp_t exponent)
}
}
-mpfr_exp_t
+MPFR_COLD_FUNCTION_ATTR mpfr_exp_t
mpfr_get_emin_min (void)
{
return MPFR_EMIN_MIN;
}
-mpfr_exp_t
+MPFR_COLD_FUNCTION_ATTR mpfr_exp_t
mpfr_get_emin_max (void)
{
return MPFR_EMIN_MAX;
@@ -64,7 +64,7 @@ mpfr_get_emin_max (void)
#undef mpfr_get_emax
-mpfr_exp_t
+MPFR_COLD_FUNCTION_ATTR mpfr_exp_t
mpfr_get_emax (void)
{
return __gmpfr_emax;
@@ -75,7 +75,7 @@ mpfr_get_emax (void)
int
mpfr_set_emax (mpfr_exp_t exponent)
{
- if (exponent >= MPFR_EMAX_MIN && exponent <= MPFR_EMAX_MAX)
+ if (MPFR_LIKELY (exponent >= MPFR_EMAX_MIN && exponent <= MPFR_EMAX_MAX))
{
__gmpfr_emax = exponent;
return 0;
@@ -86,18 +86,62 @@ mpfr_set_emax (mpfr_exp_t exponent)
}
}
-mpfr_exp_t
+MPFR_COLD_FUNCTION_ATTR mpfr_exp_t
mpfr_get_emax_min (void)
{
return MPFR_EMAX_MIN;
}
-mpfr_exp_t
+
+MPFR_COLD_FUNCTION_ATTR mpfr_exp_t
mpfr_get_emax_max (void)
{
return MPFR_EMAX_MAX;
}
+#undef mpfr_flags_clear
+
+MPFR_COLD_FUNCTION_ATTR void
+mpfr_flags_clear (mpfr_flags_t mask)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ mask;
+}
+
+#undef mpfr_flags_set
+
+MPFR_COLD_FUNCTION_ATTR void
+mpfr_flags_set (mpfr_flags_t mask)
+{
+ __gmpfr_flags |= mask;
+}
+
+#undef mpfr_flags_test
+
+MPFR_COLD_FUNCTION_ATTR mpfr_flags_t
+mpfr_flags_test (mpfr_flags_t mask)
+{
+ return __gmpfr_flags & mask;
+}
+
+#undef mpfr_flags_save
+
+MPFR_COLD_FUNCTION_ATTR mpfr_flags_t
+mpfr_flags_save (void)
+{
+ return __gmpfr_flags;
+}
+
+#undef mpfr_flags_restore
+
+MPFR_COLD_FUNCTION_ATTR void
+mpfr_flags_restore (mpfr_flags_t flags, mpfr_flags_t mask)
+{
+ __gmpfr_flags =
+ (__gmpfr_flags & (MPFR_FLAGS_ALL ^ mask)) |
+ (flags & mask);
+}
+
+
#undef mpfr_clear_flags
void
@@ -108,7 +152,7 @@ mpfr_clear_flags (void)
#undef mpfr_clear_underflow
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_clear_underflow (void)
{
__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW;
@@ -116,7 +160,7 @@ mpfr_clear_underflow (void)
#undef mpfr_clear_overflow
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_clear_overflow (void)
{
__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW;
@@ -124,7 +168,7 @@ mpfr_clear_overflow (void)
#undef mpfr_clear_divby0
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_clear_divby0 (void)
{
__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0;
@@ -132,7 +176,7 @@ mpfr_clear_divby0 (void)
#undef mpfr_clear_nanflag
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_clear_nanflag (void)
{
__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN;
@@ -140,7 +184,7 @@ mpfr_clear_nanflag (void)
#undef mpfr_clear_inexflag
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_clear_inexflag (void)
{
__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT;
@@ -148,7 +192,7 @@ mpfr_clear_inexflag (void)
#undef mpfr_clear_erangeflag
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_clear_erangeflag (void)
{
__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
@@ -156,7 +200,7 @@ mpfr_clear_erangeflag (void)
#undef mpfr_set_underflow
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_set_underflow (void)
{
__gmpfr_flags |= MPFR_FLAGS_UNDERFLOW;
@@ -164,7 +208,7 @@ mpfr_set_underflow (void)
#undef mpfr_set_overflow
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_set_overflow (void)
{
__gmpfr_flags |= MPFR_FLAGS_OVERFLOW;
@@ -172,7 +216,7 @@ mpfr_set_overflow (void)
#undef mpfr_set_divby0
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_set_divby0 (void)
{
__gmpfr_flags |= MPFR_FLAGS_DIVBY0;
@@ -180,7 +224,7 @@ mpfr_set_divby0 (void)
#undef mpfr_set_nanflag
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_set_nanflag (void)
{
__gmpfr_flags |= MPFR_FLAGS_NAN;
@@ -188,7 +232,7 @@ mpfr_set_nanflag (void)
#undef mpfr_set_inexflag
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_set_inexflag (void)
{
__gmpfr_flags |= MPFR_FLAGS_INEXACT;
@@ -196,7 +240,7 @@ mpfr_set_inexflag (void)
#undef mpfr_set_erangeflag
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_set_erangeflag (void)
{
__gmpfr_flags |= MPFR_FLAGS_ERANGE;
@@ -205,13 +249,18 @@ mpfr_set_erangeflag (void)
#undef mpfr_check_range
+/* Note: It is possible that for pure FP numbers, EXP(x) < MPFR_EMIN_MIN,
+ but the caller must make sure that the difference remains small enough
+ to avoid reaching the special exponent values. */
int
mpfr_check_range (mpfr_ptr x, int t, mpfr_rnd_t rnd_mode)
{
- if (MPFR_LIKELY( MPFR_IS_PURE_FP(x)) )
+ if (MPFR_LIKELY (! MPFR_IS_SINGULAR (x)))
{ /* x is a non-zero FP */
mpfr_exp_t exp = MPFR_EXP (x); /* Do not use MPFR_GET_EXP */
- if (MPFR_UNLIKELY( exp < __gmpfr_emin) )
+
+ MPFR_ASSERTD (MPFR_IS_NORMALIZED (x));
+ if (MPFR_UNLIKELY (exp < __gmpfr_emin))
{
/* The following test is necessary because in the rounding to the
* nearest mode, mpfr_underflow always rounds away from 0. In
@@ -225,9 +274,9 @@ mpfr_check_range (mpfr_ptr x, int t, mpfr_rnd_t rnd_mode)
(mpfr_powerof2_raw(x) &&
(MPFR_IS_NEG(x) ? t <= 0 : t >= 0))))
rnd_mode = MPFR_RNDZ;
- return mpfr_underflow(x, rnd_mode, MPFR_SIGN(x));
+ return mpfr_underflow (x, rnd_mode, MPFR_SIGN(x));
}
- if (MPFR_UNLIKELY( exp > __gmpfr_emax) )
+ if (MPFR_UNLIKELY (exp > __gmpfr_emax))
return mpfr_overflow (x, rnd_mode, MPFR_SIGN(x));
}
else if (MPFR_UNLIKELY (t != 0 && MPFR_IS_INF (x)))
@@ -258,66 +307,82 @@ mpfr_check_range (mpfr_ptr x, int t, mpfr_rnd_t rnd_mode)
MPFR_RET (t); /* propagate inexact ternary value, unlike most functions */
}
+
#undef mpfr_underflow_p
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_underflow_p (void)
{
+ MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_UNDERFLOW <= INT_MAX);
return __gmpfr_flags & MPFR_FLAGS_UNDERFLOW;
}
#undef mpfr_overflow_p
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_overflow_p (void)
{
+ MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_OVERFLOW <= INT_MAX);
return __gmpfr_flags & MPFR_FLAGS_OVERFLOW;
}
#undef mpfr_divby0_p
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_divby0_p (void)
{
+ MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_DIVBY0 <= INT_MAX);
return __gmpfr_flags & MPFR_FLAGS_DIVBY0;
}
#undef mpfr_nanflag_p
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_nanflag_p (void)
{
+ MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_NAN <= INT_MAX);
return __gmpfr_flags & MPFR_FLAGS_NAN;
}
#undef mpfr_inexflag_p
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_inexflag_p (void)
{
+ MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_INEXACT <= INT_MAX);
return __gmpfr_flags & MPFR_FLAGS_INEXACT;
}
#undef mpfr_erangeflag_p
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_erangeflag_p (void)
{
+ MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_ERANGE <= INT_MAX);
return __gmpfr_flags & MPFR_FLAGS_ERANGE;
}
+
/* #undef mpfr_underflow */
/* Note: In the rounding to the nearest mode, mpfr_underflow
always rounds away from 0. In this rounding mode, you must call
mpfr_underflow with rnd_mode = MPFR_RNDZ if the exact result
- is <= 2^(emin-2) in absolute value. */
+ is <= 2^(emin-2) in absolute value.
+ We chose the default to round away from zero instead of toward zero
+ because rounding away from zero (MPFR_RNDA) wasn't supported at that
+ time (r1910), so that the caller had no way to change rnd_mode to
+ this mode. */
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_underflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign)
{
int inex;
+ MPFR_LOG_FUNC
+ (("rnd=%d sign=%d", rnd_mode, sign),
+ ("x[%Pu]=%.*Rg", mpfr_get_prec (x), mpfr_log_prec, x));
+
MPFR_ASSERT_SIGN (sign);
if (MPFR_IS_LIKE_RNDZ(rnd_mode, sign < 0))
@@ -337,12 +402,17 @@ mpfr_underflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign)
/* #undef mpfr_overflow */
-int
+MPFR_COLD_FUNCTION_ATTR int
mpfr_overflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign)
{
int inex;
- MPFR_ASSERT_SIGN(sign);
+ MPFR_LOG_FUNC
+ (("rnd=%d sign=%d", rnd_mode, sign),
+ ("x[%Pu]=%.*Rg", mpfr_get_prec (x), mpfr_log_prec, x));
+
+ MPFR_ASSERT_SIGN (sign);
+
if (MPFR_IS_LIKE_RNDZ(rnd_mode, sign < 0))
{
mpfr_setmax (x, __gmpfr_emax);
@@ -353,7 +423,50 @@ mpfr_overflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign)
MPFR_SET_INF(x);
inex = 1;
}
- MPFR_SET_SIGN(x,sign);
+ MPFR_SET_SIGN(x, sign);
__gmpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
return sign > 0 ? inex : -inex;
}
+
+/**************************************************************************/
+
+/* Code related to constructors and destructors (for debugging) should
+ be put here. The reason is that such code must be in an object file
+ that will be kept by the linker for symbol resolution, and symbols
+ __gmpfr_emin and __gmpfr_emax from this file will be used by every
+ program calling a MPFR math function (where rounding is involved). */
+
+#if defined MPFR_DEBUG_PREDICTION
+
+/* Print prediction statistics at the end of a program.
+ *
+ * Code to debug branch prediction, based on Ulrich Drepper's paper
+ * "What Every Programmer Should Know About Memory":
+ * http://people.freebsd.org/~lstewart/articles/cpumemory.pdf
+ */
+
+extern long int __start_predict_data;
+extern long int __stop_predict_data;
+extern long int __start_predict_line;
+extern const char *__start_predict_file;
+
+static void __attribute__ ((destructor))
+predprint (void)
+{
+ long int *s = &__start_predict_data;
+ long int *e = &__stop_predict_data;
+ long int *sl = &__start_predict_line;
+ const char **sf = &__start_predict_file;
+
+ while (s < e)
+ {
+ printf("%s:%ld: incorrect=%ld, correct=%ld%s\n",
+ *sf, *sl, s[0], s[1],
+ s[0] > s[1] ? " <==== WARNING" : "");
+ ++sl;
+ ++sf;
+ s += 2;
+ }
+}
+
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/exp.c b/Build/source/libs/mpfr/mpfr-src/src/exp.c
index e880cbd990c..aac0a4ffa61 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/exp.c
@@ -22,7 +22,15 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-/* #define DEBUG */
+/* Cache for emin and emax bounds.
+ Contrary to other caches, it uses a fixed size for the mantissa,
+ so there is no dynamic allocation, and no need to free them. */
+static MPFR_THREAD_ATTR mpfr_exp_t previous_emin;
+static MPFR_THREAD_ATTR mp_limb_t bound_emin_limb[(32 - 1) / GMP_NUMB_BITS + 1];
+static MPFR_THREAD_ATTR mpfr_t bound_emin;
+static MPFR_THREAD_ATTR mpfr_exp_t previous_emax;
+static MPFR_THREAD_ATTR mp_limb_t bound_emax_limb[(32 - 1) / GMP_NUMB_BITS + 1];
+static MPFR_THREAD_ATTR mpfr_t bound_emax;
int
mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
@@ -61,81 +69,96 @@ mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
/* First, let's detect most overflow and underflow cases. */
- {
- mpfr_t e, bound;
-
- /* We must extended the exponent range and save the flags now. */
- MPFR_SAVE_EXPO_MARK (expo);
-
- mpfr_init2 (e, sizeof (mpfr_exp_t) * CHAR_BIT);
- mpfr_init2 (bound, 32);
-
- inexact = mpfr_set_exp_t (e, expo.saved_emax, MPFR_RNDN);
- MPFR_ASSERTD (inexact == 0);
- mpfr_const_log2 (bound, expo.saved_emax < 0 ? MPFR_RNDD : MPFR_RNDU);
- mpfr_mul (bound, bound, e, MPFR_RNDU);
- if (MPFR_UNLIKELY (mpfr_cmp (x, bound) >= 0))
- {
- /* x > log(2^emax), thus exp(x) > 2^emax */
- mpfr_clears (e, bound, (mpfr_ptr) 0);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_overflow (y, rnd_mode, 1);
- }
-
- inexact = mpfr_set_exp_t (e, expo.saved_emin, MPFR_RNDN);
- MPFR_ASSERTD (inexact == 0);
- inexact = mpfr_sub_ui (e, e, 2, MPFR_RNDN);
- MPFR_ASSERTD (inexact == 0);
- mpfr_const_log2 (bound, expo.saved_emin < 0 ? MPFR_RNDU : MPFR_RNDD);
- mpfr_mul (bound, bound, e, MPFR_RNDD);
- if (MPFR_UNLIKELY (mpfr_cmp (x, bound) <= 0))
- {
- /* x < log(2^(emin - 2)), thus exp(x) < 2^(emin - 2) */
- mpfr_clears (e, bound, (mpfr_ptr) 0);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
- 1);
- }
-
- /* Other overflow/underflow cases must be detected
- by the generic routines. */
- mpfr_clears (e, bound, (mpfr_ptr) 0);
- MPFR_SAVE_EXPO_FREE (expo);
- }
+ /* emax bound is cached. Check if the value in cache is ok */
+ if (MPFR_UNLIKELY (mpfr_get_emax() != previous_emax))
+ {
+ /* Recompute the emax bound */
+ mp_limb_t e_limb[MPFR_EXP_LIMB_SIZE];
+ mpfr_t e;
+
+ /* We extend the exponent range and save the flags. */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ MPFR_TMP_INIT1(e_limb, e, sizeof (mpfr_exp_t) * CHAR_BIT);
+ MPFR_TMP_INIT1(bound_emax_limb, bound_emax, 32);
+
+ inexact = mpfr_set_exp_t (e, expo.saved_emax, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ mpfr_mul (bound_emax, expo.saved_emax < 0 ?
+ __gmpfr_const_log2_RNDD : __gmpfr_const_log2_RNDU,
+ e, MPFR_RNDU);
+ previous_emax = expo.saved_emax;
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+
+ /* mpfr_cmp works even in reduced emin,emax range */
+ if (MPFR_UNLIKELY (mpfr_cmp (x, bound_emax) >= 0))
+ {
+ /* x > log(2^emax), thus exp(x) > 2^emax */
+ return mpfr_overflow (y, rnd_mode, 1);
+ }
+
+ /* emin bound is cached. Check if the value in cache is ok */
+ if (MPFR_UNLIKELY (mpfr_get_emin() != previous_emin))
+ {
+ mp_limb_t e_limb[MPFR_EXP_LIMB_SIZE];
+ mpfr_t e;
+
+ /* We extend the exponent range and save the flags. */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* avoid using a full limb since arithmetic might be slower */
+ MPFR_TMP_INIT1(e_limb, e, sizeof (mpfr_exp_t) * CHAR_BIT - 1);
+ MPFR_TMP_INIT1(bound_emin_limb, bound_emin, 32);
+
+ inexact = mpfr_set_exp_t (e, expo.saved_emin, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ inexact = mpfr_sub_ui (e, e, 2, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ mpfr_const_log2 (bound_emin, expo.saved_emin < 0 ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_mul (bound_emin, bound_emin, e, MPFR_RNDD);
+ previous_emin = expo.saved_emin;
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+
+ if (MPFR_UNLIKELY (mpfr_cmp (x, bound_emin) <= 0))
+ {
+ /* x < log(2^(emin - 2)), thus exp(x) < 2^(emin - 2) */
+ return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
+ 1);
+ }
expx = MPFR_GET_EXP (x);
precy = MPFR_PREC (y);
- /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */
+ /* if x < 2^(-precy), then exp(x) gives 1 +/- 1 ulp(1) */
if (MPFR_UNLIKELY (expx < 0 && (mpfr_uexp_t) (-expx) > precy))
{
mpfr_exp_t emin = __gmpfr_emin;
mpfr_exp_t emax = __gmpfr_emax;
int signx = MPFR_SIGN (x);
+ /* Make sure that the exponent range is large enough:
+ * [0,2] is sufficient in all precisions.
+ */
+ __gmpfr_emin = 0;
+ __gmpfr_emax = 2;
+
MPFR_SET_POS (y);
if (MPFR_IS_NEG_SIGN (signx) && (rnd_mode == MPFR_RNDD ||
rnd_mode == MPFR_RNDZ))
{
- __gmpfr_emin = 0;
- __gmpfr_emax = 0;
mpfr_setmax (y, 0); /* y = 1 - epsilon */
inexact = -1;
}
else
{
- __gmpfr_emin = 1;
- __gmpfr_emax = 1;
mpfr_setmin (y, 1); /* y = 1 */
if (MPFR_IS_POS_SIGN (signx) && (rnd_mode == MPFR_RNDU ||
rnd_mode == MPFR_RNDA))
{
- mp_size_t yn;
- int sh;
-
- yn = MPFR_LIMB_SIZE (y);
- sh = (mpfr_prec_t) yn * GMP_NUMB_BITS - MPFR_PREC(y);
- MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh;
+ /* Warning: should work for precision 1 bit too! */
+ mpfr_nextabove (y);
inexact = 1;
}
else
diff --git a/Build/source/libs/mpfr/mpfr-src/src/exp2.c b/Build/source/libs/mpfr/mpfr-src/src/exp2.c
index a6f396752e4..8aa133224ab 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/exp2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/exp2.c
@@ -29,7 +29,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
- int inexact;
+ int inexact, inex2;
long xint;
mpfr_t xfrac;
MPFR_SAVE_EXPO_DECL (expo);
@@ -62,24 +62,22 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
}
- /* 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 */
- MPFR_ASSERTN (MPFR_EMIN_MIN >= LONG_MIN + 2);
- if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emin - 1) < 0))
- {
- mpfr_rnd_t rnd2 = rnd_mode;
- /* in round to nearest mode, round to zero when x <= __gmpfr_emin-2 */
- if (rnd_mode == MPFR_RNDN &&
- mpfr_cmp_si_2exp (x, __gmpfr_emin - 2, 0) <= 0)
- rnd2 = MPFR_RNDZ;
- return mpfr_underflow (y, rnd2, 1);
- }
+ /* Since the smallest representable non-zero float is 1/2 * 2^emin,
+ if x <= emin - 2, the result is either 1/2 * 2^emin or 0.
+ Warning, for emin - 2 < x < emin - 1, we cannot conclude, since 2^x
+ might round to 2^(emin - 1) for rounding away or to nearest, and there
+ might be no underflow, since we consider underflow "after rounding". */
+
+ MPFR_STAT_STATIC_ASSERT (MPFR_EMIN_MIN >= LONG_MIN + 2);
+ if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emin - 2) <= 0))
+ return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode, 1);
- MPFR_ASSERTN (MPFR_EMAX_MAX <= LONG_MAX);
+ MPFR_STAT_STATIC_ASSERT (MPFR_EMAX_MAX <= LONG_MAX);
if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emax) >= 0))
return mpfr_overflow (y, rnd_mode, 1);
- /* We now know that emin - 1 <= x < emax. */
+ /* We now know that emin - 2 < x < emax. Note that an underflow or
+ overflow is still possible (we have eliminated only easy cases). */
MPFR_SAVE_EXPO_MARK (expo);
@@ -87,14 +85,17 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
|2^x - 1| <= x < 2^EXP(x). If x > 0 we must round away from 0 (dir=1);
if x < 0 we must round toward 0 (dir=0). */
MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_one, - MPFR_GET_EXP (x), 0,
- MPFR_SIGN(x) > 0, rnd_mode, expo, {});
+ MPFR_IS_POS (x), rnd_mode, expo, {});
xint = mpfr_get_si (x, MPFR_RNDZ);
mpfr_init2 (xfrac, MPFR_PREC (x));
- mpfr_sub_si (xfrac, x, xint, MPFR_RNDN); /* exact */
+ MPFR_DBGRES (inexact = mpfr_sub_si (xfrac, x, xint, MPFR_RNDN));
+ MPFR_ASSERTD (inexact == 0);
if (MPFR_IS_ZERO (xfrac))
{
+ /* Here, emin - 1 <= x <= emax - 1, so that an underflow or overflow
+ will not be possible. */
mpfr_set_ui (y, 1, MPFR_RNDN);
inexact = 0;
}
@@ -113,7 +114,7 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
/* the optimal number of bits : see algorithms.tex */
Nt = Ny + 5 + MPFR_INT_CEIL_LOG2 (Ny);
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
/* First computation */
@@ -141,11 +142,27 @@ mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
mpfr_clear (xfrac);
- mpfr_clear_flags ();
- mpfr_mul_2si (y, y, xint, MPFR_RNDN); /* exact or overflow */
- /* Note: We can have an overflow only when t was rounded up to 2. */
- MPFR_ASSERTD (MPFR_IS_PURE_FP (y) || inexact > 0);
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ if (MPFR_UNLIKELY (rnd_mode == MPFR_RNDN && xint == __gmpfr_emin - 1 &&
+ MPFR_GET_EXP (y) == 0 && mpfr_powerof2_raw (y)))
+ {
+ /* y was rounded down to 1/2 and the rounded value with an unbounded
+ exponent range would be 2^(emin-2), i.e. the midpoint between 0
+ and the smallest positive FP number. This is a double rounding
+ problem: we should not round to 0, but to (1/2) * 2^emin. */
+ MPFR_SET_EXP (y, __gmpfr_emin);
+ inexact = 1;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW);
+ }
+ else
+ {
+ MPFR_CLEAR_FLAGS ();
+ inex2 = mpfr_mul_2si (y, y, xint, rnd_mode);
+ if (inex2 != 0) /* underflow or overflow */
+ inexact = inex2;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ }
+
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (y, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/exp3.c b/Build/source/libs/mpfr/mpfr-src/src/exp3.c
index 04f3e68519d..2940b471b49 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/exp3.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/exp3.c
@@ -42,7 +42,7 @@ static void
mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m,
mpz_t *Q, mpfr_prec_t *mult)
{
- unsigned long n, i, j;
+ mp_bitcnt_t n, h, i, j; /* unsigned type, which is >= unsigned long */
mpz_t *S, *ptoj;
mpfr_prec_t *log2_nb_terms;
mpfr_exp_t diff, expo;
@@ -58,8 +58,9 @@ mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m,
/* Normalize p */
MPFR_ASSERTD (mpz_cmp_ui (p, 0) != 0);
n = mpz_scan1 (p, 0); /* number of trailing zeros in p */
+ MPFR_ASSERTN (n <= LONG_MAX); /* This is a limitation. */
mpz_tdiv_q_2exp (p, p, n);
- r -= n; /* since |p/2^r| < 1 and p >= 1, r >= 1 */
+ r -= (long) n; /* since |p/2^r| < 1 and p >= 1, r >= 1 */
/* Set initial var */
mpz_set (ptoj[0], p);
@@ -75,6 +76,7 @@ mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m,
/* Main Loop */
n = 1UL << m;
+ MPFR_ASSERTN (n != 0); /* no overflow */
for (i = 1; (prec_i_have < precy) && (i < n); i++)
{
/* invariant: Q[0]*Q[1]*...*Q[k] equals i! */
@@ -112,14 +114,14 @@ mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m,
/* accumulate all products in S[0] and Q[0]. Warning: contrary to above,
here we do not have log2_nb_terms[k-1] = log2_nb_terms[k]+1. */
- l = 0; /* number of accumulated terms in the right part S[k]/Q[k] */
+ h = 0; /* number of accumulated terms in the right part S[k]/Q[k] */
while (k > 0)
{
j = log2_nb_terms[k-1];
mpz_mul (S[k], S[k], ptoj[j]);
mpz_mul (S[k-1], S[k-1], Q[k]);
- l += 1 << log2_nb_terms[k];
- mpz_mul_2exp (S[k-1], S[k-1], r * l);
+ h += (mp_bitcnt_t) 1 << log2_nb_terms[k];
+ mpz_mul_2exp (S[k-1], S[k-1], r * h);
mpz_add (S[k-1], S[k-1], S[k]);
mpz_mul (Q[k-1], Q[k-1], Q[k]);
k--;
@@ -144,7 +146,9 @@ mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m,
mpz_tdiv_q (S[0], S[0], Q[0]);
mpfr_set_z (y, S[0], MPFR_RNDD);
- MPFR_SET_EXP (y, MPFR_GET_EXP (y) + expo - r * (i - 1) );
+ /* TODO: Check/prove that the following expression doesn't overflow. */
+ expo = MPFR_GET_EXP (y) + expo - r * (i - 1);
+ MPFR_SET_EXP (y, expo);
}
#define shift (GMP_NUMB_BITS/2)
@@ -215,10 +219,10 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
twopoweri = GMP_NUMB_BITS;
/* Allocate tables */
- P = (mpz_t*) (*__gmp_allocate_func) (3*(k+2)*sizeof(mpz_t));
+ P = (mpz_t*) mpfr_allocate_func (3*(k+2)*sizeof(mpz_t));
for (i = 0; i < 3*(k+2); i++)
mpz_init (P[i]);
- mult = (mpfr_prec_t*) (*__gmp_allocate_func) (2*(k+2)*sizeof(mpfr_prec_t));
+ mult = (mpfr_prec_t*) mpfr_allocate_func (2*(k+2)*sizeof(mpfr_prec_t));
/* Particular case for i==0 */
mpfr_extract (uk, x_copy, 0);
@@ -245,8 +249,8 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
/* Clear tables */
for (i = 0; i < 3*(k+2); i++)
mpz_clear (P[i]);
- (*__gmp_free_func) (P, 3*(k+2)*sizeof(mpz_t));
- (*__gmp_free_func) (mult, 2*(k+2)*sizeof(mpfr_prec_t));
+ mpfr_free_func (P, 3*(k+2)*sizeof(mpz_t));
+ mpfr_free_func (mult, 2*(k+2)*sizeof(mpfr_prec_t));
if (shift_x > 0)
{
@@ -283,8 +287,8 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
}
- if (mpfr_can_round (shift_x > 0 ? t : tmp, realprec, MPFR_RNDN, MPFR_RNDZ,
- MPFR_PREC(y) + (rnd_mode == MPFR_RNDN)))
+ if (MPFR_CAN_ROUND (shift_x > 0 ? t : tmp, realprec,
+ MPFR_PREC(y), rnd_mode))
{
inexact = mpfr_set (y, shift_x > 0 ? t : tmp, rnd_mode);
if (MPFR_UNLIKELY (scaled && MPFR_IS_PURE_FP (y)))
diff --git a/Build/source/libs/mpfr/mpfr-src/src/exp_2.c b/Build/source/libs/mpfr/mpfr-src/src/exp_2.c
index e90d462e654..64a9fd286d0 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/exp_2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/exp_2.c
@@ -21,7 +21,6 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-/* #define DEBUG */
#define MPFR_NEED_LONGLONG_H /* for count_leading_zeros */
#include "mpfr-impl.h"
@@ -44,13 +43,12 @@ mpz_normalize (mpz_t rop, mpz_t z, mpfr_exp_t q)
MPFR_MPZ_SIZEINBASE2 (k, z);
MPFR_ASSERTD (k == (mpfr_uexp_t) k);
- if (q < 0 || (mpfr_uexp_t) k > (mpfr_uexp_t) q)
+ if (MPFR_LIKELY(q < 0 || (mpfr_uexp_t) k > (mpfr_uexp_t) q))
{
mpz_fdiv_q_2exp (rop, z, (unsigned long) ((mpfr_uexp_t) k - q));
return (mpfr_exp_t) k - q;
}
- if (MPFR_UNLIKELY(rop != z))
- mpz_set (rop, z);
+ mpz_set (rop, z);
return 0;
}
@@ -61,7 +59,7 @@ mpz_normalize (mpz_t rop, mpz_t z, mpfr_exp_t q)
static mpfr_exp_t
mpz_normalize2 (mpz_t rop, mpz_t z, mpfr_exp_t expz, mpfr_exp_t target)
{
- if (target > expz)
+ if (MPFR_LIKELY(target > expz))
mpz_fdiv_q_2exp (rop, z, target - expz);
else
mpz_mul_2exp (rop, z, expz - target);
@@ -83,8 +81,9 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_exp_t exps, expx;
mpfr_prec_t q, precy;
int inexact;
- mpfr_t r, s;
+ mpfr_t s, r;
mpz_t ss;
+ MPFR_GROUP_DECL(group);
MPFR_ZIV_DECL (loop);
MPFR_LOG_FUNC
@@ -95,20 +94,47 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
expx = MPFR_GET_EXP (x);
precy = MPFR_PREC(y);
- /* Warning: we cannot use the 'double' type here, since on 64-bit machines
+ /* First perform argument reduction: if x' = x - n*log(2) we have
+ exp(x) = exp(x)*2^n. We should take n near from x/log(2) but it does not
+ need to be exact.
+ Warning: we cannot use the 'double' type here, since on 64-bit machines
x may be as large as 2^62*log(2) without overflow, and then x/log(2)
is about 2^62: not every integer of that size can be represented as a
'double', thus the argument reduction would fail. */
- if (expx <= -2)
+ if (MPFR_UNLIKELY(expx <= -2))
/* |x| <= 0.25, thus n = round(x/log(2)) = 0 */
n = 0;
else
{
- mpfr_init2 (r, sizeof (long) * CHAR_BIT);
- mpfr_const_log2 (r, MPFR_RNDZ);
- mpfr_div (r, x, r, MPFR_RNDN);
+ mp_limb_t r_limb[(sizeof (long) -1) / sizeof(mp_limb_t) + 1];
+ /* Note: we use precision sizeof (long) * CHAR_BIT - 1 here since it is
+ more efficient that full limb precision. */
+ MPFR_TMP_INIT1(r_limb, r, sizeof (long) * CHAR_BIT - 1);
+ mpfr_div (r, x, __gmpfr_const_log2_RNDD, MPFR_RNDN);
+#ifdef MPFR_LONG_WITHIN_LIMB
+ /* The following code assume an unsigned long can fit in a mp_limb_t */
+ {
+ mp_limb_t a;
+ mpfr_exp_t exp;
+ MPFR_STAT_STATIC_ASSERT (MPFR_LIMB_MAX >= ULONG_MAX);
+ /* Read the long directly (faster than using mpfr_get_si
+ since it fits, it is not singular, it can't be zero
+ and there is no conversion to do) */
+ MPFR_ASSERTD (MPFR_NOTZERO (r));
+ exp = MPFR_GET_EXP (r);
+ MPFR_ASSERTD (exp <= GMP_NUMB_BITS);
+ if (exp >= 1)
+ {
+ a = MPFR_MANT(r)[0] >> (GMP_NUMB_BITS - exp);
+ n = MPFR_IS_POS (r) ? a : a <= LONG_MAX ? - (long) a : LONG_MIN;
+ }
+ else
+ n = 0;
+ }
+#else
+ /* Use generic way to get the long */
n = mpfr_get_si (r, MPFR_RNDN);
- mpfr_clear (r);
+#endif
}
/* we have |x| <= (|n|+1)*log(2) */
MPFR_LOG_MSG (("d(x)=%1.30e n=%ld\n", mpfr_get_d1(x), n));
@@ -118,7 +144,8 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
error_r = 0;
else
{
- count_leading_zeros (error_r, (mp_limb_t) SAFE_ABS (unsigned long, n) + 1);
+ count_leading_zeros (error_r,
+ (mp_limb_t) SAFE_ABS (unsigned long, n) + 1);
error_r = GMP_NUMB_BITS - error_r;
/* we have |x| <= 2^error_r * log(2) */
}
@@ -126,21 +153,21 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_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 < MPFR_EXP_2_THRESHOLD) ? __gmpfr_isqrt ((precy + 1) / 2)
+ K = (precy < MPFR_EXP_2_THRESHOLD) ? __gmpfr_isqrt ((precy + 1) / 2) + 3
: __gmpfr_cuberoot (4*precy);
l = (precy - 1) / K + 1;
err = K + MPFR_INT_CEIL_LOG2 (2 * l + 18);
/* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */
- q = precy + err + K + 8;
+ q = precy + err + K + 10;
/* if |x| >> 1, take into account the cancelled bits */
if (expx > 0)
q += expx;
- /* Note: due to the mpfr_prec_round below, it is not possible to use
- the MPFR_GROUP_* macros here. */
-
- mpfr_init2 (r, q + error_r);
- mpfr_init2 (s, q + error_r);
+ /* Even with to the mpfr_prec_round below, it is possible to use
+ the MPFR_GROUP_* macros here because mpfr_prec_round is only
+ called in a special case. */
+ MPFR_GROUP_INIT_2(group, q + error_r, r, s);
+ mpz_init (ss);
/* the algorithm consists in computing an upper bound of exp(x) using
a precision of q bits, and see if we can round to MPFR_PREC(y) taking
@@ -171,27 +198,31 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_sub (r, x, r, MPFR_RNDU);
- if (MPFR_IS_PURE_FP (r))
- {
- while (MPFR_IS_NEG (r))
- { /* initial approximation n was too large */
- n--;
- mpfr_add (r, r, s, MPFR_RNDU);
- }
+ while (MPFR_IS_PURE_FP(r) && MPFR_IS_NEG (r))
+ { /* initial approximation n was too large */
+ n--;
+ mpfr_add (r, r, s, MPFR_RNDU);
+ }
+ /* if r is 0, we cannot round correctly */
+ if (MPFR_LIKELY(MPFR_IS_PURE_FP (r)))
+ {
/* since there was a cancellation in x - n*log(2), the low error_r
bits from r are zero and thus non significant, thus we can reduce
the working precision */
- if (error_r > 0)
- mpfr_prec_round (r, q, MPFR_RNDU);
+ if (MPFR_LIKELY(error_r > 0))
+ {
+ MPFR_ASSERTD( MPFR_PREC(r) > q);
+ /* since MPFR_PREC(r) > q, there is no reallocation to do,
+ and it is safe to use it with MPFR_GROUP functions */
+ mpfr_prec_round (r, q, MPFR_RNDU);
+ }
/* the error on r is at most 3 ulps (3 ulps if error_r = 0,
and 1 + 3/2 if error_r > 0) */
MPFR_LOG_VAR (r);
MPFR_ASSERTD (MPFR_IS_POS (r));
mpfr_div_2ui (r, r, K, MPFR_RNDU); /* r = (x-n*log(2))/2^K, exact */
- mpz_init (ss);
- exps = mpfr_get_z_2exp (ss, s);
/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! */
MPFR_ASSERTD (MPFR_IS_PURE_FP (r) && MPFR_EXP (r) < 0);
l = (precy < MPFR_EXP_2_THRESHOLD)
@@ -207,10 +238,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
exps *= 2;
exps += mpz_normalize (ss, ss, q);
}
- mpfr_set_z (s, ss, MPFR_RNDN);
-
- MPFR_SET_EXP(s, MPFR_GET_EXP (s) + exps);
- mpz_clear (ss);
+ mpfr_set_z_2exp (s, ss, exps, MPFR_RNDN);
/* error is at most 2^K*l, plus 2 to take into account of
the error of 3 ulps on r */
@@ -222,20 +250,17 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
if (MPFR_LIKELY (MPFR_CAN_ROUND (s, q - err, precy, rnd_mode)))
{
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_mul_2si (y, s, n, rnd_mode);
break;
}
}
-
MPFR_ZIV_NEXT (loop, q);
- mpfr_set_prec (r, q + error_r);
- mpfr_set_prec (s, q + error_r);
+ MPFR_GROUP_REPREC_2(group, q+error_r, r, s);
}
MPFR_ZIV_FREE (loop);
-
- mpfr_clear (r);
- mpfr_clear (s);
+ mpz_clear (ss);
+ MPFR_GROUP_CLEAR (group);
return inexact;
}
@@ -246,10 +271,6 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
The absolute error on s is less than 3*l*(l+1)*2^(-q).
Version using fixed-point arithmetic with mpz instead
of mpfr for internal computations.
- NOTE[VL]: the following sentence seems to be obsolete since MY_INIT_MPZ
- is no longer used (r6919); qn was the number of limbs of q.
- s must have at least qn+1 limbs (qn should be enough, but currently fails
- since mpz_mul_2exp(s, s, q-1) reallocates qn+1 limbs)
*/
static unsigned long
mpfr_exp2_aux (mpz_t s, mpfr_srcptr r, mpfr_prec_t q, mpfr_exp_t *exps)
@@ -259,38 +280,52 @@ mpfr_exp2_aux (mpz_t s, mpfr_srcptr r, mpfr_prec_t q, mpfr_exp_t *exps)
mpz_t t, rr;
mp_size_t sbit, tbit;
- MPFR_ASSERTN (MPFR_IS_PURE_FP (r));
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (r));
expt = 0;
*exps = 1 - (mpfr_exp_t) q; /* s = 2^(q-1) */
mpz_init (t);
mpz_init (rr);
- mpz_set_ui(t, 1);
- mpz_set_ui(s, 1);
- mpz_mul_2exp(s, s, q-1);
- expr = mpfr_get_z_2exp(rr, r); /* no error here */
+ mpz_set_ui (t, 1);
+ mpz_set_ui (s, 1);
+ mpz_mul_2exp (s, s, q-1);
+ expr = mpfr_get_z_2exp (rr, r); /* no error here */
l = 0;
- for (;;) {
- l++;
- mpz_mul(t, t, rr);
- expt += expr;
- MPFR_MPZ_SIZEINBASE2 (sbit, s);
- MPFR_MPZ_SIZEINBASE2 (tbit, t);
- dif = *exps + sbit - expt - tbit;
- /* truncates the bits of t which are < ulp(s) = 2^(1-q) */
- expt += mpz_normalize(t, t, (mpfr_exp_t) q-dif); /* error at most 2^(1-q) */
- mpz_fdiv_q_ui (t, t, l); /* error at most 2^(1-q) */
- /* the error wrt t^l/l! is here at most 3*l*ulp(s) */
- MPFR_ASSERTD (expt == *exps);
- if (mpz_sgn (t) == 0)
- break;
- mpz_add(s, s, t); /* no error here: exact */
- /* ensures rr has the same size as t: after several shifts, the error
- on rr is still at most ulp(t)=ulp(s) */
- MPFR_MPZ_SIZEINBASE2 (tbit, t);
- expr += mpz_normalize(rr, rr, tbit);
- }
+ for (;;)
+ {
+ l++;
+ mpz_mul(t, t, rr);
+ expt += expr;
+ MPFR_MPZ_SIZEINBASE2 (sbit, s);
+ MPFR_MPZ_SIZEINBASE2 (tbit, t);
+ dif = *exps + sbit - expt - tbit;
+ /* truncates the bits of t which are < ulp(s) = 2^(1-q) */
+ expt += mpz_normalize (t, t, (mpfr_exp_t) q - dif);
+ /* error at most 2^(1-q) */
+ if (l > 1)
+ {
+ /* GMP doesn't optimize the case of power of 2 */
+ if (IS_POW2(l))
+ {
+ int bits = MPFR_INT_CEIL_LOG2(l);
+ mpz_fdiv_q_2exp (t, t, bits); /* error at most 2^(1-q) */
+ }
+ else
+ {
+ mpz_fdiv_q_ui (t, t, l); /* error at most 2^(1-q) */
+ }
+ /* the error wrt t^l/l! is here at most 3*l*ulp(s) */
+ MPFR_ASSERTD (expt == *exps);
+ }
+ if (mpz_sgn (t) == 0)
+ break;
+ mpz_add (s, s, t); /* no error here: exact */
+ /* ensures rr has the same size as t: after several shifts, the error
+ on rr is still at most ulp(t)=ulp(s) */
+ MPFR_MPZ_SIZEINBASE2 (tbit, t);
+ expr += mpz_normalize (rr, rr, tbit);
+ }
mpz_clear (t);
mpz_clear (rr);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/expm1.c b/Build/source/libs/mpfr/mpfr-src/src/expm1.c
index 97c880178ce..0899f181e63 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/expm1.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/expm1.c
@@ -82,14 +82,12 @@ mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mpfr_rnd_t rnd_mode)
if (MPFR_IS_NEG (x) && ex > 5) /* x <= -32 */
{
- mpfr_t minus_one, t;
+ mp_limb_t t_limb[(64 - 1) / GMP_NUMB_BITS + 1];
+ mpfr_t t;
mpfr_exp_t err;
- mpfr_init2 (minus_one, 2);
- mpfr_init2 (t, 64);
- mpfr_set_si (minus_one, -1, MPFR_RNDN);
- mpfr_const_log2 (t, MPFR_RNDU); /* round upward since x is negative */
- mpfr_div (t, x, t, MPFR_RNDU); /* > x / ln(2) */
+ MPFR_TMP_INIT1(t_limb, t, 64);
+ mpfr_div (t, x, __gmpfr_const_log2_RNDU, MPFR_RNDU); /* > x / ln(2) */
err = mpfr_cmp_si (t, MPFR_EMIN_MIN >= -LONG_MAX ?
MPFR_EMIN_MIN : -LONG_MAX) <= 0 ?
- (MPFR_EMIN_MIN >= -LONG_MAX ? MPFR_EMIN_MIN : -LONG_MAX) :
@@ -97,10 +95,8 @@ mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mpfr_rnd_t rnd_mode)
/* exp(x) = 2^(x/ln(2))
<= 2^max(MPFR_EMIN_MIN,-LONG_MAX,ceil(x/ln(2)+epsilon))
with epsilon > 0 */
- mpfr_clear (t);
- MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, minus_one, err, 0, 0, rnd_mode,
- expo, { mpfr_clear (minus_one); });
- mpfr_clear (minus_one);
+ MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_mone, err, 0, 0,
+ rnd_mode, expo, {});
}
/* General case */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/extract.c b/Build/source/libs/mpfr/mpfr-src/src/extract.c
index 9dd58da377a..b3a56ffab3d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/extract.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/extract.c
@@ -37,19 +37,21 @@ mpfr_extract (mpz_ptr y, mpfr_srcptr p, unsigned int i)
unsigned long two_i_2 = i ? two_i / 2 : 1;
mp_size_t size_p = MPFR_LIMB_SIZE (p);
+ MPFR_ASSERTN (two_i != 0 && two_i_2 <= INT_MAX); /* overflow check */
+
/* as 0 <= |p| < 1, we don't have to care with infinities, NaN, ... */
MPFR_ASSERTD (!MPFR_IS_SINGULAR (p));
- _mpz_realloc (y, two_i_2);
- if ((mpfr_uexp_t) size_p < two_i)
+ mpz_realloc2 (y, (mp_bitcnt_t) two_i_2 * GMP_NUMB_BITS);
+ if (size_p < two_i)
{
MPN_ZERO (PTR(y), two_i_2);
- if ((mpfr_uexp_t) size_p >= two_i_2)
- MPN_COPY (PTR(y) + two_i - size_p, MPFR_MANT(p), size_p - two_i_2);
+ if (size_p >= two_i_2)
+ MPN_COPY (PTR(y) + (two_i - size_p), MPFR_MANT(p), size_p - two_i_2);
}
else
MPN_COPY (PTR(y), MPFR_MANT(p) + size_p - two_i, two_i_2);
MPN_NORMALIZE (PTR(y), two_i_2);
- SIZ(y) = (MPFR_IS_NEG (p)) ? -two_i_2 : two_i_2;
+ SIZ(y) = MPFR_IS_NEG (p) ? - (int) two_i_2 : (int) two_i_2;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/factorial.c b/Build/source/libs/mpfr/mpfr-src/src/factorial.c
index e256e517137..1ce413f9dd3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/factorial.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/factorial.c
@@ -1,4 +1,4 @@
-/* mpfr_fac_ui -- factorial of a non-negative integer
+/* mpfr_fac_ui -- factorial of a nonnegative integer
Copyright 2001, 2004-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -57,7 +57,7 @@ mpfr_fac_ui (mpfr_ptr y, unsigned long int x, mpfr_rnd_t rnd_mode)
/* compute the size of intermediary variable */
Nt = Ny + 2 * MPFR_INT_CEIL_LOG2 (x) + 7;
- mpfr_init2 (t, Nt); /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt); /* initialize of intermediary variable */
rnd = MPFR_RNDZ;
MPFR_ZIV_INIT (loop, Nt);
@@ -76,8 +76,7 @@ mpfr_fac_ui (mpfr_ptr y, unsigned long int x, mpfr_rnd_t rnd_mode)
err = Nt - 1 - MPFR_INT_CEIL_LOG2 (Nt);
- round = !inexact || mpfr_can_round (t, err, rnd, MPFR_RNDZ,
- Ny + (rnd_mode == MPFR_RNDN));
+ round = !inexact || MPFR_CAN_ROUND (t, err, Ny, rnd_mode);
if (MPFR_LIKELY (round))
{
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fits_intmax.c b/Build/source/libs/mpfr/mpfr-src/src/fits_intmax.c
index 9c4f27f6a7a..f2f06881383 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/fits_intmax.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/fits_intmax.c
@@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-# include "config.h" /* for a build within gmp */
+# include "config.h"
#endif
#include "mpfr-intmax.h"
@@ -29,11 +29,11 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#ifdef _MPFR_H_HAVE_INTMAX_T
-/* We can't use fits_s.h <= mpfr_cmp_ui */
+/* We can't use fits_s.h as it uses mpfr_cmp_si */
int
mpfr_fits_intmax_p (mpfr_srcptr f, mpfr_rnd_t rnd)
{
- unsigned int saved_flags;
+ mpfr_flags_t saved_flags;
mpfr_exp_t e;
int prec;
mpfr_t x, y;
@@ -88,7 +88,9 @@ mpfr_fits_intmax_p (mpfr_srcptr f, mpfr_rnd_t rnd)
/* hard case: first round to prec bits, then check */
saved_flags = __gmpfr_flags;
mpfr_init2 (x, prec);
- mpfr_set (x, f, rnd);
+ /* for RNDF, it is necessary and sufficient to check it fits when rounding
+ away from zero */
+ mpfr_set (x, f, (rnd == MPFR_RNDF) ? MPFR_RNDA : rnd);
if (neg)
{
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fits_s.h b/Build/source/libs/mpfr/mpfr-src/src/fits_s.h
index ce1d882f680..13473cb9c34 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/fits_s.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/fits_s.h
@@ -29,7 +29,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
{
- unsigned int saved_flags;
+ mpfr_flags_t saved_flags;
mpfr_exp_t e;
int prec;
mpfr_t x;
@@ -84,7 +84,8 @@ FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
/* hard case: first round to prec bits, then check */
saved_flags = __gmpfr_flags;
mpfr_init2 (x, prec);
- mpfr_set (x, f, rnd);
+ /* for RNDF, it suffices to check it fits when rounded away from zero */
+ mpfr_set (x, f, (rnd == MPFR_RNDF) ? MPFR_RNDA : rnd);
/* Warning! Due to the rounding, x can be an infinity. Here we use
the fact that singular numbers have a special exponent field,
thus well-defined and different from e, in which case this means
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fits_u.h b/Build/source/libs/mpfr/mpfr-src/src/fits_u.h
index e84c6b6560b..1faabf48314 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/fits_u.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/fits_u.h
@@ -25,7 +25,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
{
- unsigned int saved_flags;
+ mpfr_flags_t saved_flags;
mpfr_exp_t e;
int prec;
TYPE s;
@@ -65,7 +65,8 @@ FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
/* hard case: first round to prec bits, then check */
saved_flags = __gmpfr_flags;
mpfr_init2 (x, prec);
- mpfr_set (x, f, rnd);
+ /* For MPFR_RNDF, if f > 0 fits with RNDU, it will also fit with RNDD. */
+ mpfr_set (x, f, (rnd != MPFR_RNDF) ? rnd : MPFR_RNDU);
/* Warning! Due to the rounding, x can be an infinity. Here we use
the fact that singular numbers have a special exponent field,
thus well-defined and different from e, in which case this means
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fits_uintmax.c b/Build/source/libs/mpfr/mpfr-src/src/fits_uintmax.c
index eaafbe9a8ca..f1dd73547a2 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/fits_uintmax.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/fits_uintmax.c
@@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-# include "config.h" /* for a build within gmp */
+# include "config.h"
#endif
#include "mpfr-intmax.h"
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fma.c b/Build/source/libs/mpfr/mpfr-src/src/fma.c
index f12105fead9..5acbec69f2d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/fma.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/fma.c
@@ -20,18 +20,90 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
/* The fused-multiply-add (fma) of x, y and z is defined by:
fma(x,y,z)= x*y + z
*/
+/* this function deals with all cases where inputs are singular, i.e.,
+ either NaN, Inf or zero */
+static int
+mpfr_fma_singular (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
+ mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
+ {
+ MPFR_SET_NAN(s);
+ MPFR_RET_NAN;
+ }
+ /* now neither x, y or z is NaN */
+ else if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
+ {
+ /* cases Inf*0+z, 0*Inf+z, Inf-Inf */
+ if ((MPFR_IS_ZERO(y)) ||
+ (MPFR_IS_ZERO(x)) ||
+ (MPFR_IS_INF(z) &&
+ ((MPFR_MULT_SIGN(MPFR_SIGN(x), MPFR_SIGN(y))) != MPFR_SIGN(z))))
+ {
+ MPFR_SET_NAN(s);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SAME_SIGN(s, z);
+ MPFR_RET(0);
+ }
+ else /* z is finite */
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SIGN(s, MPFR_MULT_SIGN(MPFR_SIGN(x) , MPFR_SIGN(y)));
+ MPFR_RET(0);
+ }
+ }
+ /* now x and y are finite */
+ else if (MPFR_IS_INF(z))
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SAME_SIGN(s, z);
+ MPFR_RET(0);
+ }
+ else if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
+ {
+ if (MPFR_IS_ZERO(z))
+ {
+ int sign_p;
+ sign_p = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
+ MPFR_SET_SIGN(s, (rnd_mode != MPFR_RNDD ?
+ (MPFR_IS_NEG_SIGN(sign_p) && MPFR_IS_NEG(z) ?
+ MPFR_SIGN_NEG : MPFR_SIGN_POS) :
+ (MPFR_IS_POS_SIGN(sign_p) && MPFR_IS_POS(z) ?
+ MPFR_SIGN_POS : MPFR_SIGN_NEG)));
+ MPFR_SET_ZERO(s);
+ MPFR_RET(0);
+ }
+ else
+ return mpfr_set (s, z, rnd_mode);
+ }
+ else /* necessarily z is zero here */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(z));
+ return mpfr_mul (s, x, y, rnd_mode);
+ }
+}
+
+/* s <- x*y + z */
int
mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t u;
+ mp_size_t n;
+ mpfr_exp_t e;
+ mpfr_prec_t precx, precy;
MPFR_SAVE_EXPO_DECL (expo);
MPFR_GROUP_DECL(group);
@@ -44,75 +116,103 @@ mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
mpfr_get_prec (s), mpfr_log_prec, s, inexact));
/* particular cases */
- if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) ||
- MPFR_IS_SINGULAR(y) ||
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) || MPFR_IS_SINGULAR(y) ||
MPFR_IS_SINGULAR(z) ))
+ return mpfr_fma_singular (s, x, y, z, rnd_mode);
+
+ e = MPFR_GET_EXP (x) + MPFR_GET_EXP (y);
+
+ precx = MPFR_PREC (x);
+ precy = MPFR_PREC (y);
+
+ /* First deal with special case where prec(x) = prec(y) and x*y does
+ not overflow nor underflow. Do it only for small sizes since for large
+ sizes x*y is faster using Mulders' algorithm (as a rule of thumb,
+ we assume mpn_mul_n is faster up to 4*MPFR_MUL_THRESHOLD).
+ Since |EXP(x)|, |EXP(y)| < 2^(k-2) on a k-bit computer,
+ |EXP(x)+EXP(y)| < 2^(k-1), thus cannot overflow nor underflow. */
+ if (precx == precy && e <= __gmpfr_emax && e > __gmpfr_emin)
{
- if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
- {
- MPFR_SET_NAN(s);
- MPFR_RET_NAN;
- }
- /* now neither x, y or z is NaN */
- else if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
+ if (precx < GMP_NUMB_BITS &&
+ MPFR_PREC(z) == precx &&
+ MPFR_PREC(s) == precx)
{
- /* cases Inf*0+z, 0*Inf+z, Inf-Inf */
- if ((MPFR_IS_ZERO(y)) ||
- (MPFR_IS_ZERO(x)) ||
- (MPFR_IS_INF(z) &&
- ((MPFR_MULT_SIGN(MPFR_SIGN(x), MPFR_SIGN(y))) != MPFR_SIGN(z))))
- {
- MPFR_SET_NAN(s);
- MPFR_RET_NAN;
- }
- else if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
+ mp_limb_t umant[2], zmant[2];
+ mpfr_t zz;
+ int inex;
+
+ umul_ppmm (umant[1], umant[0], MPFR_MANT(x)[0], MPFR_MANT(y)[0]);
+ MPFR_PREC(u) = MPFR_PREC(zz) = 2 * precx;
+ MPFR_MANT(u) = umant;
+ MPFR_MANT(zz) = zmant;
+ MPFR_SIGN(u) = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
+ MPFR_SIGN(zz) = MPFR_SIGN(z);
+ MPFR_EXP(zz) = MPFR_EXP(z);
+ if (MPFR_PREC(zz) <= GMP_NUMB_BITS) /* zz fits in one limb */
{
- MPFR_SET_INF(s);
- MPFR_SET_SAME_SIGN(s, z);
- MPFR_RET(0);
+ if ((umant[1] & MPFR_LIMB_HIGHBIT) == 0)
+ {
+ umant[0] = umant[1] << 1;
+ MPFR_EXP(u) = e - 1;
+ }
+ else
+ {
+ umant[0] = umant[1];
+ MPFR_EXP(u) = e;
+ }
+ zmant[0] = MPFR_MANT(z)[0];
}
- else /* z is finite */
+ else
{
- MPFR_SET_INF(s);
- MPFR_SET_SIGN(s, MPFR_MULT_SIGN(MPFR_SIGN(x) , MPFR_SIGN(y)));
- MPFR_RET(0);
+ zmant[1] = MPFR_MANT(z)[0];
+ zmant[0] = MPFR_LIMB_ZERO;
+ if ((umant[1] & MPFR_LIMB_HIGHBIT) == 0)
+ {
+ umant[1] = (umant[1] << 1) |
+ (umant[0] >> (GMP_NUMB_BITS - 1));
+ umant[0] = umant[0] << 1;
+ MPFR_EXP(u) = e - 1;
+ }
+ else
+ MPFR_EXP(u) = e;
}
+ inex = mpfr_add (u, u, zz, rnd_mode);
+ /* mpfr_set_1_2 requires PREC(u) = 2*PREC(s),
+ thus we need PREC(s) = PREC(x) = PREC(y) = PREC(z) */
+ return mpfr_set_1_2 (s, u, rnd_mode, inex);
}
- /* now x and y are finite */
- else if (MPFR_IS_INF(z))
- {
- MPFR_SET_INF(s);
- MPFR_SET_SAME_SIGN(s, z);
- MPFR_RET(0);
- }
- else if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
+ else if ((n = MPFR_LIMB_SIZE(x)) <= 4 * MPFR_MUL_THRESHOLD)
{
- if (MPFR_IS_ZERO(z))
+ mpfr_limb_ptr up;
+ mp_size_t un = n + n;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_TMP_MARK(marker);
+ MPFR_TMP_INIT (up, u, un * GMP_NUMB_BITS, un);
+ up = MPFR_MANT(u);
+ /* multiply x*y exactly into u */
+ mpn_mul_n (up, MPFR_MANT(x), MPFR_MANT(y), n);
+ if (MPFR_LIMB_MSB (up[un - 1]) == 0)
{
- int sign_p;
- sign_p = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
- MPFR_SET_SIGN(s,(rnd_mode != MPFR_RNDD ?
- ((MPFR_IS_NEG_SIGN(sign_p) && MPFR_IS_NEG(z))
- ? -1 : 1) :
- ((MPFR_IS_POS_SIGN(sign_p) && MPFR_IS_POS(z))
- ? 1 : -1)));
- MPFR_SET_ZERO(s);
- MPFR_RET(0);
+ mpn_lshift (up, up, un, 1);
+ MPFR_EXP(u) = e - 1;
}
else
- return mpfr_set (s, z, rnd_mode);
- }
- else /* necessarily z is zero here */
- {
- MPFR_ASSERTD(MPFR_IS_ZERO(z));
- return mpfr_mul (s, x, y, rnd_mode);
+ MPFR_EXP(u) = e;
+ MPFR_SIGN(u) = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
+ /* The above code does not generate any exception.
+ The exceptions will come only from mpfr_add. */
+ inexact = mpfr_add (s, u, z, rnd_mode);
+ MPFR_TMP_FREE(marker);
+ return inexact;
}
}
/* If we take prec(u) >= prec(x) + prec(y), the product u <- x*y
is exact, except in case of overflow or underflow. */
+ MPFR_ASSERTN (precx + precy <= MPFR_PREC_MAX);
+ MPFR_GROUP_INIT_1 (group, precx + precy, u);
MPFR_SAVE_EXPO_MARK (expo);
- MPFR_GROUP_INIT_1 (group, MPFR_PREC(x) + MPFR_PREC(y), u);
if (MPFR_UNLIKELY (mpfr_mul (u, x, y, MPFR_RNDN)))
{
@@ -132,8 +232,7 @@ mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
Also, we know that |z| < 2^emax. If E(x) + E(y) >= emax+3,
then |x*y| >= 2^(emax+1), and |x*y + z| >= 2^emax. This case
is also an overflow. */
- if (MPFR_SIGN (u) == MPFR_SIGN (z) ||
- MPFR_GET_EXP (x) + MPFR_GET_EXP (y) >= __gmpfr_emax + 3)
+ if (MPFR_SIGN (u) == MPFR_SIGN (z) || e >= __gmpfr_emax + 3)
{
MPFR_GROUP_CLEAR (group);
MPFR_SAVE_EXPO_FREE (expo);
@@ -239,13 +338,13 @@ mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
MPFR_BLOCK (flags,
if (MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
{
- mpfr_init2 (scaled_v, MPFR_PREC (x));
+ mpfr_init2 (scaled_v, precx);
mpfr_mul_2ui (scaled_v, x, scale, MPFR_RNDN);
mpfr_mul (u, scaled_v, y, MPFR_RNDN);
}
else
{
- mpfr_init2 (scaled_v, MPFR_PREC (y));
+ mpfr_init2 (scaled_v, precy);
mpfr_mul_2ui (scaled_v, y, scale, MPFR_RNDN);
mpfr_mul (u, x, scaled_v, MPFR_RNDN);
});
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fmma.c b/Build/source/libs/mpfr/mpfr-src/src/fmma.c
new file mode 100644
index 00000000000..6168c2af0f2
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/fmma.c
@@ -0,0 +1,91 @@
+/* mpfr_fmma, mpfr_fmms -- Compute a*b +/- c*d
+
+Copyright 2014-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+static int
+mpfr_fmma_aux (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c,
+ mpfr_srcptr d, mpfr_rnd_t rnd, int neg)
+{
+ mpfr_ubf_t u, v;
+ mpfr_t zz;
+ mpfr_prec_t prec_z = MPFR_PREC(z);
+ mp_size_t un, vn;
+ mpfr_limb_ptr up, vp, zp;
+ int inex;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_LOG_FUNC
+ (("a[%Pu]=%.*Rg b[%Pu]=%.*Rg c[%Pu]=%.*Rg d[%Pu]=%.*Rg rnd=%d neg=%d",
+ mpfr_get_prec (a), mpfr_log_prec, a,
+ mpfr_get_prec (b), mpfr_log_prec, b,
+ mpfr_get_prec (c), mpfr_log_prec, c,
+ mpfr_get_prec (d), mpfr_log_prec, d, rnd, neg),
+ ("z[%Pu]=%.*Rg inex=%d",
+ mpfr_get_prec (z), mpfr_log_prec, z, inex));
+
+ MPFR_TMP_MARK (marker);
+
+ un = MPFR_LIMB_SIZE (a) + MPFR_LIMB_SIZE (b);
+ vn = MPFR_LIMB_SIZE (c) + MPFR_LIMB_SIZE (d);
+ MPFR_TMP_INIT (up, u, (mpfr_prec_t) un * GMP_NUMB_BITS, un);
+ MPFR_TMP_INIT (vp, v, (mpfr_prec_t) vn * GMP_NUMB_BITS, vn);
+
+ mpfr_ubf_mul_exact (u, a, b);
+ mpfr_ubf_mul_exact (v, c, d);
+ if (neg)
+ MPFR_CHANGE_SIGN (v);
+ if (prec_z == MPFR_PREC(a) && prec_z == MPFR_PREC(b) &&
+ prec_z == MPFR_PREC(c) && prec_z == MPFR_PREC(d) &&
+ un == MPFR_PREC2LIMBS(2 * prec_z))
+ {
+ MPFR_TMP_INIT (zp, zz, 2 * prec_z, un);
+ MPFR_PREC(u) = MPFR_PREC(v) = 2 * prec_z;
+ inex = mpfr_add (zz, (mpfr_srcptr) u, (mpfr_srcptr) v, rnd);
+ inex = mpfr_set_1_2 (z, zz, rnd, inex);
+ }
+ else
+ inex = mpfr_add (z, (mpfr_srcptr) u, (mpfr_srcptr) v, rnd);
+
+ MPFR_UBF_CLEAR_EXP (u);
+ MPFR_UBF_CLEAR_EXP (v);
+
+ MPFR_TMP_FREE (marker);
+
+ return inex;
+}
+
+/* z <- a*b + c*d */
+int
+mpfr_fmma (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c,
+ mpfr_srcptr d, mpfr_rnd_t rnd)
+{
+ return mpfr_fmma_aux (z, a, b, c, d, rnd, 0);
+}
+
+/* z <- a*b - c*d */
+int
+mpfr_fmms (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c,
+ mpfr_srcptr d, mpfr_rnd_t rnd)
+{
+ return mpfr_fmma_aux (z, a, b, c, d, rnd, 1);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fms.c b/Build/source/libs/mpfr/mpfr-src/src/fms.c
index 10501d37624..5f05fbb2394 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/fms.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/fms.c
@@ -24,281 +24,15 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
/* The fused-multiply-subtract (fms) of x, y and z is defined by:
fms(x,y,z)= x*y - z
- Note: this is neither in IEEE754R, nor in LIA-2, but both the
+ Note: this is neither in IEEE 754-2008, nor in LIA-2, but both the
PowerPC and the Itanium define fms as x*y - z.
*/
-
int
mpfr_fms (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
mpfr_rnd_t rnd_mode)
{
- int inexact;
- mpfr_t u;
- MPFR_SAVE_EXPO_DECL (expo);
- MPFR_GROUP_DECL(group);
-
- MPFR_LOG_FUNC
- (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg z[%Pu]=%.*Rg rnd=%d",
- mpfr_get_prec (x), mpfr_log_prec, x,
- mpfr_get_prec (y), mpfr_log_prec, y,
- mpfr_get_prec (z), mpfr_log_prec, z, rnd_mode),
- ("s[%Pu]=%.*Rg inexact=%d",
- mpfr_get_prec (s), mpfr_log_prec, s, inexact));
-
- /* particular cases */
- if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) ||
- MPFR_IS_SINGULAR(y) ||
- MPFR_IS_SINGULAR(z) ))
- {
- if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
- {
- MPFR_SET_NAN(s);
- MPFR_RET_NAN;
- }
- /* now neither x, y or z is NaN */
- else if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
- {
- /* cases Inf*0-z, 0*Inf-z, Inf-Inf */
- if ((MPFR_IS_ZERO(y)) ||
- (MPFR_IS_ZERO(x)) ||
- (MPFR_IS_INF(z) &&
- ((MPFR_MULT_SIGN(MPFR_SIGN(x), MPFR_SIGN(y))) == MPFR_SIGN(z))))
- {
- MPFR_SET_NAN(s);
- MPFR_RET_NAN;
- }
- else if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
- {
- MPFR_SET_INF(s);
- MPFR_SET_OPPOSITE_SIGN(s, z);
- MPFR_RET(0);
- }
- else /* z is finite */
- {
- MPFR_SET_INF(s);
- MPFR_SET_SIGN(s, MPFR_MULT_SIGN(MPFR_SIGN(x) , MPFR_SIGN(y)));
- MPFR_RET(0);
- }
- }
- /* now x and y are finite */
- else if (MPFR_IS_INF(z))
- {
- MPFR_SET_INF(s);
- MPFR_SET_OPPOSITE_SIGN(s, z);
- MPFR_RET(0);
- }
- else if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
- {
- if (MPFR_IS_ZERO(z))
- {
- int sign_p;
- sign_p = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
- MPFR_SET_SIGN(s,(rnd_mode != MPFR_RNDD ?
- ((MPFR_IS_NEG_SIGN(sign_p) && MPFR_IS_POS(z))
- ? -1 : 1) :
- ((MPFR_IS_POS_SIGN(sign_p) && MPFR_IS_NEG(z))
- ? 1 : -1)));
- MPFR_SET_ZERO(s);
- MPFR_RET(0);
- }
- else
- return mpfr_neg (s, z, rnd_mode);
- }
- else /* necessarily z is zero here */
- {
- MPFR_ASSERTD(MPFR_IS_ZERO(z));
- return mpfr_mul (s, x, y, rnd_mode);
- }
- }
-
- /* If we take prec(u) >= prec(x) + prec(y), the product u <- x*y
- is exact, except in case of overflow or underflow. */
- MPFR_SAVE_EXPO_MARK (expo);
- MPFR_GROUP_INIT_1 (group, MPFR_PREC(x) + MPFR_PREC(y), u);
-
- if (MPFR_UNLIKELY (mpfr_mul (u, x, y, MPFR_RNDN)))
- {
- /* overflow or underflow - this case is regarded as rare, thus
- does not need to be very efficient (even if some tests below
- could have been done earlier).
- It is an overflow iff u is an infinity (since MPFR_RNDN was used).
- Alternatively, we could test the overflow flag, but in this case,
- mpfr_clear_flags would have been necessary. */
- if (MPFR_IS_INF (u)) /* overflow */
- {
- /* Let's eliminate the obvious case where x*y and z have the
- same sign. No possible cancellation -> real overflow.
- Also, we know that |z| < 2^emax. If E(x) + E(y) >= emax+3,
- then |x*y| >= 2^(emax+1), and |x*y - z| >= 2^emax. This case
- is also an overflow. */
- if (MPFR_SIGN (u) != MPFR_SIGN (z) ||
- MPFR_GET_EXP (x) + MPFR_GET_EXP (y) >= __gmpfr_emax + 3)
- {
- MPFR_GROUP_CLEAR (group);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_overflow (s, rnd_mode, - MPFR_SIGN (z));
- }
-
- /* E(x) + E(y) <= emax+2, therefore |x*y| < 2^(emax+2), and
- (x/4)*y does not overflow (let's recall that the result
- is exact with an unbounded exponent range). It does not
- underflow either, because x*y overflows and the exponent
- range is large enough. */
- inexact = mpfr_div_2ui (u, x, 2, MPFR_RNDN);
- MPFR_ASSERTN (inexact == 0);
- inexact = mpfr_mul (u, u, y, MPFR_RNDN);
- MPFR_ASSERTN (inexact == 0);
-
- /* Now, we need to subtract z/4... But it may underflow! */
- {
- mpfr_t zo4;
- mpfr_srcptr zz;
- MPFR_BLOCK_DECL (flags);
-
- if (MPFR_GET_EXP (u) > MPFR_GET_EXP (z) &&
- MPFR_GET_EXP (u) - MPFR_GET_EXP (z) > MPFR_PREC (u))
- {
- /* |z| < ulp(u)/2, therefore one can use z instead of z/4. */
- zz = z;
- }
- else
- {
- mpfr_init2 (zo4, MPFR_PREC (z));
- if (mpfr_div_2ui (zo4, z, 2, MPFR_RNDZ))
- {
- /* The division by 4 underflowed! */
- MPFR_ASSERTN (0); /* TODO... */
- }
- zz = zo4;
- }
-
- /* Let's recall that u = x*y/4 and zz = z/4 (or z if the
- following subtraction would give the same result). */
- MPFR_BLOCK (flags, inexact = mpfr_sub (s, u, zz, rnd_mode));
- /* u and zz have the same sign, so that an overflow
- is not possible. But an underflow is theoretically
- possible! */
- if (MPFR_UNDERFLOW (flags))
- {
- MPFR_ASSERTN (zz != z);
- MPFR_ASSERTN (0); /* TODO... */
- mpfr_clears (zo4, u, (mpfr_ptr) 0);
- }
- else
- {
- int inex2;
-
- if (zz != z)
- mpfr_clear (zo4);
- MPFR_GROUP_CLEAR (group);
- MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
- inex2 = mpfr_mul_2ui (s, s, 2, rnd_mode);
- if (inex2) /* overflow */
- {
- inexact = inex2;
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- }
- goto end;
- }
- }
- }
- else /* underflow: one has |xy| < 2^(emin-1). */
- {
- unsigned long scale = 0;
- mpfr_t scaled_z;
- mpfr_srcptr new_z;
- mpfr_exp_t diffexp;
- mpfr_prec_t pzs;
- int xy_underflows;
-
- /* Let's scale z so that ulp(z) > 2^emin and ulp(s) > 2^emin
- (the + 1 on MPFR_PREC (s) is necessary because the exponent
- of the result can be EXP(z) - 1). */
- diffexp = MPFR_GET_EXP (z) - __gmpfr_emin;
- pzs = MAX (MPFR_PREC (z), MPFR_PREC (s) + 1);
- if (diffexp <= pzs)
- {
- mpfr_uexp_t uscale;
- mpfr_t scaled_v;
- MPFR_BLOCK_DECL (flags);
-
- uscale = (mpfr_uexp_t) pzs - diffexp + 1;
- MPFR_ASSERTN (uscale > 0);
- MPFR_ASSERTN (uscale <= ULONG_MAX);
- scale = uscale;
- mpfr_init2 (scaled_z, MPFR_PREC (z));
- inexact = mpfr_mul_2ui (scaled_z, z, scale, MPFR_RNDN);
- MPFR_ASSERTN (inexact == 0); /* TODO: overflow case */
- new_z = scaled_z;
- /* Now we need to recompute u = xy * 2^scale. */
- MPFR_BLOCK (flags,
- if (MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
- {
- mpfr_init2 (scaled_v, MPFR_PREC (x));
- mpfr_mul_2ui (scaled_v, x, scale, MPFR_RNDN);
- mpfr_mul (u, scaled_v, y, MPFR_RNDN);
- }
- else
- {
- mpfr_init2 (scaled_v, MPFR_PREC (y));
- mpfr_mul_2ui (scaled_v, y, scale, MPFR_RNDN);
- mpfr_mul (u, x, scaled_v, MPFR_RNDN);
- });
- mpfr_clear (scaled_v);
- MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
- xy_underflows = MPFR_UNDERFLOW (flags);
- }
- else
- {
- new_z = z;
- xy_underflows = 1;
- }
-
- if (xy_underflows)
- {
- /* Let's replace xy by sign(xy) * 2^(emin-1). */
- MPFR_PREC (u) = MPFR_PREC_MIN;
- mpfr_setmin (u, __gmpfr_emin);
- MPFR_SET_SIGN (u, MPFR_MULT_SIGN (MPFR_SIGN (x),
- MPFR_SIGN (y)));
- }
-
- {
- MPFR_BLOCK_DECL (flags);
-
- MPFR_BLOCK (flags, inexact = mpfr_sub (s, u, new_z, rnd_mode));
- MPFR_GROUP_CLEAR (group);
- if (scale != 0)
- {
- int inex2;
-
- mpfr_clear (scaled_z);
- /* Here an overflow is theoretically possible, in which case
- the result may be wrong, hence the assert. An underflow
- is not possible, but let's check that anyway. */
- MPFR_ASSERTN (! MPFR_OVERFLOW (flags)); /* TODO... */
- MPFR_ASSERTN (! MPFR_UNDERFLOW (flags)); /* not possible */
- inex2 = mpfr_div_2ui (s, s, scale, MPFR_RNDN);
- /* FIXME: this seems incorrect. MPFR_RNDN -> rnd_mode?
- Also, handle the double rounding case:
- s / 2^scale = 2^(emin - 2) in MPFR_RNDN. */
- if (inex2) /* underflow */
- inexact = inex2;
- }
- }
-
- /* FIXME/TODO: I'm not sure that the following is correct.
- Check for possible spurious exceptions due to intermediate
- computations. */
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- goto end;
- }
- }
+ mpfr_t minus_z;
- inexact = mpfr_sub (s, u, z, rnd_mode);
- MPFR_GROUP_CLEAR (group);
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- end:
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_check_range (s, inexact, rnd_mode);
+ MPFR_ALIAS (minus_z, z, -MPFR_SIGN(z), MPFR_EXP(z));
+ return mpfr_fma (s, x, y, minus_z, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/fpif.c b/Build/source/libs/mpfr/mpfr-src/src/fpif.c
new file mode 100644
index 00000000000..7dd620ba7be
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/fpif.c
@@ -0,0 +1,651 @@
+/* mpfr_fpif -- Binary export & import of MPFR numbers
+ (floating-point interchange format)
+
+Copyright 2012-2017 Free Software Foundation, Inc.
+Contributed by Olivier Demengeon.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#if !defined (HAVE_BIG_ENDIAN) && !defined (HAVE_LITTLE_ENDIAN)
+#error "Endianness is unknown. Not supported yet."
+#endif
+
+/* The format is described as follows. Any multi-byte number is encoded
+ in little endian.
+
+ 1. We first store the precision p (this format is able to represent
+ any precision from 1 to 2^64 + 248).
+ Let B be the first byte (0 <= B <= 255).
+ * If B >= 8, the precision p is B-7.
+ Here, the condition is equivalent to 1 <= p <= 248.
+ * If B <= 7, the next B+1 bytes contain p-249.
+ Here, the condition is equivalent to 249 <= p <= 2^64 + 248.
+ We will use the following macros:
+ * MPFR_MAX_PRECSIZE = 7
+ * MPFR_MAX_EMBEDDED_PRECISION = 255 - 7 = 248
+
+ 2. Then we store the sign bit and exponent related information
+ (possibly a special value). We first have byte A = [seeeeeee],
+ where s is the sign bit and E = [eeeeeee] such that:
+ * If 0 <= E <= 94, then the exponent e is E-47 (-47 <= e <= 47).
+ * If 95 <= E <= 110, the exponent is stored in the next E-94 bytes
+ (1 to 16 bytes) in sign + absolute value representation.
+ * If 111 <= E <= 118, the exponent size S is stored in the next
+ E-110 bytes (1 to 8), then the exponent itself is stored in the
+ next S bytes. [Not implemented yet]
+ * If 119 <= E <= 127, we have a special value:
+ E = 119 (MPFR_KIND_ZERO) for a signed zero;
+ E = 120 (MPFR_KIND_INF) for a signed infinity;
+ E = 121 (MPFR_KIND_NAN) for NaN.
+
+ 3. Then we store the significand (for regular values).
+
+ The sign bit is preserved by the import/export functions, even for NaN.
+
+ Note: When a size is stored, it must be minimal, i.e. a number cannot
+ start with a null byte. Otherwise the import may fail.
+*/
+
+#define MPFR_MAX_PRECSIZE 7
+#define MPFR_MAX_EMBEDDED_PRECISION (255 - MPFR_MAX_PRECSIZE)
+
+#define MPFR_KIND_ZERO 119
+#define MPFR_KIND_INF 120
+#define MPFR_KIND_NAN 121
+#define MPFR_MAX_EMBEDDED_EXPONENT 47
+#define MPFR_EXTERNAL_EXPONENT 94
+
+/* Begin: Low level helper functions */
+
+/* storage must have an unsigned type */
+#define COUNT_NB_BYTE(storage, size) \
+ do \
+ { \
+ (storage) >>= 8; \
+ (size)++; \
+ } \
+ while ((storage) != 0)
+
+#define ALLOC_RESULT(buffer, buffer_size, wanted_size) \
+ do \
+ { \
+ if ((buffer) == NULL || *(buffer_size) < (wanted_size)) \
+ { \
+ (buffer) = (unsigned char *) mpfr_reallocate_func \
+ ((buffer), *(buffer_size), (wanted_size)); \
+ if ((buffer) == NULL) \
+ { \
+ *(buffer_size) = 0; \
+ return NULL; \
+ } \
+ } \
+ *(buffer_size) = (wanted_size); \
+ } \
+ while (0)
+
+/*
+ * size in byte of a MPFR number in a binary object of a variable size
+ */
+#define MAX_VARIABLE_STORAGE(exponent_size, precision) \
+ ((size_t)(((precision) >> 3) + (exponent_size) + \
+ ((precision) > 248 ? sizeof(mpfr_prec_t) : 0) + 3))
+
+/* copy in result[] the values in data[] with a different endianness,
+ where data_size might be smaller than data_max_size, so that we only
+ copy data_size bytes from the end of data[]. */
+static void
+#if defined (HAVE_BIG_ENDIAN)
+putLittleEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#elif defined (HAVE_LITTLE_ENDIAN)
+putBigEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#endif
+{
+ size_t j;
+
+ MPFR_ASSERTD (data_size <= data_max_size);
+ for (j = 0; j < data_size; j++)
+ result[j] = data[data_max_size - j - 1];
+}
+
+/* copy in result[] the values in data[] with the same endianness */
+static void
+#if defined (HAVE_BIG_ENDIAN)
+putBigEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#elif defined (HAVE_LITTLE_ENDIAN)
+putLittleEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#endif
+{
+ MPFR_ASSERTD (data_size <= data_max_size);
+ memcpy (result, data, data_size);
+}
+
+/* copy in result[] the values in data[] with a different endianness;
+ the data are written at the end of the result[] buffer (if
+ data_size < data_max_size, the first bytes of result[] are
+ left untouched). */
+static void
+#if defined (HAVE_BIG_ENDIAN)
+getLittleEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#elif defined (HAVE_LITTLE_ENDIAN)
+getBigEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#endif
+{
+ size_t j;
+
+ MPFR_ASSERTD (data_size <= data_max_size);
+ for (j = 0; j < data_size; j++)
+ result[data_max_size - j - 1] = data[j];
+}
+
+/* copy in result[] the values in data[] with the same endianness */
+static void
+#if defined (HAVE_BIG_ENDIAN)
+getBigEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#elif defined (HAVE_LITTLE_ENDIAN)
+getLittleEndianData (unsigned char *result, unsigned char *data,
+ size_t data_max_size, size_t data_size)
+#endif
+{
+ MPFR_ASSERTD (data_size <= data_max_size);
+ memcpy (result, data, data_size);
+}
+
+/* End: Low level helper functions */
+
+/* Internal Function */
+/*
+ * buffer : OUT : store the precision in binary format, can be null
+ * (may be reallocated if too small)
+ * buffer_size : IN/OUT : size of the buffer => size used in the buffer
+ * precision : IN : precision to store
+ * return pointer to a buffer storing the precision in binary format
+ */
+static unsigned char *
+mpfr_fpif_store_precision (unsigned char *buffer, size_t *buffer_size,
+ mpfr_prec_t precision)
+{
+ unsigned char *result;
+ size_t size_precision;
+
+ MPFR_ASSERTD (precision >= 1);
+ size_precision = 0;
+
+ if (precision > MPFR_MAX_EMBEDDED_PRECISION)
+ {
+ mpfr_uprec_t copy_precision;
+
+ copy_precision = precision - (MPFR_MAX_EMBEDDED_PRECISION + 1);
+ COUNT_NB_BYTE(copy_precision, size_precision);
+ }
+
+ result = buffer;
+ ALLOC_RESULT(result, buffer_size, size_precision + 1);
+
+ if (precision > MPFR_MAX_EMBEDDED_PRECISION)
+ {
+ result[0] = size_precision - 1;
+ precision -= (MPFR_MAX_EMBEDDED_PRECISION + 1);
+ putLittleEndianData (result + 1, (unsigned char *) &precision,
+ sizeof(mpfr_prec_t), size_precision);
+ }
+ else
+ result[0] = precision + MPFR_MAX_PRECSIZE;
+
+ return result;
+}
+
+#define BUFFER_SIZE 8
+
+/*
+ * fh : IN : file handler
+ * return the precision stored in the binary buffer, 0 in case of error
+ */
+static mpfr_prec_t
+mpfr_fpif_read_precision_from_file (FILE *fh)
+{
+ mpfr_prec_t precision;
+ size_t precision_size;
+ unsigned char buffer[BUFFER_SIZE];
+
+ if (fh == NULL)
+ return 0;
+
+ if (fread (buffer, 1, 1, fh) != 1)
+ return 0;
+
+ precision_size = buffer[0];
+ if (precision_size > MPFR_MAX_PRECSIZE)
+ return precision_size - MPFR_MAX_PRECSIZE;
+
+ precision_size++;
+ MPFR_ASSERTD (precision_size <= BUFFER_SIZE);
+
+ /* Read the precision in little-endian format. */
+ if (fread (buffer, precision_size, 1, fh) != 1)
+ return 0;
+
+ while (precision_size > sizeof(mpfr_prec_t))
+ {
+ if (buffer[precision_size-1] != 0)
+ return 0; /* the read precision doesn't fit in a mpfr_prec_t */
+ precision_size--;
+ }
+
+ if (precision_size == sizeof(mpfr_prec_t) &&
+ buffer[precision_size-1] >= 0x80)
+ return 0; /* the read precision doesn't fit in a mpfr_prec_t */
+
+ precision = 0; /* to pad with 0's if data_size < data_max_size */
+
+ /* On big-endian machines, the data must be copied at the end of the
+ precision object in the memory; thus data_max_size (3rd argument)
+ must be sizeof(mpfr_prec_t). */
+ getLittleEndianData ((unsigned char *) &precision, buffer,
+ sizeof(mpfr_prec_t), precision_size);
+
+ return precision + (MPFR_MAX_EMBEDDED_PRECISION + 1);
+}
+
+/*
+ * buffer : OUT : store the kind of the MPFR number x, its sign, the size of
+ * its exponent and its exponent value in a binary format,
+ * can be null (may be reallocated if too small)
+ * buffer_size : IN/OUT : size of the buffer => size used in the buffer
+ * x : IN : MPFR number
+ * return pointer to a buffer storing the kind of the MPFR number x, its sign,
+ * the size of its exponent and its exponent value in a binary format,
+ */
+/* TODO
+ * Exponents that use more than 16 bytes are not managed (not an issue
+ * until one has integer types larger than 128 bits).
+ */
+static unsigned char*
+mpfr_fpif_store_exponent (unsigned char *buffer, size_t *buffer_size, mpfr_t x)
+{
+ unsigned char *result;
+ mpfr_uexp_t uexp;
+ size_t exponent_size;
+
+ exponent_size = 0;
+
+ if (MPFR_IS_PURE_FP (x))
+ {
+ mpfr_exp_t exponent = MPFR_GET_EXP (x);
+
+ if (exponent > MPFR_MAX_EMBEDDED_EXPONENT ||
+ exponent < -MPFR_MAX_EMBEDDED_EXPONENT)
+ {
+ mpfr_uexp_t copy_exponent, exp_sign_bit;
+
+ uexp = SAFE_ABS (mpfr_uexp_t, exponent)
+ - MPFR_MAX_EMBEDDED_EXPONENT;
+
+ /* Shift uexp to take the sign bit of the exponent into account.
+ Because of constraints on the valid exponents, this cannot
+ overflow (check with an MPFR_ASSERTD). */
+ copy_exponent = uexp << 1;
+ MPFR_ASSERTD (copy_exponent > uexp);
+ COUNT_NB_BYTE(copy_exponent, exponent_size);
+ MPFR_ASSERTN (exponent_size <= 16); /* see TODO */
+
+ /* Sign bit of the exponent. */
+ exp_sign_bit = (mpfr_uexp_t) 1 << (8 * exponent_size - 1);
+ MPFR_ASSERTD (uexp < exp_sign_bit);
+ if (exponent < 0)
+ uexp |= exp_sign_bit;
+ }
+ else
+ uexp = exponent + MPFR_MAX_EMBEDDED_EXPONENT;
+ }
+
+ result = buffer;
+ ALLOC_RESULT(result, buffer_size, exponent_size + 1);
+
+ if (MPFR_IS_PURE_FP (x))
+ {
+ if (exponent_size == 0)
+ result[0] = uexp;
+ else
+ {
+ result[0] = MPFR_EXTERNAL_EXPONENT + exponent_size;
+
+ putLittleEndianData (result + 1, (unsigned char *) &uexp,
+ sizeof(mpfr_exp_t), exponent_size);
+ }
+ }
+ else if (MPFR_IS_ZERO (x))
+ result[0] = MPFR_KIND_ZERO;
+ else if (MPFR_IS_INF (x))
+ result[0] = MPFR_KIND_INF;
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_NAN (x));
+ result[0] = MPFR_KIND_NAN;
+ }
+
+ /* Set the sign, even for NaN. */
+ if (MPFR_IS_NEG (x))
+ result[0] |= 0x80;
+
+ return result;
+}
+
+/*
+ * x : OUT : MPFR number extracted from the binary buffer
+ * fh : IN : file handler
+ * return 0 if successful
+ */
+/* TODO
+ * Exponents that use more than 16 bytes are not managed (this is not
+ * an issue if the data were written by MPFR with mpfr_exp_t not larger
+ * than 128 bits).
+ */
+static int
+mpfr_fpif_read_exponent_from_file (mpfr_t x, FILE * fh)
+{
+ mpfr_exp_t exponent;
+ mpfr_uexp_t uexp;
+ size_t exponent_size;
+ int sign;
+ unsigned char buffer[sizeof(mpfr_exp_t)];
+
+ if (fh == NULL)
+ return 1;
+
+ if (fread (buffer, 1, 1, fh) != 1)
+ return 1;
+
+ /* sign value that can be used with MPFR_SET_SIGN,
+ mpfr_set_zero and mpfr_set_inf */
+ sign = (buffer[0] & 0x80) ? MPFR_SIGN_NEG : MPFR_SIGN_POS;
+ /* Set the sign, even for NaN. */
+ MPFR_SET_SIGN (x, sign);
+
+ exponent = buffer[0] & 0x7F;
+ exponent_size = 1;
+
+ if (exponent > MPFR_EXTERNAL_EXPONENT && exponent < MPFR_KIND_ZERO)
+ {
+ mpfr_uexp_t exp_sign_bit;
+
+ exponent_size = exponent - MPFR_EXTERNAL_EXPONENT;
+
+ /* A failure is acceptable when the exponent starts with leading zeros,
+ even if it would fit in mpfr_exp_t (see format description). */
+ if (MPFR_UNLIKELY (exponent_size > 16 /* see TODO */ ||
+ exponent_size > sizeof(mpfr_exp_t)))
+ return 1;
+
+ if (MPFR_UNLIKELY (fread (buffer, exponent_size, 1, fh) != 1))
+ return 1;
+
+ uexp = 0;
+ getLittleEndianData ((unsigned char *) &uexp, buffer,
+ sizeof(mpfr_exp_t), exponent_size);
+
+ /* Sign bit of the exponent. */
+ exp_sign_bit = uexp & ((mpfr_uexp_t) 1 << (8 * exponent_size - 1));
+
+ uexp &= ~exp_sign_bit;
+ uexp += MPFR_MAX_EMBEDDED_EXPONENT;
+ if (MPFR_UNLIKELY (uexp > MPFR_EMAX_MAX && uexp > -MPFR_EMIN_MIN))
+ return 1;
+
+ exponent = exp_sign_bit ? - (mpfr_exp_t) uexp : (mpfr_exp_t) uexp;
+ if (MPFR_UNLIKELY (! MPFR_EXP_IN_RANGE (exponent)))
+ return 1;
+ MPFR_SET_EXP (x, exponent);
+
+ exponent_size++;
+ }
+ else if (exponent == MPFR_KIND_ZERO)
+ MPFR_SET_ZERO (x);
+ else if (exponent == MPFR_KIND_INF)
+ MPFR_SET_INF (x);
+ else if (exponent == MPFR_KIND_NAN)
+ MPFR_SET_NAN (x);
+ else if (exponent <= MPFR_EXTERNAL_EXPONENT)
+ {
+ exponent -= MPFR_MAX_EMBEDDED_EXPONENT;
+ if (MPFR_UNLIKELY (! MPFR_EXP_IN_RANGE (exponent)))
+ return 1;
+ MPFR_SET_EXP (x, exponent);
+ }
+ else
+ return 1;
+
+ return 0;
+}
+
+/*
+ * buffer : OUT : store the limb of the MPFR number x in a binary format,
+ * can be null (may be reallocated if too small)
+ * buffer_size : IN/OUT : size of the buffer => size used in the buffer
+ * x : IN : MPFR number
+ * return pointer to a buffer storing the limb of the MPFR number x in a binary
+ * format
+ */
+static unsigned char*
+mpfr_fpif_store_limbs (unsigned char *buffer, size_t *buffer_size, mpfr_t x)
+{
+ unsigned char *result;
+ mpfr_prec_t precision;
+ size_t nb_byte;
+ size_t nb_limb, mp_bytes_per_limb;
+ size_t nb_partial_byte;
+ size_t i, j;
+
+ precision = mpfr_get_prec (x);
+ nb_byte = (precision + 7) >> 3;
+ mp_bytes_per_limb = mp_bits_per_limb >> 3;
+ nb_partial_byte = nb_byte % mp_bytes_per_limb;
+ nb_limb = (nb_byte + mp_bytes_per_limb - 1) / mp_bytes_per_limb;
+
+ result = buffer;
+ ALLOC_RESULT(result, buffer_size, nb_byte);
+
+ putBigEndianData (result, (unsigned char*) MPFR_MANT(x),
+ sizeof(mp_limb_t), nb_partial_byte);
+ for (i = nb_partial_byte, j = (nb_partial_byte == 0) ? 0 : 1; j < nb_limb;
+ i += mp_bytes_per_limb, j++)
+ putLittleEndianData (result + i, (unsigned char*) (MPFR_MANT(x) + j),
+ sizeof(mp_limb_t), sizeof(mp_limb_t));
+
+ return result;
+}
+
+/*
+ * x : OUT : MPFR number extracted from the binary buffer, should have the same
+ * precision than the number in the binary format
+ * buffer : IN : limb of the MPFR number x in a binary format,
+ * buffer_size : IN/OUT : size of the buffer => size used in the buffer
+ * return 0 if successful
+ */
+static int
+mpfr_fpif_read_limbs (mpfr_t x, unsigned char *buffer, size_t *buffer_size)
+{
+ mpfr_prec_t precision;
+ size_t nb_byte;
+ size_t mp_bytes_per_limb;
+ size_t nb_partial_byte;
+ size_t i, j;
+
+ precision = mpfr_get_prec (x);
+ nb_byte = (precision + 7) >> 3;
+ mp_bytes_per_limb = mp_bits_per_limb >> 3;
+ nb_partial_byte = nb_byte % mp_bytes_per_limb;
+
+ if ((buffer == NULL) || (*buffer_size < nb_byte))
+ {
+ *buffer_size = 0;
+ return 1;
+ }
+ *buffer_size = nb_byte;
+
+ if (nb_partial_byte > 0)
+ {
+ memset (MPFR_MANT(x), 0, sizeof(mp_limb_t));
+ getBigEndianData ((unsigned char*) MPFR_MANT(x), buffer,
+ sizeof(mp_limb_t), nb_partial_byte);
+ }
+ for (i = nb_partial_byte, j = (nb_partial_byte == 0) ? 0 : 1; i < nb_byte;
+ i += mp_bytes_per_limb, j++)
+ getLittleEndianData ((unsigned char*) (MPFR_MANT(x) + j), buffer + i,
+ sizeof(mp_limb_t), sizeof(mp_limb_t));
+
+ return 0;
+}
+
+/* External Function */
+/*
+ * fh : IN : file hander
+ * x : IN : MPFR number to put in the file
+ * return 0 if successful
+ */
+int
+mpfr_fpif_export (FILE *fh, mpfr_t x)
+{
+ int status;
+ unsigned char *buf;
+ unsigned char *bufResult;
+ size_t used_size, buf_size;
+
+ if (fh == NULL)
+ return -1;
+
+ buf_size = MAX_VARIABLE_STORAGE(sizeof(mpfr_exp_t), mpfr_get_prec (x));
+ buf = (unsigned char*) mpfr_allocate_func (buf_size);
+ if (buf == NULL)
+ return -1;
+
+ used_size = buf_size;
+ buf = mpfr_fpif_store_precision (buf, &used_size, mpfr_get_prec (x));
+ used_size > buf_size ? buf_size = used_size : 0;
+ status = fwrite (buf, used_size, 1, fh);
+ if (status != 1)
+ {
+ mpfr_free_func (buf, buf_size);
+ return -1;
+ }
+ used_size = buf_size;
+ bufResult = mpfr_fpif_store_exponent (buf, &used_size, x);
+ if (bufResult == NULL)
+ {
+ mpfr_free_func (buf, buf_size);
+ return -1;
+ }
+ buf = bufResult;
+ used_size > buf_size ? buf_size = used_size : 0;
+ status = fwrite (buf, used_size, 1, fh);
+ if (status != 1)
+ {
+ mpfr_free_func (buf, buf_size);
+ return -1;
+ }
+
+ if (mpfr_regular_p (x))
+ {
+ used_size = buf_size;
+ buf = mpfr_fpif_store_limbs (buf, &used_size, x);
+ used_size > buf_size ? buf_size = used_size : 0;
+ status = fwrite (buf, used_size, 1, fh);
+ if (status != 1)
+ {
+ mpfr_free_func (buf, buf_size);
+ return -1;
+ }
+ }
+
+ mpfr_free_func (buf, buf_size);
+ return 0;
+}
+
+/*
+ * x : IN/OUT : MPFR number extracted from the file, its precision is reset to
+ * be able to hold the number
+ * fh : IN : file hander
+ * Return 0 if the import was successful.
+ */
+int
+mpfr_fpif_import (mpfr_t x, FILE *fh)
+{
+ int status;
+ mpfr_prec_t precision;
+ unsigned char *buffer;
+ size_t used_size;
+
+ precision = mpfr_fpif_read_precision_from_file (fh);
+ if (precision == 0) /* precision = 0 means an error */
+ return -1;
+ if (precision > MPFR_PREC_MAX)
+ return -1;
+ MPFR_STAT_STATIC_ASSERT (MPFR_PREC_MIN == 1); /* as specified */
+ mpfr_set_prec (x, precision);
+
+ status = mpfr_fpif_read_exponent_from_file (x, fh);
+ if (status != 0)
+ {
+ mpfr_set_nan (x);
+ return -1;
+ }
+
+ /* Warning! The significand of x is not set yet. Thus use MPFR_IS_SINGULAR
+ for the test. */
+ if (!MPFR_IS_SINGULAR (x))
+ {
+ /* For portability, we need to consider bytes with only 8 significant
+ bits in the interchange format. That's OK because CHAR_BIT >= 8.
+ But the implementation is currently not clear when CHAR_BIT > 8.
+ This may have never been tested. For safety, require CHAR_BIT == 8,
+ and test/adapt the code if this ever fails. */
+ MPFR_STAT_STATIC_ASSERT (CHAR_BIT == 8);
+ MPFR_STAT_STATIC_ASSERT ((MPFR_PREC_MAX + 7) >> 3 <= (size_t) -1);
+ used_size = (precision + 7) >> 3; /* ceil(precision/8) */
+ buffer = (unsigned char*) mpfr_allocate_func (used_size);
+ if (buffer == NULL)
+ {
+ mpfr_set_nan (x);
+ return -1;
+ }
+ status = fread (buffer, used_size, 1, fh);
+ if (status != 1)
+ {
+ mpfr_free_func (buffer, used_size);
+ mpfr_set_nan (x);
+ return -1;
+ }
+ status = mpfr_fpif_read_limbs (x, buffer, &used_size);
+ mpfr_free_func (buffer, used_size);
+ if (status != 0)
+ {
+ mpfr_set_nan (x);
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/frac.c b/Build/source/libs/mpfr/mpfr-src/src/frac.c
index 754166231da..f6bdd1bddee 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/frac.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/frac.c
@@ -108,9 +108,9 @@ mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
t0 = tn - un;
tp = MPFR_MANT(t);
if (sh == 0)
- MPN_COPY_DECR(tp + t0, up, un + 1);
+ mpn_copyd (tp + t0, up, un + 1);
else /* warning: un may be 0 here */
- tp[tn] = k | ((un) ? mpn_lshift (tp + t0, up, un, sh) : (mp_limb_t) 0);
+ tp[tn] = k | ((un) ? mpn_lshift (tp + t0, up, un, sh) : MPFR_LIMB_ZERO);
if (t0 > 0)
MPN_ZERO(tp, t0);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/free_cache.c b/Build/source/libs/mpfr/mpfr-src/src/free_cache.c
index 91d37e86e7c..dcc5b047838 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/free_cache.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/free_cache.c
@@ -1,4 +1,4 @@
-/* mpfr_free_cache - Free the cache used by MPFR for internal consts.
+/* mpfr_free_cache... - Free cache/pool memory used by MPFR.
Copyright 2004-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -22,27 +22,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-#if 0
+/* Theses caches may be global to all threads or local to the current one. */
static void
-free_l2b (void)
-{
- int i, b;
-
- for (b = 2; b <= BASE_MAX; b++)
- for (i = 0; i < 2; i++)
- {
- mpfr_ptr p = __gmpfr_l2b[b-2][i];
- if (p != NULL)
- {
- mpfr_clear (p);
- (*__gmp_free_func) (p, sizeof (mpfr_t));
- }
- }
-}
-#endif
-
-void
-mpfr_free_cache (void)
+mpfr_free_const_caches (void)
{
#ifndef MPFR_USE_LOGGING
mpfr_clear_cache (__gmpfr_cache_const_pi);
@@ -55,5 +37,56 @@ mpfr_free_cache (void)
#endif
mpfr_clear_cache (__gmpfr_cache_const_euler);
mpfr_clear_cache (__gmpfr_cache_const_catalan);
- /* free_l2b (); */
+}
+
+/* Theses caches/pools are always local to a thread. */
+static void
+mpfr_free_local_cache (void)
+{
+ /* Before freeing the mpz_t pool, we need to free any cache of
+ mpz_t numbers, since freeing such a cache may add entries to
+ the mpz_t pool. */
+ mpfr_bernoulli_freecache ();
+ mpfr_free_pool ();
+}
+
+void
+mpfr_free_cache (void)
+{
+ mpfr_free_local_cache ();
+ mpfr_free_const_caches ();
+}
+
+void
+mpfr_free_cache2 (mpfr_free_cache_t way)
+{
+ if ((unsigned int) way & MPFR_FREE_LOCAL_CACHE)
+ {
+ mpfr_free_local_cache ();
+#if !defined (WANT_SHARED_CACHE)
+ mpfr_free_const_caches ();
+#endif
+ }
+ if ((unsigned int) way & MPFR_FREE_GLOBAL_CACHE)
+ {
+#if defined (WANT_SHARED_CACHE)
+ mpfr_free_const_caches ();
+#endif
+ }
+}
+
+/* Function an application should call before mp_set_memory_functions().
+ This is currently equivalent to freeing the caches (and pools) since
+ they are allocated with GMP's current allocator. But this might change
+ in the future to avoid the drawback of having to free the caches just
+ because the allocators are changed: the caches could optionally be
+ allocated with malloc().
+ This function returns 0 in case of success, non-zero in case of error.
+ Errors are currently not possible. But let's avoid a prototype change
+ in the future, in case errors would be possible. */
+int
+mpfr_mp_memory_cleanup (void)
+{
+ mpfr_free_cache ();
+ return 0;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/frexp.c b/Build/source/libs/mpfr/mpfr-src/src/frexp.c
index 9512e9f8ca6..383c627a8d7 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/frexp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/frexp.c
@@ -26,7 +26,7 @@ int
mpfr_frexp (mpfr_exp_t *exp, mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
{
int inex;
- unsigned int saved_flags = __gmpfr_flags;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
MPFR_BLOCK_DECL (flags);
MPFR_LOG_FUNC
diff --git a/Build/source/libs/mpfr/mpfr-src/src/gamma.c b/Build/source/libs/mpfr/mpfr-src/src/gamma.c
index c9f52d0523e..2cebfee8ef5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/gamma.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/gamma.c
@@ -27,7 +27,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "lngamma.c"
#undef IS_GAMMA
-/* return a sufficient precision such that 2-x is exact, assuming x < 0 */
+/* return a sufficient precision such that 2-x is exact, assuming x < 0
+ and x is not an integer */
static mpfr_prec_t
mpfr_gamma_2_minus_x_exact (mpfr_srcptr x)
{
@@ -38,13 +39,16 @@ mpfr_gamma_2_minus_x_exact (mpfr_srcptr x)
carry can occur, or ULP(y) > 2, and we need w >= EXP(y)-1:
(a) if EXP(y) <= 1, w = PREC(y) + 2 - EXP(y)
(b) if EXP(y) > 1 and EXP(y)-PREC(y) <= 1, w = PREC(y) + 1
- (c) if EXP(y) > 1 and EXP(y)-PREC(y) > 1, w = EXP(y) - 1 */
+ (c) if EXP(y) > 1 and EXP(y)-PREC(y) > 1, w = EXP(y) - 1.
+
+ Note: case (c) cannot happen in practice since this would imply that
+ y is integer, thus x is negative integer */
return (MPFR_GET_EXP(x) <= 1) ? MPFR_PREC(x) + 2 - MPFR_GET_EXP(x)
- : ((MPFR_GET_EXP(x) <= MPFR_PREC(x) + 1) ? MPFR_PREC(x) + 1
- : MPFR_GET_EXP(x) - 1);
+ : MPFR_PREC(x) + 1;
}
-/* return a sufficient precision such that 1-x is exact, assuming x < 1 */
+/* return a sufficient precision such that 1-x is exact, assuming x < 1
+ and x is not an integer */
static mpfr_prec_t
mpfr_gamma_1_minus_x_exact (mpfr_srcptr x)
{
@@ -52,10 +56,9 @@ mpfr_gamma_1_minus_x_exact (mpfr_srcptr x)
return MPFR_PREC(x) - MPFR_GET_EXP(x);
else if (MPFR_GET_EXP(x) <= 0)
return MPFR_PREC(x) + 1 - MPFR_GET_EXP(x);
- else if (MPFR_PREC(x) >= MPFR_GET_EXP(x))
+ else /* necessarily MPFR_PREC(x) > MPFR_GET_EXP(x) since otherwise
+ x would be an integer */
return MPFR_PREC(x) + 1;
- else
- return MPFR_GET_EXP(x);
}
/* returns a lower bound of the number of significant bits of n!
@@ -72,6 +75,8 @@ bits_fac (unsigned long n)
unsigned long r, k;
MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ASSERTD (n >= 1);
+
MPFR_SAVE_EXPO_MARK (expo);
mpfr_init2 (x, 38);
mpfr_init2 (y, 38);
@@ -84,9 +89,14 @@ bits_fac (unsigned long n)
mpfr_sqrt (y, y, MPFR_RNDZ);
mpfr_mul (x, x, y, MPFR_RNDZ);
mpfr_log2 (x, x, MPFR_RNDZ);
- r = mpfr_get_ui (x, MPFR_RNDU);
+ r = mpfr_get_ui (x, MPFR_RNDU); /* lower bound on ceil(x) */
for (k = 2; k <= n; k *= 2)
- r -= n / k;
+ {
+ /* Note: the approximation is accurate enough so that the
+ subtractions do not wrap. */
+ MPFR_ASSERTD (r >= n / k);
+ r -= n / k;
+ }
mpfr_clear (x);
mpfr_clear (y);
MPFR_SAVE_EXPO_FREE (expo);
@@ -143,19 +153,30 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD(MPFR_IS_ZERO(x));
MPFR_SET_INF(gamma);
MPFR_SET_SAME_SIGN(gamma, x);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0); /* exact */
}
}
- /* Check for tiny arguments, where gamma(x) ~ 1/x - euler + ....
+ /* Check for tiny arguments, where gamma(x) ~ 1/x - euler + ... can be
+ approximated by 1/x, with some error term ~= - euler.
+ We need to make sure that there are no breakpoints (discontinuity
+ points of the rounding function) between gamma(x) and 1/x (included),
+ where the possible breakpoints (for all rounding modes) are the numbers
+ that fit on PREC(gamma)+1 bits. There will be a special case when |x|
+ is a power of two, since such values are breakpoints. We will choose n
+ minimum such that x fits on n bits and the breakpoints fit on n+1 bits,
+ thus
+ n = MAX(MPFR_PREC(x), MPFR_PREC(gamma)).
We know from "Bound on Runs of Zeros and Ones for Algebraic Functions",
Proceedings of Arith15, T. Lang and J.-M. Muller, 2001, that the maximal
- number of consecutive zeroes or ones after the round bit is n-1 for an
- input of n bits. But we need a more precise lower bound. Assume x has
- n bits, and 1/x is near a floating-point number y of n+1 bits. We can
- write x = X*2^e, y = Y/2^f with X, Y integers of n and n+1 bits.
- Thus X*Y^2^(e-f) is near from 1, i.e., X*Y is near from 2^(f-e).
+ number of consecutive zeroes or ones after the round bit for 1/x is n-1
+ for an input x of n bits [this is an actually much older result!].
+ But we need a more precise lower bound. Assume that 1/x is near a
+ breakpoint y. From the definition of n, the input x fits on n bits
+ and the breakpoint y fits on of n+1 bits. We can write x = X*2^e,
+ y = Y/2^f with X, Y integers of n and n+1 bits respectively.
+ Thus X*Y^2^(e-f) is near 1, i.e., X*Y is near the integer 2^(f-e).
Two cases can happen:
(i) either X*Y is exactly 2^(f-e), but this can happen only if X and Y
are themselves powers of two, i.e., x is a power of two;
@@ -163,13 +184,21 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
|xy-1| >= 2^(e-f), or |y-1/x| >= 2^(e-f)/x = 2^(-f)/X >= 2^(-f-n).
Since ufp(y) = 2^(n-f) [ufp = unit in first place], this means
that the distance |y-1/x| >= 2^(-2n) ufp(y).
- Now assuming |gamma(x)-1/x| <= 1, which is true for x <= 1,
- if 2^(-2n) ufp(y) >= 2, the error is at most 2^(-2n-1) ufp(y),
- and round(1/x) with precision >= 2n+2 gives the correct result.
- If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
- A sufficient condition is thus EXP(x) + 2 <= -2 MAX(PREC(x),PREC(Y)).
+ Now, assuming |gamma(x)-1/x| < 1, which is true for 0 < x <= 1,
+ if 2^(-2n) ufp(y) >= 1, then gamma(x) and 1/x round in the same
+ way, so that rounding 1/x gives the correct result and correct
+ (nonzero) ternary value.
+ If x < 2^E, then y >= 2^(-E), thus ufp(y) >= 2^(-E).
+ A sufficient condition is thus EXP(x) <= -2n, where
+ n = MAX(MPFR_PREC(x), MPFR_PREC(gamma)).
*/
- if (MPFR_GET_EXP (x) + 2
+ /* TODO: The above proof uses the same precision for input and output.
+ Without this assumption, one might obtain a bound like
+ PREC(x) + PREC(y) instead of 2 MAX(PREC(x),PREC(y)). */
+ /* TODO: Handle the very small arguments that do not satisfy the condition,
+ by using the approximation 1/x - euler and a Ziv loop. Otherwise, after
+ some tests, even Gamma(1+x)/x would be faster than the generic code. */
+ if (MPFR_GET_EXP (x)
<= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(gamma)))
{
int sign = MPFR_SIGN (x); /* retrieve sign before possible override */
@@ -187,7 +216,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_powerof2_raw (x);
MPFR_BLOCK (flags, inex = mpfr_ui_div (gamma, 1, x, rnd_mode));
- if (inex == 0) /* x is a power of two */
+ if (inex == 0) /* |x| is a power of two */
{
/* return RND(1/x - euler) = RND(+/- 2^k - eps) with eps > 0 */
if (rnd_mode == MPFR_RNDN || MPFR_IS_LIKE_RNDU (rnd_mode, sign))
@@ -239,6 +268,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
unsigned long int u;
mpfr_prec_t p = MPFR_PREC(gamma);
u = mpfr_get_ui (x, MPFR_RNDN);
+ MPFR_ASSERTD (u >= 2);
if (u < 44787929UL && bits_fac (u - 1) <= p + (rnd_mode == MPFR_RNDN))
/* bits_fac: lower bound on the number of bits of m,
where gamma(x) = (u-1)! = m*2^e with m odd. */
@@ -256,26 +286,31 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
>= 2 * (x/e)^x / x for x >= 1 */
if (compared > 0)
{
- mpfr_t yp;
+ mpfr_t yp, zp;
mpfr_exp_t expxp;
MPFR_BLOCK_DECL (flags);
+ MPFR_GROUP_DECL (group);
+
+ /* quick test for the default exponent range */
+ if (mpfr_get_emax () >= 1073741823UL && MPFR_GET_EXP(x) <= 25)
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_gamma_aux (gamma, x, rnd_mode);
+ }
+ MPFR_GROUP_INIT_3 (group, 53, xp, yp, zp);
/* 1/e rounded down to 53 bits */
-#define EXPM1_STR "0.010111100010110101011000110110001011001110111100111"
- mpfr_init2 (xp, 53);
- mpfr_init2 (yp, 53);
- mpfr_set_str_binary (xp, EXPM1_STR);
- mpfr_mul (xp, x, xp, MPFR_RNDZ);
+ mpfr_set_str_binary (zp,
+ "0.010111100010110101011000110110001011001110111100111");
+ mpfr_mul (xp, x, zp, MPFR_RNDZ);
mpfr_sub_ui (yp, x, 2, MPFR_RNDZ);
mpfr_pow (xp, xp, yp, MPFR_RNDZ); /* (x/e)^(x-2) */
- mpfr_set_str_binary (yp, EXPM1_STR);
- mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^(x-1) */
- mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^x */
+ mpfr_mul (xp, xp, zp, MPFR_RNDZ); /* x^(x-2) / e^(x-1) */
+ mpfr_mul (xp, xp, zp, MPFR_RNDZ); /* x^(x-2) / e^x */
mpfr_mul (xp, xp, x, MPFR_RNDZ); /* lower bound on x^(x-1) / e^x */
MPFR_BLOCK (flags, mpfr_mul_2ui (xp, xp, 1, MPFR_RNDZ));
expxp = MPFR_GET_EXP (xp);
- mpfr_clear (xp);
- mpfr_clear (yp);
+ MPFR_GROUP_CLEAR (group);
MPFR_SAVE_EXPO_FREE (expo);
return MPFR_OVERFLOW (flags) || expxp > __gmpfr_emax ?
mpfr_overflow (gamma, rnd_mode, 1) :
@@ -316,8 +351,8 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
w += 17; /* to get tmp2 small enough */
mpfr_set_prec (tmp, w);
mpfr_set_prec (tmp2, w);
- ck = mpfr_ui_sub (tmp, 2, x, MPFR_RNDN);
- MPFR_ASSERTD (ck == 0); (void) ck; /* use ck to avoid a warning */
+ MPFR_DBGRES (ck = mpfr_ui_sub (tmp, 2, x, MPFR_RNDN));
+ MPFR_ASSERTD (ck == 0); /* tmp = 2-x exactly */
mpfr_const_pi (tmp2, MPFR_RNDN);
mpfr_mul (tmp2, tmp2, tmp, MPFR_RNDN); /* Pi*(2-x) */
mpfr_sin (tmp, tmp2, MPFR_RNDN); /* sin(Pi*(2-x)) */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/gamma_inc.c b/Build/source/libs/mpfr/mpfr-src/src/gamma_inc.c
new file mode 100644
index 00000000000..1271d906756
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/gamma_inc.c
@@ -0,0 +1,504 @@
+/* mpfr_gamma_inc -- incomplete gamma function
+
+Copyright 2016-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The incomplete gamma function is defined for x >= 0 and a not a negative
+ integer by:
+
+ gamma_inc(a,x) := Gamma(a,x) = int(t^(a-1) * exp(-t), t=x..infinity)
+
+ = Gamma(a) - gamma(a,x) with:
+
+ gamma(a,x) = int(t^(a-1) * exp(-t), t=0..x).
+
+ The function gamma(a,x) satisfies the Taylor expansions (we use the second
+ one in the code below):
+
+ gamma(a,x) = x^a * sum((-x)^k/k!/(a+k), k=0..infinity)
+
+ gamma(a,x) = x^a * exp(-x) * sum(x^k/(a*(a+1)*...*(a+k)), k=0..infinity)
+*/
+
+static int
+mpfr_gamma_inc_negint (mpfr_ptr y, mpfr_srcptr a, mpfr_srcptr x, mpfr_rnd_t r);
+
+int
+mpfr_gamma_inc (mpfr_ptr y, mpfr_srcptr a, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t w;
+ mpfr_t s, t, u;
+ int inex;
+ unsigned long k;
+ mpfr_exp_t e0, e1, e2, err;
+ MPFR_GROUP_DECL(group);
+ MPFR_ZIV_DECL(loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (MPFR_ARE_SINGULAR (a, x))
+ {
+ /* if a or x is NaN, return NaN */
+ if (MPFR_IS_NAN (a) || MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ /* Note: for x < 0, gamma_inc (a, x) is a complex number */
+
+ if (MPFR_IS_INF (a) || MPFR_IS_INF (x))
+ {
+ if (MPFR_IS_INF (a) && MPFR_IS_INF (x))
+ {
+ if ((MPFR_IS_POS (a) && MPFR_IS_POS (x)) || MPFR_IS_NEG (x))
+ {
+ /* (a) gamma_inc(+Inf,+Inf) = NaN because
+ gamma_inc(x,x) tends to +Inf but
+ gamma_inc(x,x^2) tends to +0.
+ (b) gamma_inc(+/-Inf,-Inf) = NaN, for example
+ gamma_inc (a, -a) is a complex number
+ for a not an integer */
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ /* gamma_inc(-Inf,+Inf) = +0 */
+ MPFR_SET_ZERO (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0); /* exact */
+ }
+ }
+ else /* only one of a, x is infinite */
+ {
+ if (MPFR_IS_INF (a))
+ {
+ MPFR_ASSERTD (MPFR_IS_INF (a) && MPFR_IS_FP (x));
+ if (MPFR_IS_POS (a))
+ {
+ /* gamma_inc(+Inf, x) = +Inf */
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0); /* exact */
+ }
+ else /* a = -Inf */
+ {
+ /* gamma_inc(-Inf, x) = NaN for x < 0
+ +Inf for 0 <= x < 1
+ +0 for 1 <= x */
+ if (mpfr_cmp_ui (x, 0) < 0)
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (mpfr_cmp_ui (x, 1) < 0)
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_ZERO (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0); /* exact */
+ }
+ }
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_FP (a) && MPFR_IS_INF (x));
+ if (MPFR_IS_POS (x))
+ {
+ /* x is +Inf: integral tends to zero */
+ MPFR_SET_ZERO (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0); /* exact */
+ }
+ else /* NaN for x < 0 */
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ }
+ }
+ }
+
+ if (MPFR_IS_ZERO (a) || MPFR_IS_ZERO (x))
+ {
+ if (MPFR_IS_ZERO (a))
+ {
+ if (mpfr_cmp_ui (x, 0) < 0)
+ {
+ /* gamma_inc(a,x) = NaN for x < 0 */
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_ZERO (x))
+ /* gamma_inc(a,0) = gamma(a) */
+ return mpfr_gamma (y, a, rnd); /* a=+0->+Inf, a=-0->-Inf */
+ else
+ {
+ /* gamma_inc (0, x) = int (exp(-t), t=x..infinity) = E1(x) */
+ mpfr_t minus_x;
+ MPFR_TMP_INIT_NEG(minus_x, x);
+ /* mpfr_eint(x) for x < 0 returns -E1(-x) */
+ inex = mpfr_eint (y, minus_x, MPFR_INVERT_RND(rnd));
+ MPFR_CHANGE_SIGN(y);
+ return -inex;
+ }
+ }
+ else /* x = 0: gamma_inc(a,0) = gamma(a) */
+ return mpfr_gamma (y, a, rnd);
+ }
+ }
+
+ /* for x < 0 return NaN */
+ if (MPFR_SIGN(x) < 0)
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ if (mpfr_integer_p (a) && MPFR_SIGN(a) < 0)
+ return mpfr_gamma_inc_negint (y, a, x, rnd);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ w = MPFR_PREC(y) + 13; /* working precision */
+
+ MPFR_GROUP_INIT_2(group, w, s, t);
+ mpfr_init2 (u, 2); /* u is special (see below) */
+ MPFR_ZIV_INIT (loop, w);
+ for (;;)
+ {
+ mpfr_exp_t expu, precu, exps;
+ mpfr_t s_abs;
+ mpfr_exp_t decay = 0;
+ MPFR_BLOCK_DECL (flags);
+
+ /* Note: in the error analysis below, theta represents any value of
+ absolute value less than 2^(-w) where w is the working precision (two
+ instances of theta may represent different values), cf Higham's book.
+ */
+
+ /* to ensure that u = a + k is exact, we have three cases:
+ (1) EXP(a) <= 0, then we need PREC(u) >= 1 - EXP(a) + PREC(a)
+ (2) EXP(a) - PREC(a) <= 0 < E(a), then PREC(u) >= PREC(a)
+ (3) 0 < EXP(a) - PREC(a), then PREC(u) >= EXP(a) */
+ precu = MPFR_GET_EXP(a) <= 0 ?
+ MPFR_ADD_PREC (MPFR_PREC(a), 1 - MPFR_EXP(a))
+ : (MPFR_EXP(a) <= MPFR_PREC(a)) ? MPFR_PREC(a) : MPFR_EXP(a);
+ MPFR_ASSERTD (precu + 1 <= MPFR_PREC_MAX);
+ mpfr_set_prec (u, precu + 1);
+ expu = (MPFR_EXP(a) > 0) ? MPFR_EXP(a) : 1;
+
+ /* estimate Taylor series */
+ mpfr_ui_div (t, 1, a, MPFR_RNDA); /* t = 1/a * (1 + theta) */
+ mpfr_set (s, t, MPFR_RNDA); /* s = 1/a * (1 + theta) */
+ if (MPFR_IS_NEG(a))
+ {
+ mpfr_init2 (s_abs, 32);
+ mpfr_abs (s_abs, s, MPFR_RNDU);
+ }
+ for (k = 1;; k++)
+ {
+ mpfr_mul (t, t, x, MPFR_RNDU); /* t = x^k/(a * ... * (a+k-1))
+ * (1 + theta)^(2k) */
+ inex = mpfr_add_ui (u, a, k, MPFR_RNDZ); /* u = a+k exactly */
+ MPFR_ASSERTD(inex == 0);
+ mpfr_div (t, t, u, MPFR_RNDA); /* t = x^k/(a * ... * (a+k))
+ * (1 + theta)^(2k+1) */
+ mpfr_add (s, s, t, MPFR_RNDZ);
+ /* when s is zero, we consider ulp(s) = ulp(t) */
+ exps = (MPFR_IS_ZERO(s)) ? MPFR_GET_EXP(t) : MPFR_GET_EXP(s);
+ if (MPFR_IS_NEG(a))
+ {
+ if (MPFR_IS_POS(t))
+ mpfr_add (s_abs, s_abs, t, MPFR_RNDU);
+ else
+ mpfr_sub (s_abs, s_abs, t, MPFR_RNDU);
+ }
+ /* we stop when |t| < ulp(s), u > 0 and |x/u| < 1/2, which ensures
+ that the tail is at most 2*ulp(s) */
+ MPFR_ASSERTD (MPFR_NOTZERO(t));
+ if (MPFR_GET_EXP(t) + w <= exps && MPFR_IS_POS(u) &&
+ MPFR_GET_EXP(x) + 1 < MPFR_GET_EXP(u))
+ break;
+
+ /* if there was an exponent shift in u, increase the precision of
+ u so that mpfr_add_ui (u, a, k) remains exact */
+ if (MPFR_EXP(u) > expu) /* exponent shift in u */
+ {
+ MPFR_ASSERTD(MPFR_EXP(u) == expu + 1);
+ expu = MPFR_EXP(u);
+ mpfr_set_prec (u, mpfr_get_prec (u) + 1);
+ }
+ }
+ if (MPFR_IS_NEG(a))
+ {
+ decay = MPFR_GET_EXP(s_abs) - MPFR_GET_EXP(s);
+ mpfr_clear (s_abs);
+ }
+ /* For a > 0, since all terms are positive, we have
+ s = S * (1 + theta)^(2k+3) with S being the infinite Taylor series.
+ For a < 0, the error is bounded by that on the sum s_abs of absolute
+ values of the terms, i.e., S_abs * [(1 + theta)^(2k+3) - 1]. Thus we
+ can simply use the same error analysis as for a > 0, adding an error
+ corresponding to the decay of exponent between s_abs and s. */
+
+ /* multiply by exp(-x) */
+ mpfr_exp (t, x, MPFR_RNDZ); /* t = exp(x) * (1+theta) */
+ mpfr_div (s, s, t, MPFR_RNDZ); /* s = <exact value> * (1+theta)^(2k+5) */
+
+ /* multiply by x^a */
+ mpfr_pow (t, x, a, MPFR_RNDZ); /* t = x^a * (1+theta) */
+ mpfr_mul (s, s, t, MPFR_RNDZ); /* s = Gamma(a,x) * (1+theta)^(2k+7) */
+
+ /* Since |theta| < 2^(-w) using the Taylor expansion of log(1+x)
+ we have log(1+theta) = theta1 with |theta1| < 1.16*2^(-w) for w >= 2,
+ thus (1+theta)^(2k+7) = exp((2k+7)*theta1).
+ Assuming 2k+7 = t*2^w for |t| < 0.5, we have
+ |(2k+7)*theta1| = |t*2^w*theta1| < 0.58.
+ For |u| < 0.58 we have |exp(u)-1| < 1.36*|u|
+ thus |(1+theta)^(2k+7) - 1| < 1.36*0.58*(2k+7)/2^w < 0.79*(2k+7)/2^w.
+ Since one ulp is at worst a relative error of 2^(1-w),
+ the error on s is at most 2^(decay+1)*(2k+7) ulps. */
+
+ /* subtract from gamma(a) */
+ MPFR_BLOCK (flags, mpfr_gamma (t, a, MPFR_RNDZ));
+ MPFR_ASSERTN (!MPFR_OVERFLOW (flags)); /* FIXME: support overflow */
+ /* t = gamma(a) * (1+theta) */
+ e0 = MPFR_GET_EXP (t);
+ e1 = (MPFR_IS_ZERO(s)) ? __gmpfr_emin : MPFR_GET_EXP (s);
+ mpfr_sub (s, t, s, MPFR_RNDZ);
+ /* if s is zero, we can assume ulp(s) = ulp(t), but anyway we won't
+ be able to round */
+ e2 = (MPFR_IS_ZERO(s)) ? e0 : MPFR_GET_EXP (s);
+ /* the final error is at most 1 ulp (for the final subtraction)
+ + 2^(e0-e2) ulps # for the error in t
+ + 2^(decay+1)*(2k+7) ulps * 2^(e1-e2) # for the error in gamma(a,x) */
+
+ e1 += decay + 1 + MPFR_INT_CEIL_LOG2 (2*k+7);
+ /* Now the error is <= 1 + 2^(e0-e2) + 2^(e1-e2).
+ Since the formula is symmetric in e0 and e1, we can assume without
+ loss of generality e0 >= e1, then:
+ if e0 = e1: err <= 1 + 2*2^(e0-e2) <= 2^(e0-e2+2)
+ if e0 > e1: err <= 1 + 1.5*2^(e0-e2)
+ <= 2^(e0-e2+1) if e0 > e2
+ <= 2^2 otherwise */
+ if (e0 == e1)
+ {
+ /* Check that e0 - e2 + 2 <= MPFR_EXP_MAX */
+ MPFR_ASSERTD (e2 >= 2 || e0 <= (MPFR_EXP_MAX - 2) + e2);
+ /* Check that e0 - e2 + 2 >= MPFR_EXP_MIN */
+ MPFR_ASSERTD (e2 <= 2 || e0 >= MPFR_EXP_MIN + (e2 - 2));
+ err = e0 - e2 + 2;
+ }
+ else
+ {
+ e0 = (e0 > e1) ? e0 : e1; /* max(e0,e1) */
+ MPFR_ASSERTD (e0 <= e2 || e2 >= 1 || e0 <= (MPFR_EXP_MAX - 1) + e2);
+ err = (e0 > e2) ? e0 - e2 + 1 : 2;
+ }
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, w - err, MPFR_PREC(y), rnd)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, w);
+ MPFR_GROUP_REPREC_2(group, w, s, t);
+ }
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (u);
+
+ inex = mpfr_set (y, s, rnd);
+ MPFR_GROUP_CLEAR(group);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd);
+}
+
+/* For a negative integer, we have (formula 6.5.19):
+
+ gamma(-n,x) = (-1)^n/n! [E_1(x) - exp(-x) sum((-1)^j*j!/x^(j+1), j=0..n-1)]
+
+ See also http://arxiv.org/pdf/1407.0349v1.pdf.
+
+ Assumes 'a' is a negative integer.
+*/
+static int
+mpfr_gamma_inc_negint (mpfr_ptr y, mpfr_srcptr a, mpfr_srcptr x,
+ mpfr_rnd_t rnd)
+{
+ mpfr_t s, t, abs_a, neg_x;
+ unsigned long j;
+ mpfr_prec_t w;
+ int inex;
+ mpfr_exp_t exp_s, new_exp_s, exp_t, err_s, logj;
+ MPFR_GROUP_DECL(group);
+ MPFR_ZIV_DECL(loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_ASSERTD(mpfr_integer_p (a));
+ MPFR_ASSERTD(mpfr_cmp_ui (a, 0) < 0);
+
+ MPFR_TMP_INIT_ABS(abs_a, a);
+
+ /* below, theta represents any value such that |theta| <= 2^(-w) */
+
+ w = MPFR_PREC(y) + 10; /* initial working precision */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_GROUP_INIT_2(group, w, s, t);
+ MPFR_ZIV_INIT (loop, w);
+ for (;;)
+ {
+ /* we require |a| <= 2^(w-3) for the error analysis below */
+ if (MPFR_GET_EXP(a) + 3 > w)
+ w = MPFR_GET_EXP(a) + 3;
+
+ mpfr_ui_div (t, 1, x, MPFR_RNDN); /* t = 1/x * (1 + theta) */
+ mpfr_set (s, t, MPFR_RNDN);
+ MPFR_ASSERTD (MPFR_NOTZERO(s));
+ exp_t = exp_s = MPFR_GET_EXP(s); /* max. exponent of s/t during loop */
+ new_exp_s = exp_s;
+
+ for (j = 1; mpfr_cmp_ui (abs_a, j) > 0; j++)
+ {
+ /* invariant: t = (-1)^(j-1)*(j-1)!/x^j * (1 + theta)^(2j-1) */
+ mpfr_mul_ui (t, t, j, MPFR_RNDN);
+ mpfr_neg (t, t, MPFR_RNDN); /* exact */
+ mpfr_div (t, t, x, MPFR_RNDN);
+ /* now t = (-1)^j*j!/x^(j+1) * (1 + theta)^(2j+1).
+ We have (1 + theta)^(2j+1) = exp((2j+1)*log(1+theta)).
+ For |u| <= 1/2, we have |log(1+u)| <= 1.4 |u| thus:
+ |(1+theta)^(2j+1)-1| <= max |exp(1.4*(2j+1)*u)-1| for |u|<=2^(-w).
+ Now for |v| <= 1/2 we have |exp(v)-1| <= 0.7*|v| thus:
+ |(1+theta)^(2j+1) - 1| <= 2*(2j+1)*2^(-w)
+ as long as 1.4*(2j+1)*2^(-w) <= 1/2, which is true when j<2^(w-3).
+ Since j < |a| it suffices that |a| <= 2^(w-3).
+ In that case the rel. error on t is bounded by 2*(2j+1)*2^(-w),
+ thus the error in ulps is bounded by 2*(2j+1) ulp(t). */
+ if (MPFR_IS_ZERO(t)) /* underflow on t */
+ break;
+ if (MPFR_GET_EXP(t) > exp_t)
+ exp_t = MPFR_GET_EXP(t);
+ mpfr_add (s, s, t, MPFR_RNDN);
+ /* if s is zero, we can assume its ulp is that of t */
+ new_exp_s = (MPFR_IS_ZERO(s)) ? MPFR_GET_EXP(t) : MPFR_GET_EXP(s);
+ if (new_exp_s > exp_s)
+ exp_s = new_exp_s;
+ }
+
+ /* the error on s is bounded by (j-1) * 2^(exp_s - EXP(s)) * 1/2
+ for the mpfr_add roundings, plus
+ sum(2*(2i+1), i=1..j-1) * 2^(exp_t - EXP(s)) for the error on t.
+ The latter sum is (2*j^2-2) * 2^(exp_t - EXP(s)). */
+
+ logj = MPFR_INT_CEIL_LOG2(j);
+ exp_s += logj - 1;
+ exp_t += 1 + 2 * logj;
+
+ /* now the error on s is bounded by 2^(exp_s-EXP(s))+2^(exp_t-EXP(s)) */
+
+ exp_s = (exp_s >= exp_t) ? exp_s + 1 : exp_t + 1;
+ err_s = exp_s - new_exp_s;
+
+ /* now the error on the sum S := sum((-1)^j*j!/x^(j+1), j=0..n-1)
+ is bounded by 2^err_s ulp(s) */
+
+ MPFR_TMP_INIT_NEG(neg_x, x);
+
+ mpfr_exp (t, neg_x, MPFR_RNDN); /* t = exp(-x) * (1 + theta) */
+ mpfr_mul (s, s, t, MPFR_RNDN);
+ if (MPFR_IS_ZERO(s))
+ {
+ MPFR_ASSERTD (MPFR_NOTZERO(t));
+ new_exp_s += MPFR_GET_EXP(t);
+ }
+ /* s = exp(-x) * (S +/- 2^err_s ulp(S)) * (1 + theta)^2.
+ = exp(-x) * (S +/- 2^err_s ulp(S)) * (1 +/- 3 ulp(1))
+ The error on s is bounded by:
+ exp(-x) * [2^err_s*ulp(S) + S*3*ulp(1) + 2^err_s*ulp(S)*3*ulp(1)]
+ <= ulp(s) * [2^(err_s+1) + 6 + 1]
+ <= ulp(s) * 2^(err_s+2) as long as err_s >= 2. */
+
+ err_s = (err_s >= 2) ? err_s + 2 : 4;
+ /* now the error on s is bounded by 2^err_s ulp(s) */
+
+ mpfr_eint (t, neg_x, MPFR_RNDN); /* t = -E1(-x) * (1 + theta) */
+ mpfr_neg (t, t, MPFR_RNDN); /* exact */
+
+ exp_s = (MPFR_IS_ZERO(s)) ? new_exp_s : MPFR_GET_EXP(s);
+ MPFR_ASSERTD (MPFR_NOTZERO(t));
+ exp_t = MPFR_GET_EXP(t);
+ mpfr_sub (s, t, s, MPFR_RNDN); /* E_1(x) - exp(-x) * S */
+ if (MPFR_IS_ZERO(s)) /* cancellation: increase working precision */
+ goto next_w;
+
+ /* err(s) <= 1/2 * ulp(s) [mpfr_sub]
+ + 2^err_s * 2^(exp_s-EXP(s)) * ulp(s) [previous error on s]
+ + 1/2 * 2^(exp_t-EXP(s)) * ulp(s) [error on t] */
+
+ exp_s += err_s;
+ exp_t -= 1;
+ exp_s = (exp_s >= exp_t) ? exp_s + 1 : exp_t + 1;
+ MPFR_ASSERTD (MPFR_NOTZERO(s));
+ err_s = exp_s - MPFR_GET_EXP(s);
+ /* err(s) <= 1/2 * ulp(s) + 2^err_s * ulp(s) */
+
+ /* divide by n! */
+ mpfr_gamma (t, abs_a, MPFR_RNDN); /* t = (n-1)! * (1 + theta) */
+ mpfr_mul (t, t, abs_a, MPFR_RNDN); /* t = n! * (1 + theta)^2 */
+ mpfr_div (s, s, t, MPFR_RNDN);
+ /* since (1 + theta)^2 converts to an error of at most 3 ulps
+ for w >= 2, the final error is at most:
+ 2 * (1/2 + 2^err_s) * ulp(s) [error on previous s]
+ + 2 * 3 * ulp(s) [error on t]
+ + 1 * ulp(s) [product of errors]
+ = ulp(s) * (2^(err_s+1) + 8) */
+ err_s = (err_s >= 2) ? err_s + 1 : 4;
+
+ /* the final error is bounded by 2^err_s * ulp(s) */
+
+ /* Is there a better way to compute (-1)^n? */
+ mpfr_set_si (t, -1, MPFR_RNDN);
+ mpfr_pow (t, t, abs_a, MPFR_RNDN);
+ if (MPFR_IS_NEG(t))
+ mpfr_neg (s, s, MPFR_RNDN);
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, w - err_s, MPFR_PREC(y), rnd)))
+ break;
+
+ next_w:
+ MPFR_ZIV_NEXT (loop, w);
+ MPFR_GROUP_REPREC_2(group, w, s, t);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inex = mpfr_set (y, s, rnd);
+ MPFR_GROUP_CLEAR(group);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/generic/coverage/mparam.h b/Build/source/libs/mpfr/mpfr-src/src/generic/coverage/mparam.h
new file mode 100644
index 00000000000..67dbe278dd0
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/generic/coverage/mparam.h
@@ -0,0 +1,225 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005-2017 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* mparam tuned for coverage test */
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,-1,-1,-1,-1,-1,-1,0,0,0,0,8,9,10,11, \
+ 10,11,12,13,0,13,14,13,14,15,16,17,16,16,18,19, \
+ 19,19,20,19,28,28,28,28,28,28,28,28,28,28,28,30, \
+ 32,32,32,32,34,34,36,34,36,36,36,36,36,40,38,38, \
+ 40,38,40,40,56,56,56,56,56,56,56,56,56,56,56,56, \
+ 56,56,56,56,56,56,56,56,60,56,60,64,64,64,56,56, \
+ 56,64,64,56,60,64,60,64,64,64,64,68,68,64,68,84, \
+ 84,86,84,84,87,84,87,84,87,84,84,84,84,84,84,84, \
+ 87,87,86,87,87,87,92,93,92,93,93,93,93,99,96,93, \
+ 99,99,99,99,99,98,99,99,102,99,105,104,105,105,108,108, \
+ 110,108,108,111,114,114,116,117,117, \
+ 117,117,117,124,124,124,124, \
+ 124,124,124,132,132,132,132,124,132,\
+ 132,132,132,132,132,132,132, \
+ 140,140,140,140,123,140,124,124,124,\
+ 124,132,128,132,132,132,132, \
+ 132,132,132,132,132,132,140,140,132,140,140,140,140,140,148,147, \
+ 140,148,148,147,148,148,148,156,148,156,156,156,156,156,156,155, \
+ 156,160,156,156,164,164,164,156,164,164,164,164,164,164,164,164, \
+ 164,217,220,220,220,220,220,220,220,220,220,220,220,220,220,220, \
+ 220,220,220,220,220,220,220,220,220,220,224,220,220,220,220,220, \
+ 220,220,220,220,220,220,220,220,220,224,220,220,220,224,220,220, \
+ 220,220,220,224,224,224,224,236,220,236,235,236,235,235,234,236, \
+ 236,235,236,236,235,236,236,236,236,236,236,252,236,251,236,251, \
+ 252,252,252,252,236,235,252,252,252,252,252,251,268,252,252,252, \
+ 268,251,268,268,252,252,268,268,268,268,267,268,268,268,267,268, \
+ 268,252,268,268,268,267,268,268,268,252,268,252,252,252,251,268, \
+ 252,268,252,268,268,268,268,268,267,268,268,268,268,268,268,268, \
+ 268,268,268,268,268,268,332,332,330,268,332,332,332,332,330,331, \
+ 332,332,332,332,344,331,344,344,344,344,344,332,342,332,344,332, \
+ 332,332,344,332,344,344,342,344,344,342,344,344,344,344,344,342, \
+ 344,344,344,344,344,344,344,368,344,342,344,344,368,344,344,344, \
+ 344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, \
+ 344,344,368,344,344,368,344,363,368,367,368,368,368,368,368,366, \
+ 366,368,368,368,368,368,368,368,368,368,368,368,368,368,380,368, \
+ 368,368,368,368,368,392,392,392,392,392,392,392,392,392,392,392, \
+ 392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392, \
+ 392,391,392,392,392,392,392,416,392,416,416,416,416,412,416,392, \
+ 416,416,416,416,416,416,416,416,416,416,416,428,416,416,416,428, \
+ 416,440,416,480,480,480,480,480,480,480,504,503,504,504,504,504, \
+ 504,504,504,503,504,504,504,504,504,504,504,504,504,503,504,504, \
+ 480,504,504,504,504,504,504,480,504,488,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,536,536,536,536,536,536,536, \
+ 536,536,536,536,535,536,536,536,536,536,536,536,536,535,536,536, \
+ 536,536,536,535,536,535,536,536,536,536,536,536,536,536,536,536, \
+ 536,568,536,536,536,536,536,536,568,536,535,536,536,536,536,536, \
+ 536,536,536,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,664,664,664,664,664,664,664, \
+ 664,663,664,664,664,664,664,664,664,664,664,663,664,664,664,663, \
+ 664,663,664,664,664,664,664,664,664,663,664,664,664,663,664,664, \
+ 664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664, \
+ 664,664,664,663,664,664,664,664,664,664,664,663,664,664,664,664, \
+ 664,688,664,664,688,688,664,664,688,664,664,664,664,664,664,664, \
+ 664,680,688,688,688,688,688,688,688,688,688,688,688,688,688,688, \
+ 688,688,712,712,688,688,688,712,712,711,712,712,736,728,736,728, \
+ 728,728,736,728,736,736,736,736,728,736,736,736,728,736,736,736, \
+ 735,736,736,736,736,736,736,736,736,736,736,736,736,728,736,736, \
+ 728,736,736,736,736,735,736,736,735,736,736,736,736,735,736,736, \
+ 736,728,736,736,736,736,736,736,736,736,736,736,736,736,736,784, \
+ 736,784,783,736,784,735,784,735,784,735,736,736,736,736,736,736, \
+ 736,736,784,735,736,784,736,784,784,736,736,736,736,784,784,784, \
+ 784,784,784,783,784,784,784,736,784,784,784,784,784,784,784,784, \
+ 784,784,784,784,783,784,784,784,784,784,784,784,784,784,784,784, \
+ 784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,783, \
+ 736,784,784,784,784,784,783,784,784,831,784,832,832,832,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,-1,-1,-1,-1,-1,7,7,7,8,9,10,11, \
+ 11,11,11,11,12,13,13,15,15,15,15,15,17,17,19,19, \
+ 19,19,19,19,20,20,23,21,23,23,24,23,27,25,26,27, \
+ 26,27,27,34,34,34,34,34,34,34,34,34,34,38,34,38, \
+ 38,38,38,40,40,42,42,44,42,42,46,42,42,46,46,42, \
+ 42,42,44,44,46,46,46,46,46,46,50,50,50,50,50,50, \
+ 54,54,54,56,54,56,58,58,68,68,68,68,68,68,68,68, \
+ 68,68,68,72,68,68,68,68,68,68,72,72,76,76,76,76, \
+ 76,76,76,76,84,84,84,84,76,84,84,84,84,84,88,92, \
+ 84,84,92,92,84,76,92,88,80,80,80,80,84,84,84,84, \
+ 84,88,84,84,84,92,92,92,92,88,92,96,92,96,92,96, \
+ 92,96,100,104,100,100,96,100,100,100,108,104,117,104,117,108, \
+ 117,117,117,123,122,122,120,117,122,117,122,123,122,123,122,123, \
+ 126,123,126,129,126,129,135,123,132,135,132,135,134,135,134,135, \
+ 138,129,132,123,144,144,134,135,140,129,146,135,132,147,146,147, \
+ 146,135,138,147,138,135,140,141,144,147,146,147,146,147,150,152, \
+ 152,153,152,153,156,153,138,135,140,141,138,144,146,147,147,147, \
+ 147,146,146,146,150,150,150,147,147,159,156,159,158,156,153,159, \
+ 159,159,159,158,201,201,201,201,170,201,170,201,171,201,168,201, \
+ 200,201,201,201,201,200,201,201,200,201,201,201,201,200,201,201, \
+ 201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, \
+ 201,201,201,201,201,201,201,201,201,213,201,212,213,225,213,225, \
+ 225,225,225,225,225,225,225,225,225,224,225,225,225,225,224,225, \
+ 225,225,225,225,225,225,225,225,225,225,225,225,237,225,237,225, \
+ 249,249,249,249,249,249,249,249,249,249,248,249,249,249,261,249, \
+ 261,249,261,261,261,249,249,261,260,261,248,261,261,273,248,249, \
+ 249,261,261,249,249,273,249,248,249,249,249,273,261,273,273,249, \
+ 273,249,273,272,273,273,261,273,273,273,273,273,273,261,273,273, \
+ 273,273,273,276,285,273,273,273,273,273,273,273,273,261,285,285, \
+ 285,285,273,261,261,285,273,297,285,273,273,273,272,273,273,273, \
+ 273,273,273,273,273,273,273,276,273,273,273,273,285,273,273,285, \
+ 351,351,351,351,351,351,297,351,351,366,351,351,351,297,366,366, \
+ 351,351,351,351,366,363,351,362,364,366,366,366,364,351,351,351, \
+ 351,351,366,366,351,366,366,366,366,366,363,366,360,363,366,366, \
+ 366,363,366,366,366,366,366,366,366,351,366,366,351,351,351,384, \
+ 366,366,366,366,366,384,366,366,363,364,366,363,366,366,366,363, \
+ 366,366,366,366,366,366,366,366,366,365,366,366,366,384,366,366, \
+ 384,366,384,366,366,366,384,366,366,366,366,366,366,384,366,402, \
+ 393,384,366,402,402,402,384,402,402,402,384,401,402,402,351,402, \
+ 351,351,402,402,402,351,402,402,366,363,365,366,366,363,366,366, \
+ 365,360,366,366,366,351,366,363,365,363,366,366,366,366,363,365, \
+ 366,366,366,366,366,366,366,366,366,366,366,363,366,366,366,363, \
+ 365,366,402,402,366,402,384,384,381,402,384,384,384,384,384,384, \
+ 402,384,387,384,402,401,402,391,402,393,399,402,402,402,401,399, \
+ 401,402,402,402,402,402,402,402,402,402,402,402,402,402,399,402, \
+ 401,402,402,402,402,402,402,402,402,438,402,438,438,437,402,437, \
+ 438,437,438,438,438,441,438,438,438,438,438,438,438,438,437,438, \
+ 438,438,456,435,437,437,438,438,438,435,438,437,438,456,456,438, \
+ 455,456,456,456,474,456,474,456,456,474,456,456,512,456,512,512, \
+ 512,512,512,512,512,512,512,474,512,512,512,512,512,512,512,512, \
+ 512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, \
+ 512,512,512,512,512,512,512,536,512,512,536,522,512,536,536,512, \
+ 512,512,512,536,536,524,536,531,536,536,536,536,536,536,536,536, \
+ 535,512,536,534,512,536,512,536,536,535,536,536,535,534,534,536, \
+ 536,536,536,535,536,535,534,536,536,536,536,536,536,534,536,536, \
+ 536,536,536,536,536,560,560,535,536,560,536,535,584,536,536,572, \
+ 583,584,584,584,536,572,560,584,584,584,584,584,583,584,584,584, \
+ 584,583,584,570,584,584,572,584,584,584,584,584,584,583,584,584, \
+ 584,584,584,560,584,584,584,584,584,584,584,584,584,584,584,584, \
+ 584,584,584,584,584,632,696,632,584,582,696,696,696,696,584,696, \
+ 694,696,695,696,695,696,694,695,695,696,696,696,695,696,696,695, \
+ 696,696,695,696,696,696,696,696,695,695,696,695,696,695,696,695, \
+ 696,695,696,695,696,695,696,695,696,696,696,696,696,695,696,696, \
+ 695,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*0-15*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*16-31*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*32-47*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*48-63*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0, /*64-79*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,56,56,56, /*80-95*/ \
+ 56,56,60,58,59,56,59,59,56,59,60,58,56,64,60,60, /*96-111*/ \
+ 63,64,64,60,63,60,64,64,64,66,67,66,68,66,72,66, /*112-127*/ \
+ 67,67,71,68,68,71,71,70,76,74,74,76,76,72,75,80, /*128-143*/ \
+ 76,76,76,76,78,76,79,77,80,78,79,80,82,80,83,83, /*144-159*/ \
+ 83,85,86,91,85,88,87,85,87,90,112,91,112,89,112,112, /*160-175*/ \
+ 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, /*176-191*/ \
+ 112,112,118,112,112,112,112,112,112,112,120,120,112,112,112,120, /*192-207*/ \
+ 112,112,112,112,112,120,112,119,112,112,114,112,124,120,120,116, /*208-223*/ \
+ 120,118,123,128,124,120,120,123,120,128,128,120,128,134,128,127, /*224-239*/ \
+ 126,128,136,134,136,128,126,127,136,128,134,136,136,128,136,132, /*240-255*/ \
+ 136,136,134,132,136,136,135,136,136,134,136,136,136,140,144,142, /*256-271*/ \
+ 143,144,144,143,144,143,150,144,144,143,144,144,156,144,152,151, /*272-287*/ \
+ 166,149,152,152,156,152,168,160,152,168,168,168,152,160,168,168, /*288-303*/ \
+ 168,172,166,168,168,180,166,166,165,165,168,168,168,164,174,167, /*304-319*/ \
+ 168,166,174,168,168,168,174,176,180,172,174,182,180,172,184,178, /*320-335*/ \
+ 184,183,184,186,182,182,183,185,174,224,176,224,224,224,196,191, /*336-351*/ \
+ 192,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /*352-367*/ \
+ 224,224,224,224,224,224,224,224,224,224,228,224,224,224,233,224, /*368-383*/ \
+ 224,224,224,240,224,232,224,224,224,224,224,224,224,224,224,224, /*384-399*/ \
+ 224,224,224,224,228,224,224,224,224,224,224,224,224,225,224,224, /*400-415*/ \
+ 224,224,224,224,224,224,224,224,233,232,224,240,224,240,224,223, /*416-431*/ \
+ 224,224,224,224,224,232,224,232,228,233,224,224,228,240,230,240, /*432-447*/ \
+ 240,240,242,239,240,247,240,239,248,240,239,242,256,232,256,254, /*448-463*/ \
+ 256,256,256,256,256,256,256,256,256,240,264,256,264,264,256,263, /*464-479*/ \
+ 272,272,256,248,254,272,256,256,254,256,256,255,254,272,272,256, /*480-495*/ \
+ 256,272,264,256,255,271,272,264,256,272,272,272,272,256,272,272, /*496-511*/ \
+ 278,280,272,272,280,287,280,280,287,280,270,272,272,264,272,272, /*512-527*/ \
+ 271,269,270,280,272,272,271,272,272,270,272,272,272,272,288,273, /*528-543*/ \
+ 278,276,288,286,280,288,287,285,280,286,288,280,280,288,288,296, /*544-559*/ \
+ 288,288,288,289,288,288,287,287,288,296,288,288,296,302,312,294, /*560-575*/ \
+ 310,304,303,304,304,312,303,320,304,300,312,296,305,310,304,304, /*576-591*/ \
+ 304,302,303,312,302,304,304,304,302,336,304,304,328,311,312,328, /*592-607*/ \
+ 310,312,316,336,336,320,312,320,336,320,319,336,336,328,328,325, /*608-623*/ \
+ 320,328,328,336,320,336,320,324,336,348,320,336,343,320,336,336, /*624-639*/ \
+ 336,334,335,344,341,328,342,336,328,335,336,336,336,336,335,336, /*640-655*/ \
+ 336,343,336,344,336,336,348,360,344,359,344,360,360,360,344,348, /*656-671*/ \
+ 344,347,348,360,348,360,360,360,360,367,368,368,448,360,448,372, /*672-687*/ \
+ 360,360,448,368,448,448,448,448,448,448,448,448,448,448,448,448, /*688-703*/ \
+ 448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, /*704-719*/ \
+ 448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, /*720-735*/ \
+ 448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, /*736-751*/ \
+ 448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, /*752-767*/ \
+ 448,448,448,448,448,448,448,448,448,448,448,448,448,467,448,468, /*768-783*/ \
+ 448,468,448,466,448,464,468,448,464,464,448,448,448,448,464,448, /*784-799*/ \
+ 480,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, /*800-815*/ \
+ 448,448,448,448,448,448,448,448,448,448,480,448,448,448,447,448, /*816-831*/ \
+ 448,448,448,464,448,448,448,448,448,448,448,448,448,447,448,448, /*832-847*/ \
+ 448,448,448,448,447,448,448,448,448,456,448,448,448,456,448,448, /*848-863*/ \
+ 448,448,448,448,448,448,448,448,448,448,464,464,448,467,448,448, /*864-879*/ \
+ 448,448,448,464,448,447,468,464,448,464,464,448,448,468,472,472, /*880-895*/ \
+ 466,462,464,469,468,464,463,480,472,479,496,480,472,512,472,479, /*896-911*/ \
+ 512,464,495,512,496,495,480,496,488,472,492,512,512,480,512,479, /*912-927*/ \
+ 512,480,504,480,480,496,512,480,472,480,512,496,480,512,536,496, /*928-943*/ \
+ 512,512,512,512,496,512,512,515,496,480,512,496,512,480,510,543, /*944-959*/ \
+ 512,496,512,496,528,528,496,512,512,528,527,496,512,508,512,528, /*960-975*/ \
+ 512,512,512,512,512,512,512,512,528,528,512,512,512,512,528,528, /*976-991*/ \
+ 512,528,526,527,528,511,508,511,512,512,528,527,528,528,510,512, /*992-1007*/ \
+ 528,544,544,536,536,520,511,536,536,543,512,528,544,512,542,543 /*1008-1023*/ \
+
+
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_d.c b/Build/source/libs/mpfr/mpfr-src/src/get_d.c
index 197eab4d290..d89b5c621c4 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_d.c
@@ -151,8 +151,7 @@ mpfr_get_d_2exp (long *expptr, mpfr_srcptr src, mpfr_rnd_t rnd_mode)
return negative ? DBL_NEG_ZERO : 0.0;
}
- tmp[0] = *src; /* Hack copy mpfr_t */
- MPFR_SET_EXP (tmp, 0);
+ MPFR_ALIAS (tmp, src, MPFR_SIGN (src), 0);
ret = mpfr_get_d (tmp, rnd_mode);
if (MPFR_IS_PURE_FP(src))
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_d64.c b/Build/source/libs/mpfr/mpfr-src/src/get_d64.c
index 58528ff00ad..9da7650b29c 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_d64.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_d64.c
@@ -1,8 +1,8 @@
/* mpfr_get_decimal64 -- convert a multiple precision floating-point number
- to a IEEE 754r decimal64 float
+ to an IEEE 754-2008 decimal64 float
-See http://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
-http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
+See https://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
+https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
and TR 24732 <http://www.open-std.org/jtc1/sc22/wg14/www/projects#24732>.
Copyright 2006-2017 Free Software Foundation, Inc.
@@ -25,19 +25,23 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <stdlib.h> /* for strtol */
#include "mpfr-impl.h"
#define ISDIGIT(c) ('0' <= c && c <= '9')
#ifdef MPFR_WANT_DECIMAL_FLOATS
+#if _MPFR_IEEE_FLOATS
+#else
+#include "ieee_floats.h"
+#endif
+
#ifndef DEC64_MAX
# define DEC64_MAX 9.999999999999999E384dd
#endif
#ifdef DPD_FORMAT
-static int T[1000] = {
+static const int T[1000] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88,
@@ -110,25 +114,33 @@ static int T[1000] = {
static _Decimal64
get_decimal64_nan (void)
{
- union ieee_double_extract x;
+#if _MPFR_IEEE_FLOATS
+ union mpfr_ieee_double_extract x;
union ieee_double_decimal64 y;
x.s.exp = 1984; /* G[0]..G[4] = 11111: quiet NaN */
y.d = x.d;
return y.d64;
+#else
+ return (_Decimal64) MPFR_DBL_NAN;
+#endif
}
/* construct the decimal64 Inf with given sign */
static _Decimal64
get_decimal64_inf (int negative)
{
- union ieee_double_extract x;
+#if _MPFR_IEEE_FLOATS
+ union mpfr_ieee_double_extract x;
union ieee_double_decimal64 y;
x.s.sig = (negative) ? 1 : 0;
x.s.exp = 1920; /* G[0]..G[4] = 11110: Inf */
y.d = x.d;
return y.d64;
+#else
+ return (_Decimal64) (negative ? MPFR_DBL_INFM : MPFR_DBL_INFP);
+#endif
}
/* construct the decimal64 zero with given sign */
@@ -164,6 +176,7 @@ get_decimal64_max (int negative)
(b2) or -398 <= e <= 369 with m integer, |m| < 10^16.
Assumes s is neither NaN nor +Inf nor -Inf.
*/
+#if _MPFR_IEEE_FLOATS
static _Decimal64
string_to_Decimal64 (char *s)
{
@@ -171,7 +184,7 @@ string_to_Decimal64 (char *s)
char m[17];
long n = 0; /* mantissa length */
char *endptr[1];
- union ieee_double_extract x;
+ union mpfr_ieee_double_extract x;
union ieee_double_decimal64 y;
#ifdef DPD_FORMAT
unsigned int G, d1, d2, d3, d4, d5;
@@ -284,6 +297,199 @@ string_to_Decimal64 (char *s)
y.d = x.d;
return y.d64;
}
+#else
+/* portable version */
+static _Decimal64
+string_to_Decimal64 (char *s)
+{
+ long int exp = 0;
+ char m[17];
+ long n = 0; /* mantissa length */
+ char *endptr[1];
+ _Decimal64 x = 0.0;
+ int sign = 0;
+#ifdef DPD_FORMAT
+ unsigned int G, d1, d2, d3, d4, d5;
+#endif
+
+ /* read sign */
+ if (*s == '-')
+ {
+ sign = 1;
+ s ++;
+ }
+ /* read mantissa */
+ while (ISDIGIT (*s))
+ m[n++] = *s++;
+ exp = n;
+ if (*s == '.')
+ {
+ s ++;
+ while (ISDIGIT (*s))
+ m[n++] = *s++;
+ }
+ /* we have exp digits before decimal point, and a total of n digits */
+ exp -= n; /* we will consider an integer mantissa */
+ MPFR_ASSERTN(n <= 16);
+ if (*s == 'E' || *s == 'e')
+ exp += strtol (s + 1, endptr, 10);
+ else
+ *endptr = s;
+ MPFR_ASSERTN(**endptr == '\0');
+ MPFR_ASSERTN(-398 <= exp && exp <= (long) (385 - n));
+ while (n < 16)
+ {
+ m[n++] = '0';
+ exp --;
+ }
+ /* now n=16 and -398 <= exp <= 369 */
+ m[n] = '\0';
+
+ /* the number to convert is m[] * 10^exp where the mantissa is a 16-digit
+ integer */
+
+ /* compute biased exponent */
+ exp += 398;
+
+ MPFR_ASSERTN(exp >= -15);
+ if (exp < 0)
+ {
+ int i;
+ n = -exp;
+ /* check the last n digits of the mantissa are zero */
+ for (i = 1; i <= n; i++)
+ MPFR_ASSERTN(m[16 - n] == '0');
+ /* shift the first (16-n) digits to the right */
+ for (i = 16 - n - 1; i >= 0; i--)
+ m[i + n] = m[i];
+ /* zero the first n digits */
+ for (i = 0; i < n; i ++)
+ m[i] = '0';
+ exp = 0;
+ }
+
+ /* the number to convert is m[] * 10^(exp-398) */
+ exp -= 398;
+
+ for (n = 0; n < 16; n++)
+ x = (_Decimal64) 10.0 * x + (_Decimal64) (m[n] - '0');
+
+ /* multiply by 10^exp */
+ if (exp > 0)
+ {
+ _Decimal64 ten16 = (double) 1e16; /* 10^16 is exactly representable
+ in binary64 */
+ _Decimal64 ten32 = ten16 * ten16;
+ _Decimal64 ten64 = ten32 * ten32;
+ _Decimal64 ten128 = ten64 * ten64;
+ _Decimal64 ten256 = ten128 * ten128;
+ if (exp >= 256)
+ {
+ x *= ten256;
+ exp -= 256;
+ }
+ if (exp >= 128)
+ {
+ x *= ten128;
+ exp -= 128;
+ }
+ if (exp >= 64)
+ {
+ x *= ten64;
+ exp -= 64;
+ }
+ if (exp >= 32)
+ {
+ x *= ten32;
+ exp -= 32;
+ }
+ if (exp >= 16)
+ {
+ x *= (_Decimal64) 10000000000000000.0;
+ exp -= 16;
+ }
+ if (exp >= 8)
+ {
+ x *= (_Decimal64) 100000000.0;
+ exp -= 8;
+ }
+ if (exp >= 4)
+ {
+ x *= (_Decimal64) 10000.0;
+ exp -= 4;
+ }
+ if (exp >= 2)
+ {
+ x *= (_Decimal64) 100.0;
+ exp -= 2;
+ }
+ if (exp >= 1)
+ {
+ x *= (_Decimal64) 10.0;
+ exp -= 1;
+ }
+ }
+ else if (exp < 0)
+ {
+ _Decimal64 ten16 = (double) 1e16; /* 10^16 is exactly representable
+ in binary64 */
+ _Decimal64 ten32 = ten16 * ten16;
+ _Decimal64 ten64 = ten32 * ten32;
+ _Decimal64 ten128 = ten64 * ten64;
+ _Decimal64 ten256 = ten128 * ten128;
+ if (exp <= -256)
+ {
+ x /= ten256;
+ exp += 256;
+ }
+ if (exp <= -128)
+ {
+ x /= ten128;
+ exp += 128;
+ }
+ if (exp <= -64)
+ {
+ x /= ten64;
+ exp += 64;
+ }
+ if (exp <= -32)
+ {
+ x /= ten32;
+ exp += 32;
+ }
+ if (exp <= -16)
+ {
+ x /= (_Decimal64) 10000000000000000.0;
+ exp += 16;
+ }
+ if (exp <= -8)
+ {
+ x /= (_Decimal64) 100000000.0;
+ exp += 8;
+ }
+ if (exp <= -4)
+ {
+ x /= (_Decimal64) 10000.0;
+ exp += 4;
+ }
+ if (exp <= -2)
+ {
+ x /= (_Decimal64) 100.0;
+ exp += 2;
+ }
+ if (exp <= -1)
+ {
+ x /= (_Decimal64) 10.0;
+ exp += 1;
+ }
+ }
+
+ if (sign)
+ x = -x;
+
+ return x;
+}
+#endif
_Decimal64
mpfr_get_decimal64 (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_f.c b/Build/source/libs/mpfr/mpfr-src/src/get_f.c
index 942b0d7c5a3..ef5dec9928a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_f.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_f.c
@@ -20,8 +20,10 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#define MPFR_NEED_MPF_INTERNALS
#include "mpfr-impl.h"
+#ifndef MPFR_USE_MINI_GMP
/* Since MPFR-3.0, return the usual inexact value.
The erange flag is set if an error occurred in the conversion
(y is NaN, +Inf, or -Inf that have no equivalent in mpf)
@@ -44,7 +46,7 @@ mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
}
else if (MPFR_IS_NAN (y))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return 0;
}
else /* y is plus infinity (resp. minus infinity), set x to the maximum
@@ -53,7 +55,7 @@ mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
int i;
mp_limb_t *xp;
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
/* To this day, [mp_exp_t] and mp_size_t are #defined as the same
type */
@@ -63,7 +65,7 @@ mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
SIZ (x) = sx;
xp = PTR (x);
for (i = 0; i < sx; i++)
- xp[i] = MP_LIMB_T_MAX;
+ xp[i] = MPFR_LIMB_MAX;
if (MPFR_IS_POS (y))
return -1;
@@ -146,3 +148,4 @@ mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
return inex;
}
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_float128.c b/Build/source/libs/mpfr/mpfr-src/src/get_float128.c
new file mode 100644
index 00000000000..46b612c059c
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_float128.c
@@ -0,0 +1,129 @@
+/* mpfr_get_float128 -- convert a multiple precision floating-point
+ number to a __float128 number
+
+Copyright 2012-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#ifdef MPFR_WANT_FLOAT128
+
+/* generic code */
+__float128
+mpfr_get_float128 (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return (__float128) mpfr_get_d (x, rnd_mode);
+ else /* now x is a normal non-zero number */
+ {
+ __float128 r; /* result */
+ __float128 m;
+ mpfr_exp_t e; /* exponent of x (before rounding) */
+ mpfr_exp_t sh; /* exponent shift, so that x/2^sh is in the double range */
+ const int emin = -16381;
+ const int esub = emin - IEEE_FLOAT128_MANT_DIG;
+ int sign;
+
+ sign = MPFR_SIGN (x);
+ e = MPFR_GET_EXP (x);
+
+ if (MPFR_UNLIKELY (e <= esub))
+ {
+ if (MPFR_IS_LIKE_RNDZ (rnd_mode, sign < 0) ||
+ (rnd_mode == MPFR_RNDN && (e < esub || mpfr_powerof2_raw (x))))
+ return sign < 0 ? -0.0 : 0.0;
+ r = 1.0;
+ sh = esub;
+ }
+ else
+ {
+ mpfr_t y;
+ mp_limb_t *yp;
+ int prec, i; /* small enough to fit in an int */
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* First round x to the target __float128 precision, taking the
+ reduced precision of the subnormals into account, so that all
+ subsequent operations are exact (this avoids double rounding
+ problems). */
+ prec = e < emin ? e - esub : IEEE_FLOAT128_MANT_DIG;
+ MPFR_ASSERTD (prec >= MPFR_PREC_MIN);
+ mpfr_init2 (y, prec);
+
+ mpfr_set (y, x, rnd_mode);
+ sh = MPFR_GET_EXP (y);
+ MPFR_SET_EXP (y, 0);
+ MPFR_SET_POS (y);
+ yp = MPFR_MANT (y);
+
+ r = 0.0;
+ for (i = 0; i < MPFR_LIMB_SIZE (y); i++)
+ {
+ /* Note: MPFR_LIMB_MAX is avoided below as it might not
+ always work if GMP_NUMB_BITS > IEEE_FLOAT128_MANT_DIG.
+ MPFR_LIMB_HIGHBIT has the advantage to fit on 1 bit. */
+ r += yp[i];
+ r *= 1 / (2 * (__float128) MPFR_LIMB_HIGHBIT);
+ }
+
+ mpfr_clear (y);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+
+ /* we now have to multiply r by 2^sh */
+ MPFR_ASSERTD (r > 0);
+ if (sh != 0)
+ {
+ /* An overflow may occur (example: 0.5*2^1024) */
+ while (r < 1.0)
+ {
+ r += r;
+ sh--;
+ }
+
+ if (sh > 0)
+ m = 2.0;
+ else
+ {
+ m = 0.5;
+ sh = -sh;
+ }
+
+ for (;;)
+ {
+ if (sh % 2)
+ r = r * m;
+ sh >>= 1;
+ if (sh == 0)
+ break;
+ m = m * m;
+ }
+ }
+ if (sign < 0)
+ r = -r;
+ return r;
+ }
+}
+
+#endif /* MPFR_WANT_FLOAT128 */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_flt.c b/Build/source/libs/mpfr/mpfr-src/src/get_flt.c
index 168c58702db..c1ba68e4baf 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_flt.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_flt.c
@@ -50,7 +50,10 @@ mpfr_get_flt (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
rnd_mode = negative ? MPFR_RNDD : MPFR_RNDU;
/* FIXME: The code below assumes the IEEE-754 binary32 format
- with subnormal support. */
+ with subnormal support. Fix it by converting to double, then
+ to float, and in case of binary radix (for which we want
+ correct rounding), handle double-rounding issues somewhere
+ in the code? */
/* the smallest positive normal float number is 2^(-126) = 0.5*2^(-125),
and the smallest positive subnormal number is 2^(-149) = 0.5*2^(-148) */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_ld.c b/Build/source/libs/mpfr/mpfr-src/src/get_ld.c
index b1d77c77145..8a3ad88ad57 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_ld.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_ld.c
@@ -21,94 +21,28 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <float.h>
+#include <float.h> /* needed so that MPFR_LDBL_MANT_DIG is correctly defined */
#include "mpfr-impl.h"
-#ifndef HAVE_LDOUBLE_IEEE_EXT_LITTLE
+#if defined(HAVE_LDOUBLE_IS_DOUBLE)
+/* special code when "long double" is the same format as "double" */
long double
mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
-
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
- return (long double) mpfr_get_d (x, rnd_mode);
- else /* now x is a normal non-zero number */
- {
- long double r; /* result */
- long double m;
- double s; /* part of result */
- mpfr_exp_t sh; /* exponent shift, so that x/2^sh is in the double range */
- mpfr_t y, z;
- int sign;
-
- /* first round x to the target long double precision, so that
- all subsequent operations are exact (this avoids double rounding
- problems) */
- mpfr_init2 (y, MPFR_LDBL_MANT_DIG);
- mpfr_init2 (z, MPFR_LDBL_MANT_DIG);
- /* Note about the precision of z: even though IEEE_DBL_MANT_DIG is
- sufficient, z has been set to the same precision as y so that
- the mpfr_sub below calls mpfr_sub1sp, which is faster than the
- generic subtraction, even in this particular case (from tests
- done by Patrick Pelissier on a 64-bit Core2 Duo against r7285).
- But here there is an important cancellation in the subtraction.
- TODO: get more information about what has been tested. */
-
- mpfr_set (y, x, rnd_mode);
- sh = MPFR_GET_EXP (y);
- sign = MPFR_SIGN (y);
- MPFR_SET_EXP (y, 0);
- MPFR_SET_POS (y);
-
- r = 0.0;
- do {
- s = mpfr_get_d (y, MPFR_RNDN); /* high part of y */
- r += (long double) s;
- mpfr_set_d (z, s, MPFR_RNDN); /* exact */
- mpfr_sub (y, y, z, MPFR_RNDN); /* exact */
- } while (!MPFR_IS_ZERO (y));
-
- mpfr_clear (z);
- mpfr_clear (y);
-
- /* we now have to multiply back by 2^sh */
- MPFR_ASSERTD (r > 0);
- if (sh != 0)
- {
- /* An overflow may occurs (example: 0.5*2^1024) */
- while (r < 1.0)
- {
- r += r;
- sh--;
- }
-
- if (sh > 0)
- m = 2.0;
- else
- {
- m = 0.5;
- sh = -sh;
- }
-
- for (;;)
- {
- if (sh % 2)
- r = r * m;
- sh >>= 1;
- if (sh == 0)
- break;
- m = m * m;
- }
- }
- if (sign < 0)
- r = -r;
- return r;
- }
+ return (long double) mpfr_get_d (x, rnd_mode);
}
-#else
+#elif defined(HAVE_LDOUBLE_IEEE_EXT_LITTLE)
+/* Note: The code will return a result with a 64-bit precision, even
+ if the rounding precision is only 53 bits like on FreeBSD and
+ NetBSD 6- (or with GCC's -mpc64 option to simulate this on other
+ platforms). This is consistent with how strtold behaves in these
+ cases, for instance. */
+
+/* special code for IEEE 754 little-endian extended format */
long double
mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
@@ -122,7 +56,7 @@ mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_init2 (tmp, MPFR_LDBL_MANT_DIG);
inex = mpfr_set (tmp, x, rnd_mode);
- mpfr_set_emin (-16381-63); /* emin=-16444 */
+ mpfr_set_emin (-16381-63); /* emin=-16444, see below */
mpfr_set_emax (16384);
mpfr_subnormalize (tmp, mpfr_check_range (tmp, inex, rnd_mode), rnd_mode);
mpfr_prec_round (tmp, 64, MPFR_RNDZ); /* exact */
@@ -135,10 +69,12 @@ mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
tmpmant = MPFR_MANT (tmp);
e = MPFR_GET_EXP (tmp);
- /* the smallest normal number is 2^(-16382), which is 0.5*2^(-16381)
- in MPFR, thus any exponent <= -16382 corresponds to a subnormal
- number */
+ /* The smallest positive normal number is 2^(-16382), which is
+ 0.5*2^(-16381) in MPFR, thus any exponent <= -16382 corresponds to a
+ subnormal number. The smallest positive subnormal number is 2^(-16445)
+ which is 0.5*2^(-16444) in MPFR thus 0 <= denorm <= 63. */
denorm = MPFR_UNLIKELY (e <= -16382) ? - e - 16382 + 1 : 0;
+ MPFR_ASSERTD (0 <= denorm && denorm < 64);
#if GMP_NUMB_BITS >= 64
ld.s.manl = (tmpmant[0] >> denorm);
ld.s.manh = (tmpmant[0] >> denorm) >> 32;
@@ -153,7 +89,7 @@ mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
ld.s.manl = (tmpmant[0] >> denorm) | (tmpmant[1] << (32 - denorm));
ld.s.manh = tmpmant[1] >> denorm;
}
- else /* 32 <= denorm <= 64 */
+ else /* 32 <= denorm < 64 */
{
ld.s.manl = tmpmant[1] >> (denorm - 32);
ld.s.manh = 0;
@@ -177,6 +113,128 @@ mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
return ld.ld;
}
+#else
+
+/* generic code */
+long double
+mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return (long double) mpfr_get_d (x, rnd_mode);
+ else /* now x is a normal non-zero number */
+ {
+ long double r; /* result */
+ double s; /* part of result */
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+#if defined(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE)
+ if (MPFR_LDBL_MANT_DIG == 106)
+ {
+ /* Assume double-double format (as found with the PowerPC ABI).
+ The generic code below isn't used because numbers with
+ precision > 106 would not be supported. */
+ s = mpfr_get_d (x, MPFR_RNDN); /* high part of x */
+ /* Let's first consider special cases separately. The test for
+ infinity is really needed to avoid a NaN result. The test
+ for NaN is mainly for optimization. The test for 0 is useful
+ to get the correct sign (assuming mpfr_get_d supports signed
+ zeros on the implementation). */
+ if (s == 0 || DOUBLE_ISNAN (s) || DOUBLE_ISINF (s))
+ r = (long double) s;
+ else
+ {
+ mpfr_t y, z;
+
+ mpfr_init2 (y, mpfr_get_prec (x));
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG); /* keep the precision small */
+ mpfr_set_d (z, s, MPFR_RNDN); /* exact */
+ mpfr_sub (y, x, z, MPFR_RNDN); /* exact */
+ /* Add the second part of y (in the correct rounding mode). */
+ r = (long double) s + (long double) mpfr_get_d (y, rnd_mode);
+ mpfr_clear (z);
+ mpfr_clear (y);
+ }
+ }
+ else
+#endif
+ {
+ long double m;
+ mpfr_exp_t sh; /* exponent shift -> x/2^sh is in the double range */
+ mpfr_t y, z;
+ int sign;
+
+ /* First round x to the target long double precision, so that
+ all subsequent operations are exact (this avoids double rounding
+ problems). However if the format contains numbers that have more
+ precision, MPFR won't be able to generate such numbers. */
+ mpfr_init2 (y, MPFR_LDBL_MANT_DIG);
+ mpfr_init2 (z, MPFR_LDBL_MANT_DIG);
+ /* Note about the precision of z: even though IEEE_DBL_MANT_DIG is
+ sufficient, z has been set to the same precision as y so that
+ the mpfr_sub below calls mpfr_sub1sp, which is faster than the
+ generic subtraction, even in this particular case (from tests
+ done by Patrick Pelissier on a 64-bit Core2 Duo against r7285).
+ But here there is an important cancellation in the subtraction.
+ TODO: get more information about what has been tested. */
+
+ mpfr_set (y, x, rnd_mode);
+ sh = MPFR_GET_EXP (y);
+ sign = MPFR_SIGN (y);
+ MPFR_SET_EXP (y, 0);
+ MPFR_SET_POS (y);
+
+ r = 0.0;
+ do
+ {
+ s = mpfr_get_d (y, MPFR_RNDN); /* high part of y */
+ r += (long double) s;
+ mpfr_set_d (z, s, MPFR_RNDN); /* exact */
+ mpfr_sub (y, y, z, MPFR_RNDN); /* exact */
+ }
+ while (!MPFR_IS_ZERO (y));
+
+ mpfr_clear (z);
+ mpfr_clear (y);
+
+ /* we now have to multiply back by 2^sh */
+ MPFR_ASSERTD (r > 0);
+ if (sh != 0)
+ {
+ /* An overflow may occur (example: 0.5*2^1024) */
+ while (r < 1.0)
+ {
+ r += r;
+ sh--;
+ }
+
+ if (sh > 0)
+ m = 2.0;
+ else
+ {
+ m = 0.5;
+ sh = -sh;
+ }
+
+ for (;;)
+ {
+ if (sh % 2)
+ r = r * m;
+ sh >>= 1;
+ if (sh == 0)
+ break;
+ m = m * m;
+ }
+ }
+ if (sign < 0)
+ r = -r;
+ }
+ MPFR_SAVE_EXPO_FREE (expo);
+ return r;
+ }
+}
+
#endif
/* contributed by Damien Stehle */
@@ -190,8 +248,7 @@ mpfr_get_ld_2exp (long *expptr, mpfr_srcptr src, mpfr_rnd_t rnd_mode)
if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
return (long double) mpfr_get_d_2exp (expptr, src, rnd_mode);
- tmp[0] = *src; /* Hack copy mpfr_t */
- MPFR_SET_EXP (tmp, 0);
+ MPFR_ALIAS (tmp, src, MPFR_SIGN (src), 0);
ret = mpfr_get_ld (tmp, rnd_mode);
if (MPFR_IS_PURE_FP(src))
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_q.c b/Build/source/libs/mpfr/mpfr-src/src/get_q.c
new file mode 100644
index 00000000000..8cc2bc02b9c
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_q.c
@@ -0,0 +1,63 @@
+/* mpfr_get_q -- get a multiple-precision rational from
+ a floating-point number
+
+Copyright 2004, 2006-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#ifndef MPFR_USE_MINI_GMP
+/* part of the code was copied from get_z.c */
+void
+mpfr_get_q (mpq_ptr q, mpfr_srcptr f)
+{
+ mpfr_exp_t exp;
+ mpz_ptr u = mpq_numref (q);
+ mpz_ptr v = mpq_denref (q);
+
+ /* v is set to 1 and will not be changed directly.
+ This ensures that q will be canonical. */
+ mpz_set_ui (v, 1);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ {
+ if (MPFR_UNLIKELY (MPFR_NOTZERO (f)))
+ MPFR_SET_ERANGEFLAG ();
+ mpz_set_ui (u, 0);
+ /* The ternary value is 0 even for infinity. Giving the rounding
+ direction in this case would not make much sense anyway, and
+ the direction would not necessarily match rnd. */
+ }
+ else
+ {
+ exp = mpfr_get_z_2exp (u, f);
+ if (exp >= 0)
+ {
+ MPFR_ASSERTN (exp <= (mp_bitcnt_t) -1);
+ mpz_mul_2exp (u, u, exp);
+ }
+ else /* exp < 0 */
+ {
+ MPFR_ASSERTN (-exp <= (mp_bitcnt_t) -1);
+ mpq_div_2exp (q, q, -exp);
+ }
+ }
+}
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_si.c b/Build/source/libs/mpfr/mpfr-src/src/get_si.c
index 134874c3068..48e12c21b94 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_si.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_si.c
@@ -28,10 +28,11 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd)
mpfr_prec_t prec;
long s;
mpfr_t x;
+ MPFR_SAVE_EXPO_DECL (expo);
if (MPFR_UNLIKELY (!mpfr_fits_slong_p (f, rnd)))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return MPFR_IS_NAN (f) ? 0 :
MPFR_IS_NEG (f) ? LONG_MIN : LONG_MAX;
}
@@ -39,14 +40,22 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd)
if (MPFR_IS_ZERO (f))
return (long) 0;
- /* determine prec of long */
- for (s = LONG_MIN, prec = 0; s != 0; s /= 2, prec++)
+ /* Determine the precision of long. |LONG_MIN| may have one more bit
+ as an integer, but in this case, this is a power of 2, thus fits
+ in a precision-prec floating-point number. */
+ for (s = LONG_MAX, prec = 0; s != 0; s /= 2, prec++)
{ }
+ MPFR_SAVE_EXPO_MARK (expo);
+
/* first round to prec bits */
mpfr_init2 (x, prec);
mpfr_rint (x, f, rnd);
+ /* The flags from mpfr_rint are the wanted ones. In particular,
+ it sets the inexact flag when necessary. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
/* warning: if x=0, taking its exponent is illegal */
if (MPFR_UNLIKELY (MPFR_IS_ZERO(x)))
s = 0;
@@ -60,10 +69,12 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd)
exp = MPFR_GET_EXP (x); /* since |x| >= 1, exp >= 1 */
n = MPFR_LIMB_SIZE(x);
a = MPFR_MANT(x)[n - 1] >> (GMP_NUMB_BITS - exp);
- s = MPFR_SIGN(f) > 0 ? a : a <= LONG_MAX ? - (long) a : LONG_MIN;
+ s = MPFR_IS_POS (f) ? a : a <= LONG_MAX ? - (long) a : LONG_MIN;
}
mpfr_clear (x);
+ MPFR_SAVE_EXPO_FREE (expo);
+
return s;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_sj.c b/Build/source/libs/mpfr/mpfr-src/src/get_sj.c
index 5e92199d009..b2e04c6c98a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_sj.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_sj.c
@@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-# include "config.h" /* for a build within gmp */
+# include "config.h"
#endif
#include "mpfr-intmax.h"
@@ -35,10 +35,11 @@ mpfr_get_sj (mpfr_srcptr f, mpfr_rnd_t rnd)
intmax_t r;
mpfr_prec_t prec;
mpfr_t x;
+ MPFR_SAVE_EXPO_DECL (expo);
if (MPFR_UNLIKELY (!mpfr_fits_intmax_p (f, rnd)))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return MPFR_IS_NAN (f) ? 0 :
MPFR_IS_NEG (f) ? MPFR_INTMAX_MIN : MPFR_INTMAX_MAX;
}
@@ -46,20 +47,24 @@ mpfr_get_sj (mpfr_srcptr f, mpfr_rnd_t rnd)
if (MPFR_IS_ZERO (f))
return (intmax_t) 0;
- /* determine the precision of intmax_t */
- for (r = MPFR_INTMAX_MIN, prec = 0; r != 0; r /= 2, prec++)
+ /* Determine the precision of intmax_t. |INTMAX_MIN| may have one
+ more bit as an integer, but in this case, this is a power of 2,
+ thus fits in a precision-prec floating-point number. */
+ for (r = MPFR_INTMAX_MAX, prec = 0; r != 0; r /= 2, prec++)
{ }
- /* Note: though INTMAX_MAX would have been sufficient for the conversion,
- we chose INTMAX_MIN so that INTMAX_MIN - 1 is always representable in
- precision prec; this is useful to detect overflows in MPFR_RNDZ (will
- be needed later). */
- /* Now, r = 0. */
+ MPFR_ASSERTD (r == 0);
+
+ MPFR_SAVE_EXPO_MARK (expo);
mpfr_init2 (x, prec);
mpfr_rint (x, f, rnd);
MPFR_ASSERTN (MPFR_IS_FP (x));
+ /* The flags from mpfr_rint are the wanted ones. In particular,
+ it sets the inexact flag when necessary. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
if (MPFR_NOTZERO (x))
{
mp_limb_t *xp;
@@ -67,15 +72,15 @@ mpfr_get_sj (mpfr_srcptr f, mpfr_rnd_t rnd)
xp = MPFR_MANT (x);
sh = MPFR_GET_EXP (x);
- MPFR_ASSERTN ((mpfr_prec_t) sh <= prec);
+ MPFR_ASSERTN ((mpfr_prec_t) sh <= prec + 1);
if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0
- && MPFR_UNLIKELY ((mpfr_prec_t) sh == prec))
+ && MPFR_UNLIKELY ((mpfr_prec_t) sh > prec))
{
/* 2's complement and x <= INTMAX_MIN: in the case mp_limb_t
has the same size as intmax_t, we cannot use the code in
the for loop since the operations would be performed in
unsigned arithmetic. */
- MPFR_ASSERTN (MPFR_IS_NEG (x) && (mpfr_powerof2_raw (x)));
+ MPFR_ASSERTN (MPFR_IS_NEG (x) && mpfr_powerof2_raw (x));
r = MPFR_INTMAX_MIN;
}
else if (MPFR_IS_POS (x))
@@ -117,6 +122,8 @@ mpfr_get_sj (mpfr_srcptr f, mpfr_rnd_t rnd)
mpfr_clear (x);
+ MPFR_SAVE_EXPO_FREE (expo);
+
return r;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_str.c b/Build/source/libs/mpfr/mpfr-src/src/get_str.c
index c71488dafd6..e1a8f0138f4 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_str.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_str.c
@@ -21,6 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#define MPFR_NEED_LONGLONG_H
+#include "mpfr-intmax.h"
#include "mpfr-impl.h"
static int mpfr_get_str_aux (char *const, mpfr_exp_t *const, mp_limb_t *const,
@@ -47,15 +48,19 @@ static const char num_to_text62[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define MPFR_ROUND_FAILED 3
-/* Input: an approximation r*2^f of a 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
- exponent in exp.
+/* Input: an approximation r*2^f to a real Y, with |r*2^f - Y| <= 2^(e+f).
+
+ If rounding is possible, returns:
+ - in s: a string representing the significand corresponding to
+ the integer nearest to Y, within the direction rnd;
+ - in exp: the exponent.
+
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 <= 62).
- m is the number of wanted digits in the mantissa.
+ e represents the maximal error in the approximation to Y (see above),
+ (e < 0 means that the approximation is known to be exact, i.e.,
+ r*2^f = Y).
+ b is the wanted base (2 <= b <= 62 or -36 <= b <= -2).
+ m is the number of wanted digits in the significand.
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).
@@ -77,6 +82,7 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
mpfr_rnd_t rnd)
{
const char *num_to_text;
+ int b0 = b; /* initial base (might be negative) */
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 */
@@ -95,7 +101,8 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
MPFR_TMP_MARK(marker);
- num_to_text = b < 37 ? num_to_text36 : num_to_text62;
+ num_to_text = (2 <= b0 && b0 <= 36) ? num_to_text36 : num_to_text62;
+ b = (b0 > 0) ? b0 : -b0;
/* R = 2^f sum r[i]K^(i)
r[i] = (r_(i,k-1)...r_(i,0))_2
@@ -103,7 +110,7 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
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)
+ where |r*2^f - Y| <= 2^(e+f)
the exponent of R is: f + n*GMP_NUMB_BITS
we must have e + f == f + n*GMP_NUMB_BITS - err
err = n*GMP_NUMB_BITS - e
@@ -111,8 +118,8 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
to determine the nearest integer, we thus need a precision of
n * GMP_NUMB_BITS + f */
- if (exact || mpfr_can_round_raw (r, n, (mp_size_t) 1,
- n * GMP_NUMB_BITS - e, MPFR_RNDN, rnd, n * GMP_NUMB_BITS + f))
+ if (exact || mpfr_round_p (r, n, n * GMP_NUMB_BITS - e,
+ n * GMP_NUMB_BITS + f + (rnd == MPFR_RNDN)))
{
/* compute the nearest integer to R */
@@ -124,9 +131,6 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
n * GMP_NUMB_BITS + f, rnd, &dir);
MPFR_ASSERTD(dir != MPFR_ROUND_FAILED);
- /* warning: mpfr_round_raw_generic returns MPFR_EVEN_INEX (2) or
- -MPFR_EVEN_INEX (-2) in case of even rounding */
-
if (ret) /* Y is a power of 2 */
{
if (j0)
@@ -145,7 +149,7 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
/* now the rounded value Y is in {r+i0, n-i0} */
- /* convert r+i0 into base b */
+ /* convert r+i0 into base b: we use b0 which might be in -36..-2 */
str1 = (unsigned char*) MPFR_TMP_ALLOC (m + 3); /* need one extra character for mpn_get_str */
size_s1 = mpn_get_str (str1, b, r + i0, n - i0);
@@ -240,17 +244,21 @@ mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
/***************************************************************************
* __gmpfr_l2b[b-2][0] is a 23-bit upper approximation to log(b)/log(2), *
- * __gmpfr_l2b[b-2][1] is a 76-bit upper approximation to log(2)/log(b). *
+ * __gmpfr_l2b[b-2][1] is a 77-bit upper approximation to log(2)/log(b). *
* The following code is generated by tests/tl2b (with an argument). *
***************************************************************************/
+#ifndef UINT64_C
+# define UINT64_C(c) c
+#endif
+
#if 0
#elif GMP_NUMB_BITS == 16
const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x0000, 0x8000 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x80000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x8000000000000000 };
+const mp_limb_t mpfr_l2b_2_0__tab[] = { UINT64_C(0x8000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x800000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -265,7 +273,7 @@ const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x8000 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x00000000, 0x00000000, 0x80000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x0000000000000000, 0x8000000000000000 };
+const mp_limb_t mpfr_l2b_2_1__tab[] = { UINT64_C(0x0000000000000000), UINT64_C(0x8000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x800000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -280,7 +288,7 @@ const mp_limb_t mpfr_l2b_3_0__tab[] = { 0x0e00, 0xcae0 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e0000000000 };
+const mp_limb_t mpfr_l2b_3_0__tab[] = { UINT64_C(0xcae00e0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -295,7 +303,7 @@ const mp_limb_t mpfr_l2b_3_1__tab[] = { 0x0448, 0xe94e, 0xa9a9, 0x9cc1, 0xa184 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_3_1__tab[] = { 0x04480000, 0xa9a9e94e, 0xa1849cc1 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_3_1__tab[] = { 0x0448000000000000, 0xa1849cc1a9a9e94e };
+const mp_limb_t mpfr_l2b_3_1__tab[] = { UINT64_C(0x0448000000000000), UINT64_C(0xa1849cc1a9a9e94e) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_3_1__tab[] = { 0xa1849cc1a9a9e94e04480000 };
#elif GMP_NUMB_BITS == 128
@@ -310,7 +318,7 @@ const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x0000, 0x8000 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x80000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x8000000000000000 };
+const mp_limb_t mpfr_l2b_4_0__tab[] = { UINT64_C(0x8000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x800000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -325,7 +333,7 @@ const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x8000 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x00000000, 0x00000000, 0x80000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x0000000000000000, 0x8000000000000000 };
+const mp_limb_t mpfr_l2b_4_1__tab[] = { UINT64_C(0x0000000000000000), UINT64_C(0x8000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x800000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -340,7 +348,7 @@ const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x7a00, 0x949a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a0000000000 };
+const mp_limb_t mpfr_l2b_5_0__tab[] = { UINT64_C(0x949a7a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -355,7 +363,7 @@ const mp_limb_t mpfr_l2b_5_1__tab[] = { 0x67b8, 0x9728, 0x287b, 0xa348, 0xdc81 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_5_1__tab[] = { 0x67b80000, 0x287b9728, 0xdc81a348 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_5_1__tab[] = { 0x67b8000000000000, 0xdc81a348287b9728 };
+const mp_limb_t mpfr_l2b_5_1__tab[] = { UINT64_C(0x67b8000000000000), UINT64_C(0xdc81a348287b9728) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_5_1__tab[] = { 0xdc81a348287b972867b80000 };
#elif GMP_NUMB_BITS == 128
@@ -370,7 +378,7 @@ const mp_limb_t mpfr_l2b_6_0__tab[] = { 0x0800, 0xa570 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa5700800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa570080000000000 };
+const mp_limb_t mpfr_l2b_6_0__tab[] = { UINT64_C(0xa570080000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa57008000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -385,7 +393,7 @@ const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xff10, 0xf9e9, 0xe054, 0x9236, 0xc611 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xff100000, 0xe054f9e9, 0xc6119236 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xff10000000000000, 0xc6119236e054f9e9 };
+const mp_limb_t mpfr_l2b_6_1__tab[] = { UINT64_C(0xff10000000000000), UINT64_C(0xc6119236e054f9e9) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xc6119236e054f9e9ff100000 };
#elif GMP_NUMB_BITS == 128
@@ -400,7 +408,7 @@ const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb400, 0xb3ab };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb40000000000 };
+const mp_limb_t mpfr_l2b_7_0__tab[] = { UINT64_C(0xb3abb40000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb4000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -415,7 +423,7 @@ const mp_limb_t mpfr_l2b_7_1__tab[] = { 0x37b8, 0xa711, 0x754d, 0xc9d6, 0xb660 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_7_1__tab[] = { 0x37b80000, 0x754da711, 0xb660c9d6 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_7_1__tab[] = { 0x37b8000000000000, 0xb660c9d6754da711 };
+const mp_limb_t mpfr_l2b_7_1__tab[] = { UINT64_C(0x37b8000000000000), UINT64_C(0xb660c9d6754da711) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_7_1__tab[] = { 0xb660c9d6754da71137b80000 };
#elif GMP_NUMB_BITS == 128
@@ -430,7 +438,7 @@ const mp_limb_t mpfr_l2b_8_0__tab[] = { 0x0000, 0xc000 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc0000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc000000000000000 };
+const mp_limb_t mpfr_l2b_8_0__tab[] = { UINT64_C(0xc000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc00000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -445,7 +453,7 @@ const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaab0, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaab00000, 0xaaaaaaaa, 0xaaaaaaaa };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaab0000000000000, 0xaaaaaaaaaaaaaaaa };
+const mp_limb_t mpfr_l2b_8_1__tab[] = { UINT64_C(0xaab0000000000000), UINT64_C(0xaaaaaaaaaaaaaaaa) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaaaaaaaaaaaaaaaaaab00000 };
#elif GMP_NUMB_BITS == 128
@@ -460,7 +468,7 @@ const mp_limb_t mpfr_l2b_9_0__tab[] = { 0x0e00, 0xcae0 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e0000000000 };
+const mp_limb_t mpfr_l2b_9_0__tab[] = { UINT64_C(0xcae00e0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -475,7 +483,7 @@ const mp_limb_t mpfr_l2b_9_1__tab[] = { 0x0448, 0xe94e, 0xa9a9, 0x9cc1, 0xa184 }
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_9_1__tab[] = { 0x04480000, 0xa9a9e94e, 0xa1849cc1 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_9_1__tab[] = { 0x0448000000000000, 0xa1849cc1a9a9e94e };
+const mp_limb_t mpfr_l2b_9_1__tab[] = { UINT64_C(0x0448000000000000), UINT64_C(0xa1849cc1a9a9e94e) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_9_1__tab[] = { 0xa1849cc1a9a9e94e04480000 };
#elif GMP_NUMB_BITS == 128
@@ -490,7 +498,7 @@ const mp_limb_t mpfr_l2b_10_0__tab[] = { 0x7a00, 0xd49a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a0000000000 };
+const mp_limb_t mpfr_l2b_10_0__tab[] = { UINT64_C(0xd49a7a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -505,7 +513,7 @@ const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x8f90, 0xf798, 0xfbcf, 0x9a84, 0x9a20
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x8f900000, 0xfbcff798, 0x9a209a84 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x8f90000000000000, 0x9a209a84fbcff798 };
+const mp_limb_t mpfr_l2b_10_1__tab[] = { UINT64_C(0x8f90000000000000), UINT64_C(0x9a209a84fbcff798) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x9a209a84fbcff7988f900000 };
#elif GMP_NUMB_BITS == 128
@@ -520,7 +528,7 @@ const mp_limb_t mpfr_l2b_11_0__tab[] = { 0x5400, 0xdd67 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd675400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd67540000000000 };
+const mp_limb_t mpfr_l2b_11_0__tab[] = { UINT64_C(0xdd67540000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd6754000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -535,7 +543,7 @@ const mp_limb_t mpfr_l2b_11_1__tab[] = { 0xe170, 0x9d10, 0xeb22, 0x4e0e, 0x9400
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_11_1__tab[] = { 0xe1700000, 0xeb229d10, 0x94004e0e };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_11_1__tab[] = { 0xe170000000000000, 0x94004e0eeb229d10 };
+const mp_limb_t mpfr_l2b_11_1__tab[] = { UINT64_C(0xe170000000000000), UINT64_C(0x94004e0eeb229d10) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_11_1__tab[] = { 0x94004e0eeb229d10e1700000 };
#elif GMP_NUMB_BITS == 128
@@ -550,7 +558,7 @@ const mp_limb_t mpfr_l2b_12_0__tab[] = { 0x0800, 0xe570 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe5700800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe570080000000000 };
+const mp_limb_t mpfr_l2b_12_0__tab[] = { UINT64_C(0xe570080000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe57008000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -565,7 +573,7 @@ const mp_limb_t mpfr_l2b_12_1__tab[] = { 0xfe28, 0x1c24, 0x0b03, 0x9c1a, 0x8ed1
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_12_1__tab[] = { 0xfe280000, 0x0b031c24, 0x8ed19c1a };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_12_1__tab[] = { 0xfe28000000000000, 0x8ed19c1a0b031c24 };
+const mp_limb_t mpfr_l2b_12_1__tab[] = { UINT64_C(0xfe28000000000000), UINT64_C(0x8ed19c1a0b031c24) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_12_1__tab[] = { 0x8ed19c1a0b031c24fe280000 };
#elif GMP_NUMB_BITS == 128
@@ -580,7 +588,7 @@ const mp_limb_t mpfr_l2b_13_0__tab[] = { 0x0200, 0xecd4 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd40200 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd4020000000000 };
+const mp_limb_t mpfr_l2b_13_0__tab[] = { UINT64_C(0xecd4020000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd402000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -595,7 +603,7 @@ const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x57f8, 0xf7b4, 0xcb20, 0xa7c6, 0x8a5c
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x57f80000, 0xcb20f7b4, 0x8a5ca7c6 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x57f8000000000000, 0x8a5ca7c6cb20f7b4 };
+const mp_limb_t mpfr_l2b_13_1__tab[] = { UINT64_C(0x57f8000000000000), UINT64_C(0x8a5ca7c6cb20f7b4) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x8a5ca7c6cb20f7b457f80000 };
#elif GMP_NUMB_BITS == 128
@@ -610,7 +618,7 @@ const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xb400, 0xf3ab };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb40000000000 };
+const mp_limb_t mpfr_l2b_14_0__tab[] = { UINT64_C(0xf3abb40000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb4000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -625,7 +633,7 @@ const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x85a8, 0x5cab, 0x96b5, 0xfff6, 0x8679
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x85a80000, 0x96b55cab, 0x8679fff6 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x85a8000000000000, 0x8679fff696b55cab };
+const mp_limb_t mpfr_l2b_14_1__tab[] = { UINT64_C(0x85a8000000000000), UINT64_C(0x8679fff696b55cab) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x8679fff696b55cab85a80000 };
#elif GMP_NUMB_BITS == 128
@@ -640,7 +648,7 @@ const mp_limb_t mpfr_l2b_15_0__tab[] = { 0x8000, 0xfa0a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a8000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a800000000000 };
+const mp_limb_t mpfr_l2b_15_0__tab[] = { UINT64_C(0xfa0a800000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a80000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -655,7 +663,7 @@ const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x6f80, 0xa6aa, 0x69f0, 0xee23, 0x830c
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x6f800000, 0x69f0a6aa, 0x830cee23 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x6f80000000000000, 0x830cee2369f0a6aa };
+const mp_limb_t mpfr_l2b_15_1__tab[] = { UINT64_C(0x6f80000000000000), UINT64_C(0x830cee2369f0a6aa) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x830cee2369f0a6aa6f800000 };
#elif GMP_NUMB_BITS == 128
@@ -670,7 +678,7 @@ const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x0000, 0x8000 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x80000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x8000000000000000 };
+const mp_limb_t mpfr_l2b_16_0__tab[] = { UINT64_C(0x8000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x800000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -685,7 +693,7 @@ const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x8000
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x00000000, 0x00000000, 0x80000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x0000000000000000, 0x8000000000000000 };
+const mp_limb_t mpfr_l2b_16_1__tab[] = { UINT64_C(0x0000000000000000), UINT64_C(0x8000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x800000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -700,7 +708,7 @@ const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x8000, 0x82cc };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc8000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc800000000000 };
+const mp_limb_t mpfr_l2b_17_0__tab[] = { UINT64_C(0x82cc800000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc80000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -715,7 +723,7 @@ const mp_limb_t mpfr_l2b_17_1__tab[] = { 0x8720, 0x259b, 0x62c4, 0xabf5, 0xfa85
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_17_1__tab[] = { 0x87200000, 0x62c4259b, 0xfa85abf5 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_17_1__tab[] = { 0x8720000000000000, 0xfa85abf562c4259b };
+const mp_limb_t mpfr_l2b_17_1__tab[] = { UINT64_C(0x8720000000000000), UINT64_C(0xfa85abf562c4259b) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_17_1__tab[] = { 0xfa85abf562c4259b87200000 };
#elif GMP_NUMB_BITS == 128
@@ -730,7 +738,7 @@ const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x0800, 0x8570 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x85700800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x8570080000000000 };
+const mp_limb_t mpfr_l2b_18_0__tab[] = { UINT64_C(0x8570080000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x857008000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -745,7 +753,7 @@ const mp_limb_t mpfr_l2b_18_1__tab[] = { 0x3698, 0x1378, 0x5537, 0x6634, 0xf591
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_18_1__tab[] = { 0x36980000, 0x55371378, 0xf5916634 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_18_1__tab[] = { 0x3698000000000000, 0xf591663455371378 };
+const mp_limb_t mpfr_l2b_18_1__tab[] = { UINT64_C(0x3698000000000000), UINT64_C(0xf591663455371378) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_18_1__tab[] = { 0xf59166345537137836980000 };
#elif GMP_NUMB_BITS == 128
@@ -760,7 +768,7 @@ const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x0600, 0x87ef };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef0600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef060000000000 };
+const mp_limb_t mpfr_l2b_19_0__tab[] = { UINT64_C(0x87ef060000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef06000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -775,7 +783,7 @@ const mp_limb_t mpfr_l2b_19_1__tab[] = { 0x0db8, 0x558c, 0x62ed, 0x08c0, 0xf10f
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_19_1__tab[] = { 0x0db80000, 0x62ed558c, 0xf10f08c0 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_19_1__tab[] = { 0x0db8000000000000, 0xf10f08c062ed558c };
+const mp_limb_t mpfr_l2b_19_1__tab[] = { UINT64_C(0x0db8000000000000), UINT64_C(0xf10f08c062ed558c) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_19_1__tab[] = { 0xf10f08c062ed558c0db80000 };
#elif GMP_NUMB_BITS == 128
@@ -790,7 +798,7 @@ const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x3e00, 0x8a4d };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e0000000000 };
+const mp_limb_t mpfr_l2b_20_0__tab[] = { UINT64_C(0x8a4d3e0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -805,7 +813,7 @@ const mp_limb_t mpfr_l2b_20_1__tab[] = { 0x0b40, 0xa71c, 0x1cc1, 0x690a, 0xecee
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_20_1__tab[] = { 0x0b400000, 0x1cc1a71c, 0xecee690a };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_20_1__tab[] = { 0x0b40000000000000, 0xecee690a1cc1a71c };
+const mp_limb_t mpfr_l2b_20_1__tab[] = { UINT64_C(0x0b40000000000000), UINT64_C(0xecee690a1cc1a71c) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_20_1__tab[] = { 0xecee690a1cc1a71c0b400000 };
#elif GMP_NUMB_BITS == 128
@@ -820,7 +828,7 @@ const mp_limb_t mpfr_l2b_21_0__tab[] = { 0xde00, 0x8c8d };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde0000000000 };
+const mp_limb_t mpfr_l2b_21_0__tab[] = { UINT64_C(0x8c8dde0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -835,7 +843,7 @@ const mp_limb_t mpfr_l2b_21_1__tab[] = { 0x4108, 0x6b26, 0xb3d0, 0x63c1, 0xe922
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_21_1__tab[] = { 0x41080000, 0xb3d06b26, 0xe92263c1 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_21_1__tab[] = { 0x4108000000000000, 0xe92263c1b3d06b26 };
+const mp_limb_t mpfr_l2b_21_1__tab[] = { UINT64_C(0x4108000000000000), UINT64_C(0xe92263c1b3d06b26) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_21_1__tab[] = { 0xe92263c1b3d06b2641080000 };
#elif GMP_NUMB_BITS == 128
@@ -850,7 +858,7 @@ const mp_limb_t mpfr_l2b_22_0__tab[] = { 0xaa00, 0x8eb3 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa0000000000 };
+const mp_limb_t mpfr_l2b_22_0__tab[] = { UINT64_C(0x8eb3aa0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -865,7 +873,7 @@ const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xdbe8, 0xf061, 0x60b9, 0x2c4d, 0xe5a0
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xdbe80000, 0x60b9f061, 0xe5a02c4d };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xdbe8000000000000, 0xe5a02c4d60b9f061 };
+const mp_limb_t mpfr_l2b_22_1__tab[] = { UINT64_C(0xdbe8000000000000), UINT64_C(0xe5a02c4d60b9f061) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xe5a02c4d60b9f061dbe80000 };
#elif GMP_NUMB_BITS == 128
@@ -880,7 +888,7 @@ const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x0600, 0x90c1 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c10600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c1060000000000 };
+const mp_limb_t mpfr_l2b_23_0__tab[] = { UINT64_C(0x90c1060000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c106000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -895,7 +903,7 @@ const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xc3e0, 0x586a, 0x46b9, 0xcadd, 0xe25e
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xc3e00000, 0x46b9586a, 0xe25ecadd };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xc3e0000000000000, 0xe25ecadd46b9586a };
+const mp_limb_t mpfr_l2b_23_1__tab[] = { UINT64_C(0xc3e0000000000000), UINT64_C(0xe25ecadd46b9586a) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xe25ecadd46b9586ac3e00000 };
#elif GMP_NUMB_BITS == 128
@@ -910,7 +918,7 @@ const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x0400, 0x92b8 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b80400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b8040000000000 };
+const mp_limb_t mpfr_l2b_24_0__tab[] = { UINT64_C(0x92b8040000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b804000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -925,7 +933,7 @@ const mp_limb_t mpfr_l2b_24_1__tab[] = { 0x3668, 0x7263, 0xc7c6, 0xbb44, 0xdf56
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_24_1__tab[] = { 0x36680000, 0xc7c67263, 0xdf56bb44 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_24_1__tab[] = { 0x3668000000000000, 0xdf56bb44c7c67263 };
+const mp_limb_t mpfr_l2b_24_1__tab[] = { UINT64_C(0x3668000000000000), UINT64_C(0xdf56bb44c7c67263) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_24_1__tab[] = { 0xdf56bb44c7c6726336680000 };
#elif GMP_NUMB_BITS == 128
@@ -940,7 +948,7 @@ const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x7a00, 0x949a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a0000000000 };
+const mp_limb_t mpfr_l2b_25_0__tab[] = { UINT64_C(0x949a7a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -955,7 +963,7 @@ const mp_limb_t mpfr_l2b_25_1__tab[] = { 0x67b8, 0x9728, 0x287b, 0xa348, 0xdc81
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_25_1__tab[] = { 0x67b80000, 0x287b9728, 0xdc81a348 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_25_1__tab[] = { 0x67b8000000000000, 0xdc81a348287b9728 };
+const mp_limb_t mpfr_l2b_25_1__tab[] = { UINT64_C(0x67b8000000000000), UINT64_C(0xdc81a348287b9728) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_25_1__tab[] = { 0xdc81a348287b972867b80000 };
#elif GMP_NUMB_BITS == 128
@@ -970,7 +978,7 @@ const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x0200, 0x966a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a0200 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a020000000000 };
+const mp_limb_t mpfr_l2b_26_0__tab[] = { UINT64_C(0x966a020000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a02000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -985,7 +993,7 @@ const mp_limb_t mpfr_l2b_26_1__tab[] = { 0x6458, 0x78a4, 0x7583, 0x19f9, 0xd9da
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_26_1__tab[] = { 0x64580000, 0x758378a4, 0xd9da19f9 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_26_1__tab[] = { 0x6458000000000000, 0xd9da19f9758378a4 };
+const mp_limb_t mpfr_l2b_26_1__tab[] = { UINT64_C(0x6458000000000000), UINT64_C(0xd9da19f9758378a4) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_26_1__tab[] = { 0xd9da19f9758378a464580000 };
#elif GMP_NUMB_BITS == 128
@@ -1000,7 +1008,7 @@ const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x0a00, 0x9828 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a0000000000 };
+const mp_limb_t mpfr_l2b_27_0__tab[] = { UINT64_C(0x98280a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1015,7 +1023,7 @@ const mp_limb_t mpfr_l2b_27_1__tab[] = { 0x5b08, 0xe1bd, 0xe237, 0x7bac, 0xd75b
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_27_1__tab[] = { 0x5b080000, 0xe237e1bd, 0xd75b7bac };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_27_1__tab[] = { 0x5b08000000000000, 0xd75b7bace237e1bd };
+const mp_limb_t mpfr_l2b_27_1__tab[] = { UINT64_C(0x5b08000000000000), UINT64_C(0xd75b7bace237e1bd) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_27_1__tab[] = { 0xd75b7bace237e1bd5b080000 };
#elif GMP_NUMB_BITS == 128
@@ -1030,7 +1038,7 @@ const mp_limb_t mpfr_l2b_28_0__tab[] = { 0xda00, 0x99d5 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da0000000000 };
+const mp_limb_t mpfr_l2b_28_0__tab[] = { UINT64_C(0x99d5da0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1045,7 +1053,7 @@ const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xdeb8, 0xe8b8, 0x71df, 0xc758, 0xd501
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xdeb80000, 0x71dfe8b8, 0xd501c758 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xdeb8000000000000, 0xd501c75871dfe8b8 };
+const mp_limb_t mpfr_l2b_28_1__tab[] = { UINT64_C(0xdeb8000000000000), UINT64_C(0xd501c75871dfe8b8) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xd501c75871dfe8b8deb80000 };
#elif GMP_NUMB_BITS == 128
@@ -1060,7 +1068,7 @@ const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9600, 0x9b74 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b749600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b74960000000000 };
+const mp_limb_t mpfr_l2b_29_0__tab[] = { UINT64_C(0x9b74960000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b7496000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1075,7 +1083,7 @@ const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xccc8, 0x62b3, 0x9c6c, 0x8315, 0xd2c9
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xccc80000, 0x9c6c62b3, 0xd2c98315 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xccc8000000000000, 0xd2c983159c6c62b3 };
+const mp_limb_t mpfr_l2b_29_1__tab[] = { UINT64_C(0xccc8000000000000), UINT64_C(0xd2c983159c6c62b3) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xd2c983159c6c62b3ccc80000 };
#elif GMP_NUMB_BITS == 128
@@ -1090,7 +1098,7 @@ const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x4000, 0x9d05 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d054000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d05400000000000 };
+const mp_limb_t mpfr_l2b_30_0__tab[] = { UINT64_C(0x9d05400000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d0540000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1105,7 +1113,7 @@ const mp_limb_t mpfr_l2b_30_1__tab[] = { 0x3588, 0x1732, 0x5cad, 0xa619, 0xd0af
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_30_1__tab[] = { 0x35880000, 0x5cad1732, 0xd0afa619 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_30_1__tab[] = { 0x3588000000000000, 0xd0afa6195cad1732 };
+const mp_limb_t mpfr_l2b_30_1__tab[] = { UINT64_C(0x3588000000000000), UINT64_C(0xd0afa6195cad1732) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_30_1__tab[] = { 0xd0afa6195cad173235880000 };
#elif GMP_NUMB_BITS == 128
@@ -1120,7 +1128,7 @@ const mp_limb_t mpfr_l2b_31_0__tab[] = { 0xc800, 0x9e88 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c80000000000 };
+const mp_limb_t mpfr_l2b_31_0__tab[] = { UINT64_C(0x9e88c80000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c8000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1135,7 +1143,7 @@ const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xd578, 0xf7ca, 0x63ee, 0x86e6, 0xceb1
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xd5780000, 0x63eef7ca, 0xceb186e6 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xd578000000000000, 0xceb186e663eef7ca };
+const mp_limb_t mpfr_l2b_31_1__tab[] = { UINT64_C(0xd578000000000000), UINT64_C(0xceb186e663eef7ca) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xceb186e663eef7cad5780000 };
#elif GMP_NUMB_BITS == 128
@@ -1150,7 +1158,7 @@ const mp_limb_t mpfr_l2b_32_0__tab[] = { 0x0000, 0xa000 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa0000000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa000000000000000 };
+const mp_limb_t mpfr_l2b_32_0__tab[] = { UINT64_C(0xa000000000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa00000000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1165,7 +1173,7 @@ const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccd0, 0xcccc, 0xcccc, 0xcccc, 0xcccc
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccd00000, 0xcccccccc, 0xcccccccc };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccd0000000000000, 0xcccccccccccccccc };
+const mp_limb_t mpfr_l2b_32_1__tab[] = { UINT64_C(0xccd0000000000000), UINT64_C(0xcccccccccccccccc) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccccccccccccccccccd00000 };
#elif GMP_NUMB_BITS == 128
@@ -1180,7 +1188,7 @@ const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xae00, 0xa16b };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae0000000000 };
+const mp_limb_t mpfr_l2b_33_0__tab[] = { UINT64_C(0xa16bae0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1195,7 +1203,7 @@ const mp_limb_t mpfr_l2b_33_1__tab[] = { 0x0888, 0xa187, 0x5304, 0x6404, 0xcaff
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_33_1__tab[] = { 0x08880000, 0x5304a187, 0xcaff6404 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_33_1__tab[] = { 0x0888000000000000, 0xcaff64045304a187 };
+const mp_limb_t mpfr_l2b_33_1__tab[] = { UINT64_C(0x0888000000000000), UINT64_C(0xcaff64045304a187) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_33_1__tab[] = { 0xcaff64045304a18708880000 };
#elif GMP_NUMB_BITS == 128
@@ -1210,7 +1218,7 @@ const mp_limb_t mpfr_l2b_34_0__tab[] = { 0x8000, 0xa2cc };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc8000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc800000000000 };
+const mp_limb_t mpfr_l2b_34_0__tab[] = { UINT64_C(0xa2cc800000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc80000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1225,7 +1233,7 @@ const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xfb50, 0x17ca, 0x5a79, 0x73d8, 0xc947
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xfb500000, 0x5a7917ca, 0xc94773d8 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xfb50000000000000, 0xc94773d85a7917ca };
+const mp_limb_t mpfr_l2b_34_1__tab[] = { UINT64_C(0xfb50000000000000), UINT64_C(0xc94773d85a7917ca) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xc94773d85a7917cafb500000 };
#elif GMP_NUMB_BITS == 128
@@ -1240,7 +1248,7 @@ const mp_limb_t mpfr_l2b_35_0__tab[] = { 0x1800, 0xa423 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa4231800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa423180000000000 };
+const mp_limb_t mpfr_l2b_35_0__tab[] = { UINT64_C(0xa423180000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa42318000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1255,7 +1263,7 @@ const mp_limb_t mpfr_l2b_35_1__tab[] = { 0x6960, 0x18c2, 0x6037, 0x567c, 0xc7a3
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_35_1__tab[] = { 0x69600000, 0x603718c2, 0xc7a3567c };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_35_1__tab[] = { 0x6960000000000000, 0xc7a3567c603718c2 };
+const mp_limb_t mpfr_l2b_35_1__tab[] = { UINT64_C(0x6960000000000000), UINT64_C(0xc7a3567c603718c2) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_35_1__tab[] = { 0xc7a3567c603718c269600000 };
#elif GMP_NUMB_BITS == 128
@@ -1270,7 +1278,7 @@ const mp_limb_t mpfr_l2b_36_0__tab[] = { 0x0800, 0xa570 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa5700800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa570080000000000 };
+const mp_limb_t mpfr_l2b_36_0__tab[] = { UINT64_C(0xa570080000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa57008000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1285,7 +1293,7 @@ const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xff10, 0xf9e9, 0xe054, 0x9236, 0xc611
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xff100000, 0xe054f9e9, 0xc6119236 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xff10000000000000, 0xc6119236e054f9e9 };
+const mp_limb_t mpfr_l2b_36_1__tab[] = { UINT64_C(0xff10000000000000), UINT64_C(0xc6119236e054f9e9) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xc6119236e054f9e9ff100000 };
#elif GMP_NUMB_BITS == 128
@@ -1300,7 +1308,7 @@ const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xd800, 0xa6b3 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d80000000000 };
+const mp_limb_t mpfr_l2b_37_0__tab[] = { UINT64_C(0xa6b3d80000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d8000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1315,7 +1323,7 @@ const mp_limb_t mpfr_l2b_37_1__tab[] = { 0x1618, 0x6b36, 0x70d7, 0xd3a2, 0xc490
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_37_1__tab[] = { 0x16180000, 0x70d76b36, 0xc490d3a2 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_37_1__tab[] = { 0x1618000000000000, 0xc490d3a270d76b36 };
+const mp_limb_t mpfr_l2b_37_1__tab[] = { UINT64_C(0x1618000000000000), UINT64_C(0xc490d3a270d76b36) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_37_1__tab[] = { 0xc490d3a270d76b3616180000 };
#elif GMP_NUMB_BITS == 128
@@ -1330,7 +1338,7 @@ const mp_limb_t mpfr_l2b_38_0__tab[] = { 0x0600, 0xa7ef };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef0600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef060000000000 };
+const mp_limb_t mpfr_l2b_38_0__tab[] = { UINT64_C(0xa7ef060000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef06000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1345,7 +1353,7 @@ const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xa3e0, 0x9505, 0x5182, 0xe8d2, 0xc31f
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xa3e00000, 0x51829505, 0xc31fe8d2 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xa3e0000000000000, 0xc31fe8d251829505 };
+const mp_limb_t mpfr_l2b_38_1__tab[] = { UINT64_C(0xa3e0000000000000), UINT64_C(0xc31fe8d251829505) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xc31fe8d251829505a3e00000 };
#elif GMP_NUMB_BITS == 128
@@ -1360,7 +1368,7 @@ const mp_limb_t mpfr_l2b_39_0__tab[] = { 0x0400, 0xa922 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa9220400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa922040000000000 };
+const mp_limb_t mpfr_l2b_39_0__tab[] = { UINT64_C(0xa922040000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa92204000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1375,7 +1383,7 @@ const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xfcf8, 0xf1b5, 0x10ca, 0xbd32, 0xc1bd
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xfcf80000, 0x10caf1b5, 0xc1bdbd32 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xfcf8000000000000, 0xc1bdbd3210caf1b5 };
+const mp_limb_t mpfr_l2b_39_1__tab[] = { UINT64_C(0xfcf8000000000000), UINT64_C(0xc1bdbd3210caf1b5) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xc1bdbd3210caf1b5fcf80000 };
#elif GMP_NUMB_BITS == 128
@@ -1390,7 +1398,7 @@ const mp_limb_t mpfr_l2b_40_0__tab[] = { 0x3e00, 0xaa4d };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e0000000000 };
+const mp_limb_t mpfr_l2b_40_0__tab[] = { UINT64_C(0xaa4d3e0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1405,7 +1413,7 @@ const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xdce8, 0x4948, 0xeff7, 0x55ff, 0xc069
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xdce80000, 0xeff74948, 0xc06955ff };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xdce8000000000000, 0xc06955ffeff74948 };
+const mp_limb_t mpfr_l2b_40_1__tab[] = { UINT64_C(0xdce8000000000000), UINT64_C(0xc06955ffeff74948) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xc06955ffeff74948dce80000 };
#elif GMP_NUMB_BITS == 128
@@ -1420,7 +1428,7 @@ const mp_limb_t mpfr_l2b_41_0__tab[] = { 0x1200, 0xab71 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab711200 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab71120000000000 };
+const mp_limb_t mpfr_l2b_41_0__tab[] = { UINT64_C(0xab71120000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab7112000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1435,7 +1443,7 @@ const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xdc28, 0x7cef, 0xf695, 0xcf47, 0xbf21
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xdc280000, 0xf6957cef, 0xbf21cf47 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xdc28000000000000, 0xbf21cf47f6957cef };
+const mp_limb_t mpfr_l2b_41_1__tab[] = { UINT64_C(0xdc28000000000000), UINT64_C(0xbf21cf47f6957cef) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xbf21cf47f6957cefdc280000 };
#elif GMP_NUMB_BITS == 128
@@ -1450,7 +1458,7 @@ const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xde00, 0xac8d };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde0000000000 };
+const mp_limb_t mpfr_l2b_42_0__tab[] = { UINT64_C(0xac8dde0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1465,7 +1473,7 @@ const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xba10, 0x7125, 0x939b, 0x594a, 0xbde6
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xba100000, 0x939b7125, 0xbde6594a };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xba10000000000000, 0xbde6594a939b7125 };
+const mp_limb_t mpfr_l2b_42_1__tab[] = { UINT64_C(0xba10000000000000), UINT64_C(0xbde6594a939b7125) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xbde6594a939b7125ba100000 };
#elif GMP_NUMB_BITS == 128
@@ -1480,7 +1488,7 @@ const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xf600, 0xada3 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f60000000000 };
+const mp_limb_t mpfr_l2b_43_0__tab[] = { UINT64_C(0xada3f60000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f6000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1495,7 +1503,7 @@ const mp_limb_t mpfr_l2b_43_1__tab[] = { 0x9560, 0x2ab5, 0x9118, 0x363d, 0xbcb6
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_43_1__tab[] = { 0x95600000, 0x91182ab5, 0xbcb6363d };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_43_1__tab[] = { 0x9560000000000000, 0xbcb6363d91182ab5 };
+const mp_limb_t mpfr_l2b_43_1__tab[] = { UINT64_C(0x9560000000000000), UINT64_C(0xbcb6363d91182ab5) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_43_1__tab[] = { 0xbcb6363d91182ab595600000 };
#elif GMP_NUMB_BITS == 128
@@ -1510,7 +1518,7 @@ const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaa00, 0xaeb3 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa0000000000 };
+const mp_limb_t mpfr_l2b_44_0__tab[] = { UINT64_C(0xaeb3aa0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1525,7 +1533,7 @@ const mp_limb_t mpfr_l2b_44_1__tab[] = { 0x1590, 0x4e90, 0x3a3d, 0xb859, 0xbb90
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_44_1__tab[] = { 0x15900000, 0x3a3d4e90, 0xbb90b859 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_44_1__tab[] = { 0x1590000000000000, 0xbb90b8593a3d4e90 };
+const mp_limb_t mpfr_l2b_44_1__tab[] = { UINT64_C(0x1590000000000000), UINT64_C(0xbb90b8593a3d4e90) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_44_1__tab[] = { 0xbb90b8593a3d4e9015900000 };
#elif GMP_NUMB_BITS == 128
@@ -1540,7 +1548,7 @@ const mp_limb_t mpfr_l2b_45_0__tab[] = { 0x4400, 0xafbd };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd4400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd440000000000 };
+const mp_limb_t mpfr_l2b_45_0__tab[] = { UINT64_C(0xafbd440000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd44000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1555,7 +1563,7 @@ const mp_limb_t mpfr_l2b_45_1__tab[] = { 0x1e78, 0x76f5, 0x1010, 0x4026, 0xba75
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_45_1__tab[] = { 0x1e780000, 0x101076f5, 0xba754026 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_45_1__tab[] = { 0x1e78000000000000, 0xba754026101076f5 };
+const mp_limb_t mpfr_l2b_45_1__tab[] = { UINT64_C(0x1e78000000000000), UINT64_C(0xba754026101076f5) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_45_1__tab[] = { 0xba754026101076f51e780000 };
#elif GMP_NUMB_BITS == 128
@@ -1570,7 +1578,7 @@ const mp_limb_t mpfr_l2b_46_0__tab[] = { 0x0600, 0xb0c1 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c10600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c1060000000000 };
+const mp_limb_t mpfr_l2b_46_0__tab[] = { UINT64_C(0xb0c1060000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c106000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1585,7 +1593,7 @@ const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb670, 0x0512, 0x69aa, 0x3b01, 0xb963
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb6700000, 0x69aa0512, 0xb9633b01 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb670000000000000, 0xb9633b0169aa0512 };
+const mp_limb_t mpfr_l2b_46_1__tab[] = { UINT64_C(0xb670000000000000), UINT64_C(0xb9633b0169aa0512) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb9633b0169aa0512b6700000 };
#elif GMP_NUMB_BITS == 128
@@ -1600,7 +1608,7 @@ const mp_limb_t mpfr_l2b_47_0__tab[] = { 0x3200, 0xb1bf };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf3200 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf320000000000 };
+const mp_limb_t mpfr_l2b_47_0__tab[] = { UINT64_C(0xb1bf320000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf32000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1615,7 +1623,7 @@ const mp_limb_t mpfr_l2b_47_1__tab[] = { 0x5118, 0x4133, 0xfbe4, 0x21d0, 0xb85a
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_47_1__tab[] = { 0x51180000, 0xfbe44133, 0xb85a21d0 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_47_1__tab[] = { 0x5118000000000000, 0xb85a21d0fbe44133 };
+const mp_limb_t mpfr_l2b_47_1__tab[] = { UINT64_C(0x5118000000000000), UINT64_C(0xb85a21d0fbe44133) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_47_1__tab[] = { 0xb85a21d0fbe4413351180000 };
#elif GMP_NUMB_BITS == 128
@@ -1630,7 +1638,7 @@ const mp_limb_t mpfr_l2b_48_0__tab[] = { 0x0400, 0xb2b8 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b80400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b8040000000000 };
+const mp_limb_t mpfr_l2b_48_0__tab[] = { UINT64_C(0xb2b8040000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b804000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1645,7 +1653,7 @@ const mp_limb_t mpfr_l2b_48_1__tab[] = { 0x0490, 0x663d, 0x960d, 0x77de, 0xb759
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_48_1__tab[] = { 0x04900000, 0x960d663d, 0xb75977de };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_48_1__tab[] = { 0x0490000000000000, 0xb75977de960d663d };
+const mp_limb_t mpfr_l2b_48_1__tab[] = { UINT64_C(0x0490000000000000), UINT64_C(0xb75977de960d663d) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_48_1__tab[] = { 0xb75977de960d663d04900000 };
#elif GMP_NUMB_BITS == 128
@@ -1660,7 +1668,7 @@ const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb400, 0xb3ab };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb40000000000 };
+const mp_limb_t mpfr_l2b_49_0__tab[] = { UINT64_C(0xb3abb40000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb4000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1675,7 +1683,7 @@ const mp_limb_t mpfr_l2b_49_1__tab[] = { 0x37b8, 0xa711, 0x754d, 0xc9d6, 0xb660
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_49_1__tab[] = { 0x37b80000, 0x754da711, 0xb660c9d6 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_49_1__tab[] = { 0x37b8000000000000, 0xb660c9d6754da711 };
+const mp_limb_t mpfr_l2b_49_1__tab[] = { UINT64_C(0x37b8000000000000), UINT64_C(0xb660c9d6754da711) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_49_1__tab[] = { 0xb660c9d6754da71137b80000 };
#elif GMP_NUMB_BITS == 128
@@ -1690,7 +1698,7 @@ const mp_limb_t mpfr_l2b_50_0__tab[] = { 0x7a00, 0xb49a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a0000000000 };
+const mp_limb_t mpfr_l2b_50_0__tab[] = { UINT64_C(0xb49a7a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1705,7 +1713,7 @@ const mp_limb_t mpfr_l2b_50_1__tab[] = { 0x27f0, 0xe532, 0x7344, 0xace3, 0xb56f
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_50_1__tab[] = { 0x27f00000, 0x7344e532, 0xb56face3 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_50_1__tab[] = { 0x27f0000000000000, 0xb56face37344e532 };
+const mp_limb_t mpfr_l2b_50_1__tab[] = { UINT64_C(0x27f0000000000000), UINT64_C(0xb56face37344e532) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_50_1__tab[] = { 0xb56face37344e53227f00000 };
#elif GMP_NUMB_BITS == 128
@@ -1720,7 +1728,7 @@ const mp_limb_t mpfr_l2b_51_0__tab[] = { 0x8400, 0xb584 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb5848400 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb584840000000000 };
+const mp_limb_t mpfr_l2b_51_0__tab[] = { UINT64_C(0xb584840000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb58484000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1735,7 +1743,7 @@ const mp_limb_t mpfr_l2b_51_1__tab[] = { 0x4000, 0xe9a9, 0x0f8a, 0xbde5, 0xb485
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_51_1__tab[] = { 0x40000000, 0x0f8ae9a9, 0xb485bde5 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_51_1__tab[] = { 0x4000000000000000, 0xb485bde50f8ae9a9 };
+const mp_limb_t mpfr_l2b_51_1__tab[] = { UINT64_C(0x4000000000000000), UINT64_C(0xb485bde50f8ae9a9) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_51_1__tab[] = { 0xb485bde50f8ae9a940000000 };
#elif GMP_NUMB_BITS == 128
@@ -1750,7 +1758,7 @@ const mp_limb_t mpfr_l2b_52_0__tab[] = { 0x0200, 0xb66a };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a0200 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a020000000000 };
+const mp_limb_t mpfr_l2b_52_0__tab[] = { UINT64_C(0xb66a020000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a02000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1765,7 +1773,7 @@ const mp_limb_t mpfr_l2b_52_1__tab[] = { 0x4608, 0xfcb3, 0xeecf, 0xa0bb, 0xb3a2
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_52_1__tab[] = { 0x46080000, 0xeecffcb3, 0xb3a2a0bb };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_52_1__tab[] = { 0x4608000000000000, 0xb3a2a0bbeecffcb3 };
+const mp_limb_t mpfr_l2b_52_1__tab[] = { UINT64_C(0x4608000000000000), UINT64_C(0xb3a2a0bbeecffcb3) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_52_1__tab[] = { 0xb3a2a0bbeecffcb346080000 };
#elif GMP_NUMB_BITS == 128
@@ -1780,7 +1788,7 @@ const mp_limb_t mpfr_l2b_53_0__tab[] = { 0x2000, 0xb74b };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b2000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b200000000000 };
+const mp_limb_t mpfr_l2b_53_0__tab[] = { UINT64_C(0xb74b200000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b20000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1795,7 +1803,7 @@ const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xa360, 0x8ccb, 0xeb5f, 0xffa9, 0xb2c5
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xa3600000, 0xeb5f8ccb, 0xb2c5ffa9 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xa360000000000000, 0xb2c5ffa9eb5f8ccb };
+const mp_limb_t mpfr_l2b_53_1__tab[] = { UINT64_C(0xa360000000000000), UINT64_C(0xb2c5ffa9eb5f8ccb) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xb2c5ffa9eb5f8ccba3600000 };
#elif GMP_NUMB_BITS == 128
@@ -1810,7 +1818,7 @@ const mp_limb_t mpfr_l2b_54_0__tab[] = { 0x0a00, 0xb828 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a0000000000 };
+const mp_limb_t mpfr_l2b_54_0__tab[] = { UINT64_C(0xb8280a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1825,7 +1833,7 @@ const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xf368, 0xe940, 0x3e86, 0x8ac3, 0xb1ef
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xf3680000, 0x3e86e940, 0xb1ef8ac3 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xf368000000000000, 0xb1ef8ac33e86e940 };
+const mp_limb_t mpfr_l2b_54_1__tab[] = { UINT64_C(0xf368000000000000), UINT64_C(0xb1ef8ac33e86e940) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xb1ef8ac33e86e940f3680000 };
#elif GMP_NUMB_BITS == 128
@@ -1840,7 +1848,7 @@ const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xe800, 0xb900 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e80000000000 };
+const mp_limb_t mpfr_l2b_55_0__tab[] = { UINT64_C(0xb900e80000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e8000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1855,7 +1863,7 @@ const mp_limb_t mpfr_l2b_55_1__tab[] = { 0x7a40, 0xd18e, 0xa4b5, 0xf76e, 0xb11e
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_55_1__tab[] = { 0x7a400000, 0xa4b5d18e, 0xb11ef76e };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_55_1__tab[] = { 0x7a40000000000000, 0xb11ef76ea4b5d18e };
+const mp_limb_t mpfr_l2b_55_1__tab[] = { UINT64_C(0x7a40000000000000), UINT64_C(0xb11ef76ea4b5d18e) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_55_1__tab[] = { 0xb11ef76ea4b5d18e7a400000 };
#elif GMP_NUMB_BITS == 128
@@ -1870,7 +1878,7 @@ const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xda00, 0xb9d5 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da0000000000 };
+const mp_limb_t mpfr_l2b_56_0__tab[] = { UINT64_C(0xb9d5da0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1885,7 +1893,7 @@ const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xe818, 0x4c7b, 0xaa2c, 0xfff2, 0xb053
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xe8180000, 0xaa2c4c7b, 0xb053fff2 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xe818000000000000, 0xb053fff2aa2c4c7b };
+const mp_limb_t mpfr_l2b_56_1__tab[] = { UINT64_C(0xe818000000000000), UINT64_C(0xb053fff2aa2c4c7b) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xb053fff2aa2c4c7be8180000 };
#elif GMP_NUMB_BITS == 128
@@ -1900,7 +1908,7 @@ const mp_limb_t mpfr_l2b_57_0__tab[] = { 0x0a00, 0xbaa7 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a0000000000 };
+const mp_limb_t mpfr_l2b_57_0__tab[] = { UINT64_C(0xbaa70a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1915,7 +1923,7 @@ const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xefb0, 0x814f, 0x8e2f, 0x630e, 0xaf8e
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xefb00000, 0x8e2f814f, 0xaf8e630e };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xefb0000000000000, 0xaf8e630e8e2f814f };
+const mp_limb_t mpfr_l2b_57_1__tab[] = { UINT64_C(0xefb0000000000000), UINT64_C(0xaf8e630e8e2f814f) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xaf8e630e8e2f814fefb00000 };
#elif GMP_NUMB_BITS == 128
@@ -1930,7 +1938,7 @@ const mp_limb_t mpfr_l2b_58_0__tab[] = { 0x9600, 0xbb74 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb749600 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb74960000000000 };
+const mp_limb_t mpfr_l2b_58_0__tab[] = { UINT64_C(0xbb74960000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb7496000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1945,7 +1953,7 @@ const mp_limb_t mpfr_l2b_58_1__tab[] = { 0x5d18, 0x41a1, 0x6114, 0xe39d, 0xaecd
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_58_1__tab[] = { 0x5d180000, 0x611441a1, 0xaecde39d };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_58_1__tab[] = { 0x5d18000000000000, 0xaecde39d611441a1 };
+const mp_limb_t mpfr_l2b_58_1__tab[] = { UINT64_C(0x5d18000000000000), UINT64_C(0xaecde39d611441a1) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_58_1__tab[] = { 0xaecde39d611441a15d180000 };
#elif GMP_NUMB_BITS == 128
@@ -1960,7 +1968,7 @@ const mp_limb_t mpfr_l2b_59_0__tab[] = { 0x9e00, 0xbc3e };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e0000000000 };
+const mp_limb_t mpfr_l2b_59_0__tab[] = { UINT64_C(0xbc3e9e0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -1975,7 +1983,7 @@ const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xd000, 0x97df, 0x2f97, 0x4842, 0xae12
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xd0000000, 0x2f9797df, 0xae124842 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xd000000000000000, 0xae1248422f9797df };
+const mp_limb_t mpfr_l2b_59_1__tab[] = { UINT64_C(0xd000000000000000), UINT64_C(0xae1248422f9797df) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xae1248422f9797dfd0000000 };
#elif GMP_NUMB_BITS == 128
@@ -1990,7 +1998,7 @@ const mp_limb_t mpfr_l2b_60_0__tab[] = { 0x4000, 0xbd05 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd054000 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd05400000000000 };
+const mp_limb_t mpfr_l2b_60_0__tab[] = { UINT64_C(0xbd05400000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd0540000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -2005,7 +2013,7 @@ const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xfe58, 0x206d, 0x3555, 0x5b1c, 0xad5b
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xfe580000, 0x3555206d, 0xad5b5b1c };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xfe58000000000000, 0xad5b5b1c3555206d };
+const mp_limb_t mpfr_l2b_60_1__tab[] = { UINT64_C(0xfe58000000000000), UINT64_C(0xad5b5b1c3555206d) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xad5b5b1c3555206dfe580000 };
#elif GMP_NUMB_BITS == 128
@@ -2020,7 +2028,7 @@ const mp_limb_t mpfr_l2b_61_0__tab[] = { 0x9a00, 0xbdc8 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a00 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a0000000000 };
+const mp_limb_t mpfr_l2b_61_0__tab[] = { UINT64_C(0xbdc89a0000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -2035,7 +2043,7 @@ const mp_limb_t mpfr_l2b_61_1__tab[] = { 0x4df8, 0x7757, 0x31cb, 0xe982, 0xaca8
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_61_1__tab[] = { 0x4df80000, 0x31cb7757, 0xaca8e982 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_61_1__tab[] = { 0x4df8000000000000, 0xaca8e98231cb7757 };
+const mp_limb_t mpfr_l2b_61_1__tab[] = { UINT64_C(0x4df8000000000000), UINT64_C(0xaca8e98231cb7757) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_61_1__tab[] = { 0xaca8e98231cb77574df80000 };
#elif GMP_NUMB_BITS == 128
@@ -2050,7 +2058,7 @@ const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xc800, 0xbe88 };
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c800 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c80000000000 };
+const mp_limb_t mpfr_l2b_62_0__tab[] = { UINT64_C(0xbe88c80000000000) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c8000000000000000000 };
#elif GMP_NUMB_BITS == 128
@@ -2065,7 +2073,7 @@ const mp_limb_t mpfr_l2b_62_1__tab[] = { 0x74f8, 0xf905, 0x1831, 0xc3c4, 0xabfa
#elif GMP_NUMB_BITS == 32
const mp_limb_t mpfr_l2b_62_1__tab[] = { 0x74f80000, 0x1831f905, 0xabfac3c4 };
#elif GMP_NUMB_BITS == 64
-const mp_limb_t mpfr_l2b_62_1__tab[] = { 0x74f8000000000000, 0xabfac3c41831f905 };
+const mp_limb_t mpfr_l2b_62_1__tab[] = { UINT64_C(0x74f8000000000000), UINT64_C(0xabfac3c41831f905) };
#elif GMP_NUMB_BITS == 96
const mp_limb_t mpfr_l2b_62_1__tab[] = { 0xabfac3c41831f90574f80000 };
#elif GMP_NUMB_BITS == 128
@@ -2202,7 +2210,7 @@ const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2] = {
/* returns ceil(e * log2(b)^((-1)^i)), or ... + 1.
For i=0, uses a 23-bit upper approximation to log(beta)/log(2).
- For i=1, uses a 76-bit upper approximation to log(2)/log(beta).
+ For i=1, uses a 77-bit upper approximation to log(2)/log(beta).
Note: this function should be called only in the extended exponent range.
*/
mpfr_exp_t
@@ -2211,20 +2219,20 @@ mpfr_ceil_mul (mpfr_exp_t e, int beta, int i)
mpfr_srcptr p;
mpfr_t t;
mpfr_exp_t r;
+ mp_limb_t tmpmant[MPFR_EXP_LIMB_SIZE];
p = &__gmpfr_l2b[beta-2][i];
- mpfr_init2 (t, sizeof (mpfr_exp_t) * CHAR_BIT);
+ MPFR_TMP_INIT1(tmpmant, t, sizeof (mpfr_exp_t) * CHAR_BIT - 1);
mpfr_set_exp_t (t, e, MPFR_RNDU);
mpfr_mul (t, t, p, MPFR_RNDU);
r = mpfr_get_exp_t (t, MPFR_RNDU);
- mpfr_clear (t);
return r;
}
/* 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 <= 62).
+ |b| is the given base (2 <= b <= 62 or -36 <= b <= -2).
Return value:
if s=NULL, allocates a string to store the mantissa, with
@@ -2232,10 +2240,11 @@ mpfr_ceil_mul (mpfr_exp_t e, int beta, int i)
(thus m+1 or m+2 characters).
Important: when you call this function with s=NULL, don't forget to free
- the memory space allocated, with free(s, strlen(s)).
+ the memory space allocated, with mpfr_free_str.
*/
char*
-mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t rnd)
+mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x,
+ mpfr_rnd_t rnd)
{
const char *num_to_text;
int exact; /* exact result */
@@ -2251,35 +2260,53 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
size_t n, i;
char *s0;
int neg;
- int ret; /* return value of mpfr_get_str_aux */
+ int ret; /* return value of mpfr_get_str_aux */
+ int b0 = b; /* initial base argument, might be negative */
MPFR_ZIV_DECL (loop);
MPFR_SAVE_EXPO_DECL (expo);
- MPFR_TMP_DECL(marker);
+ MPFR_TMP_DECL (marker);
/* if exact = 1 then err is undefined */
/* otherwise err is such that |x*b^(m-g)-a*2^exp_a| < 2^(err+exp_a) */
- /* is the base valid? */
- if (b < 2 || b > 62)
+ MPFR_LOG_FUNC
+ (("b=%d m=%zu x[%Pu]=%.*Rg rnd=%d",
+ b, m, mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("flags=%lx", (unsigned long) __gmpfr_flags));
+
+ /* Is the base argument valid? Valid values are -36 to -2 and 2 to 62. */
+ if (b < -36 || (-2 < b && b < 2) || 62 < b)
return NULL;
- num_to_text = b < 37 ? num_to_text36 : num_to_text62;
+ num_to_text = (2 <= b && b <= 36) ? num_to_text36 : num_to_text62;
+
+ b = (b > 0) ? b : -b;
+
+ /* now b is positive */
+
+ /* map RNDF to RNDN, to avoid problems with specification of mpfr_can_round
+ or mpfr_can_round_raw */
+ if (rnd == MPFR_RNDF)
+ rnd = MPFR_RNDN;
if (MPFR_UNLIKELY (MPFR_IS_NAN (x)))
{
if (s == NULL)
- s = (char *) (*__gmp_allocate_func) (6);
+ s = (char *) mpfr_allocate_func (6);
strcpy (s, "@NaN@");
+ MPFR_LOG_MSG (("%s\n", s));
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
return s;
}
- neg = MPFR_SIGN(x) < 0; /* 0 if positive, 1 if negative */
+ neg = MPFR_IS_NEG (x); /* 0 if positive, 1 if negative */
if (MPFR_UNLIKELY (MPFR_IS_INF (x)))
{
if (s == NULL)
- s = (char *) (*__gmp_allocate_func) (neg + 6);
+ s = (char *) mpfr_allocate_func (neg + 6);
strcpy (s, (neg) ? "-@Inf@" : "@Inf@");
+ MPFR_LOG_MSG (("%s\n", s));
return s;
}
@@ -2302,18 +2329,22 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
m = 2;
}
- /* the code below for non-power-of-two bases works for m=1 */
- MPFR_ASSERTN (m >= 2 || (IS_POW2(b) == 0 && m >= 1));
+ MPFR_LOG_MSG (("m=%zu\n", m));
+
+ /* The code below for non-power-of-two bases works for m=1;
+ this is important for the internal use of mpfr_get_str. */
+ MPFR_ASSERTN (m >= 2 || (!IS_POW2(b) && m >= 1));
/* x is a floating-point number */
- if (MPFR_IS_ZERO(x))
+ if (s == NULL)
+ s = (char *) mpfr_allocate_func (neg + m + 1);
+ s0 = s;
+ if (neg)
+ *s++ = '-';
+
+ 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 */
@@ -2321,15 +2352,9 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
return s0; /* strlen(s0) = neg + m */
}
- if (s == NULL)
- s = (char*) (*__gmp_allocate_func) (neg + m + 1);
- s0 = s;
- if (neg)
- *s++ = '-';
+ xp = MPFR_MANT (x);
- xp = MPFR_MANT(x);
-
- if (IS_POW2(b))
+ if (IS_POW2 (b))
{
int pow2;
mpfr_exp_t f, r;
@@ -2384,22 +2409,24 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
n --;
}
- mpn_get_str ((unsigned char*) s, b, x1, n);
- for (i=0; i<m; i++)
+ 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;
- MPFR_TMP_FREE(marker);
+ MPFR_LOG_MSG (("e=%" MPFR_EXP_FSPEC "d\n", (mpfr_eexp_t) *e));
+
+ MPFR_TMP_FREE (marker);
MPFR_SAVE_EXPO_FREE (expo);
- return (s0);
+ return s0;
}
/* if x < 0, reduce to x > 0 */
if (neg)
- rnd = MPFR_INVERT_RND(rnd);
+ rnd = MPFR_INVERT_RND (rnd);
g = mpfr_ceil_mul (MPFR_GET_EXP (x) - 1, b, 1);
exact = 1;
@@ -2412,7 +2439,7 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
MPFR_ZIV_INIT (loop, prec);
for (;;)
{
- MPFR_TMP_MARK(marker);
+ MPFR_TMP_MARK (marker);
exact = 1;
@@ -2425,7 +2452,7 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
nx = MPFR_LIMB_SIZE (x);
if ((mpfr_exp_t) m == g) /* final exponent is 0, no multiplication or
- division to perform */
+ division to perform */
{
if (nx > n)
exact = mpn_scan1 (xp, 0) >= (nx - n) * GMP_NUMB_BITS;
@@ -2515,41 +2542,48 @@ mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t
/* check if rounding is possible */
if (exact)
err = -1;
- ret = mpfr_get_str_aux (s, e, a, n, exp_a, err, b, m, rnd);
+
+ ret = mpfr_get_str_aux (s, e, a, n, exp_a, err, b0, m, rnd);
+
+ MPFR_TMP_FREE (marker);
+
if (ret == MPFR_ROUND_FAILED)
{
/* too large error: increment the working precision */
MPFR_ZIV_NEXT (loop, prec);
}
- else if (ret == -MPFR_ROUND_FAILED)
+ else if (ret == - MPFR_ROUND_FAILED)
{
/* too many digits in mantissa: exp = |m-g| */
if ((mpfr_exp_t) m > g) /* exp = m - g, multiply by b^exp */
{
- g++;
+ g ++;
exp --;
}
else /* exp = g - m, divide by b^exp */
{
- g++;
+ g ++;
exp ++;
}
}
else
- break;
-
- MPFR_TMP_FREE(marker);
+ {
+ if (ret != 0)
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_INEXACT);
+ break;
+ }
}
MPFR_ZIV_FREE (loop);
*e += g;
- MPFR_TMP_FREE(marker);
+ MPFR_LOG_MSG (("e=%" MPFR_EXP_FSPEC "d\n", (mpfr_eexp_t) *e));
+
MPFR_SAVE_EXPO_FREE (expo);
return s0;
}
void mpfr_free_str (char *str)
{
- (*__gmp_free_func) (str, strlen (str) + 1);
+ mpfr_free_func (str, strlen (str) + 1);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_ui.c b/Build/source/libs/mpfr/mpfr-src/src/get_ui.c
index 48a5f333fbe..9be8d1bdf30 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_ui.c
@@ -30,10 +30,11 @@ mpfr_get_ui (mpfr_srcptr f, mpfr_rnd_t rnd)
mpfr_t x;
mp_size_t n;
mpfr_exp_t exp;
+ MPFR_SAVE_EXPO_DECL (expo);
if (MPFR_UNLIKELY (!mpfr_fits_ulong_p (f, rnd)))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return MPFR_IS_NAN (f) || MPFR_IS_NEG (f) ?
(unsigned long) 0 : ULONG_MAX;
}
@@ -44,10 +45,16 @@ mpfr_get_ui (mpfr_srcptr f, mpfr_rnd_t rnd)
for (s = ULONG_MAX, prec = 0; s != 0; s /= 2, prec ++)
{ }
+ MPFR_SAVE_EXPO_MARK (expo);
+
/* first round to prec bits */
mpfr_init2 (x, prec);
mpfr_rint (x, f, rnd);
+ /* The flags from mpfr_rint are the wanted ones. In particular,
+ it sets the inexact flag when necessary. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
/* warning: if x=0, taking its exponent is illegal */
if (MPFR_IS_ZERO(x))
s = 0;
@@ -61,5 +68,7 @@ mpfr_get_ui (mpfr_srcptr f, mpfr_rnd_t rnd)
mpfr_clear (x);
+ MPFR_SAVE_EXPO_FREE (expo);
+
return s;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_uj.c b/Build/source/libs/mpfr/mpfr-src/src/get_uj.c
index 805c8a1a874..b5193510c42 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_uj.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_uj.c
@@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-# include "config.h" /* for a build within gmp */
+# include "config.h"
#endif
#include "mpfr-intmax.h"
@@ -35,10 +35,11 @@ mpfr_get_uj (mpfr_srcptr f, mpfr_rnd_t rnd)
uintmax_t r;
mpfr_prec_t prec;
mpfr_t x;
+ MPFR_SAVE_EXPO_DECL (expo);
if (MPFR_UNLIKELY (!mpfr_fits_uintmax_p (f, rnd)))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return MPFR_IS_NAN (f) || MPFR_IS_NEG (f) ?
(uintmax_t) 0 : MPFR_UINTMAX_MAX;
}
@@ -50,12 +51,18 @@ mpfr_get_uj (mpfr_srcptr f, mpfr_rnd_t rnd)
for (r = MPFR_UINTMAX_MAX, prec = 0; r != 0; r /= 2, prec++)
{ }
- /* Now, r = 0. */
+ MPFR_ASSERTD (r == 0);
+
+ MPFR_SAVE_EXPO_MARK (expo);
mpfr_init2 (x, prec);
mpfr_rint (x, f, rnd);
MPFR_ASSERTN (MPFR_IS_FP (x));
+ /* The flags from mpfr_rint are the wanted ones. In particular,
+ it sets the inexact flag when necessary. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
if (MPFR_NOTZERO (x))
{
mp_limb_t *xp;
@@ -76,6 +83,8 @@ mpfr_get_uj (mpfr_srcptr f, mpfr_rnd_t rnd)
mpfr_clear (x);
+ MPFR_SAVE_EXPO_FREE (expo);
+
return r;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_z.c b/Build/source/libs/mpfr/mpfr-src/src/get_z.c
index 68249a465a6..7eae0dc5be1 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_z.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_z.c
@@ -29,11 +29,12 @@ mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd)
int inex;
mpfr_t r;
mpfr_exp_t exp;
+ MPFR_SAVE_EXPO_DECL (expo);
if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
{
if (MPFR_UNLIKELY (MPFR_NOTZERO (f)))
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
mpz_set_ui (z, 0);
/* The ternary value is 0 even for infinity. Giving the rounding
direction in this case would not make much sense anyway, and
@@ -41,6 +42,8 @@ mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd)
return 0;
}
+ MPFR_SAVE_EXPO_MARK (expo);
+
exp = MPFR_GET_EXP (f);
/* if exp <= 0, then |f|<1, thus |o(f)|<=1 */
MPFR_ASSERTN (exp < 0 || exp <= MPFR_PREC_MAX);
@@ -50,6 +53,11 @@ mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd)
MPFR_ASSERTN (inex != 1 && inex != -1); /* integral part of f is
representable in r */
MPFR_ASSERTN (MPFR_IS_FP (r));
+
+ /* The flags from mpfr_rint are the wanted ones. In particular,
+ it sets the inexact flag when necessary. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
exp = mpfr_get_z_2exp (z, r);
if (exp >= 0)
mpz_mul_2exp (z, z, exp);
@@ -57,5 +65,7 @@ mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd)
mpz_fdiv_q_2exp (z, z, -exp);
mpfr_clear (r);
+ MPFR_SAVE_EXPO_FREE (expo);
+
return inex;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/get_z_exp.c b/Build/source/libs/mpfr/mpfr-src/src/get_z_exp.c
index f05afc19434..4674619f199 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/get_z_exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/get_z_exp.c
@@ -48,16 +48,19 @@ mpfr_get_z_2exp (mpz_ptr z, mpfr_srcptr f)
if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
{
if (MPFR_UNLIKELY (MPFR_NOTZERO (f)))
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
mpz_set_ui (z, 0);
return __gmpfr_emin;
}
fn = MPFR_LIMB_SIZE(f);
+ /* FIXME: temporary assert for security. Too large values should
+ probably be handled like infinities. */
+ MPFR_ASSERTN (fn <= INT_MAX); /* due to SIZ(z) being an int */
+
/* check whether allocated space for z is enough */
- if (MPFR_UNLIKELY (ALLOC (z) < fn))
- MPZ_REALLOC (z, fn);
+ mpz_realloc2 (z, (mp_bitcnt_t) fn * GMP_NUMB_BITS);
MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (f));
if (MPFR_LIKELY (sh))
@@ -71,7 +74,7 @@ mpfr_get_z_2exp (mpz_ptr z, mpfr_srcptr f)
< (mpfr_uexp_t) MPFR_PREC (f)))
{
/* The exponent isn't representable in an mpfr_exp_t. */
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return MPFR_EXP_MIN;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/gmp_op.c b/Build/source/libs/mpfr/mpfr-src/src/gmp_op.c
index 2677b7089cd..e76a8afb969 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/gmp_op.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/gmp_op.c
@@ -23,6 +23,11 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
+/* TODO: for functions with mpz_srcptr, check whether mpz_fits_slong_p
+ is really useful in all cases. For instance, concerning the addition,
+ one now has mpz_t -> long -> unsigned long -> mpfr_t then mpfr_add
+ instead of mpz_t -> mpfr_t then mpfr_add. */
+
/* Init and set a mpfr_t with enough precision to store a mpz.
This function should be called in the extended exponent range. */
static void
@@ -83,21 +88,26 @@ foo2 (mpfr_ptr x, mpz_srcptr y, mpfr_srcptr z, mpfr_rnd_t r,
int
mpfr_mul_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
{
- return foo (y, x, z, r, mpfr_mul);
+ if (mpz_fits_slong_p (z))
+ return mpfr_mul_si (y, x, mpz_get_si (z), r);
+ else
+ return foo (y, x, z, r, mpfr_mul);
}
int
mpfr_div_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
{
- return foo (y, x, z, r, mpfr_div);
+ if (mpz_fits_slong_p (z))
+ return mpfr_div_si (y, x, mpz_get_si (z), r);
+ else
+ return foo (y, x, z, r, mpfr_div);
}
int
mpfr_add_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
{
- /* Mpz 0 is unsigned */
- if (MPFR_UNLIKELY (mpz_sgn (z) == 0))
- return mpfr_set (y, x, r);
+ if (mpz_fits_slong_p (z))
+ return mpfr_add_si (y, x, mpz_get_si (z), r);
else
return foo (y, x, z, r, mpfr_add);
}
@@ -105,9 +115,8 @@ mpfr_add_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
int
mpfr_sub_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
{
- /* Mpz 0 is unsigned */
- if (MPFR_UNLIKELY (mpz_sgn (z) == 0))
- return mpfr_set (y, x, r);
+ if (mpz_fits_slong_p (z))
+ return mpfr_sub_si (y, x, mpz_get_si (z), r);
else
return foo (y, x, z, r, mpfr_sub);
}
@@ -115,9 +124,8 @@ mpfr_sub_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
int
mpfr_z_sub (mpfr_ptr y, mpz_srcptr x, mpfr_srcptr z, mpfr_rnd_t r)
{
- /* Mpz 0 is unsigned */
- if (MPFR_UNLIKELY (mpz_sgn (x) == 0))
- return mpfr_neg (y, z, r);
+ if (mpz_fits_slong_p (x))
+ return mpfr_si_sub (y, mpz_get_si (x), z, r);
else
return foo2 (y, x, z, r, mpfr_sub);
}
@@ -128,11 +136,14 @@ mpfr_cmp_z (mpfr_srcptr x, mpz_srcptr z)
mpfr_t t;
int res;
mpfr_prec_t p;
- unsigned int flags;
+ mpfr_flags_t flags;
if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
return mpfr_cmp_si (x, mpz_sgn (z));
+ if (mpz_fits_slong_p (z))
+ return mpfr_cmp_si (x, mpz_get_si (z));
+
if (mpz_size (z) <= 1)
p = GMP_NUMB_BITS;
else
@@ -153,6 +164,7 @@ mpfr_cmp_z (mpfr_srcptr x, mpz_srcptr z)
return res;
}
+#ifndef MPFR_USE_MINI_GMP
/* Compute y = RND(x*n/d), where n and d are mpz integers.
An integer 0 is assumed to have a positive sign.
This function is used by mpfr_mul_q and mpfr_div_q.
@@ -220,7 +232,8 @@ mpfr_muldiv_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr n, mpz_srcptr d,
MPFR_ASSERTN (!MPFR_BLOCK_EXCEP));
MPFR_EXP (y) += ex;
/* Detect highly unlikely, not supported corner cases... */
- MPFR_ASSERTN (MPFR_EXP (y) >= __gmpfr_emin && MPFR_IS_PURE_FP (y));
+ MPFR_ASSERTN (MPFR_EXP (y) >= __gmpfr_emin);
+ MPFR_ASSERTN (! MPFR_IS_SINGULAR (y));
/* The potential overflow will be detected by mpfr_check_range. */
}
else
@@ -465,7 +478,9 @@ mpfr_cmp_q (mpfr_srcptr x, mpq_srcptr q)
MPFR_SAVE_EXPO_FREE (expo);
return res;
}
+#endif
+#ifndef MPFR_USE_MINI_GMP
int
mpfr_cmp_f (mpfr_srcptr x, mpf_srcptr z)
{
@@ -478,7 +493,7 @@ mpfr_cmp_f (mpfr_srcptr x, mpf_srcptr z)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (t, MPFR_PREC_MIN + ABS(SIZ(z)) * GMP_NUMB_BITS );
+ mpfr_init2 (t, MPFR_PREC_MIN + ABSIZ(z) * GMP_NUMB_BITS);
res = mpfr_set_f (t, z, MPFR_RNDN);
MPFR_ASSERTD (res == 0);
res = mpfr_cmp (x, t);
@@ -487,3 +502,4 @@ mpfr_cmp_f (mpfr_srcptr x, mpf_srcptr z)
MPFR_SAVE_EXPO_FREE (expo);
return res;
}
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/grandom.c b/Build/source/libs/mpfr/mpfr-src/src/grandom.c
index eee0eec1671..27a11719af0 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/grandom.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/grandom.c
@@ -1,5 +1,5 @@
/* mpfr_grandom (rop1, rop2, state, rnd_mode) -- Generate up to two
- pseudorandom real numbers according to a standard normal gaussian
+ pseudorandom real numbers according to a standard normal Gaussian
distribution and round it to the precision of rop1, rop2 according
to the given rounding mode.
diff --git a/Build/source/libs/mpfr/mpfr-src/src/hypot.c b/Build/source/libs/mpfr/mpfr-src/src/hypot.c
index 51bb00649bb..246f55d0b4a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/hypot.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/hypot.c
@@ -98,7 +98,13 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
/* If z > abs(x), then it was already rounded up; otherwise
z = abs(x), and we need to add one ulp due to y. */
if (mpfr_abs (z, x, rnd_mode) == 0)
- mpfr_nexttoinf (z);
+ {
+ mpfr_nexttoinf (z);
+ /* since mpfr_nexttoinf does not set the overflow flag,
+ we have to check manually for overflow */
+ if (MPFR_UNLIKELY (MPFR_IS_INF (z)))
+ MPFR_SET_OVERFLOW ();
+ }
MPFR_RET (1);
}
else /* MPFR_RNDZ, MPFR_RNDD, MPFR_RNDN */
@@ -111,7 +117,7 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
else
{
MPFR_SET_EXP (z, Ex);
- MPFR_SET_SIGN (z, 1);
+ MPFR_SET_SIGN (z, MPFR_SIGN_POS);
MPFR_RNDRAW_GEN (inexact, z, MPFR_MANT (x), N, rnd_mode, 1,
goto addoneulp,
if (MPFR_UNLIKELY (++ MPFR_EXP (z) >
@@ -139,11 +145,29 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- /* Scale x and y to avoid overflow/underflow in x^2 and overflow in y^2
- (as |x| >= |y|). The scaling of y can underflow only when the target
- precision is huge, otherwise the case would already have been handled
- by the diff_exp > threshold code. */
- sh = mpfr_get_emax () / 2 - Ex - 1;
+ /* Scale x and y to avoid any overflow and underflow in x^2
+ (as |x| >= |y|), and to limit underflow cases for y or y^2.
+ We have: x = Mx * 2^Ex with 1/2 <= |Mx| < 1, and we choose:
+ sh = floor((Emax - 1) / 2) - Ex.
+ Thus (x * 2^sh)^2 = Mx^2 * 2^(2*floor((Emax-1)/2)), which has an
+ exponent of at most Emax - 1. Therefore (x * 2^sh)^2 + (y * 2^sh)^2
+ will have an exponent of at most Emax, even after rounding as we
+ round toward zero. Using a larger sh wouldn't guarantee an absence
+ of overflow. Note that the scaling of y can underflow only when the
+ target precision is huge, otherwise the case would already have been
+ handled by the diff_exp > threshold code.
+ FIXME: Friedland in "Algorithm 312: Absolute Value and Square Root of a
+ Complex Number" (Communications of the ACM, 1967) avoids overflow by
+ computing |x|*sqrt(1+(y/x)^2) if |x| >= |y|, and |y|*sqrt(1+(x/y)^2)
+ otherwise.
+ [VL] This trick (which is a scaling by a non-power of 2, thus doesn't
+ really bring new behavior w.r.t. overflow/underflow exceptions) may be
+ useful for hardware floating-point formats because a whole power-of-2
+ scaling code is likely to take more time than the additional division,
+ but in the context of multiple-precision, I doubt that it is a good
+ idea. Ideally scaling by a power of 2 could be done in a constant time,
+ e.g. with MPFR_ALIAS; but one needs to be very careful... */
+ sh = (mpfr_get_emax () - 1) / 2 - Ex;
MPFR_ZIV_INIT (loop, Nt);
for (;;)
@@ -170,7 +194,7 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
MPFR_ZIV_FREE (loop);
MPFR_BLOCK (flags, inexact = mpfr_div_2si (z, t, sh, rnd_mode));
- MPFR_ASSERTD (exact == 0 || inexact != 0);
+ MPFR_ASSERTD (exact == 0 || inexact != 0 || rnd_mode == MPFR_RNDF);
mpfr_clear (t);
mpfr_clear (ti);
@@ -187,7 +211,7 @@ mpfr_hypot (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_FREE (expo);
if (MPFR_OVERFLOW (flags))
- mpfr_set_overflow ();
+ MPFR_SET_OVERFLOW ();
/* hypot(x,y) >= |x|, thus underflow is not possible. */
return mpfr_check_range (z, inexact, rnd_mode);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ieee_floats.h b/Build/source/libs/mpfr/mpfr-src/src/ieee_floats.h
index cae1c696124..cb791054590 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ieee_floats.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/ieee_floats.h
@@ -28,7 +28,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
on alphaev56-unknown-freebsd4.3 the NaN must be 8-bytes, since that
compiler+system was seen incorrectly converting from a "float" NaN. */
-#if _GMP_IEEE_FLOATS
+#if _MPFR_IEEE_FLOATS
/* The "d" field guarantees alignment to a suitable boundary for a double.
Could use a union instead, if we checked the compiler supports union
@@ -40,41 +40,38 @@ union dbl_bytes {
#define MPFR_DBL_INFP (dbl_infp.d)
#define MPFR_DBL_INFM (dbl_infm.d)
-#define MPFR_DBL_NAN (dbl_nan.d)
+#define MPFR_DBL_NAN DBL_NAN
-/* Warning! dbl_nan.d is not consistently the same NaN on all the
- processors: it can be either a qNaN (quiet) or sNaN (signaling).
- Processors are known to differ... */
+/* For NaN, we use DBL_NAN since the memory representation of a NaN depends
+ on the processor: a fixed memory representation could yield either a
+ quiet NaN (qNaN) or a signaling NaN (sNaN). For instance, HP PA-RISC
+ is known to do the opposite way of the usual choice recommended in
+ IEEE 754-2008; see:
+ http://grouper.ieee.org/groups/1788/email/msg03272.html
-#if HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+ Moreover, the right choice is to generate a qNaN in particular because
+ signaling NaNs are not supported by all compilers (note that the support
+ must be in the compiler used to build the user-end application because
+ this is where the sNaN will be obtained). */
+
+#ifdef HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
static const union dbl_bytes dbl_infp =
{ { 0, 0, 0, 0, 0, 0, 0xF0, 0x7F } };
static const union dbl_bytes dbl_infm =
{ { 0, 0, 0, 0, 0, 0, 0xF0, 0xFF } };
-static const union dbl_bytes dbl_nan =
- { { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F } };
#endif
-#if HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
-static const union dbl_bytes dbl_infp =
- { { 0, 0, 0xF0, 0x7F, 0, 0, 0, 0 } };
-static const union dbl_bytes dbl_infm =
- { { 0, 0, 0xF0, 0xFF, 0, 0, 0, 0 } };
-static const union dbl_bytes dbl_nan =
- { { 0, 0, 0xF8, 0x7F, 0, 0, 0, 0 } };
-#endif
-#if HAVE_DOUBLE_IEEE_BIG_ENDIAN
+
+#ifdef HAVE_DOUBLE_IEEE_BIG_ENDIAN
static const union dbl_bytes dbl_infp =
{ { 0x7F, 0xF0, 0, 0, 0, 0, 0, 0 } };
static const union dbl_bytes dbl_infm =
{ { 0xFF, 0xF0, 0, 0, 0, 0, 0, 0 } };
-static const union dbl_bytes dbl_nan =
- { { 0x7F, 0xF8, 0, 0, 0, 0, 0, 0 } };
#endif
-#else /* _GMP_IEEE_FLOATS */
+#else /* _MPFR_IEEE_FLOATS */
#define MPFR_DBL_INFP DBL_POS_INF
#define MPFR_DBL_INFM DBL_NEG_INF
#define MPFR_DBL_NAN DBL_NAN
-#endif /* _GMP_IEEE_FLOATS */
+#endif /* _MPFR_IEEE_FLOATS */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/init2.c b/Build/source/libs/mpfr/mpfr-src/src/init2.c
index 66a4b989cda..a08dd8f4dc6 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/init2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/init2.c
@@ -22,37 +22,37 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-void
+MPFR_HOT_FUNCTION_ATTR void
mpfr_init2 (mpfr_ptr x, mpfr_prec_t p)
{
mp_size_t xsize;
- mpfr_limb_ptr tmp;
+ mpfr_size_limb_t *tmp;
/* Check if we can represent the number of limbs
* associated to the maximum of mpfr_prec_t*/
- MPFR_ASSERTN( MP_SIZE_T_MAX >= (MPFR_PREC_MAX/MPFR_BYTES_PER_MP_LIMB) );
+ MPFR_STAT_STATIC_ASSERT( MP_SIZE_T_MAX >= (MPFR_PREC_MAX/MPFR_BYTES_PER_MP_LIMB) );
/* Check for correct GMP_NUMB_BITS and MPFR_BYTES_PER_MP_LIMB */
- MPFR_ASSERTN( GMP_NUMB_BITS == MPFR_BYTES_PER_MP_LIMB * CHAR_BIT
- && sizeof(mp_limb_t) == MPFR_BYTES_PER_MP_LIMB );
-
+ MPFR_STAT_STATIC_ASSERT( GMP_NUMB_BITS == MPFR_BYTES_PER_MP_LIMB * CHAR_BIT
+ && sizeof(mp_limb_t) == MPFR_BYTES_PER_MP_LIMB );
+ /* Check for mp_bits_per_limb (a global variable inside GMP library) */
MPFR_ASSERTN (mp_bits_per_limb == GMP_NUMB_BITS);
/* Check for correct EXP NAN, ZERO & INF in both mpfr.h and mpfr-impl.h */
- MPFR_ASSERTN( __MPFR_EXP_NAN == MPFR_EXP_NAN );
- MPFR_ASSERTN( __MPFR_EXP_ZERO == MPFR_EXP_ZERO );
- MPFR_ASSERTN( __MPFR_EXP_INF == MPFR_EXP_INF );
+ MPFR_STAT_STATIC_ASSERT( __MPFR_EXP_NAN == MPFR_EXP_NAN );
+ MPFR_STAT_STATIC_ASSERT( __MPFR_EXP_ZERO == MPFR_EXP_ZERO );
+ MPFR_STAT_STATIC_ASSERT( __MPFR_EXP_INF == MPFR_EXP_INF );
- MPFR_ASSERTN( MPFR_EMAX_MAX <= (MPFR_EXP_MAX >> 1) );
- MPFR_ASSERTN( MPFR_EMIN_MIN >= -(MPFR_EXP_MAX >> 1) );
+ MPFR_STAT_STATIC_ASSERT( MPFR_EMAX_MAX <= (MPFR_EXP_MAX >> 1) );
+ MPFR_STAT_STATIC_ASSERT( MPFR_EMIN_MIN >= -(MPFR_EXP_MAX >> 1) );
/* p=1 is not allowed since the rounding to nearest even rule requires at
- least two bits of mantissa: the neighbours of 3/2 are 1*2^0 and 1*2^1,
+ least two bits of mantissa: the neighbors of 3/2 are 1*2^0 and 1*2^1,
which both have an odd mantissa */
- MPFR_ASSERTN(p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (MPFR_PREC_COND (p));
xsize = MPFR_PREC2LIMBS (p);
- tmp = (mpfr_limb_ptr) (*__gmp_allocate_func)(MPFR_MALLOC_SIZE(xsize));
+ tmp = (mpfr_size_limb_t *) mpfr_allocate_func(MPFR_MALLOC_SIZE(xsize));
MPFR_PREC(x) = p; /* Set prec */
MPFR_EXP (x) = MPFR_EXP_INVALID; /* make sure that the exp field has a
@@ -62,8 +62,3 @@ mpfr_init2 (mpfr_ptr x, mpfr_prec_t p)
MPFR_SET_ALLOC_SIZE(x, xsize); /* Fix alloc size of Mantissa */
MPFR_SET_NAN(x); /* initializes to NaN */
}
-
-#ifdef MPFR_USE_OWN_MPFR_TMP_ALLOC
-static unsigned char mpfr_stack_tab[8000000];
-unsigned char *mpfr_stack = mpfr_stack_tab;
-#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/inits.c b/Build/source/libs/mpfr/mpfr-src/src/inits.c
index 959d822c06d..4491e13f683 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/inits.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/inits.c
@@ -21,8 +21,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-#undef HAVE_STDARG
-#include "config.h" /* for a build within gmp */
+# undef HAVE_STDARG
+# include "config.h"
#endif
#if HAVE_STDARG
diff --git a/Build/source/libs/mpfr/mpfr-src/src/inits2.c b/Build/source/libs/mpfr/mpfr-src/src/inits2.c
index c6784444684..1b9fe1bc0ae 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/inits2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/inits2.c
@@ -22,8 +22,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-#undef HAVE_STDARG
-#include "config.h" /* for a build within gmp */
+# undef HAVE_STDARG
+# include "config.h"
#endif
#if HAVE_STDARG
diff --git a/Build/source/libs/mpfr/mpfr-src/src/inp_str.c b/Build/source/libs/mpfr/mpfr-src/src/inp_str.c
index db8a1bd8643..7facdeaaeae 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/inp_str.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/inp_str.c
@@ -41,7 +41,7 @@ mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mpfr_rnd_t rnd_mode)
stream = stdin;
alloc_size = 100;
- str = (unsigned char *) (*__gmp_allocate_func) (alloc_size);
+ str = (unsigned char *) mpfr_allocate_func (alloc_size);
str_size = 0;
nread = 0;
@@ -62,7 +62,7 @@ mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mpfr_rnd_t rnd_mode)
size_t old_alloc_size = alloc_size;
alloc_size = alloc_size * 3 / 2;
str = (unsigned char *)
- (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
+ mpfr_reallocate_func (str, old_alloc_size, alloc_size);
}
if (c == EOF || isspace (c))
break;
@@ -80,7 +80,7 @@ mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mpfr_rnd_t rnd_mode)
str[str_size] = '\0';
retval = mpfr_set_str (rop, (char *) str, base, rnd_mode);
- (*__gmp_free_func) (str, alloc_size);
+ mpfr_free_func (str, alloc_size);
if (retval == -1)
return 0; /* error */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/invert_limb.h b/Build/source/libs/mpfr/mpfr-src/src/invert_limb.h
new file mode 100644
index 00000000000..b65214fa507
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/invert_limb.h
@@ -0,0 +1,233 @@
+/* __gmpfr_invert_limb -- implement GMP's invert_limb (which is not in GMP API)
+
+Copyright 2016-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* for now, we only provide __gmpfr_invert_limb for 64-bit limb */
+#if GMP_NUMB_BITS == 64
+
+/* umul_hi(h, x, y) puts in h the high part of x*y */
+#ifdef HAVE_MULX_U64
+#include <immintrin.h>
+#define umul_hi(h, x, y) _mulx_u64 (x, y, (unsigned long long *) &h)
+#else
+#define umul_hi(h, x, y) \
+ do { \
+ mp_limb_t _l; \
+ umul_ppmm (h, _l, x, y); \
+ } while (0)
+#endif
+
+/* for 256 <= d9 < 512, invert_limb_table[d9-256] = floor((2^19-3*2^8)/d9)*2^11 */
+static const mp_limb_t invert_limb_table[256] =
+ { 2045<<11, 2037<<11, 2029<<11, 2021<<11, 2013<<11, 2005<<11, 1998<<11, 1990<<11,
+ 1983<<11, 1975<<11, 1968<<11, 1960<<11, 1953<<11, 1946<<11, 1938<<11, 1931<<11,
+ 1924<<11, 1917<<11, 1910<<11, 1903<<11, 1896<<11, 1889<<11, 1883<<11, 1876<<11,
+ 1869<<11, 1863<<11, 1856<<11, 1849<<11, 1843<<11, 1836<<11, 1830<<11, 1824<<11,
+ 1817<<11, 1811<<11, 1805<<11, 1799<<11, 1792<<11, 1786<<11, 1780<<11, 1774<<11,
+ 1768<<11, 1762<<11, 1756<<11, 1750<<11, 1745<<11, 1739<<11, 1733<<11, 1727<<11,
+ 1722<<11, 1716<<11, 1710<<11, 1705<<11, 1699<<11, 1694<<11, 1688<<11, 1683<<11,
+ 1677<<11, 1672<<11, 1667<<11, 1661<<11, 1656<<11, 1651<<11, 1646<<11, 1641<<11,
+ 1636<<11, 1630<<11, 1625<<11, 1620<<11, 1615<<11, 1610<<11, 1605<<11, 1600<<11,
+ 1596<<11, 1591<<11, 1586<<11, 1581<<11, 1576<<11, 1572<<11, 1567<<11, 1562<<11,
+ 1558<<11, 1553<<11, 1548<<11, 1544<<11, 1539<<11, 1535<<11, 1530<<11, 1526<<11,
+ 1521<<11, 1517<<11, 1513<<11, 1508<<11, 1504<<11, 1500<<11, 1495<<11, 1491<<11,
+ 1487<<11, 1483<<11, 1478<<11, 1474<<11, 1470<<11, 1466<<11, 1462<<11, 1458<<11,
+ 1454<<11, 1450<<11, 1446<<11, 1442<<11, 1438<<11, 1434<<11, 1430<<11, 1426<<11,
+ 1422<<11, 1418<<11, 1414<<11, 1411<<11, 1407<<11, 1403<<11, 1399<<11, 1396<<11,
+ 1392<<11, 1388<<11, 1384<<11, 1381<<11, 1377<<11, 1374<<11, 1370<<11, 1366<<11,
+ 1363<<11, 1359<<11, 1356<<11, 1352<<11, 1349<<11, 1345<<11, 1342<<11, 1338<<11,
+ 1335<<11, 1332<<11, 1328<<11, 1325<<11, 1322<<11, 1318<<11, 1315<<11, 1312<<11,
+ 1308<<11, 1305<<11, 1302<<11, 1299<<11, 1295<<11, 1292<<11, 1289<<11, 1286<<11,
+ 1283<<11, 1280<<11, 1276<<11, 1273<<11, 1270<<11, 1267<<11, 1264<<11, 1261<<11,
+ 1258<<11, 1255<<11, 1252<<11, 1249<<11, 1246<<11, 1243<<11, 1240<<11, 1237<<11,
+ 1234<<11, 1231<<11, 1228<<11, 1226<<11, 1223<<11, 1220<<11, 1217<<11, 1214<<11,
+ 1211<<11, 1209<<11, 1206<<11, 1203<<11, 1200<<11, 1197<<11, 1195<<11, 1192<<11,
+ 1189<<11, 1187<<11, 1184<<11, 1181<<11, 1179<<11, 1176<<11, 1173<<11, 1171<<11,
+ 1168<<11, 1165<<11, 1163<<11, 1160<<11, 1158<<11, 1155<<11, 1153<<11, 1150<<11,
+ 1148<<11, 1145<<11, 1143<<11, 1140<<11, 1138<<11, 1135<<11, 1133<<11, 1130<<11,
+ 1128<<11, 1125<<11, 1123<<11, 1121<<11, 1118<<11, 1116<<11, 1113<<11, 1111<<11,
+ 1109<<11, 1106<<11, 1104<<11, 1102<<11, 1099<<11, 1097<<11, 1095<<11, 1092<<11,
+ 1090<<11, 1088<<11, 1086<<11, 1083<<11, 1081<<11, 1079<<11, 1077<<11, 1074<<11,
+ 1072<<11, 1070<<11, 1068<<11, 1066<<11, 1064<<11, 1061<<11, 1059<<11, 1057<<11,
+ 1055<<11, 1053<<11, 1051<<11, 1049<<11, 1047<<11, 1044<<11, 1042<<11, 1040<<11,
+ 1038<<11, 1036<<11, 1034<<11, 1032<<11, 1030<<11, 1028<<11, 1026<<11, 1024<<11 };
+
+/* for 256 <= d9 < 512, invert_limb_table2[d9-256] = floor((2^19-3*2^8)/d9)^2 */
+static const mp_limb_t invert_limb_table2[256] =
+ { 4182025, 4149369, 4116841, 4084441, 4052169, 4020025, 3992004, 3960100, 3932289,
+ 3900625, 3873024, 3841600, 3814209, 3786916, 3755844, 3728761, 3701776, 3674889,
+ 3648100, 3621409, 3594816, 3568321, 3545689, 3519376, 3493161, 3470769, 3444736,
+ 3418801, 3396649, 3370896, 3348900, 3326976, 3301489, 3279721, 3258025, 3236401,
+ 3211264, 3189796, 3168400, 3147076, 3125824, 3104644, 3083536, 3062500, 3045025,
+ 3024121, 3003289, 2982529, 2965284, 2944656, 2924100, 2907025, 2886601, 2869636,
+ 2849344, 2832489, 2812329, 2795584, 2778889, 2758921, 2742336, 2725801, 2709316,
+ 2692881, 2676496, 2656900, 2640625, 2624400, 2608225, 2592100, 2576025, 2560000,
+ 2547216, 2531281, 2515396, 2499561, 2483776, 2471184, 2455489, 2439844, 2427364,
+ 2411809, 2396304, 2383936, 2368521, 2356225, 2340900, 2328676, 2313441, 2301289,
+ 2289169, 2274064, 2262016, 2250000, 2235025, 2223081, 2211169, 2199289, 2184484,
+ 2172676, 2160900, 2149156, 2137444, 2125764, 2114116, 2102500, 2090916, 2079364,
+ 2067844, 2056356, 2044900, 2033476, 2022084, 2010724, 1999396, 1990921, 1979649,
+ 1968409, 1957201, 1948816, 1937664, 1926544, 1915456, 1907161, 1896129, 1887876,
+ 1876900, 1865956, 1857769, 1846881, 1838736, 1827904, 1819801, 1809025, 1800964,
+ 1790244, 1782225, 1774224, 1763584, 1755625, 1747684, 1737124, 1729225, 1721344,
+ 1710864, 1703025, 1695204, 1687401, 1677025, 1669264, 1661521, 1653796, 1646089,
+ 1638400, 1628176, 1620529, 1612900, 1605289, 1597696, 1590121, 1582564, 1575025,
+ 1567504, 1560001, 1552516, 1545049, 1537600, 1530169, 1522756, 1515361, 1507984,
+ 1503076, 1495729, 1488400, 1481089, 1473796, 1466521, 1461681, 1454436, 1447209,
+ 1440000, 1432809, 1428025, 1420864, 1413721, 1408969, 1401856, 1394761, 1390041,
+ 1382976, 1375929, 1371241, 1364224, 1357225, 1352569, 1345600, 1340964, 1334025,
+ 1329409, 1322500, 1317904, 1311025, 1306449, 1299600, 1295044, 1288225, 1283689,
+ 1276900, 1272384, 1265625, 1261129, 1256641, 1249924, 1245456, 1238769, 1234321,
+ 1229881, 1223236, 1218816, 1214404, 1207801, 1203409, 1199025, 1192464, 1188100,
+ 1183744, 1179396, 1172889, 1168561, 1164241, 1159929, 1153476, 1149184, 1144900,
+ 1140624, 1136356, 1132096, 1125721, 1121481, 1117249, 1113025, 1108809, 1104601,
+ 1100401, 1096209, 1089936, 1085764, 1081600, 1077444, 1073296, 1069156, 1065024,
+ 1060900, 1056784, 1052676, 1048576 };
+
+/* Implements Algorithm 2 from "Improved Division by Invariant Integers",
+ Niels Möller and Torbjörn Granlund, IEEE Transactions on Computers,
+ volume 60, number 2, pages 165-175, 2011. */
+#define __gmpfr_invert_limb(r, d) \
+ do { \
+ mp_limb_t _d, _d0, _i, _d40, _d63, _v0, _v1, _v2, _e, _v3, _h, _l; \
+ _d = (d); \
+ _i = (_d >> 55) - 256; /* i = d9 - 256 */ \
+ _v0 = invert_limb_table[_i]; \
+ _d40 = (_d >> 24) + 1; \
+ _v1 = _v0 - ((invert_limb_table2[_i] * _d40) >> 40) - 1; \
+ _v2 = (_v1 << 13) + \
+ ((_v1 * ((MPFR_LIMB_ONE << 60) - _v1 * _d40)) >> 47); \
+ _d0 = _d & 1; \
+ _d63 = ((_d - 1) >> 1) + 1; \
+ _e = - _v2 * _d63 + ((_v2 & -_d0) >> 1); \
+ umul_hi (_h, _v2, _e); \
+ _v3 = (_v2 << 31) + (_h >> 1); \
+ umul_ppmm (_h, _l, _v3, d); \
+ /* v3 is too small iff (h+d)*2^64+l+d < 2^128 */ \
+ add_ssaaaa(_h, _l, _h, _l, _d, _d); \
+ MPFR_ASSERTD(_h == MPFR_LIMB_ZERO || -_h == MPFR_LIMB_ONE); \
+ (r) = _v3 - _h; \
+ } while (0)
+
+/* same algorithm, but return the value v3, which is such that
+ v3 <= invert_limb (d) <= v3 + 1 */
+#define __gmpfr_invert_limb_approx(r, d) \
+ do { \
+ mp_limb_t _d, _d0, _i, _d40, _d63, _v0, _v1, _v2, _e, _h; \
+ _d = (d); \
+ _i = (_d >> 55) - 256; /* i = d9 - 256 */ \
+ _v0 = invert_limb_table[_i]; \
+ _d40 = (_d >> 24) + 1; \
+ _v1 = _v0 - ((invert_limb_table2[_i] * _d40) >> 40) - 1; \
+ _v2 = (_v1 << 13) + \
+ ((_v1 * ((MPFR_LIMB_ONE << 60) - _v1 * _d40)) >> 47); \
+ _d0 = _d & 1; \
+ _d63 = ((_d - 1) >> 1) + 1; \
+ _e = - _v2 * _d63 + ((_v2 & -_d0) >> 1); \
+ umul_hi (_h, _v2, _e); \
+ (r) = (_v2 << 31) + (_h >> 1); \
+ } while (0)
+
+#elif GMP_NUMB_BITS == 32
+
+/* for 512 <= d10 < 1024, l[d10-512] = floor((2^24-2^14+2^9)/d10) */
+static const mp_limb_t invert_limb_table[512] =
+ { 32737, 32673, 32609, 32546, 32483, 32420, 32357, 32295, 32233, 32171,
+ 32109, 32048, 31987, 31926, 31865, 31805, 31744, 31684, 31625, 31565,
+ 31506, 31447, 31388, 31329, 31271, 31212, 31154, 31097, 31039, 30982,
+ 30924, 30868, 30811, 30754, 30698, 30642, 30586, 30530, 30475, 30419,
+ 30364, 30309, 30255, 30200, 30146, 30092, 30038, 29984, 29930, 29877,
+ 29824, 29771, 29718, 29666, 29613, 29561, 29509, 29457, 29405, 29354,
+ 29303, 29251, 29200, 29150, 29099, 29049, 28998, 28948, 28898, 28849,
+ 28799, 28750, 28700, 28651, 28602, 28554, 28505, 28457, 28409, 28360,
+ 28313, 28265, 28217, 28170, 28123, 28075, 28029, 27982, 27935, 27889,
+ 27842, 27796, 27750, 27704, 27658, 27613, 27568, 27522, 27477, 27432,
+ 27387, 27343, 27298, 27254, 27209, 27165, 27121, 27078, 27034, 26990,
+ 26947, 26904, 26861, 26818, 26775, 26732, 26690, 26647, 26605, 26563,
+ 26521, 26479, 26437, 26395, 26354, 26312, 26271, 26230, 26189, 26148,
+ 26108, 26067, 26026, 25986, 25946, 25906, 25866, 25826, 25786, 25747,
+ 25707, 25668, 25628, 25589, 25550, 25511, 25473, 25434, 25395, 25357,
+ 25319, 25281, 25242, 25205, 25167, 25129, 25091, 25054, 25016, 24979,
+ 24942, 24905, 24868, 24831, 24794, 24758, 24721, 24685, 24649, 24612,
+ 24576, 24540, 24504, 24469, 24433, 24397, 24362, 24327, 24291, 24256,
+ 24221, 24186, 24151, 24117, 24082, 24047, 24013, 23979, 23944, 23910,
+ 23876, 23842, 23808, 23774, 23741, 23707, 23674, 23640, 23607, 23574,
+ 23541, 23508, 23475, 23442, 23409, 23377, 23344, 23312, 23279, 23247,
+ 23215, 23183, 23151, 23119, 23087, 23055, 23023, 22992, 22960, 22929,
+ 22898, 22866, 22835, 22804, 22773, 22742, 22711, 22681, 22650, 22619,
+ 22589, 22559, 22528, 22498, 22468, 22438, 22408, 22378, 22348, 22318,
+ 22289, 22259, 22229, 22200, 22171, 22141, 22112, 22083, 22054, 22025,
+ 21996, 21967, 21938, 21910, 21881, 21853, 21824, 21796, 21767, 21739,
+ 21711, 21683, 21655, 21627, 21599, 21571, 21544, 21516, 21488, 21461,
+ 21433, 21406, 21379, 21352, 21324, 21297, 21270, 21243, 21216, 21190,
+ 21163, 21136, 21110, 21083, 21056, 21030, 21004, 20977, 20951, 20925,
+ 20899, 20873, 20847, 20821, 20795, 20769, 20744, 20718, 20693, 20667,
+ 20642, 20616, 20591, 20566, 20540, 20515, 20490, 20465, 20440, 20415,
+ 20390, 20366, 20341, 20316, 20292, 20267, 20243, 20218, 20194, 20170,
+ 20145, 20121, 20097, 20073, 20049, 20025, 20001, 19977, 19953, 19930,
+ 19906, 19882, 19859, 19835, 19812, 19789, 19765, 19742, 19719, 19696,
+ 19672, 19649, 19626, 19603, 19581, 19558, 19535, 19512, 19489, 19467,
+ 19444, 19422, 19399, 19377, 19354, 19332, 19310, 19288, 19265, 19243,
+ 19221, 19199, 19177, 19155, 19133, 19112, 19090, 19068, 19046, 19025,
+ 19003, 18982, 18960, 18939, 18917, 18896, 18875, 18854, 18832, 18811,
+ 18790, 18769, 18748, 18727, 18706, 18686, 18665, 18644, 18623, 18603,
+ 18582, 18561, 18541, 18520, 18500, 18479, 18459, 18439, 18419, 18398,
+ 18378, 18358, 18338, 18318, 18298, 18278, 18258, 18238, 18218, 18199,
+ 18179, 18159, 18139, 18120, 18100, 18081, 18061, 18042, 18022, 18003,
+ 17984, 17964, 17945, 17926, 17907, 17888, 17869, 17850, 17831, 17812,
+ 17793, 17774, 17755, 17736, 17718, 17699, 17680, 17662, 17643, 17624,
+ 17606, 17587, 17569, 17551, 17532, 17514, 17496, 17477, 17459, 17441,
+ 17423, 17405, 17387, 17369, 17351, 17333, 17315, 17297, 17279, 17261,
+ 17244, 17226, 17208, 17191, 17173, 17155, 17138, 17120, 17103, 17085,
+ 17068, 17051, 17033, 17016, 16999, 16982, 16964, 16947, 16930, 16913,
+ 16896, 16879, 16862, 16845, 16828, 16811, 16794, 16778, 16761, 16744,
+ 16727, 16711, 16694, 16677, 16661, 16644, 16628, 16611, 16595, 16578,
+ 16562, 16546, 16529, 16513, 16497, 16481, 16464, 16448, 16432, 16416,
+ 16400, 16384 };
+
+/* Implements Algorithm 3 from "Improved Division by Invariant Integers",
+ Niels Möller and Torbjörn Granlund, IEEE Transactions on Computers,
+ volume 60, number 2, pages 165-175, 2011. */
+#define __gmpfr_invert_limb(r, d) \
+ do { \
+ mp_limb_t _d, _d0, _d10, _d21, _d31, _v0, _v1, _v2, _e, _h, _l; \
+ _d = (d); \
+ _d0 = _d & 1; \
+ _d10 = _d >> 22; \
+ _d21 = (_d >> 11) + 1; \
+ _d31 = ((_d - 1) >> 1) + 1; \
+ _v0 = invert_limb_table[_d10 - 512]; \
+ umul_ppmm (_h, _l, _v0 * _v0, _d21); \
+ _v1 = (_v0 << 4) - _h - 1; \
+ _e = - _v1 * _d31 + ((_v1 & - _d0) >> 1); \
+ umul_ppmm (_h, _l, _v1, _e); \
+ _v2 = (_v1 << 15) + (_h >> 1); \
+ umul_ppmm (_h, _l, _v2, d); \
+ /* v2 is too small iff (h+d)*2^32+l+d < 2^64 */ \
+ add_ssaaaa(_h, _l, _h, _l, _d, _d); \
+ MPFR_ASSERTD(_h == MPFR_LIMB_ZERO || -_h == MPFR_LIMB_ONE); \
+ (r) = _v2 - _h; \
+ } while (0)
+
+#endif /* GMP_NUMB_BITS == 64 or 32 */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/invsqrt_limb.h b/Build/source/libs/mpfr/mpfr-src/src/invsqrt_limb.h
new file mode 100644
index 00000000000..54af7b76c9b
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/invsqrt_limb.h
@@ -0,0 +1,365 @@
+/* __gmpfr_invsqrt_limb_approx -- reciprocal approximate square root of a limb
+
+Copyright 2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* for now, we only provide __gmpfr_invert_limb for 64-bit limb */
+#if GMP_NUMB_BITS == 64
+
+/* For 257 <= d10 <= 1024, T[d10-257] = floor(sqrt(2^30/d10)).
+ Sage code:
+ T = [floor(sqrt(2^30/d10)) for d10 in [257..1024]] */
+static const mp_limb_t T[768] =
+ { 2044, 2040, 2036, 2032, 2028, 2024, 2020, 2016, 2012, 2009, 2005,
+ 2001, 1997, 1994, 1990, 1986, 1983, 1979, 1975, 1972, 1968, 1965, 1961,
+ 1958, 1954, 1951, 1947, 1944, 1941, 1937, 1934, 1930, 1927, 1924, 1920,
+ 1917, 1914, 1911, 1907, 1904, 1901, 1898, 1895, 1891, 1888, 1885, 1882,
+ 1879, 1876, 1873, 1870, 1867, 1864, 1861, 1858, 1855, 1852, 1849, 1846,
+ 1843, 1840, 1837, 1834, 1831, 1828, 1826, 1823, 1820, 1817, 1814, 1812,
+ 1809, 1806, 1803, 1801, 1798, 1795, 1792, 1790, 1787, 1784, 1782, 1779,
+ 1777, 1774, 1771, 1769, 1766, 1764, 1761, 1759, 1756, 1754, 1751, 1749,
+ 1746, 1744, 1741, 1739, 1736, 1734, 1731, 1729, 1727, 1724, 1722, 1719,
+ 1717, 1715, 1712, 1710, 1708, 1705, 1703, 1701, 1698, 1696, 1694, 1692,
+ 1689, 1687, 1685, 1683, 1680, 1678, 1676, 1674, 1672, 1670, 1667, 1665,
+ 1663, 1661, 1659, 1657, 1655, 1652, 1650, 1648, 1646, 1644, 1642, 1640,
+ 1638, 1636, 1634, 1632, 1630, 1628, 1626, 1624, 1622, 1620, 1618, 1616,
+ 1614, 1612, 1610, 1608, 1606, 1604, 1602, 1600, 1598, 1597, 1595, 1593,
+ 1591, 1589, 1587, 1585, 1583, 1582, 1580, 1578, 1576, 1574, 1572, 1571,
+ 1569, 1567, 1565, 1563, 1562, 1560, 1558, 1556, 1555, 1553, 1551, 1549,
+ 1548, 1546, 1544, 1542, 1541, 1539, 1537, 1536, 1534, 1532, 1531, 1529,
+ 1527, 1526, 1524, 1522, 1521, 1519, 1517, 1516, 1514, 1513, 1511, 1509,
+ 1508, 1506, 1505, 1503, 1501, 1500, 1498, 1497, 1495, 1494, 1492, 1490,
+ 1489, 1487, 1486, 1484, 1483, 1481, 1480, 1478, 1477, 1475, 1474, 1472,
+ 1471, 1469, 1468, 1466, 1465, 1463, 1462, 1461, 1459, 1458, 1456, 1455,
+ 1453, 1452, 1450, 1449, 1448, 1446, 1445, 1443, 1442, 1441, 1439, 1438,
+ 1436, 1435, 1434, 1432, 1431, 1430, 1428, 1427, 1426, 1424, 1423, 1422,
+ 1420, 1419, 1418, 1416, 1415, 1414, 1412, 1411, 1410, 1408, 1407, 1406,
+ 1404, 1403, 1402, 1401, 1399, 1398, 1397, 1395, 1394, 1393, 1392, 1390,
+ 1389, 1388, 1387, 1385, 1384, 1383, 1382, 1381, 1379, 1378, 1377, 1376,
+ 1374, 1373, 1372, 1371, 1370, 1368, 1367, 1366, 1365, 1364, 1362, 1361,
+ 1360, 1359, 1358, 1357, 1355, 1354, 1353, 1352, 1351, 1350, 1349, 1347,
+ 1346, 1345, 1344, 1343, 1342, 1341, 1339, 1338, 1337, 1336, 1335, 1334,
+ 1333, 1332, 1331, 1330, 1328, 1327, 1326, 1325, 1324, 1323, 1322, 1321,
+ 1320, 1319, 1318, 1317, 1315, 1314, 1313, 1312, 1311, 1310, 1309, 1308,
+ 1307, 1306, 1305, 1304, 1303, 1302, 1301, 1300, 1299, 1298, 1297, 1296,
+ 1295, 1294, 1293, 1292, 1291, 1290, 1289, 1288, 1287, 1286, 1285, 1284,
+ 1283, 1282, 1281, 1280, 1279, 1278, 1277, 1276, 1275, 1274, 1273, 1272,
+ 1271, 1270, 1269, 1268, 1267, 1266, 1265, 1264, 1264, 1263, 1262, 1261,
+ 1260, 1259, 1258, 1257, 1256, 1255, 1254, 1253, 1252, 1252, 1251, 1250,
+ 1249, 1248, 1247, 1246, 1245, 1244, 1243, 1242, 1242, 1241, 1240, 1239,
+ 1238, 1237, 1236, 1235, 1234, 1234, 1233, 1232, 1231, 1230, 1229, 1228,
+ 1228, 1227, 1226, 1225, 1224, 1223, 1222, 1222, 1221, 1220, 1219, 1218,
+ 1217, 1216, 1216, 1215, 1214, 1213, 1212, 1211, 1211, 1210, 1209, 1208,
+ 1207, 1207, 1206, 1205, 1204, 1203, 1202, 1202, 1201, 1200, 1199, 1198,
+ 1198, 1197, 1196, 1195, 1194, 1194, 1193, 1192, 1191, 1190, 1190, 1189,
+ 1188, 1187, 1187, 1186, 1185, 1184, 1183, 1183, 1182, 1181, 1180, 1180,
+ 1179, 1178, 1177, 1177, 1176, 1175, 1174, 1174, 1173, 1172, 1171, 1171,
+ 1170, 1169, 1168, 1168, 1167, 1166, 1165, 1165, 1164, 1163, 1162, 1162,
+ 1161, 1160, 1159, 1159, 1158, 1157, 1157, 1156, 1155, 1154, 1154, 1153,
+ 1152, 1152, 1151, 1150, 1149, 1149, 1148, 1147, 1147, 1146, 1145, 1145,
+ 1144, 1143, 1142, 1142, 1141, 1140, 1140, 1139, 1138, 1138, 1137, 1136,
+ 1136, 1135, 1134, 1133, 1133, 1132, 1131, 1131, 1130, 1129, 1129, 1128,
+ 1127, 1127, 1126, 1125, 1125, 1124, 1123, 1123, 1122, 1121, 1121, 1120,
+ 1119, 1119, 1118, 1118, 1117, 1116, 1116, 1115, 1114, 1114, 1113, 1112,
+ 1112, 1111, 1110, 1110, 1109, 1109, 1108, 1107, 1107, 1106, 1105, 1105,
+ 1104, 1103, 1103, 1102, 1102, 1101, 1100, 1100, 1099, 1099, 1098, 1097,
+ 1097, 1096, 1095, 1095, 1094, 1094, 1093, 1092, 1092, 1091, 1091, 1090,
+ 1089, 1089, 1088, 1088, 1087, 1086, 1086, 1085, 1085, 1084, 1083, 1083,
+ 1082, 1082, 1081, 1080, 1080, 1079, 1079, 1078, 1077, 1077, 1076, 1076,
+ 1075, 1075, 1074, 1073, 1073, 1072, 1072, 1071, 1071, 1070, 1069, 1069,
+ 1068, 1068, 1067, 1067, 1066, 1065, 1065, 1064, 1064, 1063, 1063, 1062,
+ 1062, 1061, 1060, 1060, 1059, 1059, 1058, 1058, 1057, 1057, 1056, 1055,
+ 1055, 1054, 1054, 1053, 1053, 1052, 1052, 1051, 1051, 1050, 1049, 1049,
+ 1048, 1048, 1047, 1047, 1046, 1046, 1045, 1045, 1044, 1044, 1043, 1043,
+ 1042, 1041, 1041, 1040, 1040, 1039, 1039, 1038, 1038, 1037, 1037, 1036,
+ 1036, 1035, 1035, 1034, 1034, 1033, 1033, 1032, 1032, 1031, 1031, 1030,
+ 1030, 1029, 1029, 1028, 1028, 1027, 1027, 1026, 1026, 1025, 1025, 1024,
+ 1024 };
+
+/* table of v0^3 */
+static const mp_limb_t T3[768] =
+ { 8539701184, 8489664000, 8439822656, 8390176768, 8340725952,
+ 8291469824, 8242408000, 8193540096, 8144865728, 8108486729, 8060150125,
+ 8012006001, 7964053973, 7928215784, 7880599000, 7833173256, 7797729087,
+ 7750636739, 7703734375, 7668682048, 7622111232, 7587307125, 7541066681,
+ 7506509912, 7460598664, 7426288351, 7380705123, 7346640384, 7312680621,
+ 7267563953, 7233848504, 7189057000, 7155584983, 7122217024, 7077888000,
+ 7044762213, 7011739944, 6978821031, 6935089643, 6902411264, 6869835701,
+ 6837362792, 6804992375, 6761990971, 6729859072, 6697829125, 6665900968,
+ 6634074439, 6602349376, 6570725617, 6539203000, 6507781363, 6476460544,
+ 6445240381, 6414120712, 6383101375, 6352182208, 6321363049, 6290643736,
+ 6260024107, 6229504000, 6199083253, 6168761704, 6138539191, 6108415552,
+ 6088387976, 6058428767, 6028568000, 5998805513, 5969141144, 5949419328,
+ 5919918129, 5890514616, 5861208627, 5841725401, 5812581592, 5783534875,
+ 5754585088, 5735339000, 5706550403, 5677858304, 5658783768, 5630252139,
+ 5611284433, 5582912824, 5554637011, 5535839609, 5507723096, 5489031744,
+ 5461074081, 5442488479, 5414689216, 5396209064, 5368567751, 5350192749,
+ 5322708936, 5304438784, 5277112021, 5258946419, 5231776256, 5213714904,
+ 5186700891, 5168743489, 5150827583, 5124031424, 5106219048, 5079577959,
+ 5061868813, 5044200875, 5017776128, 5000211000, 4982686912, 4956477625,
+ 4939055927, 4921675101, 4895680392, 4878401536, 4861163384, 4843965888,
+ 4818245769, 4801149703, 4784094125, 4767078987, 4741632000, 4724717752,
+ 4707843776, 4691010024, 4674216448, 4657463000, 4632407963, 4615754625,
+ 4599141247, 4582567781, 4566034179, 4549540393, 4533086375, 4508479808,
+ 4492125000, 4475809792, 4459534136, 4443297984, 4427101288, 4410944000,
+ 4394826072, 4378747456, 4362708104, 4346707968, 4330747000, 4314825152,
+ 4298942376, 4283098624, 4267293848, 4251528000, 4235801032, 4220112896,
+ 4204463544, 4188852928, 4173281000, 4157747712, 4142253016, 4126796864,
+ 4111379208, 4096000000, 4080659192, 4073003173, 4057719875, 4042474857,
+ 4027268071, 4012099469, 3996969003, 3981876625, 3966822287, 3959309368,
+ 3944312000, 3929352552, 3914430976, 3899547224, 3884701248, 3877292411,
+ 3862503009, 3847751263, 3833037125, 3818360547, 3811036328, 3796416000,
+ 3781833112, 3767287616, 3760028875, 3745539377, 3731087151, 3716672149,
+ 3709478592, 3695119336, 3680797184, 3666512088, 3659383421, 3645153819,
+ 3630961153, 3623878656, 3609741304, 3595640768, 3588604291, 3574558889,
+ 3560550183, 3553559576, 3539605824, 3525688648, 3518743761, 3504881359,
+ 3491055413, 3484156096, 3470384744, 3463512697, 3449795831, 3436115229,
+ 3429288512, 3415662216, 3408862625, 3395290527, 3381754501, 3375000000,
+ 3361517992, 3354790473, 3341362375, 3334661784, 3321287488, 3307949000,
+ 3301293169, 3288008303, 3281379256, 3268147904, 3261545587, 3248367641,
+ 3241792000, 3228667352, 3222118333, 3209046875, 3202524424, 3189506048,
+ 3183010111, 3170044709, 3163575232, 3150662696, 3144219625, 3131359847,
+ 3124943128, 3118535181, 3105745579, 3099363912, 3086626816, 3080271375,
+ 3067586677, 3061257408, 3048625000, 3042321849, 3036027392, 3023464536,
+ 3017196125, 3004685307, 2998442888, 2992209121, 2979767519, 2973559672,
+ 2961169856, 2954987875, 2948814504, 2936493568, 2930345991, 2924207000,
+ 2911954752, 2905841483, 2899736776, 2887553024, 2881473967, 2875403448,
+ 2863288000, 2857243059, 2851206632, 2839159296, 2833148375, 2827145944,
+ 2815166528, 2809189531, 2803221000, 2791309312, 2785366143, 2779431416,
+ 2767587264, 2761677827, 2755776808, 2749884201, 2738124199, 2732256792,
+ 2726397773, 2714704875, 2708870984, 2703045457, 2697228288, 2685619000,
+ 2679826869, 2674043072, 2668267603, 2656741625, 2650991104, 2645248887,
+ 2639514968, 2633789341, 2622362939, 2616662152, 2610969633, 2605285376,
+ 2593941624, 2588282117, 2582630848, 2576987811, 2571353000, 2560108032,
+ 2554497863, 2548895896, 2543302125, 2537716544, 2526569928, 2521008881,
+ 2515456000, 2509911279, 2504374712, 2498846293, 2487813875, 2482309864,
+ 2476813977, 2471326208, 2465846551, 2460375000, 2454911549, 2444008923,
+ 2438569736, 2433138625, 2427715584, 2422300607, 2416893688, 2411494821,
+ 2400721219, 2395346472, 2389979753, 2384621056, 2379270375, 2373927704,
+ 2368593037, 2363266368, 2357947691, 2352637000, 2342039552, 2336752783,
+ 2331473976, 2326203125, 2320940224, 2315685267, 2310438248, 2305199161,
+ 2299968000, 2294744759, 2289529432, 2284322013, 2273930875, 2268747144,
+ 2263571297, 2258403328, 2253243231, 2248091000, 2242946629, 2237810112,
+ 2232681443, 2227560616, 2222447625, 2217342464, 2212245127, 2207155608,
+ 2202073901, 2197000000, 2191933899, 2186875592, 2181825073, 2176782336,
+ 2171747375, 2166720184, 2161700757, 2156689088, 2151685171, 2146689000,
+ 2141700569, 2136719872, 2131746903, 2126781656, 2121824125, 2116874304,
+ 2111932187, 2106997768, 2102071041, 2097152000, 2092240639, 2087336952,
+ 2082440933, 2077552576, 2072671875, 2067798824, 2062933417, 2058075648,
+ 2053225511, 2048383000, 2043548109, 2038720832, 2033901163, 2029089096,
+ 2024284625, 2019487744, 2019487744, 2014698447, 2009916728, 2005142581,
+ 2000376000, 1995616979, 1990865512, 1986121593, 1981385216, 1976656375,
+ 1971935064, 1967221277, 1962515008, 1962515008, 1957816251, 1953125000,
+ 1948441249, 1943764992, 1939096223, 1934434936, 1929781125, 1925134784,
+ 1920495907, 1915864488, 1915864488, 1911240521, 1906624000, 1902014919,
+ 1897413272, 1892819053, 1888232256, 1883652875, 1879080904, 1879080904,
+ 1874516337, 1869959168, 1865409391, 1860867000, 1856331989, 1851804352,
+ 1851804352, 1847284083, 1842771176, 1838265625, 1833767424, 1829276567,
+ 1824793048, 1824793048, 1820316861, 1815848000, 1811386459, 1806932232,
+ 1802485313, 1798045696, 1798045696, 1793613375, 1789188344, 1784770597,
+ 1780360128, 1775956931, 1775956931, 1771561000, 1767172329, 1762790912,
+ 1758416743, 1758416743, 1754049816, 1749690125, 1745337664, 1740992427,
+ 1736654408, 1736654408, 1732323601, 1728000000, 1723683599, 1719374392,
+ 1719374392, 1715072373, 1710777536, 1706489875, 1702209384, 1702209384,
+ 1697936057, 1693669888, 1689410871, 1685159000, 1685159000, 1680914269,
+ 1676676672, 1672446203, 1672446203, 1668222856, 1664006625, 1659797504,
+ 1655595487, 1655595487, 1651400568, 1647212741, 1643032000, 1643032000,
+ 1638858339, 1634691752, 1630532233, 1630532233, 1626379776, 1622234375,
+ 1618096024, 1618096024, 1613964717, 1609840448, 1605723211, 1605723211,
+ 1601613000, 1597509809, 1593413632, 1593413632, 1589324463, 1585242296,
+ 1581167125, 1581167125, 1577098944, 1573037747, 1568983528, 1568983528,
+ 1564936281, 1560896000, 1556862679, 1556862679, 1552836312, 1548816893,
+ 1548816893, 1544804416, 1540798875, 1536800264, 1536800264, 1532808577,
+ 1528823808, 1528823808, 1524845951, 1520875000, 1516910949, 1516910949,
+ 1512953792, 1509003523, 1509003523, 1505060136, 1501123625, 1501123625,
+ 1497193984, 1493271207, 1489355288, 1489355288, 1485446221, 1481544000,
+ 1481544000, 1477648619, 1473760072, 1473760072, 1469878353, 1466003456,
+ 1466003456, 1462135375, 1458274104, 1454419637, 1454419637, 1450571968,
+ 1446731091, 1446731091, 1442897000, 1439069689, 1439069689, 1435249152,
+ 1431435383, 1431435383, 1427628376, 1423828125, 1423828125, 1420034624,
+ 1416247867, 1416247867, 1412467848, 1408694561, 1408694561, 1404928000,
+ 1401168159, 1401168159, 1397415032, 1397415032, 1393668613, 1389928896,
+ 1389928896, 1386195875, 1382469544, 1382469544, 1378749897, 1375036928,
+ 1375036928, 1371330631, 1367631000, 1367631000, 1363938029, 1363938029,
+ 1360251712, 1356572043, 1356572043, 1352899016, 1349232625, 1349232625,
+ 1345572864, 1341919727, 1341919727, 1338273208, 1338273208, 1334633301,
+ 1331000000, 1331000000, 1327373299, 1327373299, 1323753192, 1320139673,
+ 1320139673, 1316532736, 1312932375, 1312932375, 1309338584, 1309338584,
+ 1305751357, 1302170688, 1302170688, 1298596571, 1298596571, 1295029000,
+ 1291467969, 1291467969, 1287913472, 1287913472, 1284365503, 1280824056,
+ 1280824056, 1277289125, 1277289125, 1273760704, 1270238787, 1270238787,
+ 1266723368, 1266723368, 1263214441, 1259712000, 1259712000, 1256216039,
+ 1256216039, 1252726552, 1249243533, 1249243533, 1245766976, 1245766976,
+ 1242296875, 1242296875, 1238833224, 1235376017, 1235376017, 1231925248,
+ 1231925248, 1228480911, 1228480911, 1225043000, 1221611509, 1221611509,
+ 1218186432, 1218186432, 1214767763, 1214767763, 1211355496, 1207949625,
+ 1207949625, 1204550144, 1204550144, 1201157047, 1201157047, 1197770328,
+ 1197770328, 1194389981, 1191016000, 1191016000, 1187648379, 1187648379,
+ 1184287112, 1184287112, 1180932193, 1180932193, 1177583616, 1174241375,
+ 1174241375, 1170905464, 1170905464, 1167575877, 1167575877, 1164252608,
+ 1164252608, 1160935651, 1160935651, 1157625000, 1154320649, 1154320649,
+ 1151022592, 1151022592, 1147730823, 1147730823, 1144445336, 1144445336,
+ 1141166125, 1141166125, 1137893184, 1137893184, 1134626507, 1134626507,
+ 1131366088, 1128111921, 1128111921, 1124864000, 1124864000, 1121622319,
+ 1121622319, 1118386872, 1118386872, 1115157653, 1115157653, 1111934656,
+ 1111934656, 1108717875, 1108717875, 1105507304, 1105507304, 1102302937,
+ 1102302937, 1099104768, 1099104768, 1095912791, 1095912791, 1092727000,
+ 1092727000, 1089547389, 1089547389, 1086373952, 1086373952, 1083206683,
+ 1083206683, 1080045576, 1080045576, 1076890625, 1076890625, 1073741824,
+ 1073741824 };
+
+/* umul_hi(h, x, y) puts in h the high part of x*y */
+#ifdef HAVE_MULX_U64
+#include <immintrin.h>
+#define umul_hi(h, x, y) _mulx_u64 (x, y, (unsigned long long *) &h)
+#else
+#define umul_hi(h, x, y) \
+ do { \
+ mp_limb_t _l; \
+ umul_ppmm (h, _l, x, y); \
+ } while (0)
+#endif
+
+/* given 2^62 <= d < 2^64, put in r an approximation of
+ s = floor(2^96/sqrt(r)) - 2^64, with r <= s <= r + 15 */
+#define __gmpfr_invsqrt_limb_approx(r, d) \
+ do { \
+ mp_limb_t _d, _i, _v0, _e0, _d37, _v1, _e1, _h, _v2, _e2; \
+ _d = (d); \
+ _i = (_d >> 54) - 256; \
+ /* i = d10 - 256 */ \
+ _v0 = T[_i]; \
+ _d37 = 1 + (_d >> 27); \
+ _e0 = T3[_i] * _d37; \
+ /* the value (_v0 << 57) - _e0 is less than 2^61 */ \
+ _v1 = (_v0 << 11) + (((_v0 << 57) - _e0) >> 47); \
+ _e1 = - _v1 * _v1 * _d37; \
+ umul_hi (_h, _v1, _e1); \
+ /* _h = floor(e_1*v_1/2^64) */ \
+ _v2 = (_v1 << 10) + (_h >> 6); \
+ umul_hi (_h, _v2 * _v2, _d); \
+ /* in _h + 2, one +1 accounts for the lower neglected part of */ \
+ /* v2^2*d. the other +1 is to compute ceil((h+1)/2) */ \
+ _e2 = (MPFR_LIMB_ONE << 61) - ((_h + 2) >> 1); \
+ _h = _v2 * _e2; \
+ (r) = (_v2 << 33) + (_h >> 29); \
+ } while (0)
+
+/* given 2^62 <= d < 2^64, return a 32-bit approximation r of
+ sqrt(2^126/d) */
+#define __gmpfr_invsqrt_halflimb_approx(r, d) \
+ do { \
+ mp_limb_t _d, _i, _v0, _e0, _d37, _v1, _e1, _h; \
+ _d = (d); \
+ _i = (_d >> 54) - 256; \
+ /* i = d10 - 256 */ \
+ _v0 = T[_i]; \
+ _d37 = 1 + (_d >> 27); \
+ _e0 = T3[_i] * _d37; \
+ /* the value (_v0 << 57) - _e0 is less than 2^61 */ \
+ _v1 = (_v0 << 11) + (((_v0 << 57) - _e0) >> 47); \
+ _e1 = - _v1 * _v1 * _d37; \
+ umul_hi (_h, _v1, _e1); \
+ /* _h = floor(e_1*v_1/2^64) */ \
+ (r) = (_v1 << 10) + (_h >> 6); \
+ } while (0)
+
+/* given 2^62 <= n < 2^64, put in s an approximation of sqrt(2^64*n),
+ with: s <= floor(sqrt(2^64*u)) <= s + 7 */
+#define __gmpfr_sqrt_limb_approx(s, n) \
+ do { \
+ mp_limb_t _n, _x, _y, _z, _t; \
+ _n = (n); \
+ __gmpfr_invsqrt_halflimb_approx (_x, _n); \
+ MPFR_ASSERTD(_x < MPFR_LIMB_ONE << 32); \
+ /* x has 32 bits, and is near (by below) sqrt(2^126/n) */ \
+ _y = (_x * (_n >> 31)) >> 32; \
+ MPFR_ASSERTD(_y < MPFR_LIMB_ONE << 32); \
+ /* y is near (by below) sqrt(n) */ \
+ _z = _n - _y * _y; \
+ /* reduce _z so that _z <= 2*_y */ \
+ /* the maximal value of _z is 2*(2^32-1) */ \
+ while (_z > 2 * ((MPFR_LIMB_ONE << 32) - 1)) \
+ { \
+ _z -= (_y + _y) + 1; \
+ _y ++; \
+ } \
+ /* now z <= 2*(2^32-1): one reduction is enough */ \
+ if (_z > _y + _y) \
+ { \
+ _z -= (_y + _y) + 1; \
+ _y ++; \
+ } \
+ /* _x * _z should be < 2^64 */ \
+ _t = (_x * _z) >> 32; \
+ (s) = (_y << 32) + _t; \
+ } while (0)
+
+/* given 2^62 <= u < 2^64, put in s the value floor(sqrt(2^64*u)),
+ and in rh in rl the remainder: 2^64*u - s^2 = 2^64*rh + rl, with
+ 2^64*rh + rl <= 2*s, and in invs the approximation of 2^96/sqrt(u) */
+#define __gmpfr_sqrt_limb(s, rh, rl, invs, u) \
+ do { \
+ mp_limb_t _u, _invs, _r, _h, _l; \
+ _u = (u); \
+ __gmpfr_invsqrt_limb_approx (_invs, _u); \
+ umul_hi (_h, _invs, _u); \
+ _r = _h + _u; \
+ /* make sure _r has its most significant bit set */ \
+ if (MPFR_UNLIKELY(_r < MPFR_LIMB_HIGHBIT)) \
+ _r = MPFR_LIMB_HIGHBIT; \
+ /* we know _r <= sqrt(2^64*u) <= _r + 16 */ \
+ umul_ppmm (_h, _l, _r, _r); \
+ sub_ddmmss (_h, _l, _u, 0, _h, _l); \
+ /* now h:l <= 30*_r */ \
+ MPFR_ASSERTD(_h < 30); \
+ if (_h >= 16) \
+ { /* subtract 16r+64 to h:l, add 8 to _r */ \
+ sub_ddmmss (_h, _l, _h, _l, _r >> 60, _r << 4); \
+ sub_ddmmss (_h, _l, _h, _l, 0, 64); \
+ _r += 8; \
+ } \
+ if (_h >= 8) \
+ { /* subtract 8r+16 to h:l, add 4 to _r */ \
+ sub_ddmmss (_h, _l, _h, _l, _r >> 61, _r << 3); \
+ sub_ddmmss (_h, _l, _h, _l, 0, 16); \
+ _r += 4; \
+ } \
+ if (_h >= 4) \
+ { /* subtract 4r+4 to h:l, add 2 to _r */ \
+ sub_ddmmss (_h, _l, _h, _l, _r >> 62, _r << 2); \
+ sub_ddmmss (_h, _l, _h, _l, 0, 4); \
+ _r += 2; \
+ } \
+ while (_h > 1 || ((_h == 1) && (_l > 2 * _r))) \
+ { /* subtract 2r+1 to h:l, add 1 to _r */ \
+ sub_ddmmss (_h, _l, _h, _l, _r >> 63, (_r << 1) + 1); \
+ _r ++; \
+ } \
+ (s) = _r; \
+ (rh) = _h; \
+ (rl) = _l; \
+ (invs) = _invs; \
+ } while (0)
+
+#endif /* GMP_NUMB_BITS == 64 */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/jn.c b/Build/source/libs/mpfr/mpfr-src/src/jn.c
index 1336d22d3f1..8bf0509e157 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/jn.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/jn.c
@@ -158,12 +158,12 @@ mpfr_jn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
but in rounding to nearest, res/2 will yield 0 iff |res| is the
minimum positive number, so that we just need to test the result
of the division and the sign of _inexact. */
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
MPFR_FAST_COMPUTE_IF_SMALL_INPUT
(res, z, -2 * MPFR_GET_EXP (z), 3, 0, r, {
int inex2 = mpfr_div_2ui (res, res, 1, r);
if (MPFR_UNLIKELY (r == MPFR_RNDN && MPFR_IS_ZERO (res)) &&
- (MPFR_ASSERTN (inex2 != 0), SIGN (_inexact) != MPFR_SIGN (z)))
+ (MPFR_ASSERTN (inex2 != 0), VSIGN (_inexact) != MPFR_SIGN (z)))
{
mpfr_nexttoinf (res);
inex = - inex2;
@@ -197,7 +197,7 @@ mpfr_jn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
{
/* the following is an upper 32-bit approximation to exp(1)/2 */
mpfr_set_str_binary (y, "1.0101101111110000101010001011001");
- if (MPFR_SIGN(z) > 0)
+ if (MPFR_IS_POS (z))
mpfr_mul (y, y, z, MPFR_RNDU);
else
{
@@ -246,10 +246,10 @@ mpfr_jn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
MPFR_BLOCK (flags, {
mpfr_pow_ui (t, z, absn, MPFR_RNDN); /* z^|n| */
mpfr_mul (y, z, z, MPFR_RNDN); /* z^2 */
- mpfr_clear_erangeflag ();
+ MPFR_CLEAR_ERANGEFLAG ();
zz = mpfr_get_ui (y, MPFR_RNDU);
/* FIXME: The error analysis is incorrect in case of range error. */
- MPFR_ASSERTN (! mpfr_erangeflag_p ()); /* since mpfr_clear_erangeflag */
+ MPFR_ASSERTN (! mpfr_erangeflag_p ()); /* since MPFR_CLEAR_ERANGEFLAG */
mpfr_div_2ui (y, y, 2, MPFR_RNDN); /* z^2/4 */
mpfr_fac_ui (s, absn, MPFR_RNDN); /* |n|! */
mpfr_div (t, t, s, MPFR_RNDN);
@@ -311,6 +311,11 @@ mpfr_jn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
MPFR_ASSERTN (! exception);
exception = 1;
}
+ /* the expected number of lost bits is k0, if err is larger than k0
+ most probably there is a cancellation in the series, thus we add
+ err - k0 bits to prec */
+ if (err > k0)
+ prec = MPFR_ADD_PREC (prec, err - k0);
MPFR_ZIV_NEXT (loop, prec);
}
MPFR_ZIV_FREE (loop);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/jyn_asympt.c b/Build/source/libs/mpfr/mpfr-src/src/jyn_asympt.c
index 53ac2bbbfb3..6f3f01b70a0 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/jyn_asympt.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/jyn_asympt.c
@@ -36,6 +36,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
(z can be negative only for jn).
Return 0 if the expansion does not converge enough (the value 0 as inexact
flag should not happen for normal input).
+ Note: for MPFR_RNDF, it returns 0 if the expansion failed, and a non-zero
+ value otherwise (with no other meaning).
*/
static int
FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
@@ -265,5 +267,7 @@ FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
: mpfr_neg (res, c, r);
mpfr_clear (c);
- return inex;
+ /* for RNDF, mpfr_set or mpfr_neg may return 0, but if we return 0, it
+ would mean the asymptotic expansion failed, thus we return 1 instead */
+ return (r != MPFR_RNDF) ? inex : 1;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/li2.c b/Build/source/libs/mpfr/mpfr-src/src/li2.c
index d8191f7e16a..cfa2d382309 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/li2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/li2.c
@@ -33,18 +33,17 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
static int
li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
{
- int i, Bm, Bmax;
+ int i;
mpfr_t s, u, v, w;
mpfr_prec_t sump, p;
mpfr_exp_t se, err;
- mpz_t *B;
MPFR_ZIV_DECL (loop);
/* The series converges for |z| < 2 pi, but in mpfr_li2 the argument is
reduced so that 0 < z <= log(2). Here is additionnal check that z is
(nearly) correct */
MPFR_ASSERTD (MPFR_IS_STRICTPOS (z));
- MPFR_ASSERTD (mpfr_cmp_d (z, 0.6953125) <= 0);
+ MPFR_ASSERTD (mpfr_cmp_ui_2exp (z, 89, -7) <= 0); /* z <= 0.6953125 */
sump = MPFR_PREC (sum); /* target precision */
p = sump + MPFR_INT_CEIL_LOG2 (sump) + 4; /* the working precision */
@@ -53,9 +52,6 @@ li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
mpfr_init2 (v, p);
mpfr_init2 (w, p);
- B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
- Bm = Bmax = 1;
-
MPFR_ZIV_INIT (loop, p);
for (;;)
{
@@ -67,9 +63,6 @@ li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
for (i = 1;; i++)
{
- if (i >= Bmax)
- B = mpfr_bernoulli_internal (B, Bmax++); /* B_2i*(2i+1)!, exact */
-
mpfr_mul (v, u, v, MPFR_RNDU);
mpfr_div_ui (v, v, 2 * i, MPFR_RNDU);
mpfr_div_ui (v, v, 2 * i, MPFR_RNDU);
@@ -77,7 +70,7 @@ li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
mpfr_div_ui (v, v, 2 * i + 1, MPFR_RNDU);
/* here, v_2i = v_{2i-2} / (2i * (2i+1))^2 */
- mpfr_mul_z (w, v, B[i], MPFR_RNDN);
+ mpfr_mul_z (w, v, mpfr_bernoulli_cache(i), MPFR_RNDN);
/* here, w_2i = v_2i * B_2i * (2i+1)! with
error(w_2i) < 2^(5 * i + 8) ulp(w_2i) (see algorithms.tex) */
@@ -107,10 +100,6 @@ li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
MPFR_ZIV_FREE (loop);
mpfr_set (sum, s, rnd_mode);
- Bm = Bmax;
- while (Bm--)
- mpz_clear (B[Bm]);
- (*__gmp_free_func) (B, Bmax * sizeof (mpz_t));
mpfr_clears (s, u, v, w, (mpfr_ptr) 0);
/* Let K be the returned value.
@@ -129,7 +118,7 @@ li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
thus |Li2(x) - g(x)| <= 2/x.
Assumes x >= 38, which ensures log(x)^2/2 >= 2*Pi^2/3, and g(x) <= -3.3.
Return 0 if asymptotic expansion failed (unable to round), otherwise
- returns correct ternary value.
+ returns 1 for RNDF, and correct ternary value otherwise.
*/
static int
mpfr_li2_asympt_pos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
@@ -161,7 +150,11 @@ mpfr_li2_asympt_pos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
bounded by 16 ulp(g). */
if ((MPFR_EXP (x) >= (mpfr_exp_t) w - MPFR_EXP (g)) &&
MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
- inex = mpfr_set (y, g, rnd_mode);
+ {
+ inex = mpfr_set (y, g, rnd_mode);
+ if (rnd_mode == MPFR_RNDF)
+ inex = 1;
+ }
mpfr_clear (g);
mpfr_clear (h);
@@ -175,7 +168,7 @@ mpfr_li2_asympt_pos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
|Li2(x) - g(x)| <= 1/|x|.
Assumes x <= -7, which ensures |log(-x)^2/2| >= Pi^2/6, and g(x) <= -3.5.
Return 0 if asymptotic expansion failed (unable to round), otherwise
- returns correct ternary value.
+ returns 1 for RNDF, and correct ternary value otherwise.
*/
static int
mpfr_li2_asympt_neg (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
@@ -204,7 +197,11 @@ mpfr_li2_asympt_neg (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
total error is bounded by 16 ulp(g). */
if ((MPFR_EXP (x) >= (mpfr_exp_t) (w - 2) - MPFR_EXP (g)) &&
MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
- inex = mpfr_neg (y, g, rnd_mode);
+ {
+ inex = mpfr_neg (y, g, rnd_mode);
+ if (rnd_mode == MPFR_RNDF)
+ inex = 1;
+ }
mpfr_clear (g);
mpfr_clear (h);
@@ -264,7 +261,7 @@ mpfr_li2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
yp = MPFR_PREC (y);
m = yp + MPFR_INT_CEIL_LOG2 (yp) + 13;
- if (MPFR_LIKELY ((mpfr_cmp_ui (x, 0) > 0) && (mpfr_cmp_d (x, 0.5) <= 0)))
+ if (MPFR_LIKELY ((mpfr_cmp_ui (x, 0) > 0) && (mpfr_cmp_ui_2exp (x, 1, -1) <= 0)))
/* 0 < x <= 1/2: Li2(x) = S(-log(1-x))-log^2(1-x)/4 */
{
mpfr_t s, u;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/lngamma.c b/Build/source/libs/mpfr/mpfr-src/src/lngamma.c
index 84bd7d1fae7..5511fd1dccd 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/lngamma.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/lngamma.c
@@ -33,6 +33,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
static void
mpfr_gamma_alpha (mpfr_t s, mpfr_prec_t p)
{
+ MPFR_LOG_FUNC
+ (("p=%Pu", p),
+ ("s[%Pu]=%.*Rg", mpfr_get_prec (s), mpfr_log_prec, s));
+
if (p <= 100)
mpfr_set_ui_2exp (s, 614, -10, MPFR_RNDN); /* about 0.6 */
else if (p <= 500)
@@ -72,7 +76,7 @@ mpfr_explgamma (mpfr_ptr y, mpfr_srcptr x, mpfr_save_expo_t *pexpo,
/* s1 = RNDD(lngamma(x)), inexact */
if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags1)))
{
- if (MPFR_SIGN (s1) > 0)
+ if (MPFR_IS_POS (s1))
{
MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, MPFR_FLAGS_OVERFLOW);
return mpfr_overflow (y, rnd, sign);
@@ -141,6 +145,12 @@ unit_bit (mpfr_srcptr x)
#endif
+/* FIXME: There is an internal overflow when z is very large.
+ Simple overflow detection with possible false negatives?
+ For the particular cases near the overflow boundary,
+ scaling by a power of two?
+*/
+
/* lngamma(x) = log(gamma(x)).
We use formula [6.1.40] from Abramowitz&Stegun:
lngamma(z) = (z-1/2)*log(z) - z + 1/2*log(2*Pi)
@@ -161,17 +171,18 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
{
mpfr_prec_t precy, w; /* working precision */
mpfr_t s, t, u, v, z;
- unsigned long m, k, maxm;
- mpz_t *INITIALIZED(B); /* variable B declared as initialized */
- int compared;
- int inexact = 0; /* 0 means: result y not set yet */
+ unsigned long m, k, maxm, l;
+ int compared, inexact;
mpfr_exp_t err_s, err_t;
- unsigned long Bm = 0; /* number of allocated B[] */
- unsigned long oldBm;
double d;
MPFR_SAVE_EXPO_DECL (expo);
MPFR_ZIV_DECL (loop);
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (z0), mpfr_log_prec, z0, rnd),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
compared = mpfr_cmp_ui (z0, 1);
MPFR_SAVE_EXPO_MARK (expo);
@@ -183,9 +194,52 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
return mpfr_set_ui (y, 0, MPFR_RNDN); /* lngamma(1 or 2) = +0 */
}
+ /* Deal with very large inputs: according to [6.1.42], if we denote
+ R_n(z) = lngamma(z) - (z-1/2)*log(z) + z - 1/2*log(2*Pi), we have
+ |R_n(z)| <= B_2/2/z, thus for z >= 2 we have
+ |lngamma(z) - [z*(log(z) - 1)]| < 1/2*log(z) + 1. */
+ if (compared > 0 && MPFR_GET_EXP (z0) >= (mpfr_exp_t) MPFR_PREC(y) + 2)
+ {
+ /* Since PREC(y) >= 2, this ensures EXP(z0) >= 4, thus |z0| >= 8,
+ thus 1/2*log(z0) + 1 < log(z0).
+ Since the largest possible z is < 2^(2^62) on a 64-bit machine,
+ the largest value of log(z) is 2^62*log(2.) < 3.2e18 < 2^62,
+ thus if we use at least 62 bits of precision, then log(t)-1 will
+ be exact */
+ mpfr_init2 (t, MPFR_PREC(y) >= 52 ? MPFR_PREC(y) + 10 : 62);
+ mpfr_log (t, z0, MPFR_RNDU); /* error < 1 ulp */
+ inexact = mpfr_sub_ui (t, t, 1, MPFR_RNDU); /* err < 2 ulps, since the
+ exponent of t might have
+ decreased */
+ MPFR_ASSERTD(inexact == 0);
+ mpfr_mul (t, z0, t, MPFR_RNDU); /* err < 1+2*2=5 ulps according to
+ "Generic error on multiplication"
+ in algorithms.tex */
+ if (MPFR_IS_INF(t))
+ {
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ inexact = mpfr_overflow (y, rnd, 1);
+ return inexact;
+ }
+ if (MPFR_GET_EXP(t) - MPFR_PREC(t) >= 62)
+ {
+ /* then ulp(t) >= 2^62 > log(z0) thus the total error is bounded
+ by 6 ulp(t) */
+ if (MPFR_CAN_ROUND (t, MPFR_PREC(t) - 3, MPFR_PREC(y), rnd))
+ {
+ inexact = mpfr_set (y, t, rnd);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd);
+ }
+ }
+ mpfr_clear (t);
+ }
+
/* Deal here with tiny inputs. We have for -0.3 <= x <= 0.3:
- log|x| - gamma*x <= log|gamma(x)| <= - log|x| - gamma*x + x^2 */
- if (MPFR_EXP(z0) <= - (mpfr_exp_t) MPFR_PREC(y))
+ if (MPFR_GET_EXP (z0) <= - (mpfr_exp_t) MPFR_PREC(y))
{
mpfr_t l, h, g;
int ok, inex1, inex2;
@@ -250,7 +304,7 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
which would need precision n. */
MPFR_ZIV_NEXT (loop, prec);
}
- while (prec <= -MPFR_EXP(z0));
+ while (prec <= - MPFR_GET_EXP (z0));
MPFR_ZIV_FREE (loop);
}
#endif
@@ -263,6 +317,8 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
mpfr_init2 (v, MPFR_PREC_MIN);
mpfr_init2 (z, MPFR_PREC_MIN);
+ inexact = 0; /* 0 means: result y not set yet */
+
if (compared < 0)
{
mpfr_exp_t err_u;
@@ -294,7 +350,10 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
ulp(u)/2 + (2-z0)*max(1,log(2-z0))*2^(1-w)
= (1/2 + (2-z0)*max(1,log(2-z0))*2^(1-E(u))) ulp(u) */
d = (double) MPFR_GET_EXP(s) * 0.694; /* upper bound for log(2-z0) */
- err_u = MPFR_GET_EXP(s) + __gmpfr_ceil_log2 (d) + 1 - MPFR_GET_EXP(u);
+ if (MPFR_IS_ZERO(u)) /* in that case the error on u is zero */
+ err_u = 0;
+ else
+ err_u = MPFR_GET_EXP(s) + __gmpfr_ceil_log2 (d) + 1 - MPFR_GET_EXP(u);
err_u = (err_u >= 0) ? err_u + 1 : 0;
/* now the error on u is bounded by 2^err_u ulps */
@@ -341,19 +400,22 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
}
else
{
- err_s += 1 - MPFR_GET_EXP(v);
+ /* if v = 0 here, it was 1 before the call to mpfr_log,
+ thus the error on v was zero */
+ if (!MPFR_IS_ZERO(v))
+ err_s += 1 - MPFR_GET_EXP(v);
err_s = (err_s >= 0) ? err_s + 1 : 0;
/* the error on v is bounded by 2^err_s ulps */
err_u += MPFR_GET_EXP(u); /* absolute error on u */
- err_s += MPFR_GET_EXP(v); /* absolute error on v */
+ if (!MPFR_IS_ZERO(v)) /* same as above */
+ err_s += MPFR_GET_EXP(v); /* absolute error on v */
mpfr_sub (s, v, u, MPFR_RNDN);
/* the total error on s is bounded by ulp(s)/2 + 2^(err_u-w)
+ 2^(err_s-w) <= ulp(s)/2 + 2^(max(err_u,err_s)+1-w) */
err_s = (err_s >= err_u) ? err_s : err_u;
err_s += 1 - MPFR_GET_EXP(s); /* error is 2^err_s ulp(s) */
err_s = (err_s >= 0) ? err_s + 1 : 0;
- if (mpfr_can_round (s, w - err_s, MPFR_RNDN, MPFR_RNDZ, precy
- + (rnd == MPFR_RNDN)))
+ if (MPFR_CAN_ROUND (s, w - err_s, precy, rnd))
goto end;
}
MPFR_ZIV_NEXT (loop, w);
@@ -379,11 +441,14 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
and we need k steps of argument reconstruction. Assuming k is large
with respect to z0, and k = n, we get 1/(Pi*e)^(2n) ~ 2^(-w), i.e.,
k ~ w*log(2)/2/log(Pi*e) ~ 0.1616 * w.
- However, since the series is more expensive to compute, the optimal
- value seems to be k ~ 4.5 * w experimentally. */
+ However, since the series is slightly more expensive to compute,
+ the optimal value seems to be k ~ 0.25 * w experimentally (with
+ caching of Bernoulli numbers).
+ For only one computation of gamma with large precision, it is better
+ to set k to a larger value, say k ~ w. */
mpfr_set_prec (s, 53);
mpfr_gamma_alpha (s, w);
- mpfr_set_ui_2exp (s, 9, -1, MPFR_RNDU);
+ mpfr_set_ui_2exp (s, 4, -4, MPFR_RNDU);
mpfr_mul_ui (s, s, w, MPFR_RNDU);
if (mpfr_cmp (z0, s) < 0)
{
@@ -431,15 +496,8 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
mpfr_mul (u, u, u, MPFR_RNDN); /* 1/z^2 * (1+u)^3 */
- if (Bm == 0)
- {
- B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
- B = mpfr_bernoulli_internal (B, 1);
- Bm = 2;
- }
-
/* m <= maxm ensures that 2*m*(2*m+1) <= ULONG_MAX */
- maxm = 1UL << (GMP_NUMB_BITS / 2 - 1);
+ maxm = 1UL << (sizeof(unsigned long) * CHAR_BIT / 2 - 1);
/* s:(1+u)^15, t:(1+u)^2, t <= 3/128 */
@@ -463,12 +521,7 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
}
/* (1+u)^(10m-8) */
/* invariant: t=1/(2m)/(2m-1)/z^(2m-1)/(2m+1)! */
- if (Bm <= m)
- {
- B = mpfr_bernoulli_internal (B, m); /* B[2m]*(2m+1)!, exact */
- Bm ++;
- }
- mpfr_mul_z (v, t, B[m], MPFR_RNDN); /* (1+u)^(10m-7) */
+ mpfr_mul_z (v, t, mpfr_bernoulli_cache(m), MPFR_RNDN); /* (1+u)^(10m-7) */
MPFR_ASSERTD(MPFR_GET_EXP(v) <= - (2 * m + 3));
mpfr_add (s, s, v, MPFR_RNDN);
}
@@ -492,22 +545,92 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
/* add 1/2*log(2*Pi) and subtract log(z0*(z0+1)*...*(z0+k-1)) */
mpfr_const_pi (v, MPFR_RNDN); /* v = Pi*(1+u) */
mpfr_mul_2ui (v, v, 1, MPFR_RNDN); /* v = 2*Pi * (1+u) */
- if (k)
+ /* k >= 3 */
+ mpfr_set (t, z0, MPFR_RNDN); /* t = z0*(1+u) */
+ l = 1;
+
+/* replace #if 1 by #if 0 for the naive argument reconstruction */
+#if 1
+
+ /* We multiply by (z0+1)*(z0+2)*...*(z0+k-1) by blocks of j consecutive
+ terms where j ~ sqrt(k).
+ If we multiply naively by z0+1, then by z0+2, ..., then by z0+j,
+ the multiplicative term for the rounding error is (1+u)^(2j).
+ The multiplicative term is not larger when we multiply by
+ Z[j] + c[j-1]*Z[j-1] + ... + c[2]*Z[2] + c[1]*z0 + c[0]
+ with c[p] integers, and Z[p] = z0^p * (1+u)^(p-1).
+ Note that all terms are positive.
+ Indeed, since c[1] is exact, c[1]*z0 corresponds to (1+u),
+ then c[1]*z0 + c[0] corresponds to (1+u)^2,
+ c[2]*Z[2] + c[1]*z0 + c[0] to (1+u)^3, ...,
+ c[j-1]*Z[j-1] + ... + c[0] to (1+u)^j,
+ and Z[j] + c[j-1]*Z[j-1] + ... + c[1]*z0 + c[0] to (1+u)^(j+1).
+ With the accumulation in t, we get (1+u)^(j+2) and j+2 <= 2j. */
+ {
+ unsigned long j, i, p;
+ mpfr_t *Z;
+ mpz_t *c;
+ for (j = 2; (j + 1) * (j + 1) < k; j++);
+ /* Z[i] stores z0^i for i <= j */
+ Z = (mpfr_t *) mpfr_allocate_func ((j + 1) * sizeof (mpfr_t));
+ for (i = 2; i <= j; i++)
+ mpfr_init2 (Z[i], w);
+ mpfr_sqr (Z[2], z0, MPFR_RNDN);
+ for (i = 3; i <= j; i++)
+ if ((i & 1) == 0)
+ mpfr_sqr (Z[i], Z[i >> 1], MPFR_RNDN);
+ else
+ mpfr_mul (Z[i], Z[i-1], z0, MPFR_RNDN);
+ c = (mpz_t *) mpfr_allocate_func ((j + 1) * sizeof (mpz_t));
+ for (i = 0; i <= j; i++)
+ mpz_init (c[i]);
+ for (; l + j <= k; l += j)
+ {
+ /* c[i] is the coefficient of x^i in (x+l)*...*(x+l+j-1) */
+ mpz_set_ui (c[0], 1);
+ for (i = 0; i < j; i++)
+ /* multiply (x+l)*(x+l+1)*...*(x+l+i-1) by x+l+i:
+ (b[i]*x^i + b[i-1]*x^(i-1) + ... + b[0])*(x+l+i) =
+ b[i]*x^(i+1) + (b[i-1]+(l+i)*b[i])*x^i + ...
+ + (b[0]+(l+i)*b[1])*x + i*b[0] */
+ {
+ mpz_set (c[i+1], c[i]); /* b[i]*x^(i+1) */
+ for (p = i; p > 0; p--)
+ {
+ mpz_mul_ui (c[p], c[p], l + i);
+ mpz_add (c[p], c[p], c[p-1]); /* b[p-1]+(l+i)*b[p] */
+ }
+ mpz_mul_ui (c[0], c[0], l+i); /* i*b[0] */
+ }
+ /* now compute z0^j + c[j-1]*z0^(j-1) + ... + c[1]*z0 + c[0] */
+ mpfr_set_z (u, c[0], MPFR_RNDN);
+ for (i = 0; i < j; i++)
+ {
+ mpfr_mul_z (z, (i == 0) ? z0 : Z[i+1], c[i+1], MPFR_RNDN);
+ mpfr_add (u, u, z, MPFR_RNDN);
+ }
+ mpfr_mul (t, t, u, MPFR_RNDN);
+ }
+ for (i = 0; i <= j; i++)
+ mpz_clear (c[i]);
+ mpfr_free_func (c, (j + 1) * sizeof (mpz_t));
+ for (i = 2; i <= j; i++)
+ mpfr_clear (Z[i]);
+ mpfr_free_func (Z, (j + 1) * sizeof (mpfr_t));
+ }
+#endif /* end of fast argument reconstruction */
+
+ for (; l < k; l++)
{
- unsigned long l;
- mpfr_set (t, z0, MPFR_RNDN); /* t = z0*(1+u) */
- for (l = 1; l < k; l++)
- {
- mpfr_add_ui (u, z0, l, MPFR_RNDN); /* u = (z0+l)*(1+u) */
- mpfr_mul (t, t, u, MPFR_RNDN); /* (1+u)^(2l+1) */
- }
- /* now t: (1+u)^(2k-1) */
- /* instead of computing log(sqrt(2*Pi)/t), we compute
- 1/2*log(2*Pi/t^2), which trades a square root for a square */
- mpfr_mul (t, t, t, MPFR_RNDN); /* (z0*...*(z0+k-1))^2, (1+u)^(4k-1) */
- mpfr_div (v, v, t, MPFR_RNDN);
- /* 2*Pi/(z0*...*(z0+k-1))^2 (1+u)^(4k+1) */
+ mpfr_add_ui (u, z0, l, MPFR_RNDN); /* u = (z0+l)*(1+u) */
+ mpfr_mul (t, t, u, MPFR_RNDN); /* (1+u)^(2l+1) */
}
+ /* now t: (1+u)^(2k-1) */
+ /* instead of computing log(sqrt(2*Pi)/t), we compute
+ 1/2*log(2*Pi/t^2), which trades a square root for a square */
+ mpfr_mul (t, t, t, MPFR_RNDN); /* (z0*...*(z0+k-1))^2, (1+u)^(4k-1) */
+ mpfr_div (v, v, t, MPFR_RNDN);
+ /* 2*Pi/(z0*...*(z0+k-1))^2 (1+u)^(4k+1) */
#ifdef IS_GAMMA
err_s = MPFR_GET_EXP(s);
mpfr_exp (s, s, MPFR_RNDN);
@@ -524,7 +647,7 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
|h| <= (2m+48)*ulp(s), thus exp(s0) = exp(s) * exp(-h).
For |h| <= 1/4, we have |exp(h)-1| <= 1.2*|h| thus
|exp(s) - exp(s0)| <= 1.2 * exp(s) * (2m+48)* 2^(EXP(s)-w). */
- d = 1.2 * (2.0 * (double) m + 48.0);
+ /* d = 1.2 * (2.0 * (double) m + 48.0); */
/* the error on s is bounded by d*2^err_s * 2^(-w) */
mpfr_sqrt (t, v, MPFR_RNDN);
/* let v0 be the exact value of v. We have v = v0*(1+u)^(4k+1),
@@ -533,7 +656,13 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
/* the error on input s is bounded by (1+u)^(d*2^err_s),
and that on t is (1+u)^(2k+3/2), thus the
total error is (1+u)^(d*2^err_s+2k+5/2) */
- err_s += __gmpfr_ceil_log2 (d);
+ /* err_s += __gmpfr_ceil_log2 (d); */
+ /* since d = 1.2 * (2m+48), ceil(log2(d)) = 2 + ceil(log2(0.6*m+14.4))
+ <= 2 + ceil(log2(0.6*m+15)) */
+ {
+ unsigned long mm = (1 + m / 5) * 3; /* 0.6*m <= mm */
+ err_s += 2 + __gmpfr_int_ceil_log2 (mm + 15);
+ }
err_t = __gmpfr_ceil_log2 (2.0 * (double) k + 2.5);
err_s = (err_s >= err_t) ? err_s + 1 : err_t + 1;
#else
@@ -570,10 +699,6 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
#ifdef IS_GAMMA
end0:
#endif
- oldBm = Bm;
- while (Bm--)
- mpz_clear (B[Bm]);
- (*__gmp_free_func) (B, oldBm * sizeof (mpz_t));
end:
if (inexact == 0)
@@ -614,7 +739,7 @@ mpfr_lngamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
else /* lngamma(+/-Inf) = lngamma(nonpositive integer) = +Inf */
{
if (!MPFR_IS_INF (x))
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_SET_INF (y);
MPFR_SET_POS (y);
MPFR_RET (0); /* exact */
@@ -654,7 +779,7 @@ mpfr_lgamma (mpfr_ptr y, int *signp, mpfr_srcptr x, mpfr_rnd_t rnd)
else
{
if (MPFR_IS_ZERO (x))
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
*signp = MPFR_INT_SIGN (x);
MPFR_SET_INF (y);
MPFR_SET_POS (y);
@@ -668,7 +793,7 @@ mpfr_lgamma (mpfr_ptr y, int *signp, mpfr_srcptr x, mpfr_rnd_t rnd)
{
MPFR_SET_INF (y);
MPFR_SET_POS (y);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/log.c b/Build/source/libs/mpfr/mpfr-src/src/log.c
index 866ce86b3b8..7b61280b7c8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/log.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/log.c
@@ -44,6 +44,7 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
int inexact;
mpfr_prec_t p, q;
mpfr_t tmp1, tmp2;
+ mpfr_exp_t exp_a;
MPFR_SAVE_EXPO_DECL (expo);
MPFR_ZIV_DECL (loop);
MPFR_GROUP_DECL(group);
@@ -83,18 +84,22 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD (MPFR_IS_ZERO (a));
MPFR_SET_INF (r);
MPFR_SET_NEG (r);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0); /* log(0) is an exact -infinity */
}
}
+
/* If a is negative, the result is NaN */
- else if (MPFR_UNLIKELY (MPFR_IS_NEG (a)))
+ if (MPFR_UNLIKELY (MPFR_IS_NEG (a)))
{
MPFR_SET_NAN (r);
MPFR_RET_NAN;
}
- /* If a is 1, the result is 0 */
- else if (MPFR_UNLIKELY (MPFR_GET_EXP (a) == 1 && mpfr_cmp_ui (a, 1) == 0))
+
+ exp_a = MPFR_GET_EXP (a);
+
+ /* If a is 1, the result is +0 */
+ if (MPFR_UNLIKELY (exp_a == 1 && mpfr_cmp_ui (a, 1) == 0))
{
MPFR_SET_ZERO (r);
MPFR_SET_POS (r);
@@ -103,8 +108,8 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
q = MPFR_PREC (r);
- /* use initial precision about q+lg(q)+5 */
- p = q + 5 + 2 * MPFR_INT_CEIL_LOG2 (q);
+ /* use initial precision about q+2*lg(q)+cte */
+ p = q + 2 * MPFR_INT_CEIL_LOG2 (q) + 10;
/* % ~(mpfr_prec_t)GMP_NUMB_BITS ;
m=q; while (m) { p++; m >>= 1; } */
/* if (MPFR_LIKELY(p % GMP_NUMB_BITS != 0))
@@ -116,13 +121,28 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
MPFR_ZIV_INIT (loop, p);
for (;;)
{
- long m;
+ mpfr_exp_t m;
mpfr_exp_t cancel;
- /* Calculus of m (depends on p) */
- m = (p + 1) / 2 - MPFR_GET_EXP (a) + 1;
+ /* Calculus of m (depends on p)
+ If mpfr_exp_t has N bits, then both (p + 3) / 2 and |exp_a| fit
+ on N-2 bits, so that there cannot be an overflow. */
+ m = (p + 3) / 2 - exp_a;
+
+ /* In standard configuration (_MPFR_EXP_FORMAT <= 3), one has
+ mpfr_exp_t <= long, so that the following assertion is always
+ true. */
+ MPFR_ASSERTN (m >= LONG_MIN && m <= LONG_MAX);
+ /* FIXME: Why 1 ulp and not 1/2 ulp? Ditto with some other ones
+ below. The error concerning the AGM should be explained since
+ 4/s is inexact (one needs a bound on its derivative). */
mpfr_mul_2si (tmp2, a, m, MPFR_RNDN); /* s=a*2^m, err<=1 ulp */
+ MPFR_ASSERTD (MPFR_EXP (tmp2) >= (p + 3) / 2);
+ /* [FIXME] and one can have the equality, even if p is even.
+ This means that if a is a power of 2 and p is even, then
+ s = (1/2) * 2^((p+2)/2) = 2^(p/2), so that the condition
+ s > 2^(p/2) from algorithms.tex is not satisfied. */
mpfr_div (tmp1, __gmpfr_four, tmp2, MPFR_RNDN);/* 4/s, err<=2 ulps */
mpfr_agm (tmp2, __gmpfr_one, tmp1, MPFR_RNDN); /* AG(1,4/s),err<=3 ulps */
mpfr_mul_2ui (tmp2, tmp2, 1, MPFR_RNDN); /* 2*AG(1,4/s), err<=3 ulps */
@@ -143,19 +163,19 @@ mpfr_log (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
/* we have 7 ulps of error from the above roundings,
4 ulps from the 4/s^2 second order term,
plus the canceled bits */
- if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp1, p-cancel-4, q, rnd_mode)))
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp1, p - cancel - 4, q, rnd_mode)))
break;
/* VL: I think it is better to have an increment that it isn't
too low; in particular, the increment must be positive even
if cancel = 0 (can this occur?). */
- p += cancel >= 8 ? cancel : 8;
+ p += cancel + MPFR_INT_CEIL_LOG2 (p);
}
else
{
/* TODO: find why this case can occur and what is best to do
with it. */
- p += 32;
+ p += MPFR_INT_CEIL_LOG2 (p);
}
MPFR_ZIV_NEXT (loop, p);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/log10.c b/Build/source/libs/mpfr/mpfr-src/src/log10.c
index bc2c3ffbeaf..04052b8ea92 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/log10.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/log10.c
@@ -68,7 +68,7 @@ mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD (MPFR_IS_ZERO (a));
MPFR_SET_INF (r);
MPFR_SET_NEG (r);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0); /* log10(0) is an exact -infinity */
}
}
@@ -104,7 +104,7 @@ mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
/* the optimal number of bits : see algorithms.tex */
Nt = Ny + 4 + MPFR_INT_CEIL_LOG2 (Ny);
- /* initialise of intermediary variables */
+ /* initialize of intermediary variables */
mpfr_init2 (t, Nt);
mpfr_init2 (tt, Nt);
@@ -132,7 +132,7 @@ mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
&& mpfr_cmp (a, tt) == 0)
break;
- /* actualisation of the precision */
+ /* actualization of the precision */
MPFR_ZIV_NEXT (loop, Nt);
mpfr_set_prec (t, Nt);
mpfr_set_prec (tt, Nt);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/log1p.c b/Build/source/libs/mpfr/mpfr-src/src/log1p.c
index 4ef43c2ae68..96c2f6831ed 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/log1p.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/log1p.c
@@ -23,8 +23,80 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
- /* The computation of log1p is done by
- log1p(x)=log(1+x) */
+/* Put in y an approximation of log(1+x) for x small.
+ We assume |x| < 1, in which case:
+ |x/2| <= |log(1+x)| = |x - x^2/2 + x^3/3 - x^4/4 + ...| <= |x|.
+ Return k such that the error is bounded by 2^k*ulp(y).
+*/
+static int
+mpfr_log1p_small (mpfr_ptr y, mpfr_srcptr x)
+{
+ mpfr_prec_t p = MPFR_PREC(y), err;
+ mpfr_t t, u;
+ unsigned long i;
+ int k;
+
+ MPFR_ASSERTD(MPFR_GET_EXP (x) <= 0); /* ensures |x| < 1 */
+
+ /* in the following, theta represents a value with |theta| <= 2^(1-p)
+ (might be a different value each time) */
+
+ mpfr_init2 (t, p);
+ mpfr_init2 (u, p);
+ mpfr_set (t, x, MPFR_RNDF); /* t = x * (1 + theta) */
+ mpfr_set (y, t, MPFR_RNDF); /* exact */
+ for (i = 2; ; i++)
+ {
+ mpfr_mul (t, t, x, MPFR_RNDF); /* t = x^i * (1 + theta)^i */
+ mpfr_div_ui (u, t, i, MPFR_RNDF); /* u = x^i/i * (1 + theta)^(i+1) */
+ if (MPFR_GET_EXP (u) <= MPFR_GET_EXP (y) - p) /* |u| < ulp(y) */
+ break;
+ if (i & 1)
+ mpfr_add (y, y, u, MPFR_RNDF); /* error <= ulp(y) */
+ else
+ mpfr_sub (y, y, u, MPFR_RNDF); /* error <= ulp(y) */
+ }
+ /* We assume |(1 + theta)^(i+1)| <= 2.
+ The neglected part is at most |u| + |u|/2 + ... <= 2|u| < 2 ulp(y)
+ which has to be multiplied by |(1 + theta)^(i+1)| <= 2, thus at most
+ 4 ulp(y).
+ The rounding error on y is bounded by:
+ * for the (i-2) add/sub, each error is bounded by ulp(y),
+ and since |y| <= |x|, this yields (i-2)*ulp(x)
+ * from Lemma 3.1 from [Higham02] (see algorithms.tex),
+ the relative error on u at step i is bounded by:
+ (i+1)*epsilon/(1-(i+1)*epsilon) where epsilon = 2^(1-p).
+ If (i+1)*epsilon <= 1/2, then the relative error on u at
+ step i is bounded by 2*(i+1)*epsilon, and since |u| <= 1/2^(i+1)
+ at step i, this gives an absolute error bound of;
+ 2*epsilon*x*(3/2^3 + 4/2^4 + 5/2^5 + ...) <= 2*2^(1-p)*x =
+ 4*2^(-p)*x <= 4*ulp(x).
+
+ If (i+1)*epsilon <= 1/2, then the relative error on u at step i
+ is bounded by (i+1)*epsilon/(1-(i+1)*epsilon) <= 1, thus it follows
+ |(1 + theta)^(i+1)| <= 2.
+
+ Finally the total error is bounded by 4*ulp(y) + (i-2)*ulp(x) + 4*ulp(x)
+ = 4*ulp(y) + (i+2)*ulp(x).
+ Since x/2 <= y, we have ulp(x) <= 2*ulp(y), thus the error is bounded by:
+ (2*i+8)*ulp(y).
+ */
+ err = 2 * i + 8;
+ k = __gmpfr_int_ceil_log2 (err);
+ MPFR_ASSERTN(k < p);
+ /* if k < p, since k = ceil(log2(err)), we have err <= 2^k <= 2^(p-1),
+ thus i+4 = err/2 <= 2^(p-2), thus (i+4)*epsilon <= 1/2, which implies
+ our assumption (i+1)*epsilon <= 1/2. */
+ mpfr_clear (t);
+ mpfr_clear (u);
+ return k;
+}
+
+/* The computation of log1p is done by
+ log1p(x) = log(1+x)
+ except when x is very small, in which case log1p(x) = x + tiny error,
+ or when x is small, where we use directly the Taylor expansion.
+*/
int
mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
@@ -89,7 +161,7 @@ mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
MPFR_SET_INF (y);
MPFR_SET_NEG (y);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0);
}
MPFR_SET_NAN (y);
@@ -117,27 +189,40 @@ mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
if (MPFR_EXP(x) < 0)
Nt += -MPFR_EXP(x);
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
/* First computation of log1p */
MPFR_ZIV_INIT (loop, Nt);
for (;;)
{
- /* compute log1p */
- inexact = mpfr_add_ui (t, x, 1, MPFR_RNDN); /* 1+x */
- /* if inexact = 0, then t = x+1, and the result is simply log(t) */
- if (inexact == 0)
+ int k;
+ /* small case: assuming the AGM algorithm used by mpfr_log uses
+ log2(p) steps for a precision of p bits, we try the special
+ variant whenever EXP(x) <= -p/log2(p). */
+ k = 1 + __gmpfr_int_ceil_log2 (Ny); /* the +1 avoids a division by 0
+ when Ny=1 */
+ if (MPFR_GET_EXP (x) <= - (mpfr_exp_t) (Ny / k))
+ /* this implies EXP(x) <= 0 thus x < 1 */
+ err = Nt - mpfr_log1p_small (t, x);
+ else
{
- inexact = mpfr_log (y, t, rnd_mode);
- goto end;
+ /* compute log1p */
+ inexact = mpfr_add_ui (t, x, 1, MPFR_RNDN); /* 1+x */
+ /* if inexact = 0, then t = x+1, and the result is simply log(t) */
+ if (inexact == 0)
+ {
+ inexact = mpfr_log (y, t, rnd_mode);
+ goto end;
+ }
+ mpfr_log (t, t, MPFR_RNDN); /* log(1+x) */
+
+ /* the error is bounded by (1/2+2^(1-EXP(t))*ulp(t)
+ (cf algorithms.tex)
+ if EXP(t)>=2, then error <= ulp(t)
+ if EXP(t)<=1, then error <= 2^(2-EXP(t))*ulp(t) */
+ err = Nt - MAX (0, 2 - MPFR_GET_EXP (t));
}
- mpfr_log (t, t, MPFR_RNDN); /* log(1+x) */
-
- /* the error is bounded by (1/2+2^(1-EXP(t))*ulp(t) (cf algorithms.tex)
- if EXP(t)>=2, then error <= ulp(t)
- if EXP(t)<=1, then error <= 2^(2-EXP(t))*ulp(t) */
- err = Nt - MAX (0, 2 - MPFR_GET_EXP (t));
if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
break;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/log2.c b/Build/source/libs/mpfr/mpfr-src/src/log2.c
index 4c01a32d3e0..3f81f882304 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/log2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/log2.c
@@ -66,7 +66,7 @@ mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD (MPFR_IS_ZERO (a));
MPFR_SET_INF (r);
MPFR_SET_NEG (r);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0); /* log2(0) is an exact -infinity */
}
}
@@ -106,7 +106,7 @@ mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
/* the optimal number of bits : see algorithms.tex */
Nt = Ny + 3 + MPFR_INT_CEIL_LOG2 (Ny);
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
mpfr_init2 (tt, Nt);
@@ -124,7 +124,7 @@ mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
break;
- /* actualisation of the precision */
+ /* actualization of the precision */
MPFR_ZIV_NEXT (loop, Nt);
mpfr_set_prec (t, Nt);
mpfr_set_prec (tt, Nt);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/log_ui.c b/Build/source/libs/mpfr/mpfr-src/src/log_ui.c
new file mode 100644
index 00000000000..3dc39c73415
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/log_ui.c
@@ -0,0 +1,234 @@
+/* mpfr_log_ui -- compute natural logarithm of an unsigned long
+
+Copyright 2014-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* FIXME: mpfr_log_ui is much slower than mpfr_log on some values of n,
+ e.g. about 4 times as slow for n around ULONG_MAX/3 on an
+ x86_64 Linux machine, for 10^6 bits of precision. The reason is that
+ for say n=6148914691236517205 and prec=10^6, the value of T computed
+ has more than 50M bits, which is much more than needed. Indeed the
+ binary splitting algorithm for series with a finite radius of convergence
+ gives rationals of size n*log(n) for a target precision n. One might
+ truncate the rationals inside the algorithm, but then the error analysis
+ should be redone. */
+
+/* Cf http://www.ginac.de/CLN/binsplit.pdf: the Taylor series of log(1+x)
+ up to order N for x=p/2^k is T/(B*Q).
+ P[0] <- (-p)^(n2-n1) [with opposite sign when n1=1]
+ q <- k*(n2-n1) [corresponding to Q[0] = 2^q]
+ B[0] <- n1 * (n1+1) * ... * (n2-1)
+ T[0] <- B[0]*Q[0] * S(n1,n2)
+ where S(n1,n2) = -sum((-x)^(i-n1+1)/i, i=n1..n2-1)
+ Assumes p is odd or zero, and -1/3 <= x = p/2^k <= 1/3.
+*/
+static void
+S (mpz_t *P, unsigned long *q, mpz_t *B, mpz_t *T, unsigned long n1,
+ unsigned long n2, long p, unsigned long k, int need_P)
+{
+ MPFR_ASSERTD (n1 < n2);
+ MPFR_ASSERTD (p == 0 || ((unsigned long) p & 1) != 0);
+ if (n2 == n1 + 1)
+ {
+ mpz_set_si (P[0], (n1 == 1) ? p : -p);
+ *q = k;
+ mpz_set_ui (B[0], n1);
+ /* T = B*Q*S where S = P/(B*Q) thus T = P */
+ mpz_set (T[0], P[0]);
+ /* since p is odd (or zero), there is no common factor 2 between
+ P and Q, or T and B */
+ }
+ else
+ {
+ unsigned long m = (n1 / 2) + (n2 / 2) + (n1 & 1UL & n2), q1;
+ /* m = floor((n1+n2)/2) */
+
+ MPFR_ASSERTD (n1 < m && m < n2);
+ S (P, q, B, T, n1, m, p, k, 1);
+ S (P + 1, &q1, B + 1, T + 1, m, n2, p, k, need_P);
+
+ /* T0 <- T0*B1*Q1 + P0*B0*T1 */
+ mpz_mul (T[1], T[1], P[0]);
+ mpz_mul (T[1], T[1], B[0]);
+ mpz_mul (T[0], T[0], B[1]);
+ /* Q[1] = 2^q1 */
+ mpz_mul_2exp (T[0], T[0], q1); /* mpz_mul (T[0], T[0], Q[1]) */
+ mpz_add (T[0], T[0], T[1]);
+ if (need_P)
+ mpz_mul (P[0], P[0], P[1]);
+ *q += q1; /* mpz_mul (Q[0], Q[0], Q[1]) */
+ mpz_mul (B[0], B[0], B[1]);
+
+ /* there should be no common factors 2 between P, Q and T,
+ since P is odd (or zero) */
+ }
+}
+
+int
+mpfr_log_ui (mpfr_ptr x, unsigned long n, mpfr_rnd_t rnd_mode)
+{
+ unsigned long k;
+ mpfr_prec_t w; /* working precision */
+ mpz_t three_n, *P, *B, *T;
+ mpfr_t t, q;
+ int inexact;
+ unsigned long N, lgN, i, kk;
+ long p;
+ MPFR_GROUP_DECL(group);
+ MPFR_TMP_DECL(marker);
+ MPFR_ZIV_DECL(loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (n <= 2)
+ {
+ if (n == 0)
+ {
+ MPFR_SET_INF (x);
+ MPFR_SET_NEG (x);
+ MPFR_SET_DIVBY0 ();
+ MPFR_RET (0); /* log(0) is an exact -infinity */
+ }
+ else if (n == 1)
+ {
+ MPFR_SET_ZERO (x);
+ MPFR_SET_POS (x);
+ MPFR_RET (0); /* only "normal" case where the result is exact */
+ }
+ /* now n=2 */
+ return mpfr_const_log2 (x, rnd_mode);
+ }
+
+ /* here n >= 3 */
+
+ /* Argument reduction: compute k such that 2/3 <= n/2^k < 4/3,
+ i.e., 2^(k+1) <= 3n < 2^(k+2).
+
+ FIXME: we could do better by considering n/(2^k*3^i*5^j),
+ which reduces the maximal distance to 1 from 1/3 to 1/8,
+ thus needing about 1.89 less terms in the Taylor expansion of
+ the reduced argument. Then log(2^k*3^i*5^j) can be computed
+ using a combination of log(16/15), log(25/24) and log(81/80),
+ see Section 6.5 of "A Fortran Multiple-Precision Arithmetic Package",
+ Richard P. Brent, ACM Transactions on Mathematical Software, 1978. */
+
+ mpz_init_set_ui (three_n, n);
+ mpz_mul_ui (three_n, three_n, 3);
+ k = mpz_sizeinbase (three_n, 2) - 2;
+ MPFR_ASSERTD (k >= 2);
+ mpz_clear (three_n);
+
+ /* The reduced argument is n/2^k - 1 = (n-2^k)/2^k.
+ Compute p = n-2^k. One has: |p| = |n-2^k| < 2^k/3 < n/2 <= LONG_MAX,
+ so that p and -p both fit in a long. */
+ if (k < sizeof (unsigned long) * CHAR_BIT)
+ n -= 1UL << k;
+ /* n is now the value of p mod ULONG_MAX+1 */
+ p = n > LONG_MAX ? - (long) - n : (long) n;
+
+ MPFR_TMP_MARK(marker);
+ w = MPFR_PREC(x) + MPFR_INT_CEIL_LOG2 (MPFR_PREC(x)) + 10;
+ MPFR_GROUP_INIT_2(group, w, t, q);
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ kk = k;
+ if (p != 0)
+ while ((p % 2) == 0) /* replace p/2^kk by (p/2)/2^(kk-1) */
+ {
+ p /= 2;
+ kk --;
+ }
+
+ MPFR_ZIV_INIT (loop, w);
+ for (;;)
+ {
+ mpfr_t tmp;
+ unsigned int err;
+ unsigned long q0;
+
+ /* we need at most w/log2(2^kk/|p|) terms for an accuracy of w bits */
+ mpfr_init2 (tmp, 32);
+ mpfr_set_ui (tmp, (p > 0) ? p : -p, MPFR_RNDU);
+ mpfr_log2 (tmp, tmp, MPFR_RNDU);
+ mpfr_ui_sub (tmp, kk, tmp, MPFR_RNDD);
+ MPFR_ASSERTN (w <= ULONG_MAX);
+ mpfr_ui_div (tmp, w, tmp, MPFR_RNDU);
+ N = mpfr_get_ui (tmp, MPFR_RNDU);
+ if (N < 2)
+ N = 2;
+ lgN = MPFR_INT_CEIL_LOG2 (N) + 1;
+ mpfr_clear (tmp);
+ P = (mpz_t *) MPFR_TMP_ALLOC (3 * lgN * sizeof (mpz_t));
+ B = P + lgN;
+ T = B + lgN;
+ for (i = 0; i < lgN; i++)
+ {
+ mpz_init (P[i]);
+ mpz_init (B[i]);
+ mpz_init (T[i]);
+ }
+
+ S (P, &q0, B, T, 1, N, p, kk, 0);
+ /* mpz_mul (Q[0], B[0], Q[0]); */
+ /* mpz_mul_2exp (B[0], B[0], q0); */
+
+ mpfr_set_z (t, T[0], MPFR_RNDN); /* t = P[0] * (1 + theta_1) */
+ mpfr_set_z (q, B[0], MPFR_RNDN); /* q = B[0] * (1 + theta_2) */
+ mpfr_mul_2exp (q, q, q0, MPFR_RNDN); /* B[0]*Q[0] */
+ mpfr_div (t, t, q, MPFR_RNDN); /* t = T[0]/(B[0]*Q[0])*(1 + theta_3)^3
+ = log(n/2^k) * (1 + theta_4)^4
+ for |theta_i| < 2^(-w) */
+
+ /* argument reconstruction: add k*log(2) */
+ mpfr_const_log2 (q, MPFR_RNDN);
+ mpfr_mul_ui (q, q, k, MPFR_RNDN);
+ mpfr_add (t, t, q, MPFR_RNDN);
+ for (i = 0; i < lgN; i++)
+ {
+ mpz_clear (P[i]);
+ mpz_clear (B[i]);
+ mpz_clear (T[i]);
+ }
+ /* The maximal error is 5 ulps for P/Q, since |(1+/-u)^4 - 1| < 5*u
+ for u < 2^(-12), k ulps for k*log(2), and 1 ulp for the addition,
+ thus at most k+6 ulps.
+ Note that there might be some cancellation in the addition: the worst
+ case is when log(1 + p/2^kk) = log(2/3) ~ -0.405, and with n=3 which
+ gives k=2, thus we add 2*log(2) = 1.386. Thus in the worst case we
+ have an exponent decrease of 1, which accounts for +1 in the error. */
+ err = MPFR_INT_CEIL_LOG2 (k + 6) + 1;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, w - err, MPFR_PREC(x), rnd_mode)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, w);
+ MPFR_GROUP_REPREC_2(group, w, t, q);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (x, t, rnd_mode);
+
+ MPFR_GROUP_CLEAR(group);
+ MPFR_TMP_FREE(marker);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (x, inexact, rnd_mode);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/logging.c b/Build/source/libs/mpfr/mpfr-src/src/logging.c
index 37a886755c4..c66467138d5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/logging.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/logging.c
@@ -26,14 +26,15 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#ifdef MPFR_USE_LOGGING
-/* Can't include them before (in particular, printf.h) */
-#include <stdlib.h>
-#include <stdarg.h>
+/* The <time.h> header might not be available everywhere (it is standard,
+ but not even required by freestanding C implementations); thus it isn't
+ included unconditionally. */
#include <time.h>
/* Define LOGGING variables */
FILE *mpfr_log_file;
+int mpfr_log_flush;
int mpfr_log_type;
int mpfr_log_level;
int mpfr_log_current;
@@ -78,6 +79,8 @@ mpfr_log_begin (void)
mpfr_log_type = MPFR_LOG_INPUT_F|MPFR_LOG_OUTPUT_F|MPFR_LOG_TIME_F
|MPFR_LOG_INTERNAL_F|MPFR_LOG_MSG_F|MPFR_LOG_BADCASE_F|MPFR_LOG_STAT_F;
+ mpfr_log_flush = getenv ("MPFR_LOG_FLUSH") != NULL;
+
/* Open filename if needed */
var = getenv ("MPFR_LOG_FILE");
if (var == NULL || *var == 0)
@@ -92,6 +95,7 @@ mpfr_log_begin (void)
}
time (&tt);
fprintf (mpfr_log_file, "MPFR LOG FILE %s\n", ctime (&tt));
+ fflush (mpfr_log_file); /* always done */
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mips/mparam.h b/Build/source/libs/mpfr/mpfr-src/src/mips/mparam.h
new file mode 100644
index 00000000000..10c5886f29b
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/mips/mparam.h
@@ -0,0 +1,234 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005-2017 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2012-03-05, gcc 4.4.6
+ on gcc49.fsffrance.org (Loongson 3A) with GMP 5.0.4
+ configured with ac_cv_func_getrusage=no */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,16,16,16,16,16,16,18,18,18, \
+ 18,20,20,20,20,22,22,22,24,32,32,32,32,32,32,32, \
+ 32,32,32,32,32,36,36,36,36,32,36,36,36,36,36,36, \
+ 36,40,40,40,40,40,44,44,44,44,44,44,48,64,64,64, \
+ 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, \
+ 64,64,64,64,64,64,72,72,72,72,64,64,64,64,64,64, \
+ 64,64,64,72,72,72,72,93,93,93,93,93,93,93,93,93, \
+ 93,93,93,93,93,93,93,93,93,93,93,93,93,93,96,93, \
+ 96,93,96,105,105,105,105,105,105,105,105,105,105,105,105,105, \
+ 105,105,108,105,117,117,117,117,117,117,117,117,117,117,117,117, \
+ 117,117,117,117,117,117,117,117,129,129,129,129,129,129,129,129, \
+ 129,129,129,129,129,129,129,129,129,129,141,141,117,117,117,117, \
+ 117,117,129,129,128,129,129,129,189,189,189,189,189,189,189,189, \
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, \
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, \
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, \
+ 189,189,189,189,189,189,189,188,189,189,192,189,189,189,189,189, \
+ 189,189,189,189,189,189,213,213,213,213,213,213,213,213,213,213, \
+ 213,213,213,213,213,213,213,212,213,213,213,213,213,213,213,213, \
+ 213,213,213,213,213,213,237,237,237,213,213,237,276,237,276,275, \
+ 276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,283, \
+ 276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276, \
+ 276,275,276,276,276,276,285,283,283,283,285,283,283,285,285,285, \
+ 285,285,378,377,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,377,378,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,378,378,377,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,378,378,378,378,378,377,378,378,378,378,378,378, \
+ 378,378,376,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 378,378,378,378,504,504,504,503,504,504,504,504,504,503,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 568,504,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,566,566,568,568,568,568,568,568, \
+ 568,632,568,632,632,632,632,632,632,632,632,632,632,632,632,632, \
+ 632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632, \
+ 632,632,632,632,632,632,632,632,632,632,736,736,736,735,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,735, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,735,736,736,736,736,736,736,736, \
+ 736,736,736,736,735,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760, \
+ 760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760, \
+ 760,760,760,760,760,760,832,760,832,832,832,832,832,832,832,832, \
+ 832,832,832,831,832,832,832,832,832,832,832,831,832,832,832,832, \
+ 832,831,832,832,832,832,831,832,832,832,832,832,832,832,832,832, \
+ 832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, \
+ 832,832,831,832,832,832,832,832,832,832,832,832,832,832,832,832, \
+ 832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,0,0,6,6,7,7,8,8,9,9, \
+ 10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17, \
+ 18,18,20,19,20,20,22,21,22,23,24,23,24,25,32,32, \
+ 32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34, \
+ 34,34,36,36,36,36,38,38,38,38,40,40,40,40,42,42, \
+ 42,44,44,44,44,44,46,45,46,46,48,47,48,48,64,64, \
+ 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, \
+ 64,64,64,64,64,64,64,64,64,64,64,68,68,64,68,72, \
+ 68,68,68,68,72,72,72,72,72,72,72,72,72,76,76,98, \
+ 98,98,98,99,98,99,98,99,98,99,98,99,98,99,98,99, \
+ 98,99,98,99,98,99,98,99,102,99,102,99,102,105,102,105, \
+ 102,105,98,99,98,99,98,99,98,99,98,99,98,99,98,99, \
+ 102,102,102,105,104,105,104,105,108,105,108,111,110,111,114,111, \
+ 114,117,116,117,117,117,120,117,120,123,120,123,122,123,126,129, \
+ 126,117,116,117,120,117,120,123,123,123,126,126,126,129,126,129, \
+ 122,129,123,123,126,126,126,126,129,126,129,128,129,129,129,129, \
+ 132,132,135,132,135,132,135,135,135,134,135,138,141,138,141,141, \
+ 141,189,189,189,192,189,192,189,192,189,192,192,192,192,192,192, \
+ 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, \
+ 192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, \
+ 192,192,192,192,192,192,189,192,192,192,192,192,192,192,192,192, \
+ 192,192,192,192,192,192,192,192,192,192,192,192,192,192,201,201, \
+ 201,201,201,201,201,201,201,201,201,201,201,213,213,213,213,213, \
+ 213,213,213,213,213,213,213,216,213,213,213,213,213,213,213,213, \
+ 213,213,213,213,213,216,213,213,213,225,225,225,225,225,225,224, \
+ 225,225,225,237,237,237,237,237,237,237,237,294,294,294,294,294, \
+ 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, \
+ 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, \
+ 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, \
+ 294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, \
+ 294,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,402,400,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 402,402,402,402,402,402,402,402,402,402,402,426,426,426,504,504, \
+ 504,503,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,503,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,503,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 503,504,504,504,504,504,504,504,504,504,504,504,504,504,504,503, \
+ 504,504,503,504,504,504,504,536,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,535, \
+ 536,536,535,536,536,536,536,536,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,567,568,568,568,568,568,568,568,568,568,568,567, \
+ 568,568,567,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,599, \
+ 600,600,568,600,600,568,600,600,600,600,568,600,568,600,504,504, \
+ 504,504,504,504,504,503,503,503,504,503,504,504,504,504,502,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,503,503,504,504,504,504,504,504,504,503,504,504,504,504,504, \
+ 504,504,504,536,536,536,536,536,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,536,535,536,536,536,536,536, \
+ 536,536,536,536,568,568,568,568,552,568,568,568,568,568,568,536 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, /*0-15*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*16-31*/ \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*32-47*/ \
+ 0,0,0,27,0,28,0,29,30,30,31,32,32,33,34,33, /*48-63*/ \
+ 34,35,36,35,36,36,37,37,38,39,39,39,40,40,41,41, /*64-79*/ \
+ 50,51,50,50,52,50,50,52,51,52,50,51,50,50,52,50, /*80-95*/ \
+ 52,50,52,52,52,52,56,55,56,64,64,64,64,64,64,64, /*96-111*/ \
+ 64,64,64,64,64,64,64,64,64,64,64,64,64,64,72,66, /*112-127*/ \
+ 66,71,72,71,72,71,72,69,72,72,72,72,72,72,78,80, /*128-143*/ \
+ 78,79,78,80,80,80,80,80,80,79,80,80,80,80,88,84, /*144-159*/ \
+ 88,88,88,88,88,84,87,85,86,86,88,87,88,88,104,89, /*160-175*/ \
+ 104,100,102,104,104,102,100,100,102,103,100,103,128,103,100,104, /*176-191*/ \
+ 128,103,100,100,104,103,104,103,128,102,104,128,104,128,128,128, /*192-207*/ \
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /*208-223*/ \
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /*224-239*/ \
+ 128,128,127,127,128,128,127,128,128,128,140,128,144,128,144,132, /*240-255*/ \
+ 144,135,143,144,144,143,144,143,144,144,142,143,144,144,140,144, /*256-271*/ \
+ 138,141,144,144,144,143,144,143,144,144,144,144,144,144,160,160, /*272-287*/ \
+ 160,160,148,152,156,157,160,160,160,158,159,160,160,160,160,159, /*288-303*/ \
+ 160,160,160,159,159,160,160,159,159,160,160,161,176,160,162,181, /*304-319*/ \
+ 182,185,186,184,185,186,185,176,185,186,200,192,186,208,184,208, /*320-335*/ \
+ 185,206,200,200,203,200,208,204,204,206,208,208,209,208,208,208, /*336-351*/ \
+ 206,208,206,206,200,204,204,208,208,208,208,208,208,208,208,208, /*352-367*/ \
+ 207,204,206,207,208,208,208,206,208,208,208,208,208,208,208,206, /*368-383*/ \
+ 208,208,208,208,206,208,208,208,256,256,208,256,256,206,256,256, /*384-399*/ \
+ 256,256,256,208,255,256,256,256,256,256,256,256,256,256,256,256, /*400-415*/ \
+ 256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, /*416-431*/ \
+ 256,256,255,256,256,256,256,256,256,256,256,254,256,255,256,256, /*432-447*/ \
+ 256,256,256,256,256,256,255,255,256,256,256,255,254,254,256,253, /*448-463*/ \
+ 256,256,256,256,256,256,256,256,256,255,255,256,256,256,256,256, /*464-479*/ \
+ 256,256,256,255,256,256,255,256,256,256,256,255,254,256,256,255, /*480-495*/ \
+ 256,256,256,256,255,256,255,255,255,256,255,256,256,256,257,264, /*496-511*/ \
+ 272,264,269,281,277,281,280,268,269,281,282,282,279,264,288,288, /*512-527*/ \
+ 287,280,281,280,288,288,288,282,287,288,287,288,287,288,282,287, /*528-543*/ \
+ 281,282,288,288,280,288,288,282,281,288,280,282,287,288,287,288, /*544-559*/ \
+ 282,288,288,288,287,285,288,287,288,288,288,288,288,288,289,292, /*560-575*/ \
+ 296,293,304,304,304,312,304,306,304,305,303,304,312,304,305,316, /*576-591*/ \
+ 315,318,318,312,316,316,318,316,316,320,318,318,320,320,371,370, /*592-607*/ \
+ 371,372,373,372,372,373,376,376,378,377,378,378,384,373,377,372, /*608-623*/ \
+ 378,372,378,378,378,378,377,384,378,384,378,372,378,378,378,378, /*624-639*/ \
+ 372,377,378,378,377,378,378,378,377,371,384,384,378,378,378,378, /*640-655*/ \
+ 378,377,378,378,378,378,378,378,378,384,384,384,383,384,417,384, /*656-671*/ \
+ 378,378,378,378,377,378,378,401,378,400,378,378,400,408,384,412, /*672-687*/ \
+ 384,384,414,408,416,417,411,416,384,414,414,414,416,416,417,414, /*688-703*/ \
+ 416,420,400,412,412,412,416,413,416,414,414,416,416,416,412,412, /*704-719*/ \
+ 416,416,414,416,416,416,417,416,416,416,416,414,415,416,416,416, /*720-735*/ \
+ 414,378,378,377,384,378,378,384,384,384,384,384,384,384,414,384, /*736-751*/ \
+ 415,416,416,413,414,416,416,413,414,414,416,416,415,416,416,400, /*752-767*/ \
+ 412,408,417,411,412,416,415,416,416,412,416,417,416,414,416,416, /*768-783*/ \
+ 416,416,416,416,416,416,416,414,416,416,416,400,415,416,416,401, /*784-799*/ \
+ 416,420,412,408,408,412,416,407,408,416,415,412,416,414,416,415, /*800-815*/ \
+ 414,412,413,416,412,414,413,416,416,416,418,416,416,416,417,417, /*816-831*/ \
+ 419,418,420,419,420,420,426,421,424,426,424,432,426,425,426,426, /*832-847*/ \
+ 426,426,432,432,432,432,432,432,432,432,436,432,432,432,433,435, /*848-863*/ \
+ 440,438,440,438,436,440,440,438,448,444,444,448,440,444,448,446, /*864-879*/ \
+ 444,448,444,443,444,446,446,448,448,449,448,448,448,449,450,468, /*880-895*/ \
+ 466,468,460,457,458,460,463,456,460,456,464,467,462,473,512,458, /*896-911*/ \
+ 488,468,512,473,512,468,512,510,512,512,510,510,512,508,512,512, /*912-927*/ \
+ 512,512,510,512,512,510,512,510,474,511,486,512,512,512,512,512, /*928-943*/ \
+ 509,510,510,512,512,512,512,512,512,512,514,512,512,511,508,512, /*944-959*/ \
+ 512,510,512,511,512,508,512,512,512,511,512,512,510,512,512,510, /*960-975*/ \
+ 512,510,510,512,512,511,512,512,512,512,512,512,512,512,549,512, /*976-991*/ \
+ 512,512,545,512,512,512,510,512,512,512,512,512,512,512,510,512, /*992-1007*/ \
+ 512,512,551,510,545,512,550,512,552,545,511,557,545,512,544,551 /*1008-1023*/ \
+
+#define MPFR_MUL_THRESHOLD 6 /* limbs */
+#define MPFR_SQR_THRESHOLD 9 /* limbs */
+#define MPFR_DIV_THRESHOLD 6 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 530 /* bits */
+#define MPFR_EXP_THRESHOLD 12546 /* bits */
+#define MPFR_SINCOS_THRESHOLD 22043 /* bits */
+#define MPFR_AI_THRESHOLD1 -17975 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 1889
+#define MPFR_AI_THRESHOLD3 28004
+/* Tuneup completed successfully, took 13753 seconds */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mp_clz_tab.c b/Build/source/libs/mpfr/mpfr-src/src/mp_clz_tab.c
index 5581935a773..1953f309573 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mp_clz_tab.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mp_clz_tab.c
@@ -26,13 +26,15 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
+/* Warning: up from version 5.1.0, __clz_tab has 129 elements. */
#if defined(COUNT_LEADING_ZEROS_NEED_CLZ_TAB) && defined(__GMPFR_GMP_H__)
const
-unsigned char __clz_tab[128] =
+unsigned char __clz_tab[129] =
{
1,2,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 9
};
#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mparam_h.in b/Build/source/libs/mpfr/mpfr-src/src/mparam_h.in
index 750330afb83..d693cdad128 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mparam_h.in
+++ b/Build/source/libs/mpfr/mpfr-src/src/mparam_h.in
@@ -23,11 +23,16 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
# error "MPFR Internal not included"
#endif
+/* Threshold when testing coverage */
+#if defined(MPFR_TUNE_COVERAGE)
+#define MPFR_TUNE_CASE "src/generic/coverage/mparam.h"
+#include "generic/coverage/mparam.h"
+
/* Note: the different macros used here are those defined by gcc,
for example with gcc -dM -E -xc /dev/null
As of gcc 4.2, you can also use: -march=native or -mtune=native */
-#if 1 /* no processor specific optimization for TeX Live */
+#elif 1 /* no processor specific optimization for TeX Live */
#define MPFR_TUNE_CASE "default"
#elif defined (__tune_pentium4__) /* Threshold for Pentium 4 */
#define MPFR_TUNE_CASE "src/x86_64/pentium4/mparam.h"
@@ -42,7 +47,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_TUNE_CASE "src/x86/core2/mparam.h"
#include "x86/core2/mparam.h"
-#elif defined (__tune_k8__) /* Threshold for AMD 64 */
+#elif defined (__tune_k8__) && defined (__amd64__) /* AMD K8 */
#define MPFR_TUNE_CASE "src/amd/k8/mparam.h"
#include "amd/k8/mparam.h"
@@ -81,6 +86,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_TUNE_CASE "src/hppa/mparam.h"
#include "hppa/mparam.h"
+#elif defined (__mips__) /* MIPS */
+#define MPFR_TUNE_CASE "src/mips/mparam.h"
+#include "mips/mparam.h"
+
#else
#define MPFR_TUNE_CASE "default"
#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpf2mpfr.h b/Build/source/libs/mpfr/mpfr-src/src/mpf2mpfr.h
index 17b70fc95da..2c2c881c8b3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpf2mpfr.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpf2mpfr.h
@@ -33,12 +33,18 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
# define MPFR_DEFAULT_RND mpfr_get_default_rounding_mode ()
#endif
-/* mpf_init initalizes at 0 */
+/* mpf_init initializes at 0 */
#undef mpf_init
#define mpf_init(x) mpfr_init_set_ui ((x), 0, MPFR_DEFAULT_RND)
#undef mpf_init2
#define mpf_init2(x,p) (mpfr_init2((x),(p)), mpfr_set_ui ((x), 0, MPFR_DEFAULT_RND))
+/* Warning! This assumes that all pointer types have the same representation. */
+#undef mpf_inits
+#define mpf_inits mpfr_inits
+#undef mpf_clears
+#define mpf_clears mpfr_clears
+
/* functions which don't take as argument the rounding mode */
#undef mpf_ceil
#define mpf_ceil mpfr_ceil
@@ -52,6 +58,11 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define mpf_cmp_ui mpfr_cmp_ui
#undef mpf_cmp_d
#define mpf_cmp_d mpfr_cmp_d
+/* mpf_cmp_z appeared in GMP 6.1.0 */
+#if __GNU_MP_VERSION > 6 || (__GNU_MP_VERSION == 6 && __GNU_MP_VERSION_MINOR >= 1)
+#undef mpf_cmp_z
+#define mpf_cmp_z mpfr_cmp_z
+#endif
#undef mpf_eq
#define mpf_eq mpfr_eq
#undef mpf_floor
@@ -171,5 +182,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#undef mpz_set_f
#define mpz_set_f(z,f) mpfr_get_z(z,f,MPFR_DEFAULT_RND)
+#undef mpq_set_f
+#define mpq_set_f(q,f) mpfr_get_q(q,f)
#endif /* __MPFR_FROM_MPF__ */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-cvers.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-cvers.h
new file mode 100644
index 00000000000..177bac31b33
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-cvers.h
@@ -0,0 +1,62 @@
+/* Utilities for MPFR developers, not exported.
+
+Copyright 1999-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_CVERS_H__
+#define __MPFR_CVERS_H__
+
+/* Macros to detect STDC, ICC, GCC, and GLIBC versions */
+#if defined(__STDC_VERSION__)
+# define __MPFR_STDC(version) (__STDC_VERSION__ >= (version))
+#else
+# define __MPFR_STDC(version) 0
+#endif
+
+#if defined(_WIN32)
+/* Under MS Windows (e.g. with VS2008 or VS2010), Intel's compiler doesn't
+ support/enable extensions like the ones seen under GNU/Linux.
+ https://sympa.inria.fr/sympa/arc/mpfr/2011-02/msg00032.html */
+# define __MPFR_ICC(a,b,c) 0
+#elif defined(__ICC)
+# define __MPFR_ICC(a,b,c) (__ICC >= (a)*100+(b)*10+(c))
+#elif defined(__INTEL_COMPILER)
+# define __MPFR_ICC(a,b,c) (__INTEL_COMPILER >= (a)*100+(b)*10+(c))
+#else
+# define __MPFR_ICC(a,b,c) 0
+#endif
+
+#define __MPFR_MAJMIN(a,i) (((a) << 8) | (i))
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && ! __MPFR_ICC(0,0,0)
+# define __MPFR_GNUC(a,i) \
+ (__MPFR_MAJMIN(__GNUC__,__GNUC_MINOR__) >= __MPFR_MAJMIN(a,i))
+#else
+# define __MPFR_GNUC(a,i) 0
+#endif
+
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+# define __MPFR_GLIBC(a,i) \
+ (__MPFR_MAJMIN(__GLIBC__,__GLIBC_MINOR__) >= __MPFR_MAJMIN(a,i))
+#else
+# define __MPFR_GLIBC(a,i) 0
+#endif
+
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.c b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.c
index ce4698292a9..0791d036a5a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.c
@@ -21,15 +21,10 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <stdlib.h> /* For malloc, free, realloc and abort */
-
#include "mpfr-impl.h"
#ifndef MPFR_HAVE_GMP_IMPL
-char mpfr_rands_initialized = 0;
-gmp_randstate_t mpfr_rands;
-
const struct bases mpfr_bases[257] =
{
/* 0 */ {0.0},
@@ -291,9 +286,9 @@ const struct bases mpfr_bases[257] =
/* 256 */ {0.1250000000000000},
};
-void
+MPFR_COLD_FUNCTION_ATTR void
mpfr_assert_fail (const char *filename, int linenum,
- const char *expr)
+ const char *expr)
{
if (filename != NULL && filename[0] != '\0')
{
@@ -305,54 +300,41 @@ mpfr_assert_fail (const char *filename, int linenum,
abort();
}
-#ifdef mp_get_memory_functions
-
-/* putting 0 as initial values forces those symbols to be fully defined,
- and always resolved, otherwise they are only tentatively defined, which
- leads to problems on e.g. MacOS, cf
- http://lists.gforge.inria.fr/pipermail/mpc-discuss/2008-November/000048.html
- and http://software.intel.com/en-us/articles/intelr-fortran-compiler-for-mac-os-non_lazy_ptr-unresolved-references-from-linking
- Note that using ranlib -c or libtool -c is another fix.
-*/
-MPFR_THREAD_ATTR void * (*mpfr_allocate_func) (size_t) = 0;
-MPFR_THREAD_ATTR void * (*mpfr_reallocate_func) (void *, size_t, size_t) = 0;
-MPFR_THREAD_ATTR void (*mpfr_free_func) (void *, size_t) = 0;
-
-#endif
-
-void *
-mpfr_default_allocate (size_t size)
+/* Performing a concentration for theses indirect functions may be
+ good for performance since branch prediction for indirect calls
+ is not well supported by a lot of CPU's (typically they can only
+ predict a limited number of indirections). */
+MPFR_HOT_FUNCTION_ATTR void *
+mpfr_allocate_func (size_t alloc_size)
{
- void *ret;
- ret = malloc (size);
- if (ret == NULL)
- {
- fprintf (stderr, "MPFR: Can't allocate memory (size=%lu)\n",
- (unsigned long) size);
- abort ();
- }
- return ret;
+ void * (*allocate_func) (size_t);
+ void * (*reallocate_func) (void *, size_t, size_t);
+ void (*free_func) (void *, size_t);
+ /* Always calling with the 3 arguments smooths branch prediction. */
+ mp_get_memory_functions (&allocate_func, &reallocate_func, &free_func);
+ return (*allocate_func) (alloc_size);
}
-void *
-mpfr_default_reallocate (void *oldptr, size_t old_size, size_t new_size)
+MPFR_HOT_FUNCTION_ATTR void *
+mpfr_reallocate_func (void * ptr, size_t old_size, size_t new_size)
{
- void *ret;
- ret = realloc (oldptr, new_size);
- if (ret == NULL)
- {
- fprintf (stderr,
- "MPFR: Can't reallocate memory (old_size=%lu new_size=%lu)\n",
- (unsigned long) old_size, (unsigned long) new_size);
- abort ();
- }
- return ret;
+ void * (*allocate_func) (size_t);
+ void * (*reallocate_func) (void *, size_t, size_t);
+ void (*free_func) (void *, size_t);
+ /* Always calling with the 3 arguments smooths branch prediction. */
+ mp_get_memory_functions (&allocate_func, &reallocate_func, &free_func);
+ return (*reallocate_func) (ptr, old_size, new_size);
}
-void
-mpfr_default_free (void *blk_ptr, size_t blk_size)
+MPFR_HOT_FUNCTION_ATTR void
+mpfr_free_func (void *ptr, size_t size)
{
- free (blk_ptr);
+ void * (*allocate_func) (size_t);
+ void * (*reallocate_func) (void *, size_t, size_t);
+ void (*free_func) (void *, size_t);
+ /* Always calling with the 3 arguments smooths branch prediction. */
+ mp_get_memory_functions (&allocate_func, &reallocate_func, &free_func);
+ (*free_func) (ptr, size);
}
void *
@@ -361,8 +343,8 @@ mpfr_tmp_allocate (struct tmp_marker **tmp_marker, size_t size)
struct tmp_marker *head;
head = (struct tmp_marker *)
- mpfr_default_allocate (sizeof (struct tmp_marker));
- head->ptr = mpfr_default_allocate (size);
+ mpfr_allocate_func (sizeof (struct tmp_marker));
+ head->ptr = mpfr_allocate_func (size);
head->size = size;
head->next = *tmp_marker;
*tmp_marker = head;
@@ -377,9 +359,9 @@ mpfr_tmp_free (struct tmp_marker *tmp_marker)
while (tmp_marker != NULL)
{
t = tmp_marker;
- mpfr_default_free (t->ptr, t->size);
+ mpfr_free_func (t->ptr, t->size);
tmp_marker = t->next;
- mpfr_default_free (t, sizeof (struct tmp_marker));
+ mpfr_free_func (t, sizeof (struct tmp_marker));
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h
index 850e0d396db..a4c13aa4125 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-gmp.h
@@ -1,4 +1,4 @@
-/* Interface to replace gmp-impl.h
+/* Uniform Interface to GMP.
Copyright 2004-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -27,8 +27,75 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
# error "mpfr-impl.h not included"
#endif
-#include <limits.h> /* For INT_MAX, ... */
-#include <string.h> /* For memcpy, memset and memmove */
+
+/******************************************************
+ ******************** C++ Compatibility ***************
+ ******************************************************/
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/******************************************************
+ ******************** Identify GMP ********************
+ ******************************************************/
+
+/* Macro to detect the GMP version */
+#if defined(__GNU_MP_VERSION) && \
+ defined(__GNU_MP_VERSION_MINOR) && \
+ defined(__GNU_MP_VERSION_PATCHLEVEL)
+# define __MPFR_GMP(a,b,c) \
+ (MPFR_VERSION_NUM(__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR,__GNU_MP_VERSION_PATCHLEVEL) >= MPFR_VERSION_NUM(a,b,c))
+#else
+# define __MPFR_GMP(a,b,c) 0
+#endif
+
+
+
+/******************************************************
+ ******************** Check GMP ***********************
+ ******************************************************/
+
+#if !__MPFR_GMP(5,0,0) && !defined(MPFR_USE_MINI_GMP)
+# error "GMP 5.0.0 or newer is required"
+#endif
+
+#if GMP_NAIL_BITS != 0
+# error "MPFR doesn't support nonzero values of GMP_NAIL_BITS"
+#endif
+
+#if (GMP_NUMB_BITS<32) || (GMP_NUMB_BITS & (GMP_NUMB_BITS - 1))
+# error "GMP_NUMB_BITS must be a power of 2, and >= 32"
+#endif
+
+#if GMP_NUMB_BITS == 32
+# define MPFR_LOG2_GMP_NUMB_BITS 5
+#elif GMP_NUMB_BITS == 64
+# define MPFR_LOG2_GMP_NUMB_BITS 6
+#elif GMP_NUMB_BITS == 128
+# define MPFR_LOG2_GMP_NUMB_BITS 7
+#elif GMP_NUMB_BITS == 256
+# define MPFR_LOG2_GMP_NUMB_BITS 8
+#else
+# error "Can't compute log2(GMP_NUMB_BITS)"
+#endif
+
+/* Remap names of internal mpn functions (for longlong.h).
+ Note: this should be made both with and without gmp build. */
+#undef __clz_tab
+#define __clz_tab mpfr_clz_tab
+
+/******************************************************
+ ************* Define GMP Internal Interface *********
+ ******************************************************/
+
+#ifdef MPFR_HAVE_GMP_IMPL /* with gmp build */
+
+#define mpfr_allocate_func (*__gmp_allocate_func)
+#define mpfr_reallocate_func (*__gmp_reallocate_func)
+#define mpfr_free_func (*__gmp_free_func)
+
+#else /* without gmp build (gmp-impl.h replacement) */
/* The following tries to get a good version of alloca.
See gmp-impl.h for implementation details and original version */
@@ -51,36 +118,12 @@ void *alloca (size_t);
# endif
#endif
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-/* Define GMP_NUMB_BITS
- Can't use sizeof(mp_limb_t) since it should be a preprocessor constant */
-#if defined(GMP_NUMB_BITS) /* GMP 4.1.2 or above */
-#ifndef GMP_NUMB_BITS
-# define GMP_NUMB_BITS (GMP_NUMB_BITS+GMP_NAIL_BITS)
-#endif
-#elif defined (__GMP_GMP_NUMB_BITS) /* Older versions 4.x.x */
-# define GMP_NUMB_BITS __GMP_GMP_NUMB_BITS
-# define GMP_NUMB_BITS GMP_NUMB_BITS
-# ifndef GMP_NAIL_BITS
-# define GMP_NAIL_BITS 0
-# endif
-#else
-# error "Could not detect GMP_NUMB_BITS. Try with gmp internal files."
-#endif
-
/* Define some macros */
-#define MP_LIMB_T_MAX (~(mp_limb_t)0)
-
#define ULONG_HIGHBIT (ULONG_MAX ^ ((unsigned long) ULONG_MAX >> 1))
#define UINT_HIGHBIT (UINT_MAX ^ ((unsigned) UINT_MAX >> 1))
#define USHRT_HIGHBIT ((unsigned short) (USHRT_MAX ^ ((unsigned short) USHRT_MAX >> 1)))
-#define GMP_LIMB_HIGHBIT (MP_LIMB_T_MAX ^ (MP_LIMB_T_MAX >> 1))
-
#if __GMP_MP_SIZE_T_INT
#define MP_SIZE_T_MAX INT_MAX
@@ -90,14 +133,8 @@ extern "C" {
#define MP_SIZE_T_MIN LONG_MIN
#endif
-#define LONG_HIGHBIT LONG_MIN
-#define INT_HIGHBIT INT_MIN
-#define SHRT_HIGHBIT SHRT_MIN
-
/* MP_LIMB macros */
#define MPN_ZERO(dst, n) memset((dst), 0, (n)*MPFR_BYTES_PER_MP_LIMB)
-#define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*MPFR_BYTES_PER_MP_LIMB)
-#define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*MPFR_BYTES_PER_MP_LIMB)
#define MPN_COPY(dst,src,n) \
do \
{ \
@@ -152,24 +189,27 @@ extern "C" {
#endif
/* ASSERT */
-__MPFR_DECLSPEC void mpfr_assert_fail _MPFR_PROTO((const char *, int,
- const char *));
+__MPFR_DECLSPEC void mpfr_assert_fail (const char *, int,
+ const char *);
#define ASSERT_FAIL(expr) mpfr_assert_fail (__FILE__, __LINE__, #expr)
+/* ASSERT() is for mpfr-longlong.h only. */
#define ASSERT(expr) MPFR_ASSERTD(expr)
/* Access fields of GMP struct */
#define SIZ(x) ((x)->_mp_size)
#define ABSIZ(x) ABS (SIZ (x))
#define PTR(x) ((x)->_mp_d)
+#define ALLOC(x) ((x)->_mp_alloc)
+/* For mpf numbers only. */
+#ifdef MPFR_NEED_MPF_INTERNALS
+/* Note: the EXP macro name is reserved when <errno.h> is included.
+ For compatibility with gmp-impl.h (cf --with-gmp-build), we cannot
+ change this macro, but let's define it only when we need it, where
+ <errno.h> will not be included. */
#define EXP(x) ((x)->_mp_exp)
#define PREC(x) ((x)->_mp_prec)
-#define ALLOC(x) ((x)->_mp_alloc)
-#define MPZ_REALLOC(z,n) ((n) > ALLOC(z) ? _mpz_realloc(z,n) : PTR(z))
-
-/* Non IEEE float supports -- needs to detect them with proper configure */
-#undef XDEBUG
-#define XDEBUG
+#endif
/* For longlong.h */
#ifdef HAVE_ATTRIBUTE_MODE
@@ -194,14 +234,10 @@ typedef mp_limb_t UWtype;
typedef unsigned int UHWtype;
#define W_TYPE_SIZE GMP_NUMB_BITS
-/* Remap names of internal mpn functions (for longlong.h). */
-#undef __clz_tab
-#define __clz_tab mpfr_clz_tab
-
/* Use (4.0 * ...) instead of (2.0 * ...) to work around buggy compilers
that don't convert ulong->double correctly (eg. SunOS 4 native cc). */
#undef MP_BASE_AS_DOUBLE
-#define MP_BASE_AS_DOUBLE (4.0 * ((mp_limb_t) 1 << (GMP_NUMB_BITS - 2)))
+#define MP_BASE_AS_DOUBLE (4.0 * (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 2)))
/* Structure for conversion between internal binary format and
strings in base 2..36. */
@@ -218,89 +254,50 @@ __MPFR_DECLSPEC extern const struct bases mpfr_bases[257];
#undef ABS
#undef MIN
#undef MAX
-#undef numberof
#define ABS(x) ((x) >= 0 ? (x) : -(x))
#define MIN(l,o) ((l) < (o) ? (l) : (o))
#define MAX(h,i) ((h) > (i) ? (h) : (i))
-#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
-
-/* Random */
-#undef __gmp_rands_initialized
-#undef __gmp_rands
-#define __gmp_rands_initialized mpfr_rands_initialized
-#define __gmp_rands mpfr_rands
-
-__MPFR_DECLSPEC extern char mpfr_rands_initialized;
-__MPFR_DECLSPEC extern gmp_randstate_t mpfr_rands;
-
-#undef RANDS
-#define RANDS \
- ((__gmp_rands_initialized ? 0 \
- : (__gmp_rands_initialized = 1, \
- gmp_randinit_default (__gmp_rands), 0)), \
- __gmp_rands)
-
-#undef RANDS_CLEAR
-#define RANDS_CLEAR() \
- do { \
- if (__gmp_rands_initialized) \
- { \
- __gmp_rands_initialized = 0; \
- gmp_randclear (__gmp_rands); \
- } \
- } while (0)
-
-/* Allocate func are defined in gmp-impl.h */
-
-/* In newer GMP, there aren't anymore __gmp_allocate_func,
- __gmp_reallocate_func & __gmp_free_func in gmp.h
- Just getting the correct value by calling mp_get_memory_functions */
-#ifdef mp_get_memory_functions
-
-#undef __gmp_allocate_func
-#undef __gmp_reallocate_func
-#undef __gmp_free_func
-#define MPFR_GET_MEMFUNC \
- ((void) (MPFR_LIKELY (mpfr_allocate_func != 0) || \
- (mp_get_memory_functions(&mpfr_allocate_func, \
- &mpfr_reallocate_func, \
- &mpfr_free_func), 1)))
-#define __gmp_allocate_func (MPFR_GET_MEMFUNC, mpfr_allocate_func)
-#define __gmp_reallocate_func (MPFR_GET_MEMFUNC, mpfr_reallocate_func)
-#define __gmp_free_func (MPFR_GET_MEMFUNC, mpfr_free_func)
-__MPFR_DECLSPEC extern MPFR_THREAD_ATTR void * (*mpfr_allocate_func) _MPFR_PROTO ((size_t));
-__MPFR_DECLSPEC extern MPFR_THREAD_ATTR void * (*mpfr_reallocate_func) _MPFR_PROTO ((void *, size_t, size_t));
-__MPFR_DECLSPEC extern MPFR_THREAD_ATTR void (*mpfr_free_func) _MPFR_PROTO ((void *, size_t));
+/* Size of an array, safe version but not a constant expression:
+ Since an array can silently be converted to a pointer, we check
+ that this macro is applied on an array, not a pointer. */
+#undef numberof
+#if 0
+/* The following should work with GCC as documented in its manual,
+ but fails: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38377#c10
+ Thus disabled for now. */
+# define numberof(x) \
+ ( __extension__ ({ \
+ int is_array = (void *) &(x) == (void *) &(x)[0]; \
+ MPFR_STAT_STATIC_ASSERT (__builtin_constant_p (is_array) ? \
+ is_array : 1); \
+ MPFR_ASSERTN (is_array); \
+ numberof_const (x); \
+ }) )
+#else
+# define numberof(x) \
+ (MPFR_ASSERTN ((void *) &(x) == (void *) &(x)[0]), \
+ numberof_const (x))
#endif
-#undef __gmp_default_allocate
-#undef __gmp_default_reallocate
-#undef __gmp_default_free
-#define __gmp_default_allocate mpfr_default_allocate
-#define __gmp_default_reallocate mpfr_default_reallocate
-#define __gmp_default_free mpfr_default_free
-__MPFR_DECLSPEC void *__gmp_default_allocate _MPFR_PROTO ((size_t));
-__MPFR_DECLSPEC void *__gmp_default_reallocate _MPFR_PROTO ((void *, size_t,
- size_t));
-__MPFR_DECLSPEC void __gmp_default_free _MPFR_PROTO ((void *, size_t));
-
-#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_ROOTREM)
-#ifndef __gmpn_rootrem
- __MPFR_DECLSPEC mp_size_t __gmpn_rootrem _MPFR_PROTO ((mp_limb_t*,
- mp_limb_t*, mp_limb_t*, mp_size_t, mp_limb_t));
-#endif
-#endif
+__MPFR_DECLSPEC void * mpfr_allocate_func (size_t);
+__MPFR_DECLSPEC void * mpfr_reallocate_func (void *, size_t, size_t);
+__MPFR_DECLSPEC void mpfr_free_func (void *, size_t);
#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q)
#ifndef __gmpn_sbpi1_divappr_q
- __MPFR_DECLSPEC mp_limb_t __gmpn_sbpi1_divappr_q _MPFR_PROTO ((mp_limb_t*,
- mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t, mp_limb_t));
+__MPFR_DECLSPEC mp_limb_t __gmpn_sbpi1_divappr_q (mp_limb_t*,
+ mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t, mp_limb_t);
#endif
#endif
-/* Temp memory allocate */
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB)
+#ifndef __gmpn_invert_limb
+__MPFR_DECLSPEC mp_limb_t __gmpn_invert_limb (mp_limb_t);
+#endif
+#endif
+/* Temp memory allocate */
struct tmp_marker
{
void *ptr;
@@ -308,62 +305,59 @@ struct tmp_marker
struct tmp_marker *next;
};
-__MPFR_DECLSPEC void *mpfr_tmp_allocate _MPFR_PROTO ((struct tmp_marker **,
- size_t));
-__MPFR_DECLSPEC void mpfr_tmp_free _MPFR_PROTO ((struct tmp_marker *));
+__MPFR_DECLSPEC void *mpfr_tmp_allocate (struct tmp_marker **,
+ size_t);
+__MPFR_DECLSPEC void mpfr_tmp_free (struct tmp_marker *);
+
+/* Can be overriden at configure time. Useful for checking buffer overflow. */
+#ifndef MPFR_ALLOCA_MAX
+# define MPFR_ALLOCA_MAX 16384
+#endif
/* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */
-#define TMP_ALLOC(n) (MPFR_LIKELY ((n) < 16384) ? \
+#define TMP_ALLOC(n) (MPFR_LIKELY ((n) <= MPFR_ALLOCA_MAX) ? \
alloca (n) : mpfr_tmp_allocate (&tmp_marker, (n)))
#define TMP_DECL(m) struct tmp_marker *tmp_marker
#define TMP_MARK(m) (tmp_marker = 0)
-#define TMP_FREE(m) mpfr_tmp_free (tmp_marker)
+/* Note about TMP_FREE: For small precisions, tmp_marker is null as
+ the allocation is done on the stack (see TMP_ALLOC above). */
+#define TMP_FREE(m) \
+ (MPFR_LIKELY (tmp_marker == NULL) ? (void) 0 : mpfr_tmp_free (tmp_marker))
+
+#endif /* gmp-impl.h replacement */
+
+
+
+/******************************************************
+ ****** GMP Interface which changes with versions *****
+ ****** to other versions of GMP. Add missing *****
+ ****** interfaces. *****
+ ******************************************************/
+
+/* If mpn_sqr is not defined, use mpn_mul_n instead
+ (mpn_sqr was called mpn_sqr_n (internal) in older versions of GMP). */
+#ifndef mpn_sqr
+# define mpn_sqr(dst,src,n) mpn_mul_n((dst),(src),(src),(n))
+#endif
/* invert_limb macro, copied from GMP 5.0.2, file gmp-impl.h.
It returns invxl = floor((B^2-1)/xl)-B, where B=2^BITS_PER_LIMB,
assuming the most significant bit of xl is set. */
-#undef invert_limb
+#ifndef invert_limb
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB)
#define invert_limb(invxl,xl) \
do { \
- mp_limb_t dummy; \
- MPFR_ASSERTD ((xl) != 0); \
- udiv_qrnnd (invxl, dummy, ~(xl), ~(mp_limb_t)0, xl); \
+ invxl = __gmpn_invert_limb (xl); \
} while (0)
-
-typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into
- mpfr_pi1_t to avoid using
- GMP's namespace. */
-/* invert_pi1 macro, adapted from GMP 5.0.2, file gmp-impl.h.
- It returns dinv = floor((B^3-1)/(d1*B+d0))-B, where B=2^BITS_PER_LIMB,
- assuming the most significant bit of d1 is set. */
-#undef invert_pi1
-#define invert_pi1(dinv, d1, d0) \
- do { \
- mp_limb_t _v, _p, _t1, _t0, _mask; \
- invert_limb (_v, d1); \
- _p = d1 * _v; \
- _p += d0; \
- if (_p < d0) \
- { \
- _v--; \
- _mask = -(_p >= d1); \
- _p -= d1; \
- _v += _mask; \
- _p -= _mask & d1; \
- } \
- umul_ppmm (_t1, _t0, d0, _v); \
- _p += _t1; \
- if (_p < _t1) \
- { \
- _v--; \
- if (MPFR_UNLIKELY (_p >= d1)) \
- { \
- if (_p > d1 || _t0 >= d0) \
- _v--; \
- } \
- } \
- (dinv).inv32 = _v; \
+#else
+#define invert_limb(invxl,xl) \
+ do { \
+ mp_limb_t dummy MPFR_MAYBE_UNUSED; \
+ MPFR_ASSERTD ((xl) != 0); \
+ udiv_qrnnd (invxl, dummy, ~(xl), MPFR_LIMB_MAX, xl); \
} while (0)
+#endif /* defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB) */
+#endif /* ifndef invert_limb */
/* udiv_qr_3by2 macro, adapted from GMP 5.0.2, file gmp-impl.h.
Compute quotient the quotient and remainder for n / d. Requires d
@@ -374,7 +368,7 @@ typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into
NOTE: Output variables are updated multiple times. Only some inputs
and outputs may overlap.
*/
-#undef udiv_qr_3by2
+#ifndef udiv_qr_3by2
#define udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
do { \
mp_limb_t _q0, _t1, _t0, _mask; \
@@ -402,7 +396,245 @@ typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into
} \
} \
} while (0)
+#endif
+
+/* invert_pi1 macro adapted from GMP 5 */
+typedef struct {mp_limb_t inv32;} mpfr_pi1_t;
+#ifndef invert_pi1
+#define invert_pi1(dinv, d1, d0) \
+ do { \
+ mp_limb_t _v, _p, _t1, _t0, _mask; \
+ invert_limb (_v, d1); \
+ _p = (d1) * _v; \
+ _p += (d0); \
+ if (_p < (d0)) \
+ { \
+ _v--; \
+ _mask = -(mp_limb_t) (_p >= (d1)); \
+ _p -= (d1); \
+ _v += _mask; \
+ _p -= _mask & (d1); \
+ } \
+ umul_ppmm (_t1, _t0, d0, _v); \
+ _p += _t1; \
+ if (_p < _t1) \
+ { \
+ _v--; \
+ if (MPFR_UNLIKELY (_p >= (d1))) \
+ { \
+ if (_p > (d1) || _t0 >= (d0)) \
+ _v--; \
+ } \
+ } \
+ (dinv).inv32 = _v; \
+ } while (0)
+#endif
+
+/* The following macro is copied from GMP-6.1.1, file gmp-impl.h,
+ macro udiv_qrnnd_preinv.
+ It computes q and r such that nh*2^GMP_NUMB_BITS + nl = q*d + r,
+ with 0 <= r < d, assuming di = __gmpn_invert_limb (d). */
+#define __udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
+ do { \
+ mp_limb_t _qh, _ql, _r, _mask; \
+ umul_ppmm (_qh, _ql, (nh), (di)); \
+ if (__builtin_constant_p (nl) && (nl) == 0) \
+ { \
+ _qh += (nh) + 1; \
+ _r = - _qh * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _qh += _mask; \
+ _r += _mask & (d); \
+ } \
+ else \
+ { \
+ add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \
+ _r = (nl) - _qh * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _qh += _mask; \
+ _r += _mask & (d); \
+ if (MPFR_UNLIKELY (_r >= (d))) \
+ { \
+ _r -= (d); \
+ _qh++; \
+ } \
+ } \
+ (r) = _r; \
+ (q) = _qh; \
+ } while (0)
+
+#if GMP_NUMB_BITS == 64
+/* specialized version for nl = 0, with di computed inside */
+#define __udiv_qrnd_preinv(q, r, nh, d) \
+ do { \
+ mp_limb_t _di; \
+ \
+ MPFR_ASSERTD ((d) != 0); \
+ MPFR_ASSERTD ((nh) < (d)); \
+ MPFR_ASSERTD ((d) & MPFR_LIMB_HIGHBIT); \
+ \
+ __gmpfr_invert_limb (_di, d); \
+ __udiv_qrnnd_preinv (q, r, nh, 0, d, _di); \
+ } while (0)
+#elif defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_INVERT_LIMB)
+/* specialized version for nl = 0, with di computed inside */
+#define __udiv_qrnd_preinv(q, r, nh, d) \
+ do { \
+ mp_limb_t _di; \
+ \
+ MPFR_ASSERTD ((d) != 0); \
+ MPFR_ASSERTD ((nh) < (d)); \
+ MPFR_ASSERTD ((d) & MPFR_LIMB_HIGHBIT); \
+ \
+ _di = __gmpn_invert_limb (d); \
+ __udiv_qrnnd_preinv (q, r, nh, 0, d, _di); \
+ } while (0)
+#else
+/* Same as __udiv_qrnnd_c from longlong.h, but using a single UWType/UWtype
+ division instead of two, and with n0=0. The analysis below assumes a limb
+ has 64 bits for simplicity. */
+#define __udiv_qrnd_preinv(q, r, n1, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __i; \
+ \
+ MPFR_ASSERTD ((d) != 0); \
+ MPFR_ASSERTD ((n1) < (d)); \
+ MPFR_ASSERTD ((d) & MPFR_LIMB_HIGHBIT); \
+ \
+ __d1 = __ll_highpart (d); \
+ /* 2^31 <= d1 < 2^32 */ \
+ __d0 = __ll_lowpart (d); \
+ /* 0 <= d0 < 2^32 */ \
+ __i = ~(UWtype) 0 / __d1; \
+ /* 2^32 < i < 2^33 with i < 2^64/d1 */ \
+ \
+ __q1 = (((n1) / __ll_B) * __i) / __ll_B; \
+ /* Since n1 < d, high(n1) <= d1 = high(d), thus */ \
+ /* q1 <= high(n1) * (2^64/d1) / 2^32 <= 2^32 */ \
+ /* and also q1 <= n1/d1 thus r1 >= 0 below */ \
+ __r1 = (n1) - __q1 * __d1; \
+ while (__r1 >= __d1) \
+ __q1 ++, __r1 -= __d1; \
+ /* by construction, we have n1 = q1*d1+r1, and 0 <= r1 < d1 */ \
+ /* thus q1 <= n1/d1 < 2^32+2 */ \
+ /* q1*d0 <= (2^32+1)*(2^32-1) <= 2^64-1 thus it fits in a limb. */ \
+ __r0 = __r1 * __ll_B; \
+ __r1 = __r0 - __q1 * __d0; \
+ /* At most two corrections are needed like in __udiv_qrnnd_c. */ \
+ if (__r1 > __r0) /* borrow when subtracting q1*d0 */ \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 > (d)) /* no carry when adding d */ \
+ __q1--, __r1 += (d); \
+ } \
+ /* We can have r1 < m here, but in this case the true remainder */ \
+ /* is 2^64+r1, which is > m (same analysis as below for r0). */ \
+ /* Now we have n1*2^32 = q1*d + r1, with 0 <= r1 < d. */ \
+ MPFR_ASSERTD(__r1 < (d)); \
+ \
+ /* The same analysis as above applies, with n1 replaced by r1, */ \
+ /* q1 by q0, r1 by r0. */ \
+ __q0 = ((__r1 / __ll_B) * __i) / __ll_B; \
+ __r0 = __r1 - __q0 * __d1; \
+ while (__r0 >= __d1) \
+ __q0 ++, __r0 -= __d1; \
+ __r1 = __r0 * __ll_B; \
+ __r0 = __r1 - __q0 * __d0; \
+ /* We know the quotient floor(r1*2^64/d) is q0, q0-1 or q0-2.*/ \
+ if (__r0 > __r1) /* borrow when subtracting q0*d0 */ \
+ { \
+ /* The quotient is either q0-1 or q0-2. */ \
+ __q0--, __r0 += (d); \
+ if (__r0 > (d)) /* no carry when adding d */ \
+ __q0--, __r0 += (d); \
+ } \
+ /* Now we have n1*2^64 = (q1*2^32+q0)*d + r0, with 0 <= r0 < d. */ \
+ MPFR_ASSERTD(__r0 < (d)); \
+ \
+ (q) = __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+#endif
+
+/******************************************************
+ ************* GMP Basic Pointer Types ****************
+ ******************************************************/
+
+typedef mp_limb_t *mpfr_limb_ptr;
+typedef const mp_limb_t *mpfr_limb_srcptr;
+
+/* mpfr_ieee_double_extract structure (copied from GMP 6.1.0, gmp-impl.h, with
+ ieee_double_extract changed into mpfr_ieee_double_extract, and
+ _GMP_IEEE_FLOATS changed into _MPFR_IEEE_FLOATS). */
+
+/* Define mpfr_ieee_double_extract and _MPFR_IEEE_FLOATS.
+
+ Bit field packing is "implementation defined" according to C99, which
+ leaves us at the compiler's mercy here. For some systems packing is
+ defined in the ABI (eg. x86). In any case so far it seems universal that
+ little endian systems pack from low to high, and big endian from high to
+ low within the given type.
+
+ Within the fields we rely on the integer endianness being the same as the
+ float endianness, this is true everywhere we know of and it'd be a fairly
+ strange system that did anything else. */
+
+/* Note for MPFR: building with "gcc -std=c89 -pedantic -pedantic-errors"
+ fails if the bit-field type is unsigned long:
+
+ error: type of bit-field '...' is a GCC extension [-Wpedantic]
+
+ Though with -std=c99 no errors are obtained, this is still an extension
+ in C99, which says:
+
+ A bit-field shall have a type that is a qualified or unqualified version
+ of _Bool, signed int, unsigned int, or some other implementation-defined
+ type.
+
+ So, unsigned int should be better. This will fail with implementations
+ having 16-bit int's, but such implementations are not required to
+ support bit-fields of size > 16 anyway; if ever an implementation with
+ 16-bit int's is found, the appropriate minimal changes could still be
+ done in the future.
+*/
+
+#ifndef _MPFR_IEEE_FLOATS
+
+#ifdef HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+#define _MPFR_IEEE_FLOATS 1
+union mpfr_ieee_double_extract
+{
+ struct
+ {
+ unsigned int manl:32;
+ unsigned int manh:20;
+ unsigned int exp:11;
+ unsigned int sig:1;
+ } s;
+ double d;
+};
+#endif
+
+#ifdef HAVE_DOUBLE_IEEE_BIG_ENDIAN
+#define _MPFR_IEEE_FLOATS 1
+union mpfr_ieee_double_extract
+{
+ struct
+ {
+ unsigned int sig:1;
+ unsigned int exp:11;
+ unsigned int manh:20;
+ unsigned int manl:32;
+ } s;
+ double d;
+};
+#endif
+
+#endif /* _MPFR_IEEE_FLOATS */
+/******************************************************
+ ******************** C++ Compatibility ***************
+ ******************************************************/
#if defined (__cplusplus)
}
#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h
index 03e64f4be13..95c44ebfd9c 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h
@@ -23,11 +23,16 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#ifndef __MPFR_IMPL_H__
#define __MPFR_IMPL_H__
-/* Include MPFR 'config.h' before ANY system headers */
+/* Include config.h before using ANY configure macros if needed. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+
+/******************************************************
+ ***************** Standard headers *****************
+ ******************************************************/
+
/* Let's include some standard headers unconditionally as they are
already needed by several source files or when some options are
enabled/disabled, and it is easy to forget them (some configure
@@ -36,16 +41,34 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
(which is very unlikely and probably means something broken in
this source file), we should do that with some macro (that would
also force to disable incompatible features). */
+
#if defined (__cplusplus)
-#include <cstdio>
-#include <cstring>
+# include <cstdio>
+# include <cstring>
#else
-#include <stdio.h>
-#include <string.h>
+# include <stdio.h>
+# include <string.h>
+#endif
+
+/* Since <stdio.h> (<cstdio> for C++) is unconditionally included... */
+#ifndef MPFR_DONT_USE_FILE
+# define MPFR_USE_FILE
#endif
+
+#include <stdlib.h>
#include <limits.h>
-#if _MPFR_EXP_FORMAT == 4
+
+/******************************************************
+ ***************** Include files ********************
+ ******************************************************/
+
+/* The macros defined in mpfr-cvers.h do not depend on anything,
+ so that it is better to include this header file early: then
+ it can be used by any other header. */
+#include "mpfr-cvers.h"
+
+#if defined(_MPFR_EXP_FORMAT) && _MPFR_EXP_FORMAT == 4
/* mpfr_exp_t will be defined as intmax_t */
# include "mpfr-intmax.h"
#endif
@@ -57,125 +80,50 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
# define __MPFR_WITHIN_MPFR 1
#endif
-/******************************************************
- ****************** Include files *********************
- ******************************************************/
-
/* For the definition of MPFR_THREAD_ATTR. GCC/ICC detection macros are
no longer used, as they sometimes gave incorrect information about
the support of thread-local variables. A configure check is now done. */
+#if defined (WANT_SHARED_CACHE)
+# define MPFR_NEED_THREAD_LOCK 1
+#endif
#include "mpfr-thread.h"
-#ifdef MPFR_HAVE_GMP_IMPL /* Build with gmp internals */
+#ifdef MPFR_HAVE_GMP_IMPL /* Build with gmp internals */
-# ifndef __GMP_H__
-# include "gmp.h"
-# endif
-# ifndef __GMP_IMPL_H__
-# include "gmp-impl.h"
-# endif
+# include "gmp.h"
+# include "gmp-impl.h"
# ifdef MPFR_NEED_LONGLONG_H
# include "longlong.h"
# endif
-# ifndef __MPFR_H
-# include "mpfr.h"
-# endif
+# include "mpfr.h"
+# include "mpfr-gmp.h"
#else /* Build without gmp internals */
-# ifndef __GMP_H__
-# include "gmp.h"
-# endif
-# ifndef __MPFR_H
-# include "mpfr.h"
-# endif
-# ifndef __GMPFR_GMP_H__
-# include "mpfr-gmp.h"
+# include "gmp.h"
+/* if using mini-gmp, include missing definitions in mini-gmp */
+# ifdef MPFR_USE_MINI_GMP
+# include "mpfr-mini-gmp.h"
# endif
+# include "mpfr.h"
+# include "mpfr-gmp.h"
# ifdef MPFR_NEED_LONGLONG_H
# define LONGLONG_STANDALONE
# include "mpfr-longlong.h"
# endif
#endif
-#undef MPFR_NEED_LONGLONG_H
-
-/* If a mpn_sqr_n macro is not defined, use mpn_mul. GMP 4.x defines a
- mpn_sqr_n macro in gmp-impl.h (and this macro disappeared in GMP 5),
- so that GMP's macro can only be used when MPFR has been configured
- with --with-gmp-build (and only with GMP 4.x). */
-#ifndef mpn_sqr_n
-# define mpn_sqr_n(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
-#endif
-
-
-/******************************************************
- ***************** Detection macros *******************
- ******************************************************/
-
-/* Macros to detect STDC, GCC, GLIBC, GMP and ICC version */
-#if defined(__STDC_VERSION__)
-# define __MPFR_STDC(version) (__STDC_VERSION__>=(version))
-#elif defined(__STDC__)
-# define __MPFR_STDC(version) (0 == (version))
-#else
-# define __MPFR_STDC(version) 0
-#endif
-
-#if defined(_WIN32)
-/* Under MS Windows (e.g. with VS2008 or VS2010), Intel's compiler doesn't
- support/enable extensions like the ones seen under GNU/Linux.
- https://sympa.inria.fr/sympa/arc/mpfr/2011-02/msg00032.html */
-# define __MPFR_ICC(a,b,c) 0
-#elif defined(__ICC)
-# define __MPFR_ICC(a,b,c) (__ICC >= (a)*100+(b)*10+(c))
-#elif defined(__INTEL_COMPILER)
-# define __MPFR_ICC(a,b,c) (__INTEL_COMPILER >= (a)*100+(b)*10+(c))
-#else
-# define __MPFR_ICC(a,b,c) 0
-#endif
-
-#if defined(__GNUC__) && defined(__GNUC_MINOR__) && ! __MPFR_ICC(0,0,0)
-# define __MPFR_GNUC(a,i) \
- (MPFR_VERSION_NUM(__GNUC__,__GNUC_MINOR__,0) >= MPFR_VERSION_NUM(a,i,0))
-#else
-# define __MPFR_GNUC(a,i) 0
-#endif
-
-#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
-# define __MPFR_GLIBC(a,i) \
- (MPFR_VERSION_NUM(__GLIBC__,__GLIBC_MINOR__,0) >= MPFR_VERSION_NUM(a,i,0))
-#else
-# define __MPFR_GLIBC(a,i) 0
-#endif
-
-#if defined(__GNU_MP_VERSION) && \
- defined(__GNU_MP_VERSION_MINOR) && \
- defined(__GNU_MP_VERSION_PATCHLEVEL)
-# define __MPFR_GMP(a,b,c) \
- (MPFR_VERSION_NUM(__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR,__GNU_MP_VERSION_PATCHLEVEL) >= MPFR_VERSION_NUM(a,b,c))
-#else
-# define __MPFR_GMP(a,b,c) 0
-#endif
-
-
-
-/******************************************************
- ************* GMP Basic Pointer Types ****************
- ******************************************************/
-
-typedef mp_limb_t *mpfr_limb_ptr;
-typedef __gmp_const mp_limb_t *mpfr_limb_srcptr;
+#undef MPFR_NEED_LONGLONG_H
/******************************************************
- ****************** (U)INTMAX_MAX *********************
+ ***************** (U)INTMAX_MAX ********************
******************************************************/
/* Let's try to fix UINTMAX_MAX and INTMAX_MAX if these macros don't work
(e.g. with gcc -ansi -pedantic-errors in 32-bit mode under GNU/Linux),
- see <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582698>. */
+ see <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582698>. */
#ifdef _MPFR_H_HAVE_INTMAX_T
# ifdef MPFR_HAVE_INTMAX_MAX
# define MPFR_UINTMAX_MAX UINTMAX_MAX
@@ -188,61 +136,89 @@ typedef __gmp_const mp_limb_t *mpfr_limb_srcptr;
# endif
#endif
-#define MPFR_BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
/******************************************************
- ******************** Check GMP ***********************
+ ************* Attribute definitions ****************
******************************************************/
-#if !__MPFR_GMP(4,1,0)
-# error "GMP 4.1.0 or newer needed"
+#if defined(MPFR_HAVE_NORETURN)
+/* _Noreturn is specified by ISO C11 (Section 6.7.4);
+ in GCC, it is supported as of version 4.7. */
+# define MPFR_NORETURN _Noreturn
+#elif !defined(noreturn)
+/* A noreturn macro could be defined if <stdnoreturn.h> has been included,
+ in which case it would make sense to #define MPFR_NORETURN noreturn.
+ But this is unlikely, as MPFR_HAVE_NORETURN should have been defined
+ in such a case. So, in doubt, let us avoid any code that would use a
+ noreturn macro, since it could be invalid. */
+# if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+# define MPFR_NORETURN __attribute__ ((noreturn))
+# elif defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)
+# define MPFR_NORETURN __declspec (noreturn)
+# endif
+#endif
+#ifndef MPFR_NORETURN
+# define MPFR_NORETURN
#endif
-#if GMP_NAIL_BITS != 0
-# error "MPFR doesn't support nonzero values of GMP_NAIL_BITS"
+#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+# define MPFR_CONST_ATTR __attribute__ ((const))
+#else
+# define MPFR_CONST_ATTR
#endif
-#if (GMP_NUMB_BITS<32) || (GMP_NUMB_BITS & (GMP_NUMB_BITS - 1))
-# error "GMP_NUMB_BITS must be a power of 2, and >= 32"
+#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+# define MPFR_PURE_FUNCTION_ATTR __attribute__ ((pure))
+#else
+# define MPFR_PURE_FUNCTION_ATTR
#endif
-#if GMP_NUMB_BITS == 16
-# define MPFR_LOG2_GMP_NUMB_BITS 4
-#elif GMP_NUMB_BITS == 32
-# define MPFR_LOG2_GMP_NUMB_BITS 5
-#elif GMP_NUMB_BITS == 64
-# define MPFR_LOG2_GMP_NUMB_BITS 6
-#elif GMP_NUMB_BITS == 128
-# define MPFR_LOG2_GMP_NUMB_BITS 7
-#elif GMP_NUMB_BITS == 256
-# define MPFR_LOG2_GMP_NUMB_BITS 8
+/* The hot attribute on a function is used to inform the compiler
+ that the function is a hot spot of the compiled program. */
+#if __MPFR_GNUC(4,3)
+# define MPFR_HOT_FUNCTION_ATTR __attribute__ ((hot))
#else
-# error "Can't compute log2(GMP_NUMB_BITS)"
+# define MPFR_HOT_FUNCTION_ATTR
#endif
-#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
-/* For the future: N1478: Supporting the 'noreturn' property in C1x
- http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1478.htm */
-# define MPFR_NORETURN_ATTR __attribute__ ((noreturn))
-# define MPFR_CONST_ATTR __attribute__ ((const))
+/* The cold attribute on functions is used to inform the compiler
+ that the function is unlikely to be executed. */
+#if __MPFR_GNUC(4,3)
+# define MPFR_COLD_FUNCTION_ATTR __attribute__ ((cold))
#else
-# define MPFR_NORETURN_ATTR
-# define MPFR_CONST_ATTR
+# define MPFR_COLD_FUNCTION_ATTR
+#endif
+
+/* add MPFR_MAYBE_UNUSED after a variable declaration to avoid compiler
+ warnings if it is not used */
+#if __MPFR_GNUC(3,4)
+#define MPFR_MAYBE_UNUSED __attribute__ ((unused))
+#else
+#define MPFR_MAYBE_UNUSED
#endif
+
+
/******************************************************
- ************* Global Internal Variables **************
+ *** Global internal variables and related macros ***
******************************************************/
#if defined (__cplusplus)
extern "C" {
#endif
-/* Cache struct */
+#if defined(WANT_SHARED_CACHE)
+# define MPFR_CACHE_ATTR
+#else
+# define MPFR_CACHE_ATTR MPFR_THREAD_ATTR
+#endif
+
struct __gmpfr_cache_s {
mpfr_t x;
int inexact;
int (*func)(mpfr_ptr, mpfr_rnd_t);
+ MPFR_DEFERRED_INIT_SLAVE_DECL()
+ MPFR_LOCK_DECL(lock)
};
typedef struct __gmpfr_cache_s mpfr_cache_t[1];
typedef struct __gmpfr_cache_s *mpfr_cache_ptr;
@@ -252,33 +228,33 @@ typedef struct __gmpfr_cache_s *mpfr_cache_ptr;
#endif
#if defined(__MPFR_WITHIN_MPFR) || !defined(MPFR_WIN_THREAD_SAFE_DLL)
-extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags;
+extern MPFR_THREAD_ATTR mpfr_flags_t __gmpfr_flags;
extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emin;
extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emax;
extern MPFR_THREAD_ATTR mpfr_prec_t __gmpfr_default_fp_bit_precision;
extern MPFR_THREAD_ATTR mpfr_rnd_t __gmpfr_default_rounding_mode;
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_euler;
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_catalan;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_cache_const_euler;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_cache_const_catalan;
# ifndef MPFR_USE_LOGGING
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_pi;
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_log2;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_cache_const_pi;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_cache_const_log2;
# else
/* Two constants are used by the logging functions (via mpfr_fprintf,
then mpfr_log, for the base conversion): pi and log(2). Since the
mpfr_cache function isn't re-entrant when working on the same cache,
we need to define two caches for each constant. */
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_normal_pi;
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_normal_log2;
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_logging_pi;
-extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_logging_log2;
-extern MPFR_THREAD_ATTR mpfr_cache_ptr __gmpfr_cache_const_pi;
-extern MPFR_THREAD_ATTR mpfr_cache_ptr __gmpfr_cache_const_log2;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_normal_pi;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_normal_log2;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_logging_pi;
+extern MPFR_CACHE_ATTR mpfr_cache_t __gmpfr_logging_log2;
+extern MPFR_CACHE_ATTR mpfr_cache_ptr __gmpfr_cache_const_pi;
+extern MPFR_CACHE_ATTR mpfr_cache_ptr __gmpfr_cache_const_log2;
# endif
#endif
#ifdef MPFR_WIN_THREAD_SAFE_DLL
# define MPFR_MAKE_VARFCT(T,N) T * N ## _f (void) { return &N; }
-__MPFR_DECLSPEC unsigned int * __gmpfr_flags_f (void);
+__MPFR_DECLSPEC mpfr_flags_t * __gmpfr_flags_f (void);
__MPFR_DECLSPEC mpfr_exp_t * __gmpfr_emin_f (void);
__MPFR_DECLSPEC mpfr_exp_t * __gmpfr_emax_f (void);
__MPFR_DECLSPEC mpfr_prec_t * __gmpfr_default_fp_bit_precision_f (void);
@@ -333,24 +309,18 @@ __MPFR_DECLSPEC extern const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2];
__MPFR_DECLSPEC extern const mpfr_t __gmpfr_one;
__MPFR_DECLSPEC extern const mpfr_t __gmpfr_two;
__MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
-
+__MPFR_DECLSPEC extern const mpfr_t __gmpfr_mone;
+__MPFR_DECLSPEC extern const mpfr_t __gmpfr_const_log2_RNDD;
+__MPFR_DECLSPEC extern const mpfr_t __gmpfr_const_log2_RNDU;
#if defined (__cplusplus)
}
#endif
-/* Flags of __gmpfr_flags */
-#define MPFR_FLAGS_UNDERFLOW 1
-#define MPFR_FLAGS_OVERFLOW 2
-#define MPFR_FLAGS_NAN 4
-#define MPFR_FLAGS_INEXACT 8
-#define MPFR_FLAGS_ERANGE 16
-#define MPFR_FLAGS_DIVBY0 32
-#define MPFR_FLAGS_ALL 63
-
/* Replace some common functions for direct access to the global vars.
The casts prevent these macros from being used as a lvalue (and this
method makes sure that the expressions have the correct type). */
+
#define mpfr_get_emin() ((mpfr_exp_t) __gmpfr_emin)
#define mpfr_get_emax() ((mpfr_exp_t) __gmpfr_emax)
#define mpfr_get_default_rounding_mode() \
@@ -358,20 +328,17 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
#define mpfr_get_default_prec() \
((mpfr_prec_t) __gmpfr_default_fp_bit_precision)
-#define mpfr_clear_flags() \
- ((void) (__gmpfr_flags = 0))
-#define mpfr_clear_underflow() \
- ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW))
-#define mpfr_clear_overflow() \
- ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW))
-#define mpfr_clear_nanflag() \
- ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN))
-#define mpfr_clear_inexflag() \
- ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT))
-#define mpfr_clear_erangeflag() \
- ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE))
-#define mpfr_clear_divby0() \
- ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0))
+/* Flags related macros. */
+/* Note: Function-like macros that modify __gmpfr_flags are not defined
+ because of the risk to break the sequence point rules if two such
+ macros are used in the same expression (without a sequence point
+ between). For instance, mpfr_sgn currently uses mpfr_set_erangeflag,
+ which mustn't be implemented as a macro for this reason. */
+
+#define mpfr_flags_test(mask) \
+ (__gmpfr_flags & (mpfr_flags_t) (mask))
+
+#if MPFR_FLAGS_ALL <= INT_MAX
#define mpfr_underflow_p() \
((int) (__gmpfr_flags & MPFR_FLAGS_UNDERFLOW))
#define mpfr_overflow_p() \
@@ -384,6 +351,41 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
((int) (__gmpfr_flags & MPFR_FLAGS_ERANGE))
#define mpfr_divby0_p() \
((int) (__gmpfr_flags & MPFR_FLAGS_DIVBY0))
+#endif
+
+/* Use a do-while statement for the following macros in order to prevent
+ one from using them in an expression, as the sequence point rules could
+ be broken if __gmpfr_flags is assigned twice in the same expression
+ (via macro expansions). For instance, the mpfr_sgn macro currently uses
+ mpfr_set_erangeflag, which mustn't be implemented as a function-like
+ macro for this reason. It is not clear whether an expression with
+ sequence points, like (void) (0, __gmpfr_flags = 0), would avoid UB. */
+#define MPFR_CLEAR_FLAGS() \
+ do __gmpfr_flags = 0; while (0)
+#define MPFR_CLEAR_UNDERFLOW() \
+ do __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW; while (0)
+#define MPFR_CLEAR_OVERFLOW() \
+ do __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW; while (0)
+#define MPFR_CLEAR_DIVBY0() \
+ do __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0; while (0)
+#define MPFR_CLEAR_NANFLAG() \
+ do __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN; while (0)
+#define MPFR_CLEAR_INEXFLAG() \
+ do __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT; while (0)
+#define MPFR_CLEAR_ERANGEFLAG() \
+ do __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE; while (0)
+#define MPFR_SET_UNDERFLOW() \
+ do __gmpfr_flags |= MPFR_FLAGS_UNDERFLOW; while (0)
+#define MPFR_SET_OVERFLOW() \
+ do __gmpfr_flags |= MPFR_FLAGS_OVERFLOW; while (0)
+#define MPFR_SET_DIVBY0() \
+ do __gmpfr_flags |= MPFR_FLAGS_DIVBY0; while (0)
+#define MPFR_SET_NANFLAG() \
+ do __gmpfr_flags |= MPFR_FLAGS_NAN; while (0)
+#define MPFR_SET_INEXFLAG() \
+ do __gmpfr_flags |= MPFR_FLAGS_INEXACT; while (0)
+#define MPFR_SET_ERANGEFLAG() \
+ do __gmpfr_flags |= MPFR_FLAGS_ERANGE; while (0)
/* Testing an exception flag correctly is tricky. There are mainly two
pitfalls: First, one needs to remember to clear the corresponding
@@ -398,14 +400,14 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
Note: _op can be either a statement or an expression.
MPFR_BLOCK_EXCEP should be used only inside a block; it is useful to
detect some exception in order to exit the block as soon as possible. */
-#define MPFR_BLOCK_DECL(_flags) unsigned int _flags
+#define MPFR_BLOCK_DECL(_flags) mpfr_flags_t _flags
/* The (void) (_flags) makes sure that _flags is read at least once (it
makes sense to use MPFR_BLOCK while _flags will never be read in the
source, so that we wish to avoid the corresponding warning). */
#define MPFR_BLOCK(_flags,_op) \
do \
{ \
- mpfr_clear_flags (); \
+ MPFR_CLEAR_FLAGS (); \
_op; \
(_flags) = __gmpfr_flags; \
(void) (_flags); \
@@ -427,41 +429,120 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
/******************************************************
- ******************** Assertions **********************
+ ******************* Assertions *********************
******************************************************/
-/* Compile with -DMPFR_WANT_ASSERT to check all assert statements */
+/* MPFR_WANT_ASSERT can take 4 values (the default value is 0):
+ -1 (or below): Do not check any assertion. Discouraged, in particular
+ for a shared library (for time-critical applications, LTO with a
+ static library should also be used anyway).
+ 0: Check normal assertions.
+ 1: Check debugging assertions too.
+ 2 (or above): Additional checks that may take time. For instance,
+ some functions may be tested by using two different implementations
+ and comparing the results.
+*/
/* Note: do not use GMP macros ASSERT_ALWAYS and ASSERT as they are not
expressions, and as a consequence, they cannot be used in a for(),
with a comma operator and so on. */
-/* MPFR_ASSERTN(expr): assertions that should always be checked */
-#define MPFR_ASSERTN(expr) \
- ((void) ((MPFR_UNLIKELY(expr)) || MPFR_UNLIKELY( (ASSERT_FAIL(expr),0) )))
+/* MPFR_ASSERTN(expr): assertions that should normally be checked,
+ otherwise give a hint to the compiler.
+ MPFR_ASSERTD(expr): assertions that should be checked when testing,
+ otherwise give a hint to the compiler.
+ MPFR_DBGRES(assignment): to be used when the result is tested only
+ in an MPFR_ASSERTD expression (in order to avoid a warning, e.g.
+ with GCC's -Wunused-but-set-variable, in non-debug mode).
+ Note: Evaluating expr might yield side effects, but such side effects
+ must not change the results (except by yielding an assertion failure).
+*/
+#ifndef MPFR_WANT_ASSERT
+# define MPFR_WANT_ASSERT 0
+#endif
+
+#if MPFR_WANT_ASSERT < 0
+# undef MPFR_EXP_CHECK
+# define MPFR_ASSERTN(expr) MPFR_ASSUME (expr)
+#else
+# define MPFR_ASSERTN(expr) \
+ ((void) ((MPFR_LIKELY(expr)) || (ASSERT_FAIL(expr),MPFR_ASSUME(expr),0)))
+/* Some explanations: mpfr_assert_fail is not marked as "no return",
+ so that ((void) ((MPFR_LIKELY(expr)) || (ASSERT_FAIL(expr),0)))
+ cannot be a way to tell the compiler that after this code, expr is
+ necessarily true. The MPFR_ASSUME(expr) is a way to tell the compiler
+ that if expr is false, then ASSERT_FAIL(expr) does not return
+ (otherwise they would be a contradiction / UB when MPFR_ASSUME(expr)
+ is reached). Such information is useful to avoid warnings like those
+ from -Wmaybe-uninitialized, e.g. in tests/turandom.c r11663 on t[0]
+ from "mpfr_equal_p (y, t[0])".
+ TODO: Remove the MPFR_ASSUME(expr) once mpfr_assert_fail is marked as
+ "no return".
+ */
+#endif
-/* MPFR_ASSERTD(expr): assertions that should be checked when testing */
-#ifdef MPFR_WANT_ASSERT
+#if MPFR_WANT_ASSERT > 0
# define MPFR_EXP_CHECK 1
# define MPFR_ASSERTD(expr) MPFR_ASSERTN (expr)
+# define MPFR_DBGRES(A) (A)
+#else
+# define MPFR_ASSERTD(expr) MPFR_ASSUME (expr)
+# define MPFR_DBGRES(A) ((void) (A))
+#endif
+
+/* MPFR_ASSUME is like assert(), but it is a hint to a compiler about a
+ statement of fact in a function call free expression, which allows
+ the compiler to generate better machine code.
+ __builtin_unreachable has been introduced in GCC 4.5 but it works
+ fine since 4.8 only (before it may generate unoptimized code if there
+ are more than one decision).
+ Note:
+ The goal of MPFR_ASSUME() is to allow the compiler to optimize even
+ more. Thus we need to make sure that its use in MPFR will never yield
+ code generation. Since MPFR_ASSUME() may be used by MPFR_ASSERTN()
+ and MPFR_ASSERTD(), whose expression might have side effects, we need
+ to make sure that the expression x is not evaluated in such a case.
+ This is done with __builtin_constant_p (!!(x) || !(x)), whose value
+ is 0 if x has side effects, and normally 1 if the compiler knows that
+ x has no side effects (since here, it can deduce that !!(x) || !(x)
+ is equivalent to the constant 1). In the former case, MPFR_ASSUME(x)
+ will give (void) 0, and in the latter case, it will give:
+ (x) ? (void) 0 : __builtin_unreachable()
+ In the development code, it is better to use MPFR_ASSERTD than
+ MPFR_ASSUME, since it'll check if the condition is true in debug
+ build.
+*/
+#if defined(MPFR_HAVE_BUILTIN_UNREACHABLE) && __MPFR_GNUC(4, 8)
+# define MPFR_ASSUME(x) \
+ (! __builtin_constant_p (!!(x) || !(x)) || (x) ? \
+ (void) 0 : __builtin_unreachable())
+#elif defined(_MSC_VER)
+# define MPFR_ASSUME(x) __assume(x)
#else
-# define MPFR_ASSERTD(expr) ((void) 0)
+# define MPFR_ASSUME(x) ((void) 0)
#endif
-/* Code to deal with impossible
- WARNING: It doesn't use do { } while (0) for Insure++*/
-#define MPFR_RET_NEVER_GO_HERE() {MPFR_ASSERTN(0); return 0;}
+#include "mpfr-sassert.h"
+
+/* Code to deal with impossible, for functions returning an int.
+ The "return 0;" avoids an error with current GCC versions and
+ "-Werror=return-type".
+ WARNING: It doesn't use do { } while (0) for Insure++ */
+#if defined(HAVE_BUILTIN_UNREACHABLE)
+# define MPFR_RET_NEVER_GO_HERE() do { __builtin_unreachable(); } while (0)
+#else
+# define MPFR_RET_NEVER_GO_HERE() do { MPFR_ASSERTN(0); return 0; } while (0)
+#endif
/******************************************************
- ******************** Warnings ************************
+ ******************* Warnings ***********************
******************************************************/
/* MPFR_WARNING is no longer useful, but let's keep the macro in case
it needs to be used again in the future. */
#ifdef MPFR_USE_WARNINGS
-# include <stdlib.h>
# define MPFR_WARNING(W) \
do \
{ \
@@ -476,7 +557,7 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
/******************************************************
- ****************** double macros *********************
+ ***************** double macros ********************
******************************************************/
/* Precision used for lower precision computations */
@@ -484,8 +565,6 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
/* Definition of constants */
#define LOG2 0.69314718055994528622 /* log(2) rounded to zero on 53 bits */
-#define ALPHA 4.3191365662914471407 /* a+2 = a*log(a), rounded to +infinity */
-#define EXPM1 0.36787944117144227851 /* exp(-1), rounded to zero */
/* MPFR_DOUBLE_SPEC = 1 if the C type 'double' corresponds to IEEE-754
double precision, 0 if it doesn't, and undefined if one doesn't know.
@@ -502,12 +581,12 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
# endif
#endif
-/* Debug non IEEE floats */
-#ifdef XDEBUG
-# undef _GMP_IEEE_FLOATS
-#endif
-#ifndef _GMP_IEEE_FLOATS
-# define _GMP_IEEE_FLOATS 0
+/* With -DMPFR_DISABLE_IEEE_FLOATS, exercise non IEEE floats */
+#ifdef MPFR_DISABLE_IEEE_FLOATS
+# ifdef _MPFR_IEEE_FLOATS
+# undef _MPFR_IEEE_FLOATS
+# endif
+# define _MPFR_IEEE_FLOATS 0
#endif
#ifndef IEEE_DBL_MANT_DIG
@@ -523,11 +602,12 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
/* Visual C++ doesn't support +1.0/0.0, -1.0/0.0 and 0.0/0.0
at compile time.
Clang with -fsanitize=undefined is a bit similar due to a bug:
- http://llvm.org/bugs/show_bug.cgi?id=17381
+ https://llvm.org/bugs/show_bug.cgi?id=17381 (fixed on 2015-12-03)
but even without its sanitizer, it may be better to use the
double_zero version until IEEE 754 division by zero is properly
supported:
- http://llvm.org/bugs/show_bug.cgi?id=17000
+ https://llvm.org/bugs/show_bug.cgi?id=17005
+ Note: DBL_NAN is 0/0, thus its value is a quiet NaN (qNAN).
*/
#if (defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)) || \
defined(__clang__)
@@ -543,7 +623,7 @@ static double double_zero = 0.0;
# define DBL_NEG_ZERO (-0.0)
#endif
-/* Note: In the past, there was specific code for _GMP_IEEE_FLOATS, which
+/* Note: In the past, there was specific code for _MPFR_IEEE_FLOATS, which
was based on NaN and Inf memory representations. This code was breaking
the aliasing rules (see ISO C99, 6.5#6 and 6.5#7 on the effective type)
and for this reason it did not behave correctly with GCC 4.5.0 20091119.
@@ -568,15 +648,21 @@ static double double_zero = 0.0;
/* Avoid MIPSpro / IRIX64 / gcc -ffast-math (incorrect) optimizations.
The + must not be replaced by a ||. With gcc -ffast-math, NaN is
regarded as a positive number or something like that; the second
- test catches this case. */
+ test catches this case.
+ [2016-03-01] Various tests now fail with gcc -ffast-math or just
+ -ffinite-math-only; such options are not supported, but this makes
+ difficult to test MPFR assuming x == x optimization to 1. Anyway
+ support of functions/tests of using native FP and special values for
+ non-IEEE-754 environment will always be on a case-by-case basis. */
# define DOUBLE_ISNAN(x) \
(LVALUE(x) && !((((x) >= 0.0) + ((x) <= 0.0)) && -(x)*(x) <= 0.0))
#else
# define DOUBLE_ISNAN(x) (LVALUE(x) && (x) != (x))
#endif
+
/******************************************************
- *************** Long double macros *******************
+ ********** long double macros and typedef **********
******************************************************/
/* We try to get the exact value of the precision of long double
@@ -592,6 +678,10 @@ static double double_zero = 0.0;
Otherwise (e.g. in base 10), we get an upper bound of the
precision, and correct rounding isn't currently provided.
*/
+
+/* Definitions are enabled only if <float.h> is included. */
+#if defined (FLT_RADIX)
+
#if defined(LDBL_MANT_DIG) && FLT_RADIX == 2
# define MPFR_LDBL_MANT_DIG LDBL_MANT_DIG
#else
@@ -667,7 +757,8 @@ static double double_zero = 0.0;
optimizing anything. */
#ifdef WANT_LONGDOUBLE_VOLATILE
# ifdef volatile
-__MPFR_DECLSPEC long double __gmpfr_longdouble_volatile _MPFR_PROTO ((long double)) MPFR_CONST_ATTR;
+__MPFR_DECLSPEC long double
+ __gmpfr_longdouble_volatile (long double) MPFR_CONST_ATTR;
# define LONGDOUBLE_VOLATILE(x) (__gmpfr_longdouble_volatile (x))
# define WANT_GMPFR_LONGDOUBLE_VOLATILE 1
# else
@@ -696,19 +787,34 @@ typedef union {
#endif
+#endif /* long double macros and typedef */
+
+
+/******************************************************
+ **************** __float128 support ****************
+ ******************************************************/
+
+/* This is standardized by IEEE 754-2008. */
+#define IEEE_FLOAT128_MANT_DIG 113
+
+
/******************************************************
- *************** _Decimal64 support *******************
+ **************** _Decimal64 support ****************
******************************************************/
#ifdef MPFR_WANT_DECIMAL_FLOATS
/* to cast between binary64 and decimal64 */
union ieee_double_decimal64 { double d; _Decimal64 d64; };
-#endif
+#endif /* MPFR_WANT_DECIMAL_FLOATS */
+
/******************************************************
- **************** mpfr_t properties *******************
+ **************** mpfr_t properties *****************
******************************************************/
+#define MPFR_PREC_COND(p) ((p) >= MPFR_PREC_MIN && (p) <= MPFR_PREC_MAX)
+#define MPFR_PREC_IN_RANGE(p) (MPFR_ASSERTD (MPFR_PREC_COND(p)), (p))
+
/* In the following macro, p is usually a mpfr_prec_t, but this macro
works with other integer types (without integer overflow). Checking
that p >= 1 in debug mode is useful here because this macro can be
@@ -725,12 +831,13 @@ union ieee_double_decimal64 { double d; _Decimal64 d64; };
#define MPFR_PREC(x) ((x)->_mpfr_prec)
#define MPFR_EXP(x) ((x)->_mpfr_exp)
#define MPFR_MANT(x) ((x)->_mpfr_d)
-#define MPFR_LAST_LIMB(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS)
+#define MPFR_GET_PREC(x) MPFR_PREC_IN_RANGE (MPFR_PREC (x))
+#define MPFR_LAST_LIMB(x) ((MPFR_GET_PREC (x) - 1) / GMP_NUMB_BITS)
#define MPFR_LIMB_SIZE(x) (MPFR_LAST_LIMB (x) + 1)
/******************************************************
- **************** exponent properties *****************
+ *************** Exponent properties ****************
******************************************************/
/* Limits of the mpfr_exp_t type (NOT those of valid exponent values).
@@ -745,6 +852,8 @@ union ieee_double_decimal64 { double d; _Decimal64 d64; };
# define MPFR_EXP_MAX (LONG_MAX)
# define MPFR_EXP_MIN (LONG_MIN)
#elif _MPFR_EXP_FORMAT == 4
+/* Note: MPFR_EXP_MAX and MPFR_EXP_MIN must not be used in #if directives
+ if _MPFR_EXP_FORMAT == 4 and MPFR_HAVE_INTMAX_MAX is not defined. */
# define MPFR_EXP_MAX (MPFR_INTMAX_MAX)
# define MPFR_EXP_MIN (MPFR_INTMAX_MIN)
#else
@@ -755,20 +864,24 @@ union ieee_double_decimal64 { double d; _Decimal64 d64; };
nonnegative. */
#define MPFR_UEXP(X) (MPFR_ASSERTD ((X) >= 0), (mpfr_uexp_t) (X))
-#if MPFR_EXP_MIN >= LONG_MIN && MPFR_EXP_MAX <= LONG_MAX
-typedef long int mpfr_eexp_t;
+#if _MPFR_EXP_FORMAT <= 3
+typedef long mpfr_eexp_t;
+typedef unsigned long mpfr_ueexp_t;
# define mpfr_get_exp_t(x,r) mpfr_get_si((x),(r))
# define mpfr_set_exp_t(x,e,r) mpfr_set_si((x),(e),(r))
# define MPFR_EXP_FSPEC "l"
-#elif defined (_MPFR_H_HAVE_INTMAX_T)
+#else
typedef intmax_t mpfr_eexp_t;
+typedef uintmax_t mpfr_ueexp_t;
# define mpfr_get_exp_t(x,r) mpfr_get_sj((x),(r))
# define mpfr_set_exp_t(x,e,r) mpfr_set_sj((x),(e),(r))
# define MPFR_EXP_FSPEC "j"
-#else
-# error "Cannot define mpfr_get_exp_t and mpfr_set_exp_t"
#endif
+/* Size of mpfr_exp_t in limbs */
+#define MPFR_EXP_LIMB_SIZE \
+ ((sizeof (mpfr_exp_t) - 1) / MPFR_BYTES_PER_MP_LIMB + 1)
+
/* Invalid exponent value (to track bugs...) */
#define MPFR_EXP_INVALID \
((mpfr_exp_t) 1 << (GMP_NUMB_BITS*sizeof(mpfr_exp_t)/sizeof(mp_limb_t)-2))
@@ -792,28 +905,42 @@ typedef intmax_t mpfr_eexp_t;
setting the exponent before calling mpfr_check_range.
MPFR_EXP_CHECK is defined when MPFR_WANT_ASSERT is defined, but if you
don't use MPFR_WANT_ASSERT (for speed reasons), you can still define
- MPFR_EXP_CHECK by setting -DMPFR_EXP_CHECK in $CFLAGS. */
+ MPFR_EXP_CHECK by setting -DMPFR_EXP_CHECK in $CFLAGS.
+ Note about MPFR_EXP_IN_RANGE and MPFR_SET_EXP:
+ The exp expression is required to have a signed type. To avoid spurious
+ failures, we could cast (exp) to mpfr_exp_t, but this wouldn't allow us
+ to detect some bugs that can occur on particular platforms. Anyway, an
+ unsigned type for exp is suspicious and should be regarded as a bug.
+*/
+
+#define MPFR_EXP_IN_RANGE(e) \
+ (MPFR_ASSERTD (IS_SIGNED (e)), (e) >= __gmpfr_emin && (e) <= __gmpfr_emax)
#ifdef MPFR_EXP_CHECK
# define MPFR_GET_EXP(x) (mpfr_get_exp) (x)
-# define MPFR_SET_EXP(x, exp) MPFR_ASSERTN (!mpfr_set_exp ((x), (exp)))
+# define MPFR_SET_EXP(x,e) (MPFR_ASSERTN (MPFR_EXP_IN_RANGE (e)), \
+ (void) (MPFR_EXP (x) = (e)))
# define MPFR_SET_INVALID_EXP(x) ((void) (MPFR_EXP (x) = MPFR_EXP_INVALID))
#else
# define MPFR_GET_EXP(x) MPFR_EXP (x)
-# define MPFR_SET_EXP(x, exp) ((void) (MPFR_EXP (x) = (exp)))
+# define MPFR_SET_EXP(x,e) ((void) (MPFR_EXP (x) = (e)))
# define MPFR_SET_INVALID_EXP(x) ((void) 0)
#endif
+#define MPFR_UBF_EXP_LESS_P(x,y) \
+ (MPFR_UNLIKELY (MPFR_IS_UBF (x) || MPFR_IS_UBF (y)) ? \
+ mpfr_ubf_exp_less_p (x, y) : MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
/******************************************************
- ********** Singular Values (NAN, INF, ZERO) **********
+ ********* Singular values (NAN, INF, ZERO) *********
******************************************************/
/* Enum special value of exponent. */
# define MPFR_EXP_ZERO (MPFR_EXP_MIN+1)
# define MPFR_EXP_NAN (MPFR_EXP_MIN+2)
# define MPFR_EXP_INF (MPFR_EXP_MIN+3)
+# define MPFR_EXP_UBF (MPFR_EXP_MIN+4)
#define MPFR_IS_NAN(x) (MPFR_EXP(x) == MPFR_EXP_NAN)
#define MPFR_SET_NAN(x) (MPFR_EXP(x) = MPFR_EXP_NAN)
@@ -822,29 +949,51 @@ typedef intmax_t mpfr_eexp_t;
#define MPFR_IS_ZERO(x) (MPFR_EXP(x) == MPFR_EXP_ZERO)
#define MPFR_SET_ZERO(x) (MPFR_EXP(x) = MPFR_EXP_ZERO)
#define MPFR_NOTZERO(x) (MPFR_EXP(x) != MPFR_EXP_ZERO)
+#define MPFR_IS_UBF(x) (MPFR_EXP(x) == MPFR_EXP_UBF)
+#define MPFR_SET_UBF(x) (MPFR_EXP(x) = MPFR_EXP_UBF)
+
+#define MPFR_IS_NORMALIZED(x) \
+ (MPFR_LIMB_MSB (MPFR_MANT(x)[MPFR_LAST_LIMB(x)]) != 0)
#define MPFR_IS_FP(x) (!MPFR_IS_NAN(x) && !MPFR_IS_INF(x))
+/* Note: contrary to the MPFR_IS_PURE_*(x) macros, the MPFR_IS_SINGULAR*(x)
+ macros may be used even when x is being constructed, i.e. its exponent
+ field is already set (possibly out-of-range), but its significand field
+ may still contain arbitrary data. Thus MPFR_IS_PURE_FP(x) is not always
+ equivalent to !MPFR_IS_SINGULAR(x); see the code below. */
#define MPFR_IS_SINGULAR(x) (MPFR_EXP(x) <= MPFR_EXP_INF)
-#define MPFR_IS_PURE_FP(x) (!MPFR_IS_SINGULAR(x) && \
- (MPFR_ASSERTD ((MPFR_MANT(x)[MPFR_LAST_LIMB(x)] \
- & MPFR_LIMB_HIGHBIT) != 0), 1))
+#define MPFR_IS_SINGULAR_OR_UBF(x) (MPFR_EXP(x) <= MPFR_EXP_UBF)
+#define MPFR_IS_PURE_FP(x) \
+ (!MPFR_IS_SINGULAR(x) && \
+ (MPFR_ASSERTD (MPFR_EXP (x) >= MPFR_EMIN_MIN && \
+ MPFR_EXP (x) <= MPFR_EMAX_MAX && \
+ MPFR_IS_NORMALIZED (x)), 1))
+#define MPFR_IS_PURE_UBF(x) \
+ (!MPFR_IS_SINGULAR(x) && \
+ (MPFR_ASSERTD ((MPFR_IS_UBF (x) || \
+ (MPFR_EXP (x) >= MPFR_EMIN_MIN && \
+ MPFR_EXP (x) <= MPFR_EMAX_MAX)) && \
+ MPFR_IS_NORMALIZED (x)), 1))
#define MPFR_ARE_SINGULAR(x,y) \
(MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)) || MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
-#define MPFR_IS_POWER_OF_2(x) \
- (mpfr_cmp_ui_2exp ((x), 1, MPFR_GET_EXP (x) - 1) == 0)
+#define MPFR_ARE_SINGULAR_OR_UBF(x,y) \
+ (MPFR_UNLIKELY(MPFR_IS_SINGULAR_OR_UBF(x)) || \
+ MPFR_UNLIKELY(MPFR_IS_SINGULAR_OR_UBF(y)))
/******************************************************
- ********************* Sign Macros ********************
+ ******************** Sign macros *******************
******************************************************/
+/* These are sign macros for MPFR numbers only. */
+
#define MPFR_SIGN_POS (1)
#define MPFR_SIGN_NEG (-1)
-#define MPFR_IS_STRICTPOS(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x) > 0)
-#define MPFR_IS_STRICTNEG(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x) < 0)
+#define MPFR_IS_STRICTPOS(x) (MPFR_NOTZERO (x) && MPFR_IS_POS (x))
+#define MPFR_IS_STRICTNEG(x) (MPFR_NOTZERO (x) && MPFR_IS_NEG (x))
#define MPFR_IS_NEG(x) (MPFR_SIGN(x) < 0)
#define MPFR_IS_POS(x) (MPFR_SIGN(x) > 0)
@@ -867,9 +1016,8 @@ typedef intmax_t mpfr_eexp_t;
#define MPFR_INT_SIGN(x) MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(x))
-
/******************************************************
- ***************** Ternary Value Macros ***************
+ *************** Ternary value macros ***************
******************************************************/
/* Special inexact value */
@@ -886,22 +1034,18 @@ typedef intmax_t mpfr_eexp_t;
(I) != 0 ? ((__gmpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0
#define MPFR_RET_NAN return (__gmpfr_flags |= MPFR_FLAGS_NAN), 0
-#define MPFR_SET_ERANGE() (__gmpfr_flags |= MPFR_FLAGS_ERANGE)
-
-#define SIGN(I) ((I) < 0 ? -1 : (I) > 0)
-#define SAME_SIGN(I1,I2) (SIGN (I1) == SIGN (I2))
-
+/* Sign of a native value. */
+#define VSIGN(I) ((I) < 0 ? -1 : (I) > 0)
+#define SAME_SIGN(I1,I2) (VSIGN (I1) == VSIGN (I2))
/******************************************************
- ************** Rounding mode macros *****************
+ *************** Rounding mode macros ***************
******************************************************/
/* MPFR_RND_MAX gives the number of supported rounding modes by all functions.
- * Once faithful rounding is implemented, MPFR_RNDA should be changed
- * to MPFR_RNDF. But this will also require more changes in the tests.
*/
-#define MPFR_RND_MAX ((mpfr_rnd_t)((MPFR_RNDA)+1))
+#define MPFR_RND_MAX ((mpfr_rnd_t)((MPFR_RNDF)+1))
/* We want to test this :
* (rnd == MPFR_RNDU && test) || (rnd == RNDD && !test)
@@ -910,9 +1054,12 @@ typedef intmax_t mpfr_eexp_t;
(((rnd) + (test)) == MPFR_RNDD)
/* We want to test if rnd = Zero, or Away.
- 'test' is 1 if negative, and 0 if positive. */
-#define MPFR_IS_LIKE_RNDZ(rnd, test) \
- ((rnd) == MPFR_RNDZ || MPFR_IS_RNDUTEST_OR_RNDDNOTTEST (rnd, test))
+ 'neg' is 1 if negative, and 0 if positive. */
+#define MPFR_IS_LIKE_RNDZ(rnd, neg) \
+ ((rnd) == MPFR_RNDZ || MPFR_IS_RNDUTEST_OR_RNDDNOTTEST (rnd, neg))
+
+#define MPFR_IS_LIKE_RNDA(rnd, neg) \
+ ((rnd) == MPFR_RNDA || MPFR_IS_RNDUTEST_OR_RNDDNOTTEST (rnd, (neg) == 0))
#define MPFR_IS_LIKE_RNDU(rnd, sign) \
(((rnd) == MPFR_RNDU) || \
@@ -947,53 +1094,58 @@ typedef intmax_t mpfr_eexp_t;
/******************************************************
- ******************* Limb Macros **********************
+ ****************** Limb macros *********************
******************************************************/
- /* Definition of MPFR_LIMB_HIGHBIT */
-#if defined(GMP_LIMB_HIGHBIT)
-# define MPFR_LIMB_HIGHBIT GMP_LIMB_HIGHBIT
-#elif defined(MP_LIMB_T_HIGHBIT)
-# define MPFR_LIMB_HIGHBIT MP_LIMB_T_HIGHBIT
-#else
-# error "Neither GMP_LIMB_HIGHBIT nor MP_LIMB_T_HIGHBIT defined in GMP"
-#endif
+/* Definition of simple mp_limb_t constants */
+#define MPFR_LIMB_ZERO ((mp_limb_t) 0)
+#define MPFR_LIMB_ONE ((mp_limb_t) 1)
+#define MPFR_LIMB_HIGHBIT (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1))
+#define MPFR_LIMB_MAX ((mp_limb_t) -1)
/* Mask to get the Most Significant Bit of a limb */
-#define MPFR_LIMB_MSB(l) ((l)&MPFR_LIMB_HIGHBIT)
-
-/* Definition of MPFR_LIMB_ONE & MPFR_LIMB_ZERO */
-#ifdef CNST_LIMB
-# define MPFR_LIMB_ONE CNST_LIMB(1)
-# define MPFR_LIMB_ZERO CNST_LIMB(0)
-#else
-# define MPFR_LIMB_ONE ((mp_limb_t) 1L)
-# define MPFR_LIMB_ZERO ((mp_limb_t) 0L)
-#endif
+#define MPFR_LIMB_MSB(l) ((l) & MPFR_LIMB_HIGHBIT)
/* Mask for the low 's' bits of a limb */
-#define MPFR_LIMB_MASK(s) ((MPFR_LIMB_ONE<<(s))-MPFR_LIMB_ONE)
-
+#define MPFR_LIMB_MASK(s) ((MPFR_LIMB_ONE << (s)) - MPFR_LIMB_ONE)
/******************************************************
- ********************** Memory ************************
+ ********************** Memory **********************
******************************************************/
-/* Heap Memory gestion */
+#define MPFR_BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
+
+/* Heap memory handling
+ --------------------
+ Memory allocated for a significand (mantissa) has the following
+ format:
+ * A mp_size_t in a mpfr_size_limb_t union (see below).
+ * An array of mp_limb_t (not all of them are necessarily used,
+ as the precision can change without a reallocation).
+ The goal of the mpfr_size_limb_t union is to make sure that
+ size and alignment requirements are satisfied if mp_size_t and
+ mp_limb_t have different sizes and/or alignment requirements.
+ Moreover, pointer conversions are not fully specified by the
+ C standard, and the use of a union (and the double casts below)
+ might help even if mp_size_t and mp_limb_t have the same size
+ and the same alignment requirements. Still, there is currently
+ no guarantee that this code is portable. Note that union members
+ are not used at all.
+*/
typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t;
#define MPFR_GET_ALLOC_SIZE(x) \
- ( ((mp_size_t*) MPFR_MANT(x))[-1] + 0)
+ (((mp_size_t *) (mpfr_size_limb_t *) MPFR_MANT(x))[-1] + 0)
#define MPFR_SET_ALLOC_SIZE(x, n) \
- ( ((mp_size_t*) MPFR_MANT(x))[-1] = n)
+ (((mp_size_t *) (mpfr_size_limb_t *) MPFR_MANT(x))[-1] = (n))
#define MPFR_MALLOC_SIZE(s) \
- ( sizeof(mpfr_size_limb_t) + MPFR_BYTES_PER_MP_LIMB * ((size_t) s) )
+ (sizeof(mpfr_size_limb_t) + MPFR_BYTES_PER_MP_LIMB * (size_t) (s))
#define MPFR_SET_MANT_PTR(x,p) \
- (MPFR_MANT(x) = (mp_limb_t*) ((mpfr_size_limb_t*) p + 1))
+ (MPFR_MANT(x) = (mp_limb_t *) ((mpfr_size_limb_t *) (p) + 1))
#define MPFR_GET_REAL_PTR(x) \
- ((mp_limb_t*) ((mpfr_size_limb_t*) MPFR_MANT(x) - 1))
+ ((mp_limb_t *) ((mpfr_size_limb_t *) MPFR_MANT(x) - 1))
-/* Temporary memory gestion */
+/* Temporary memory handling */
#ifndef TMP_SALLOC
/* GMP 4.1.x or below or internals */
#define MPFR_TMP_DECL TMP_DECL
@@ -1007,19 +1159,6 @@ typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t;
#define MPFR_TMP_FREE(x) TMP_FREE
#endif
-/* This code is experimental: don't use it */
-#ifdef MPFR_USE_OWN_MPFR_TMP_ALLOC
-extern unsigned char *mpfr_stack;
-#undef MPFR_TMP_DECL
-#undef MPFR_TMP_MARK
-#undef MPFR_TMP_ALLOC
-#undef MPFR_TMP_FREE
-#define MPFR_TMP_DECL(_x) unsigned char *(_x)
-#define MPFR_TMP_MARK(_x) ((_x) = mpfr_stack)
-#define MPFR_TMP_ALLOC(_s) (mpfr_stack += (_s), mpfr_stack - (_s))
-#define MPFR_TMP_FREE(_x) (mpfr_stack = (_x))
-#endif
-
#define MPFR_TMP_LIMBS_ALLOC(N) \
((mp_limb_t *) MPFR_TMP_ALLOC ((size_t) (N) * MPFR_BYTES_PER_MP_LIMB))
@@ -1042,52 +1181,132 @@ extern unsigned char *mpfr_stack;
MPFR_SET_POS(d), \
MPFR_EXP(d) = MPFR_EXP(s))
+#define MPFR_TMP_INIT_NEG(d, s) \
+ ( MPFR_PREC(d) = MPFR_PREC(s), \
+ MPFR_MANT(d) = MPFR_MANT(s), \
+ MPFR_SET_OPPOSITE_SIGN(d,s), \
+ MPFR_EXP(d) = MPFR_EXP(s))
/******************************************************
- ***************** Cache macros **********************
+ ******************* Cache macros *******************
******************************************************/
+/* Cache struct */
#define mpfr_const_pi(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_pi,_r)
#define mpfr_const_log2(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_log2, _r)
#define mpfr_const_euler(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_euler, _r)
#define mpfr_const_catalan(_d,_r) mpfr_cache(_d,__gmpfr_cache_const_catalan,_r)
+/* Declare a global cache for a MPFR constant.
+ If the shared cache is enabled, and if the constructor/destructor
+ attributes are available, we need to initialize the shared lock of
+ the cache with a constructor. It is the goal of the macro
+ MPFR_DEFERRED_INIT_MASTER_DECL.
+ FIXME: When MPFR is built with shared cache, the field "lock" is
+ not explicitly initialized, which can yield a warning, e.g. with
+ GCC's -Wmissing-field-initializers (and an error with -Werror).
+ Since one does not know what is behind the associated typedef name,
+ one cannot provide an explicit initialization for such a type. Two
+ possible solutions:
+ 1. Encapsulate the type in a structure or a union and use the
+ universal zero initializer: { 0 }
+ But: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80454
+ 2. Use designated initializers when supported. But this needs a
+ configure test.
+*/
#define MPFR_DECL_INIT_CACHE(_cache,_func) \
- MPFR_THREAD_ATTR mpfr_cache_t _cache = \
- {{{{0,MPFR_SIGN_POS,0,(mp_limb_t*)0}},0,_func}}; \
+ MPFR_DEFERRED_INIT_MASTER_DECL(_func, \
+ MPFR_LOCK_INIT( (_cache)->lock), \
+ MPFR_LOCK_CLEAR((_cache)->lock)) \
+ MPFR_CACHE_ATTR mpfr_cache_t _cache = {{ \
+ {{ 0, MPFR_SIGN_POS, 0, (mp_limb_t *) 0 }}, 0, _func \
+ MPFR_DEFERRED_INIT_SLAVE_VALUE(_func) \
+ }}; \
MPFR_MAKE_VARFCT (mpfr_cache_t,_cache)
-
-
/******************************************************
- ******************* Threshold ***********************
+ *************** Threshold parameters ***************
******************************************************/
#include "mparam.h"
+
/******************************************************
- ***************** Useful macros *********************
+ ****************** Useful macros *******************
******************************************************/
/* Theses macros help the compiler to determine if a test is
likely or unlikely. The !! is necessary in case x is larger
than a long. */
-#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
-# define MPFR_LIKELY(x) (__builtin_expect(!!(x),1))
-# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x),0))
+#if defined MPFR_DEBUG_PREDICTION && __MPFR_GNUC(3,0)
+
+/* Code to debug branch prediction, based on Ulrich Drepper's paper
+ * "What Every Programmer Should Know About Memory":
+ * http://people.freebsd.org/~lstewart/articles/cpumemory.pdf
+ */
+asm (".section predict_data, \"aw\"; .previous\n"
+ ".section predict_line, \"a\"; .previous\n"
+ ".section predict_file, \"a\"; .previous");
+# if defined __x86_64__
+# define MPFR_DEBUGPRED__(e,E) \
+ ({ long _e = !!(e); \
+ asm volatile (".pushsection predict_data\n" \
+ "..predictcnt%=: .quad 0; .quad 0\n" \
+ ".section predict_line; .quad %c1\n" \
+ ".section predict_file; .quad %c2; .popsection\n" \
+ "addq $1,..predictcnt%=(,%0,8)" \
+ : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+ __builtin_expect (_e, E); \
+ })
+# elif defined __i386__
+# define MPFR_DEBUGPRED__(e,E) \
+ ({ long _e = !!(e); \
+ asm volatile (".pushsection predict_data\n" \
+ "..predictcnt%=: .long 0; .long 0\n" \
+ ".section predict_line; .long %c1\n" \
+ ".section predict_file; .long %c2; .popsection\n" \
+ "incl ..predictcnt%=(,%0,4)" \
+ : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+ __builtin_expect (_e, E); \
+ })
+# else
+# error "MPFR_DEBUGPRED__ definition missing"
+# endif
+
+# define MPFR_LIKELY(x) MPFR_DEBUGPRED__ ((x), 1)
+# define MPFR_UNLIKELY(x) MPFR_DEBUGPRED__ ((x), 0)
+
+#elif __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+
+# define MPFR_LIKELY(x) (__builtin_expect(!!(x), 1))
+# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x), 0))
+
#else
+
# define MPFR_LIKELY(x) (x)
# define MPFR_UNLIKELY(x) (x)
+
#endif
/* Declare that some variable is initialized before being used (without a
dummy initialization) in order to avoid some compiler warnings. Use the
- VAR = VAR trick (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36296)
- only with gcc as this is undefined behavior, and we don't know what
- other compilers do (they may also be smarter). This trick could be
- disabled with future gcc versions. */
-#if defined(__GNUC__)
+ VAR = VAR trick (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36296#c3)
+ only with gcc as this is undefined behavior, and we don't know what other
+ compilers do (they may also be smarter). This self-initialization trick
+ could be disabled with future gcc versions.
+ However, for clang (which defines __GNUC__), this trick must not be used
+ as it currently generates a warning, at least with:
+ Debian clang version 3.0-6.2 (tags/RELEASE_30/final) (based on LLVM 3.0)
+ __VERSION__ "4.2.1 Compatible Debian Clang 3.0 (tags/RELEASE_30/final)"
+ __clang__ 1
+ __clang_major__ 3
+ __clang_minor__ 0
+ __clang_patchlevel__ 0
+ __clang_version__ "3.0 (tags/RELEASE_30/final)"
+ (see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=705583 for this
+ problem with clang). */
+#if defined(__GNUC__) && !defined(__clang__)
# define INITIALIZED(VAR) VAR = VAR
#else
# define INITIALIZED(VAR) VAR
@@ -1099,6 +1318,16 @@ extern unsigned char *mpfr_stack;
* Computes ceil(log2(x)) only for x integer (unsigned long)
* Undefined if x is 0 */
#if __MPFR_GNUC(2,95) || __MPFR_ICC(8,1,0)
+/* Note: This macro MPFR_INT_CEIL_LOG2 shouldn't be used in an MPFR_ASSERT*
+ macro, either directly or indirectly via other macros, otherwise it can
+ yield an error due to a too large stringized expression in ASSERT_FAIL.
+ A static inline function could be a better solution than this macro. */
+/* FIXME: The current code assumes that x fits in an unsigned long
+ (used by __gmpfr_int_ceil_log2) while MPFR_INT_CEIL_LOG2 is used on
+ values that might be larger than ULONG_MAX on some platforms and/or
+ with some build options; a loop could be used if x > ULONG_MAX. If
+ the type of x is <= unsigned long, then no additional code will be
+ generated thanks to obvious compiler optimization. */
# define MPFR_INT_CEIL_LOG2(x) \
(MPFR_UNLIKELY ((x) == 1) ? 0 : \
__extension__ ({ int _b; mp_limb_t _limb; \
@@ -1108,7 +1337,8 @@ extern unsigned char *mpfr_stack;
count_leading_zeros (_b, _limb); \
(GMP_NUMB_BITS - _b); }))
#else
-# define MPFR_INT_CEIL_LOG2(x) (__gmpfr_int_ceil_log2(x))
+# define MPFR_INT_CEIL_LOG2(x) \
+ (MPFR_ASSERTN (x <= ULONG_MAX), __gmpfr_int_ceil_log2(x))
#endif
/* Add two integers with overflow handling */
@@ -1167,23 +1397,20 @@ do { \
} \
while (0)
-/* Use it only for debug reasons */
-/* MPFR_TRACE (operation) : execute operation iff DEBUG flag is set */
-/* MPFR_DUMP (x) : print x (a mpfr_t) on stdout */
-#ifdef DEBUG
-# define MPFR_TRACE(x) x
-#else
-# define MPFR_TRACE(x) (void) 0
-#endif
-#define MPFR_DUMP(x) ( printf(#x"="), mpfr_dump(x) )
-
/* Test if X (positive) is a power of 2 */
#define IS_POW2(X) (((X) & ((X) - 1)) == 0)
#define NOT_POW2(X) (((X) & ((X) - 1)) != 0)
-/* Safe absolute value (to avoid possible integer overflow) */
+/* Safe absolute value and difference (to avoid possible integer overflow) */
/* type is the target (unsigned) type */
#define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
+#define SAFE_DIFF(type,x,y) (MPFR_ASSERTD((x) >= (y)), (type)(x) - (type)(y))
+
+/* Check whether an integer type (after integer promotion) is signed.
+ This can be determined at compilation time, but unfortunately this
+ is not a constant expression, so that this cannot be used for a
+ static assertion. */
+#define IS_SIGNED(X) ((X) * 0 - 1 < 0)
#define mpfr_get_d1(x) mpfr_get_d(x,__gmpfr_default_rounding_mode)
@@ -1194,8 +1421,9 @@ do { \
mp_size_t _size; \
MPFR_ASSERTD (mpz_sgn (z) != 0); \
_size = ABSIZ(z); \
+ MPFR_ASSERTD (_size >= 1); \
count_leading_zeros (_cnt, PTR(z)[_size-1]); \
- (r) = _size * GMP_NUMB_BITS - _cnt; \
+ (r) = _size * GMP_NUMB_BITS - _cnt; \
} while (0)
/* MPFR_LCONV_DPTS can also be forced to 0 or 1 by the user. */
@@ -1250,9 +1478,15 @@ do { \
MPFR_MANT(y) = MPFR_MANT(x); \
} while (0)
+/* Size of an array, as a constant expression. */
+#define numberof_const(x) (sizeof (x) / sizeof ((x)[0]))
+
+/* Addition with carry (detected by GCC and other good compilers). */
+#define ADD_LIMB(u,v,c) ((u) += (v), (c) = (u) < (v))
+
/******************************************************
- ************** Save exponent macros ****************
+ ************ Save exponent/flags macros ************
******************************************************/
/* See README.dev for details on how to use the macros.
@@ -1260,7 +1494,7 @@ do { \
temporarily */
typedef struct {
- unsigned int saved_flags;
+ mpfr_flags_t saved_flags;
mpfr_exp_t saved_emin;
mpfr_exp_t saved_emax;
} mpfr_save_expo_t;
@@ -1285,13 +1519,13 @@ typedef struct {
/* Speed up final checking */
#define mpfr_check_range(x,t,r) \
- (MPFR_LIKELY (MPFR_EXP (x) >= __gmpfr_emin && MPFR_EXP (x) <= __gmpfr_emax) \
- ? ((t) ? (__gmpfr_flags |= MPFR_FLAGS_INEXACT, (t)) : 0) \
- : mpfr_check_range(x,t,r))
+ (MPFR_LIKELY (MPFR_EXP_IN_RANGE (MPFR_EXP (x))) \
+ ? ((t) ? (__gmpfr_flags |= MPFR_FLAGS_INEXACT, (t)) : 0) \
+ : mpfr_check_range(x,t,r))
/******************************************************
- ***************** Inline Rounding *******************
+ ***************** Inline rounding ******************
******************************************************/
/*
@@ -1305,6 +1539,10 @@ typedef struct {
* In rounding to nearest mode, execute MIDDLE_HANDLER when the value
* is the middle of two consecutive numbers in dest precision.
* Execute OVERFLOW_HANDLER in case of overflow when rounding.
+ *
+ * Note: the exponent field of dest is not used, possibly except by the
+ * handlers. It is the caller (via the handlers) who entirely decides
+ * how to handle it.
*/
#define MPFR_RNDRAW_GEN(inexact, dest, srcp, sprec, rnd, sign, \
MIDDLE_HANDLER, OVERFLOW_HANDLER) \
@@ -1316,6 +1554,8 @@ typedef struct {
/* Check Trivial Case when Dest Mantissa has more bits than source */ \
_srcprec = (sprec); \
_destprec = MPFR_PREC (dest); \
+ MPFR_ASSERTD (_srcprec >= MPFR_PREC_MIN); \
+ MPFR_ASSERTD (_destprec >= MPFR_PREC_MIN); \
_destp = MPFR_MANT (dest); \
if (MPFR_UNLIKELY (_destprec >= _srcprec)) \
{ \
@@ -1352,9 +1592,8 @@ typedef struct {
_mask = MPFR_LIMB_ONE << (_sh - 1); \
_rb = _sp[0] & _mask; \
_sb = _sp[0] & (_mask - 1); \
- if (MPFR_UNLIKELY (_sb == 0) && \
- ((rnd) == MPFR_RNDN || _rb == 0)) \
- { /* TODO: Improve it */ \
+ if ((rnd) == MPFR_RNDN || _rb == 0) \
+ { \
mp_limb_t *_tmp; \
mp_size_t _n; \
for (_tmp = _sp, _n = _srcs - _dests ; \
@@ -1369,8 +1608,7 @@ typedef struct {
/* Compute Rounding Bit and Sticky Bit - see note above */ \
_rb = _sp[-1] & MPFR_LIMB_HIGHBIT; \
_sb = _sp[-1] & (MPFR_LIMB_HIGHBIT-1); \
- if (MPFR_UNLIKELY (_sb == 0) && \
- ((rnd) == MPFR_RNDN || _rb == 0)) \
+ if ((rnd) == MPFR_RNDN || _rb == 0) \
{ \
mp_limb_t *_tmp; \
mp_size_t _n; \
@@ -1381,7 +1619,12 @@ typedef struct {
_ulp = MPFR_LIMB_ONE; \
} \
/* Rounding */ \
- if (MPFR_LIKELY (rnd == MPFR_RNDN)) \
+ if (rnd == MPFR_RNDF) \
+ { \
+ inexact = 0; \
+ goto trunc_doit; \
+ } \
+ else if (rnd == MPFR_RNDN) \
{ \
if (_rb == 0) \
{ \
@@ -1412,8 +1655,7 @@ typedef struct {
} \
else \
{ /* Directed rounding mode */ \
- if (MPFR_LIKELY (MPFR_IS_LIKE_RNDZ (rnd, \
- MPFR_IS_NEG_SIGN (sign)))) \
+ if (MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG_SIGN (sign))) \
goto trunc; \
else if (MPFR_UNLIKELY ((_sb | _rb) == 0)) \
{ \
@@ -1472,10 +1714,10 @@ typedef struct {
/* Copy the sign and the significand, and handle the exponent in exp. */
#define MPFR_SETRAW(inexact,dest,src,exp,rnd) \
- if (MPFR_UNLIKELY (dest != src)) \
+ if (dest != src) \
{ \
MPFR_SET_SIGN (dest, MPFR_SIGN (src)); \
- if (MPFR_LIKELY (MPFR_PREC (dest) == MPFR_PREC (src))) \
+ if (MPFR_PREC (dest) == MPFR_PREC (src)) \
{ \
MPN_COPY (MPFR_MANT (dest), MPFR_MANT (src), \
MPFR_LIMB_SIZE (src)); \
@@ -1547,7 +1789,7 @@ typedef struct {
if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1)) \
{ \
int _inexact; \
- mpfr_clear_flags (); \
+ MPFR_CLEAR_FLAGS (); \
_inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd)); \
if (_inexact != 0) \
{ \
@@ -1560,15 +1802,31 @@ typedef struct {
} \
} while (0)
+
/******************************************************
- *************** Ziv Loop Macro *********************
+ ***************** Ziv loop macros ******************
******************************************************/
+/* To safely increase some precision, detecting integer overflows.
+ This macro is particularly useful when determining the initial
+ working precision before Ziv's loop. P is a precision, X is an
+ arbitrary nonnegative integer.
+ Note: On 2012-02-23, the MPFR_PREC_MAX value has been decreased
+ by 256 from the maximum value representable in the mpfr_prec_t
+ type, in order to avoid some integer overflows when this macro
+ is not used (if the result is larger than MPFR_PREC_MAX, this
+ should be detected with a later assertion, e.g. in mpfr_init2).
+ But this change is mainly for existing code that has not been
+ updated yet. So, it is advised to always use MPFR_ADD_PREC if
+ the result can be larger than MPFR_PREC_MAX. */
+#define MPFR_ADD_PREC(P,X) \
+ (MPFR_ASSERTN ((X) <= MPFR_PREC_MAX - (P)), (P) + (X))
+
#ifndef MPFR_USE_LOGGING
#define MPFR_ZIV_DECL(_x) mpfr_prec_t _x
#define MPFR_ZIV_INIT(_x, _p) (_x) = GMP_NUMB_BITS
-#define MPFR_ZIV_NEXT(_x, _p) ((_p) += (_x), (_x) = (_p)/2)
+#define MPFR_ZIV_NEXT(_x, _p) ((_p) = MPFR_ADD_PREC (_p, _x), (_x) = (_p)/2)
#define MPFR_ZIV_FREE(x)
#else
@@ -1594,11 +1852,15 @@ typedef struct {
static const char *_x ## _fname = __func__; \
auto void __attribute__ ((destructor)) x ## _f (void); \
void __attribute__ ((destructor)) x ## _f (void) { \
- if (_x ## _loop != 0 && (MPFR_LOG_STAT_F & mpfr_log_type)) \
+ if (_x ## _loop != 0 && (MPFR_LOG_STAT_F & mpfr_log_type)) { \
fprintf (mpfr_log_file, \
"%s: Ziv failed %2.2f%% (%lu bad cases / %lu calls)\n", \
_x ## _fname, (double) 100.0 * _x ## _bad / _x ## _loop, \
- _x ## _bad, _x ## _loop ); }
+ _x ## _bad, _x ## _loop ); \
+ if (mpfr_log_flush) \
+ fflush (mpfr_log_file); \
+ } \
+ }
#define MPFR_ZIV_INIT(_x, _p) \
do \
@@ -1606,43 +1868,36 @@ typedef struct {
(_x) = GMP_NUMB_BITS; \
if (mpfr_log_level >= 0) \
_x ## _loop ++; \
- if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- LOG_PRINT ("%s:ZIV 1st prec=%Pd\n", \
- __func__, (mpfr_prec_t) (_p)); \
+ LOG_PRINT (MPFR_LOG_BADCASE_F, "%s:ZIV 1st prec=%Pd\n", \
+ __func__, (mpfr_prec_t) (_p)); \
} \
while (0)
#define MPFR_ZIV_NEXT(_x, _p) \
do \
{ \
- (_p) += (_x); \
+ (_p) = MPFR_ADD_PREC (_p, _x); \
(_x) = (_p) / 2; \
if (mpfr_log_level >= 0) \
_x ## _bad += (_x ## _cpt == 1); \
_x ## _cpt ++; \
- if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- LOG_PRINT ("%s:ZIV new prec=%Pd\n", \
- __func__, (mpfr_prec_t) (_p)); \
+ LOG_PRINT (MPFR_LOG_BADCASE_F, "%s:ZIV new prec=%Pd\n", \
+ __func__, (mpfr_prec_t) (_p)); \
} \
while (0)
#define MPFR_ZIV_FREE(_x) \
do \
- { \
- if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && _x ## _cpt > 1 && \
- (mpfr_log_current <= mpfr_log_level)) \
- fprintf (mpfr_log_file, "%s:ZIV %d loops\n", \
+ if (_x ## _cpt > 1) \
+ LOG_PRINT (MPFR_LOG_BADCASE_F, "%s:ZIV %d loops\n", \
__func__, _x ## _cpt); \
- } \
while (0)
#endif
/******************************************************
- *************** Logging Macros *********************
+ ****************** Logging macros ******************
******************************************************/
/* The different kind of LOG */
@@ -1669,6 +1924,7 @@ extern "C" {
#endif
__MPFR_DECLSPEC extern FILE *mpfr_log_file;
+__MPFR_DECLSPEC extern int mpfr_log_flush;
__MPFR_DECLSPEC extern int mpfr_log_type;
__MPFR_DECLSPEC extern int mpfr_log_level;
__MPFR_DECLSPEC extern int mpfr_log_current;
@@ -1680,41 +1936,34 @@ __MPFR_DECLSPEC extern mpfr_prec_t mpfr_log_prec;
/* LOG_PRINT calls mpfr_fprintf on mpfr_log_file with logging disabled
(recursive logging is not wanted and freezes MPFR). */
-#define LOG_PRINT(format, ...) \
+#define LOG_PRINT(type, format, ...) \
do \
- { \
- int old_level = mpfr_log_level; \
- mpfr_log_level = -1; /* disable logging in mpfr_fprintf */ \
- __gmpfr_cache_const_pi = __gmpfr_logging_pi; \
- __gmpfr_cache_const_log2 = __gmpfr_logging_log2; \
- mpfr_fprintf (mpfr_log_file, format, __VA_ARGS__); \
- mpfr_log_level = old_level; \
- __gmpfr_cache_const_pi = __gmpfr_normal_pi; \
- __gmpfr_cache_const_log2 = __gmpfr_normal_log2; \
- } \
+ if ((mpfr_log_type & (type)) && mpfr_log_current <= mpfr_log_level) \
+ { \
+ int old_level = mpfr_log_level; \
+ mpfr_log_level = -1; /* disable logging in mpfr_fprintf */ \
+ __gmpfr_cache_const_pi = __gmpfr_logging_pi; \
+ __gmpfr_cache_const_log2 = __gmpfr_logging_log2; \
+ mpfr_fprintf (mpfr_log_file, format, __VA_ARGS__); \
+ if (mpfr_log_flush) \
+ fflush (mpfr_log_file); \
+ mpfr_log_level = old_level; \
+ __gmpfr_cache_const_pi = __gmpfr_normal_pi; \
+ __gmpfr_cache_const_log2 = __gmpfr_normal_log2; \
+ } \
while (0)
#define MPFR_LOG_VAR(x) \
- do \
- if ((MPFR_LOG_INTERNAL_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- LOG_PRINT ("%s.%d:%s[%#Pu]=%.*Rg\n", __func__, __LINE__, \
- #x, mpfr_get_prec (x), mpfr_log_prec, x); \
- while (0)
+ LOG_PRINT (MPFR_LOG_INTERNAL_F, "%s.%d:%s[%#Pu]=%.*Rg\n", __func__, \
+ __LINE__, #x, mpfr_get_prec (x), mpfr_log_prec, x)
#define MPFR_LOG_MSG2(format, ...) \
- do \
- if ((MPFR_LOG_MSG_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- LOG_PRINT ("%s.%d: "format, __func__, __LINE__, __VA_ARGS__); \
- while (0)
+ LOG_PRINT (MPFR_LOG_MSG_F, "%s.%d: "format, __func__, __LINE__, __VA_ARGS__)
#define MPFR_LOG_MSG(x) MPFR_LOG_MSG2 x
#define MPFR_LOG_BEGIN2(format, ...) \
mpfr_log_current ++; \
- if ((MPFR_LOG_INPUT_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- LOG_PRINT ("%s:IN "format"\n", __func__, __VA_ARGS__); \
+ LOG_PRINT (MPFR_LOG_INPUT_F, "%s:IN "format"\n", __func__, __VA_ARGS__); \
if ((MPFR_LOG_TIME_F & mpfr_log_type) && \
(mpfr_log_current <= mpfr_log_level)) \
__gmpfr_log_time = mpfr_get_cputime ();
@@ -1723,13 +1972,10 @@ __MPFR_DECLSPEC extern mpfr_prec_t mpfr_log_prec;
MPFR_LOG_BEGIN2 x
#define MPFR_LOG_END2(format, ...) \
- if ((MPFR_LOG_TIME_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- fprintf (mpfr_log_file, "%s:TIM %dms\n", __mpfr_log_fname, \
+ LOG_PRINT (MPFR_LOG_TIME_F, "%s:TIM %dms\n", __mpfr_log_fname, \
mpfr_get_cputime () - __gmpfr_log_time); \
- if ((MPFR_LOG_OUTPUT_F & mpfr_log_type) && \
- (mpfr_log_current <= mpfr_log_level)) \
- LOG_PRINT ("%s:OUT "format"\n", __mpfr_log_fname, __VA_ARGS__); \
+ LOG_PRINT (MPFR_LOG_OUTPUT_F, "%s:OUT "format"\n", __mpfr_log_fname, \
+ __VA_ARGS__); \
mpfr_log_current --;
#define MPFR_LOG_END(x) \
static const char *__mpfr_log_fname = __func__; \
@@ -1777,9 +2023,9 @@ struct mpfr_group_t {
MPFR_LOG_MSG (("GROUP_CLEAR: ptr = 0x%lX, size = %lu\n", \
(unsigned long) (g).mant, \
(unsigned long) (g).alloc)); \
- if (MPFR_UNLIKELY ((g).alloc != 0)) { \
+ if ((g).alloc != 0) { \
MPFR_ASSERTD ((g).mant != (g).tab); \
- (*__gmp_free_func) ((g).mant, (g).alloc); \
+ mpfr_free_func ((g).mant, (g).alloc); \
}} while (0)
#define MPFR_GROUP_INIT_TEMPLATE(g, prec, num, handler) do { \
@@ -1789,10 +2035,10 @@ struct mpfr_group_t {
if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
mpfr_abort_prec_max (); \
_size = MPFR_PREC2LIMBS (_prec); \
- if (MPFR_UNLIKELY (_size * (num) > MPFR_GROUP_STATIC_SIZE)) \
+ if (_size * (num) > MPFR_GROUP_STATIC_SIZE) \
{ \
(g).alloc = (num) * _size * sizeof (mp_limb_t); \
- (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
+ (g).mant = (mp_limb_t *) mpfr_allocate_func ((g).alloc); \
} \
else \
{ \
@@ -1841,11 +2087,11 @@ struct mpfr_group_t {
mpfr_abort_prec_max (); \
_size = MPFR_PREC2LIMBS (_prec); \
(g).alloc = (num) * _size * sizeof (mp_limb_t); \
- if (MPFR_LIKELY (_oalloc == 0)) \
- (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
+ if (_oalloc == 0) \
+ (g).mant = (mp_limb_t *) mpfr_allocate_func ((g).alloc); \
else \
(g).mant = (mp_limb_t *) \
- (*__gmp_reallocate_func) ((g).mant, _oalloc, (g).alloc); \
+ mpfr_reallocate_func ((g).mant, _oalloc, (g).alloc); \
MPFR_LOG_MSG (("GROUP_REPREC: newptr = 0x%lX, newsize = %lu\n", \
(unsigned long) (g).mant, (unsigned long) (g).alloc)); \
handler; \
@@ -1877,141 +2123,282 @@ struct mpfr_group_t {
/******************************************************
- *************** Internal Functions *****************
+ *************** Internal functions *****************
******************************************************/
#if defined (__cplusplus)
extern "C" {
#endif
-__MPFR_DECLSPEC int mpfr_underflow _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t, int));
-__MPFR_DECLSPEC int mpfr_overflow _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t, int));
+MPFR_COLD_FUNCTION_ATTR __MPFR_DECLSPEC int
+ mpfr_underflow (mpfr_ptr, mpfr_rnd_t, int);
+MPFR_COLD_FUNCTION_ATTR __MPFR_DECLSPEC int
+ mpfr_overflow (mpfr_ptr, mpfr_rnd_t, int);
-__MPFR_DECLSPEC int mpfr_add1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_add1sp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub1sp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_can_round_raw _MPFR_PROTO ((const mp_limb_t *,
- mp_size_t, int, mpfr_exp_t, mpfr_rnd_t, mpfr_rnd_t, mpfr_prec_t));
+__MPFR_DECLSPEC int mpfr_add1 (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub1 (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_add1sp (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub1sp (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_can_round_raw (const mp_limb_t *,
+ mp_size_t, int, mpfr_exp_t, mpfr_rnd_t, mpfr_rnd_t, mpfr_prec_t);
-__MPFR_DECLSPEC int mpfr_cmp2 _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr,
- mpfr_prec_t *));
+__MPFR_DECLSPEC int mpfr_set_1_2 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t, int);
-__MPFR_DECLSPEC long __gmpfr_ceil_log2 _MPFR_PROTO ((double));
-__MPFR_DECLSPEC long __gmpfr_floor_log2 _MPFR_PROTO ((double));
-__MPFR_DECLSPEC double __gmpfr_ceil_exp2 _MPFR_PROTO ((double));
-__MPFR_DECLSPEC unsigned long __gmpfr_isqrt _MPFR_PROTO ((unsigned long));
-__MPFR_DECLSPEC unsigned long __gmpfr_cuberoot _MPFR_PROTO ((unsigned long));
-__MPFR_DECLSPEC int __gmpfr_int_ceil_log2 _MPFR_PROTO ((unsigned long));
+__MPFR_DECLSPEC int mpfr_cmp2 (mpfr_srcptr, mpfr_srcptr, mpfr_prec_t *);
-__MPFR_DECLSPEC mpfr_exp_t mpfr_ceil_mul _MPFR_PROTO ((mpfr_exp_t, int, int));
+__MPFR_DECLSPEC long __gmpfr_ceil_log2 (double);
+__MPFR_DECLSPEC long __gmpfr_floor_log2 (double);
+__MPFR_DECLSPEC double __gmpfr_ceil_exp2 (double);
+__MPFR_DECLSPEC unsigned long __gmpfr_isqrt (unsigned long);
+__MPFR_DECLSPEC unsigned long __gmpfr_cuberoot (unsigned long);
+__MPFR_DECLSPEC int __gmpfr_int_ceil_log2 (unsigned long);
-__MPFR_DECLSPEC int mpfr_exp_2 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_exp_3 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_powerof2_raw _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_ceil_mul (mpfr_exp_t, int, int);
+
+__MPFR_DECLSPEC int mpfr_exp_2 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_exp_3 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_powerof2_raw (mpfr_srcptr);
__MPFR_DECLSPEC int mpfr_powerof2_raw2 (const mp_limb_t *, mp_size_t);
-__MPFR_DECLSPEC int mpfr_pow_general _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t, int, mpfr_save_expo_t *));
+__MPFR_DECLSPEC int mpfr_pow_general (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t, int, mpfr_save_expo_t *);
-__MPFR_DECLSPEC void mpfr_setmax _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
-__MPFR_DECLSPEC void mpfr_setmin _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
+__MPFR_DECLSPEC void mpfr_setmax (mpfr_ptr, mpfr_exp_t);
+__MPFR_DECLSPEC void mpfr_setmin (mpfr_ptr, mpfr_exp_t);
-__MPFR_DECLSPEC long mpfr_mpn_exp _MPFR_PROTO ((mp_limb_t *, mpfr_exp_t *, int,
- mpfr_exp_t, size_t));
+__MPFR_DECLSPEC long mpfr_mpn_exp (mp_limb_t *, mpfr_exp_t *, int,
+ mpfr_exp_t, size_t);
#ifdef _MPFR_H_HAVE_FILE
-__MPFR_DECLSPEC void mpfr_fprint_binary _MPFR_PROTO ((FILE *, mpfr_srcptr));
+__MPFR_DECLSPEC void mpfr_fdump (FILE *, mpfr_srcptr);
#endif
-__MPFR_DECLSPEC void mpfr_print_binary _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC void mpfr_print_mant_binary _MPFR_PROTO ((const char*,
- const mp_limb_t*, mpfr_prec_t));
-__MPFR_DECLSPEC void mpfr_set_str_binary _MPFR_PROTO((mpfr_ptr, const char*));
-
-__MPFR_DECLSPEC int mpfr_round_raw _MPFR_PROTO ((mp_limb_t *,
- const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *));
-__MPFR_DECLSPEC int mpfr_round_raw_2 _MPFR_PROTO ((const mp_limb_t *,
- mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t));
+__MPFR_DECLSPEC void mpfr_print_mant_binary (const char*, const mp_limb_t*,
+ mpfr_prec_t);
+__MPFR_DECLSPEC void mpfr_set_str_binary (mpfr_ptr, const char*);
+
+__MPFR_DECLSPEC int mpfr_round_raw (mp_limb_t *,
+ const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *);
+__MPFR_DECLSPEC int mpfr_round_raw_2 (const mp_limb_t *, mpfr_prec_t, int,
+ mpfr_prec_t, mpfr_rnd_t);
/* No longer defined (see round_prec.c).
Uncomment if it needs to be defined again.
-__MPFR_DECLSPEC int mpfr_round_raw_3 _MPFR_PROTO ((const mp_limb_t *,
- mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *));
+__MPFR_DECLSPEC int mpfr_round_raw_3 (const mp_limb_t *,
+ mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *);
*/
-__MPFR_DECLSPEC int mpfr_round_raw_4 _MPFR_PROTO ((mp_limb_t *,
- const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_round_raw_4 (mp_limb_t *,
+ const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t);
#define mpfr_round_raw2(xp, xn, neg, r, prec) \
mpfr_round_raw_2((xp),(xn)*GMP_NUMB_BITS,(neg),(prec),(r))
-__MPFR_DECLSPEC int mpfr_check _MPFR_PROTO ((mpfr_srcptr));
-
-__MPFR_DECLSPEC int mpfr_sum_sort _MPFR_PROTO ((mpfr_srcptr *const,
- unsigned long, mpfr_srcptr *,
- mpfr_prec_t *));
+__MPFR_DECLSPEC int mpfr_check (mpfr_srcptr);
-__MPFR_DECLSPEC int mpfr_get_cputime _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_get_cputime (void);
-__MPFR_DECLSPEC void mpfr_nexttozero _MPFR_PROTO ((mpfr_ptr));
-__MPFR_DECLSPEC void mpfr_nexttoinf _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_nexttozero (mpfr_ptr);
+__MPFR_DECLSPEC void mpfr_nexttoinf (mpfr_ptr);
-__MPFR_DECLSPEC int mpfr_const_pi_internal _MPFR_PROTO ((mpfr_ptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_const_log2_internal _MPFR_PROTO((mpfr_ptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_const_euler_internal _MPFR_PROTO((mpfr_ptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_const_catalan_internal _MPFR_PROTO((mpfr_ptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_pi_internal (mpfr_ptr,mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_const_log2_internal (mpfr_ptr,mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_const_euler_internal (mpfr_ptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_const_catalan_internal (mpfr_ptr, mpfr_rnd_t);
#if 0
-__MPFR_DECLSPEC void mpfr_init_cache _MPFR_PROTO ((mpfr_cache_t,
- int(*)(mpfr_ptr,mpfr_rnd_t)));
+__MPFR_DECLSPEC void mpfr_init_cache (mpfr_cache_t,
+ int(*)(mpfr_ptr,mpfr_rnd_t));
#endif
-__MPFR_DECLSPEC void mpfr_clear_cache _MPFR_PROTO ((mpfr_cache_t));
-__MPFR_DECLSPEC int mpfr_cache _MPFR_PROTO ((mpfr_ptr, mpfr_cache_t,
- mpfr_rnd_t));
+__MPFR_DECLSPEC void mpfr_clear_cache (mpfr_cache_t);
+__MPFR_DECLSPEC int mpfr_cache (mpfr_ptr, mpfr_cache_t, mpfr_rnd_t);
-__MPFR_DECLSPEC void mpfr_mulhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
- mpfr_limb_srcptr, mpfr_limb_srcptr, mp_size_t));
-__MPFR_DECLSPEC void mpfr_mullow_n _MPFR_PROTO ((mpfr_limb_ptr,
- mpfr_limb_srcptr, mpfr_limb_srcptr, mp_size_t));
-__MPFR_DECLSPEC void mpfr_sqrhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
- mpfr_limb_srcptr, mp_size_t));
-__MPFR_DECLSPEC mp_limb_t mpfr_divhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
- mpfr_limb_ptr, mpfr_limb_ptr, mp_size_t));
+__MPFR_DECLSPEC void mpfr_mulhigh_n (mpfr_limb_ptr, mpfr_limb_srcptr,
+ mpfr_limb_srcptr, mp_size_t);
+__MPFR_DECLSPEC void mpfr_mullow_n (mpfr_limb_ptr, mpfr_limb_srcptr,
+ mpfr_limb_srcptr, mp_size_t);
+__MPFR_DECLSPEC void mpfr_sqrhigh_n (mpfr_limb_ptr, mpfr_limb_srcptr,
+ mp_size_t);
+__MPFR_DECLSPEC mp_limb_t mpfr_divhigh_n (mpfr_limb_ptr, mpfr_limb_ptr,
+ mpfr_limb_ptr, mp_size_t);
-__MPFR_DECLSPEC int mpfr_round_p _MPFR_PROTO ((mp_limb_t *, mp_size_t,
- mpfr_exp_t, mpfr_prec_t));
+__MPFR_DECLSPEC int mpfr_round_p (mp_limb_t *, mp_size_t, mpfr_exp_t,
+ mpfr_prec_t);
-__MPFR_DECLSPEC void mpfr_dump_mant _MPFR_PROTO ((const mp_limb_t *,
- mpfr_prec_t, mpfr_prec_t,
- mpfr_prec_t));
+__MPFR_DECLSPEC int mpfr_round_near_x (mpfr_ptr, mpfr_srcptr, mpfr_uexp_t, int,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC MPFR_COLD_FUNCTION_ATTR MPFR_NORETURN void
+ mpfr_abort_prec_max (void);
-__MPFR_DECLSPEC int mpfr_round_near_x _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_uexp_t, int,
- mpfr_rnd_t));
-__MPFR_DECLSPEC void mpfr_abort_prec_max _MPFR_PROTO ((void))
- MPFR_NORETURN_ATTR;
+__MPFR_DECLSPEC void mpfr_rand_raw (mpfr_limb_ptr, gmp_randstate_t,
+ mpfr_prec_t);
-__MPFR_DECLSPEC void mpfr_rand_raw _MPFR_PROTO((mpfr_limb_ptr, gmp_randstate_t,
- mpfr_prec_t));
+__MPFR_DECLSPEC mpz_srcptr mpfr_bernoulli_cache (unsigned long);
+__MPFR_DECLSPEC void mpfr_bernoulli_freecache (void);
-__MPFR_DECLSPEC mpz_t* mpfr_bernoulli_internal _MPFR_PROTO((mpz_t*,
- unsigned long));
+__MPFR_DECLSPEC int mpfr_sincos_fast (mpfr_t, mpfr_t, mpfr_srcptr, mpfr_rnd_t);
-__MPFR_DECLSPEC int mpfr_sincos_fast _MPFR_PROTO((mpfr_t, mpfr_t,
- mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC double mpfr_scale2 (double, int);
-__MPFR_DECLSPEC double mpfr_scale2 _MPFR_PROTO((double, int));
+__MPFR_DECLSPEC void mpfr_div_ui2 (mpfr_ptr, mpfr_srcptr, unsigned long,
+ unsigned long, mpfr_rnd_t);
-__MPFR_DECLSPEC void mpfr_div_ui2 _MPFR_PROTO((mpfr_ptr, mpfr_srcptr,
- unsigned long int, unsigned long int,
- mpfr_rnd_t));
+__MPFR_DECLSPEC void mpfr_gamma_one_and_two_third (mpfr_ptr, mpfr_ptr,
+ mpfr_prec_t);
-__MPFR_DECLSPEC void mpfr_gamma_one_and_two_third _MPFR_PROTO((mpfr_ptr, mpfr_ptr, mpfr_prec_t));
+__MPFR_DECLSPEC void mpfr_mpz_init (mpz_ptr);
+__MPFR_DECLSPEC void mpfr_mpz_init2 (mpz_t, mp_bitcnt_t);
+__MPFR_DECLSPEC void mpfr_mpz_clear (mpz_ptr);
+
+__MPFR_DECLSPEC int mpfr_odd_p (mpfr_srcptr);
+
+#ifdef _MPFR_H_HAVE_VA_LIST
+/* Declared only if <stdarg.h> has been included. */
+__MPFR_DECLSPEC int mpfr_vasnprintf_aux (char**, char*, size_t, const char*,
+ va_list);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+
+/*****************************************************
+ *************** Internal mpz_t pool ***************
+ *****************************************************/
+
+/* don't use the mpz_t pool with mini-gmp */
+#ifdef MPFR_USE_MINI_GMP
+# define MPFR_POOL_NENTRIES 0
+#endif
+
+#ifndef MPFR_POOL_NENTRIES
+# define MPFR_POOL_NENTRIES 32 /* default number of entries of the pool */
+#endif
+
+#if MPFR_POOL_NENTRIES && !defined(MPFR_POOL_DONT_REDEFINE)
+# undef mpz_init
+# undef mpz_init2
+# undef mpz_clear
+# undef mpz_init_set_ui
+# undef mpz_init_set
+# define mpz_init mpfr_mpz_init
+# define mpz_init2 mpfr_mpz_init2
+# define mpz_clear mpfr_mpz_clear
+# define mpz_init_set_ui(a,b) do { mpz_init (a); mpz_set_ui (a, b); } while (0)
+# define mpz_init_set(a,b) do { mpz_init (a); mpz_set (a, b); } while (0)
+#endif
+
+
+/******************************************************
+ ******** Compute LOG2(LOG2(MPFR_PREC_MAX)) *********
+ ******************************************************/
+
+#if _MPFR_PREC_FORMAT == 1
+# define MPFR_PREC_MAX_TEMP USHRT_MAX
+#elif _MPFR_PREC_FORMAT == 2
+# define MPFR_PREC_MAX_TEMP UINT_MAX
+#elif _MPFR_PREC_FORMAT == 3
+# define MPFR_PREC_MAX_TEMP ULONG_MAX
+#else
+# error "Invalid MPFR Prec format"
+#endif
+
+/* Note: In the constants below, it is sufficient to use the suffix U.
+ * A large enough unsigned type will be chosen automatically, but the
+ * exact type doesn't matter here.
+ */
+
+#if MPFR_PREC_MAX_TEMP == 255U
+# define MPFR_PREC_BITS 8
+# define MPFR_LOG2_PREC_BITS 3
+#elif MPFR_PREC_MAX_TEMP == 65535U
+# define MPFR_PREC_BITS 16
+# define MPFR_LOG2_PREC_BITS 4
+#elif MPFR_PREC_MAX_TEMP == 4294967295U
+# define MPFR_PREC_BITS 32
+# define MPFR_LOG2_PREC_BITS 5
+#elif MPFR_PREC_MAX_TEMP == 18446744073709551615U
+# define MPFR_PREC_BITS 64
+# define MPFR_LOG2_PREC_BITS 6
+#else
+# error "Unsupported MPFR_PREC_MAX_TEMP value"
+#endif
+
+
+/******************************************************
+ ************* Value coverage checking **************
+ ******************************************************/
+
+#ifdef MPFR_COV_CHECK
+
+/* Variable names should start with the __gmpfr_cov_ prefix. */
+
+#define MPFR_COV_SET(X) (__gmpfr_cov_ ## X = 1)
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+__MPFR_DECLSPEC extern int __gmpfr_cov_sum_tmd[MPFR_RND_MAX][2][2][3][2][2];
#if defined (__cplusplus)
}
#endif
+#else /* MPFR_COV_CHECK */
+
+#define MPFR_COV_SET(X) ((void) 0)
+
+#endif /* MPFR_COV_CHECK */
+
+
+/******************************************************
+ ***************** Unbounded Floats *****************
+ ******************************************************/
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* An UBF is like a MPFR number, but with an additional mpz_t member,
+ which is assumed to be present (with a value in it) when the usual
+ exponent field has the value MPFR_EXP_UBF. The goal of this compatible
+ representation is to easily be able to support UBF in "normal" code
+ and hopefully avoid aliasing issues at the same time. And code that
+ accepts UBF in input should also accept mpfr_t as a consequence; this
+ makes mpfr_t to UBF conversion unnecessary.
+ When an input of a public function is a UBF, the semantic remains
+ internal to MPFR and can change in the future.
+ Note that functions used for logging need to support UBF (currently
+ done by printing that a number is a UBF, as it may be difficult to
+ do more without significant changes). */
+
+typedef struct {
+ mpfr_prec_t _mpfr_prec;
+ mpfr_sign_t _mpfr_sign;
+ mpfr_exp_t _mpfr_exp;
+ mp_limb_t *_mpfr_d;
+ mpz_t _mpfr_zexp;
+} __mpfr_ubf_struct;
+
+typedef __mpfr_ubf_struct mpfr_ubf_t[1];
+typedef __mpfr_ubf_struct *mpfr_ubf_ptr;
+
+__MPFR_DECLSPEC void mpfr_ubf_mul_exact (mpfr_ubf_ptr,
+ mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_ubf_exp_less_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_ubf_zexp2exp (mpz_ptr);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_ubf_diff_exp (mpfr_srcptr, mpfr_srcptr);
+
+#if defined (__cplusplus)
+}
#endif
+
+#define MPFR_ZEXP(x) \
+ ((void) (x)->_mpfr_exp /* to check that x has a correct type */, \
+ ((mpfr_ubf_ptr) (x))->_mpfr_zexp)
+
+#define MPFR_UBF_CLEAR_EXP(x) \
+ ((void) (MPFR_IS_UBF (x) && (mpz_clear (MPFR_ZEXP (x)), 0)))
+
+#endif /* __MPFR_IMPL_H__ */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-intmax.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-intmax.h
index a51031aec81..6cffccc54cd 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-intmax.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-intmax.h
@@ -24,17 +24,47 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define __MPFR_INTMAX_H__
/* The ISO C99 standard specifies that in C++ implementations the
- INTMAX_MAX, ... macros should only be defined if explicitly requested. */
+ * INTMAX_MAX, ... macros should only be defined if explicitly requested.
+ */
#if defined __cplusplus
# define __STDC_LIMIT_MACROS
# define __STDC_CONSTANT_MACROS
#endif
+/* The definition of MPFR_USE_INTMAX_T is needed on systems for which
+ * the current (non-standard) macro tests in mpfr.h is not sufficient.
+ * This will force the support of intmax_t/uintmax_t if <inttypes.h>
+ * and/or <stdint.h> are available. This also avoids a failure in the
+ * tests (replace the macro tests in mpfr.h by just
+ * #if defined (MPFR_USE_INTMAX_T)
+ * to simulate such a system and reproduce the problem).
+ * Note: if this makes the build fail on some systems (because these
+ * headers are broken), we will need a configure test to undefine
+ * HAVE_INTTYPES_H and HAVE_STDINT_H in such a case.
+ */
+
#if HAVE_INTTYPES_H
# include <inttypes.h>
+# define MPFR_USE_INTMAX_T
#endif
+
#if HAVE_STDINT_H
# include <stdint.h>
+# define MPFR_USE_INTMAX_T
+#endif
+
+/* Largest signed integer type available for the MPFR build. */
+#if defined(MPFR_USE_INTMAX_T)
+typedef intmax_t mpfr_intmax_t;
+typedef uintmax_t mpfr_uintmax_t;
+#elif defined(HAVE_LONG_LONG)
+typedef long long mpfr_intmax_t;
+typedef unsigned long long mpfr_uintmax_t;
+# define MPFR_INTMAX_MAX LLONG_MAX
+#else
+typedef long mpfr_intmax_t;
+typedef unsigned long mpfr_uintmax_t;
+# define MPFR_INTMAX_MAX LONG_MAX
#endif
#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-longlong.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-longlong.h
index 5b9cca411d4..2fabb40d794 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-longlong.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-longlong.h
@@ -1,36 +1,48 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
-Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
-2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2013-2017 Free Software Foundation, Inc.
+Copyright 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2017 Free Software Foundation, Inc.
-This file is free software; you can redistribute it and/or modify it under the
-terms of the GNU Lesser General Public License as published by the Free
-Software Foundation; either version 3 of the License, or (at your option) any
-later version.
+This file is part of the GNU MPFR Library and has been copied from
+GNU MP 6.1.0 (the FIXME's come from GNU MP), except the parts marked
+beginning of code specific to MPFR ... end of code specific to MPFR.
-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 Lesser General Public License for more
-details.
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
You should have received a copy of the GNU Lesser General Public License
-along with this file. If not, see http://www.gnu.org/licenses/. */
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
/* You have to define the following before including this file:
UWtype -- An unsigned type, default type for operations (typically a "word")
- UHWtype -- An unsigned type, at least half the size of UWtype.
+ UHWtype -- An unsigned type, at least half the size of UWtype
UDWtype -- An unsigned type, at least twice as large a UWtype
W_TYPE_SIZE -- size in bits of UWtype
- SItype, USItype -- Signed and unsigned 32 bit types.
- DItype, UDItype -- Signed and unsigned 64 bit types.
+ SItype, USItype -- Signed and unsigned 32 bit types
+ DItype, UDItype -- Signed and unsigned 64 bit types
On a 32 bit machine UWtype should typically be USItype;
on a 64 bit machine, UWtype should typically be UDItype.
- CAUTION! Using this file outside of GMP is not safe. You need to include
- gmp.h and gmp-impl.h, or certain things might not work as expected.
+ Optionally, define:
+
+ LONGLONG_STANDALONE -- Avoid code that needs machine-dependent support files
+ NO_ASM -- Disable inline asm
+
+
+ CAUTION! Using this version of longlong.h outside of GMP is not safe. You
+ need to include gmp.h and gmp-impl.h, or certain things might not work as
+ expected.
*/
#define __BITS4 (W_TYPE_SIZE / 4)
@@ -44,14 +56,6 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
#define __MPN(x) __##x
#endif
-#ifndef _PROTO
-#if (__STDC__-0) || defined (__cplusplus)
-#define _PROTO(x) x
-#else
-#define _PROTO(x) ()
-#endif
-#endif
-
/* Define auxiliary asm macros.
1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
@@ -71,7 +75,7 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
denominator). Like udiv_qrnnd but the numbers are signed. The quotient
- is rounded toward 0.
+ is rounded towards 0.
5) count_leading_zeros(count, x) counts the number of zero-bits from the
msb to the first non-zero bit in the UWtype X. This is the number of
@@ -140,35 +144,34 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
or want. */
#ifdef _LONG_LONG_LIMB
-#define count_leading_zeros_gcc_clz(count,x) \
- do { \
- ASSERT ((x) != 0); \
- (count) = __builtin_clzll (x); \
+#define count_leading_zeros_gcc_clz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_clzll (x); \
} while (0)
#else
-#define count_leading_zeros_gcc_clz(count,x) \
- do { \
- ASSERT ((x) != 0); \
- (count) = __builtin_clzl (x); \
+#define count_leading_zeros_gcc_clz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_clzl (x); \
} while (0)
#endif
#ifdef _LONG_LONG_LIMB
-#define count_trailing_zeros_gcc_ctz(count,x) \
- do { \
- ASSERT ((x) != 0); \
- (count) = __builtin_ctzll (x); \
+#define count_trailing_zeros_gcc_ctz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_ctzll (x); \
} while (0)
#else
-#define count_trailing_zeros_gcc_ctz(count,x) \
- do { \
- ASSERT ((x) != 0); \
- (count) = __builtin_ctzl (x); \
+#define count_trailing_zeros_gcc_ctz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_ctzl (x); \
} while (0)
#endif
-/* Note: the following FIXME comes from GMP, thus it does make sense to try
- to resolve it in MPFR. */
+
/* FIXME: The macros using external routines like __MPN(count_leading_zeros)
don't need to be under !NO_ASM */
#if ! defined (NO_ASM)
@@ -189,7 +192,7 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
UDItype __m0 = (m0), __m1 = (m1); \
__asm__ ("umulh %r1,%2,%0" \
: "=r" (ph) \
- : "%rJ" (m0), "rI" (m1)); \
+ : "%rJ" (__m0), "rI" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#endif
@@ -199,7 +202,7 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- (ph) = __UMULH (m0, m1); \
+ (ph) = __UMULH (__m0, __m1); \
(pl) = __m0 * __m1; \
} while (0)
#endif
@@ -225,55 +228,64 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
__asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
#endif /* clz/ctz using cix */
-#if ! defined (count_leading_zeros) \
+#if ! defined (count_leading_zeros) \
&& defined (__GNUC__) && ! defined (LONGLONG_STANDALONE)
/* ALPHA_CMPBGE_0 gives "cmpbge $31,src,dst", ie. test src bytes == 0.
"$31" is written explicitly in the asm, since an "r" constraint won't
select reg 31. There seems no need to worry about "r31" syntax for cray,
- since gcc itself (pre-release 3.4) emits just $31 in various places. */
-#define ALPHA_CMPBGE_0(dst, src) \
+ since gcc itself (pre-release 3.4) emits just $31 in various places. */
+#define ALPHA_CMPBGE_0(dst, src) \
do { asm ("cmpbge $31, %1, %0" : "=r" (dst) : "r" (src)); } while (0)
/* Zero bytes are turned into bits with cmpbge, a __clz_tab lookup counts
them, locating the highest non-zero byte. A second __clz_tab lookup
counts the leading zero bits in that byte, giving the result. */
-#define count_leading_zeros(count, x) \
- do { \
- UWtype __clz__b, __clz__c, __clz__x = (x); \
- ALPHA_CMPBGE_0 (__clz__b, __clz__x); /* zero bytes */ \
- __clz__b = __clz_tab [(__clz__b >> 1) ^ 0x7F]; /* 8 to 1 byte */ \
- __clz__b = __clz__b * 8 - 7; /* 57 to 1 shift */ \
- __clz__x >>= __clz__b; \
- __clz__c = __clz_tab [__clz__x]; /* 8 to 1 bit */ \
- __clz__b = 65 - __clz__b; \
- (count) = __clz__b - __clz__c; \
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __clz__b, __clz__c, __clz__x = (x); \
+ ALPHA_CMPBGE_0 (__clz__b, __clz__x); /* zero bytes */ \
+ __clz__b = __clz_tab [(__clz__b >> 1) ^ 0x7F]; /* 8 to 1 byte */ \
+ __clz__b = __clz__b * 8 - 7; /* 57 to 1 shift */ \
+ __clz__x >>= __clz__b; \
+ __clz__c = __clz_tab [__clz__x]; /* 8 to 1 bit */ \
+ __clz__b = 65 - __clz__b; \
+ (count) = __clz__b - __clz__c; \
} while (0)
#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
#endif /* clz using cmpbge */
#if ! defined (count_leading_zeros) && ! defined (LONGLONG_STANDALONE)
#if HAVE_ATTRIBUTE_CONST
-long __MPN(count_leading_zeros) _PROTO ((UDItype)) __attribute__ ((const));
+long __MPN(count_leading_zeros) (UDItype) __attribute__ ((const));
#else
-long __MPN(count_leading_zeros) _PROTO ((UDItype));
+long __MPN(count_leading_zeros) (UDItype);
#endif
#define count_leading_zeros(count, x) \
((count) = __MPN(count_leading_zeros) (x))
#endif /* clz using mpn */
#endif /* __alpha */
+#if defined (__AVR) && W_TYPE_SIZE == 8
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ unsigned short __p = (unsigned short) (m0) * (m1); \
+ (ph) = __p >> 8; \
+ (pl) = __p; \
+ } while (0)
+#endif /* AVR */
+
#if defined (_CRAY) && W_TYPE_SIZE == 64
#include <intrinsics.h>
#define UDIV_PREINV_ALWAYS 1
#define UDIV_NEEDS_NORMALIZATION 1
#define UDIV_TIME 220
-long __MPN(count_leading_zeros) _PROTO ((UDItype));
+long __MPN(count_leading_zeros) (UDItype);
#define count_leading_zeros(count, x) \
((count) = _leadz ((UWtype) (x)))
#if defined (_CRAYIEEE) /* I.e., Cray T90/ieee, T3D, and T3E */
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- (ph) = _int_mult_upper (m0, m1); \
+ (ph) = _int_mult_upper (__m0, __m1); \
(pl) = __m0 * __m1; \
} while (0)
#ifndef LONGLONG_STANDALONE
@@ -292,14 +304,14 @@ long __MPN(count_leading_zeros) _PROTO ((UDItype));
code using "al<bl" arithmetically comes out making an actual 0 or 1 in a
register, which takes an extra cycle. */
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- do { \
- UWtype __x; \
- __x = (al) - (bl); \
- if ((al) < (bl)) \
- (sh) = (ah) - (bh) - 1; \
- else \
- (sh) = (ah) - (bh); \
- (sl) = __x; \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ if ((al) < (bl)) \
+ (sh) = (ah) - (bh) - 1; \
+ else \
+ (sh) = (ah) - (bh); \
+ (sl) = __x; \
} while (0)
#if defined (__GNUC__) && ! defined (__INTEL_COMPILER)
/* Do both product parts in assembly, since that gives better code with
@@ -338,9 +350,9 @@ long __MPN(count_leading_zeros) _PROTO ((UDItype));
#include <ia64intrin.h>
#define umul_ppmm(ph, pl, m0, m1) \
do { \
- UWtype _m0 = (m0), _m1 = (m1); \
- ph = _m64_xmahu (_m0, _m1, 0); \
- pl = _m0 * _m1; \
+ UWtype __m0 = (m0), __m1 = (m1); \
+ ph = _m64_xmahu (__m0, __m1, 0); \
+ pl = __m0 * __m1; \
} while (0)
#endif
#ifndef LONGLONG_STANDALONE
@@ -417,7 +429,8 @@ long __MPN(count_leading_zeros) _PROTO ((UDItype));
"rIJ" ((USItype) (bl)))
#endif
-#if defined (__arm__) && W_TYPE_SIZE == 32
+#if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \
+ && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
: "=r" (sh), "=&r" (sl) \
@@ -462,7 +475,37 @@ long __MPN(count_leading_zeros) _PROTO ((UDItype));
: "=r" (sh), "=&r" (sl) \
: "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC);\
} while (0)
-#if 1 || defined (__arm_m__) /* `M' series has widening multiply support */
+#if defined (__ARM_ARCH_2__) || defined (__ARM_ARCH_2A__) \
+ || defined (__ARM_ARCH_3__)
+#define umul_ppmm(xh, xl, a, b) \
+ do { \
+ register USItype __t0, __t1, __t2; \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ " mov %2, %5, lsr #16\n" \
+ " mov %0, %6, lsr #16\n" \
+ " bic %3, %5, %2, lsl #16\n" \
+ " bic %4, %6, %0, lsl #16\n" \
+ " mul %1, %3, %4\n" \
+ " mul %4, %2, %4\n" \
+ " mul %3, %0, %3\n" \
+ " mul %0, %2, %0\n" \
+ " adds %3, %4, %3\n" \
+ " addcs %0, %0, #65536\n" \
+ " adds %1, %1, %3, lsl #16\n" \
+ " adc %0, %0, %3, lsr #16" \
+ : "=&r" ((USItype) (xh)), "=r" ((USItype) (xl)), \
+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
+ : "r" ((USItype) (a)), "r" ((USItype) (b)) __CLOBBER_CC); \
+ } while (0)
+#define UMUL_TIME 20
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __r; \
+ (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
+#define UDIV_TIME 200
+#else /* ARMv4 or newer */
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("umull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b))
#define UMUL_TIME 5
@@ -478,37 +521,36 @@ long __MPN(count_leading_zeros) _PROTO ((UDItype));
#define UDIV_NEEDS_NORMALIZATION 1
#define UDIV_TIME 70
#endif /* LONGLONG_STANDALONE */
-#else
-#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("%@ Inlined umul_ppmm\n" \
-" mov %|r0, %2, lsr #16\n" \
-" mov %|r2, %3, lsr #16\n" \
-" bic %|r1, %2, %|r0, lsl #16\n" \
-" bic %|r2, %3, %|r2, lsl #16\n" \
-" mul %1, %|r1, %|r2\n" \
-" mul %|r2, %|r0, %|r2\n" \
-" mul %|r1, %0, %|r1\n" \
-" mul %0, %|r0, %0\n" \
-" adds %|r1, %|r2, %|r1\n" \
-" addcs %0, %0, #65536\n" \
-" adds %1, %1, %|r1, lsl #16\n" \
-" adc %0, %0, %|r1, lsr #16" \
- : "=&r" (xh), "=r" (xl) \
- : "r" (a), "r" (b) \
- : "r0", "r1", "r2")
-#define UMUL_TIME 20
-#ifndef LONGLONG_STANDALONE
-#define udiv_qrnnd(q, r, n1, n0, d) \
- do { UWtype __r; \
- (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
- (r) = __r; \
- } while (0)
-extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
-#define UDIV_TIME 200
-#endif /* LONGLONG_STANDALONE */
-#endif
+#endif /* defined(__ARM_ARCH_2__) ... */
+#define count_leading_zeros(count, x) count_leading_zeros_gcc_clz(count, x)
+#define count_trailing_zeros(count, x) count_trailing_zeros_gcc_ctz(count, x)
+#define COUNT_LEADING_ZEROS_0 32
#endif /* __arm__ */
+#if defined (__aarch64__) && W_TYPE_SIZE == 64
+/* FIXME: Extend the immediate range for the low word by using both
+ ADDS and SUBS, since they set carry in the same way. */
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
+ : "=r,r" (sh), "=&r,&r" (sl) \
+ : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
+ "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh\t%0, %1, %2" : "=r" (ph) : "r" (__m0), "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define count_leading_zeros(count, x) count_leading_zeros_gcc_clz(count, x)
+#define count_trailing_zeros(count, x) count_trailing_zeros_gcc_ctz(count, x)
+#define COUNT_LEADING_ZEROS_0 64
+#endif /* __aarch64__ */
+
#if defined (__clipper__) && W_TYPE_SIZE == 32
#define umul_ppmm(w1, w0, u, v) \
({union {UDItype __ll; \
@@ -642,29 +684,176 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
#endif /* hppa */
#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
-#define smul_ppmm(xh, xl, m0, m1) \
+#if defined (__zarch__) || defined (HAVE_HOST_CPU_s390_zarch)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+/* if (__builtin_constant_p (bl)) \
+ __asm__ ("alfi\t%1,%o5\n\talcr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "%1" (al), "n" (bl) __CLOBBER_CC);\
+ else \
+*/ __asm__ ("alr\t%1,%5\n\talcr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "%1" (al), "r" (bl)__CLOBBER_CC); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+/* if (__builtin_constant_p (bl)) \
+ __asm__ ("slfi\t%1,%o5\n\tslbr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "1" (al), "n" (bl) __CLOBBER_CC); \
+ else \
+*/ __asm__ ("slr\t%1,%5\n\tslbr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "1" (al), "r" (bl) __CLOBBER_CC); \
+ } while (0)
+#if __GMP_GNUC_PREREQ (4,5)
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __x.__ll = (UDItype) (m0) * (UDItype) (m1); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#else
+#if 0
+/* FIXME: this fails if gcc knows about the 64-bit registers. Use only
+ with a new enough processor pretending we have 32-bit registers. */
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mlr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "%0" (m0), "r" (m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#else
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ /* When we have 64-bit regs and gcc is aware of that, we cannot simply use
+ DImode for the product, since that would be allocated to a single 64-bit
+ register, whereas mlr uses the low 32-bits of an even-odd register pair.
+ */ \
+ register USItype __r0 __asm__ ("0"); \
+ register USItype __r1 __asm__ ("1") = (m0); \
+ __asm__ ("mlr\t%0,%3" \
+ : "=r" (__r0), "=r" (__r1) \
+ : "r" (__r1), "r" (m1)); \
+ (xh) = __r0; (xl) = __r1; \
+ } while (0)
+#endif /* if 0 */
+#endif
+#if 0
+/* FIXME: this fails if gcc knows about the 64-bit registers. Use only
+ with a new enough processor pretending we have 32-bit registers. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("dlr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "0" (__x.__ll), "r" (d)); \
+ (q) = __x.__i.__l; (r) = __x.__i.__h; \
+ } while (0)
+#else
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ register USItype __r0 __asm__ ("0") = (n1); \
+ register USItype __r1 __asm__ ("1") = (n0); \
+ __asm__ ("dlr\t%0,%4" \
+ : "=r" (__r0), "=r" (__r1) \
+ : "r" (__r0), "r" (__r1), "r" (d)); \
+ (q) = __r1; (r) = __r0; \
+ } while (0)
+#endif /* if 0 */
+#else /* if __zarch__ */
+/* FIXME: this fails if gcc knows about the 64-bit registers. */
+#define smul_ppmm(xh, xl, m0, m1) \
do { \
union {DItype __ll; \
struct {USItype __h, __l;} __i; \
} __x; \
- __asm__ ("lr %N0,%1\n\tmr %0,%2" \
- : "=&r" (__x.__ll) \
- : "r" (m0), "r" (m1)); \
+ __asm__ ("mr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "%0" (m0), "r" (m1)); \
(xh) = __x.__i.__h; (xl) = __x.__i.__l; \
} while (0)
-#define sdiv_qrnnd(q, r, n1, n0, d) \
+/* FIXME: this fails if gcc knows about the 64-bit registers. */
+#define sdiv_qrnnd(q, r, n1, n0, d) \
do { \
union {DItype __ll; \
struct {USItype __h, __l;} __i; \
} __x; \
__x.__i.__h = n1; __x.__i.__l = n0; \
- __asm__ ("dr %0,%2" \
+ __asm__ ("dr\t%0,%2" \
: "=r" (__x.__ll) \
: "0" (__x.__ll), "r" (d)); \
(q) = __x.__i.__l; (r) = __x.__i.__h; \
} while (0)
+#endif /* if __zarch__ */
#endif
+#if defined (__s390x__) && W_TYPE_SIZE == 64
+/* We need to cast operands with register constraints, otherwise their types
+ will be assumed to be SImode by gcc. For these machines, such operations
+ will insert a value into the low 32 bits, and leave the high 32 bits with
+ garbage. */
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ __asm__ ("algr\t%1,%5\n\talcgr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "%1" ((UDItype)(al)), "r" ((UDItype)(bl)) __CLOBBER_CC); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ __asm__ ("slgr\t%1,%5\n\tslbgr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), "r" ((UDItype)(bl)) __CLOBBER_CC); \
+ } while (0)
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {unsigned int __attribute__ ((mode(TI))) __ll; \
+ struct {UDItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mlgr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "%0" ((UDItype)(m0)), "r" ((UDItype)(m1))); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {unsigned int __attribute__ ((mode(TI))) __ll; \
+ struct {UDItype __h, __l;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("dlgr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "0" (__x.__ll), "r" ((UDItype)(d))); \
+ (q) = __x.__i.__l; (r) = __x.__i.__h; \
+ } while (0)
+#if 0 /* FIXME: Enable for z10 (?) */
+#define count_leading_zeros(cnt, x) \
+ do { \
+ union {unsigned int __attribute__ ((mode(TI))) __ll; \
+ struct {UDItype __h, __l;} __i; \
+ } __clr_cnt; \
+ __asm__ ("flogr\t%0,%1" \
+ : "=r" (__clr_cnt.__ll) \
+ : "r" (x) __CLOBBER_CC); \
+ (cnt) = __clr_cnt.__i.__h; \
+ } while (0)
+#endif
+#endif
+
+/* On x86 and x86_64, every asm implicitly clobbers "flags" and "fpsr",
+ so we don't need __CLOBBER_CC. */
#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl %5,%k1\n\tadcl %3,%k0" \
@@ -759,7 +948,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
being 1 code byte smaller. "31-__cbtmp" is a workaround, probably at the
cost of one extra instruction. Do this for "i386" too, since that means
generic x86. */
-#if ! defined (count_leading_zeros) && __GNUC__ < 3 \
+#if ! defined (count_leading_zeros) && __GNUC__ < 3 \
&& (HAVE_HOST_CPU_i386 \
|| HAVE_HOST_CPU_i686 \
|| HAVE_HOST_CPU_pentiumpro \
@@ -840,7 +1029,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
ASSERT ((x) != 0); \
__asm__ ("bsfq %1,%q0" : "=r" (count) : "rm" ((UDItype)(x))); \
} while (0)
-#endif /* x86_64 */
+#endif /* __amd64__ */
#if defined (__i860__) && W_TYPE_SIZE == 32
#define rshift_rhlc(r,h,l,c) \
@@ -969,7 +1158,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
|| defined (__mc68030__) || defined (mc68030) \
|| defined (__mc68040__) || defined (mc68040) \
|| defined (__mc68060__) || defined (mc68060) \
- || defined (__NeXT__)) \
+ || defined (__NeXT__)) \
&& ! defined (__mcpu32__)
#define count_leading_zeros(count, x) \
__asm__ ("bfffo %1{%b2:%b2},%0" \
@@ -1030,7 +1219,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
w0 = __ll; \
} while (0)
#endif
-#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7) && !defined (__clang__)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
#endif
@@ -1053,14 +1242,17 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
w0 = __ll; \
} while (0)
#endif
-#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7) && !defined (__clang__)
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("dmultu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
+ __asm__ ("dmultu %2,%3" \
+ : "=l" (w0), "=h" (w1) \
+ : "d" ((UDItype)(u)), "d" ((UDItype)(v)))
#endif
#if !defined (umul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("dmultu %2,%3\n\tmflo %0\n\tmfhi %1" \
- : "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
+ : "=d" (w0), "=d" (w1) \
+ : "d" ((UDItype)(u)), "d" ((UDItype)(v)))
#endif
#define UMUL_TIME 20
#define UDIV_TIME 140
@@ -1122,42 +1314,42 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
the system vendor compilers. (Is that vendor compilers with inline asm,
or what?) */
-#if (HAVE_HOST_CPU_FAMILY_power || HAVE_HOST_CPU_FAMILY_powerpc) \
+#if (HAVE_HOST_CPU_FAMILY_power || HAVE_HOST_CPU_FAMILY_powerpc) \
&& W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
do { \
if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
else \
- __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \
: "=r" (sh), "=&r" (sl) \
: "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
} while (0)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
: "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
: "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
: "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
: "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
else \
- __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
: "=r" (sh), "=&r" (sl) \
: "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
} while (0)
#define count_leading_zeros(count, x) \
- __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
+ __asm__ ("cntlzw %0,%1" : "=r" (count) : "r" (x))
#define COUNT_LEADING_ZEROS_0 32
#if HAVE_HOST_CPU_FAMILY_powerpc
#if __GMP_GNUC_PREREQ (4,4)
@@ -1205,61 +1397,84 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
do { \
if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl))); \
else \
- __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl))); \
} while (0)
/* We use "*rI" for the constant operand here, since with just "I", gcc barfs.
This might seem strange, but gcc folds away the dead code late. */
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (bl) && bl > -0x8000 && bl <= 0x8000) { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("{ai|addic} %1,%3,%4\n\t{sfze|subfze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
- else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
- __asm__ ("{ai|addic} %1,%3,%4\n\t{sfme|subfme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
- else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{ai|addic} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
- else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("{ai|addic} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
- else \
- __asm__ ("{ai|addic} %1,%4,%5\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "rI" (al), "*rI" (-bl)); \
- } else { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
- else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
- else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
- else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
- else \
- __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
- } \
+ do { \
+ if (__builtin_constant_p (bl) && bl > -0x8000 && bl <= 0x8000) { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("addic %1,%3,%4\n\tsubfze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("addic %1,%3,%4\n\tsubfme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("addic %1,%3,%4\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("addic %1,%3,%4\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
+ else \
+ __asm__ ("addic %1,%4,%5\n\tsubfe %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
+ } else { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
+ else \
+ __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
+ } \
} while (0)
#endif /* ! _LONG_LONG_LIMB */
#define count_leading_zeros(count, x) \
__asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
#define COUNT_LEADING_ZEROS_0 64
-#if __GMP_GNUC_PREREQ (4,4)
+#if 0 && __GMP_GNUC_PREREQ (4,4) /* Disable, this results in libcalls! */
#define umul_ppmm(w1, w0, u, v) \
do { \
typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
@@ -1272,7 +1487,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (__m0), "r" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#endif
@@ -1280,7 +1495,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
#define smul_ppmm(ph, pl, m0, m1) \
do { \
DItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (__m0), "r" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#define SMUL_TIME 14 /* ??? */
@@ -1361,7 +1576,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
} while (0)
#endif /* RT/ROMP */
-#if defined (__sh2__) && W_TYPE_SIZE == 32
+#if (defined (__SH2__) || defined (__SH3__) || defined (__SH4__)) && W_TYPE_SIZE == 32
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \
: "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "macl", "mach")
@@ -1379,8 +1594,6 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
: "=r" (sh), "=&r" (sl) \
: "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl) \
__CLOBBER_CC)
-/* Note: the following FIXME comes from GMP, thus it does make sense to try
- to resolve it in MPFR. */
/* FIXME: When gcc -mcpu=v9 is used on solaris, gcc/config/sol2-sld-64.h
doesn't define anything to indicate that to us, it only sets __sparcv8. */
#if defined (__sparc_v9__) || defined (__sparcv9)
@@ -1545,7 +1758,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
(q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
(r) = __r; \
} while (0)
-extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
+extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
#ifndef UDIV_TIME
#define UDIV_TIME 140
#endif
@@ -1559,22 +1772,46 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
"addcc %r4,%5,%1\n" \
" addccc %r6,%7,%%g0\n" \
" addc %r2,%3,%0" \
- : "=r" (sh), "=&r" (sl) \
- : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl), \
- "%rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" ((UDItype)(ah)), "rI" ((UDItype)(bh)), \
+ "%rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)), \
+ "%rJ" ((UDItype)(al) >> 32), "rI" ((UDItype)(bl) >> 32) \
__CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ( \
"subcc %r4,%5,%1\n" \
" subccc %r6,%7,%%g0\n" \
" subc %r2,%3,%0" \
- : "=r" (sh), "=&r" (sl) \
- : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl), \
- "rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" ((UDItype)(ah)), "rI" ((UDItype)(bh)), \
+ "rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)), \
+ "rJ" ((UDItype)(al) >> 32), "rI" ((UDItype)(bl) >> 32) \
__CLOBBER_CC)
+#if __VIS__ >= 0x300
+#undef add_ssaaaa
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ( \
+ "addcc %r4, %5, %1\n" \
+ " addxc %r2, %r3, %0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" ((UDItype)(ah)), "rJ" ((UDItype)(bh)), \
+ "%rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (pl) = __m0 * __m1; \
+ __asm__ ("umulxhi\t%2, %1, %0" \
+ : "=r" (ph) \
+ : "%r" (__m0), "r" (__m1)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("lzd\t%1,%0" : "=r" (count) : "r" (x))
+/* Needed by count_leading_zeros_32 in sparc64.h. */
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif
#endif
-#if defined (__vax__) && W_TYPE_SIZE == 32
+#if (defined (__vax) || defined (__vax__)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl2 %5,%1\n\tadwc %3,%0" \
: "=g" (sh), "=&g" (sl) \
@@ -1605,8 +1842,6 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
: "=g" (q), "=g" (r) : "g" (__x.__ll), "g" (d)); \
} while (0)
#if 0
-/* Note: the following FIXME comes from GMP, thus it does make sense to try
- to resolve it in MPFR. */
/* FIXME: This instruction appears to be unimplemented on some systems (vax
8800 maybe). */
#define count_trailing_zeros(count,x) \
@@ -1616,7 +1851,7 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
: "g" ((USItype) (x))); \
} while (0)
#endif
-#endif /* __vax__ */
+#endif /* vax */
#if defined (__z8000__) && W_TYPE_SIZE == 16
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
@@ -1649,13 +1884,14 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
#endif /* NO_ASM */
+/* FIXME: "sidi" here is highly doubtful, should sometimes be "diti". */
#if !defined (umul_ppmm) && defined (__umulsidi3)
#define umul_ppmm(ph, pl, m0, m1) \
- { \
+ do { \
UDWtype __ll = __umulsidi3 (m0, m1); \
ph = (UWtype) (__ll >> W_TYPE_SIZE); \
pl = (UWtype) __ll; \
- }
+ } while (0)
#endif
#if !defined (__umulsidi3)
@@ -1666,62 +1902,68 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
#endif
+#if defined (__cplusplus)
+#define __longlong_h_C "C"
+#else
+#define __longlong_h_C
+#endif
+
/* Use mpn_umul_ppmm or mpn_udiv_qrnnd functions, if they exist. The "_r"
forms have "reversed" arguments, meaning the pointer is last, which
sometimes allows better parameter passing, in particular on 64-bit
hppa. */
#define mpn_umul_ppmm __MPN(umul_ppmm)
-extern UWtype mpn_umul_ppmm _PROTO ((UWtype *, UWtype, UWtype));
+extern __longlong_h_C UWtype mpn_umul_ppmm (UWtype *, UWtype, UWtype);
#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm \
&& ! defined (LONGLONG_STANDALONE)
-#define umul_ppmm(wh, wl, u, v) \
- do { \
- UWtype __umul_ppmm__p0; \
- (wh) = mpn_umul_ppmm (&__umul_ppmm__p0, (UWtype) (u), (UWtype) (v)); \
- (wl) = __umul_ppmm__p0; \
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UWtype __umul_ppmm__p0; \
+ (wh) = mpn_umul_ppmm (&__umul_ppmm__p0, (UWtype) (u), (UWtype) (v));\
+ (wl) = __umul_ppmm__p0; \
} while (0)
#endif
#define mpn_umul_ppmm_r __MPN(umul_ppmm_r)
-extern UWtype mpn_umul_ppmm_r _PROTO ((UWtype, UWtype, UWtype *));
+extern __longlong_h_C UWtype mpn_umul_ppmm_r (UWtype, UWtype, UWtype *);
#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm_r \
&& ! defined (LONGLONG_STANDALONE)
-#define umul_ppmm(wh, wl, u, v) \
- do { \
- UWtype __umul_ppmm__p0; \
- (wh) = mpn_umul_ppmm_r ((UWtype) (u), (UWtype) (v), &__umul_ppmm__p0); \
- (wl) = __umul_ppmm__p0; \
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UWtype __umul_p0; \
+ (wh) = mpn_umul_ppmm_r ((UWtype) (u), (UWtype) (v), &__umul_p0); \
+ (wl) = __umul_p0; \
} while (0)
#endif
#define mpn_udiv_qrnnd __MPN(udiv_qrnnd)
-extern UWtype mpn_udiv_qrnnd _PROTO ((UWtype *, UWtype, UWtype, UWtype));
+extern __longlong_h_C UWtype mpn_udiv_qrnnd (UWtype *, UWtype, UWtype, UWtype);
#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd \
&& ! defined (LONGLONG_STANDALONE)
#define udiv_qrnnd(q, r, n1, n0, d) \
do { \
- UWtype __udiv_qrnnd__r; \
- (q) = mpn_udiv_qrnnd (&__udiv_qrnnd__r, \
+ UWtype __udiv_qrnnd_r; \
+ (q) = mpn_udiv_qrnnd (&__udiv_qrnnd_r, \
(UWtype) (n1), (UWtype) (n0), (UWtype) d); \
- (r) = __udiv_qrnnd__r; \
+ (r) = __udiv_qrnnd_r; \
} while (0)
#endif
#define mpn_udiv_qrnnd_r __MPN(udiv_qrnnd_r)
-extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
+extern __longlong_h_C UWtype mpn_udiv_qrnnd_r (UWtype, UWtype, UWtype, UWtype *);
#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd_r \
&& ! defined (LONGLONG_STANDALONE)
#define udiv_qrnnd(q, r, n1, n0, d) \
do { \
- UWtype __udiv_qrnnd__r; \
+ UWtype __udiv_qrnnd_r; \
(q) = mpn_udiv_qrnnd_r ((UWtype) (n1), (UWtype) (n0), (UWtype) d, \
- &__udiv_qrnnd__r); \
- (r) = __udiv_qrnnd__r; \
+ &__udiv_qrnnd_r); \
+ (r) = __udiv_qrnnd_r; \
} while (0)
#endif
@@ -1743,7 +1985,7 @@ extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
do { \
UWtype __x; \
__x = (al) - (bl); \
- (sh) = (ah) - (bh) - ((al) < (bl)); \
+ (sh) = (ah) - (bh) - ((al) < (bl)); \
(sl) = __x; \
} while (0)
#endif
@@ -1854,13 +2096,14 @@ extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
__udiv_w_sdiv (defined in libgcc or elsewhere). */
-#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) && !defined(LONGLONG_STANDALONE)
#define udiv_qrnnd(q, r, nh, nl, d) \
do { \
UWtype __r; \
(q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
(r) = __r; \
} while (0)
+__GMP_DECLSPEC UWtype __MPN(udiv_w_sdiv) (UWtype *, UWtype, UWtype, UWtype);
#endif
/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
@@ -1895,6 +2138,7 @@ extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
/* This version gives a well-defined value for zero. */
#define COUNT_LEADING_ZEROS_0 (W_TYPE_SIZE - 1)
#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#define COUNT_LEADING_ZEROS_SLOW
#endif
/* clz_tab needed by mpn/x86/pentium/mod_1.asm in a fat binary */
@@ -1903,17 +2147,13 @@ extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
#endif
#ifdef COUNT_LEADING_ZEROS_NEED_CLZ_TAB
-# ifdef MPFR_HAVE_GMP_IMPL
- extern const unsigned char __GMP_DECLSPEC __clz_tab[128];
-# else
- extern const unsigned char __clz_tab[128];
-# endif
+extern const unsigned char __GMP_DECLSPEC __clz_tab[129];
#endif
#if !defined (count_trailing_zeros)
-/* Define count_trailing_zeros using count_leading_zeros. The latter might be
- defined in asm, but if it is not, the C version above is good enough. */
-#define count_trailing_zeros(count, x) \
+#if !defined (COUNT_LEADING_ZEROS_SLOW)
+/* Define count_trailing_zeros using an asm count_leading_zeros. */
+#define count_trailing_zeros(count, x) \
do { \
UWtype __ctz_x = (x); \
UWtype __ctz_c; \
@@ -1921,6 +2161,30 @@ extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
(count) = W_TYPE_SIZE - 1 - __ctz_c; \
} while (0)
+#else
+/* Define count_trailing_zeros in plain C, assuming small counts are common.
+ We use clz_tab without ado, since the C count_leading_zeros above will have
+ pulled it in. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ int __ctz_c; \
+ \
+ if (LIKELY ((__ctz_x & 0xff) != 0)) \
+ (count) = __clz_tab[__ctz_x & -__ctz_x] - 2; \
+ else \
+ { \
+ for (__ctz_c = 8 - 2; __ctz_c < W_TYPE_SIZE - 2; __ctz_c += 8) \
+ { \
+ __ctz_x >>= 8; \
+ if (LIKELY ((__ctz_x & 0xff) != 0)) \
+ break; \
+ } \
+ \
+ (count) = __ctz_c + __clz_tab[__ctz_x & -__ctz_x]; \
+ } \
+ } while (0)
+#endif
#endif
#ifndef UDIV_NEEDS_NORMALIZATION
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.c b/Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.c
new file mode 100644
index 00000000000..c215882a1ab
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.c
@@ -0,0 +1,211 @@
+/* mpfr-mini-gmp.c -- Interface functions for mini-gmp.
+
+Copyright 2014-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* The following include will do 2 things: include the config.h
+ if there is one (as it may define MPFR_USE_MINI_GMP), and avoid
+ an empty translation unit (see ISO C99, 6.9). */
+#include "mpfr-impl.h"
+
+#ifdef MPFR_USE_MINI_GMP
+
+#include "mpfr-mini-gmp.h"
+
+/************************ random generation functions ************************/
+
+#ifdef WANT_gmp_randinit_default
+void
+gmp_randinit_default (gmp_randstate_t state)
+{
+}
+#endif
+
+#ifdef WANT_gmp_randseed_ui
+void
+gmp_randseed_ui (gmp_randstate_t state, unsigned long int seed)
+{
+ srand48 (seed);
+}
+#endif
+
+#ifdef WANT_gmp_randclear
+void
+gmp_randclear (gmp_randstate_t state)
+{
+}
+#endif
+
+#ifdef WANT_gmp_randinit_set
+void
+gmp_randinit_set (gmp_randstate_t s1, gmp_randstate_t s2)
+{
+}
+#endif
+
+static mp_limb_t
+random_limb (void)
+{
+ /* lrand48() only gives 31 bits */
+#if GMP_NUMB_BITS == 32
+ return lrand48 () + (lrand48 () << 31);
+#else
+ return lrand48 () + (((mp_limb_t) lrand48 ()) << 31)
+ + (((mp_limb_t) lrand48 ()) << 62);
+#endif
+}
+
+#ifdef WANT_mpz_urandomb
+void
+mpz_urandomb (mpz_t rop, gmp_randstate_t state, mp_bitcnt_t nbits)
+{
+ unsigned long n, i;
+
+ mpz_realloc2 (rop, nbits);
+ n = (nbits - 1) / GMP_NUMB_BITS + 1; /* number of limbs */
+ for (i = n; i-- > 0;)
+ rop->_mp_d[i] = random_limb ();
+ i = n * GMP_NUMB_BITS - nbits;
+ /* mask the upper i bits */
+ if (i)
+ rop->_mp_d[n-1] = (rop->_mp_d[n-1] << i) >> i;
+ while (n > 0 && (rop->_mp_d[n-1] == 0))
+ n--;
+ rop->_mp_size = n;
+}
+#endif
+
+#ifdef WANT_gmp_urandomm_ui
+unsigned long
+gmp_urandomm_ui (gmp_randstate_t state, unsigned long n)
+{
+ return random_limb () % n;
+}
+#endif
+
+#ifdef WANT_gmp_urandomb_ui
+unsigned long
+gmp_urandomb_ui (gmp_randstate_t state, unsigned long n)
+{
+ return random_limb () % (1UL << n);
+}
+#endif
+
+/************************* division functions ********************************/
+
+#ifdef WANT_mpn_divrem_1
+mp_limb_t
+mpn_divrem_1 (mp_limb_t *qp, mp_size_t qxn, mp_limb_t *np, mp_size_t nn,
+ mp_limb_t d0)
+{
+ mpz_t q, r, n, d;
+ mp_limb_t ret, dd[1];
+
+ d->_mp_d = dd;
+ d->_mp_d[0] = d0;
+ d->_mp_size = 1;
+ mpz_init (q);
+ mpz_init (r);
+ if (qxn == 0)
+ {
+ n->_mp_d = np;
+ n->_mp_size = nn;
+ }
+ else
+ {
+ mpz_init2 (n, (nn + qxn) * GMP_NUMB_BITS);
+ mpn_copyi (n->_mp_d + qxn, np, nn);
+ mpn_zero (n->_mp_d, qxn);
+ n->_mp_size = nn + qxn;
+ }
+ mpz_tdiv_qr (q, r, n, d);
+ if (q->_mp_size > 0)
+ mpn_copyi (qp, q->_mp_d, q->_mp_size);
+ if (q->_mp_size < nn + qxn)
+ mpn_zero (qp + q->_mp_size, nn + qxn - q->_mp_size);
+ ret = (r->_mp_size == 1) ? r->_mp_d[0] : 0;
+ mpz_clear (q);
+ mpz_clear (r);
+ if (qxn != 0)
+ mpz_clear (n);
+ return ret;
+}
+#endif
+
+#ifdef WANT_mpn_divrem
+mp_limb_t
+mpn_divrem (mp_limb_t *qp, mp_size_t qn, mp_limb_t *np,
+ mp_size_t nn, const mp_limb_t *dp, mp_size_t dn)
+{
+ mpz_t q, r, n, d;
+ mp_limb_t ret;
+
+ MPFR_ASSERTN(qn == 0);
+ qn = nn - dn;
+ n->_mp_d = np;
+ n->_mp_size = nn;
+ d->_mp_d = (mp_limb_t*) dp;
+ d->_mp_size = dn;
+ mpz_init (q);
+ mpz_init (r);
+ mpz_tdiv_qr (q, r, n, d);
+ MPFR_ASSERTN(q->_mp_size == qn || q->_mp_size == qn + 1);
+ mpn_copyi (qp, q->_mp_d, qn);
+ ret = (q->_mp_size == qn) ? 0 : q->_mp_d[qn];
+ if (r->_mp_size > 0)
+ mpn_copyi (np, r->_mp_d, r->_mp_size);
+ if (r->_mp_size < dn)
+ mpn_zero (np + r->_mp_size, dn - r->_mp_size);
+ mpz_clear (q);
+ mpz_clear (r);
+ return ret;
+}
+#endif
+
+#ifdef WANT_mpn_tdiv_qr
+void
+mpn_tdiv_qr (mp_limb_t *qp, mp_limb_t *rp, mp_size_t qxn,
+ const mp_limb_t *np, mp_size_t nn,
+ const mp_limb_t *dp, mp_size_t dn)
+{
+ mpz_t q, r, n, d;
+
+ MPFR_ASSERTN(qxn == 0);
+ n->_mp_d = (mp_limb_t*) np;
+ n->_mp_size = nn;
+ d->_mp_d = (mp_limb_t*) dp;
+ d->_mp_size = dn;
+ mpz_init (q);
+ mpz_init (r);
+ mpz_tdiv_qr (q, r, n, d);
+ MPFR_ASSERTN(q->_mp_size > 0);
+ mpn_copyi (qp, q->_mp_d, q->_mp_size);
+ if (q->_mp_size < nn - dn + 1)
+ mpn_zero (qp + q->_mp_size, nn - dn + 1 - q->_mp_size);
+ if (r->_mp_size > 0)
+ mpn_copyi (rp, r->_mp_d, r->_mp_size);
+ if (r->_mp_size < dn)
+ mpn_zero (rp + r->_mp_size, dn - r->_mp_size);
+ mpz_clear (q);
+ mpz_clear (r);
+}
+#endif
+
+#endif /* MPFR_USE_MINI_GMP */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.h
new file mode 100644
index 00000000000..bba04f8674c
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-mini-gmp.h
@@ -0,0 +1,141 @@
+/* mpfr-mini-gmp.h -- Interface header for mini-gmp.
+
+Copyright 2014-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h> /* for size_t */
+#include "gmp.h"
+
+#ifndef gmp_version
+extern char gmp_version[];
+#endif
+
+#ifndef GMP_NUMB_BITS
+/* see https://gmplib.org/list-archives/gmp-bugs/2015-October/003755.html */
+#include <limits.h>
+#define GMP_NUMB_BITS (CHAR_BIT * sizeof(mp_limb_t))
+#endif
+
+#ifndef mp_limb_signed_t
+typedef long mp_limb_signed_t;
+#endif
+
+#ifndef __gmp_allocate_func
+#define __gmp_allocate_func gmp_default_alloc
+#define __gmp_reallocate_func gmp_default_realloc
+#define __gmp_free_func gmp_default_free
+#endif
+
+#ifndef gmp_randstate_t
+typedef long int __gmp_randstate_struct;
+typedef __gmp_randstate_struct gmp_randstate_t[1];
+#endif
+
+#ifndef gmp_randinit_default
+#define WANT_gmp_randinit_default
+void gmp_randinit_default (gmp_randstate_t);
+#endif
+
+#ifndef gmp_randseed_ui
+#define WANT_gmp_randseed_ui
+void gmp_randseed_ui (gmp_randstate_t, unsigned long int);
+#endif
+
+#ifndef gmp_randclear
+#define WANT_gmp_randclear
+void gmp_randclear (gmp_randstate_t);
+#endif
+
+#ifndef gmp_randinit_set
+#define WANT_gmp_randinit_set
+void gmp_randinit_set (gmp_randstate_t, gmp_randstate_t);
+#endif
+
+#ifndef mpn_scan1
+#define WANT_mpn_scan1
+mp_bitcnt_t mpn_scan1 (const mp_limb_t *, mp_bitcnt_t);
+#endif
+
+#ifndef mpz_perfect_square_p
+#define WANT_mpz_perfect_square_p
+int mpz_perfect_square_p (const mpz_t);
+#endif
+
+#ifndef mpz_addmul_ui
+#define WANT_mpz_addmul_ui
+void mpz_addmul_ui (mpz_t, const mpz_t, unsigned long);
+#endif
+
+#ifndef mpn_divrem_1
+#define WANT_mpn_divrem_1
+mp_limb_t mpn_divrem_1 (mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t,
+ mp_limb_t);
+#endif
+
+#ifndef mpz_urandomb
+#define WANT_mpz_urandomb
+void mpz_urandomb (mpz_t, gmp_randstate_t, mp_bitcnt_t);
+#endif
+
+#ifndef mpn_zero
+#define WANT_mpn_zero
+void mpn_zero (mp_limb_t *, mp_size_t);
+#endif
+
+#ifndef mpn_popcount
+#define WANT_mpn_popcount
+mp_bitcnt_t mpn_popcount (const mp_limb_t *, mp_size_t);
+#endif
+
+#ifndef gmp_urandomm_ui
+#define WANT_gmp_urandomm_ui
+unsigned long gmp_urandomm_ui (gmp_randstate_t state, unsigned long n);
+#endif
+
+#ifndef gmp_urandomb_ui
+#define WANT_gmp_urandomb_ui
+unsigned long gmp_urandomb_ui (gmp_randstate_t state, unsigned long n);
+#endif
+
+#ifndef mpn_divrem
+#define WANT_mpn_divrem
+mp_limb_t mpn_divrem (mp_limb_t *, mp_size_t, mp_limb_t *,
+ mp_size_t, const mp_limb_t *, mp_size_t);
+#endif
+
+#ifndef mpz_submul
+#define WANT_mpz_submul
+void mpz_submul (mpz_t, const mpz_t, const mpz_t);
+#endif
+
+#ifndef mpz_addmul
+#define WANT_mpz_addmul
+void mpz_addmul (mpz_t, const mpz_t, const mpz_t);
+#endif
+
+#ifndef mpn_tdiv_qr
+#define WANT_mpn_tdiv_qr
+void mpn_tdiv_qr (mp_limb_t *, mp_limb_t *, mp_size_t,
+ const mp_limb_t *, mp_size_t, const mp_limb_t *, mp_size_t);
+#endif
+
+#ifndef mpz_rrandomb
+#define mpz_rrandomb mpz_urandomb
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-sassert.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-sassert.h
new file mode 100644
index 00000000000..776ec771958
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-sassert.h
@@ -0,0 +1,75 @@
+/* MPFR internal header related to Static Assertions
+
+Copyright 2012-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_STATIC_ASSERT_H__
+#define __MPFR_STATIC_ASSERT_H__
+
+#include "mpfr-cvers.h" /* for __MPFR_GNUC */
+
+/* How to use:
+ ===========
+ MPFR_DECL_STATIC_ASSERT:
+ + to check a condition at compile time within the declaration section.
+ MPFR_STAT_STATIC_ASSERT:
+ + to check a condition at compile time within the statement section.
+*/
+
+#ifdef MPFR_USE_STATIC_ASSERT
+
+/* C11 version */
+# if defined (__STDC_VERSION__)
+# if (__STDC_VERSION__ >= 201112L)
+# define MPFR_DECL_STATIC_ASSERT(c) _Static_assert((c), #c )
+# define MPFR_STAT_STATIC_ASSERT(c) _Static_assert((c), #c )
+# endif
+# endif
+
+/* Default version which should be compatible with nearly all compilers */
+# if !defined(MPFR_DECL_STATIC_ASSERT)
+# if __MPFR_GNUC(4,8)
+/* Get rid of annoying warnings "typedef '...' locally defined but not used"
+ (new in GCC 4.8). Thanks to Jonathan Wakely for this solution:
+ https://gcc.gnu.org/ml/gcc-help/2013-07/msg00142.html */
+# define MPFR_TYPEDEF_UNUSED __attribute__ ((unused))
+# else
+# define MPFR_TYPEDEF_UNUSED
+# endif
+# define MPFR_ASSERT_CAT(a,b) MPFR_ASSERT_CAT_(a,b)
+# define MPFR_ASSERT_CAT_(a,b) a ## b
+# define MPFR_STAT_STATIC_ASSERT(c) do { \
+ typedef enum { MPFR_ASSERT_CAT(MPFR_STATIC_ASSERT_CONST_,__LINE__) = !(c) } \
+ MPFR_ASSERT_CAT(MPFR_ASSERT_,__LINE__)[!!(c) ? 1 : -1] \
+ MPFR_TYPEDEF_UNUSED; } while (0)
+# define MPFR_DECL_STATIC_ASSERT(c) \
+ typedef enum { MPFR_ASSERT_CAT(MPFR_STATIC_ASSERT_CONST_,__LINE__) = !(c) } \
+ MPFR_ASSERT_CAT(MPFR_ASSERT_,__LINE__)[!!(c) ? 1 : -1];
+# endif
+
+#else
+
+/* No support: default to classic assertions */
+# define MPFR_DECL_STATIC_ASSERT(c) /* Nothing */
+# define MPFR_STAT_STATIC_ASSERT(c) MPFR_ASSERTN(c)
+
+#endif
+
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr-thread.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr-thread.h
index a32f9cb2091..10e89c3f35a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr-thread.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr-thread.h
@@ -23,6 +23,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#ifndef __MPFR_THREAD_H__
#define __MPFR_THREAD_H__
+/* Note: MPFR_NEED_THREAD_LOCK shall be defined before including this
+ header */
+
/* Note: Let's define MPFR_THREAD_ATTR even after a #error to make the
error message more visible (e.g. gcc doesn't immediately stop after
the #error line and outputs many error messages if MPFR_THREAD_ATTR
@@ -42,4 +45,220 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
# endif
#endif
+/* If MPFR needs a lock mechanism for thread synchro */
+#ifdef MPFR_NEED_THREAD_LOCK
+
+/**************************************************************************/
+/**************************************************************************/
+/* ISO C11 version */
+/**************************************************************************/
+/**************************************************************************/
+#if defined (MPFR_HAVE_C11_LOCK)
+/* NOTE: This version has not been completly tested */
+#include <thread.h>
+
+#define MPFR_LOCK_DECL(_lock) \
+ mtx_t _lock;
+
+#define MPFR_LOCK_INIT(_lock) do { \
+ int error_code = mtx_init(&(_lock), mtx_plain); \
+ MPFR_ASSERTD( error_code == thrd_success); \
+ } while (0)
+
+#define MPFR_LOCK_CLEAR(_lock) do { \
+ mtx_destroy(&(_lock)); \
+ } while (0)
+
+#define MPFR_LOCK_READ(_lock) do { \
+ int error_code = mtx_lock(&(_lock)); \
+ MPFR_ASSERTD(error_code == thrd_success); \
+ } while (0)
+
+#define MPFR_UNLOCK_READ(_lock) do { \
+ int error_code = mtx_unlock(&(_lock)); \
+ MPFR_ASSERTD(error_code == thrd_success); \
+ } while (0)
+
+#define MPFR_LOCK_WRITE(_lock) do { \
+ int error_code = mtx_lock(&(_lock)); \
+ MPFR_ASSERTD(error_code == thrd_success); \
+ } while (0)
+
+#define MPFR_UNLOCK_WRITE(_lock) do { \
+ int error_code = mtx_unlock(&(_lock)); \
+ MPFR_ASSERTD(error_code == thrd_success); \
+ } while (0)
+
+#define MPFR_LOCK_READ2WRITE(_lock)
+
+#define MPFR_LOCK_WRITE2READ(_lock)
+
+#define MPFR_ONCE_DECL(_once) \
+ once_flag _once;
+
+#define MPFR_ONCE_INIT_VALUE ONCE_FLAG_INIT
+
+#define MPFR_ONCE_CALL(_once, _func) do { \
+ call_once(&(_once), (_func)); \
+ } while (0)
+
+#define MPFR_NEED_DEFERRED_INIT 1
+
+
+/**************************************************************************/
+/**************************************************************************/
+/* POSIX version */
+/**************************************************************************/
+/**************************************************************************/
+#elif defined (HAVE_PTHREAD)
+# include <pthread.h>
+
+#define MPFR_LOCK_DECL(_lock) \
+ pthread_rwlock_t _lock;
+
+#define MPFR_LOCK_INIT(_lock) do { \
+ int error_code = pthread_rwlock_init(&(_lock), NULL); \
+ MPFR_ASSERTD( error_code == 0); \
+ } while (0)
+
+#define MPFR_LOCK_CLEAR(_lock) do { \
+ pthread_rwlock_destroy(&(_lock)); \
+ } while (0)
+
+#define MPFR_LOCK_READ(_lock) do { \
+ int error_code = pthread_rwlock_rdlock(&(_lock)); \
+ MPFR_ASSERTD(error_code == 0); \
+ } while (0)
+
+#define MPFR_UNLOCK_READ(_lock) do { \
+ int error_code = pthread_rwlock_unlock(&(_lock)); \
+ MPFR_ASSERTD(error_code == 0); \
+ } while (0)
+
+#define MPFR_LOCK_WRITE(_lock) do { \
+ int error_code = pthread_rwlock_wrlock(&(_lock)); \
+ MPFR_ASSERTD(error_code == 0); \
+ } while (0)
+
+#define MPFR_UNLOCK_WRITE(_lock) do { \
+ int error_code = pthread_rwlock_unlock(&(_lock)); \
+ MPFR_ASSERTD(error_code == 0); \
+ } while (0)
+
+#define MPFR_LOCK_READ2WRITE(_lock) do { \
+ MPFR_UNLOCK_READ(_lock); \
+ MPFR_LOCK_WRITE(_lock); \
+ } while (0)
+
+#define MPFR_LOCK_WRITE2READ(_lock) do { \
+ MPFR_UNLOCK_WRITE(_lock); \
+ MPFR_LOCK_READ(_lock); \
+ } while (0)
+
+#define MPFR_ONCE_DECL(_once) \
+ pthread_once_t _once ;
+
+#define MPFR_ONCE_INIT_VALUE PTHREAD_ONCE_INIT
+
+#define MPFR_ONCE_CALL(_once, _func) do { \
+ int error_code = pthread_once (&(_once), (_func)); \
+ MPFR_ASSERTD (error_code == 0); \
+ } while (0)
+
+#define MPFR_NEED_DEFERRED_INIT 1
+
+#else
+
+/* TODO: Win32 */
+# error "No thread lock / unsupported OS."
+
+#endif
+
+#else
+
+/**************************************************************************/
+/**************************************************************************/
+/* No lock thread version */
+/**************************************************************************/
+/**************************************************************************/
+
+#define MPFR_LOCK_DECL(_lock)
+#define MPFR_LOCK_INIT(_lock) do {} while (0)
+#define MPFR_LOCK_CLEAR(_lock) do {} while (0)
+#define MPFR_LOCK_READ(_lock) do {} while (0)
+#define MPFR_UNLOCK_READ(_lock) do {} while (0)
+#define MPFR_LOCK_WRITE(_lock) do {} while (0)
+#define MPFR_UNLOCK_WRITE(_lock) do {} while (0)
+#define MPFR_LOCK_READ2WRITE(_lock) do {} while (0)
+#define MPFR_LOCK_WRITE2READ(_lock) do {} while (0)
+#define MPFR_ONCE_INIT_VALUE
+#define MPFR_ONCE_DECL(_once)
+#define MPFR_ONCE_CALL(_once,_func) do {} while (0)
+
+#endif
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+
+/* If MPFR Needs a way to init data before using them */
+#if defined(MPFR_NEED_DEFERRED_INIT)
+
+#if defined(MPFR_HAVE_CONSTRUCTOR_ATTR)
+
+/*********************** Use constructor extension ************************/
+#define MPFR_DEFERRED_INIT_MASTER_DECL(_id, _init, _clear) \
+ __attribute__ ((constructor)) static void \
+ mpfr_init_cache_ ## _id (void) { \
+ _init ; \
+ } \
+ __attribute__ ((destructor)) static void \
+ mpfr_clean_cache_ ## _id (void) { \
+ _clear; \
+ }
+
+#define MPFR_DEFERRED_INIT_CALL(_master) do {} while (0)
+#define MPFR_DEFERRED_INIT_SLAVE_DECL()
+#define MPFR_DEFERRED_INIT_SLAVE_VALUE(_id)
+
+#else
+
+/**************************** Use once semantic ***************************/
+#define MPFR_DEFERRED_INIT_MASTER_DECL(_id, _init, _clear) \
+ static void mpfr_once_ ## _id ## _clear_func (void) { \
+ _clear ; \
+ } \
+ static void mpfr_once_ ## _id ## _init_func (void) { \
+ _init; \
+ atexit(mpfr_once_ ## _id ## _clear_func); \
+ }
+
+#define MPFR_DEFERRED_INIT_CALL(_master) \
+ MPFR_ONCE_CALL((_master)->once, (_master)->init_once)
+
+#define MPFR_DEFERRED_INIT_SLAVE_DECL() \
+ MPFR_ONCE_DECL(once) \
+ void (*init_once)(void);
+
+#define MPFR_DEFERRED_INIT_SLAVE_VALUE(_id) \
+ , MPFR_ONCE_INIT_VALUE, mpfr_once_ ## _id ## _init_func
+
+#endif
+
+#else
+
+/* No need */
+#define MPFR_DEFERRED_INIT_MASTER_DECL(_id_lock, _init, _clear)
+#define MPFR_DEFERRED_INIT_CALL(_master) do {} while (0)
+#define MPFR_DEFERRED_INIT_SLAVE_DECL()
+#define MPFR_DEFERRED_INIT_SLAVE_VALUE(_id)
+
+#endif
+
+/**************************************************************************/
+
#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpfr.h b/Build/source/libs/mpfr/mpfr-src/src/mpfr.h
index 6dba95f2743..4b71733d862 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpfr.h
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpfr.h
@@ -24,32 +24,32 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define __MPFR_H
/* Define MPFR version number */
-#define MPFR_VERSION_MAJOR 3
-#define MPFR_VERSION_MINOR 1
-#define MPFR_VERSION_PATCHLEVEL 6
-#define MPFR_VERSION_STRING "3.1.6"
+#define MPFR_VERSION_MAJOR 4
+#define MPFR_VERSION_MINOR 0
+#define MPFR_VERSION_PATCHLEVEL 0
+#define MPFR_VERSION_STRING "4.0.0"
+
+/* User macros:
+ MPFR_USE_FILE: Define it to make MPFR define functions dealing
+ with FILE* (auto-detect).
+ MPFR_USE_INTMAX_T: Define it to make MPFR define functions dealing
+ with intmax_t (auto-detect).
+ MPFR_USE_VA_LIST: Define it to make MPFR define functions dealing
+ with va_list (auto-detect).
+ MPFR_USE_C99_FEATURE: Define it to 1 to make MPFR support C99-feature
+ (auto-detect), to 0 to bypass the detection.
+ MPFR_USE_EXTENSION: Define it to make MPFR use GCC extension to
+ reduce warnings.
+ MPFR_USE_NO_MACRO: Define it to make MPFR remove any overriding
+ function macro.
+*/
/* Macros dealing with MPFR VERSION */
#define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
#define MPFR_VERSION \
MPFR_VERSION_NUM(MPFR_VERSION_MAJOR,MPFR_VERSION_MINOR,MPFR_VERSION_PATCHLEVEL)
-/* Check if GMP is included, and try to include it (Works with local GMP) */
-#ifndef __GMP_H__
-# include <gmp.h>
-#endif
-
-/* GMP's internal __gmp_const macro has been removed on 2012-03-04:
- http://gmplib.org:8000/gmp/rev/d287cfaf6732
- const is standard and now assumed to be available. If the __gmp_const
- definition is no longer present in GMP, this probably means that GMP
- assumes that const is available; thus let's define it to const.
- Note: this is a temporary fix that can be backported to previous MPFR
- versions. In the future, __gmp_const should be replaced by const like
- in GMP. */
-#ifndef __gmp_const
-# define __gmp_const const
-#endif
+#include <gmp.h>
/* Avoid some problems with macro expansion if the user defines macros
with the same name as keywords. By convention, identifiers and macro
@@ -61,6 +61,28 @@ typedef long mpfr_long;
typedef unsigned long mpfr_ulong;
typedef size_t mpfr_size_t;
+/* Global (possibly TLS) flags. Might also be used in an mpfr_t in the
+ future (there would be room as mpfr_sign_t just needs 1 byte).
+ TODO: The tests currently assume that the flags fits in an unsigned int;
+ this should be cleaned up, e.g. by defining a function that outputs the
+ flags as a string or by using the flags_out function (from tests/tests.c
+ directly). */
+typedef unsigned int mpfr_flags_t;
+
+/* Flags macros (in the public API) */
+#define MPFR_FLAGS_UNDERFLOW 1
+#define MPFR_FLAGS_OVERFLOW 2
+#define MPFR_FLAGS_NAN 4
+#define MPFR_FLAGS_INEXACT 8
+#define MPFR_FLAGS_ERANGE 16
+#define MPFR_FLAGS_DIVBY0 32
+#define MPFR_FLAGS_ALL (MPFR_FLAGS_UNDERFLOW | \
+ MPFR_FLAGS_OVERFLOW | \
+ MPFR_FLAGS_NAN | \
+ MPFR_FLAGS_INEXACT | \
+ MPFR_FLAGS_ERANGE | \
+ MPFR_FLAGS_DIVBY0)
+
/* Definition of rounding modes (DON'T USE MPFR_RNDNA!).
Warning! Changing the contents of this enum should be seen as an
interface change since the old and the new types are not compatible
@@ -70,9 +92,6 @@ typedef size_t mpfr_size_t;
MPFR_RNDU must appear just before MPFR_RNDD (see
MPFR_IS_RNDUTEST_OR_RNDDNOTTEST in mpfr-impl.h).
- MPFR_RNDF has been added, though not implemented yet, in order to avoid
- to break the ABI once faithful rounding gets implemented.
-
If you change the order of the rounding modes, please update the routines
in texceptions.c which assume 0=RNDN, 1=RNDZ, 2=RNDU, 3=RNDD, 4=RNDA.
*/
@@ -82,7 +101,7 @@ typedef enum {
MPFR_RNDU, /* round toward +Inf */
MPFR_RNDD, /* round toward -Inf */
MPFR_RNDA, /* round away from zero */
- MPFR_RNDF, /* faithful rounding (not implemented yet) */
+ MPFR_RNDF, /* faithful rounding */
MPFR_RNDNA=-1 /* round to nearest, with ties away from zero (mpfr_round) */
} mpfr_rnd_t;
@@ -98,7 +117,7 @@ typedef enum {
/* Define precision: 1 (short), 2 (int) or 3 (long) (DON'T USE IT!) */
#ifndef _MPFR_PREC_FORMAT
-# if __GMP_MP_SIZE_T_INT == 1
+# if __GMP_MP_SIZE_T_INT
# define _MPFR_PREC_FORMAT 2
# else
# define _MPFR_PREC_FORMAT 3
@@ -132,10 +151,13 @@ typedef unsigned long mpfr_uprec_t;
#endif
/* Definition of precision limits without needing <limits.h> */
-/* Note: the casts allows the expression to yield the wanted behavior
- for _MPFR_PREC_FORMAT == 1 (due to integer promotion rules). */
-#define MPFR_PREC_MIN 2
-#define MPFR_PREC_MAX ((mpfr_prec_t)((mpfr_uprec_t)(~(mpfr_uprec_t)0)>>1))
+/* Note: The casts allows the expression to yield the wanted behavior
+ for _MPFR_PREC_FORMAT == 1 (due to integer promotion rules). We
+ also make sure that MPFR_PREC_MIN and MPFR_PREC_MAX have a signed
+ integer type. The "- 256" allows more security, avoiding some
+ integer overflows in extreme cases; ideally it should be useless. */
+#define MPFR_PREC_MIN 1
+#define MPFR_PREC_MAX ((mpfr_prec_t) ((((mpfr_uprec_t) -1) >> 1) - 256))
/* Definition of sign */
typedef int mpfr_sign_t;
@@ -167,7 +189,11 @@ typedef uintmax_t mpfr_uexp_t;
/* DON'T USE THIS! (For MPFR-public macros only, see below.)
The mpfr_sgn macro uses the fact that __MPFR_EXP_NAN and __MPFR_EXP_ZERO
- are the smallest values. */
+ are the smallest values. For a n-bit type, EXP_MAX is 2^(n-1)-1,
+ EXP_ZERO is 1-2^(n-1), EXP_NAN is 2-2^(n-1), EXP_INF is 3-2^(n-1).
+ This may change in the future. MPFR code should not be based on these
+ representations (but if this is absolutely needed, protect the code
+ with a static assertion). */
#define __MPFR_EXP_MAX ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1))
#define __MPFR_EXP_NAN (1 - __MPFR_EXP_MAX)
#define __MPFR_EXP_ZERO (0 - __MPFR_EXP_MAX)
@@ -202,7 +228,7 @@ typedef struct {
typedef __mpfr_struct mpfr_t[1];
typedef __mpfr_struct *mpfr_ptr;
-typedef __gmp_const __mpfr_struct *mpfr_srcptr;
+typedef const __mpfr_struct *mpfr_srcptr;
/* For those who need a direct and fast access to the sign field.
However it is not in the API, thus use it at your own risk: it might
@@ -214,16 +240,22 @@ typedef __gmp_const __mpfr_struct *mpfr_srcptr;
/* Stack interface */
typedef enum {
- MPFR_NAN_KIND = 0,
- MPFR_INF_KIND = 1, MPFR_ZERO_KIND = 2, MPFR_REGULAR_KIND = 3
+ MPFR_NAN_KIND = 0,
+ MPFR_INF_KIND = 1,
+ MPFR_ZERO_KIND = 2,
+ MPFR_REGULAR_KIND = 3
} mpfr_kind_t;
+/* Free cache policy */
+typedef enum {
+ MPFR_FREE_LOCAL_CACHE = 1, /* 1 << 0 */
+ MPFR_FREE_GLOBAL_CACHE = 2 /* 1 << 1 */
+} mpfr_free_cache_t;
+
/* GMP defines:
+ size_t: Standard size_t
- + __GMP_ATTRIBUTE_PURE Attribute for math functions.
+ __GMP_NOTHROW For C++: can't throw .
+ __GMP_EXTERN_INLINE Attribute for inline function.
- * __gmp_const const (Supports for K&R compiler only for mpfr.h).
+ __GMP_DECLSPEC_EXPORT compiling to go into a DLL
+ __GMP_DECLSPEC_IMPORT compiling to go into a application
*/
@@ -236,25 +268,59 @@ typedef enum {
# endif
#endif
-/* Prototypes: Support of K&R compiler */
-#if defined (__GMP_PROTO)
-# define _MPFR_PROTO __GMP_PROTO
-#elif defined (__STDC__) || defined (__cplusplus)
-# define _MPFR_PROTO(x) x
-#else
-# define _MPFR_PROTO(x) ()
+/* If the user hasn't requested his/her preference
+ and if the intension of support by the compiler is C99
+ and if the compiler is known to support the C99 feature
+ then we can auto-detect the C99 support as OK.
+ __GNUC__ is used to detect GNU-C, ICC & CLANG compilers.
+ Currently we need only variadic macros, and they are present
+ since GCC >= 3. We don't test library version since we don't
+ use any feature present in the library too (except intmax_t,
+ but they use another detection).*/
+#ifndef MPFR_USE_C99_FEATURE
+# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# if defined (__GNUC__)
+# if __GNUC__ >= 3
+# define MPFR_USE_C99_FEATURE 1
+# endif
+# endif
+# endif
+# ifndef MPFR_USE_C99_FEATURE
+# define MPFR_USE_C99_FEATURE 0
+# endif
#endif
+
/* Support for WINDOWS Dll:
Check if we are inside a MPFR build, and if so export the functions.
Otherwise does the same thing as GMP */
#if defined(__MPFR_WITHIN_MPFR) && __GMP_LIBGMP_DLL
# define __MPFR_DECLSPEC __GMP_DECLSPEC_EXPORT
#else
+# ifndef __GMP_DECLSPEC
+# define __GMP_DECLSPEC
+# endif
# define __MPFR_DECLSPEC __GMP_DECLSPEC
#endif
/* Use MPFR_DEPRECATED to mark MPFR functions, types or variables as
- deprecated. Code inspired by Apache Subversion's svn_types.h file. */
+ deprecated. Code inspired by Apache Subversion's svn_types.h file.
+ For compatibility with MSVC, MPFR_DEPRECATED must be put before
+ __MPFR_DECLSPEC (not at the end of the function declaration as
+ documented in the GCC manual); GCC does not seem to care.
+ Moreover, in order to avoid a warning when testing such functions,
+ do something like:
+ +------------------------------------------
+ |#ifndef _MPFR_NO_DEPRECATED_funcname
+ |MPFR_DEPRECATED
+ |#endif
+ |__MPFR_DECLSPEC int mpfr_funcname (...);
+ +------------------------------------------
+ and in the corresponding test program:
+ +------------------------------------------
+ |#define _MPFR_NO_DEPRECATED_funcname
+ |#include "mpfr-test.h"
+ +------------------------------------------
+*/
#if defined(__GNUC__) && \
(__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
# define MPFR_DEPRECATED __attribute__ ((deprecated))
@@ -263,6 +329,11 @@ typedef enum {
#else
# define MPFR_DEPRECATED
#endif
+/* TODO: Also define MPFR_EXPERIMENTAL for experimental functions?
+ See SVN_EXPERIMENTAL in Subversion 1.9+ as an example:
+ __attribute__((warning("..."))) can be used with GCC 4.3.1+ but
+ not __llvm__, and __declspec(deprecated("...")) can be used with
+ MSC as above. */
/* Note: In order to be declared, some functions need a specific
system header to be included *before* "mpfr.h". If the user
@@ -276,451 +347,415 @@ typedef enum {
extern "C" {
#endif
-__MPFR_DECLSPEC __gmp_const char * mpfr_get_version _MPFR_PROTO ((void));
-__MPFR_DECLSPEC __gmp_const char * mpfr_get_patches _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_buildopt_tls_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_buildopt_decimal_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_buildopt_gmpinternals_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC __gmp_const char * mpfr_buildopt_tune_case _MPFR_PROTO ((void));
-
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_set_emin _MPFR_PROTO ((mpfr_exp_t));
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin_min _MPFR_PROTO ((void));
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin_max _MPFR_PROTO ((void));
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_set_emax _MPFR_PROTO ((mpfr_exp_t));
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax_min _MPFR_PROTO ((void));
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax_max _MPFR_PROTO ((void));
-
-__MPFR_DECLSPEC void mpfr_set_default_rounding_mode _MPFR_PROTO((mpfr_rnd_t));
-__MPFR_DECLSPEC mpfr_rnd_t mpfr_get_default_rounding_mode _MPFR_PROTO((void));
-__MPFR_DECLSPEC __gmp_const char *
- mpfr_print_rnd_mode _MPFR_PROTO((mpfr_rnd_t));
-
-__MPFR_DECLSPEC void mpfr_clear_flags _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_clear_underflow _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_clear_overflow _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_clear_divby0 _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_clear_nanflag _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_clear_inexflag _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_clear_erangeflag _MPFR_PROTO ((void));
-
-__MPFR_DECLSPEC void mpfr_set_underflow _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_set_overflow _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_set_divby0 _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_set_nanflag _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_set_inexflag _MPFR_PROTO ((void));
-__MPFR_DECLSPEC void mpfr_set_erangeflag _MPFR_PROTO ((void));
-
-__MPFR_DECLSPEC int mpfr_underflow_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_overflow_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_divby0_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_nanflag_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_inexflag_p _MPFR_PROTO ((void));
-__MPFR_DECLSPEC int mpfr_erangeflag_p _MPFR_PROTO ((void));
-
-__MPFR_DECLSPEC int
- mpfr_check_range _MPFR_PROTO ((mpfr_ptr, int, mpfr_rnd_t));
-
-__MPFR_DECLSPEC void mpfr_init2 _MPFR_PROTO ((mpfr_ptr, mpfr_prec_t));
-__MPFR_DECLSPEC void mpfr_init _MPFR_PROTO ((mpfr_ptr));
-__MPFR_DECLSPEC void mpfr_clear _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC const char * mpfr_get_version (void);
+__MPFR_DECLSPEC const char * mpfr_get_patches (void);
+__MPFR_DECLSPEC int mpfr_buildopt_tls_p (void);
+__MPFR_DECLSPEC int mpfr_buildopt_float128_p (void);
+__MPFR_DECLSPEC int mpfr_buildopt_decimal_p (void);
+__MPFR_DECLSPEC int mpfr_buildopt_gmpinternals_p (void);
+__MPFR_DECLSPEC int mpfr_buildopt_sharedcache_p (void);
+__MPFR_DECLSPEC const char * mpfr_buildopt_tune_case (void);
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin (void);
+__MPFR_DECLSPEC int mpfr_set_emin (mpfr_exp_t);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin_min (void);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin_max (void);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax (void);
+__MPFR_DECLSPEC int mpfr_set_emax (mpfr_exp_t);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax_min (void);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax_max (void);
+
+__MPFR_DECLSPEC void mpfr_set_default_rounding_mode (mpfr_rnd_t);
+__MPFR_DECLSPEC mpfr_rnd_t mpfr_get_default_rounding_mode (void);
+__MPFR_DECLSPEC const char * mpfr_print_rnd_mode (mpfr_rnd_t);
+
+__MPFR_DECLSPEC void mpfr_clear_flags (void);
+__MPFR_DECLSPEC void mpfr_clear_underflow (void);
+__MPFR_DECLSPEC void mpfr_clear_overflow (void);
+__MPFR_DECLSPEC void mpfr_clear_divby0 (void);
+__MPFR_DECLSPEC void mpfr_clear_nanflag (void);
+__MPFR_DECLSPEC void mpfr_clear_inexflag (void);
+__MPFR_DECLSPEC void mpfr_clear_erangeflag (void);
+
+__MPFR_DECLSPEC void mpfr_set_underflow (void);
+__MPFR_DECLSPEC void mpfr_set_overflow (void);
+__MPFR_DECLSPEC void mpfr_set_divby0 (void);
+__MPFR_DECLSPEC void mpfr_set_nanflag (void);
+__MPFR_DECLSPEC void mpfr_set_inexflag (void);
+__MPFR_DECLSPEC void mpfr_set_erangeflag (void);
+
+__MPFR_DECLSPEC int mpfr_underflow_p (void);
+__MPFR_DECLSPEC int mpfr_overflow_p (void);
+__MPFR_DECLSPEC int mpfr_divby0_p (void);
+__MPFR_DECLSPEC int mpfr_nanflag_p (void);
+__MPFR_DECLSPEC int mpfr_inexflag_p (void);
+__MPFR_DECLSPEC int mpfr_erangeflag_p (void);
+
+__MPFR_DECLSPEC void mpfr_flags_clear (mpfr_flags_t);
+__MPFR_DECLSPEC void mpfr_flags_set (mpfr_flags_t);
+__MPFR_DECLSPEC mpfr_flags_t mpfr_flags_test (mpfr_flags_t);
+__MPFR_DECLSPEC mpfr_flags_t mpfr_flags_save (void);
+__MPFR_DECLSPEC void mpfr_flags_restore (mpfr_flags_t,
+ mpfr_flags_t);
+
+__MPFR_DECLSPEC int mpfr_check_range (mpfr_ptr, int, mpfr_rnd_t);
+
+__MPFR_DECLSPEC void mpfr_init2 (mpfr_ptr, mpfr_prec_t);
+__MPFR_DECLSPEC void mpfr_init (mpfr_ptr);
+__MPFR_DECLSPEC void mpfr_clear (mpfr_ptr);
__MPFR_DECLSPEC void
- mpfr_inits2 _MPFR_PROTO ((mpfr_prec_t, mpfr_ptr, ...)) __MPFR_SENTINEL_ATTR;
+ mpfr_inits2 (mpfr_prec_t, mpfr_ptr, ...) __MPFR_SENTINEL_ATTR;
__MPFR_DECLSPEC void
- mpfr_inits _MPFR_PROTO ((mpfr_ptr, ...)) __MPFR_SENTINEL_ATTR;
+ mpfr_inits (mpfr_ptr, ...) __MPFR_SENTINEL_ATTR;
__MPFR_DECLSPEC void
- mpfr_clears _MPFR_PROTO ((mpfr_ptr, ...)) __MPFR_SENTINEL_ATTR;
-
-__MPFR_DECLSPEC int
- mpfr_prec_round _MPFR_PROTO ((mpfr_ptr, mpfr_prec_t, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_can_round _MPFR_PROTO ((mpfr_srcptr, mpfr_exp_t, mpfr_rnd_t, mpfr_rnd_t,
- mpfr_prec_t));
-__MPFR_DECLSPEC mpfr_prec_t mpfr_min_prec _MPFR_PROTO ((mpfr_srcptr));
-
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_exp _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_set_exp _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
-__MPFR_DECLSPEC mpfr_prec_t mpfr_get_prec _MPFR_PROTO((mpfr_srcptr));
-__MPFR_DECLSPEC void mpfr_set_prec _MPFR_PROTO((mpfr_ptr, mpfr_prec_t));
-__MPFR_DECLSPEC void mpfr_set_prec_raw _MPFR_PROTO((mpfr_ptr, mpfr_prec_t));
-__MPFR_DECLSPEC void mpfr_set_default_prec _MPFR_PROTO((mpfr_prec_t));
-__MPFR_DECLSPEC mpfr_prec_t mpfr_get_default_prec _MPFR_PROTO((void));
-
-__MPFR_DECLSPEC int mpfr_set_d _MPFR_PROTO ((mpfr_ptr, double, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_set_flt _MPFR_PROTO ((mpfr_ptr, float, mpfr_rnd_t));
+ mpfr_clears (mpfr_ptr, ...) __MPFR_SENTINEL_ATTR;
+
+__MPFR_DECLSPEC int mpfr_prec_round (mpfr_ptr, mpfr_prec_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_can_round (mpfr_srcptr, mpfr_exp_t, mpfr_rnd_t,
+ mpfr_rnd_t, mpfr_prec_t);
+__MPFR_DECLSPEC mpfr_prec_t mpfr_min_prec (mpfr_srcptr);
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_exp (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_set_exp (mpfr_ptr, mpfr_exp_t);
+__MPFR_DECLSPEC mpfr_prec_t mpfr_get_prec (mpfr_srcptr);
+__MPFR_DECLSPEC void mpfr_set_prec (mpfr_ptr, mpfr_prec_t);
+__MPFR_DECLSPEC void mpfr_set_prec_raw (mpfr_ptr, mpfr_prec_t);
+__MPFR_DECLSPEC void mpfr_set_default_prec (mpfr_prec_t);
+__MPFR_DECLSPEC mpfr_prec_t mpfr_get_default_prec (void);
+
+__MPFR_DECLSPEC int mpfr_set_d (mpfr_ptr, double, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_flt (mpfr_ptr, float, mpfr_rnd_t);
#ifdef MPFR_WANT_DECIMAL_FLOATS
-__MPFR_DECLSPEC int mpfr_set_decimal64 _MPFR_PROTO ((mpfr_ptr, _Decimal64,
- mpfr_rnd_t));
+/* _Decimal64 is not defined in C++,
+ cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51364 */
+__MPFR_DECLSPEC int mpfr_set_decimal64 (mpfr_ptr, _Decimal64, mpfr_rnd_t);
+#endif
+__MPFR_DECLSPEC int mpfr_set_ld (mpfr_ptr, long double, mpfr_rnd_t);
+#ifdef MPFR_WANT_FLOAT128
+__MPFR_DECLSPEC int mpfr_set_float128 (mpfr_ptr, __float128, mpfr_rnd_t);
+__MPFR_DECLSPEC __float128 mpfr_get_float128 (mpfr_srcptr, mpfr_rnd_t);
#endif
-__MPFR_DECLSPEC int
- mpfr_set_ld _MPFR_PROTO ((mpfr_ptr, long double, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_z _MPFR_PROTO ((mpfr_ptr, mpz_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_z_2exp _MPFR_PROTO ((mpfr_ptr, mpz_srcptr, mpfr_exp_t, mpfr_rnd_t));
-__MPFR_DECLSPEC void mpfr_set_nan _MPFR_PROTO ((mpfr_ptr));
-__MPFR_DECLSPEC void mpfr_set_inf _MPFR_PROTO ((mpfr_ptr, int));
-__MPFR_DECLSPEC void mpfr_set_zero _MPFR_PROTO ((mpfr_ptr, int));
-__MPFR_DECLSPEC int
- mpfr_set_f _MPFR_PROTO ((mpfr_ptr, mpf_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_get_f _MPFR_PROTO ((mpf_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_set_si _MPFR_PROTO ((mpfr_ptr, long, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_ui _MPFR_PROTO ((mpfr_ptr, unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_si_2exp _MPFR_PROTO ((mpfr_ptr, long, mpfr_exp_t, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_ui_2exp _MPFR_PROTO ((mpfr_ptr,unsigned long,mpfr_exp_t,mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_q _MPFR_PROTO ((mpfr_ptr, mpq_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_str _MPFR_PROTO ((mpfr_ptr, __gmp_const char *, int, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_init_set_str _MPFR_PROTO ((mpfr_ptr, __gmp_const char *, int,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set4 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t, int));
-__MPFR_DECLSPEC int
- mpfr_abs _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_neg _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_signbit _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC int
- mpfr_setsign _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, int, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_copysign _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC mpfr_exp_t mpfr_get_z_2exp _MPFR_PROTO ((mpz_ptr, mpfr_srcptr));
-__MPFR_DECLSPEC float mpfr_get_flt _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC double mpfr_get_d _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_set_z (mpfr_ptr, mpz_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_z_2exp (mpfr_ptr, mpz_srcptr, mpfr_exp_t,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC void mpfr_set_nan (mpfr_ptr);
+__MPFR_DECLSPEC void mpfr_set_inf (mpfr_ptr, int);
+__MPFR_DECLSPEC void mpfr_set_zero (mpfr_ptr, int);
+
+#ifndef MPFR_USE_MINI_GMP
+ /* mini-gmp does not provide mpf_t, we disable the following functions */
+__MPFR_DECLSPEC int mpfr_set_f (mpfr_ptr, mpf_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cmp_f (mpfr_srcptr, mpf_srcptr);
+__MPFR_DECLSPEC int mpfr_get_f (mpf_ptr, mpfr_srcptr, mpfr_rnd_t);
+#endif
+__MPFR_DECLSPEC int mpfr_set_si (mpfr_ptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_ui (mpfr_ptr, unsigned long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_si_2exp (mpfr_ptr, long, mpfr_exp_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_ui_2exp (mpfr_ptr, unsigned long, mpfr_exp_t,
+ mpfr_rnd_t);
+#ifndef MPFR_USE_MINI_GMP
+ /* mini-gmp does not provide mpq_t, we disable the following functions */
+__MPFR_DECLSPEC int mpfr_set_q (mpfr_ptr, mpq_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul_q (mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_q (mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_add_q (mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub_q (mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cmp_q (mpfr_srcptr, mpq_srcptr);
+__MPFR_DECLSPEC void mpfr_get_q (mpq_ptr q, mpfr_srcptr f);
+#endif
+__MPFR_DECLSPEC int mpfr_set_str (mpfr_ptr, const char *, int, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_init_set_str (mpfr_ptr, const char *, int,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set4 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t, int);
+__MPFR_DECLSPEC int mpfr_abs (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_neg (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_signbit (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_setsign (mpfr_ptr, mpfr_srcptr, int, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_copysign (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_z_2exp (mpz_ptr, mpfr_srcptr);
+__MPFR_DECLSPEC float mpfr_get_flt (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC double mpfr_get_d (mpfr_srcptr, mpfr_rnd_t);
#ifdef MPFR_WANT_DECIMAL_FLOATS
-__MPFR_DECLSPEC _Decimal64 mpfr_get_decimal64 _MPFR_PROTO ((mpfr_srcptr,
- mpfr_rnd_t));
+__MPFR_DECLSPEC _Decimal64 mpfr_get_decimal64 (mpfr_srcptr, mpfr_rnd_t);
+#endif
+__MPFR_DECLSPEC long double mpfr_get_ld (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC double mpfr_get_d1 (mpfr_srcptr);
+__MPFR_DECLSPEC double mpfr_get_d_2exp (long*, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC long double mpfr_get_ld_2exp (long*, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_frexp (mpfr_exp_t*, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC long mpfr_get_si (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC unsigned long mpfr_get_ui (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC char * mpfr_get_str (char*, mpfr_exp_t*, int, size_t,
+ mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t);
+
+__MPFR_DECLSPEC void mpfr_free_str (char *);
+
+__MPFR_DECLSPEC int mpfr_urandom (mpfr_ptr, gmp_randstate_t, mpfr_rnd_t);
+#ifndef _MPFR_NO_DEPRECATED_GRANDOM /* for the test of this function */
+MPFR_DEPRECATED
+#endif
+__MPFR_DECLSPEC int mpfr_grandom (mpfr_ptr, mpfr_ptr, gmp_randstate_t,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_nrandom (mpfr_ptr, gmp_randstate_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_erandom (mpfr_ptr, gmp_randstate_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_urandomb (mpfr_ptr, gmp_randstate_t);
+
+__MPFR_DECLSPEC void mpfr_nextabove (mpfr_ptr);
+__MPFR_DECLSPEC void mpfr_nextbelow (mpfr_ptr);
+__MPFR_DECLSPEC void mpfr_nexttoward (mpfr_ptr, mpfr_srcptr);
+
+#ifndef MPFR_USE_MINI_GMP
+__MPFR_DECLSPEC int mpfr_printf (const char*, ...);
+__MPFR_DECLSPEC int mpfr_asprintf (char**, const char*, ...);
+__MPFR_DECLSPEC int mpfr_sprintf (char*, const char*, ...);
+__MPFR_DECLSPEC int mpfr_snprintf (char*, size_t, const char*, ...);
#endif
-__MPFR_DECLSPEC long double mpfr_get_ld _MPFR_PROTO ((mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC double mpfr_get_d1 _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC double mpfr_get_d_2exp _MPFR_PROTO ((long*, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC long double mpfr_get_ld_2exp _MPFR_PROTO ((long*, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_frexp _MPFR_PROTO ((mpfr_exp_t*, mpfr_ptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC long mpfr_get_si _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC unsigned long mpfr_get_ui _MPFR_PROTO ((mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC char*mpfr_get_str _MPFR_PROTO ((char*, mpfr_exp_t*, int, size_t,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_get_z _MPFR_PROTO ((mpz_ptr z, mpfr_srcptr f,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC void mpfr_free_str _MPFR_PROTO ((char *));
-
-__MPFR_DECLSPEC int mpfr_urandom _MPFR_PROTO ((mpfr_ptr, gmp_randstate_t,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_grandom _MPFR_PROTO ((mpfr_ptr, mpfr_ptr, gmp_randstate_t,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_urandomb _MPFR_PROTO ((mpfr_ptr, gmp_randstate_t));
-
-__MPFR_DECLSPEC void mpfr_nextabove _MPFR_PROTO ((mpfr_ptr));
-__MPFR_DECLSPEC void mpfr_nextbelow _MPFR_PROTO ((mpfr_ptr));
-__MPFR_DECLSPEC void mpfr_nexttoward _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr));
-
-__MPFR_DECLSPEC int mpfr_printf _MPFR_PROTO ((__gmp_const char*, ...));
-__MPFR_DECLSPEC int mpfr_asprintf _MPFR_PROTO ((char**, __gmp_const char*,
- ...));
-__MPFR_DECLSPEC int mpfr_sprintf _MPFR_PROTO ((char*, __gmp_const char*,
- ...));
-__MPFR_DECLSPEC int mpfr_snprintf _MPFR_PROTO ((char*, size_t,
- __gmp_const char*, ...));
-
-__MPFR_DECLSPEC int mpfr_pow _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_pow_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_pow_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_ui_pow_ui _MPFR_PROTO ((mpfr_ptr, unsigned long int,
- unsigned long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_ui_pow _MPFR_PROTO ((mpfr_ptr, unsigned long int,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_pow_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpz_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_sqrt _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sqrt_ui _MPFR_PROTO ((mpfr_ptr, unsigned long,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_rec_sqrt _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_add _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_mul _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_add_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_ui_sub _MPFR_PROTO ((mpfr_ptr, unsigned long,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_mul_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_ui_div _MPFR_PROTO ((mpfr_ptr, unsigned long,
- mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_add_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_si_sub _MPFR_PROTO ((mpfr_ptr, long int,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_mul_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long int, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_si_div _MPFR_PROTO ((mpfr_ptr, long int,
- mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_add_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- double, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- double, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_d_sub _MPFR_PROTO ((mpfr_ptr, double,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_mul_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- double, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- double, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_d_div _MPFR_PROTO ((mpfr_ptr, double,
- mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_sqr _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_const_pi _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_const_log2 _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_const_euler _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_const_catalan _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_agm _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_log _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_log2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_log10 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_log1p _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_exp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_exp2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_exp10 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_expm1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_eint _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_li2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_cmp _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_cmp3 _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr, int));
-__MPFR_DECLSPEC int mpfr_cmp_d _MPFR_PROTO ((mpfr_srcptr, double));
-__MPFR_DECLSPEC int mpfr_cmp_ld _MPFR_PROTO ((mpfr_srcptr, long double));
-__MPFR_DECLSPEC int mpfr_cmpabs _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_cmp_ui _MPFR_PROTO ((mpfr_srcptr, unsigned long));
-__MPFR_DECLSPEC int mpfr_cmp_si _MPFR_PROTO ((mpfr_srcptr, long));
-__MPFR_DECLSPEC int mpfr_cmp_ui_2exp _MPFR_PROTO ((mpfr_srcptr, unsigned long,
- mpfr_exp_t));
-__MPFR_DECLSPEC int mpfr_cmp_si_2exp _MPFR_PROTO ((mpfr_srcptr, long,
- mpfr_exp_t));
-__MPFR_DECLSPEC void mpfr_reldiff _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_eq _MPFR_PROTO((mpfr_srcptr, mpfr_srcptr,
- unsigned long));
-__MPFR_DECLSPEC int mpfr_sgn _MPFR_PROTO ((mpfr_srcptr));
-
-__MPFR_DECLSPEC int mpfr_mul_2exp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_2exp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_mul_2ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_2ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- unsigned long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_mul_2si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_2si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- long, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_rint _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_round _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_trunc _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_ceil _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_floor _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_rint_round _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_rint_trunc _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_rint_ceil _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_rint_floor _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_frac _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_modf _MPFR_PROTO ((mpfr_ptr, mpfr_ptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_remquo _MPFR_PROTO ((mpfr_ptr, long*, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_remainder _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fmod _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_fits_ulong_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_slong_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_uint_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_sint_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_ushort_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_sshort_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_uintmax_p _MPFR_PROTO((mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fits_intmax_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC void mpfr_extract _MPFR_PROTO ((mpz_ptr, mpfr_srcptr,
- unsigned int));
-__MPFR_DECLSPEC void mpfr_swap _MPFR_PROTO ((mpfr_ptr, mpfr_ptr));
-__MPFR_DECLSPEC void mpfr_dump _MPFR_PROTO ((mpfr_srcptr));
-
-__MPFR_DECLSPEC int mpfr_nan_p _MPFR_PROTO((mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_inf_p _MPFR_PROTO((mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_number_p _MPFR_PROTO((mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_integer_p _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_zero_p _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_regular_p _MPFR_PROTO ((mpfr_srcptr));
-
-__MPFR_DECLSPEC int mpfr_greater_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_greaterequal_p _MPFR_PROTO ((mpfr_srcptr,
- mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_less_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_lessequal_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_lessgreater_p _MPFR_PROTO((mpfr_srcptr,mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_equal_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-__MPFR_DECLSPEC int mpfr_unordered_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
-
-__MPFR_DECLSPEC int mpfr_atanh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_acosh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_asinh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_cosh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sinh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_tanh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sinh_cosh _MPFR_PROTO ((mpfr_ptr, mpfr_ptr,
- mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_sech _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_csch _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_coth _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_acos _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_asin _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_atan _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sin _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sin_cos _MPFR_PROTO ((mpfr_ptr, mpfr_ptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_cos _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_tan _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_atan2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sec _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_csc _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_cot _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_hypot _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_erf _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_erfc _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_cbrt _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_root _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,unsigned long,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_gamma _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_lngamma _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_lgamma _MPFR_PROTO((mpfr_ptr,int*,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_digamma _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_zeta _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_zeta_ui _MPFR_PROTO ((mpfr_ptr,unsigned long,mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fac_ui _MPFR_PROTO ((mpfr_ptr, unsigned long int,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_j0 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_j1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_jn _MPFR_PROTO ((mpfr_ptr, long, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_y0 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_y1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_yn _MPFR_PROTO ((mpfr_ptr, long, mpfr_srcptr,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_ai _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_min _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_max _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_dim _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_mul_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpz_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpz_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_add_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpz_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpz_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_z_sub _MPFR_PROTO ((mpfr_ptr, mpz_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_cmp_z _MPFR_PROTO ((mpfr_srcptr, mpz_srcptr));
-
-__MPFR_DECLSPEC int mpfr_mul_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpq_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_div_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpq_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_add_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpq_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sub_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
- mpq_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_cmp_q _MPFR_PROTO ((mpfr_srcptr, mpq_srcptr));
-
-__MPFR_DECLSPEC int mpfr_cmp_f _MPFR_PROTO ((mpfr_srcptr, mpf_srcptr));
-
-__MPFR_DECLSPEC int mpfr_fma _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_fms _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
- mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_sum _MPFR_PROTO ((mpfr_ptr, mpfr_ptr *__gmp_const,
- unsigned long, mpfr_rnd_t));
-
-__MPFR_DECLSPEC void mpfr_free_cache _MPFR_PROTO ((void));
-
-__MPFR_DECLSPEC int mpfr_subnormalize _MPFR_PROTO ((mpfr_ptr, int,
- mpfr_rnd_t));
-
-__MPFR_DECLSPEC int mpfr_strtofr _MPFR_PROTO ((mpfr_ptr, __gmp_const char *,
- char **, int, mpfr_rnd_t));
-
-__MPFR_DECLSPEC size_t mpfr_custom_get_size _MPFR_PROTO ((mpfr_prec_t));
-__MPFR_DECLSPEC void mpfr_custom_init _MPFR_PROTO ((void *, mpfr_prec_t));
-__MPFR_DECLSPEC void * mpfr_custom_get_significand _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC mpfr_exp_t mpfr_custom_get_exp _MPFR_PROTO ((mpfr_srcptr));
-__MPFR_DECLSPEC void mpfr_custom_move _MPFR_PROTO ((mpfr_ptr, void *));
-__MPFR_DECLSPEC void mpfr_custom_init_set _MPFR_PROTO ((mpfr_ptr, int,
- mpfr_exp_t, mpfr_prec_t, void *));
-__MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_pow (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_pow_si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_pow_ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_ui_pow_ui (mpfr_ptr, unsigned long, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_ui_pow (mpfr_ptr, unsigned long, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_pow_z (mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_sqrt (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sqrt_ui (mpfr_ptr, unsigned long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_rec_sqrt (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_add (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_add_ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub_ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_ui_sub (mpfr_ptr, unsigned long, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul_ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_ui_div (mpfr_ptr, unsigned long, mpfr_srcptr,
+ mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_add_si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub_si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_si_sub (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul_si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_si_div (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_add_d (mpfr_ptr, mpfr_srcptr, double, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub_d (mpfr_ptr, mpfr_srcptr, double, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_d_sub (mpfr_ptr, double, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul_d (mpfr_ptr, mpfr_srcptr, double, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_d (mpfr_ptr, mpfr_srcptr, double, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_d_div (mpfr_ptr, double, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_sqr (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_const_pi (mpfr_ptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_const_log2 (mpfr_ptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_const_euler (mpfr_ptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_const_catalan (mpfr_ptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_agm (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_log (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_log2 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_log10 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_log1p (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_log_ui (mpfr_ptr, unsigned long, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_exp (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_exp2 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_exp10 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_expm1 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_eint (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_li2 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_cmp (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_cmp3 (mpfr_srcptr, mpfr_srcptr, int);
+__MPFR_DECLSPEC int mpfr_cmp_d (mpfr_srcptr, double);
+__MPFR_DECLSPEC int mpfr_cmp_ld (mpfr_srcptr, long double);
+__MPFR_DECLSPEC int mpfr_cmpabs (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_cmp_ui (mpfr_srcptr, unsigned long);
+__MPFR_DECLSPEC int mpfr_cmp_si (mpfr_srcptr, long);
+__MPFR_DECLSPEC int mpfr_cmp_ui_2exp (mpfr_srcptr, unsigned long, mpfr_exp_t);
+__MPFR_DECLSPEC int mpfr_cmp_si_2exp (mpfr_srcptr, long, mpfr_exp_t);
+__MPFR_DECLSPEC void mpfr_reldiff (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_eq (mpfr_srcptr, mpfr_srcptr, unsigned long);
+__MPFR_DECLSPEC int mpfr_sgn (mpfr_srcptr);
+
+__MPFR_DECLSPEC int mpfr_mul_2exp (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_2exp (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul_2ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_2ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_mul_2si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_2si (mpfr_ptr, mpfr_srcptr, long, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_rint (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_roundeven (mpfr_ptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_round (mpfr_ptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_trunc (mpfr_ptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_ceil (mpfr_ptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_floor (mpfr_ptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_rint_roundeven (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_rint_round (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_rint_trunc (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_rint_ceil (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_rint_floor (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_frac (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_modf (mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_remquo (mpfr_ptr, long*, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_remainder (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fmod (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fmodquo (mpfr_ptr, long*, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_fits_ulong_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_slong_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_uint_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_sint_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_ushort_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_sshort_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_uintmax_p (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fits_intmax_p (mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC void mpfr_extract (mpz_ptr, mpfr_srcptr, unsigned int);
+__MPFR_DECLSPEC void mpfr_swap (mpfr_ptr, mpfr_ptr);
+__MPFR_DECLSPEC void mpfr_dump (mpfr_srcptr);
+
+__MPFR_DECLSPEC int mpfr_nan_p (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_inf_p (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_number_p (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_integer_p (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_zero_p (mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_regular_p (mpfr_srcptr);
+
+__MPFR_DECLSPEC int mpfr_greater_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_greaterequal_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_less_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_lessequal_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_lessgreater_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_equal_p (mpfr_srcptr, mpfr_srcptr);
+__MPFR_DECLSPEC int mpfr_unordered_p (mpfr_srcptr, mpfr_srcptr);
+
+__MPFR_DECLSPEC int mpfr_atanh (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_acosh (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_asinh (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cosh (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sinh (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_tanh (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sinh_cosh (mpfr_ptr, mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_sech (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_csch (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_coth (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_acos (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_asin (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_atan (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sin (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sin_cos (mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cos (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_tan (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_atan2 (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sec (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_csc (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cot (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_hypot (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_erf (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_erfc (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cbrt (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+#ifndef _MPFR_NO_DEPRECATED_ROOT /* for the test of this function */
+MPFR_DEPRECATED
+#endif
+__MPFR_DECLSPEC int mpfr_root (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_rootn_ui (mpfr_ptr, mpfr_srcptr, unsigned long,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_gamma (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_gamma_inc (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_beta (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_lngamma (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_lgamma (mpfr_ptr, int *, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_digamma (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_zeta (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_zeta_ui (mpfr_ptr, unsigned long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fac_ui (mpfr_ptr, unsigned long, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_j0 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_j1 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_jn (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_y0 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_y1 (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_yn (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_ai (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_min (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_max (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_dim (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_mul_z (mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_div_z (mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_add_z (mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sub_z (mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_z_sub (mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_cmp_z (mpfr_srcptr, mpz_srcptr);
+
+__MPFR_DECLSPEC int mpfr_fma (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fms (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fmma (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_fmms (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_sum (mpfr_ptr, const mpfr_ptr *, unsigned long,
+ mpfr_rnd_t);
+
+__MPFR_DECLSPEC void mpfr_free_cache (void);
+__MPFR_DECLSPEC void mpfr_free_cache2 (mpfr_free_cache_t);
+__MPFR_DECLSPEC void mpfr_free_pool (void);
+__MPFR_DECLSPEC int mpfr_mp_memory_cleanup (void);
+
+__MPFR_DECLSPEC int mpfr_subnormalize (mpfr_ptr, int, mpfr_rnd_t);
+
+__MPFR_DECLSPEC int mpfr_strtofr (mpfr_ptr, const char *, char **, int,
+ mpfr_rnd_t);
+
+__MPFR_DECLSPEC void mpfr_round_nearest_away_begin (mpfr_t);
+__MPFR_DECLSPEC int mpfr_round_nearest_away_end (mpfr_t, int);
+
+__MPFR_DECLSPEC size_t mpfr_custom_get_size (mpfr_prec_t);
+__MPFR_DECLSPEC void mpfr_custom_init (void *, mpfr_prec_t);
+__MPFR_DECLSPEC void * mpfr_custom_get_significand (mpfr_srcptr);
+__MPFR_DECLSPEC mpfr_exp_t mpfr_custom_get_exp (mpfr_srcptr);
+__MPFR_DECLSPEC void mpfr_custom_move (mpfr_ptr, void *);
+__MPFR_DECLSPEC void mpfr_custom_init_set (mpfr_ptr, int, mpfr_exp_t,
+ mpfr_prec_t, void *);
+__MPFR_DECLSPEC int mpfr_custom_get_kind (mpfr_srcptr);
#if defined (__cplusplus)
}
@@ -742,6 +777,18 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
MPFR_EXTENSION mp_limb_t __gmpfr_local_tab_##_x[((_p)-1)/GMP_NUMB_BITS+1]; \
MPFR_EXTENSION mpfr_t _x = {{(_p),1,__MPFR_EXP_NAN,__gmpfr_local_tab_##_x}}
+#if MPFR_USE_C99_FEATURE
+/* C99 & C11 version: functions with multiple inputs supported */
+#define mpfr_round_nearest_away(func, rop, ...) \
+ (mpfr_round_nearest_away_begin(rop), \
+ mpfr_round_nearest_away_end((rop), func((rop), __VA_ARGS__, MPFR_RNDN)))
+#else
+/* C89 version: function with one input supported */
+#define mpfr_round_nearest_away(func, rop, op) \
+ (mpfr_round_nearest_away_begin(rop), \
+ mpfr_round_nearest_away_end((rop), func((rop), (op), MPFR_RNDN)))
+#endif
+
/* Fast access macros to replace function interface.
If the USER don't want to use the macro interface, let him make happy
even if it produces faster and smaller code. */
@@ -761,8 +808,12 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
#define MPFR_VALUE_OF(x) (0 ? (x) : (x))
#define mpfr_get_prec(_x) MPFR_VALUE_OF((_x)->_mpfr_prec)
#define mpfr_get_exp(_x) MPFR_VALUE_OF((_x)->_mpfr_exp)
-/* Note: if need be, the MPFR_VALUE_OF can be used for other expressions
- (of any type). Thanks to Wojtek Lerch and Tim Rentsch for the idea. */
+/* Note 1: If need be, the MPFR_VALUE_OF can be used for other expressions
+ (of any type). Thanks to Wojtek Lerch and Tim Rentsch for the idea.
+ Note 2: Defining mpfr_get_exp() as a macro has the effect to disable
+ the check that the argument is a pure FP number (done in the function);
+ this increases the risk of undetected error and makes debugging more
+ complex. Is it really worth in practice? (Potential FIXME) */
#define mpfr_round(a,b) mpfr_rint((a), (b), MPFR_RNDNA)
#define mpfr_trunc(a,b) mpfr_rint((a), (b), MPFR_RNDZ)
@@ -782,12 +833,13 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
/* When using GCC, optimize certain common comparisons and affectations.
- + Remove ICC since it defines __GNUC__ but produces a
- huge number of warnings if you use this code.
+ + Remove some Intel C/C++ (ICC) versions since they now define __GNUC__
+ but produce a huge number of warnings if you use this code.
VL: I couldn't reproduce a single warning when enabling these macros
- with icc 10.1 20080212 on Itanium. But with this version, __ICC isn't
- defined (__INTEL_COMPILER is, though), so that these macros are enabled
- anyway. Checking with other ICC versions is needed. Possibly detect
+ with icc 10.1 20080212 on Itanium. But with this version, the obsolete
+ __ICC macro isn't defined (__INTEL_COMPILER is, though), so that these
+ macros are enabled anyway. Checking with other ICC versions is needed.
+ For now, !defined(__ICC) seems to be the right test. Possibly detect
whether warnings are produced or not with a configure test.
+ Remove C++ too, since it complains too much. */
/* Added casts to improve robustness in case of undefined behavior and
@@ -799,8 +851,8 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
are OK since if X is a constant expression, then (unsigned long) X is
also a constant expression, so that the optimizations still work. The
warnings are probably related to the following two bugs:
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
and the casts could be removed once these bugs are fixed.
Casts shouldn't be used on the generic calls (to the ..._2exp functions),
where implicit conversions are performed. Indeed, having at least one
@@ -812,6 +864,7 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
be used. */
#if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
#if (__GNUC__ >= 2)
+
#undef mpfr_cmp_ui
/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0.
But warning! mpfr_sgn is specified as a macro in the API, thus the macro
@@ -820,11 +873,13 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
(__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
(mpfr_sgn) (_f) : \
mpfr_cmp_ui_2exp ((_f), (_u), 0))
+
#undef mpfr_cmp_si
#define mpfr_cmp_si(_f,_s) \
(__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) : \
mpfr_cmp_si_2exp ((_f), (_s), 0))
+
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
#undef mpfr_set_ui
#define mpfr_set_ui(_f,_u,_r) \
@@ -836,11 +891,43 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
(mpfr_void) (_r); 0; }) : \
mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
#endif
+
#undef mpfr_set_si
#define mpfr_set_si(_f,_s,_r) \
(__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \
mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+/* If the source is a constant number that is a power of 2,
+ optimize the call */
+#undef mpfr_mul_ui
+#define mpfr_mul_ui(_f, _g, _u,_r) \
+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) >= 1 && \
+ ((mpfr_ulong) (_u) & ((mpfr_ulong) (_u) - 1)) == 0 ? \
+ mpfr_mul_2si((_f), (_g), __builtin_ctzl (_u), (_r)) : \
+ mpfr_mul_ui ((_f), (_g), (_u), (_r)))
+#undef mpfr_div_ui
+#define mpfr_div_ui(_f, _g, _u,_r) \
+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) >= 1 && \
+ ((mpfr_ulong) (_u) & ((mpfr_ulong) (_u) - 1)) == 0 ? \
+ mpfr_mul_2si((_f), (_g), - __builtin_ctzl (_u), (_r)) : \
+ mpfr_div_ui ((_f), (_g), (_u), (_r)))
+#endif
+
+/* If the source is a constant number that is non-negative,
+ optimize the call */
+#undef mpfr_mul_si
+#define mpfr_mul_si(_f, _g, _s,_r) \
+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
+ mpfr_mul_ui ((_f), (_g), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \
+ mpfr_mul_si ((_f), (_g), (_s), (_r)))
+#undef mpfr_div_si
+#define mpfr_div_si(_f, _g, _s,_r) \
+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
+ mpfr_div_ui ((_f), (_g), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \
+ mpfr_div_si ((_f), (_g), (_s), (_r)))
+
#endif
#endif
@@ -894,12 +981,14 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
( mpfr_init(x), mpfr_set_ld((x), (d), (rnd)) )
#define mpfr_init_set_z(x, i, rnd) \
( mpfr_init(x), mpfr_set_z((x), (i), (rnd)) )
+#ifndef MPFR_USE_MINI_GMP
#define mpfr_init_set_q(x, i, rnd) \
( mpfr_init(x), mpfr_set_q((x), (i), (rnd)) )
-#define mpfr_init_set(x, y, rnd) \
- ( mpfr_init(x), mpfr_set((x), (y), (rnd)) )
#define mpfr_init_set_f(x, y, rnd) \
( mpfr_init(x), mpfr_set_f((x), (y), (rnd)) )
+#endif
+#define mpfr_init_set(x, y, rnd) \
+ ( mpfr_init(x), mpfr_set((x), (y), (rnd)) )
/* Compatibility layer -- obsolete functions and macros */
/* Note: it is not possible to output warnings, unless one defines
@@ -923,10 +1012,6 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
#ifndef mpz_set_fr
# define mpz_set_fr mpfr_get_z
#endif
-#define mpfr_add_one_ulp(x,r) \
- (mpfr_sgn (x) > 0 ? mpfr_nextabove (x) : mpfr_nextbelow (x))
-#define mpfr_sub_one_ulp(x,r) \
- (mpfr_sgn (x) > 0 ? mpfr_nextbelow (x) : mpfr_nextabove (x))
#define mpfr_get_z_exp mpfr_get_z_2exp
#define mpfr_custom_get_mantissa mpfr_custom_get_significand
@@ -950,7 +1035,8 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
*/
#if (defined (INTMAX_C) && defined (UINTMAX_C) && !defined(__cplusplus)) || \
defined (MPFR_USE_INTMAX_T) || \
- defined (_STDINT_H) || defined (_STDINT_H_) || defined (_STDINT)
+ defined (_STDINT_H) || defined (_STDINT_H_) || defined (_STDINT) || \
+ defined (_SYS_STDINT_H_) /* needed for FreeBSD */
# ifndef _MPFR_H_HAVE_INTMAX_T
# define _MPFR_H_HAVE_INTMAX_T 1
@@ -964,14 +1050,12 @@ extern "C" {
#define mpfr_set_uj_2exp __gmpfr_set_uj_2exp
#define mpfr_get_sj __gmpfr_mpfr_get_sj
#define mpfr_get_uj __gmpfr_mpfr_get_uj
-__MPFR_DECLSPEC int mpfr_set_sj _MPFR_PROTO ((mpfr_t, intmax_t, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_sj_2exp _MPFR_PROTO ((mpfr_t, intmax_t, intmax_t, mpfr_rnd_t));
-__MPFR_DECLSPEC int mpfr_set_uj _MPFR_PROTO ((mpfr_t, uintmax_t, mpfr_rnd_t));
-__MPFR_DECLSPEC int
- mpfr_set_uj_2exp _MPFR_PROTO ((mpfr_t, uintmax_t, intmax_t, mpfr_rnd_t));
-__MPFR_DECLSPEC intmax_t mpfr_get_sj _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
-__MPFR_DECLSPEC uintmax_t mpfr_get_uj _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_set_sj (mpfr_t, intmax_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_sj_2exp (mpfr_t, intmax_t, intmax_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_uj (mpfr_t, uintmax_t, mpfr_rnd_t);
+__MPFR_DECLSPEC int mpfr_set_uj_2exp (mpfr_t, uintmax_t, intmax_t, mpfr_rnd_t);
+__MPFR_DECLSPEC intmax_t mpfr_get_sj (mpfr_srcptr, mpfr_rnd_t);
+__MPFR_DECLSPEC uintmax_t mpfr_get_uj (mpfr_srcptr, mpfr_rnd_t);
#if defined (__cplusplus)
}
@@ -992,13 +1076,17 @@ extern "C" {
#define mpfr_inp_str __gmpfr_inp_str
#define mpfr_out_str __gmpfr_out_str
-__MPFR_DECLSPEC size_t mpfr_inp_str _MPFR_PROTO ((mpfr_ptr, FILE*, int,
- mpfr_rnd_t));
-__MPFR_DECLSPEC size_t mpfr_out_str _MPFR_PROTO ((FILE*, int, size_t,
- mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC size_t mpfr_inp_str (mpfr_ptr, FILE*, int, mpfr_rnd_t);
+__MPFR_DECLSPEC size_t mpfr_out_str (FILE*, int, size_t, mpfr_srcptr,
+ mpfr_rnd_t);
+#ifndef MPFR_USE_MINI_GMP
#define mpfr_fprintf __gmpfr_fprintf
-__MPFR_DECLSPEC int mpfr_fprintf _MPFR_PROTO ((FILE*, __gmp_const char*,
- ...));
+__MPFR_DECLSPEC int mpfr_fprintf (FILE*, const char*, ...);
+#endif
+#define mpfr_fpif_export __gmpfr_fpif_export
+#define mpfr_fpif_import __gmpfr_fpif_import
+__MPFR_DECLSPEC int mpfr_fpif_export (FILE*, mpfr_ptr);
+__MPFR_DECLSPEC int mpfr_fpif_import (mpfr_ptr, FILE*);
#if defined (__cplusplus)
}
@@ -1021,13 +1109,10 @@ extern "C" {
#define mpfr_vasprintf __gmpfr_vasprintf
#define mpfr_vsprintf __gmpfr_vsprintf
#define mpfr_vsnprintf __gmpfr_vsnprintf
-__MPFR_DECLSPEC int mpfr_vprintf _MPFR_PROTO ((__gmp_const char*, va_list));
-__MPFR_DECLSPEC int mpfr_vasprintf _MPFR_PROTO ((char**, __gmp_const char*,
- va_list));
-__MPFR_DECLSPEC int mpfr_vsprintf _MPFR_PROTO ((char*, __gmp_const char*,
- va_list));
-__MPFR_DECLSPEC int mpfr_vsnprintf _MPFR_PROTO ((char*, size_t,
- __gmp_const char*, va_list));
+__MPFR_DECLSPEC int mpfr_vprintf (const char*, va_list);
+__MPFR_DECLSPEC int mpfr_vasprintf (char**, const char*, va_list);
+__MPFR_DECLSPEC int mpfr_vsprintf (char*, const char*, va_list);
+__MPFR_DECLSPEC int mpfr_vsnprintf (char*, size_t, const char*, va_list);
#if defined (__cplusplus)
}
@@ -1048,8 +1133,7 @@ extern "C" {
#endif
#define mpfr_vfprintf __gmpfr_vfprintf
-__MPFR_DECLSPEC int mpfr_vfprintf _MPFR_PROTO ((FILE*, __gmp_const char*,
- va_list));
+__MPFR_DECLSPEC int mpfr_vfprintf (FILE*, const char*, va_list);
#if defined (__cplusplus)
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mpn_exp.c b/Build/source/libs/mpfr/mpfr-src/src/mpn_exp.c
index 70417b870f1..de6e11fa088 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mpn_exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mpn_exp.c
@@ -91,7 +91,9 @@ mpfr_mpn_exp (mp_limb_t *a, mpfr_exp_t *exp_r, int b, mpfr_exp_t e, size_t n)
n1 = (n * GMP_NUMB_BITS - bits) / GMP_NUMB_BITS;
/* square of A : {c+2n1, 2(n-n1)} = {a+n1, n-n1}^2 */
- mpn_sqr_n (c + 2 * n1, a + n1, n - n1);
+ /* TODO: we should use a short square here, but this needs to redo
+ the error analysis */
+ mpn_sqr (c + 2 * n1, a + n1, n - n1);
/* set {c+n, 2n1-n} to 0 : {c, n} = {a, n}^2*K^n */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mul.c b/Build/source/libs/mpfr/mpfr-src/src/mul.c
index 31169eb4f86..54f8d81704d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mul.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mul.c
@@ -28,8 +28,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
/* Check if we have to check the result of mpfr_mul.
TODO: Find a better (and faster?) check than using old implementation */
-#ifdef MPFR_WANT_ASSERT
-# if MPFR_WANT_ASSERT >= 3
+#if MPFR_WANT_ASSERT >= 2
int mpfr_mul2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode);
static int
@@ -57,7 +56,7 @@ mpfr_mul3 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
if (MPFR_IS_INF(c) || MPFR_NOTZERO(c))
{
- MPFR_SET_SIGN(a,sign_product);
+ MPFR_SET_SIGN(a, sign_product);
MPFR_SET_INF(a);
MPFR_RET(0); /* exact */
}
@@ -164,6 +163,9 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpfr_t ta, tb, tc;
int inexact1, inexact2;
+ if (rnd_mode == MPFR_RNDF)
+ return mpfr_mul2 (a, b, c, rnd_mode);
+
mpfr_init2 (ta, MPFR_PREC (a));
mpfr_init2 (tb, MPFR_PREC (b));
mpfr_init2 (tc, MPFR_PREC (c));
@@ -171,22 +173,25 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_ASSERTN (mpfr_set (tc, c, MPFR_RNDN) == 0);
inexact2 = mpfr_mul3 (ta, tb, tc, rnd_mode);
- inexact1 = mpfr_mul2 (a, b, c, rnd_mode);
- if (mpfr_cmp (ta, a) || inexact1*inexact2 < 0
- || (inexact1*inexact2 == 0 && (inexact1|inexact2) != 0))
+ inexact1 = mpfr_mul2 (a, b, c, rnd_mode);
+ if (MPFR_IS_NAN (ta) && MPFR_IS_NAN (a))
+ {
+ /* Getting both NaN is OK. */
+ }
+ else if (! mpfr_equal_p (ta, a) || ! SAME_SIGN (inexact1, inexact2))
{
fprintf (stderr, "mpfr_mul return different values for %s\n"
- "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
+ "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nb = ",
mpfr_print_rnd_mode (rnd_mode),
MPFR_PREC (a), MPFR_PREC (b), MPFR_PREC (c));
- mpfr_out_str (stderr, 16, 0, tb, MPFR_RNDN);
- fprintf (stderr, "\nC = ");
- mpfr_out_str (stderr, 16, 0, tc, MPFR_RNDN);
- fprintf (stderr, "\nOldMul: ");
- mpfr_out_str (stderr, 16, 0, ta, MPFR_RNDN);
- fprintf (stderr, "\nNewMul: ");
- mpfr_out_str (stderr, 16, 0, a, MPFR_RNDN);
- fprintf (stderr, "\nNewInexact = %d | OldInexact = %d\n",
+ mpfr_fdump (stderr, b);
+ fprintf (stderr, "c = ");
+ mpfr_fdump (stderr, c);
+ fprintf (stderr, "OldMul: ");
+ mpfr_fdump (stderr, ta);
+ fprintf (stderr, "NewMul: ");
+ mpfr_fdump (stderr, a);
+ fprintf (stderr, "NewInexact = %d | OldInexact = %d\n",
inexact1, inexact2);
MPFR_ASSERTN(0);
}
@@ -196,27 +201,493 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
# define mpfr_mul mpfr_mul2
-# endif
-#endif
+
+#endif /* MPFR_WANT_ASSERT >= 2 */
/****** END OF CHECK *******/
/* Multiply 2 mpfr_t */
+#if !defined(MPFR_GENERIC_ABI)
+
+/* Special code for prec(a) < GMP_NUMB_BITS and
+ prec(b), prec(c) <= GMP_NUMB_BITS.
+ Note: this code was copied in sqr.c, function mpfr_sqr_1 (this saves a few cycles
+ with respect to have this function exported). As a consequence, any change here
+ should be reported in mpfr_sqr_1. */
+static int
+mpfr_mul_1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mp_limb_t a0;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mp_limb_t b0 = MPFR_MANT(b)[0];
+ mp_limb_t c0 = MPFR_MANT(c)[0];
+ mpfr_exp_t ax;
+ mpfr_prec_t sh = GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb, mask = MPFR_LIMB_MASK(sh);
+
+ /* When prec(b), prec(c) <= GMP_NUMB_BITS / 2, we could replace umul_ppmm
+ by a limb multiplication as follows, but we assume umul_ppmm is as fast
+ as a limb multiplication on modern processors:
+ a0 = (b0 >> (GMP_NUMB_BITS / 2)) * (c0 >> (GMP_NUMB_BITS / 2));
+ sb = 0;
+ */
+ ax = MPFR_GET_EXP(b) + MPFR_GET_EXP(c);
+ umul_ppmm (a0, sb, b0, c0);
+ if (a0 < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ /* TODO: This is actually an addition with carry (no shifts and no OR
+ needed in asm). Make sure that GCC generates optimized code once
+ it supports carry-in. */
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+
+ MPFR_SIGN(a) = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ if (ax == __gmpfr_emin - 1 && ap[0] == ~mask &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either ax < emin - 1
+ (b) or ax = emin - 1 and ap[0] = 1000....000 and rb = sb = 0 */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 ||
+ (ap[0] == MPFR_LIMB_HIGHBIT && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ if (ap[0] == 0)
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* Special code for prec(a) = GMP_NUMB_BITS and
+ prec(b), prec(c) <= GMP_NUMB_BITS. */
+static int
+mpfr_mul_1n (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mp_limb_t a0;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mp_limb_t b0 = MPFR_MANT(b)[0];
+ mp_limb_t c0 = MPFR_MANT(c)[0];
+ mpfr_exp_t ax;
+ mp_limb_t rb, sb;
+
+ ax = MPFR_GET_EXP(b) + MPFR_GET_EXP(c);
+ umul_ppmm (a0, sb, b0, c0);
+ if (a0 < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ /* TODO: This is actually an addition with carry (no shifts and no OR
+ needed in asm). Make sure that GCC generates optimized code once
+ it supports carry-in. */
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ }
+ rb = sb & MPFR_LIMB_HIGHBIT;
+ sb = sb & ~MPFR_LIMB_HIGHBIT;
+ ap[0] = a0;
+
+ MPFR_SIGN(a) = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow.
+ Note: this case can only occur when the initial a0 (after the umul_ppmm
+ call above) had its most significant bit 0, since the largest a0 is
+ obtained for b0 = c0 = B-1 where B=2^GMP_NUMB_BITS, thus b0*c0 <= (B-1)^2
+ thus a0 <= B-2. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ if (ax == __gmpfr_emin - 1 && ap[0] == ~MPFR_LIMB_ZERO &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either ax < emin - 1
+ (b) or ax = emin - 1 and ap[0] = 1000....000 and rb = sb = 0 */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 ||
+ (ap[0] == MPFR_LIMB_HIGHBIT && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & MPFR_LIMB_ONE) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE;
+ if (ap[0] == 0)
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* Special code for GMP_NUMB_BITS < prec(a) < 2*GMP_NUMB_BITS and
+ GMP_NUMB_BITS < prec(b), prec(c) <= 2*GMP_NUMB_BITS.
+ Note: this code was copied in sqr.c, function mpfr_sqr_2 (this saves a few cycles
+ with respect to have this function exported). As a consequence, any change here
+ should be reported in mpfr_sqr_2. */
+static int
+mpfr_mul_2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mp_limb_t h, l, u, v, w;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mpfr_exp_t ax = MPFR_GET_EXP(b) + MPFR_GET_EXP(c);
+ mpfr_prec_t sh = 2 * GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb, sb2, mask = MPFR_LIMB_MASK(sh);
+ mp_limb_t *bp = MPFR_MANT(b), *cp = MPFR_MANT(c);
+
+ /* we store the 4-limb product in h=ap[1], l=ap[0], sb=ap[-1], sb2=ap[-2] */
+ umul_ppmm (h, l, bp[1], cp[1]);
+ umul_ppmm (u, v, bp[1], cp[0]);
+ l += u;
+ h += (l < u);
+ umul_ppmm (u, w, bp[0], cp[1]);
+ l += u;
+ h += (l < u);
+
+ /* now the full product is {h, l, v + w + high(b0*c0), low(b0*c0)},
+ where the lower part contributes to less than 3 ulps to {h, l} */
+
+ /* If h has its most significant bit set and the low sh-1 bits of l are not
+ 000...000 nor 111...111 nor 111...110, then we can round correctly;
+ if h has zero as most significant bit, we have to shift left h and l,
+ thus if the low sh-2 bits are not 000...000 nor 111...111 nor 111...110,
+ then we can round correctly. To avoid an extra test we consider the latter
+ case (if we can round, we can also round in the former case).
+ For sh <= 3, we have mask <= 7, thus (mask>>2) <= 1, and the approximation
+ cannot be enough. */
+ if (MPFR_LIKELY(((l + 2) & (mask >> 2)) > 2))
+ sb = sb2 = 1; /* result cannot be exact in that case */
+ else
+ {
+ umul_ppmm (sb, sb2, bp[0], cp[0]);
+ /* the full product is {h, l, sb + v + w, sb2} */
+ sb += v;
+ l += (sb < v);
+ h += (l == 0) && (sb < v);
+ sb += w;
+ l += (sb < w);
+ h += (l == 0) && (sb < w);
+ }
+ if (h < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ h = (h << 1) | (l >> (GMP_NUMB_BITS - 1));
+ l = (l << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ /* no need to shift sb2 since we only want to know if it is zero or not */
+ }
+ ap[1] = h;
+ rb = l & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= ((l & mask) ^ rb) | sb2;
+ ap[0] = l & ~mask;
+
+ MPFR_SIGN(a) = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ if (ax == __gmpfr_emin - 1 &&
+ ap[1] == MPFR_LIMB_MAX &&
+ ap[0] == ~mask &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* for RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 ||
+ (ap[1] == MPFR_LIMB_HIGHBIT && ap[0] == 0 && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ if (ap[1] == 0)
+ {
+ ap[1] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* Special code for 2*GMP_NUMB_BITS < prec(a) < 3*GMP_NUMB_BITS and
+ 2*GMP_NUMB_BITS < prec(b), prec(c) <= 3*GMP_NUMB_BITS. */
+static int
+mpfr_mul_3 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mp_limb_t a0, a1, a2, h, l, cy;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mpfr_exp_t ax = MPFR_GET_EXP(b) + MPFR_GET_EXP(c);
+ mpfr_prec_t sh = 3 * GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb, sb2, mask = MPFR_LIMB_MASK(sh);
+ mp_limb_t *bp = MPFR_MANT(b), *cp = MPFR_MANT(c);
+
+ /* we store the upper 3-limb product in a2, a1, a0:
+ b2*c2, b2*c1+b1*c2, b2*c0+b1*c1+b0*c2 */
+ umul_ppmm (a2, a1, bp[2], cp[2]);
+ umul_ppmm (h, a0, bp[2], cp[1]);
+ a1 += h;
+ a2 += (a1 < h);
+ umul_ppmm (h, l, bp[1], cp[2]);
+ a1 += h;
+ a2 += (a1 < h);
+ a0 += l;
+ cy = a0 < l; /* carry in a1 */
+ umul_ppmm (h, l, bp[2], cp[0]);
+ a0 += h;
+ cy += (a0 < h);
+ umul_ppmm (h, l, bp[1], cp[1]);
+ a0 += h;
+ cy += (a0 < h);
+ umul_ppmm (h, l, bp[0], cp[2]);
+ a0 += h;
+ cy += (a0 < h);
+ /* now propagate cy */
+ a1 += cy;
+ a2 += (a1 < cy);
+
+ /* Now the approximate product {a2, a1, a0} has an error of less than
+ 5 ulps (3 ulps for the ignored low limbs of b2*c0+b1*c1+b0*c2,
+ plus 2 ulps for the ignored b1*c0+b0*c1 (plus b0*c0)).
+ Since we might shift by 1 bit, we make sure the low sh-2 bits of a0
+ are not 0, -1, -2, -3 or -4. */
+
+ if (MPFR_LIKELY(((a0 + 4) & (mask >> 2)) > 4))
+ sb = sb2 = 1; /* result cannot be exact in that case */
+ else
+ {
+ mp_limb_t p[6];
+ mpn_mul_n (p, bp, cp, 3);
+ a2 = p[5];
+ a1 = p[4];
+ a0 = p[3];
+ sb = p[2];
+ sb2 = p[1] | p[0];
+ }
+ if (a2 < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ a2 = (a2 << 1) | (a1 >> (GMP_NUMB_BITS - 1));
+ a1 = (a1 << 1) | (a0 >> (GMP_NUMB_BITS - 1));
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ /* no need to shift sb2: we only need to know if it is zero or not */
+ }
+ ap[2] = a2;
+ ap[1] = a1;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= ((a0 & mask) ^ rb) | sb2;
+ ap[0] = a0 & ~mask;
+
+ MPFR_SIGN(a) = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ if (ax == __gmpfr_emin - 1 &&
+ ap[2] == MPFR_LIMB_MAX &&
+ ap[1] == MPFR_LIMB_MAX &&
+ ap[0] == ~mask &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* for RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 ||
+ (ap[2] == MPFR_LIMB_HIGHBIT && ap[1] == 0 && ap[0] == 0
+ && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ ap[2] += (ap[1] == 0) && (ap[0] == 0);
+ if (ap[2] == 0)
+ {
+ ap[2] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+#endif /* !defined(MPFR_GENERIC_ABI) */
+
/* Note: mpfr_sqr will call mpfr_mul if bn > MPFR_SQR_THRESHOLD,
in order to use Mulders' mulhigh, which is handled only here
to avoid partial code duplication. There is some overhead due
to the additional tests, but slowdown should not be noticeable
as this code is not executed in very small precisions. */
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
int sign, inexact;
mpfr_exp_t ax, ax2;
mp_limb_t *tmp;
mp_limb_t b1;
- mpfr_prec_t bq, cq;
+ mpfr_prec_t aq, bq, cq;
mp_size_t bn, cn, tn, k, threshold;
MPFR_TMP_DECL (marker);
@@ -272,13 +743,35 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_RET (0);
}
}
+
+ aq = MPFR_GET_PREC (a);
+ bq = MPFR_GET_PREC (b);
+ cq = MPFR_GET_PREC (c);
+
+#if !defined(MPFR_GENERIC_ABI)
+ if (aq == bq && aq == cq)
+ {
+ if (aq < GMP_NUMB_BITS)
+ return mpfr_mul_1 (a, b, c, rnd_mode, aq);
+
+ if (GMP_NUMB_BITS < aq && aq < 2 * GMP_NUMB_BITS)
+ return mpfr_mul_2 (a, b, c, rnd_mode, aq);
+
+ if (aq == GMP_NUMB_BITS)
+ return mpfr_mul_1n (a, b, c, rnd_mode);
+
+ if (2 * GMP_NUMB_BITS < aq && aq < 3 * GMP_NUMB_BITS)
+ return mpfr_mul_3 (a, b, c, rnd_mode, aq);
+ }
+#endif
+
sign = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
ax = MPFR_GET_EXP (b) + MPFR_GET_EXP (c);
/* 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. */
- /* FIXME: Useful since we do an exponent check after ?
+ /* FIXME: Useful since we do an exponent check after?
* It is useful iff the precision is big, there is an overflow
* and we are doing further mults...*/
#ifdef HUGE
@@ -289,9 +782,6 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
sign);
#endif
- bq = MPFR_PREC (b);
- cq = MPFR_PREC (c);
-
MPFR_ASSERTN ((mpfr_uprec_t) bq + cq <= MPFR_PREC_MAX);
bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
@@ -300,7 +790,7 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
tn = MPFR_PREC2LIMBS (bq + cq);
MPFR_ASSERTD (tn <= k); /* tn <= k, thus no int overflow */
- /* Check for no size_t overflow*/
+ /* Check for no size_t overflow. */
MPFR_ASSERTD ((size_t) k <= ((size_t) -1) / MPFR_BYTES_PER_MP_LIMB);
MPFR_TMP_MARK (marker);
tmp = MPFR_TMP_LIMBS_ALLOC (k);
@@ -316,19 +806,19 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
cn = zn;
}
MPFR_ASSERTD (bn >= cn);
- if (MPFR_LIKELY (bn <= 2))
+ if (bn <= 2)
{
+ /* The 3 cases perform the same first operation. */
+ umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
if (bn == 1)
{
/* 1 limb * 1 limb */
- umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
b1 = tmp[1];
}
else if (MPFR_UNLIKELY (cn == 1))
{
/* 2 limbs * 1 limb */
mp_limb_t t;
- umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
umul_ppmm (tmp[2], t, MPFR_MANT (b)[1], MPFR_MANT (c)[0]);
add_ssaaaa (tmp[2], tmp[1], tmp[2], tmp[1], 0, t);
b1 = tmp[2];
@@ -338,7 +828,6 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* 2 limbs * 2 limbs */
mp_limb_t t1, t2, t3;
/* First 2 limbs * 1 limb */
- umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
umul_ppmm (tmp[2], t1, MPFR_MANT (b)[1], MPFR_MANT (c)[0]);
add_ssaaaa (tmp[2], tmp[1], tmp[2], tmp[1], 0, t1);
/* Second, the other 2 limbs * 1 limb product */
@@ -358,7 +847,7 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
/* Mulders' mulhigh. This code can also be used via mpfr_sqr,
hence the tests b != c. */
- if (MPFR_UNLIKELY (bn > (threshold = b != c ?
+ if (MPFR_UNLIKELY (cn > (threshold = b != c ?
MPFR_MUL_THRESHOLD : MPFR_SQR_THRESHOLD)))
{
mp_limb_t *bp, *cp;
@@ -369,7 +858,8 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
exact values are a nightmare for the short product trick */
bp = MPFR_MANT (b);
cp = MPFR_MANT (c);
- MPFR_ASSERTN (threshold >= 1);
+ MPFR_STAT_STATIC_ASSERT (MPFR_MUL_THRESHOLD >= 1 &&
+ MPFR_SQR_THRESHOLD >= 1);
if (MPFR_UNLIKELY ((bp[0] == 0 && bp[1] == 0) ||
(cp[0] == 0 && cp[1] == 0)))
{
@@ -384,7 +874,7 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD (bn > 0);
} /* This must end since the most significant limb is != 0 */
- /* Check for c too: if b ==c, will do nothing */
+ /* Check for c too: if b == c, this will do nothing */
while (*cp == 0)
{
cp++;
@@ -392,7 +882,7 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPFR_ASSERTD (cn > 0);
} /* This must end since the most significant limb is != 0 */
- /* It is not the faster way, but it is safer */
+ /* It is not the fastest way, but it is safer. */
MPFR_SET_SAME_SIGN (b_tmp, b);
MPFR_SET_EXP (b_tmp, MPFR_GET_EXP (b));
MPFR_PREC (b_tmp) = bn * GMP_NUMB_BITS;
@@ -426,14 +916,14 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Check if MulHigh can produce a roundable result.
We may lose 1 bit due to RNDN, 1 due to final shift. */
- if (MPFR_UNLIKELY (MPFR_PREC (a) > p - 5))
+ if (MPFR_UNLIKELY (aq > p - 5))
{
- if (MPFR_UNLIKELY (MPFR_PREC (a) > p - 5 + GMP_NUMB_BITS
+ if (MPFR_UNLIKELY (aq > p - 5 + GMP_NUMB_BITS
|| bn <= threshold + 1))
{
/* MulHigh can't produce a roundable result. */
MPFR_LOG_MSG (("mpfr_mulhigh can't be used (%lu VS %lu)\n",
- MPFR_PREC (a), p));
+ aq, p));
goto full_multiply;
}
/* Add one extra limb to mantissa of b and c. */
@@ -462,7 +952,7 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
Mulders' short product */
p = n * GMP_NUMB_BITS - MPFR_INT_CEIL_LOG2 (n + 2);
/* Due to some nasty reasons we can have only 4 bits */
- MPFR_ASSERTD (MPFR_PREC (a) <= p - 4);
+ MPFR_ASSERTD (aq <= p - 4);
if (MPFR_LIKELY (k < 2*n))
{
@@ -470,21 +960,14 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
tmp += 2*n-k; /* `tmp' still points to an area of `k' limbs */
}
}
- MPFR_LOG_MSG (("Use mpfr_mulhigh (%lu VS %lu)\n", MPFR_PREC (a), p));
+ MPFR_LOG_MSG (("Use mpfr_mulhigh (%lu VS %lu)\n", aq, p));
/* Compute an approximation of the product of b and c */
if (b != c)
mpfr_mulhigh_n (tmp + k - 2 * n, bp, cp, n);
else
mpfr_sqrhigh_n (tmp + k - 2 * n, bp, n);
- /* now tmp[0]..tmp[k-1] contains the product of both mantissa,
- with tmp[k-1]>=2^(GMP_NUMB_BITS-2) */
- /* [VL] FIXME: This cannot be true: mpfr_mulhigh_n only
- depends on pointers and n. As k can be arbitrarily larger,
- the result cannot depend on k. And indeed, with GMP compiled
- with --enable-alloca=debug, valgrind was complaining, at
- least because MPFR_RNDRAW at the end tried to compute the
- sticky bit even when not necessary; this problem is fixed,
- but there's at least something wrong with the comment above. */
+ /* now tmp[k-n]..tmp[k-1] contains an approximation of the n upper
+ limbs of the product, with tmp[k-1] >= 2^(GMP_NUMB_BITS-2) */
b1 = tmp[k-1] >> (GMP_NUMB_BITS - 1); /* msb from the product */
/* If the mantissas of b and c are uniformly distributed in (1/2, 1],
@@ -495,12 +978,18 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
tmp[k-n-1..k-1], thus we shift only those limbs */
mpn_lshift (tmp + k - n - 1, tmp + k - n - 1, n + 1, 1);
tmp += k - tn;
+ /* now the approximation is in tmp[tn-n]...tmp[tn-1] */
MPFR_ASSERTD (MPFR_LIMB_MSB (tmp[tn-1]) != 0);
+ /* for RNDF, we simply use RNDZ, since anyway here we multiply numbers
+ with large precisions, thus the overhead of RNDZ is small */
+ if (rnd_mode == MPFR_RNDF)
+ rnd_mode = MPFR_RNDZ;
+
/* if the most significant bit b1 is zero, we have only p-1 correct
bits */
- if (MPFR_UNLIKELY (!mpfr_round_p (tmp, tn, p + b1 - 1, MPFR_PREC(a)
- + (rnd_mode == MPFR_RNDN))))
+ if (MPFR_UNLIKELY (!mpfr_round_p (tmp, tn, p + b1 - 1,
+ aq + (rnd_mode == MPFR_RNDN))))
{
tmp -= k - tn; /* tmp may have changed, FIX IT!!!!! */
goto full_multiply;
@@ -525,9 +1014,9 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
ax2 = ax + (mpfr_exp_t) (b1 - 1);
- MPFR_RNDRAW (inexact, a, tmp, bq+cq, rnd_mode, sign, ax2++);
+ MPFR_RNDRAW (inexact, a, tmp, bq + cq, rnd_mode, sign, ax2++);
MPFR_TMP_FREE (marker);
- MPFR_EXP (a) = ax2; /* Can't use MPFR_SET_EXP: Expo may be out of range */
+ MPFR_EXP (a) = ax2; /* Can't use MPFR_SET_EXP: Expo may be out of range */
MPFR_SET_SIGN (a, sign);
if (MPFR_UNLIKELY (ax2 > __gmpfr_emax))
return mpfr_overflow (a, rnd_mode, sign);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c b/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c
index 981d3272365..10bc2c1645f 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c
@@ -33,7 +33,7 @@ mpfr_mul_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mpfr_rnd_t rnd_mod
("y[%Pu]=%.*Rg inexact=%d",
mpfr_get_prec (y), mpfr_log_prec, y, inexact));
- inexact = MPFR_UNLIKELY(y != x) ? mpfr_set (y, x, rnd_mode) : 0;
+ inexact = (y != x) ? mpfr_set (y, x, rnd_mode) : 0;
if (MPFR_LIKELY( MPFR_IS_PURE_FP(y)) )
{
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mul_d.c b/Build/source/libs/mpfr/mpfr-src/src/mul_d.c
index 2078fee0b3a..00a88abc413 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mul_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mul_d.c
@@ -28,6 +28,7 @@ mpfr_mul_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t d;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_LOG_FUNC
@@ -38,15 +39,14 @@ mpfr_mul_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, d, IEEE_DBL_MANT_DIG);
inexact = mpfr_set_d (d, c, rnd_mode);
- MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTD (inexact == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_mul (a, b, d, rnd_mode);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear(d);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (a, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mul_ui.c b/Build/source/libs/mpfr/mpfr-src/src/mul_ui.c
index c64c5ca26d3..28c296d1cc8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mul_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mul_ui.c
@@ -1,5 +1,4 @@
/* mpfr_mul_ui -- multiply a floating-point number by a machine integer
- mpfr_mul_si -- multiply a floating-point number by a machine integer
Copyright 1999-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -24,7 +23,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-int
+#undef mpfr_mul_ui
+MPFR_HOT_FUNCTION_ATTR int
mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
{
mp_limb_t *yp;
@@ -61,7 +61,7 @@ mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
MPFR_RET (0); /* zero is exact */
}
}
- else if (MPFR_UNLIKELY (u <= 1))
+ else if (u <= 1)
{
if (u < 1)
{
@@ -117,18 +117,3 @@ mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode
MPFR_RET (inexact);
}
-
-int mpfr_mul_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
-{
- int res;
-
- if (u >= 0)
- res = mpfr_mul_ui (y, x, u, rnd_mode);
- else
- {
- res = - mpfr_mul_ui (y, x, - (unsigned long) u,
- MPFR_INVERT_RND (rnd_mode));
- MPFR_CHANGE_SIGN (y);
- }
- return res;
-}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mulders.c b/Build/source/libs/mpfr/mpfr-src/src/mulders.c
index 24811299682..c5bc4a67104 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/mulders.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/mulders.c
@@ -1,4 +1,4 @@
-/* Mulders' MulHigh function (short product)
+/* Mulders' short product, square and division.
Copyright 2005-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -26,6 +26,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
July 25-27, 2011, pages 7-14.
*/
+/* Defines it to 1 to use short div (or 0 for FoldDiv(K)) */
+#define USE_SHORT_DIV 1
+
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
@@ -38,8 +41,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
static short mulhigh_ktab[MPFR_MULHIGH_TAB_SIZE];
#else
static short mulhigh_ktab[] = {MPFR_MULHIGH_TAB};
-#define MPFR_MULHIGH_TAB_SIZE \
- ((mp_size_t) (sizeof(mulhigh_ktab) / sizeof(mulhigh_ktab[0])))
+#define MPFR_MULHIGH_TAB_SIZE (numberof_const (mulhigh_ktab))
#endif
/* Put in rp[n..2n-1] an approximation of the n high limbs
@@ -64,19 +66,6 @@ mpfr_mulhigh_n_basecase (mpfr_limb_ptr rp, mpfr_limb_srcptr up,
/* in total, we neglect less than n*B^n, i.e., n ulps of rp[n]. */
}
-/* Put in rp[0..n] the n+1 low limbs of {up, n} * {vp, n}.
- Assume 2n limbs are allocated at rp. */
-static void
-mpfr_mullow_n_basecase (mpfr_limb_ptr rp, mpfr_limb_srcptr up,
- mpfr_limb_srcptr vp, mp_size_t n)
-{
- mp_size_t i;
-
- rp[n] = mpn_mul_1 (rp, up, n, vp[0]);
- for (i = 1 ; i < n ; i++)
- mpn_addmul_1 (rp + i, up, n - i + 1, vp[i]);
-}
-
/* Put in rp[n..2n-1] an approximation of the n high limbs
of {np, n} * {mp, n}. The error is less than n ulps of rp[n] (and the
approximation is always less or equal to the truncated full product).
@@ -89,7 +78,7 @@ mpfr_mulhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp,
{
mp_size_t k;
- MPFR_ASSERTN (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */
+ MPFR_STAT_STATIC_ASSERT (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */
k = MPFR_LIKELY (n < MPFR_MULHIGH_TAB_SIZE) ? mulhigh_ktab[n] : 3*(n/4);
/* Algorithm ShortMul from [1] requires k >= (n+3)/2, which translates
into k >= (n+4)/2 in the C language. */
@@ -114,6 +103,20 @@ mpfr_mulhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp,
}
}
+#if USE_SHORT_DIV == 0
+/* Put in rp[0..n] the n+1 low limbs of {up, n} * {vp, n}.
+ Assume 2n limbs are allocated at rp. */
+static void
+mpfr_mullow_n_basecase (mpfr_limb_ptr rp, mpfr_limb_srcptr up,
+ mpfr_limb_srcptr vp, mp_size_t n)
+{
+ mp_size_t i;
+
+ rp[n] = mpn_mul_1 (rp, up, n, vp[0]);
+ for (i = 1 ; i < n ; i++)
+ mpn_addmul_1 (rp + i, up, n - i + 1, vp[i]);
+}
+
/* Put in rp[0..n] the n+1 low limbs of {np, n} * {mp, n}.
Assume 2n limbs are allocated at rp. */
void
@@ -122,7 +125,7 @@ mpfr_mullow_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp,
{
mp_size_t k;
- MPFR_ASSERTN (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */
+ MPFR_STAT_STATIC_ASSERT (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */
k = MPFR_LIKELY (n < MPFR_MULHIGH_TAB_SIZE) ? mulhigh_ktab[n] : 3*(n/4);
MPFR_ASSERTD (k == -1 || k == 0 || (2 * k >= n && k < n));
if (k < 0)
@@ -142,12 +145,13 @@ mpfr_mullow_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp,
mpn_add_n (rp + k, rp + k, rp + n, l + 1);
}
}
+#endif
#ifdef MPFR_SQRHIGH_TAB_SIZE
static short sqrhigh_ktab[MPFR_SQRHIGH_TAB_SIZE];
#else
static short sqrhigh_ktab[] = {MPFR_SQRHIGH_TAB};
-#define MPFR_SQRHIGH_TAB_SIZE (sizeof(sqrhigh_ktab) / sizeof(sqrhigh_ktab[0]))
+#define MPFR_SQRHIGH_TAB_SIZE (numberof_const (sqrhigh_ktab))
#endif
/* Put in rp[n..2n-1] an approximation of the n high limbs
@@ -157,7 +161,7 @@ mpfr_sqrhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mp_size_t n)
{
mp_size_t k;
- MPFR_ASSERTN (MPFR_SQRHIGH_TAB_SIZE > 2); /* ensures k < n */
+ MPFR_STAT_STATIC_ASSERT (MPFR_SQRHIGH_TAB_SIZE > 2); /* ensures k < n */
k = MPFR_LIKELY (n < MPFR_SQRHIGH_TAB_SIZE) ? sqrhigh_ktab[n]
: (n+4)/2; /* ensures that k >= (n+3)/2 */
MPFR_ASSERTD (k == -1 || k == 0 || (k >= (n+4)/2 && k < n));
@@ -165,7 +169,7 @@ mpfr_sqrhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mp_size_t n)
/* we can't use mpn_sqr_basecase here, since it requires
n <= SQR_KARATSUBA_THRESHOLD, where SQR_KARATSUBA_THRESHOLD
is not exported by GMP */
- mpn_sqr_n (rp, np, n);
+ mpn_sqr (rp, np, n);
else if (k == 0)
mpfr_mulhigh_n_basecase (rp, np, np, n);
else
@@ -173,7 +177,7 @@ mpfr_sqrhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mp_size_t n)
mp_size_t l = n - k;
mp_limb_t cy;
- mpn_sqr_n (rp + 2 * l, np + l, k); /* fills rp[2l..2n-1] */
+ mpn_sqr (rp + 2 * l, np + l, k); /* fills rp[2l..2n-1] */
mpfr_mulhigh_n (rp, np, np + k, l); /* fills rp[l-1..2l-1] */
/* {rp+n-1,l+1} += 2 * {rp+l-1,l+1} */
cy = mpn_lshift (rp + l - 1, rp + l - 1, l + 1, 1);
@@ -182,15 +186,13 @@ mpfr_sqrhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mp_size_t n)
}
}
+#if USE_SHORT_DIV == 1
+
#ifdef MPFR_DIVHIGH_TAB_SIZE
static short divhigh_ktab[MPFR_DIVHIGH_TAB_SIZE];
#else
static short divhigh_ktab[] = {MPFR_DIVHIGH_TAB};
-#define MPFR_DIVHIGH_TAB_SIZE (sizeof(divhigh_ktab) / sizeof(divhigh_ktab[0]))
-#endif
-
-#ifndef __GMPFR_GMP_H__
-#define mpfr_pi1_t gmp_pi1_t /* with a GMP build */
+#define MPFR_DIVHIGH_TAB_SIZE (numberof_const (divhigh_ktab))
#endif
#if !(defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q))
@@ -240,7 +242,7 @@ mpfr_divhigh_n_basecase (mpfr_limb_ptr qp, mpfr_limb_ptr np,
since we truncate the divisor at each step, but since {np,n} < D
originally, the largest possible partial quotient is B-1. */
if (MPFR_UNLIKELY(np[n-1] > d1 || (np[n-1] == d1 && np[n-2] >= d0)))
- q2 = ~ (mp_limb_t) 0;
+ q2 = MPFR_LIMB_MAX;
else
udiv_qr_3by2 (q2, q1, q0, np[n - 1], np[n - 2], np[n - 3],
d1, d0, dinv2.inv32);
@@ -290,7 +292,6 @@ mpfr_divhigh_n_basecase (mpfr_limb_ptr qp, mpfr_limb_ptr np,
This implements the ShortDiv algorithm from reference [1].
*/
-#if 1
mp_limb_t
mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp,
mp_size_t n)
@@ -300,7 +301,7 @@ mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp,
mpfr_limb_ptr tp;
MPFR_TMP_DECL(marker);
- MPFR_ASSERTN (MPFR_MULHIGH_TAB_SIZE >= 15); /* so that 2*(n/3) >= (n+4)/2 */
+ MPFR_STAT_STATIC_ASSERT (MPFR_DIVHIGH_TAB_SIZE >= 15); /* so that 2*(n/3) >= (n+4)/2 */
k = MPFR_LIKELY (n < MPFR_DIVHIGH_TAB_SIZE) ? divhigh_ktab[n] : 2*(n/3);
if (k == 0)
@@ -348,7 +349,9 @@ mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp,
return qh;
}
+
#else /* below is the FoldDiv(K) algorithm from [1] */
+
mp_limb_t
mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp,
mp_size_t n)
diff --git a/Build/source/libs/mpfr/mpfr-src/src/neg.c b/Build/source/libs/mpfr/mpfr-src/src/neg.c
index 7e8fff8b9fb..9456a56c7ab 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/neg.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/neg.c
@@ -27,13 +27,12 @@ mpfr_neg (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
{
if (MPFR_UNLIKELY(a != b))
return mpfr_set4 (a, b, rnd_mode, -MPFR_SIGN(b));
- else if (MPFR_UNLIKELY(MPFR_IS_NAN (b)))
- {
- MPFR_RET_NAN;
- }
else
{
- MPFR_CHANGE_SIGN(a);
- MPFR_RET(0);
+ MPFR_CHANGE_SIGN (a);
+ if (MPFR_UNLIKELY (MPFR_IS_NAN (b)))
+ MPFR_RET_NAN;
+ else
+ MPFR_RET (0);
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/next.c b/Build/source/libs/mpfr/mpfr-src/src/next.c
index e6420f20464..7fd668f6e4e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/next.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/next.c
@@ -21,20 +21,29 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+/* Note concerning the exceptions: In case of NaN result, the NaN flag is
+ * set as usual. No underflow or overflow is generated (this contradicts
+ * the obsolete IEEE 754-1985 standard for Nextafter, but conforms to the
+ * current standard IEEE 754-2008 for nextUp and nextDown).
+ */
+
#include "mpfr-impl.h"
void
mpfr_nexttozero (mpfr_ptr x)
{
- if (MPFR_UNLIKELY(MPFR_IS_INF(x)))
- {
- mpfr_setmax (x, __gmpfr_emax);
- return;
- }
- else if (MPFR_UNLIKELY( MPFR_IS_ZERO(x) ))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
{
- MPFR_CHANGE_SIGN(x);
- mpfr_setmin (x, __gmpfr_emin);
+ if (MPFR_IS_INF (x))
+ {
+ mpfr_setmax (x, __gmpfr_emax);
+ }
+ else
+ {
+ MPFR_ASSERTN (MPFR_IS_ZERO (x));
+ MPFR_CHANGE_SIGN(x);
+ mpfr_setmin (x, __gmpfr_emin);
+ }
}
else
{
@@ -46,18 +55,17 @@ mpfr_nexttozero (mpfr_ptr x)
MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC(x));
xp = MPFR_MANT(x);
mpn_sub_1 (xp, xp, xn, MPFR_LIMB_ONE << sh);
- if (MPFR_UNLIKELY( MPFR_LIMB_MSB(xp[xn-1]) == 0) )
- { /* was an exact power of two: not normalized any more */
+ if (MPFR_UNLIKELY (MPFR_LIMB_MSB (xp[xn-1]) == 0))
+ { /* was an exact power of two: not normalized any more,
+ thus do not use MPFR_GET_EXP. */
mpfr_exp_t exp = MPFR_EXP (x);
- if (MPFR_UNLIKELY(exp == __gmpfr_emin))
+ if (MPFR_UNLIKELY (exp == __gmpfr_emin))
MPFR_SET_ZERO(x);
else
{
- mp_size_t i;
MPFR_SET_EXP (x, exp - 1);
- xp[0] = MP_LIMB_T_MAX << sh;
- for (i = 1; i < xn; i++)
- xp[i] = MP_LIMB_T_MAX;
+ /* The following is valid whether xn = 1 or xn > 1. */
+ xp[xn-1] |= MPFR_LIMB_HIGHBIT;
}
}
}
@@ -66,10 +74,11 @@ mpfr_nexttozero (mpfr_ptr x)
void
mpfr_nexttoinf (mpfr_ptr x)
{
- if (MPFR_UNLIKELY(MPFR_IS_INF(x)))
- return;
- else if (MPFR_UNLIKELY(MPFR_IS_ZERO(x)))
- mpfr_setmin (x, __gmpfr_emin);
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_ZERO (x))
+ mpfr_setmin (x, __gmpfr_emin);
+ }
else
{
mp_size_t xn;
@@ -79,12 +88,12 @@ mpfr_nexttoinf (mpfr_ptr x)
xn = MPFR_LIMB_SIZE (x);
MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC(x));
xp = MPFR_MANT(x);
- if (MPFR_UNLIKELY( mpn_add_1 (xp, xp, xn, MPFR_LIMB_ONE << sh)) )
+ if (MPFR_UNLIKELY (mpn_add_1 (xp, xp, xn, MPFR_LIMB_ONE << sh)))
/* got 1.0000... */
{
mpfr_exp_t exp = MPFR_EXP (x);
- if (MPFR_UNLIKELY(exp == __gmpfr_emax))
- MPFR_SET_INF(x);
+ if (MPFR_UNLIKELY (exp == __gmpfr_emax))
+ MPFR_SET_INF (x);
else
{
MPFR_SET_EXP (x, exp + 1);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/nrandom.c b/Build/source/libs/mpfr/mpfr-src/src/nrandom.c
new file mode 100644
index 00000000000..ed5133bc1fd
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/nrandom.c
@@ -0,0 +1,183 @@
+/* mpfr_nrandom (rop, state, rnd_mode) -- Generate a normal deviate with mean 0
+ and variance 1 and round it to the precision of rop according to the given
+ rounding mode.
+
+Copyright 2013-2017 Free Software Foundation, Inc.
+Contributed by Charles Karney <charles@karney.com>, SRI International.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/*
+ * Sampling from the normal distribution with zero mean and unit variance.
+ * This uses Algorithm N given in:
+ * Charles F. F. Karney,
+ * "Sampling exactly from the normal distribution",
+ * ACM Trans. Math. Software 42(1), 3:1-14 (Jan. 2016).
+ * https://dx.doi.org/10.1145/2710016
+ * http://arxiv.org/abs/1303.6257
+ *
+ * The implementation here closely follows the C++ one given in the paper
+ * above. However, here, C is simplified by using gmp_urandomm_ui; the initial
+ * rejection step in H just tests the leading bit of p; and the assignment of
+ * the sign to the deviate using gmp_urandomb_ui. Finally, the C++
+ * implementation benefits from caching temporary random deviates across calls.
+ * This isn't possible in C without additional machinery which would complicate
+ * the interface.
+ *
+ * There are a few "weasel words" regarding the accuracy of this
+ * implementation. The algorithm produces exactly rounded normal deviates
+ * provided that gmp's random number engine delivers truly random bits. If it
+ * did, the algorithm would be perfect; however, this implementation would have
+ * problems, e.g., in that the integer part of the normal deviate is
+ * represented by an unsigned long, whereas in reality the integer part in
+ * unbounded. In this implementation, asserts catch overflow in the integer
+ * part and similar (very, very) unlikely events. In reality, of course, gmp's
+ * random number engine has a finite internal state (19937 bits in the case of
+ * the MT19937 method). This means that these unlikely events in fact won't
+ * occur. If the asserts are triggered, then this is an indication that the
+ * random number engine is defective. (Even if a hardware random number
+ * generator were used, the most likely explanation for the triggering of the
+ * asserts would be that the hardware generator was broken.)
+ */
+
+#include "random_deviate.h"
+
+/* Algorithm H: true with probability exp(-1/2). */
+static int
+H (gmp_randstate_t r, mpfr_random_deviate_t p, mpfr_random_deviate_t q)
+{
+ /* p and q are temporaries */
+ mpfr_random_deviate_reset (p);
+ if (mpfr_random_deviate_tstbit (p, 1, r))
+ return 1;
+ for (;;)
+ {
+ mpfr_random_deviate_reset (q);
+ if (!mpfr_random_deviate_less (q, p, r))
+ return 0;
+ mpfr_random_deviate_reset (p);
+ if (!mpfr_random_deviate_less (p, q, r))
+ return 1;
+ }
+}
+
+/* Step N1: return n >= 0 with prob. exp(-n/2) * (1 - exp(-1/2)). */
+static unsigned long
+G (gmp_randstate_t r, mpfr_random_deviate_t p, mpfr_random_deviate_t q)
+{
+ /* p and q are temporaries */
+ unsigned long n = 0;
+
+ while (H (r, p, q))
+ {
+ ++n;
+ /* Catch n wrapping around to 0; for a 32-bit unsigned long, the
+ * probability of this is exp(-2^30)). */
+ MPFR_ASSERTN (n != 0UL);
+ }
+ return n;
+}
+
+/* Step N2: true with probability exp(-m*n/2). */
+static int
+P (unsigned long m, unsigned long n, gmp_randstate_t r,
+ mpfr_random_deviate_t p, mpfr_random_deviate_t q)
+{
+ /* p and q are temporaries. m*n is passed as two separate parameters to deal
+ * with the case where m*n overflows an unsigned long. This may be called
+ * with m = 0 and n = (unsigned long)(-1) and, because m in handled in to the
+ * outer loop, this routine will correctly return 1. */
+ while (m--)
+ {
+ unsigned long k = n;
+ while (k--)
+ {
+ if (!H (r, p, q))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Algorithm C: return (-1, 0, 1) with prob (1/m, 1/m, 1-2/m). */
+static int
+C (unsigned long m, gmp_randstate_t r)
+{
+ unsigned long n = gmp_urandomm_ui (r, m);
+ return n == 0 ? -1 : (n == 1 ? 0 : 1);
+}
+
+/* Algorithm B: true with prob exp(-x * (2*k + x) / (2*k + 2)). */
+static int
+B (unsigned long k, mpfr_random_deviate_t x, gmp_randstate_t r,
+ mpfr_random_deviate_t p, mpfr_random_deviate_t q)
+{
+ /* p and q are temporaries */
+
+ unsigned long m = 2 * k + 2;
+ /* n tracks the parity of the loop; s == 1 on first trip through loop. */
+ unsigned n = 0, s = 1;
+ int f;
+
+ /* Check if 2 * k + 2 would overflow; for a 32-bit unsigned long, the
+ * probability of this is exp(-2^61)). */
+ MPFR_ASSERTN (k < ((unsigned long)(-1) >> 1));
+
+ for (;; ++n, s = 0) /* overflow of n is innocuous */
+ {
+ if ( ((f = k ? 0 : C (m, r)) < 0) ||
+ (mpfr_random_deviate_reset (q),
+ !mpfr_random_deviate_less (q, s ? x : p, r)) ||
+ ((f = k ? C (m, r) : f) < 0) ||
+ (f == 0 &&
+ (mpfr_random_deviate_reset (p),
+ !mpfr_random_deviate_less (p, x, r))) )
+ break;
+ mpfr_random_deviate_swap (p, q); /* an efficient way of doing p = q */
+ }
+ return (n & 1U) == 0;
+}
+
+/* return a normal random deviate with mean 0 and variance 1 as a MPFR */
+int
+mpfr_nrandom (mpfr_t z, gmp_randstate_t r, mpfr_rnd_t rnd)
+{
+ mpfr_random_deviate_t x, p, q;
+ int inex;
+ unsigned long k, j;
+
+ mpfr_random_deviate_init (x);
+ mpfr_random_deviate_init (p);
+ mpfr_random_deviate_init (q);
+ for (;;)
+ {
+ k = G (r, p, q); /* step 1 */
+ if (!P (k, k - 1, r, p, q))
+ continue; /* step 2 */
+ mpfr_random_deviate_reset (x); /* step 3 */
+ for (j = 0; j <= k && B (k, x, r, p, q); ++j); /* step 4 */
+ if (j > k)
+ break;
+ }
+ mpfr_random_deviate_clear (q);
+ mpfr_random_deviate_clear (p);
+ /* steps 5, 6, 7 */
+ inex = mpfr_random_deviate_value (gmp_urandomb_ui (r, 1), k, x, z, r, rnd);
+ mpfr_random_deviate_clear (x);
+ return inex;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/odd_p.c b/Build/source/libs/mpfr/mpfr-src/src/odd_p.c
new file mode 100644
index 00000000000..411f8555dbf
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/odd_p.c
@@ -0,0 +1,73 @@
+/* mpfr_odd_p -- check for odd integers
+
+Copyright 2001-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Return 1 if y is an odd integer, 0 otherwise.
+ Assumes y is not singular. */
+int
+mpfr_odd_p (mpfr_srcptr y)
+{
+ mpfr_exp_t expo;
+ mpfr_prec_t prec;
+ mp_size_t yn;
+ mp_limb_t *yp;
+
+ /* NAN, INF or ZERO are not allowed */
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (y));
+
+ expo = MPFR_GET_EXP (y);
+ if (expo <= 0)
+ return 0; /* |y| < 1 and not 0 */
+
+ prec = MPFR_PREC(y);
+ if ((mpfr_prec_t) expo > prec)
+ return 0; /* y is a multiple of 2^(expo-prec), thus not odd */
+
+ /* 0 < expo <= prec:
+ y = 1xxxxxxxxxt.zzzzzzzzzzzzzzzzzz[000]
+ expo bits (prec-expo) bits
+
+ We have to check that:
+ (a) the bit 't' is set
+ (b) all the 'z' bits are zero
+ */
+
+ prec = MPFR_PREC2LIMBS (prec) * GMP_NUMB_BITS - expo;
+ /* number of z+0 bits */
+
+ yn = prec / GMP_NUMB_BITS;
+ MPFR_ASSERTN(yn >= 0);
+ /* yn is the index of limb containing the 't' bit */
+
+ yp = MPFR_MANT(y);
+ /* if expo is a multiple of GMP_NUMB_BITS, t is bit 0 */
+ if (expo % GMP_NUMB_BITS == 0 ? (yp[yn] & 1) == 0
+ : yp[yn] << ((expo % GMP_NUMB_BITS) - 1) != MPFR_LIMB_HIGHBIT)
+ return 0;
+ while (--yn >= 0)
+ if (yp[yn] != 0)
+ return 0;
+ return 1;
+}
+
diff --git a/Build/source/libs/mpfr/mpfr-src/src/out_str.c b/Build/source/libs/mpfr/mpfr-src/src/out_str.c
index 1b5e6da8f31..636c634547d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/out_str.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/out_str.c
@@ -73,7 +73,7 @@ mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
|| fputc (*s++, stream) == EOF /* leading digit */
|| fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF
|| fputs (s, stream) == EOF; /* trailing significand */
- (*__gmp_free_func) (s0, l);
+ mpfr_free_func (s0, l);
if (MPFR_UNLIKELY (err))
return 0;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/pool.c b/Build/source/libs/mpfr/mpfr-src/src/pool.c
new file mode 100644
index 00000000000..70f50192941
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/pool.c
@@ -0,0 +1,117 @@
+/* mpz_t pool
+
+Copyright 2014-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_POOL_DONT_REDEFINE
+#include "mpfr-impl.h"
+
+#ifndef MPFR_POOL_MAX_SIZE
+# define MPFR_POOL_MAX_SIZE 32 /* maximal size (in limbs) for each entry */
+#endif
+
+/* If the number of entries of the mpz_t pool is not zero */
+#if MPFR_POOL_NENTRIES
+
+/* Index in the stack table of mpz_t and stack table of mpz_t */
+static MPFR_THREAD_ATTR int n_alloc = 0;
+static MPFR_THREAD_ATTR __mpz_struct mpz_tab[MPFR_POOL_NENTRIES];
+
+MPFR_HOT_FUNCTION_ATTR void
+mpfr_mpz_init (mpz_t z)
+{
+ if (MPFR_LIKELY (n_alloc > 0))
+ {
+ /* Get a mpz_t from the MPFR stack of previously used mpz_t.
+ It reduces memory pressure, and it allows to reuse
+ a mpz_t that should be sufficiently big. */
+ MPFR_ASSERTD (n_alloc <= numberof (mpz_tab));
+ memcpy (z, &mpz_tab[--n_alloc], sizeof (mpz_t));
+ SIZ(z) = 0;
+ }
+ else
+ {
+ /* Call the real GMP function */
+ mpz_init (z);
+ }
+}
+
+MPFR_HOT_FUNCTION_ATTR void
+mpfr_mpz_init2 (mpz_t z, mp_bitcnt_t n)
+{
+ /* The condition on n is used below as the argument n will be ignored if
+ the mpz_t is obtained from the MPFR stack of previously used mpz_t.
+ Said otherwise, it z is expected to have a large size at the end, then
+ it is better to allocate this size directly than to get a mpz_t of
+ small size, with possibly several realloc's on it. But if n satisfies
+ the condition and is larger than the stacked mpz_t, this may still
+ yield useless realloc's. This is not ideal. We might consider to use
+ mpz_init2 with the maximum size in mpfr_mpz_init to solve this issue. */
+ if (MPFR_LIKELY (n_alloc > 0 && n <= MPFR_POOL_MAX_SIZE * GMP_NUMB_BITS))
+ {
+ /* Get a mpz_t from the MPFR stack of previously used mpz_t.
+ It reduces memory pressure, and it allows to reuse
+ a mpz_t that should be sufficiently big. */
+ MPFR_ASSERTD (n_alloc <= numberof (mpz_tab));
+ memcpy (z, &mpz_tab[--n_alloc], sizeof (mpz_t));
+ SIZ(z) = 0;
+ }
+ else
+ {
+ /* Call the real GMP function */
+ mpz_init2 (z, n);
+ }
+}
+
+
+MPFR_HOT_FUNCTION_ATTR void
+mpfr_mpz_clear (mpz_t z)
+{
+ /* We only put objects with at most MPFR_POOL_MAX_SIZE in the mpz_t pool,
+ to avoid it takes too much memory (and anyway the speedup is mainly
+ for small precision). */
+ if (MPFR_LIKELY (n_alloc < numberof (mpz_tab) &&
+ ALLOC (z) <= MPFR_POOL_MAX_SIZE))
+ {
+ /* Push back the mpz_t inside the stack of the used mpz_t */
+ MPFR_ASSERTD (n_alloc >= 0);
+ memcpy (&mpz_tab[n_alloc++], z, sizeof (mpz_t));
+ }
+ else
+ {
+ /* Call the real GMP function */
+ mpz_clear (z);
+ }
+}
+
+#endif
+
+void
+mpfr_free_pool (void)
+{
+#if MPFR_POOL_NENTRIES
+ int i;
+
+ MPFR_ASSERTD (n_alloc >= 0 && n_alloc <= numberof (mpz_tab));
+ for (i = 0; i < n_alloc; i++)
+ mpz_clear (&mpz_tab[i]);
+ n_alloc = 0;
+#endif
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/pow.c b/Build/source/libs/mpfr/mpfr-src/src/pow.c
index 5c1c2dec8c0..6d5c05f96b2 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/pow.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/pow.c
@@ -107,55 +107,10 @@ mpfr_pow_is_exact (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
return res;
}
-/* Return 1 if y is an odd integer, 0 otherwise. */
-static int
-is_odd (mpfr_srcptr y)
-{
- mpfr_exp_t expo;
- mpfr_prec_t prec;
- mp_size_t yn;
- mp_limb_t *yp;
-
- /* NAN, INF or ZERO are not allowed */
- MPFR_ASSERTD (!MPFR_IS_SINGULAR (y));
-
- expo = MPFR_GET_EXP (y);
- if (expo <= 0)
- return 0; /* |y| < 1 and not 0 */
-
- prec = MPFR_PREC(y);
- if ((mpfr_prec_t) expo > prec)
- return 0; /* y is a multiple of 2^(expo-prec), thus not odd */
-
- /* 0 < expo <= prec:
- y = 1xxxxxxxxxt.zzzzzzzzzzzzzzzzzz[000]
- expo bits (prec-expo) bits
-
- We have to check that:
- (a) the bit 't' is set
- (b) all the 'z' bits are zero
- */
-
- prec = MPFR_PREC2LIMBS (prec) * GMP_NUMB_BITS - expo;
- /* number of z+0 bits */
-
- yn = prec / GMP_NUMB_BITS;
- MPFR_ASSERTN(yn >= 0);
- /* yn is the index of limb containing the 't' bit */
-
- yp = MPFR_MANT(y);
- /* if expo is a multiple of GMP_NUMB_BITS, t is bit 0 */
- if (expo % GMP_NUMB_BITS == 0 ? (yp[yn] & 1) == 0
- : yp[yn] << ((expo % GMP_NUMB_BITS) - 1) != MPFR_LIMB_HIGHBIT)
- return 0;
- while (--yn >= 0)
- if (yp[yn] != 0)
- return 0;
- return 1;
-}
-
/* Assumes that the exponent range has already been extended and if y is
- an integer, then the result is not exact in unbounded exponent range. */
+ an integer, then the result is not exact in unbounded exponent range.
+ If x < 0, assumes y is an integer.
+*/
int
mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
mpfr_rnd_t rnd_mode, int y_is_integer, mpfr_save_expo_t *expo)
@@ -184,18 +139,26 @@ mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
MPFR_ALIAS(absx, x, /*sign=*/ 1, /*EXP=*/ MPFR_EXP(x));
/* We will compute the absolute value of the result. So, let's
- invert the rounding mode if the result is negative. */
- if (MPFR_IS_NEG (x) && is_odd (y))
+ invert the rounding mode if the result is negative (in which case
+ y not an integer was already filtered out). */
+ if (MPFR_IS_NEG (x))
{
- neg_result = 1;
- rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ MPFR_ASSERTD (y_is_integer);
+ if (mpfr_odd_p (y))
+ {
+ neg_result = 1;
+ rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ }
}
- /* compute the precision of intermediary variable */
- /* the optimal number of bits : see algorithms.tex */
- Nt = Nz + 5 + MPFR_INT_CEIL_LOG2 (Nz);
+ /* Compute the precision of intermediary variable. */
+ /* The increment 9 + MPFR_INT_CEIL_LOG2 (Nz) gives few Ziv failures
+ in binary64 and binary128 formats:
+ mfv5 -p53 -e1 mpfr_pow: 5903 / 6469.59 / 6686
+ mfv5 -p113 -e1 mpfr_pow: 10913 / 11989.46 / 12321 */
+ Nt = Nz + 9 + MPFR_INT_CEIL_LOG2 (Nz);
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
MPFR_ZIV_INIT (ziv_loop, Nt);
@@ -360,15 +323,28 @@ mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk && mpfr_powerof2_raw (z))
{
/* Rounding to nearest, real result > z * 2^k = 2^(emin - 2),
- * underflow case: as the minimum precision is > 1, we will
- * obtain the correct result and exceptions by replacing z by
- * nextabove(z).
+ * underflow case:
+ * (a) if the precision of z is > 1, we will obtain the correct
+ * result and exceptions by replacing z by nextabove(z).
+ * (b) if the precision of z is 1, we first copy z to zcopy of
+ * precision 2 bits and perform nextabove(zcopy).
*/
- MPFR_ASSERTN (MPFR_PREC_MIN > 1);
- mpfr_nextabove (z);
+ if (MPFR_PREC(z) >= 2)
+ mpfr_nextabove (z);
+ else
+ {
+ mpfr_t zcopy;
+ mpfr_init2 (zcopy, MPFR_PREC(z) + 1);
+ mpfr_set (zcopy, z, MPFR_RNDZ);
+ mpfr_nextabove (zcopy);
+ inex2 = mpfr_mul_2si (z, zcopy, lk, rnd_mode);
+ mpfr_clear (zcopy);
+ goto under_over;
+ }
}
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inex2 = mpfr_mul_2si (z, z, lk, rnd_mode);
+ under_over:
if (inex2) /* underflow or overflow */
{
inexact = inex2;
@@ -482,7 +458,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
{
int negative;
/* Determine the sign now, in case y and z are the same object */
- negative = MPFR_IS_NEG (x) && is_odd (y);
+ negative = MPFR_IS_NEG (x) && mpfr_odd_p (y);
if (MPFR_IS_POS (y))
MPFR_SET_INF (z);
else
@@ -498,12 +474,12 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
int negative;
MPFR_ASSERTD (MPFR_IS_ZERO (x));
/* Determine the sign now, in case y and z are the same object */
- negative = MPFR_IS_NEG(x) && is_odd (y);
+ negative = MPFR_IS_NEG(x) && mpfr_odd_p (y);
if (MPFR_IS_NEG (y))
{
MPFR_ASSERTD (! MPFR_IS_INF (y));
MPFR_SET_INF (z);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
}
else
MPFR_SET_ZERO (z);
@@ -529,7 +505,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
cmp_x_1 = mpfr_cmpabs (x, __gmpfr_one);
if (cmp_x_1 == 0)
- return mpfr_set_si (z, MPFR_IS_NEG (x) && is_odd (y) ? -1 : 1, rnd_mode);
+ return mpfr_set_si (z, MPFR_IS_NEG (x) && mpfr_odd_p (y) ? -1 : 1, rnd_mode);
/* now we have:
(1) either x > 0
@@ -550,6 +526,15 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
Otherwise, it should enable one to check only underflow or overflow,
instead of both cases as in the present case.
*/
+
+ /* fast check for cases where no overflow nor underflow is possible:
+ if |y| <= 2^15, and -32767 < EXP(x) <= 32767, then
+ |y*log2(x)| <= 2^15*32767 < 1073741823, thus for the default
+ emax=1073741823 and emin=-emax there can be no overflow nor underflow */
+ if (__gmpfr_emax >= 1073741823 && __gmpfr_emin <= -1073741823 &&
+ MPFR_EXP(y) <= 15 && -32767 < MPFR_EXP(x) && MPFR_EXP(x) <= 32767)
+ goto no_overflow_nor_underflow;
+
if (cmp_x_1 * MPFR_SIGN (y) > 0)
{
mpfr_t t;
@@ -562,7 +547,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
to round y*o(log2(x)) toward zero too;
(ii) if x < 0, we first compute t = o(-x), with rounding toward 1,
and then follow as in case (1). */
- if (MPFR_SIGN (x) > 0)
+ if (MPFR_IS_POS (x))
mpfr_log2 (t, x, MPFR_RNDZ);
else
{
@@ -576,7 +561,7 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
if (overflow)
{
MPFR_LOG_MSG (("early overflow detection\n", 0));
- negative = MPFR_SIGN(x) < 0 && is_odd (y);
+ negative = MPFR_IS_NEG (x) && mpfr_odd_p (y);
return mpfr_overflow (z, rnd_mode, negative ? -1 : 1);
}
}
@@ -590,13 +575,14 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
*/
if (MPFR_IS_NEG (y) ? (MPFR_GET_EXP (x) > 1) : (MPFR_GET_EXP (x) < 0))
{
+ mp_limb_t tmp_limb[MPFR_EXP_LIMB_SIZE];
mpfr_t tmp;
mpfr_eexp_t ebound;
int inex2;
/* We must restore the flags. */
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (tmp, sizeof (mpfr_exp_t) * CHAR_BIT);
+ MPFR_TMP_INIT1 (tmp_limb, tmp, sizeof (mpfr_exp_t) * CHAR_BIT);
inex2 = mpfr_set_exp_t (tmp, MPFR_GET_EXP (x), MPFR_RNDN);
MPFR_ASSERTN (inex2 == 0);
if (MPFR_IS_NEG (y))
@@ -610,7 +596,6 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
/* tmp doesn't necessarily fit in ebound, but that doesn't matter
since we get the minimum value in such a case. */
ebound = mpfr_get_exp_t (tmp, MPFR_RNDU);
- mpfr_clear (tmp);
MPFR_SAVE_EXPO_FREE (expo);
if (MPFR_UNLIKELY (ebound <=
__gmpfr_emin - (rnd_mode == MPFR_RNDN ? 2 : 1)))
@@ -619,10 +604,12 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
MPFR_LOG_MSG (("early underflow detection\n", 0));
return mpfr_underflow (z,
rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
- MPFR_SIGN (x) < 0 && is_odd (y) ? -1 : 1);
+ MPFR_IS_NEG (x) && mpfr_odd_p (y) ? -1 : 1);
}
}
+ no_overflow_nor_underflow:
+
/* If y is an integer, we can use mpfr_pow_z (based on multiplications),
but if y is very large (I'm not sure about the best threshold -- VL),
we shouldn't use it, as it can be very slow and take a lot of memory
@@ -645,65 +632,59 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
/* Special case (+/-2^b)^Y which could be exact. If x is negative, then
necessarily y is a large integer. */
+ if (mpfr_powerof2_raw (x))
{
mpfr_exp_t b = MPFR_GET_EXP (x) - 1;
+ mpfr_t tmp;
+ int sgnx = MPFR_SIGN (x);
MPFR_ASSERTN (b >= LONG_MIN && b <= LONG_MAX); /* FIXME... */
- if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), b) == 0)
+
+ MPFR_LOG_MSG (("special case (+/-2^b)^Y\n", 0));
+ /* now x = +/-2^b, so x^y = (+/-1)^y*2^(b*y) is exact whenever b*y is
+ an integer */
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, MPFR_PREC (y) + sizeof (long) * CHAR_BIT);
+ inexact = mpfr_mul_si (tmp, y, b, MPFR_RNDN); /* exact */
+ MPFR_ASSERTN (inexact == 0);
+ /* Note: as the exponent range has been extended, an overflow is not
+ possible (due to basic overflow and underflow checking above, as
+ the result is ~ 2^tmp), and an underflow is not possible either
+ because b is an integer (thus either 0 or >= 1). */
+ MPFR_CLEAR_FLAGS ();
+ inexact = mpfr_exp2 (z, tmp, rnd_mode);
+ mpfr_clear (tmp);
+ if (sgnx < 0 && mpfr_odd_p (y))
{
- mpfr_t tmp;
- int sgnx = MPFR_SIGN (x);
-
- MPFR_LOG_MSG (("special case (+/-2^b)^Y\n", 0));
- /* now x = +/-2^b, so x^y = (+/-1)^y*2^(b*y) is exact whenever b*y is
- an integer */
- MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (tmp, MPFR_PREC (y) + sizeof (long) * CHAR_BIT);
- inexact = mpfr_mul_si (tmp, y, b, MPFR_RNDN); /* exact */
- MPFR_ASSERTN (inexact == 0);
- /* Note: as the exponent range has been extended, an overflow is not
- possible (due to basic overflow and underflow checking above, as
- the result is ~ 2^tmp), and an underflow is not possible either
- because b is an integer (thus either 0 or >= 1). */
- mpfr_clear_flags ();
- inexact = mpfr_exp2 (z, tmp, rnd_mode);
- mpfr_clear (tmp);
- if (sgnx < 0 && is_odd (y))
- {
- mpfr_neg (z, z, rnd_mode);
- inexact = -inexact;
- }
- /* Without the following, the overflows3 test in tpow.c fails. */
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_check_range (z, inexact, rnd_mode);
+ mpfr_neg (z, z, rnd_mode);
+ inexact = -inexact;
}
+ /* Without the following, the overflows3 test in tpow.c fails. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (z, inexact, rnd_mode);
}
MPFR_SAVE_EXPO_MARK (expo);
- /* Case where |y * log(x)| is very small. Warning: x can be negative, in
+ /* Case where y * log(x) is very small. Warning: x can be negative, in
that case y is a large integer. */
{
- mpfr_t t;
- mpfr_exp_t err;
+ mpfr_exp_t err, expx, logt;
/* We need an upper bound on the exponent of y * log(x). */
- mpfr_init2 (t, 16);
if (MPFR_IS_POS(x))
- mpfr_log (t, x, cmp_x_1 < 0 ? MPFR_RNDD : MPFR_RNDU); /* away from 0 */
+ expx = cmp_x_1 > 0 ? MPFR_EXP(x) : 1 - MPFR_EXP(x);
else
- {
- /* if x < -1, round to +Inf, else round to zero */
- mpfr_neg (t, x, (mpfr_cmp_si (x, -1) < 0) ? MPFR_RNDU : MPFR_RNDD);
- mpfr_log (t, t, (mpfr_cmp_ui (t, 1) < 0) ? MPFR_RNDD : MPFR_RNDU);
- }
- MPFR_ASSERTN (MPFR_IS_PURE_FP (t));
- err = MPFR_GET_EXP (y) + MPFR_GET_EXP (t);
- mpfr_clear (t);
- mpfr_clear_flags ();
+ expx = mpfr_cmp_si (x, -1) > 0 ? 1 - MPFR_EXP(x) : MPFR_EXP(x);
+ MPFR_ASSERTD(expx >= 0);
+ /* now |log(x)| < expx */
+ logt = MPFR_INT_CEIL_LOG2 (expx);
+ /* now expx <= 2^logt */
+ err = MPFR_GET_EXP (y) + logt;
+ MPFR_CLEAR_FLAGS ();
MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (z, __gmpfr_one, - err, 0,
- (MPFR_SIGN (y) > 0) ^ (cmp_x_1 < 0),
+ (MPFR_IS_POS (y)) ^ (cmp_x_1 < 0),
rnd_mode, expo, {});
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/pow_si.c b/Build/source/libs/mpfr/mpfr-src/src/pow_si.c
index 6ffeed16439..f14f732161b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/pow_si.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/pow_si.c
@@ -56,7 +56,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd)
{
MPFR_ASSERTD (MPFR_IS_ZERO (x));
MPFR_SET_INF (y);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
}
if (positive)
MPFR_SET_POS (y);
@@ -158,14 +158,14 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd)
MPFR_SAVE_EXPO_MARK (expo);
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
/* We will compute rnd(rnd1(1/x) ^ |n|), where rnd1 is the rounding
toward sign(x), to avoid spurious overflow or underflow, as in
mpfr_pow_z. */
rnd1 = MPFR_EXP (x) < 1 ? MPFR_RNDZ :
- (MPFR_SIGN (x) > 0 ? MPFR_RNDU : MPFR_RNDD);
+ (MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD);
MPFR_ZIV_INIT (loop, Nt);
for (;;)
@@ -233,7 +233,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd)
if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - size_n - 2, Ny, rnd)))
break;
- /* actualisation of the precision */
+ /* actualization of the precision */
MPFR_ZIV_NEXT (loop, Nt);
mpfr_set_prec (t, Nt);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/pow_z.c b/Build/source/libs/mpfr/mpfr-src/src/pow_z.c
index 762f506fa6f..b2fe4c7cde8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/pow_z.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/pow_z.c
@@ -52,7 +52,7 @@ mpfr_pow_pos_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd, int cr)
return mpfr_set (y, x, rnd);
absz[0] = z[0];
- SIZ (absz) = ABS(SIZ(absz)); /* Hack to get abs(z) */
+ SIZ (absz) = ABSIZ (absz); /* Hack to get abs(z) */
MPFR_MPZ_SIZEINBASE2 (size_z, z);
/* round toward 1 (or -1) to avoid spurious overflow or underflow,
@@ -128,7 +128,7 @@ mpfr_pow_pos_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd, int cr)
MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_SIGN (x),
MPFR_EXP (x) - 1) != 0);
mpfr_init2 (y2, 2);
- mpfr_init2 (zz, ABS (SIZ (z)) * GMP_NUMB_BITS);
+ mpfr_init2 (zz, ABSIZ (z) * GMP_NUMB_BITS);
inexact = mpfr_set_z (zz, z, MPFR_RNDN);
MPFR_ASSERTN (inexact == 0);
inexact = mpfr_pow_general (y2, x, zz, rnd, 1,
@@ -211,7 +211,7 @@ mpfr_pow_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd)
{
/* 0^(-n) if +/- INF */
MPFR_SET_INF (y);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
}
if (MPFR_LIKELY (MPFR_IS_POS (x) || mpz_even_p (z)))
MPFR_SET_POS (y);
@@ -280,13 +280,13 @@ mpfr_pow_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd)
Nt = Nt + size_z + 3 + MPFR_INT_CEIL_LOG2 (Nt);
/* ensures Nt >= bits(z)+2 */
- /* initialise of intermediary variable */
+ /* initialize of intermediary variable */
mpfr_init2 (t, Nt);
/* We will compute rnd(rnd1(1/x) ^ (-z)), where rnd1 is the rounding
toward sign(x), to avoid spurious overflow or underflow. */
rnd1 = MPFR_EXP (x) < 1 ? MPFR_RNDZ :
- (MPFR_SIGN (x) > 0 ? MPFR_RNDU : MPFR_RNDD);
+ (MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD);
MPFR_ZIV_INIT (loop, Nt);
for (;;)
@@ -336,7 +336,7 @@ mpfr_pow_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd)
MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_SIGN (x),
MPFR_EXP (x) - 1) != 0);
mpfr_init2 (y2, 2);
- mpfr_init2 (zz, ABS (SIZ (z)) * GMP_NUMB_BITS);
+ mpfr_init2 (zz, ABSIZ (z) * GMP_NUMB_BITS);
inexact = mpfr_set_z (zz, z, MPFR_RNDN);
MPFR_ASSERTN (inexact == 0);
inexact = mpfr_pow_general (y2, x, zz, rnd, 1,
@@ -357,7 +357,7 @@ mpfr_pow_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd)
if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - size_z - 2, MPFR_PREC (y),
rnd)))
break;
- /* actualisation of the precision */
+ /* actualization of the precision */
MPFR_ZIV_NEXT (loop, Nt);
mpfr_set_prec (t, Nt);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/print_raw.c b/Build/source/libs/mpfr/mpfr-src/src/print_raw.c
index b05fcae596b..fd320f5ce16 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/print_raw.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/print_raw.c
@@ -1,5 +1,6 @@
-/* mpfr_print_binary -- print the internal binary representation of a
- floating-point number
+/* mpfr_print_mant_binary -- print the internal binary representation
+ of a significand of floating-point number (for the tests and
+ debugging purpose)
Copyright 1999-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -24,106 +25,24 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
void
-mpfr_fprint_binary (FILE *stream, mpfr_srcptr x)
-{
- if (MPFR_IS_NAN (x))
- {
- fprintf (stream, "@NaN@");
- return;
- }
-
- if (MPFR_SIGN (x) < 0)
- fprintf (stream, "-");
-
- if (MPFR_IS_INF (x))
- fprintf (stream, "@Inf@");
- else if (MPFR_IS_ZERO (x))
- fprintf (stream, "0");
- else
- {
- mp_limb_t *mx;
- mpfr_prec_t px;
- mp_size_t n;
-
- mx = MPFR_MANT (x);
- px = MPFR_PREC (x);
-
- fprintf (stream, "0.");
- for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
- {
- mp_limb_t wd, t;
-
- MPFR_ASSERTN (n >= 0);
- wd = mx[n];
- for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
- {
- putc ((wd & t) == 0 ? '0' : '1', stream);
- if (--px == 0)
- {
- mpfr_exp_t ex;
-
- ex = MPFR_GET_EXP (x);
- MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
- fprintf (stream, "E%ld", (long) ex);
- return;
- }
- }
- }
- }
-}
-
-void
-mpfr_print_binary (mpfr_srcptr x)
-{
- mpfr_fprint_binary (stdout, x);
-}
-
-void
-mpfr_print_mant_binary(const char *str, const mp_limb_t *p, mpfr_prec_t r)
-{
- int i;
- mpfr_prec_t count = 0;
- char c;
- mp_size_t n = MPFR_PREC2LIMBS (r);
-
- printf("%s ", str);
- for(n-- ; n>=0 ; n--)
- {
- for(i = GMP_NUMB_BITS-1 ; i >=0 ; i--)
- {
- c = (p[n] & (((mp_limb_t)1L)<<i)) ? '1' : '0';
- putchar(c);
- count++;
- if (count == r)
- putchar('[');
- }
- putchar('.');
- }
- putchar('\n');
-}
-
-void
-mpfr_dump_mant (const mp_limb_t *p, mpfr_prec_t r, mpfr_prec_t precx,
- mpfr_prec_t error)
+mpfr_print_mant_binary (const char *str, const mp_limb_t *p, mpfr_prec_t r)
{
int i;
mpfr_prec_t count = 0;
- char c;
mp_size_t n = MPFR_PREC2LIMBS (r);
- for(n-- ; n>=0 ; n--)
+ printf ("%s ", str);
+ for (n-- ; n >= 0 ; n--)
{
- for(i = GMP_NUMB_BITS-1 ; i >=0 ; i--)
+ for (i = GMP_NUMB_BITS - 1 ; i >=0 ; i--)
{
- c = (p[n] & (((mp_limb_t)1L)<<i)) ? '1' : '0';
- putchar(c);
- count++;
- if (count == precx)
- putchar (',');
- if (count == error)
- putchar('[');
+ putchar ((p[n] & (MPFR_LIMB_ONE << i)) ? '1' : '0');
+ if (++count == r)
+ putchar ('[');
}
- putchar('.');
+ putchar ('.');
}
- putchar('\n');
+ if (count >= r)
+ putchar (']');
+ putchar ('\n');
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/print_rnd_mode.c b/Build/source/libs/mpfr/mpfr-src/src/print_rnd_mode.c
index 6728c678734..e6a6937bba5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/print_rnd_mode.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/print_rnd_mode.c
@@ -27,7 +27,7 @@ mpfr_print_rnd_mode (mpfr_rnd_t rnd_mode)
{
/* If we forget to update this function after a new rounding mode
is added, this will be detected by the following assertion. */
- MPFR_ASSERTN (MPFR_RND_MAX == MPFR_RNDA + 1);
+ MPFR_STAT_STATIC_ASSERT (MPFR_RND_MAX == MPFR_RNDF + 1);
switch (rnd_mode)
{
case MPFR_RNDD:
@@ -40,6 +40,8 @@ mpfr_print_rnd_mode (mpfr_rnd_t rnd_mode)
return "MPFR_RNDZ";
case MPFR_RNDA:
return "MPFR_RNDA";
+ case MPFR_RNDF:
+ return "MPFR_RNDF";
default:
return (const char*) 0;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/printf.c b/Build/source/libs/mpfr/mpfr-src/src/printf.c
index 3a554e70457..0888c1d02ae 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/printf.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/printf.c
@@ -1,4 +1,4 @@
-/* mpfr_printf -- printf function and friends.
+/* Formatted output functions (printf functions family).
Copyright 2007-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -21,11 +21,12 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+# include "config.h"
#endif
-/* The mpfr_printf-like functions are defined only if <stdarg.h> exists */
-#ifdef HAVE_STDARG
+/* The mpfr_printf-like functions are defined only if <stdarg.h> exists.
+ Since they use mpf_t, they cannot be defined with mini-gmp. */
+#if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
#include <stdarg.h>
@@ -44,12 +45,12 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#ifdef _MPFR_H_HAVE_FILE
-/* Each printf-like function calls mpfr_vasprintf which
- - returns the number of characters in the returned string excluding the
- terminating null
- - returns -1 and sets the erange flag if the number of produced characters
- exceeds INT_MAX (in that case, also sets errno to EOVERFLOW in POSIX
- systems) */
+/* Each printf-like function calls mpfr_vasnprintf_aux (directly or
+ via mpfr_vasprintf), which
+ - returns the number of characters to be written excluding the
+ terminating null character (disregarding the size argument);
+ - returns -1 and sets the erange flag if this number exceeds INT_MAX
+ (in that case, also sets errno to EOVERFLOW on POSIX systems). */
#define GET_STR_VA(sz, str, fmt, ap) \
do \
@@ -130,6 +131,7 @@ mpfr_vfprintf (FILE *fp, const char *fmt, va_list ap)
mpfr_free_str (str);
return ret;
}
+
#endif /* _MPFR_H_HAVE_FILE */
int
@@ -161,45 +163,20 @@ mpfr_vsprintf (char *buf, const char *fmt, va_list ap)
int
mpfr_snprintf (char *buf, size_t size, const char *fmt, ...)
{
- char *str;
int ret;
- size_t min_size;
+ va_list ap;
- GET_STR (ret, str, fmt);
+ va_start(ap, fmt);
+ ret = mpfr_vasnprintf_aux (NULL, buf, size, fmt, ap);
+ va_end (ap);
- /* C99 allows SIZE to be zero */
- if (size != 0)
- {
- MPFR_ASSERTN (buf != NULL);
- min_size = (size_t)ret < size ? (size_t)ret : size - 1;
- strncpy (buf, str, min_size);
- buf[min_size] = '\0';
- }
-
- mpfr_free_str (str);
return ret;
}
int
mpfr_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
{
- char *str;
- int ret;
- int min_size;
-
- GET_STR_VA (ret, str, fmt, ap);
-
- /* C99 allows SIZE to be zero */
- if (size != 0)
- {
- MPFR_ASSERTN (buf != NULL);
- min_size = (size_t)ret < size ? (size_t)ret : size - 1;
- strncpy (buf, str, min_size);
- buf[min_size] = '\0';
- }
-
- mpfr_free_str (str);
- return ret;
+ return mpfr_vasnprintf_aux (NULL, buf, size, fmt, ap);
}
int
@@ -211,4 +188,16 @@ mpfr_asprintf (char **pp, const char *fmt, ...)
return ret;
}
+
+int
+mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
+{
+ return mpfr_vasnprintf_aux (ptr, NULL, 0, fmt, ap);
+}
+
+#else /* HAVE_STDARG */
+
+/* Avoid an empty translation unit (see ISO C99, 6.9) */
+typedef int foo;
+
#endif /* HAVE_STDARG */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/random_deviate.c b/Build/source/libs/mpfr/mpfr-src/src/random_deviate.c
new file mode 100644
index 00000000000..f4434528148
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/random_deviate.c
@@ -0,0 +1,384 @@
+/* random_deviate routines for mpfr_erandom and mpfr_nrandom.
+
+Copyright 2013-2017 Free Software Foundation, Inc.
+Contributed by Charles Karney <charles@karney.com>, SRI International.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/*
+ * A mpfr_random_deviate represents the initial portion e bits of a random
+ * deviate uniformly distributed in (0,1) as
+ *
+ * typedef struct {
+ * unsigned long e; // bits in the fraction
+ * unsigned long h; // the high W bits of the fraction
+ * mpz_t f; // the rest of the fraction
+ * } mpfr_random_deviate_t[1];
+ *
+ * e is always a multiple of RANDOM_CHUNK. The first RANDOM_CHUNK bits, the
+ * high fraction, are held in an unsigned long, h, and the rest are held in an
+ * mpz_t, f. The data in h is undefined if e == 0 and, similarly the data in f
+ * is undefined if e <= RANDOM_CHUNK.
+ */
+
+#define MPFR_NEED_LONGLONG_H
+#include "random_deviate.h"
+
+/*
+ * RANDOM_CHUNK can be picked in the range 1 <= RANDOM_CHUNK <= 64. Low values
+ * of RANDOM_CHUNK are good for testing, since they are more likely to make
+ * bugs obvious. For portability, pick RANDOM_CHUNK <= 32 (since an unsigned
+ * long may only hold 32 bits). For reproducibility across platforms,
+ * standardize on RANDOM_CHUNK = 32.
+ *
+ * When RANDOM_CHUNK = 32, this representation largely avoids manipulating
+ * mpz's (until the final cast to an mpfr is done). In addition
+ * mpfr_random_deviate_less usually entails just a single comparison of
+ * unsigned longs. In this way, we can stick with the published interface for
+ * extracting portions of an mpz (namely through mpz_tstbit) without hurting
+ * efficiency.
+ */
+#if !defined(RANDOM_CHUNK)
+/* note: for MPFR, we could use RANDOM_CHUNK = 32 or 64 according to the
+ number of bits per limb, but we use 32 everywhere to get reproducible
+ results on 32-bit and 64-bit computers */
+#define RANDOM_CHUNK 32 /* Require 1 <= RANDOM_CHUNK <= 32; recommend 32 */
+#endif
+
+#define W RANDOM_CHUNK /* W is just an shorter name for RANDOM_CHUNK */
+
+/* allocate and set to (0,1) */
+void
+mpfr_random_deviate_init (mpfr_random_deviate_t x)
+{
+ mpz_init (x->f);
+ x->e = 0;
+}
+
+/* reset to (0,1) */
+void
+mpfr_random_deviate_reset (mpfr_random_deviate_t x)
+{
+ x->e = 0;
+}
+
+/* deallocate */
+void
+mpfr_random_deviate_clear (mpfr_random_deviate_t x)
+{
+ mpz_clear (x->f);
+}
+
+/* swap two random deviates */
+void
+mpfr_random_deviate_swap (mpfr_random_deviate_t x, mpfr_random_deviate_t y)
+{
+ mpfr_random_size_t s;
+ unsigned long t;
+
+ /* swap x->e and y->e */
+ s = x->e;
+ x->e = y->e;
+ y->e = s;
+
+ /* swap x->h and y->h */
+ t = x->h;
+ x->h = y->h;
+ y->h = t;
+
+ /* swap x->f and y->f */
+ mpz_swap (x->f, y->f);
+}
+
+/* ensure x has at least k bits */
+static void
+random_deviate_generate (mpfr_random_deviate_t x, mpfr_random_size_t k,
+ gmp_randstate_t r, mpz_t t)
+{
+ /* Various compile time checks on mprf_random_deviate_t */
+
+ /* Check that the h field of a mpfr_random_deviate_t can hold W bits */
+ MPFR_STAT_STATIC_ASSERT (W > 0 && W <= sizeof (unsigned long) * CHAR_BIT);
+
+ /* Check mpfr_random_size_t can hold 32 bits and a mpfr_uprec_t. This
+ * ensures that max(mpfr_random_size_t) exceeds MPFR_PREC_MAX by at least
+ * 2^31 because mpfr_prec_t is a signed version of mpfr_uprec_t. This allows
+ * random deviates with many leading zeros in the fraction to be handled
+ * correctly. */
+ MPFR_STAT_STATIC_ASSERT (sizeof (mpfr_random_size_t) * CHAR_BIT >= 32 &&
+ sizeof (mpfr_random_size_t) >=
+ sizeof (mpfr_uprec_t));
+
+ /* Finally, at runtime, check that k is not too big. e is set to ceil(k/W)*W
+ * and we require that this allows x->e + 1 in random_deviate_leading_bit to
+ * be computed without overflow. */
+ MPFR_ASSERTN (k <= (mpfr_random_size_t)(-((int) W + 1)));
+
+ /* if t is non-null, it is used as a temporary */
+ if (x->e >= k)
+ return;
+
+ if (x->e == 0)
+ {
+ x->h = gmp_urandomb_ui (r, W); /* Generate the high fraction */
+ x->e = W;
+ if (x->e >= k)
+ return; /* Maybe that's it? */
+ }
+
+ if (t)
+ {
+ /* passed a mpz_t so compute needed bits in one call to mpz_urandomb */
+ k = ((k + (W-1)) / W) * W; /* Round up to multiple of W */
+ k -= x->e; /* The number of new bits */
+ mpz_urandomb (x->e == W ? x->f : t, r, k); /* Copy directly to x->f? */
+ if (x->e > W)
+ {
+ mpz_mul_2exp (x->f, x->f, k);
+ mpz_add (x->f, x->f, t);
+ }
+ x->e += k;
+ }
+ else
+ {
+ /* no mpz_t so compute the bits W at a time via gmp_urandomb_ui */
+ while (x->e < k)
+ {
+ unsigned long w = gmp_urandomb_ui (r, W);
+ if (x->e == W)
+ mpz_set_ui (x->f, w);
+ else
+ {
+ mpz_mul_2exp (x->f, x->f, W);
+ mpz_add_ui (x->f, x->f, w);
+ }
+ x->e += W;
+ }
+ }
+}
+
+/*
+ * return index [-1..127] of highest bit set. Return -1 if x = 0, 2 if x = 4,
+ * etc. (From Algorithms for programmers by Joerg Arndt.)
+ */
+static int
+highest_bit_idx_alt (unsigned long x)
+{
+ int r = 0;
+
+ if (x == 0)
+ return -1;
+ MPFR_ASSERTN (sizeof (unsigned long) * CHAR_BIT <= 128);
+ if (sizeof (unsigned long) * CHAR_BIT > 64)
+ {
+ /* handle 128-bit unsigned longs avoiding compiler warnings */
+ unsigned long y = x >> 16; y >>= 24; y >>= 24;
+ if (y) { x = y; r += 64;}
+ }
+ if (x & ~0xffffffffUL) { x >>= 16; x >>= 16; r +=32; }
+ if (x & 0xffff0000UL) { x >>= 16; r += 16; }
+ if (x & 0x0000ff00UL) { x >>= 8; r += 8; }
+ if (x & 0x000000f0UL) { x >>= 4; r += 4; }
+ if (x & 0x0000000cUL) { x >>= 2; r += 2; }
+ if (x & 0x00000002UL) { r += 1; }
+ return r;
+}
+
+/*
+ * return index [-1..63] of highest bit set.
+ * Return -1 if x = 0, 63 is if x = ~0 (for 64-bit unsigned long).
+ * See highest_bit_idx_alt too.
+ */
+static int
+highest_bit_idx (unsigned long x)
+{
+ /* this test should be evaluated at compile time */
+ if (sizeof (mp_limb_t) >= sizeof (unsigned long))
+ {
+ int cnt;
+
+ if (x == 0)
+ return -1;
+ count_leading_zeros (cnt, (mp_limb_t) x);
+ MPFR_ASSERTD (cnt <= GMP_NUMB_BITS - 1);
+ return GMP_NUMB_BITS - 1 - cnt;
+ }
+ else
+ return highest_bit_idx_alt (x);
+}
+
+/* return position of leading bit, counting from 1 */
+static mpfr_random_size_t
+random_deviate_leading_bit (mpfr_random_deviate_t x, gmp_randstate_t r)
+{
+ mpfr_random_size_t l;
+ random_deviate_generate (x, W, r, 0);
+ if (x->h)
+ return W - highest_bit_idx (x->h);
+ random_deviate_generate (x, 2 * W, r, 0);
+ while (mpz_sgn (x->f) == 0)
+ random_deviate_generate (x, x->e + 1, r, 0);
+ l = x->e + 1 - mpz_sizeinbase (x->f, 2);
+ /* Guard against a ridiculously long string of leading zeros in the fraction;
+ * probability of this happening is 2^(-2^31). In particular ensure that
+ * p + 1 + l in mpfr_random_deviate_value doesn't overflow with p =
+ * MPFR_PREC_MAX. */
+ MPFR_ASSERTN (l + 1 < (mpfr_random_size_t)(-MPFR_PREC_MAX));
+ return l;
+}
+
+/* return kth bit of fraction, representing 2^-k */
+int
+mpfr_random_deviate_tstbit (mpfr_random_deviate_t x, mpfr_random_size_t k,
+ gmp_randstate_t r)
+{
+ if (k == 0)
+ return 0;
+ random_deviate_generate (x, k, r, 0);
+ if (k <= W)
+ return (x->h >> (W - k)) & 1UL;
+ return mpz_tstbit (x->f, x->e - k);
+}
+
+/* compare two random deviates, x < y */
+int
+mpfr_random_deviate_less (mpfr_random_deviate_t x, mpfr_random_deviate_t y,
+ gmp_randstate_t r)
+{
+ mpfr_random_size_t k = 1;
+
+ if (x == y)
+ return 0;
+ random_deviate_generate (x, W, r, 0);
+ random_deviate_generate (y, W, r, 0);
+ if (x->h != y->h)
+ return x->h < y->h; /* Compare the high fractions */
+ k += W;
+ for (; ; ++k)
+ { /* Compare the rest of the fraction bit by bit */
+ int a = mpfr_random_deviate_tstbit (x, k, r);
+ int b = mpfr_random_deviate_tstbit (y, k, r);
+ if (a != b)
+ return a < b;
+ }
+}
+
+/* set mpfr_t z = (neg ? -1 : 1) * (n + x) */
+int
+mpfr_random_deviate_value (int neg, unsigned long n,
+ mpfr_random_deviate_t x, mpfr_t z,
+ gmp_randstate_t r, mpfr_rnd_t rnd)
+{
+ /* r is used to add as many bits as necessary to match the precision of z */
+ int s;
+ mpfr_random_size_t l; /* The leading bit is 2^(s*l) */
+ mpfr_random_size_t p = mpfr_get_prec (z); /* Number of bits in result */
+ mpz_t t;
+ int inex;
+
+ if (n == 0)
+ {
+ s = -1;
+ l = random_deviate_leading_bit (x, r); /* l > 0 */
+ }
+ else
+ {
+ s = 1;
+ l = highest_bit_idx (n); /* l >= 0 */
+ }
+
+ /*
+ * Leading bit is 2^(s*l); thus the trailing bit in result is 2^(s*l-p+1) =
+ * 2^-(p-1-s*l). For the sake of illustration, take l = 0 and p = 4, thus
+ * bits through the 1/8 position need to be generated; assume that these bits
+ * are 1.010 = 10/8 which represents a deviate in the range (10,11)/8.
+ *
+ * If the rounding mode is one of RNDZ, RNDU, RNDD, RNDA, we add a 1 bit to
+ * the result to give 1.0101 = (10+1/2)/8. When this is converted to a MPFR
+ * the result is rounded to 10/8, 11/8, 10/8, 11/8, respectively, and the
+ * inexact flag is set to -1, 1, -1, 1.
+ *
+ * If the rounding mode is RNDN, an additional random bit must be generated
+ * to determine if the result is in (10,10+1/2)/8 or (10+1/2,11)/8. Assume
+ * that this random bit is 0, so the result is 1.0100 = (10+0/2)/8. Then an
+ * additional 1 bit is added to give 1.010101 = (10+1/4)/8. This last bit
+ * avoids the "round ties to even rule" (because there are no ties) and sets
+ * the inexact flag so that the result is 10/8 with the inexact flag = 1.
+ *
+ * Here we always generate at least 2 additional random bits, so that bit
+ * position 2^-(p+1-s*l) is generated. (The result often contains more
+ * random bits than this because random bits are added in batches of W and
+ * because additional bits may have been required in the process of
+ * generating the random deviate.) The integer and all the bits in the
+ * fraction are then copied into an mpz, the least significant bit is
+ * unconditionally set to 1, the sign is set, and the result together with
+ * the exponent -x->e is used to generate an mpfr using mpfr_set_z_2exp.
+ *
+ * If random bits were very expensive, we would only need to generate to the
+ * 2^-(p-1-s*l) bit (no extra bits) for the RNDZ, RNDU, RNDD, RNDA modes and
+ * to the 2^-(p-s*l) bit (1 extra bit) for RNDN. By always generating 2 bits
+ * we save on some bit shuffling when formed the mpz to be converted to an
+ * mpfr. The implementation of the RandomNumber class in RandomLib
+ * illustrates the more parsimonious approach (which was taken to allow
+ * accurate counts of the number of random digits to be made).
+ */
+ mpz_init (t);
+ /*
+ * This is the only call to random_deviate_generate where a mpz_t is passed
+ * (because an arbitrarily large number of bits may need to be generated).
+ */
+ if ((s > 0 && p + 1 > l) ||
+ (s < 0 && p + 1 + l > 0))
+ random_deviate_generate (x, s > 0 ? p + 1 - l : p + 1 + l, r, t);
+ if (n == 0)
+ {
+ /* Since the minimum prec is 2 we know that x->h has been generated. */
+ mpz_set_ui (t, x->h); /* Set high fraction */
+ }
+ else
+ {
+ mpz_set_ui (t, n); /* The integer part */
+ if (x->e > 0)
+ {
+ mpz_mul_2exp (t, t, W); /* Shift to allow for high fraction */
+ mpz_add_ui (t, t, x->h); /* Add high fraction */
+ }
+ }
+ if (x->e > W)
+ {
+ mpz_mul_2exp (t, t, x->e - W); /* Shift to allow for low fraction */
+ mpz_add (t, t, x->f); /* Add low fraction */
+ }
+ /*
+ * We could trim off any excess bits here by shifting rightward. This is an
+ * unnecessary complication.
+ */
+ mpz_setbit (t, 0); /* Set the trailing bit so result is always inexact */
+ if (neg)
+ mpz_neg (t, t);
+ /* Is -x->e representable as a mpfr_exp_t? */
+ MPFR_ASSERTN (x->e <= (mpfr_uexp_t)(-1) >> 1);
+ /*
+ * Let mpfr_set_z_2exp do all the work of rounding to the requested
+ * precision, setting overflow/underflow flags, and returning the right
+ * inexact value.
+ */
+ inex = mpfr_set_z_2exp (z, t, -x->e, rnd);
+ mpz_clear (t);
+ return inex;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/random_deviate.h b/Build/source/libs/mpfr/mpfr-src/src/random_deviate.h
new file mode 100644
index 00000000000..0a69f4a8387
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/random_deviate.h
@@ -0,0 +1,86 @@
+/* Declarations of random_deviate routines for mpfr_erandom and mpfr_nrandom.
+
+Copyright 2013-2017 Free Software Foundation, Inc.
+Contributed by Charles Karney <charles@karney.com>, SRI International.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#if !defined(MPFR_RANDOM_DEVIATE_H)
+#define MPFR_RANDOM_DEVIATE_H 1
+
+#include "mpfr-impl.h"
+
+/* This should be an unsigned type with a width of at least 32 and capable of
+ * representing at least 2*MPFR_PREC_MAX. This is used to count the bits in
+ * the fraction of a mpfr_random_deviate_t. See the checks made on this type
+ * in random_deviate_generate. */
+typedef unsigned long mpfr_random_size_t;
+
+typedef struct {
+ mpfr_random_size_t e; /* total number of bits in the fraction */
+ unsigned long h; /* the high W bits of the fraction */
+ mpz_t f; /* the rest of the fraction */
+} __mpfr_random_deviate_struct;
+
+typedef __mpfr_random_deviate_struct mpfr_random_deviate_t[1];
+typedef __mpfr_random_deviate_struct *mpfr_random_deviate_ptr;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* allocate and set to (0,1) */
+__MPFR_DECLSPEC void
+ mpfr_random_deviate_init (mpfr_random_deviate_ptr);
+
+/* reset to (0,1) */
+__MPFR_DECLSPEC void
+ mpfr_random_deviate_reset (mpfr_random_deviate_ptr);
+
+/* deallocate */
+__MPFR_DECLSPEC void
+ mpfr_random_deviate_clear (mpfr_random_deviate_ptr);
+
+/* swap two random deviates */
+__MPFR_DECLSPEC void
+ mpfr_random_deviate_swap (mpfr_random_deviate_ptr,
+ mpfr_random_deviate_ptr);
+
+/* return kth bit of fraction, representing 2^-k */
+__MPFR_DECLSPEC int
+ mpfr_random_deviate_tstbit (mpfr_random_deviate_ptr,
+ mpfr_random_size_t,
+ gmp_randstate_t);
+
+/* compare two random deviates, x < y */
+__MPFR_DECLSPEC int
+ mpfr_random_deviate_less (mpfr_random_deviate_ptr,
+ mpfr_random_deviate_ptr,
+ gmp_randstate_t);
+
+/* set mpfr_t z = (neg ? -1 : 1) * (n + x) */
+__MPFR_DECLSPEC int
+ mpfr_random_deviate_value (int, unsigned long,
+ mpfr_random_deviate_ptr, mpfr_t,
+ gmp_randstate_t, mpfr_rnd_t);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/rec_sqrt.c b/Build/source/libs/mpfr/mpfr-src/src/rec_sqrt.c
index 90d3f27a054..8d190d5f315 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/rec_sqrt.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/rec_sqrt.c
@@ -20,20 +20,19 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <stdio.h>
-#include <stdlib.h>
-
#define MPFR_NEED_LONGLONG_H /* for umul_ppmm */
#include "mpfr-impl.h"
#define LIMB_SIZE(x) ((((x)-1)>>MPFR_LOG2_GMP_NUMB_BITS) + 1)
#define MPFR_COM_N(x,y,n) \
- { \
- mp_size_t i; \
- for (i = 0; i < n; i++) \
- *((x)+i) = ~*((y)+i); \
- }
+ do \
+ { \
+ mp_size_t i; \
+ for (i = 0; i < n; i++) \
+ *((x)+i) = ~*((y)+i); \
+ } \
+ while (0)
/* Put in X a p-bit approximation of 1/sqrt(A),
where X = {x, n}/B^n, n = ceil(p/GMP_NUMB_BITS),
@@ -68,7 +67,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
References:
[1] Modern Computer Algebra, Richard Brent and Paul Zimmermann,
- http://www.loria.fr/~zimmerma/mca/pub226.html
+ https://members.loria.fr/PZimmermann/mca/pub226.html
*/
static void
mpfr_mpn_rec_sqrt (mpfr_limb_ptr x, mpfr_prec_t p,
@@ -166,7 +165,7 @@ mpfr_mpn_rec_sqrt (mpfr_limb_ptr x, mpfr_prec_t p,
MPFR_ASSERTD((a[an - 1] & MPFR_LIMB_HIGHBIT) != 0);
/* We should have enough bits in one limb and GMP_NUMB_BITS should be even.
Since that does not depend on MPFR, we always check this. */
- MPFR_ASSERTN((GMP_NUMB_BITS >= 12) && ((GMP_NUMB_BITS & 1) == 0));
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS >= 12 && (GMP_NUMB_BITS & 1) == 0);
/* {a, an} and {x, n} should not overlap */
MPFR_ASSERTD((a + an <= x) || (x + n <= a));
MPFR_ASSERTD(p >= 11);
@@ -424,7 +423,7 @@ mpfr_mpn_rec_sqrt (mpfr_limb_ptr x, mpfr_prec_t p,
}
/* cy can be 1 when A=1, i.e., {a, n} = B^n. In that case we should
- have X = B^n, and setting X to 1-2^{-p} satisties the error bound
+ have X = B^n, and setting X to 1-2^{-p} satisfies the error bound
of 1 ulp. */
if (MPFR_UNLIKELY(cy != 0))
{
@@ -459,10 +458,10 @@ mpfr_rec_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
}
else if (MPFR_IS_ZERO(u)) /* 1/sqrt(+0) = 1/sqrt(-0) = +Inf */
{
- /* 0+ or 0- */
+ /* +0 or -0 */
MPFR_SET_INF(r);
MPFR_SET_POS(r);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET(0); /* Inf is exact */
}
else
diff --git a/Build/source/libs/mpfr/mpfr-src/src/rem1.c b/Build/source/libs/mpfr/mpfr-src/src/rem1.c
index 399d29bbdd3..89ca5ed57a5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/rem1.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/rem1.c
@@ -255,3 +255,10 @@ mpfr_fmod (mpfr_ptr rem, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
{
return mpfr_rem1 (rem, (long *) 0, MPFR_RNDZ, x, y, rnd);
}
+
+int
+mpfr_fmodquo (mpfr_ptr rem, long *quo, mpfr_srcptr x, mpfr_srcptr y,
+ mpfr_rnd_t rnd)
+{
+ return mpfr_rem1 (rem, quo, MPFR_RNDZ, x, y, rnd);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/rint.c b/Build/source/libs/mpfr/mpfr-src/src/rint.c
index ded7c098b26..c8b1ee96ace 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/rint.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/rint.c
@@ -213,7 +213,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
uj = un - ui; /* lowest limb of the integer part in u */
rj = rn - ui; /* lowest limb of the integer part in r */
- if (MPFR_LIKELY (rp != up))
+ if (rp != up)
MPN_COPY(rp + rj, up + uj, ui);
/* Ignore the lowest rj limbs, all equal to zero. */
@@ -281,7 +281,7 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
}
if (sh != 0)
- rp[0] &= MP_LIMB_T_MAX << sh;
+ rp[0] &= MPFR_LIMB_MAX << sh;
/* If u is a representable integer, there is no rounding. */
if (uflags == 0)
@@ -304,6 +304,14 @@ mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
} /* exp > 0, |u| >= 1 */
}
+#undef mpfr_roundeven
+
+int
+mpfr_roundeven (mpfr_ptr r, mpfr_srcptr u)
+{
+ return mpfr_rint (r, u, MPFR_RNDN);
+}
+
#undef mpfr_round
int
@@ -341,6 +349,32 @@ mpfr_floor (mpfr_ptr r, mpfr_srcptr u)
* the inexact flag when the argument is not an integer.
*/
+#undef mpfr_rint_roundeven
+
+int
+mpfr_rint_roundeven (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u))
+ return mpfr_set (r, u, rnd_mode);
+ else
+ {
+ mpfr_t tmp;
+ int inex;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
+ MPFR_BLOCK_DECL (flags);
+
+ mpfr_init2 (tmp, MPFR_PREC (u));
+ /* round(u) is representable in tmp unless an overflow occurs */
+ MPFR_BLOCK (flags, mpfr_roundeven (tmp, u));
+ __gmpfr_flags = saved_flags;
+ inex = (MPFR_OVERFLOW (flags)
+ ? mpfr_overflow (r, rnd_mode, MPFR_SIGN (u))
+ : mpfr_set (r, tmp, rnd_mode));
+ mpfr_clear (tmp);
+ return inex;
+ }
+}
+
#undef mpfr_rint_round
int
@@ -352,7 +386,7 @@ mpfr_rint_round (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
{
mpfr_t tmp;
int inex;
- unsigned int saved_flags = __gmpfr_flags;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
MPFR_BLOCK_DECL (flags);
mpfr_init2 (tmp, MPFR_PREC (u));
@@ -378,7 +412,7 @@ mpfr_rint_trunc (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
{
mpfr_t tmp;
int inex;
- unsigned int saved_flags = __gmpfr_flags;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
mpfr_init2 (tmp, MPFR_PREC (u));
/* trunc(u) is always representable in tmp */
@@ -401,7 +435,7 @@ mpfr_rint_ceil (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
{
mpfr_t tmp;
int inex;
- unsigned int saved_flags = __gmpfr_flags;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
MPFR_BLOCK_DECL (flags);
mpfr_init2 (tmp, MPFR_PREC (u));
@@ -427,7 +461,7 @@ mpfr_rint_floor (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
{
mpfr_t tmp;
int inex;
- unsigned int saved_flags = __gmpfr_flags;
+ mpfr_flags_t saved_flags = __gmpfr_flags;
MPFR_BLOCK_DECL (flags);
mpfr_init2 (tmp, MPFR_PREC (u));
diff --git a/Build/source/libs/mpfr/mpfr-src/src/rndna.c b/Build/source/libs/mpfr/mpfr-src/src/rndna.c
new file mode 100644
index 00000000000..94cf4992b75
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/rndna.c
@@ -0,0 +1,193 @@
+/* mpfr_round_nearest_away -- round to nearest away
+
+Copyright 2012-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Note: this doesn't work for 2^(emin-2). Currently, the best that can be
+ done is to extend the exponent range internally, and do not support the
+ case emin = MPFR_EMIN_MIN from the caller. */
+
+/* In order to work, we'll save the context within the mantissa of 'rop'.
+ For that, we need to do some low level stuff like for init2/clear to create
+ a mantissa of bigger size, which contains the extra context.
+ To add a new field of type T in the context, add its type in
+ mpfr_size_limb_extended_t (if it is not already present)
+ and add a new value for the enum mpfr_index_extended_t before MANTISSA. */
+typedef union {
+ mp_size_t si;
+ mp_limb_t li;
+ mpfr_exp_t ex;
+ mpfr_prec_t pr;
+ mpfr_sign_t sg;
+ mpfr_flags_t fl;
+ mpfr_limb_ptr pi;
+} mpfr_size_limb_extended_t;
+typedef enum {
+ ALLOC_SIZE = 0,
+ OLD_MANTISSA,
+ OLD_EXPONENT,
+ OLD_SIGN,
+ OLD_PREC,
+ OLD_FLAGS,
+ OLD_EXP_MIN,
+ OLD_EXP_MAX,
+ MANTISSA
+} mpfr_index_extended_t ;
+
+#define MPFR_MALLOC_EXTENDED_SIZE(s) \
+ (MANTISSA * sizeof(mpfr_size_limb_extended_t) + \
+ MPFR_BYTES_PER_MP_LIMB * (size_t) (s))
+
+/* This function is called before the applied function
+ and prepares rop to give it one more bit of precision
+ and to save its old value within it. */
+void
+mpfr_round_nearest_away_begin (mpfr_t rop)
+{
+ mpfr_t tmp;
+ mp_size_t xsize;
+ mpfr_size_limb_extended_t *ext;
+ mpfr_prec_t p;
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* when emin is the smallest possible value, we cannot
+ determine the correct round-to-nearest-away rounding for
+ 0.25*2^emin, which gets rounded to 0 with nearest-even,
+ instead of 0.5^2^emin. */
+ MPFR_ASSERTN(__gmpfr_emin > MPFR_EMIN_MIN);
+
+ p = MPFR_PREC (rop) + 1;
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* We can't use mpfr_init2 since we need to store an additional context
+ within the mantissa. */
+ MPFR_ASSERTN(p <= MPFR_PREC_MAX);
+ /* Allocate the context within the needed mantissa. */
+ xsize = MPFR_PREC2LIMBS (p);
+ ext = (mpfr_size_limb_extended_t *)
+ mpfr_allocate_func (MPFR_MALLOC_EXTENDED_SIZE(xsize));
+
+ /* Save the context first. */
+ ext[ALLOC_SIZE].si = xsize;
+ ext[OLD_MANTISSA].pi = MPFR_MANT(rop);
+ ext[OLD_EXPONENT].ex = MPFR_EXP(rop);
+ ext[OLD_SIGN].sg = MPFR_SIGN(rop);
+ ext[OLD_PREC].pr = MPFR_PREC(rop);
+ ext[OLD_FLAGS].fl = expo.saved_flags;
+ ext[OLD_EXP_MIN].ex = expo.saved_emin;
+ ext[OLD_EXP_MAX].ex = expo.saved_emax;
+
+ /* Create tmp as a proper NAN. */
+ MPFR_PREC(tmp) = p; /* Set prec */
+ MPFR_SET_POS(tmp); /* Set a sign */
+ MPFR_MANT(tmp) = (mp_limb_t*)(ext+MANTISSA); /* Set Mantissa ptr */
+ MPFR_SET_NAN(tmp); /* initializes to NaN */
+
+ /* Note: This full initialization to NaN may be unnecessary because of
+ the mpfr_set just below, but this is cleaner in case internals would
+ change in the future (for instance, some fields of tmp could be read
+ before being set, and reading an uninitialized value is UB here). */
+
+ /* Copy rop into tmp now (rop may be used as input later). */
+ MPFR_DBGRES (inexact = mpfr_set(tmp, rop, MPFR_RNDN));
+ MPFR_ASSERTD(inexact == 0); /* Shall be exact since prec(tmp) > prec(rop) */
+
+ /* Overwrite rop with tmp. */
+ rop[0] = tmp[0];
+
+ /* The new rop now contains a copy of the old rop, with one extra bit of
+ precision while keeping the old rop "hidden" within its mantissa. */
+
+ return;
+}
+
+/* This function is called after the applied function.
+ rop is the one prepared in the function above,
+ and contains the result of the applied function.
+ This function restores rop like it was before the
+ calls to mpfr_round_nearest_away_begin while
+ copying it back the result of the applied function
+ and performing additional roundings. */
+int
+mpfr_round_nearest_away_end (mpfr_t rop, int inex)
+{
+ mpfr_t tmp;
+ mp_size_t xsize;
+ mpfr_size_limb_extended_t *ext;
+ mpfr_prec_t n;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Get back the hidden context. */
+ ext = ((mpfr_size_limb_extended_t *) MPFR_MANT(rop)) - MANTISSA;
+
+ /* Create tmp with the result of the function. */
+ tmp[0] = rop[0];
+
+ /* Revert rop back to what it was before calling
+ mpfr_round_neareset_away_begin. */
+ MPFR_PREC(rop) = ext[OLD_PREC].pr;
+ MPFR_SIGN(rop) = ext[OLD_SIGN].sg;
+ MPFR_EXP(rop) = ext[OLD_EXPONENT].ex;
+ MPFR_MANT(rop) = ext[OLD_MANTISSA].pi;
+ MPFR_ASSERTD(MPFR_PREC(tmp) == MPFR_PREC(rop)+1);
+
+ /* Restore the saved context. */
+ expo.saved_flags = ext[OLD_FLAGS].fl;
+ expo.saved_emin = ext[OLD_EXP_MIN].ex;
+ expo.saved_emax = ext[OLD_EXP_MAX].ex;
+ xsize = ext[ALLOC_SIZE].si;
+
+ /* Perform RNDNA. */
+ n = MPFR_PREC(rop);
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (tmp)))
+ mpfr_set (rop, tmp, MPFR_RNDN); /* inex unchanged */
+ else
+ {
+ int lastbit, sh;
+
+ MPFR_UNSIGNED_MINUS_MODULO(sh, n + 1);
+ lastbit = (MPFR_MANT(tmp)[0] >> sh) & 1;
+
+ if (lastbit == 0)
+ mpfr_set (rop, tmp, MPFR_RNDN); /* exact, inex unchanged */
+ else if (inex == 0) /* midpoint: round away from zero */
+ inex = mpfr_set (rop, tmp, MPFR_RNDA);
+ else /* lastbit == 1, inex != 0: double rounding */
+ inex = mpfr_set (rop, tmp, (inex > 0) ? MPFR_RNDD : MPFR_RNDU);
+ }
+
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+
+ /* special treatment for the case rop = +/- 2^(emin-2), which should be
+ rounded to +/- 2^(emin-1). We do as if it was rounded to zero, thus the
+ mpfr_check_range() call will round it to +/- 2^(emin-1). */
+ if (inex == 0 && mpfr_cmp_si_2exp (rop, (mpfr_sgn (rop) > 0) ? 1 : -1,
+ __gmpfr_emin - 2) == 0)
+ inex = -mpfr_sgn (rop);
+
+ /* Free tmp (cannot call mpfr_clear): free the associated context. */
+ mpfr_free_func(ext, MPFR_MALLOC_EXTENDED_SIZE(xsize));
+
+ return mpfr_check_range (rop, inex, MPFR_RNDN);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/root.c b/Build/source/libs/mpfr/mpfr-src/src/root.c
index d3b5b171ad9..6bf9d578d8c 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/root.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/root.c
@@ -45,7 +45,7 @@ mpfr_root_aux (mpfr_ptr y, mpfr_srcptr x, unsigned long k,
mpfr_rnd_t rnd_mode);
int
-mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
+mpfr_rootn_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
{
mpz_t m;
mpfr_exp_t e, r, sh, f;
@@ -63,6 +63,7 @@ mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
{
if (k == 0)
{
+ /* rootn(x,0) is NaN (IEEE 754-2008). */
MPFR_SET_NAN (y);
MPFR_RET_NAN;
}
@@ -79,34 +80,43 @@ mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
MPFR_RET_NAN;
}
- if (MPFR_IS_INF (x)) /* +Inf^(1/k) = +Inf
- -Inf^(1/k) = -Inf if k odd
- -Inf^(1/k) = NaN if k even */
+ if (MPFR_IS_INF (x)) /* (+Inf)^(1/k) = +Inf
+ (-Inf)^(1/k) = -Inf if k odd
+ (-Inf)^(1/k) = NaN if k even */
{
- if (MPFR_IS_NEG(x) && (k % 2 == 0))
+ if (MPFR_IS_NEG (x) && (k & 1) == 0)
{
MPFR_SET_NAN (y);
MPFR_RET_NAN;
}
MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
}
else /* x is necessarily 0: (+0)^(1/k) = +0
(-0)^(1/k) = -0 */
{
MPFR_ASSERTD (MPFR_IS_ZERO (x));
MPFR_SET_ZERO (y);
+ if (MPFR_IS_POS (x) || (k & 1) == 0)
+ MPFR_SET_POS (y);
+ else
+ MPFR_SET_NEG (y);
}
- MPFR_SET_SAME_SIGN (y, x);
MPFR_RET (0);
}
/* Returns NAN for x < 0 and k even */
- if (MPFR_UNLIKELY (MPFR_IS_NEG (x) && (k % 2 == 0)))
+ if (MPFR_UNLIKELY (MPFR_IS_NEG (x) && (k & 1) == 0))
{
MPFR_SET_NAN (y);
MPFR_RET_NAN;
}
+ /* Special case |x| = 1. Note that if x = -1, then k is odd
+ (NaN results have already been filtered), so that y = -1. */
+ if (mpfr_cmpabs (x, __gmpfr_one) == 0)
+ return mpfr_set (y, x, rnd_mode);
+
/* General case */
/* For large k, use exp(log(x)/k). The threshold of 100 seems to be quite
@@ -188,6 +198,14 @@ mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
Assume all special cases have been eliminated before.
In the extended exponent range, overflows/underflows are not possible.
Assume x > 0, or x < 0 and k odd.
+ Also assume |x| <> 1 because log(1) = 0, which does not have an exponent
+ and would yield a failure in the error bound computation. A priori, this
+ constraint is quite artificial because if |x| is close enough to 1, then
+ the exponent of log|x| does not need to be used (in the code, err would
+ be 1 in such a domain). So this constraint |x| <> 1 could be avoided in
+ the code. However, this is an exact case easy to detect, so that such a
+ change would be useless. Values very close to 1 are not an issue, since
+ an underflow is not possible before the MPFR_GET_EXP.
*/
static int
mpfr_root_aux (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
@@ -219,7 +237,8 @@ mpfr_root_aux (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
mpfr_log (t, absx, MPFR_RNDN);
/* t = log|x| * (1 + theta) with |theta| <= 2^(-w) */
mpfr_div_ui (t, t, k, MPFR_RNDN);
- expt = MPFR_GET_EXP (t);
+ /* No possible underflow in mpfr_log and mpfr_div_ui. */
+ expt = MPFR_GET_EXP (t); /* assumes t <> 0 */
/* t = log|x|/k * (1 + theta) + eps with |theta| <= 2^(-w)
and |eps| <= 1/2 ulp(t), thus the total error is bounded
by 1.5 * 2^(expt - w) */
@@ -277,3 +296,36 @@ mpfr_root_aux (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
return mpfr_check_range (y, inexact, rnd_mode);
}
+
+int
+mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
+{
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg k=%lu rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, k, rnd_mode),
+ ("y[%Pu]=%.*Rg",
+ mpfr_get_prec (y), mpfr_log_prec, y));
+
+ /* Like mpfr_rootn_ui... */
+ if (MPFR_UNLIKELY (k <= 1))
+ {
+ if (k == 0)
+ {
+ /* rootn(x,0) is NaN (IEEE 754-2008). */
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else /* y = x^(1/1) = x */
+ return mpfr_set (y, x, rnd_mode);
+ }
+
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (x)))
+ {
+ /* The only case that may differ from mpfr_rootn_ui. */
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ else
+ return mpfr_rootn_ui (y, x, k, rnd_mode);
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/round_near_x.c b/Build/source/libs/mpfr/mpfr-src/src/round_near_x.c
index 3651eb1ea9e..cfa4ef0972e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/round_near_x.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/round_near_x.c
@@ -157,7 +157,10 @@ mpfr_round_near_x (mpfr_ptr y, mpfr_srcptr v, mpfr_uexp_t err, int dir,
mpfr_rnd_t rnd)
{
int inexact, sign;
- unsigned int old_flags = __gmpfr_flags;
+ mpfr_flags_t old_flags = __gmpfr_flags;
+
+ if (rnd == MPFR_RNDF)
+ rnd = MPFR_RNDZ;
MPFR_ASSERTD (!MPFR_IS_SINGULAR (v));
MPFR_ASSERTD (dir == 0 || dir == 1);
@@ -207,21 +210,21 @@ mpfr_round_near_x (mpfr_ptr y, mpfr_srcptr v, mpfr_uexp_t err, int dir,
inexact = -sign;
mpfr_nexttozero (y);
if (MPFR_UNLIKELY (MPFR_IS_ZERO (y)))
- mpfr_set_underflow ();
+ MPFR_SET_UNDERFLOW ();
}
}
else /* The error term is positive for v positive */
{
inexact = -sign;
/* Round Away */
- if (rnd != MPFR_RNDN && !MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG_SIGN(sign)))
+ if (MPFR_IS_LIKE_RNDA (rnd, MPFR_IS_NEG_SIGN(sign)))
{
/* case nexttoinf */
/* The overflow flag should be set if the result is infinity */
inexact = sign;
mpfr_nexttoinf (y);
if (MPFR_UNLIKELY (MPFR_IS_INF (y)))
- mpfr_set_overflow ();
+ MPFR_SET_OVERFLOW ();
}
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/round_p.c b/Build/source/libs/mpfr/mpfr-src/src/round_p.c
index c4f2973c25d..a7983b69ae4 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/round_p.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/round_p.c
@@ -23,8 +23,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
/* Check against mpfr_can_round? */
-#ifdef MPFR_WANT_ASSERT
-# if MPFR_WANT_ASSERT >= 2
+#if MPFR_WANT_ASSERT >= 2
int mpfr_round_p_2 (mp_limb_t *, mp_size_t, mpfr_exp_t, mpfr_prec_t);
int
mpfr_round_p (mp_limb_t *bp, mp_size_t bn, mpfr_exp_t err0, mpfr_prec_t prec)
@@ -56,8 +55,7 @@ mpfr_round_p (mp_limb_t *bp, mp_size_t bn, mpfr_exp_t err0, mpfr_prec_t prec)
return i1;
}
# define mpfr_round_p mpfr_round_p_2
-# endif
-#endif
+#endif /* MPFR_WANT_ASSERT >= 2 */
/*
* Assuming {bp, bn} is an approximation of a non-singular number
@@ -81,16 +79,16 @@ mpfr_round_p (mp_limb_t *bp, mp_size_t bn, mpfr_exp_t err0, mpfr_prec_t prec)
err = MIN (err, (mpfr_uexp_t) err0);
k = prec / GMP_NUMB_BITS;
- s = GMP_NUMB_BITS - prec%GMP_NUMB_BITS;
+ s = GMP_NUMB_BITS - prec % GMP_NUMB_BITS;
n = err / GMP_NUMB_BITS - k;
MPFR_ASSERTD (n >= 0);
MPFR_ASSERTD (bn > k);
/* Check first limb */
- bp += bn-1-k;
+ bp += bn - 1 - k;
tmp = *bp--;
- mask = s == GMP_NUMB_BITS ? MP_LIMB_T_MAX : MPFR_LIMB_MASK (s);
+ mask = s == GMP_NUMB_BITS ? MPFR_LIMB_MAX : MPFR_LIMB_MASK (s);
tmp &= mask;
if (MPFR_LIKELY (n == 0))
@@ -119,14 +117,14 @@ mpfr_round_p (mp_limb_t *bp, mp_size_t bn, mpfr_exp_t err0, mpfr_prec_t prec)
{
/* Check if all (n-1) limbs are 11111111111111111 */
while (--n)
- if (*bp-- != MP_LIMB_T_MAX)
+ if (*bp-- != MPFR_LIMB_MAX)
return 1;
/* Check if final error limb is 0 */
s = GMP_NUMB_BITS - err % GMP_NUMB_BITS;
if (s == GMP_NUMB_BITS)
return 0;
tmp = *bp >> s;
- return tmp != (MP_LIMB_T_MAX >> s);
+ return tmp != (MPFR_LIMB_MAX >> s);
}
else
{
diff --git a/Build/source/libs/mpfr/mpfr-src/src/round_prec.c b/Build/source/libs/mpfr/mpfr-src/src/round_prec.c
index 9c53c49126b..8e2e7858c3e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/round_prec.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/round_prec.c
@@ -45,6 +45,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define use_inexp 0
#include "round_raw_generic.c"
+/* Note: if the new prec is lower than the current one, a reallocation
+ must not be done (see exp_2.c). */
+
int
mpfr_prec_round (mpfr_ptr x, mpfr_prec_t prec, mpfr_rnd_t rnd_mode)
{
@@ -53,7 +56,7 @@ mpfr_prec_round (mpfr_ptr x, mpfr_prec_t prec, mpfr_rnd_t rnd_mode)
mpfr_prec_t nw, ow;
MPFR_TMP_DECL(marker);
- MPFR_ASSERTN(prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (MPFR_PREC_COND (prec));
nw = MPFR_PREC2LIMBS (prec); /* needed allocated limbs */
@@ -61,15 +64,17 @@ mpfr_prec_round (mpfr_ptr x, mpfr_prec_t prec, mpfr_rnd_t rnd_mode)
/* Get the number of limbs from the precision.
(Compatible with all allocation methods) */
ow = MPFR_LIMB_SIZE (x);
- if (nw > ow)
+ if (MPFR_UNLIKELY (nw > ow))
{
/* FIXME: Variable can't be created using custom allocation,
MPFR_DECL_INIT or GROUP_ALLOC: How to detect? */
ow = MPFR_GET_ALLOC_SIZE(x);
if (nw > ow)
{
+ mpfr_size_limb_t *tmpx;
+
/* Realloc significand */
- mpfr_limb_ptr tmpx = (mpfr_limb_ptr) (*__gmp_reallocate_func)
+ tmpx = (mpfr_size_limb_t *) mpfr_reallocate_func
(MPFR_GET_REAL_PTR(x), MPFR_MALLOC_SIZE(ow), MPFR_MALLOC_SIZE(nw));
MPFR_SET_MANT_PTR(x, tmpx); /* mant ptr must be set
before alloc size */
@@ -122,8 +127,32 @@ mpfr_prec_round (mpfr_ptr x, mpfr_prec_t prec, mpfr_rnd_t rnd_mode)
/* assuming b is an approximation to x in direction rnd1 with error at
most 2^(MPFR_EXP(b)-err), returns 1 if one is able to round exactly
x to precision prec with direction rnd2, and 0 otherwise.
-
Side effects: none.
+
+ rnd1 = RNDN and RNDF are similar: the sign of the error is unknown.
+
+ rnd2 = RNDF: assume that the user will round the approximation b
+ toward the direction of x, i.e. the opposite of rnd1 in directed
+ rounding modes, otherwise RNDN. Some details:
+
+ u xinf v xsup w
+ -----|----+----------|--+------------|-----
+ [----- x -----]
+ rnd1 = RNDD b |
+ rnd1 = RNDU b
+
+ where u, v and w are consecutive machine numbers.
+
+ * If [xinf,xsup] contains no machine numbers, then return 1.
+
+ * If [xinf,xsup] contains 2 machine numbers, then return 0.
+
+ * If [xinf,xsup] contains a single machine number, then return 1 iff
+ the rounding of b is this machine number.
+ With the above choice for the rounding of b, this will always be
+ the case if rnd1 is a directed rounding mode; said otherwise, for
+ rnd2 = RNDF and rnd1 being a directed rounding mode, return 1 iff
+ [xinf,xsup] contains at most 1 machine number.
*/
int
@@ -137,6 +166,13 @@ mpfr_can_round (mpfr_srcptr b, mpfr_exp_t err, mpfr_rnd_t rnd1,
MPFR_SIGN(b), err, rnd1, rnd2, prec);
}
+/* TODO: mpfr_can_round_raw currently does a memory allocation and some
+ mpn operations. A bit inspection like for mpfr_round_p (round_p.c) may
+ be sufficient, though this would be more complex than the one done in
+ mpfr_round_p, and in particular, for some rnd1/rnd2 combinations, one
+ needs to take care of changes of binade when the value is close to a
+ power of 2. */
+
int
mpfr_can_round_raw (const mp_limb_t *bp, mp_size_t bn, int neg, mpfr_exp_t err,
mpfr_rnd_t rnd1, mpfr_rnd_t rnd2, mpfr_prec_t prec)
@@ -161,8 +197,14 @@ mpfr_can_round_raw (const mp_limb_t *bp, mp_size_t bn, int neg, mpfr_exp_t err,
/* Transform RNDD and RNDU to Zero / Away */
MPFR_ASSERTD (neg == 0 || neg == 1);
+ /* transform RNDF to RNDN */
+ if (rnd1 == MPFR_RNDF)
+ rnd1 = MPFR_RNDN;
if (rnd1 != MPFR_RNDN)
rnd1 = MPFR_IS_LIKE_RNDZ(rnd1, neg) ? MPFR_RNDZ : MPFR_RNDA;
+ if (rnd2 == MPFR_RNDF)
+ rnd2 = (rnd1 == MPFR_RNDN) ? MPFR_RNDN :
+ MPFR_IS_LIKE_RNDZ(rnd2, neg) ? MPFR_RNDA : MPFR_RNDZ;
if (rnd2 != MPFR_RNDN)
rnd2 = MPFR_IS_LIKE_RNDZ(rnd2, neg) ? MPFR_RNDZ : MPFR_RNDA;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/round_raw_generic.c b/Build/source/libs/mpfr/mpfr-src/src/round_raw_generic.c
index f78b254e21c..66dc9ed4f8f 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/round_raw_generic.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/round_raw_generic.c
@@ -48,6 +48,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
* to 1. In this case, the even rounding is done away from 0, which is
* a natural generalization. Indeed, a number with 1-bit precision can
* be seen as a subnormal number with more precision.
+ *
+ * MPFR_RNDNA is now supported, but needs to be tested [TODO] and is
+ * still not part of the API. In particular, the MPFR_RNDNA value (-1)
+ * may change in the future without notice.
*/
int
@@ -64,7 +68,7 @@ mpfr_round_raw_generic(
{
mp_size_t xsize, nw;
mp_limb_t himask, lomask, sb;
- int rw;
+ int rw, new_use_inexp;
#if flag == 0
int carry;
#endif
@@ -76,9 +80,22 @@ mpfr_round_raw_generic(
MPFR_ASSERTD(inexp != ((int*) 0));
MPFR_ASSERTD(neg == 0 || neg == 1);
- if (flag && !use_inexp &&
- (xprec <= yprec || MPFR_IS_LIKE_RNDZ (rnd_mode, neg)))
- return 0;
+ if (rnd_mode == MPFR_RNDF)
+ {
+ if (use_inexp)
+ *inexp = 0; /* make sure it has a valid value */
+ if (flag)
+ return 0;
+ rnd_mode = MPFR_RNDZ; /* faster */
+ new_use_inexp = 0;
+ }
+ else
+ {
+ if (flag && !use_inexp &&
+ (xprec <= yprec || MPFR_IS_LIKE_RNDZ (rnd_mode, neg)))
+ return 0;
+ new_use_inexp = use_inexp;
+ }
xsize = MPFR_PREC2LIMBS (xprec);
nw = yprec / GMP_NUMB_BITS;
@@ -86,7 +103,7 @@ mpfr_round_raw_generic(
if (MPFR_UNLIKELY(xprec <= yprec))
{ /* No rounding is necessary. */
- /* if yp=xp, maybe an overlap: MPN_COPY_DECR is ok when src <= dst */
+ /* if yp=xp, maybe an overlap: mpn_copyd is OK when src <= dst */
if (MPFR_LIKELY(rw))
nw++;
MPFR_ASSERTD(nw >= 1);
@@ -94,13 +111,13 @@ mpfr_round_raw_generic(
if (use_inexp)
*inexp = 0;
#if flag == 0
- MPN_COPY_DECR(yp + (nw - xsize), xp, xsize);
+ mpn_copyd (yp + (nw - xsize), xp, xsize);
MPN_ZERO(yp, nw - xsize);
#endif
return 0;
}
- if (use_inexp || !MPFR_IS_LIKE_RNDZ(rnd_mode, neg))
+ if (new_use_inexp || !MPFR_IS_LIKE_RNDZ(rnd_mode, neg))
{
mp_size_t k = xsize - nw - 1;
@@ -112,26 +129,25 @@ mpfr_round_raw_generic(
}
else
{
- lomask = ~(mp_limb_t) 0;
- himask = ~(mp_limb_t) 0;
+ lomask = MPFR_LIMB_MAX;
+ himask = MPFR_LIMB_MAX;
}
MPFR_ASSERTD(k >= 0);
sb = xp[k] & lomask; /* First non-significant bits */
- /* Rounding to nearest ? */
- if (MPFR_LIKELY( rnd_mode == MPFR_RNDN) )
+ /* Rounding to nearest? */
+ if (rnd_mode == MPFR_RNDN || rnd_mode == MPFR_RNDNA)
{
/* Rounding to nearest */
mp_limb_t rbmask = MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1 - rw);
- if (sb & rbmask) /* rounding bit */
- sb &= ~rbmask; /* it is 1, clear it */
- else
- {
- /* Rounding bit is 0, behave like rounding to 0 */
- goto rnd_RNDZ;
- }
+
+ if ((sb & rbmask) == 0) /* rounding bit = 0 ? */
+ goto rnd_RNDZ; /* yes, behave like rounding toward zero */
+ /* Rounding to nearest with rounding bit = 1 */
+ if (MPFR_UNLIKELY (rnd_mode == MPFR_RNDNA))
+ goto away_addone_ulp; /* like rounding away from zero */
+ sb &= ~rbmask; /* first bits after the rounding bit */
while (MPFR_UNLIKELY(sb == 0) && k > 0)
sb = xp[--k];
- /* rounding to nearest, with rounding bit = 1 */
if (MPFR_UNLIKELY(sb == 0)) /* Even rounding. */
{
/* sb == 0 && rnd_mode == MPFR_RNDN */
@@ -140,34 +156,32 @@ mpfr_round_raw_generic(
{
if (use_inexp)
*inexp = 2*MPFR_EVEN_INEX*neg-MPFR_EVEN_INEX;
- /* ((neg!=0)^(sb!=0)) ? MPFR_EVEN_INEX : -MPFR_EVEN_INEX;*/
- /* Since neg = 0 or 1 and sb=0*/
-#if flag == 1
- return 0 /*sb != 0 && rnd_mode != MPFR_RNDZ */;
-#else
- MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+ /* ((neg!=0)^(sb!=0)) ? MPFR_EVEN_INEX : -MPFR_EVEN_INEX */
+ /* since neg = 0 or 1 and sb = 0 */
+#if flag == 0
+ mpn_copyi (yp, xp + xsize - nw, nw);
yp[0] &= himask;
- return 0;
#endif
+ return 0; /* sb != 0 && rnd_mode != MPFR_RNDZ */
}
else
{
+ away_addone_ulp:
/* sb != 0 && rnd_mode == MPFR_RNDN */
if (use_inexp)
*inexp = MPFR_EVEN_INEX-2*MPFR_EVEN_INEX*neg;
- /*((neg!=0)^(sb!=0))? MPFR_EVEN_INEX : -MPFR_EVEN_INEX; */
- /*Since neg= 0 or 1 and sb != 0 */
+ /* ((neg!=0)^(sb!=0)) ? MPFR_EVEN_INEX : -MPFR_EVEN_INEX */
+ /* since neg = 0 or 1 and sb != 0 */
goto rnd_RNDN_add_one_ulp;
}
}
- else /* sb != 0 && rnd_mode == MPFR_RNDN*/
+ else /* sb != 0 && rnd_mode == MPFR_RNDN */
{
if (use_inexp)
- /* *inexp = (neg == 0) ? 1 : -1; but since neg = 0 or 1 */
- *inexp = 1-2*neg;
+ *inexp = 1-2*neg; /* neg == 0 ? 1 : -1 */
rnd_RNDN_add_one_ulp:
#if flag == 1
- return 1; /*sb != 0 && rnd_mode != MPFR_RNDZ;*/
+ return 1; /* sb != 0 && rnd_mode != MPFR_RNDZ */
#else
carry = mpn_add_1 (yp, xp + xsize - nw, nw,
rw ?
@@ -178,7 +192,7 @@ mpfr_round_raw_generic(
#endif
}
}
- /* Rounding to Zero ? */
+ /* Rounding toward zero? */
else if (MPFR_IS_LIKE_RNDZ(rnd_mode, neg))
{
/* rnd_mode == MPFR_RNDZ */
@@ -187,41 +201,36 @@ mpfr_round_raw_generic(
sb = xp[--k];
if (use_inexp)
/* rnd_mode == MPFR_RNDZ and neg = 0 or 1 */
- /* (neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1);*/
+ /* ((neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1 */
*inexp = MPFR_UNLIKELY(sb == 0) ? 0 : (2*neg-1);
-#if flag == 1
- return 0; /*sb != 0 && rnd_mode != MPFR_RNDZ;*/
-#else
- MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+#if flag == 0
+ mpn_copyi (yp, xp + xsize - nw, nw);
yp[0] &= himask;
- return 0;
#endif
+ return 0; /* sb != 0 && rnd_mode != MPFR_RNDZ */
}
else
{
- /* rnd_mode = Away */
+ /* Rounding away from zero */
while (MPFR_UNLIKELY(sb == 0) && k > 0)
sb = xp[--k];
if (MPFR_UNLIKELY(sb == 0))
{
/* sb = 0 && rnd_mode != MPFR_RNDZ */
if (use_inexp)
- /* (neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1);*/
+ /* ((neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1 */
*inexp = 0;
-#if flag == 1
- return 0;
-#else
- MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+#if flag == 0
+ mpn_copyi (yp, xp + xsize - nw, nw);
yp[0] &= himask;
- return 0;
#endif
+ return 0;
}
else
{
/* sb != 0 && rnd_mode != MPFR_RNDZ */
if (use_inexp)
- /* (neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1);*/
- *inexp = 1-2*neg;
+ *inexp = 1-2*neg; /* neg == 0 ? 1 : -1 */
#if flag == 1
return 1;
#else
@@ -236,21 +245,19 @@ mpfr_round_raw_generic(
}
else
{
- /* Roundind mode = Zero / No inexact flag */
-#if flag == 1
- return 0 /*sb != 0 && rnd_mode != MPFR_RNDZ*/;
-#else
+ /* Rounding toward zero / no inexact flag */
+#if flag == 0
if (MPFR_LIKELY(rw))
{
nw++;
himask = ~MPFR_LIMB_MASK (GMP_NUMB_BITS - rw);
}
else
- himask = ~(mp_limb_t) 0;
- MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+ himask = MPFR_LIMB_MAX;
+ mpn_copyi (yp, xp + xsize - nw, nw);
yp[0] &= himask;
- return 0;
#endif
+ return 0;
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/scale2.c b/Build/source/libs/mpfr/mpfr-src/src/scale2.c
index 5081c135456..bcc8ec002fe 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/scale2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/scale2.c
@@ -30,9 +30,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
double
mpfr_scale2 (double d, int exp)
{
-#if _GMP_IEEE_FLOATS
+#if _MPFR_IEEE_FLOATS
{
- union ieee_double_extract x;
+ union mpfr_ieee_double_extract x;
if (MPFR_UNLIKELY (d == 1.0))
{
@@ -57,7 +57,7 @@ mpfr_scale2 (double d, int exp)
}
return x.d;
}
-#else /* _GMP_IEEE_FLOATS */
+#else /* _MPFR_IEEE_FLOATS */
{
double factor;
@@ -87,5 +87,5 @@ mpfr_scale2 (double d, int exp)
}
return d;
}
-#endif
+#endif /* _MPFR_IEEE_FLOATS */
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set.c b/Build/source/libs/mpfr/mpfr-src/src/set.c
index 4d4d5ecfaed..39b93e14bcc 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set.c
@@ -23,7 +23,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
/* set a to abs(b) * signb: a=b when signb = SIGN(b), a=abs(b) when signb=1 */
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_set4 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, int signb)
{
/* Sign is ALWAYS copied */
@@ -43,7 +43,7 @@ mpfr_set4 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, int signb)
else
MPFR_RET (0);
}
- else if (MPFR_LIKELY (MPFR_PREC (b) == MPFR_PREC (a)))
+ else if (MPFR_PREC (b) == MPFR_PREC (a))
{
/* Same precision and b is not singular:
* just copy the mantissa, and set the exponent and the sign
@@ -57,8 +57,9 @@ mpfr_set4 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, int signb)
/* Else Round B inside a */
MPFR_RNDRAW (inex, a, MPFR_MANT (b), MPFR_PREC (b), rnd_mode, signb,
- if (MPFR_UNLIKELY ( ++MPFR_EXP (a) > __gmpfr_emax))
- return mpfr_overflow (a, rnd_mode, signb) );
+ if (MPFR_UNLIKELY (++ MPFR_EXP (a) > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, signb)
+ );
MPFR_RET (inex);
}
}
@@ -78,3 +79,121 @@ mpfr_abs (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
{
return mpfr_set4 (a, b, rnd_mode, MPFR_SIGN_POS);
}
+
+/* Round (u, inex) into s with rounding mode rnd, where inex is the ternary
+ value associated to u with the *same* rounding mode.
+ Assumes PREC(u) = 2*PREC(s).
+ The main algorithm is the following:
+ rnd=RNDZ: inex2 = mpfr_set (s, u, rnd_mode); return inex2 | inex;
+ (a negative value, if any, is preserved in inex2 | inex)
+ rnd=RNDA: idem
+ rnd=RNDN: inex2 = mpfr_set (s, u, rnd_mode);
+ if (inex2) return inex2; else return inex; */
+int
+mpfr_set_1_2 (mpfr_ptr s, mpfr_srcptr u, mpfr_rnd_t rnd_mode, int inex)
+{
+ mpfr_prec_t p = MPFR_PREC(s);
+ mpfr_prec_t sh = GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb;
+ mp_limb_t *sp = MPFR_MANT(s);
+ mp_limb_t *up = MPFR_MANT(u);
+ mp_limb_t mask;
+ int inex2;
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(u)))
+ {
+ mpfr_set (s, u, rnd_mode);
+ return inex;
+ }
+
+ MPFR_ASSERTD(MPFR_PREC(u) == 2 * MPFR_PREC(s));
+
+ if (MPFR_PREC(s) < GMP_NUMB_BITS)
+ {
+ mask = MPFR_LIMB_MASK(sh);
+
+ if (MPFR_PREC(u) <= GMP_NUMB_BITS)
+ {
+ mp_limb_t u0 = up[0];
+
+ /* it suffices to round (u0, inex) */
+ rb = u0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb = (u0 & mask) ^ rb;
+ sp[0] = u0 & ~mask;
+ }
+ else
+ {
+ mp_limb_t u1 = up[1];
+
+ /* we need to round (u1, u0, inex) */
+ mask = MPFR_LIMB_MASK(sh);
+ rb = u1 & (MPFR_LIMB_ONE << (sh - 1));
+ sb = ((u1 & mask) ^ rb) | up[0];
+ sp[0] = u1 & ~mask;
+ }
+
+ inex2 = inex * MPFR_SIGN(u);
+ MPFR_SIGN(s) = MPFR_SIGN(u);
+ MPFR_EXP(s) = MPFR_EXP(u);
+
+ /* in case inex2 > 0, the value of u is rounded away,
+ thus we need to subtract something from (u0, rb, sb):
+ (a) if sb is not zero, since the subtracted value is < 1, we can leave
+ sb as it is;
+ (b) if rb <> 0 and sb = 0: change to rb = 0 and sb = 1
+ (c) if rb = sb = 0: change to rb = 1 and sb = 1, and subtract 1 */
+ if (inex2 > 0)
+ {
+ if (rb && sb == 0)
+ {
+ rb = 0;
+ sb = 1;
+ }
+ }
+ else /* inex2 <= 0 */
+ sb |= inex;
+
+ /* now rb, sb are the round and sticky bits, together with the value of
+ sp[0], except possibly in the case rb = sb = 0 and inex2 > 0 */
+ if (rb == 0 && sb == 0)
+ {
+ if (inex2 <= 0)
+ MPFR_RET(0);
+ else /* inex2 > 0 can only occur for RNDN and RNDA:
+ RNDN: return sp[0] and inex
+ RNDA: return sp[0] and inex */
+ MPFR_RET(inex);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (sp[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(s)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(s));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ sp[0] += MPFR_LIMB_ONE << sh;
+ if (MPFR_UNLIKELY(sp[0] == 0))
+ {
+ sp[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_EXP(s) + 1 <= __gmpfr_emax)
+ MPFR_SET_EXP (s, MPFR_EXP(s) + 1);
+ else /* overflow */
+ return mpfr_overflow (s, rnd_mode, MPFR_SIGN(s));
+ }
+ MPFR_RET(MPFR_SIGN(s));
+ }
+ }
+
+ /* general case PREC(s) >= GMP_NUMB_BITS */
+ inex2 = mpfr_set (s, u, rnd_mode);
+ return (rnd_mode != MPFR_RNDN) ? inex | inex2
+ : (inex2) ? inex2 : inex;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_d.c b/Build/source/libs/mpfr/mpfr-src/src/set_d.c
index fb6fb457d84..a1f03534e5b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_d.c
@@ -26,71 +26,83 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-/* extracts the bits of d in rp[0..n-1] where n=ceil(53/GMP_NUMB_BITS).
- Assumes d is neither 0 nor NaN nor Inf. */
-static long
-__gmpfr_extract_double (mpfr_limb_ptr rp, double d)
- /* e=0 iff GMP_NUMB_BITS=32 and rp has only one limb */
+/* Extracts the bits of |d| in rp[0..n-1] where n=ceil(53/GMP_NUMB_BITS).
+ Assumes d finite and <> 0.
+ Returns the corresponding exponent such that |d| = {rp, n} * 2^exp,
+ with the value of {rp, n} in [1/2, 1).
+ The int type should be sufficient for exp.
+*/
+static int
+extract_double (mpfr_limb_ptr rp, double d)
{
- long exp;
+ int exp;
mp_limb_t manl;
#if GMP_NUMB_BITS == 32
mp_limb_t manh;
#endif
- /* BUGS
- 1. Should handle Inf and NaN in IEEE specific code.
- 2. Handle Inf and NaN also in default code, to avoid hangs.
- 3. Generalize to handle all GMP_NUMB_BITS.
- 4. This lits is incomplete and misspelled.
- */
+ /* FIXME: Generalize to handle all GMP_NUMB_BITS. */
MPFR_ASSERTD(!DOUBLE_ISNAN(d));
MPFR_ASSERTD(!DOUBLE_ISINF(d));
MPFR_ASSERTD(d != 0.0);
-#if _GMP_IEEE_FLOATS
+#if _MPFR_IEEE_FLOATS
{
- union ieee_double_extract x;
+ union mpfr_ieee_double_extract x;
x.d = d;
exp = x.s.exp;
if (exp)
{
#if GMP_NUMB_BITS >= 64
- manl = ((MPFR_LIMB_ONE << 63)
- | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
+ manl = ((MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1)) |
+ ((mp_limb_t) x.s.manh << (GMP_NUMB_BITS - 21)) |
+ ((mp_limb_t) x.s.manl << (GMP_NUMB_BITS - 53)));
#else
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 32);
manh = (MPFR_LIMB_ONE << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
manl = x.s.manl << 11;
#endif
+ exp -= 1022;
}
else /* subnormal number */
{
+ int cnt;
+ exp = -1021;
#if GMP_NUMB_BITS >= 64
- manl = ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11);
+ manl = (((mp_limb_t) x.s.manh << (GMP_NUMB_BITS - 21)) |
+ ((mp_limb_t) x.s.manl << (GMP_NUMB_BITS - 53)));
+ count_leading_zeros (cnt, manl);
#else
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 32);
manh = (x.s.manh << 11) /* high 21 bits */
| (x.s.manl >> 21); /* middle 11 bits */
manl = x.s.manl << 11; /* low 21 bits */
+ if (manh == 0)
+ {
+ manh = manl;
+ manl = 0;
+ exp -= GMP_NUMB_BITS;
+ }
+ count_leading_zeros (cnt, manh);
+ manh = (manh << cnt) |
+ (cnt != 0 ? manl >> (GMP_NUMB_BITS - cnt) : 0);
#endif
+ manl <<= cnt;
+ exp -= cnt;
}
-
- if (exp)
- exp -= 1022;
- else
- exp = -1021;
}
-#else /* _GMP_IEEE_FLOATS */
+#else /* _MPFR_IEEE_FLOATS */
{
/* Unknown (or known to be non-IEEE) double format. */
exp = 0;
+ d = ABS (d);
if (d >= 1.0)
{
- MPFR_ASSERTN (d * 0.5 != d);
while (d >= 32768.0)
{
d *= (1.0 / 65536.0);
@@ -118,22 +130,31 @@ __gmpfr_extract_double (mpfr_limb_ptr rp, double d)
d *= MP_BASE_AS_DOUBLE;
#if GMP_NUMB_BITS >= 64
+#ifndef __clang__
manl = d;
#else
+ /* clang produces an invalid exception when d >= 2^63,
+ see https://bugs.llvm.org//show_bug.cgi?id=17686.
+ Since this is always the case, here, we use the following patch. */
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 64);
+ manl = 0x8000000000000000 + (mp_limb_t) (d - 0x8000000000000000);
+#endif /* __clang__ */
+#else
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 32);
manh = (mp_limb_t) d;
manl = (mp_limb_t) ((d - manh) * MP_BASE_AS_DOUBLE);
#endif
}
-#endif /* _GMP_IEEE_FLOATS */
+#endif /* _MPFR_IEEE_FLOATS */
-#if GMP_NUMB_BITS >= 64
rp[0] = manl;
-#else
+#if GMP_NUMB_BITS == 32
rp[1] = manh;
- rp[0] = manl;
#endif
+ MPFR_ASSERTD((rp[MPFR_LIMBS_PER_DOUBLE - 1] & MPFR_LIMB_HIGHBIT) != 0);
+
return exp;
}
@@ -142,9 +163,7 @@ __gmpfr_extract_double (mpfr_limb_ptr rp, double d)
int
mpfr_set_d (mpfr_ptr r, double d, mpfr_rnd_t rnd_mode)
{
- int signd, inexact;
- unsigned int cnt;
- mp_size_t i, k;
+ int inexact;
mpfr_t tmp;
mp_limb_t tmpmant[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
@@ -156,8 +175,8 @@ mpfr_set_d (mpfr_ptr r, double d, mpfr_rnd_t rnd_mode)
}
else if (MPFR_UNLIKELY(d == 0))
{
-#if _GMP_IEEE_FLOATS
- union ieee_double_extract x;
+#if _MPFR_IEEE_FLOATS
+ union mpfr_ieee_double_extract x;
MPFR_SET_ZERO(r);
/* set correct sign */
@@ -166,16 +185,23 @@ mpfr_set_d (mpfr_ptr r, double d, mpfr_rnd_t rnd_mode)
MPFR_SET_NEG(r);
else
MPFR_SET_POS(r);
-#else /* _GMP_IEEE_FLOATS */
+#else /* _MPFR_IEEE_FLOATS */
MPFR_SET_ZERO(r);
{
/* This is to get the sign of zero on non-IEEE hardware
- Some systems support +0.0, -0.0 and unsigned zero.
- We can't use d==+0.0 since it should be always true,
+ Some systems support +0.0, -0.0, and unsigned zero.
+ Some other systems may just have an unsigned zero.
+ We can't use d == +0.0 since it should be always true,
so we check that the memory representation of d is the
- same than +0.0. etc */
- /* FIXME: consider the case where +0.0 or -0.0 may have several
- representations. */
+ same than +0.0, etc.
+ Note: r is set to -0 only if d is detected as a negative zero
+ *and*, for the double type, -0 has a different representation
+ from +0. If -0.0 has several representations, the code below
+ may not work as expected, but this is hardly fixable in a
+ portable way (without depending on a math library) and only
+ the sign could be incorrect. Such systems should be taken
+ into account on a case-by-case basis. If the code is changed
+ here, set_d64.c code should be updated too. */
double poszero = +0.0, negzero = DBL_NEG_ZERO;
if (memcmp(&d, &poszero, sizeof(double)) == 0)
MPFR_SET_POS(r);
@@ -184,7 +210,7 @@ mpfr_set_d (mpfr_ptr r, double d, mpfr_rnd_t rnd_mode)
else
MPFR_SET_POS(r);
}
-#endif
+#endif /* _MPFR_IEEE_FLOATS */
return 0; /* 0 is exact */
}
else if (MPFR_UNLIKELY(DOUBLE_ISINF(d)))
@@ -207,45 +233,12 @@ mpfr_set_d (mpfr_ptr r, double d, mpfr_rnd_t rnd_mode)
MPFR_MANT(tmp) = tmpmant;
MPFR_PREC(tmp) = IEEE_DBL_MANT_DIG;
- signd = (d < 0) ? MPFR_SIGN_NEG : MPFR_SIGN_POS;
- d = ABS (d);
-
- /* don't use MPFR_SET_EXP here since the exponent may be out of range */
- MPFR_EXP(tmp) = __gmpfr_extract_double (tmpmant, d);
-
-#ifdef MPFR_WANT_ASSERT
- /* 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)
- {
- 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 - 1]);
-
- if (MPFR_LIKELY(cnt != 0))
- mpn_lshift (tmpmant + k, tmpmant, i, cnt);
- else if (k != 0)
- MPN_COPY (tmpmant + k, tmpmant, i);
-
- if (MPFR_UNLIKELY(k != 0))
- MPN_ZERO (tmpmant, k);
-
/* don't use MPFR_SET_EXP here since the exponent may be out of range */
- MPFR_EXP(tmp) -= (mpfr_exp_t) (cnt + k * GMP_NUMB_BITS);
+ MPFR_EXP(tmp) = extract_double (tmpmant, d);
/* tmp is exact since PREC(tmp)=53 */
- inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
+ inexact = mpfr_set4 (r, tmp, rnd_mode,
+ (d < 0) ? MPFR_SIGN_NEG : MPFR_SIGN_POS);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (r, inexact, rnd_mode);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_d64.c b/Build/source/libs/mpfr/mpfr-src/src/set_d64.c
index cf22fcaac83..2e3e37e01c6 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_d64.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_d64.c
@@ -1,8 +1,8 @@
-/* mpfr_set_decimal64 -- convert a IEEE 754r decimal64 float to
+/* mpfr_set_decimal64 -- convert an IEEE 754-2008 decimal64 float to
a multiple precision floating-point number
-See http://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
-http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
+See https://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
+https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
and TR 24732 <http://www.open-std.org/jtc1/sc22/wg14/www/projects#24732>.
Copyright 2006-2017 Free Software Foundation, Inc.
@@ -102,13 +102,19 @@ static unsigned int T[1024] = {
774, 775, 776, 777, 778, 779, 796, 797, 976, 977, 998, 999 };
#endif
+#if _MPFR_IEEE_FLOATS
/* Convert d to a decimal string (one-to-one correspondence, no rounding).
- The string s needs to have at least 23 characters.
+ The string s needs to have at least 25 characters (with the final '\0'):
+ * 1 for the sign '-'
+ * 2 for the leading '0.'
+ * 16 for the significand
+ * 5 for the exponent (for example 'E-100')
+ * 1 for the final '\0'
*/
static void
decimal64_to_string (char *s, _Decimal64 d)
{
- union ieee_double_extract x;
+ union mpfr_ieee_double_extract x;
union ieee_double_decimal64 y;
char *t;
unsigned int Gh; /* most 5 significant bits from combination field */
@@ -205,15 +211,216 @@ decimal64_to_string (char *s, _Decimal64 d)
#endif /* DPD or BID */
exp -= 398; /* unbiased exponent */
- t += sprintf (t, "E%d", exp);
+ sprintf (t, "E%d", exp);
}
+#else
+/* portable version */
+#ifndef DEC64_MAX
+# define DEC64_MAX 9.999999999999999E384dd
+#endif
+
+static void
+decimal64_to_string (char *s, _Decimal64 d)
+{
+ int sign = 0, n;
+ int exp = 0;
+
+ if (MPFR_UNLIKELY (DOUBLE_ISNAN (d))) /* NaN */
+ {
+ sprintf (s, "NaN"); /* sprintf puts a final '\0' */
+ return;
+ }
+ else if (MPFR_UNLIKELY (d > DEC64_MAX)) /* +Inf */
+ {
+ sprintf (s, "Inf");
+ return;
+ }
+ else if (MPFR_UNLIKELY (d < -DEC64_MAX)) /* -Inf */
+ {
+ sprintf (s, "-Inf");
+ return;
+ }
+
+ /* now d is neither NaN nor +Inf nor -Inf */
+
+ if (d < (_Decimal64) 0.0)
+ {
+ sign = 1;
+ d = -d;
+ }
+ else if (d == (_Decimal64) -0.0)
+ { /* Warning: the comparison d == -0.0 returns true for d = 0.0 too,
+ copy code from set_d.c here. We first compare to the +0.0 bitstring,
+ in case +0.0 and -0.0 are represented identically. */
+ double dd = (double) d, poszero = +0.0, negzero = DBL_NEG_ZERO;
+ if (memcmp (&dd, &poszero, sizeof(double)) != 0 &&
+ memcmp (&dd, &negzero, sizeof(double)) == 0)
+ {
+ sign = 1;
+ d = -d;
+ }
+ }
+
+ /* now normalize d in [0.1, 1[ */
+ if (d >= (_Decimal64) 1.0)
+ {
+ _Decimal64 ten16 = (double) 1e16; /* 10^16 is exactly representable
+ in binary64 */
+ _Decimal64 ten32 = ten16 * ten16;
+ _Decimal64 ten64 = ten32 * ten32;
+ _Decimal64 ten128 = ten64 * ten64;
+ _Decimal64 ten256 = ten128 * ten128;
+
+ if (d >= ten256)
+ {
+ d /= ten256;
+ exp += 256;
+ }
+ if (d >= ten128)
+ {
+ d /= ten128;
+ exp += 128;
+ }
+ if (d >= ten64)
+ {
+ d /= ten64;
+ exp += 64;
+ }
+ if (d >= ten32)
+ {
+ d /= ten32;
+ exp += 32;
+ }
+ if (d >= (_Decimal64) 10000000000000000.0)
+ {
+ d /= (_Decimal64) 10000000000000000.0;
+ exp += 16;
+ }
+ if (d >= (_Decimal64) 100000000.0)
+ {
+ d /= (_Decimal64) 100000000.0;
+ exp += 8;
+ }
+ if (d >= (_Decimal64) 10000.0)
+ {
+ d /= (_Decimal64) 10000.0;
+ exp += 4;
+ }
+ if (d >= (_Decimal64) 100.0)
+ {
+ d /= (_Decimal64) 100.0;
+ exp += 2;
+ }
+ if (d >= (_Decimal64) 10.0)
+ {
+ d /= (_Decimal64) 10.0;
+ exp += 1;
+ }
+ if (d >= (_Decimal64) 1.0)
+ {
+ d /= (_Decimal64) 10.0;
+ exp += 1;
+ }
+ }
+ else /* d < 1.0 */
+ {
+ _Decimal64 ten16, ten32, ten64, ten128, ten256;
+
+ ten16 = (double) 1e16; /* 10^16 is exactly representable in binary64 */
+ ten16 = (_Decimal64) 1.0 / ten16; /* 10^(-16), exact */
+ ten32 = ten16 * ten16;
+ ten64 = ten32 * ten32;
+ ten128 = ten64 * ten64;
+ ten256 = ten128 * ten128;
+
+ if (d < ten256)
+ {
+ d /= ten256;
+ exp -= 256;
+ }
+ if (d < ten128)
+ {
+ d /= ten128;
+ exp -= 128;
+ }
+ if (d < ten64)
+ {
+ d /= ten64;
+ exp -= 64;
+ }
+ if (d < ten32)
+ {
+ d /= ten32;
+ exp -= 32;
+ }
+ /* the double constant 0.0000000000000001 is 2028240960365167/2^104,
+ which should be rounded to 1e-16 in _Decimal64 */
+ if (d < (_Decimal64) 0.0000000000000001)
+ {
+ d *= (_Decimal64) 10000000000000000.0;
+ exp -= 16;
+ }
+ /* the double constant 0.00000001 is 3022314549036573/2^78,
+ which should be rounded to 1e-8 in _Decimal64 */
+ if (d < (_Decimal64) 0.00000001)
+ {
+ d *= (_Decimal64) 100000000.0;
+ exp -= 8;
+ }
+ /* the double constant 0.0001 is 7378697629483821/2^66,
+ which should be rounded to 1e-4 in _Decimal64 */
+ if (d < (_Decimal64) 0.0001)
+ {
+ d *= (_Decimal64) 10000.0;
+ exp -= 4;
+ }
+ /* the double constant 0.01 is 5764607523034235/2^59,
+ which should be rounded to 1e-2 in _Decimal64 */
+ if (d < (_Decimal64) 0.01)
+ {
+ d *= (_Decimal64) 100.0;
+ exp -= 2;
+ }
+ /* the double constant 0.1 is 3602879701896397/2^55,
+ which should be rounded to 1e-1 in _Decimal64 */
+ if (d < (_Decimal64) 0.1)
+ {
+ d *= (_Decimal64) 10.0;
+ exp -= 1;
+ }
+ }
+
+ /* now 0.1 <= d < 1 */
+ if (sign == 1)
+ *s++ = '-';
+ *s++ = '0';
+ *s++ = '.';
+ for (n = 0; n < 16; n++)
+ {
+ double e;
+ int r;
+
+ d *= (_Decimal64) 10.0;
+ e = (double) d;
+ r = (int) e;
+ *s++ = '0' + r;
+ d -= (_Decimal64) r;
+ }
+ MPFR_ASSERTN(d == (_Decimal64) 0.0);
+ if (exp != 0)
+ sprintf (s, "E%d", exp); /* adds a final '\0' */
+ else
+ *s = '\0';
+}
+#endif /* _MPFR_IEEE_FLOATS */
int
mpfr_set_decimal64 (mpfr_ptr r, _Decimal64 d, mpfr_rnd_t rnd_mode)
{
- char s[23]; /* need 1 character for sign,
- 16 characters for mantissa,
- 1 character for exponent,
+ char s[25]; /* need 1 character for sign,
+ 2 characters for '0.'
+ 16 characters for significand,
+ 1 character for exponent 'E',
4 characters for exponent (including sign),
1 character for terminating \0. */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_dfl_prec.c b/Build/source/libs/mpfr/mpfr-src/src/set_dfl_prec.c
index 68762df7353..f4c876d9033 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_dfl_prec.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_dfl_prec.c
@@ -29,7 +29,7 @@ MPFR_THREAD_VAR (mpfr_prec_t, __gmpfr_default_fp_bit_precision,
void
mpfr_set_default_prec (mpfr_prec_t prec)
{
- MPFR_ASSERTN (prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (MPFR_PREC_COND (prec));
__gmpfr_default_fp_bit_precision = prec;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_exp.c b/Build/source/libs/mpfr/mpfr-src/src/set_exp.c
index e920335dce4..3e315c825b9 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_exp.c
@@ -25,7 +25,9 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
mpfr_set_exp (mpfr_ptr x, mpfr_exp_t exponent)
{
- if (exponent >= __gmpfr_emin && exponent <= __gmpfr_emax)
+ if (MPFR_LIKELY (MPFR_IS_PURE_FP (x) &&
+ exponent >= __gmpfr_emin &&
+ exponent <= __gmpfr_emax))
{
MPFR_EXP(x) = exponent; /* do not use MPFR_SET_EXP of course... */
return 0;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_f.c b/Build/source/libs/mpfr/mpfr-src/src/set_f.c
index 07dc69277fd..82b4e125bfe 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_f.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_f.c
@@ -21,17 +21,20 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#define MPFR_NEED_LONGLONG_H
+#define MPFR_NEED_MPF_INTERNALS
#include "mpfr-impl.h"
+#ifndef MPFR_USE_MINI_GMP
int
mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mpfr_rnd_t rnd_mode)
{
mp_limb_t *my, *mx, *tmp;
- unsigned long cnt, sx, sy;
+ int cnt;
+ mp_size_t sx, sy;
int inexact, carry = 0;
MPFR_TMP_DECL(marker);
- sx = ABS(SIZ(x)); /* number of limbs of the mantissa of x */
+ sx = ABSIZ(x); /* number of limbs of the mantissa of x */
if (sx == 0) /* x is zero */
{
@@ -51,7 +54,7 @@ mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mpfr_rnd_t rnd_mode)
if (sy <= sx) /* we may have to round even when sy = sx */
{
- unsigned long xprec = sx * GMP_NUMB_BITS;
+ mpfr_prec_t xprec = (mpfr_prec_t) sx * GMP_NUMB_BITS;
MPFR_TMP_MARK(marker);
tmp = MPFR_TMP_LIMBS_ALLOC (sx);
@@ -92,8 +95,9 @@ mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mpfr_rnd_t rnd_mode)
else
{
/* Do not use MPFR_SET_EXP as the exponent may be out of range. */
- MPFR_EXP (y) = EXP (x) * GMP_NUMB_BITS - (mpfr_exp_t) cnt + carry;
+ MPFR_EXP (y) = EXP (x) * GMP_NUMB_BITS - cnt + carry;
}
return mpfr_check_range (y, inexact, rnd_mode);
}
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_float128.c b/Build/source/libs/mpfr/mpfr-src/src/set_float128.c
new file mode 100644
index 00000000000..3bc9a143c1b
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_float128.c
@@ -0,0 +1,139 @@
+/* mpfr_set_float128 -- convert a machine __float128 number to
+ a multiple precision floating-point number
+
+Copyright 2012-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h> /* for DBL_MAX */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#ifdef MPFR_WANT_FLOAT128
+
+/* The q suffix is a GNU C extension, but so is __float128. */
+#define MPFR_FLOAT128_MAX 0x1.ffffffffffffffffffffffffffffp+16383q
+
+int
+mpfr_set_float128 (mpfr_ptr r, __float128 d, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t;
+ mp_limb_t *tp;
+ int inexact, shift_exp, neg, e, i;
+ __float128 p[14], q[14];
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Check for NaN */
+ if (MPFR_UNLIKELY (DOUBLE_ISNAN (d)))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ /* Check for INF */
+ if (MPFR_UNLIKELY (d > MPFR_FLOAT128_MAX))
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_POS (r);
+ return 0;
+ }
+ else if (MPFR_UNLIKELY (d < -MPFR_FLOAT128_MAX))
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_NEG (r);
+ return 0;
+ }
+ /* Check for ZERO */
+ else if (MPFR_UNLIKELY (d == (__float128) 0.0))
+ return mpfr_set_d (r, (double) d, rnd_mode);
+
+ shift_exp = 0; /* invariant: remainder to deal with is d*2^shift_exp */
+ neg = d < 0;
+ if (d < 0)
+ d = -d;
+
+ /* Scaling, avoiding (slow) divisions. Should the tables be cached? */
+ if (d >= 1.0)
+ {
+ p[0] = 2.0;
+ q[0] = 0.5;
+ e = 1;
+ /* p[i] = 2^(2^i), q[i] = 1/p[i] */
+ for (i = 0; i < 13 && d >= p[i]; i++)
+ {
+ p[i+1] = p[i] * p[i];
+ q[i+1] = q[i] * q[i];
+ e <<= 1;
+ }
+ for (; i >= 0; e >>= 1, i--)
+ if (d >= p[i])
+ {
+ d *= q[i];
+ shift_exp += e;
+ }
+ d *= 0.5;
+ shift_exp++;
+ }
+ else if (d < 0.5)
+ {
+ p[0] = 2.0;
+ q[0] = 0.5;
+ e = 1;
+ /* p[i] = 2^(2^i), q[i] = 1/p[i] */
+ for (i = 0; i < 13 && d < q[i]; i++)
+ {
+ p[i+1] = p[i] * p[i];
+ q[i+1] = q[i] * q[i];
+ e <<= 1;
+ }
+ /* The while() may be needed for i = 13 due to subnormals.
+ This can probably be improved without yielding an underflow. */
+ for (; i >= 0; e >>= 1, i--)
+ while (d < q[i])
+ {
+ d *= p[i];
+ shift_exp -= e;
+ }
+ }
+
+ MPFR_ASSERTD (d >= 0.5 && d < 1.0);
+
+ mpfr_init2 (t, IEEE_FLOAT128_MANT_DIG);
+ tp = MPFR_MANT (t);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (t, shift_exp);
+ MPFR_SET_SIGN (t, neg ? MPFR_SIGN_NEG : MPFR_SIGN_POS);
+
+ for (i = MPFR_LAST_LIMB (t); i >= 0; i--)
+ {
+ d *= 2 * (__float128) MPFR_LIMB_HIGHBIT;
+ tp[i] = (mp_limb_t) d;
+ d -= tp[i];
+ }
+
+ inexact = mpfr_set (r, t, rnd_mode);
+ mpfr_clear (t);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
+
+#endif /* MPFR_WANT_FLOAT128 */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_ld.c b/Build/source/libs/mpfr/mpfr-src/src/set_ld.c
index 8d63de981d3..0521af56e2b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_ld.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_ld.c
@@ -21,7 +21,7 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <float.h>
+#include <float.h> /* needed so that MPFR_LDBL_MANT_DIG is correctly defined */
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
@@ -45,7 +45,176 @@ static const union {
#define MPFR_LDBL_MAX LDBL_MAX
#endif
-#ifndef HAVE_LDOUBLE_IEEE_EXT_LITTLE
+/* To check for +inf, one can use the test x > MPFR_LDBL_MAX, as LDBL_MAX
+ is the maximum finite number representable in a long double, according
+ to DR 467; see
+ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2092.htm
+ If this fails on some platform, a test x - x != 0 might be used. */
+
+#if defined(HAVE_LDOUBLE_IS_DOUBLE)
+
+/* the "long double" format is the same as "double" */
+int
+mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set_d (r, (double) d, rnd_mode);
+}
+
+#elif defined(HAVE_LDOUBLE_IEEE_EXT_LITTLE)
+
+/* IEEE Extended Little Endian Code */
+int
+mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
+{
+ int inexact, i, k, cnt;
+ mpfr_t tmp;
+ mp_limb_t tmpmant[MPFR_LIMBS_PER_LONG_DOUBLE];
+ mpfr_long_double_t x;
+ mpfr_exp_t exp;
+ int signd;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Check for NAN */
+ if (MPFR_UNLIKELY (DOUBLE_ISNAN (d)))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ /* Check for INF */
+ else if (MPFR_UNLIKELY (d > MPFR_LDBL_MAX))
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_POS (r);
+ return 0;
+ }
+ else if (MPFR_UNLIKELY (d < -MPFR_LDBL_MAX))
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_NEG (r);
+ return 0;
+ }
+ /* Check for ZERO */
+ else if (MPFR_UNLIKELY (d == 0.0))
+ {
+ x.ld = d;
+ MPFR_SET_ZERO (r);
+ if (x.s.sign == 1)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+ return 0;
+ }
+
+ /* now d is neither 0, nor NaN nor Inf */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ MPFR_MANT (tmp) = tmpmant;
+ MPFR_PREC (tmp) = 64;
+
+ /* Extract sign */
+ x.ld = d;
+ signd = MPFR_SIGN_POS;
+ if (x.ld < 0.0)
+ {
+ signd = MPFR_SIGN_NEG;
+ x.ld = -x.ld;
+ }
+
+ /* Extract mantissa */
+#if GMP_NUMB_BITS >= 64
+ tmpmant[0] = ((mp_limb_t) x.s.manh << 32) | ((mp_limb_t) x.s.manl);
+#else
+ tmpmant[0] = (mp_limb_t) x.s.manl;
+ tmpmant[1] = (mp_limb_t) x.s.manh;
+#endif
+
+ /* Normalize mantissa */
+ i = MPFR_LIMBS_PER_LONG_DOUBLE;
+ MPN_NORMALIZE_NOT_ZERO (tmpmant, i);
+ k = MPFR_LIMBS_PER_LONG_DOUBLE - i;
+ count_leading_zeros (cnt, tmpmant[i - 1]);
+ if (MPFR_UNLIKELY (cnt != 0))
+ mpn_lshift (tmpmant + k, tmpmant, i, cnt);
+ else if (MPFR_UNLIKELY (k != 0))
+ MPN_COPY (tmpmant + k, tmpmant, i);
+ if (MPFR_UNLIKELY (k != 0))
+ MPN_ZERO (tmpmant, k);
+
+ /* Set exponent */
+ exp = (mpfr_exp_t) ((x.s.exph << 8) + x.s.expl); /* 15-bit unsigned int */
+ if (MPFR_UNLIKELY (exp == 0))
+ exp -= 0x3FFD;
+ else
+ exp -= 0x3FFE;
+
+ MPFR_SET_EXP (tmp, exp - cnt - k * GMP_NUMB_BITS);
+
+ /* tmp is exact */
+ inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
+
+#elif defined(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE)
+
+/* double-double code */
+int
+mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t, u;
+ int inexact, shift_exp;
+ double h, l;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Check for NAN */
+ LONGDOUBLE_NAN_ACTION (d, goto nan);
+
+ /* Check for INF */
+ if (d > MPFR_LDBL_MAX)
+ {
+ mpfr_set_inf (r, 1);
+ return 0;
+ }
+ else if (d < -MPFR_LDBL_MAX)
+ {
+ mpfr_set_inf (r, -1);
+ return 0;
+ }
+ /* Check for ZERO */
+ else if (d == 0.0)
+ return mpfr_set_d (r, (double) d, rnd_mode);
+
+ if (d >= (long double) MPFR_LDBL_MAX || d <= (long double) -MPFR_LDBL_MAX)
+ h = (d >= (long double) MPFR_LDBL_MAX) ? MPFR_LDBL_MAX : -MPFR_LDBL_MAX;
+ else
+ h = (double) d; /* should not overflow */
+ l = (double) (d - (long double) h);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (t, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (u, IEEE_DBL_MANT_DIG);
+
+ inexact = mpfr_set_d (t, h, MPFR_RNDN);
+ MPFR_ASSERTN(inexact == 0);
+ inexact = mpfr_set_d (u, l, MPFR_RNDN);
+ MPFR_ASSERTN(inexact == 0);
+ inexact = mpfr_add (r, t, u, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (u);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ inexact = mpfr_check_range (r, inexact, rnd_mode);
+ return inexact;
+
+ nan:
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+}
+
+#else
/* Generic code */
int
@@ -191,7 +360,8 @@ mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
break;
/* Inexact. This cannot happen unless the C implementation
"lies" on the precision or when long doubles are
- implemented with FP expansions like under Mac OS X. */
+ implemented with FP expansions like double-double on
+ PowerPC. */
if (MPFR_PREC (t) != MPFR_PREC (r) + 1)
{
/* We assume that MPFR_PREC (r) < MPFR_PREC_MAX.
@@ -233,99 +403,4 @@ mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
MPFR_RET_NAN;
}
-#else /* IEEE Extended Little Endian Code */
-
-int
-mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
-{
- int inexact, i, k, cnt;
- mpfr_t tmp;
- mp_limb_t tmpmant[MPFR_LIMBS_PER_LONG_DOUBLE];
- mpfr_long_double_t x;
- mpfr_exp_t exp;
- int signd;
- MPFR_SAVE_EXPO_DECL (expo);
-
- /* Check for NAN */
- if (MPFR_UNLIKELY (d != d))
- {
- MPFR_SET_NAN (r);
- MPFR_RET_NAN;
- }
- /* Check for INF */
- else if (MPFR_UNLIKELY (d > MPFR_LDBL_MAX))
- {
- MPFR_SET_INF (r);
- MPFR_SET_POS (r);
- return 0;
- }
- else if (MPFR_UNLIKELY (d < -MPFR_LDBL_MAX))
- {
- MPFR_SET_INF (r);
- MPFR_SET_NEG (r);
- return 0;
- }
- /* Check for ZERO */
- else if (MPFR_UNLIKELY (d == 0.0))
- {
- x.ld = d;
- MPFR_SET_ZERO (r);
- if (x.s.sign == 1)
- MPFR_SET_NEG(r);
- else
- MPFR_SET_POS(r);
- return 0;
- }
-
- /* now d is neither 0, nor NaN nor Inf */
- MPFR_SAVE_EXPO_MARK (expo);
-
- MPFR_MANT (tmp) = tmpmant;
- MPFR_PREC (tmp) = 64;
-
- /* Extract sign */
- x.ld = d;
- signd = MPFR_SIGN_POS;
- if (x.ld < 0.0)
- {
- signd = MPFR_SIGN_NEG;
- x.ld = -x.ld;
- }
-
- /* Extract mantissa */
-#if GMP_NUMB_BITS >= 64
- tmpmant[0] = ((mp_limb_t) x.s.manh << 32) | ((mp_limb_t) x.s.manl);
-#else
- tmpmant[0] = (mp_limb_t) x.s.manl;
- tmpmant[1] = (mp_limb_t) x.s.manh;
-#endif
-
- /* Normalize mantissa */
- i = MPFR_LIMBS_PER_LONG_DOUBLE;
- MPN_NORMALIZE_NOT_ZERO (tmpmant, i);
- k = MPFR_LIMBS_PER_LONG_DOUBLE - i;
- count_leading_zeros (cnt, tmpmant[i - 1]);
- if (MPFR_LIKELY (cnt != 0))
- mpn_lshift (tmpmant + k, tmpmant, i, cnt);
- else if (k != 0)
- MPN_COPY (tmpmant + k, tmpmant, i);
- if (MPFR_UNLIKELY (k != 0))
- MPN_ZERO (tmpmant, k);
-
- /* Set exponent */
- exp = (mpfr_exp_t) ((x.s.exph << 8) + x.s.expl); /* 15-bit unsigned int */
- if (MPFR_UNLIKELY (exp == 0))
- exp -= 0x3FFD;
- else
- exp -= 0x3FFE;
-
- MPFR_SET_EXP (tmp, exp - cnt - k * GMP_NUMB_BITS);
-
- /* tmp is exact */
- inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
-
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_check_range (r, inexact, rnd_mode);
-}
-
#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_prc_raw.c b/Build/source/libs/mpfr/mpfr-src/src/set_prc_raw.c
index 532fa2d8a65..b4230cae6b8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_prc_raw.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_prc_raw.c
@@ -25,7 +25,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
void
mpfr_set_prec_raw (mpfr_ptr x, mpfr_prec_t p)
{
- MPFR_ASSERTN (p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (MPFR_PREC_COND (p));
MPFR_ASSERTN (p <= (mpfr_prec_t) MPFR_GET_ALLOC_SIZE(x) * GMP_NUMB_BITS);
MPFR_PREC(x) = p;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_prec.c b/Build/source/libs/mpfr/mpfr-src/src/set_prec.c
index 2927efefc89..fc6ec85a5d1 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_prec.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_prec.c
@@ -22,14 +22,13 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-void
+MPFR_HOT_FUNCTION_ATTR void
mpfr_set_prec (mpfr_ptr x, mpfr_prec_t p)
{
mp_size_t xsize, xoldsize;
- mpfr_limb_ptr tmp;
/* first, check if p is correct */
- MPFR_ASSERTN (p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (MPFR_PREC_COND (p));
/* Calculate the new number of limbs */
xsize = MPFR_PREC2LIMBS (p);
@@ -38,8 +37,12 @@ mpfr_set_prec (mpfr_ptr x, mpfr_prec_t p)
xoldsize = MPFR_GET_ALLOC_SIZE (x);
if (xsize > xoldsize)
{
- tmp = (mpfr_limb_ptr) (*__gmp_reallocate_func)
- (MPFR_GET_REAL_PTR(x), MPFR_MALLOC_SIZE(xoldsize), MPFR_MALLOC_SIZE(xsize));
+ mpfr_size_limb_t *tmp;
+
+ tmp = (mpfr_size_limb_t *) mpfr_reallocate_func
+ (MPFR_GET_REAL_PTR(x),
+ MPFR_MALLOC_SIZE(xoldsize),
+ MPFR_MALLOC_SIZE(xsize));
MPFR_SET_MANT_PTR(x, tmp);
MPFR_SET_ALLOC_SIZE(x, xsize);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_q.c b/Build/source/libs/mpfr/mpfr-src/src/set_q.c
index ffcc1de4c4e..b72ee4f7ac3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_q.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_q.c
@@ -23,6 +23,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
+#ifndef MPFR_USE_MINI_GMP
/*
* Set f to z, choosing the smallest precision for f
* so that z = f*(2^BPML)*zs*2^(RetVal)
@@ -38,7 +39,7 @@ set_z (mpfr_ptr f, mpz_srcptr z, mp_size_t *zs)
MPFR_ASSERTD (mpz_sgn (z) != 0);
/* Remove useless ending 0 */
- for (p = PTR (z), s = *zs = ABS (SIZ (z)) ; *p == 0; p++, s--)
+ for (p = PTR (z), s = *zs = ABSIZ (z) ; *p == 0; p++, s--)
MPFR_ASSERTD (s >= 0);
/* Get working precision */
@@ -131,5 +132,4 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mpfr_rnd_t rnd)
mpfr_clear (n);
MPFR_RET (inexact);
}
-
-
+#endif
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_si_2exp.c b/Build/source/libs/mpfr/mpfr-src/src/set_si_2exp.c
index 3eb41a5a6b6..5b59d131110 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_si_2exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_si_2exp.c
@@ -36,7 +36,7 @@ mpfr_set_si_2exp (mpfr_ptr x, long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
else
{
mp_size_t xn;
- unsigned int cnt, nbits;
+ int cnt, nbits;
mp_limb_t ai, *xp;
int inex = 0;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_sj.c b/Build/source/libs/mpfr/mpfr-src/src/set_sj.c
index 1e997222b6f..656012b728e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_sj.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_sj.c
@@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-# include "config.h" /* for a build within gmp */
+# include "config.h"
#endif
#include "mpfr-intmax.h"
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c b/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
index b1cefbd41e5..88281f56878 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
@@ -24,12 +24,12 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
{
MPFR_SET_POS (x);
- if (i == 0)
+ if (MPFR_UNLIKELY (i == 0))
{
MPFR_SET_ZERO (x);
MPFR_RET (0);
@@ -37,7 +37,7 @@ mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode
else
{
mp_size_t xn;
- unsigned int cnt, nbits;
+ int cnt, nbits;
mp_limb_t *xp;
int inex = 0;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_uj.c b/Build/source/libs/mpfr/mpfr-src/src/set_uj.c
index 6049e638741..fafc101c281 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_uj.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_uj.c
@@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-# include "config.h" /* for a build within gmp */
+# include "config.h"
#endif
#define MPFR_NEED_LONGLONG_H
@@ -30,6 +30,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#ifdef _MPFR_H_HAVE_INTMAX_T
+#define uintmaxpml (sizeof(uintmax_t) / sizeof(mp_limb_t))
+
int
mpfr_set_uj (mpfr_t x, uintmax_t j, mpfr_rnd_t rnd)
{
@@ -39,10 +41,10 @@ mpfr_set_uj (mpfr_t x, uintmax_t j, mpfr_rnd_t rnd)
int
mpfr_set_uj_2exp (mpfr_t x, uintmax_t j, intmax_t e, mpfr_rnd_t rnd)
{
- unsigned int cnt, i;
- mp_size_t k, len;
+ int cnt;
+ mp_size_t i, k;
mp_limb_t limb;
- mp_limb_t yp[sizeof(uintmax_t) / sizeof(mp_limb_t)];
+ mp_limb_t yp[uintmaxpml];
mpfr_t y;
unsigned long uintmax_bit_size = sizeof(uintmax_t) * CHAR_BIT;
unsigned long bpml = GMP_NUMB_BITS % uintmax_bit_size;
@@ -57,13 +59,20 @@ mpfr_set_uj_2exp (mpfr_t x, uintmax_t j, intmax_t e, mpfr_rnd_t rnd)
MPFR_ASSERTN (sizeof(uintmax_t) % sizeof(mp_limb_t) == 0);
- /* Create an auxillary var */
+ /* Create an auxiliary var */
MPFR_TMP_INIT1 (yp, y, uintmax_bit_size);
- k = numberof (yp);
- if (k == 1)
- limb = yp[0] = j;
+ /* The compiler will optimize the code by removing the useless branch. */
+ k = uintmaxpml;
+ if (uintmaxpml == 1)
+ {
+ limb = j;
+ count_leading_zeros(cnt, limb);
+ /* Normalize the most significant limb */
+ yp[0] = limb << cnt;
+ }
else
{
+ mp_size_t len;
/* Note: either GMP_NUMB_BITS = uintmax_bit_size, then k = 1 the
shift j >>= bpml is never done, or GMP_NUMB_BITS < uintmax_bit_size
and bpml = GMP_NUMB_BITS. */
@@ -78,23 +87,22 @@ mpfr_set_uj_2exp (mpfr_t x, uintmax_t j, intmax_t e, mpfr_rnd_t rnd)
}
while (limb == 0);
k++;
- }
- count_leading_zeros(cnt, limb);
- len = numberof (yp) - k;
-
- /* Normalize it: len = number of last 0 limb, k number of non-zero limbs */
- if (MPFR_LIKELY(cnt))
- mpn_lshift (yp+len, yp, k, cnt); /* Normalize the High Limb*/
- else if (len != 0)
- MPN_COPY_DECR (yp+len, yp, k); /* Must use DECR */
- if (len != 0)
- /* Note: when numberof(yp)==1, len is constant and null, so the compiler
- can optimize out this code. */
- {
- if (len == 1)
- yp[0] = (mp_limb_t) 0;
- else
- MPN_ZERO (yp, len); /* Zeroing the last limbs */
+ len = numberof (yp) - k;
+ count_leading_zeros(cnt, limb);
+
+ /* Normalize it: len = number of last zero limbs,
+ k = number of previous limbs */
+ if (MPFR_LIKELY (cnt != 0))
+ mpn_lshift (yp+len, yp, k, cnt); /* Normalize the high limb */
+ else if (len != 0)
+ mpn_copyd (yp+len, yp, k); /* Must use copyd */
+ if (len != 0)
+ {
+ if (len == 1)
+ yp[0] = MPFR_LIMB_ZERO;
+ else
+ MPN_ZERO (yp, len); /* Zero the last limbs */
+ }
}
e += k * GMP_NUMB_BITS - cnt; /* Update Expo */
MPFR_ASSERTD (MPFR_LIMB_MSB(yp[numberof (yp) - 1]) != 0);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_z_exp.c b/Build/source/libs/mpfr/mpfr-src/src/set_z_exp.c
index e540dabcba3..444c967e1a3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_z_exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_z_exp.c
@@ -42,7 +42,7 @@ mpfr_set_z_2exp (mpfr_ptr f, mpz_srcptr z, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
}
MPFR_ASSERTD (sign_z == MPFR_SIGN_POS || sign_z == MPFR_SIGN_NEG);
- zn = ABS(SIZ(z)); /* limb size of z */
+ zn = ABSIZ(z); /* limb size of z */
/* compute en = floor(e/GMP_NUMB_BITS) */
en = (e >= 0) ? e / GMP_NUMB_BITS : (e + 1) / GMP_NUMB_BITS - 1;
MPFR_ASSERTD (zn >= 1);
@@ -81,7 +81,7 @@ mpfr_set_z_2exp (mpfr_ptr f, mpz_srcptr z, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
if (MPFR_LIKELY (k != 0))
{
mpn_lshift (fp, &zp[dif], fn, k);
- if (MPFR_LIKELY (dif > 0))
+ if (MPFR_UNLIKELY (dif > 0))
fp[0] |= zp[dif - 1] >> (GMP_NUMB_BITS - k);
}
else
@@ -101,7 +101,7 @@ mpfr_set_z_2exp (mpfr_ptr f, mpz_srcptr z, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
else /* sh == 0 */
{
mp_limb_t mask = MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1 - k);
- if (MPFR_LIKELY (dif > 0))
+ if (MPFR_UNLIKELY (dif > 0))
{
rb = zp[--dif] & mask;
sb = zp[dif] & (mask-1);
@@ -111,7 +111,7 @@ mpfr_set_z_2exp (mpfr_ptr f, mpz_srcptr z, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
k = 0;
ulp = MPFR_LIMB_ONE;
}
- if (MPFR_UNLIKELY (sb == 0) && MPFR_LIKELY (dif > 0))
+ if (MPFR_UNLIKELY (sb == 0 && dif > 0))
{
sb = zp[--dif];
if (MPFR_LIKELY (k != 0))
@@ -140,7 +140,7 @@ mpfr_set_z_2exp (mpfr_ptr f, mpz_srcptr z, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
}
trunc:
- inex = MPFR_LIKELY ((sb | rb) != 0) ? -1 : 0;
+ inex = - ((sb | rb) != 0);
goto end;
addoneulp:
diff --git a/Build/source/libs/mpfr/mpfr-src/src/setmax.c b/Build/source/libs/mpfr/mpfr-src/src/setmax.c
index 88081c33cfc..fa0e41ec05a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/setmax.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/setmax.c
@@ -35,7 +35,7 @@ mpfr_setmax (mpfr_ptr x, mpfr_exp_t e)
xn = MPFR_LIMB_SIZE (x);
sh = (mpfr_prec_t) xn * GMP_NUMB_BITS - MPFR_PREC(x);
xp = MPFR_MANT(x);
- xp[0] = MP_LIMB_T_MAX << sh;
+ xp[0] = MPFR_LIMB_MAX << sh;
for (i = 1; i < xn; i++)
- xp[i] = MP_LIMB_T_MAX;
+ xp[i] = MPFR_LIMB_MAX;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sgn.c b/Build/source/libs/mpfr/mpfr-src/src/sgn.c
index 18b47279721..553bd5ac180 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sgn.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sgn.c
@@ -31,7 +31,7 @@ int
return 0;
if (MPFR_UNLIKELY (MPFR_IS_NAN (a)))
{
- MPFR_SET_ERANGE ();
+ MPFR_SET_ERANGEFLAG ();
return 0;
}
/* Remains infinity, handled by the return below. */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/si_op.c b/Build/source/libs/mpfr/mpfr-src/src/si_op.c
index 5b7a72f38fd..a65799fefa0 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/si_op.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/si_op.c
@@ -1,6 +1,9 @@
/* mpfr_add_si -- add a floating-point number with a machine integer
- mpfr_sub_si -- sub a floating-point number with a machine integer
- mpfr_si_sub -- sub a machine number with a floating-point number
+ mpfr_sub_si -- sub a floating-point number with a machine integer
+ mpfr_si_sub -- sub a machine number with a floating-point number
+ mpfr_mul_si -- multiply a floating-point number by a machine integer
+ mpfr_div_si -- divide a floating-point number by a machine integer
+ mpfr_si_div -- divide a machine number by a floating-point number
Copyright 2004-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -27,31 +30,131 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
mpfr_add_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
if (u >= 0)
- return mpfr_add_ui (y, x, u, rnd_mode);
+ res = mpfr_add_ui (y, x, u, rnd_mode);
else
- return mpfr_sub_ui (y, x, - (unsigned long) u, rnd_mode);
+ res = mpfr_sub_ui (y, x, - (unsigned long) u, rnd_mode);
+
+ return res;
}
int
mpfr_sub_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
if (u >= 0)
- return mpfr_sub_ui (y, x, u, rnd_mode);
+ res = mpfr_sub_ui (y, x, u, rnd_mode);
else
- return mpfr_add_ui (y, x, - (unsigned long) u, rnd_mode);
+ res = mpfr_add_ui (y, x, - (unsigned long) u, rnd_mode);
+
+ return res;
}
int
mpfr_si_sub (mpfr_ptr y, long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
if (u >= 0)
- return mpfr_ui_sub (y, u, x, rnd_mode);
+ res = mpfr_ui_sub (y, u, x, rnd_mode);
else
{
- int res = - mpfr_add_ui (y, x, - (unsigned long) u,
- MPFR_INVERT_RND (rnd_mode));
+ res = - mpfr_add_ui (y, x, - (unsigned long) u,
+ MPFR_INVERT_RND (rnd_mode));
MPFR_CHANGE_SIGN (y);
- return res;
}
+
+ return res;
+}
+
+#undef mpfr_mul_si
+int
+mpfr_mul_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
+{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
+ if (u >= 0)
+ res = mpfr_mul_ui (y, x, u, rnd_mode);
+ else
+ {
+ res = - mpfr_mul_ui (y, x, - (unsigned long) u,
+ MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+
+ return res;
+}
+
+#undef mpfr_div_si
+int
+mpfr_div_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
+{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
+ if (u >= 0)
+ res = mpfr_div_ui (y, x, u, rnd_mode);
+ else
+ {
+ res = - mpfr_div_ui (y, x, - (unsigned long) u,
+ MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+
+ return res;
+}
+
+int
+mpfr_si_div (mpfr_ptr y, long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
+ if (u >= 0)
+ res = mpfr_ui_div (y, u, x, rnd_mode);
+ else
+ {
+ res = - mpfr_ui_div (y, - (unsigned long) u, x,
+ MPFR_INVERT_RND(rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+
+ return res;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/signbit.c b/Build/source/libs/mpfr/mpfr-src/src/signbit.c
index bbc0dc85adc..d0e8a88df14 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/signbit.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/signbit.c
@@ -26,5 +26,5 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
mpfr_signbit (mpfr_srcptr x)
{
- return MPFR_SIGN (x) < 0;
+ return MPFR_IS_NEG (x);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sin.c b/Build/source/libs/mpfr/mpfr-src/src/sin.c
index 860aa649c09..ea920c47788 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sin.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sin.c
@@ -38,7 +38,7 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
mpfr_t c, xr;
mpfr_srcptr xx;
- mpfr_exp_t expx, err;
+ mpfr_exp_t expx, err1, err;
mpfr_prec_t precy, m;
int inexact, sign, reduce;
MPFR_ZIV_DECL (loop);
@@ -55,7 +55,6 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
MPFR_SET_NAN (y);
MPFR_RET_NAN;
-
}
else /* x is zero */
{
@@ -66,9 +65,11 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
}
+ expx = MPFR_GET_EXP (x);
+ err1 = -2 * expx;
+
/* sin(x) = x - x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
- MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * MPFR_GET_EXP (x), 2, 0,
- rnd_mode, {});
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, err1, 2, 0, rnd_mode, {});
MPFR_SAVE_EXPO_MARK (expo);
@@ -81,8 +82,20 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
goto end;
}
- m = precy + MPFR_INT_CEIL_LOG2 (precy) + 13;
- expx = MPFR_GET_EXP (x);
+ m = precy + MPFR_INT_CEIL_LOG2 (precy) + 7;
+
+ /* since we compute sin(x) as sqrt(1-cos(x)^2), and for x small we have
+ cos(x)^2 ~ 1 - x^2, when subtracting cos(x)^2 from 1 we will lose
+ about -2*expx bits if expx < 0 */
+ if (expx < 0)
+ {
+ /* The following assertion includes a check for integer overflow.
+ At this point, precy < MPFR_SINCOS_THRESHOLD, so that both m and
+ err1 should be small enough. But the assertion makes the code
+ safer (a smart compiler might be able to remove it). */
+ MPFR_ASSERTN (err1 <= MPFR_PREC_MAX - m);
+ m += err1;
+ }
mpfr_init (c);
mpfr_init (xr);
@@ -113,7 +126,7 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_div_2ui (c, c, 1, MPFR_RNDN);
/* Since c approximates Pi with an error <= 2^(2-expx-m) <= 2^(-m),
it suffices to check that c - |xr| >= 2^(2-m). */
- if (MPFR_SIGN (xr) > 0)
+ if (MPFR_IS_POS (xr))
mpfr_sub (c, c, xr, MPFR_RNDZ);
else
mpfr_add (c, c, xr, MPFR_RNDZ);
@@ -135,9 +148,8 @@ mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
sign = MPFR_SIGN(xx);
/* now that the argument is reduced, precision m is enough */
mpfr_set_prec (c, m);
- mpfr_cos (c, xx, MPFR_RNDZ); /* can't be exact */
- mpfr_nexttoinf (c); /* now c = cos(x) rounded away */
- mpfr_mul (c, c, c, MPFR_RNDU); /* away */
+ mpfr_cos (c, xx, MPFR_RNDA); /* c = cos(x) rounded away */
+ mpfr_mul (c, c, c, MPFR_RNDU); /* away */
mpfr_ui_sub (c, 1, c, MPFR_RNDZ);
mpfr_sqrt (c, c, MPFR_RNDZ);
if (MPFR_IS_NEG_SIGN(sign))
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sin_cos.c b/Build/source/libs/mpfr/mpfr-src/src/sin_cos.c
index a7c44620b46..d2fd71e0d90 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sin_cos.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sin_cos.c
@@ -147,7 +147,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_mul_2ui (c, c, 1, MPFR_RNDN);
mpfr_remainder (xr, x, c, MPFR_RNDN);
mpfr_div_2ui (c, c, 1, MPFR_RNDN);
- if (MPFR_SIGN (xr) > 0)
+ if (MPFR_IS_POS (xr))
mpfr_sub (c, c, xr, MPFR_RNDZ);
else
mpfr_add (c, c, xr, MPFR_RNDZ);
@@ -174,11 +174,10 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
err = m;
else
err = MPFR_GET_EXP (c) + (mpfr_exp_t) (m - 3);
- if (!mpfr_can_round (c, err, MPFR_RNDN, MPFR_RNDZ,
- MPFR_PREC (z) + (rnd_mode == MPFR_RNDN)))
+ if (!MPFR_CAN_ROUND (c, err, MPFR_PREC (z), rnd_mode))
goto next_step;
- /* we can't set z now, because in case z = x, and the mpfr_can_round()
+ /* we can't set z now, because in case z = x, and the MPFR_CAN_ROUND()
call below fails, we will have clobbered the input */
mpfr_set_prec (xr, MPFR_PREC(c));
mpfr_swap (xr, c); /* save the approximation of the cosine in xr */
@@ -197,8 +196,7 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
/* the absolute error on c is at most 2^(err-m), which we must put
in the form 2^(EXP(c)-err). */
err = MPFR_GET_EXP (c) + (mpfr_exp_t) m - err;
- if (mpfr_can_round (c, err, MPFR_RNDN, MPFR_RNDZ,
- MPFR_PREC (y) + (rnd_mode == MPFR_RNDN)))
+ if (MPFR_CAN_ROUND (c, err, MPFR_PREC (y), rnd_mode))
break;
/* check for huge cancellation */
if (err < (mpfr_exp_t) MPFR_PREC (y))
@@ -236,8 +234,9 @@ mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
static mpfr_prec_t
reduce (mpz_t Q, mpz_srcptr R, mpfr_prec_t prec)
{
- mpfr_prec_t l = mpz_sizeinbase (R, 2);
+ mpfr_prec_t l;
+ MPFR_MPZ_SIZEINBASE2(l, R);
l = (l > prec) ? l - prec : 0;
mpz_fdiv_q_2exp (Q, R, l);
return l;
@@ -249,10 +248,13 @@ reduce (mpz_t Q, mpz_srcptr R, mpfr_prec_t prec)
static unsigned long
reduce2 (mpz_t S, mpz_t C, mpfr_prec_t prec)
{
- unsigned long ls = mpz_sizeinbase (S, 2);
- unsigned long lc = mpz_sizeinbase (C, 2);
+ unsigned long ls;
+ unsigned long lc;
unsigned long l;
+ MPFR_MPZ_SIZEINBASE2(ls, S);
+ MPFR_MPZ_SIZEINBASE2(lc, C);
+
l = (ls < lc) ? ls : lc; /* smaller length */
l = (l > prec) ? l - prec : 0;
mpz_fdiv_q_2exp (S, S, l);
@@ -287,9 +289,9 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
mpz_t T[GMP_NUMB_BITS], Q[GMP_NUMB_BITS], ptoj[GMP_NUMB_BITS], pp;
mpfr_prec_t log2_nb_terms[GMP_NUMB_BITS], mult[GMP_NUMB_BITS];
mpfr_prec_t accu[GMP_NUMB_BITS], size_ptoj[GMP_NUMB_BITS];
- mpfr_prec_t prec_i_have, r0 = r;
- unsigned long alloc, i, j, k;
- mpfr_prec_t l;
+ mpfr_prec_t prec_i_have, h, r0 = r, pp_s, p_s;
+ unsigned long i, j, m;
+ int alloc, k, l;
if (MPFR_UNLIKELY(mpz_cmp_ui (p, 0) == 0)) /* sin(x)/x -> 1 */
{
@@ -305,10 +307,10 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
mpz_init (pp);
/* normalize p (non-zero here) */
- l = mpz_scan1 (p, 0);
- mpz_fdiv_q_2exp (pp, p, l); /* p = pp * 2^l */
+ h = mpz_scan1 (p, 0);
+ mpz_fdiv_q_2exp (pp, p, h); /* p = pp * 2^h */
mpz_mul (pp, pp, pp);
- r = 2 * (r - l); /* x^2 = (p/2^r0)^2 = pp / 2^r */
+ r = 2 * (r - h); /* x^2 = (p/2^r0)^2 = pp / 2^r */
/* now p is odd */
alloc = 2;
@@ -319,14 +321,16 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
mpz_init (Q[1]);
mpz_init (ptoj[1]);
mpz_mul (ptoj[1], pp, pp); /* ptoj[1] = pp^2 */
- size_ptoj[1] = mpz_sizeinbase (ptoj[1], 2);
+ MPFR_MPZ_SIZEINBASE2(size_ptoj[1], ptoj[1]);
mpz_mul_2exp (T[0], T[0], r);
mpz_sub (T[0], T[0], pp); /* 6*2^r - pp = 6*2^r*(1 - x^2/6) */
log2_nb_terms[0] = 1;
/* already take into account the factor x=p/2^r in sin(x) = x * (...) */
- mult[0] = r - mpz_sizeinbase (pp, 2) + r0 - mpz_sizeinbase (p, 2);
+ MPFR_MPZ_SIZEINBASE2(pp_s, pp);
+ MPFR_MPZ_SIZEINBASE2(p_s, p);
+ mult[0] = r - pp_s + r0 - p_s;
/* we have x^3 < 1/2^mult[0] */
for (i = 2, k = 0, prec_i_have = mult[0]; prec_i_have < prec; i += 2)
@@ -343,7 +347,7 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
mpz_init (Q[k+1]);
mpz_init (ptoj[k+1]);
mpz_mul (ptoj[k+1], ptoj[k], ptoj[k]); /* pp^(2^(k+1)) */
- size_ptoj[k+1] = mpz_sizeinbase (ptoj[k+1], 2);
+ MPFR_MPZ_SIZEINBASE2(size_ptoj[k+1], ptoj[k+1]);
}
/* for i even, we have Q[k] = (2*i)*(2*i+1), T[k] = 1,
then Q[k+1] = (2*i+2)*(2*i+3), T[k+1] = 1,
@@ -358,7 +362,8 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
mpz_mul_ui (Q[k], Q[k], 2 * i + 1);
/* the next term of the series is divided by Q[k] and multiplied
by pp^2/2^(2r), thus the mult. factor < 1/2^mult[k] */
- mult[k] = mpz_sizeinbase (Q[k], 2) + 2 * r - size_ptoj[1] - 1;
+ MPFR_MPZ_SIZEINBASE2(mult[k], Q[k]);
+ mult[k] += 2 * r - size_ptoj[1] - 1;
/* the absolute contribution of the next term is 1/2^accu[k] */
accu[k] = (k == 0) ? mult[k] : mult[k] + accu[k-1];
prec_i_have = accu[k]; /* the current term is < 1/2^accu[k] */
@@ -373,7 +378,7 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
mpz_mul (Q[k-1], Q[k-1], Q[k]);
log2_nb_terms[k-1] ++; /* number of terms in S[k-1]
is a power of 2 by construction */
- prec_i_have = mpz_sizeinbase (Q[k], 2);
+ MPFR_MPZ_SIZEINBASE2(prec_i_have, Q[k]);
mult[k-1] += prec_i_have + (r << l) - size_ptoj[l] - 1;
accu[k-1] = (k == 1) ? mult[k-1] : mult[k-1] + accu[k-2];
prec_i_have = accu[k-1];
@@ -385,46 +390,45 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
/* accumulate all products in T[0] and Q[0]. Warning: contrary to above,
here we do not have log2_nb_terms[k-1] = log2_nb_terms[k]+1. */
- l = 0; /* number of accumulated terms in the right part T[k]/Q[k] */
+ h = 0; /* number of accumulated terms in the right part T[k]/Q[k] */
while (k > 0)
{
- j = log2_nb_terms[k-1];
- mpz_mul (T[k], T[k], ptoj[j]);
+ mpz_mul (T[k], T[k], ptoj[log2_nb_terms[k-1]]);
mpz_mul (T[k-1], T[k-1], Q[k]);
- l += 1 << log2_nb_terms[k];
- mpz_mul_2exp (T[k-1], T[k-1], r * l);
+ h += (mpfr_prec_t) 1 << log2_nb_terms[k];
+ mpz_mul_2exp (T[k-1], T[k-1], r * h);
mpz_add (T[k-1], T[k-1], T[k]);
mpz_mul (Q[k-1], Q[k-1], Q[k]);
k--;
}
- l = r0 + r * (i - 1); /* implicit multiplier 2^r for Q0 */
- /* at this point T[0]/(2^l*Q[0]) is an approximation of sin(x) where the 1st
+ m = r0 + r * (i - 1); /* implicit multiplier 2^r for Q0 */
+ /* at this point T[0]/(2^m*Q[0]) is an approximation of sin(x) where the 1st
neglected term has contribution < 1/2^prec, thus since the series has
alternate signs, the error is < 1/2^prec */
/* we truncate Q0 to prec bits: the relative error is at most 2^(1-prec),
which means that Q0 = Q[0] * (1+theta) with |theta| <= 2^(1-prec)
[up to a power of two] */
- l += reduce (Q0, Q[0], prec);
- l -= reduce (T[0], T[0], prec);
- /* multiply by x = p/2^l */
+ m += reduce (Q0, Q[0], prec);
+ m -= reduce (T[0], T[0], prec);
+ /* multiply by x = p/2^m */
mpz_mul (S0, T[0], p);
- l -= reduce (S0, S0, prec); /* S0 = T[0] * (1 + theta)^2 up to power of 2 */
+ m -= reduce (S0, S0, prec); /* S0 = T[0] * (1 + theta)^2 up to power of 2 */
/* sin(X) ~ S0/Q0*(1 + theta)^3 + err with |theta| <= 2^(1-prec) and
|err| <= 2^(-prec), thus since |S0/Q0| <= 1:
|sin(X) - S0/Q0| <= 4*|theta*S0/Q0| + |err| <= 9*2^(-prec) */
mpz_clear (pp);
- for (j = 0; j < alloc; j ++)
+ for (k = 0; k < alloc; k ++)
{
- mpz_clear (T[j]);
- mpz_clear (Q[j]);
- mpz_clear (ptoj[j]);
+ mpz_clear (T[k]);
+ mpz_clear (Q[k]);
+ mpz_clear (ptoj[k]);
}
/* compute cos(X) from sin(X): sqrt(1-(S/Q)^2) = sqrt(Q^2-S^2)/Q
- = sqrt(Q0^2*2^(2l)-S0^2)/Q0.
+ = sqrt(Q0^2*2^(2m)-S0^2)/Q0.
Write S/Q = sin(X) + eps with |eps| <= 9*2^(-prec),
then sqrt(Q^2-S^2) = sqrt(Q^2-Q^2*(sin(X)+eps)^2)
= sqrt(Q^2*cos(X)^2-Q^2*(2*sin(X)*eps+eps^2))
@@ -438,14 +442,14 @@ sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
= Q*cos(X)*(1+eps3+eps2/(Q*cos(X)))
= Q*cos(X)*(1+eps4) with |eps4| <= 9*2^(-prec)
since |Q| >= 2^(prec-1) */
- /* we assume that Q0*2^l >= 2^(prec-1) */
- MPFR_ASSERTN(l + mpz_sizeinbase (Q0, 2) >= prec);
+ /* we assume that Q0*2^m >= 2^(prec-1) */
+ MPFR_ASSERTN(m + mpz_sizeinbase (Q0, 2) >= prec);
mpz_mul (C0, Q0, Q0);
- mpz_mul_2exp (C0, C0, 2 * l);
+ mpz_mul_2exp (C0, C0, 2 * m);
mpz_submul (C0, S0, S0);
mpz_sqrt (C0, C0);
- return l;
+ return m;
}
/* Put in s and c approximations of sin(x) and cos(x) respectively.
@@ -499,7 +503,7 @@ sincos_aux (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
/* y <- trunc(x2 * 2^sh) = trunc(x * 2^(2*sh-1)) */
mpfr_mul_2exp (x2, x2, sh, MPFR_RNDN); /* exact */
- mpfr_get_z (y, x2, MPFR_RNDZ); /* round towards zero: now
+ mpfr_get_z (y, x2, MPFR_RNDZ); /* round toward zero: now
0 <= x2 < 2^sh, thus
0 <= x2/2^(sh-1) < 2^(1-sh) */
if (mpz_cmp_ui (y, 0) == 0)
@@ -573,6 +577,7 @@ mpfr_sincos_fast (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd)
mpfr_t x_red, ts, tc;
mpfr_prec_t w;
mpfr_exp_t err, errs, errc;
+ MPFR_GROUP_DECL (group);
MPFR_ZIV_DECL (loop);
MPFR_ASSERTN(s != c);
@@ -583,8 +588,8 @@ mpfr_sincos_fast (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd)
else
w = MPFR_PREC(s) >= MPFR_PREC(c) ? MPFR_PREC(s) : MPFR_PREC(c);
w += MPFR_INT_CEIL_LOG2(w) + 9; /* ensures w >= 10 (needed by sincos_aux) */
- mpfr_init2 (ts, w);
- mpfr_init2 (tc, w);
+
+ MPFR_GROUP_INIT_2(group, w, ts, tc);
MPFR_ZIV_INIT (loop, w);
for (;;)
@@ -597,11 +602,9 @@ mpfr_sincos_fast (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd)
/* if -Pi/4 <= x < 0, use sin(-x)=-sin(x) */
else if (MPFR_IS_NEG(x) && mpfr_cmp_si_2exp (x, -1686629713, -31) >= 0)
{
- mpfr_init2 (x_red, MPFR_PREC(x));
- mpfr_neg (x_red, x, rnd); /* exact */
+ MPFR_ALIAS(x_red, x, MPFR_SIGN_POS, MPFR_GET_EXP(x));
err = sincos_aux (ts, tc, x_red, MPFR_RNDN);
- mpfr_neg (ts, ts, MPFR_RNDN);
- mpfr_clear (x_red);
+ MPFR_CHANGE_SIGN(ts);
}
else /* argument reduction is needed */
{
@@ -650,15 +653,13 @@ mpfr_sincos_fast (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd)
(c == NULL || MPFR_CAN_ROUND (tc, w - errc, MPFR_PREC(c), rnd)))
break;
MPFR_ZIV_NEXT (loop, w);
- mpfr_set_prec (ts, w);
- mpfr_set_prec (tc, w);
+ MPFR_GROUP_REPREC_2(group, w, ts, tc);
}
MPFR_ZIV_FREE (loop);
inexs = (s == NULL) ? 0 : mpfr_set (s, ts, rnd);
inexc = (c == NULL) ? 0 : mpfr_set (c, tc, rnd);
- mpfr_clear (ts);
- mpfr_clear (tc);
+ MPFR_GROUP_CLEAR (group);
return INEX(inexs,inexc);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sinh.c b/Build/source/libs/mpfr/mpfr-src/src/sinh.c
index 97bbf2f809c..4a2ca645099 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sinh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sinh.c
@@ -84,7 +84,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
if (MPFR_GET_EXP (x) < 0)
Nt -= 2*MPFR_GET_EXP (x);
- /* initialise of intermediary variables */
+ /* initialize of intermediary variables */
MPFR_GROUP_INIT_2 (group, Nt, t, ti);
/* First computation of sinh */
@@ -170,7 +170,7 @@ mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
}
}
- /* actualisation of the precision */
+ /* actualization of the precision */
Nt += err;
MPFR_ZIV_NEXT (loop, Nt);
MPFR_GROUP_REPREC_2 (group, Nt, t, ti);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sinh_cosh.c b/Build/source/libs/mpfr/mpfr-src/src/sinh_cosh.c
index 0f0a20fc367..628eecfd5d8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sinh_cosh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sinh_cosh.c
@@ -95,7 +95,7 @@ mpfr_sinh_cosh (mpfr_ptr sh, mpfr_ptr ch, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
/* the optimal number of bits : see algorithms.ps */
N = N + MPFR_INT_CEIL_LOG2 (N) + 4;
- /* initialise of intermediary variables */
+ /* initialize of intermediary variables */
MPFR_GROUP_INIT_3 (group, N, s, c, ti);
/* First computation of sinh_cosh */
@@ -143,7 +143,7 @@ mpfr_sinh_cosh (mpfr_ptr sh, mpfr_ptr ch, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
break;
}
}
- /* actualisation of the precision */
+ /* actualization of the precision */
N += err;
MPFR_ZIV_NEXT (loop, N);
MPFR_GROUP_REPREC_3 (group, N, s, c, ti);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sqr.c b/Build/source/libs/mpfr/mpfr-src/src/sqr.c
index 92e6ade9005..ac912b19b8e 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sqr.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sqr.c
@@ -1,4 +1,4 @@
-/* mpfr_sqr -- Floating square
+/* mpfr_sqr -- Floating-point square
Copyright 2004-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -20,8 +20,483 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
+#if !defined(MPFR_GENERIC_ABI) && (GMP_NUMB_BITS == 32 || GMP_NUMB_BITS == 64)
+
+/* Special code for prec(a) < GMP_NUMB_BITS and prec(b) <= GMP_NUMB_BITS.
+ Note: this function was copied from mpfr_mul_1 in file mul.c, thus any change
+ here should be done also in mpfr_mul_1. */
+static int
+mpfr_sqr_1 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, mpfr_prec_t p)
+{
+ mp_limb_t a0;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mp_limb_t b0 = MPFR_MANT(b)[0];
+ mpfr_exp_t ax;
+ mpfr_prec_t sh = GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb, mask = MPFR_LIMB_MASK(sh);
+
+ /* When prec(b) <= GMP_NUMB_BITS / 2, we could replace umul_ppmm
+ by a limb multiplication as follows, but we assume umul_ppmm is as fast
+ as a limb multiplication on modern processors:
+ a0 = (b0 >> (GMP_NUMB_BITS / 2)) * (b0 >> (GMP_NUMB_BITS / 2));
+ sb = 0;
+ */
+ ax = MPFR_GET_EXP(b) * 2;
+ umul_ppmm (a0, sb, b0, b0);
+ if (a0 < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+
+ MPFR_SIGN(a) = MPFR_SIGN_POS;
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ /* Note: for emin=2*k+1, a >= 0.111...111*2^(emin-1) is not possible,
+ i.e., a >= (1 - 2^(-p))*2^(2k), since we need a = b^2 with EXP(b)=k,
+ and the largest such b is (1 - 2^(-p))*2^k satisfies
+ b^2 < (1 - 2^(-p))*2^(2k).
+ For emin=2*k, it is only possible for some values of p: it is not
+ possible for p=53, because the largest significand is 6369051672525772
+ but its square has only 52 leading ones. For p=24 it is possible,
+ with b = 11863283, whose square has 24 leading ones. */
+ if ((ax == __gmpfr_emin - 1) && (ap[0] == ~mask) &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either ax < emin - 1
+ (b) or ax = emin - 1 and ap[0] = 1000....000 and rb = sb = 0 */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 || (ap[0] == MPFR_LIMB_HIGHBIT && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS);
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN_POS);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ if (ap[0] == 0)
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN_POS);
+ }
+}
+
+/* special code for PREC(a) = GMP_NUMB_BITS */
+static int
+mpfr_sqr_1n (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ mp_limb_t a0;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mp_limb_t b0 = MPFR_MANT(b)[0];
+ mpfr_exp_t ax;
+ mp_limb_t rb, sb;
+
+ ax = MPFR_GET_EXP(b) * 2;
+ umul_ppmm (a0, sb, b0, b0);
+ if (a0 < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ }
+ rb = sb & MPFR_LIMB_HIGHBIT;
+ sb = sb & ~MPFR_LIMB_HIGHBIT;
+ ap[0] = a0;
+
+ MPFR_SIGN(a) = MPFR_SIGN_POS;
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ /* As seen in mpfr_mul_1, we cannot have a0 = 111...111 here if there
+ was not exponent decrease (ax--) above.
+ In the case of an exponent decrease, it is not possible for
+ GMP_NUMB_BITS=32 since the largest b0 such that b0^2 < 2^(2*32-1)
+ is b0=3037000499, but its square has only 30 leading ones.
+ For GMP_NUMB_BITS=64 it is possible: the largest b0 is
+ 13043817825332782212, and its square has 64 leading ones. */
+ if ((ax == __gmpfr_emin - 1) && (ap[0] == ~MPFR_LIMB_HIGHBIT) &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either ax < emin - 1
+ (b) or ax = emin - 1 and ap[0] = 1000....000 and rb = sb = 0 */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 || (ap[0] == MPFR_LIMB_HIGHBIT && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS);
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & MPFR_LIMB_ONE) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN_POS);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE;
+ if (ap[0] == 0)
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN_POS);
+ }
+}
+
+/* Special code for GMP_NUMB_BITS < prec(a) < 2*GMP_NUMB_BITS and
+ GMP_NUMB_BITS < prec(b) <= 2*GMP_NUMB_BITS.
+ Note: this function was copied and optimized from mpfr_mul_2 in file mul.c,
+ thus any change here should be done also in mpfr_mul_2, if applicable. */
+static int
+mpfr_sqr_2 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, mpfr_prec_t p)
+{
+ mp_limb_t h, l, u, v;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mpfr_exp_t ax = 2 * MPFR_GET_EXP(b);
+ mpfr_prec_t sh = 2 * GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb, sb2, mask = MPFR_LIMB_MASK(sh);
+ mp_limb_t *bp = MPFR_MANT(b);
+
+ /* we store the 4-limb product in h=ap[1], l=ap[0], sb=ap[-1], sb2=ap[-2] */
+ umul_ppmm (h, l, bp[1], bp[1]);
+ umul_ppmm (u, v, bp[1], bp[0]);
+ l += u << 1;
+ h += (l < (u << 1)) + (u >> (GMP_NUMB_BITS - 1));
+
+ /* now the full square is {h, l, 2*v + high(b0*c0), low(b0*c0)},
+ where the lower part contributes to less than 3 ulps to {h, l} */
+
+ /* If h has its most significant bit set and the low sh-1 bits of l are not
+ 000...000 nor 111...111 nor 111...110, then we can round correctly;
+ if h has zero as most significant bit, we have to shift left h and l,
+ thus if the low sh-2 bits are not 000...000 nor 111...111 nor 111...110,
+ then we can round correctly. To avoid an extra test we consider the latter
+ case (if we can round, we can also round in the former case).
+ For sh <= 3, we have mask <= 7, thus (mask>>2) <= 1, and the approximation
+ cannot be enough. */
+ if (MPFR_LIKELY(((l + 2) & (mask >> 2)) > 2))
+ sb = sb2 = 1; /* result cannot be exact in that case */
+ else
+ {
+ mp_limb_t carry1, carry2;
+
+ umul_ppmm (sb, sb2, bp[0], bp[0]);
+ /* the full product is {h, l, sb + v + w, sb2} */
+ ADD_LIMB (sb, v, carry1);
+ ADD_LIMB (l, carry1, carry2);
+ h += carry2;
+ ADD_LIMB (sb, v, carry1);
+ ADD_LIMB (l, carry1, carry2);
+ h += carry2;
+ }
+ if (h < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ h = (h << 1) | (l >> (GMP_NUMB_BITS - 1));
+ l = (l << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ /* no need to shift sb2 since we only want to know if it is zero or not */
+ }
+ ap[1] = h;
+ rb = l & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= ((l & mask) ^ rb) | sb2;
+ ap[0] = l & ~mask;
+
+ MPFR_SIGN(a) = MPFR_SIGN_POS;
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ /* Note: like for mpfr_sqr_2, the case
+ 0.111...111*2^(emin-1) < a < 2^(emin-1) is not possible when emin is
+ odd, since (modulo a shift) this would imply 1-2^(-p) < a = b^2 < 1,
+ and this is not possible with 1-2^(-p) <= b < 1.
+ For emin even, it is possible for some values of p, for example for
+ p=69 with b=417402170410649030795*2^k. */
+ if ((ax == __gmpfr_emin - 1) &&
+ (ap[1] == MPFR_LIMB_MAX) &&
+ (ap[0] == ~mask) &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* for RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 ||
+ (ap[1] == MPFR_LIMB_HIGHBIT && ap[0] == 0 && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS);
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN_POS);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ if (ap[1] == 0)
+ {
+ ap[1] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN_POS);
+ }
+}
+
+/* Special code for 2*GMP_NUMB_BITS < prec(a) < 3*GMP_NUMB_BITS and
+ 2*GMP_NUMB_BITS < prec(b) <= 3*GMP_NUMB_BITS. */
+static int
+mpfr_sqr_3 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, mpfr_prec_t p)
+{
+ mp_limb_t a0, a1, a2, h, l;
+ mpfr_limb_ptr ap = MPFR_MANT(a);
+ mpfr_exp_t ax = 2 * MPFR_GET_EXP(b);
+ mpfr_prec_t sh = 3 * GMP_NUMB_BITS - p;
+ mp_limb_t rb, sb, sb2, mask = MPFR_LIMB_MASK(sh);
+ mp_limb_t *bp = MPFR_MANT(b);
+
+ /* we store the upper 3-limb product in a2, a1, a0:
+ b2^2, 2*b2*b1, 2*b2*b0+b1^2 */
+
+ /* first compute b2*b1 and b2*b0, which will be shifted by 1 */
+ umul_ppmm (a1, a0, bp[2], bp[1]);
+ umul_ppmm (h, l, bp[2], bp[0]);
+ a0 += h;
+ a1 += (a0 < h);
+ /* now a1, a0 contains b2*b1 + floor(b2*b0/B): there can be no overflow
+ since b2*b1*B + b2*b0 <= b2*(b1*B+b0) <= b2*(B^2-1) < B^3 */
+
+ /* multiply a2, a1, a0 by 2 */
+ a2 = a1 >> (GMP_NUMB_BITS - 1);
+ a1 = (a1 << 1) | (a0 >> (GMP_NUMB_BITS - 1));
+ a0 = (a0 << 1);
+
+ /* add b2^2 */
+ umul_ppmm (h, l, bp[2], bp[2]);
+ a1 += l;
+ a2 += h + (a1 < l);
+
+ /* add b1^2 */
+ umul_ppmm (h, l, bp[1], bp[1]);
+ a0 += h;
+ a1 += (a0 < h);
+ a2 += (a1 == 0 && a0 < h);
+
+ /* Now the approximate product {a2, a1, a0} has an error of less than
+ 5 ulps (3 ulps for the ignored low limbs of 2*b2*b0+b1^2,
+ plus 2 ulps for the ignored 2*b1*b0 (plus b0^2).
+ Since we might shift by 1 bit, we make sure the low sh-2 bits of a0
+ are not 0, -1, -2, -3 or -4. */
+
+ if (MPFR_LIKELY(((a0 + 4) & (mask >> 2)) > 4))
+ sb = sb2 = 1; /* result cannot be exact in that case */
+ else
+ {
+ mp_limb_t p[6];
+ mpn_sqr (p, bp, 3);
+ a2 = p[5];
+ a1 = p[4];
+ a0 = p[3];
+ sb = p[2];
+ sb2 = p[1] | p[0];
+ }
+ if (a2 < MPFR_LIMB_HIGHBIT)
+ {
+ ax --;
+ a2 = (a2 << 1) | (a1 >> (GMP_NUMB_BITS - 1));
+ a1 = (a1 << 1) | (a0 >> (GMP_NUMB_BITS - 1));
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ /* no need to shift sb2: we only need to know if it is zero or not */
+ }
+ ap[2] = a2;
+ ap[1] = a1;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= ((a0 & mask) ^ rb) | sb2;
+ ap[0] = a0 & ~mask;
+
+ MPFR_SIGN(a) = MPFR_SIGN_POS;
+
+ /* rounding */
+ if (MPFR_UNLIKELY(ax > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+
+ /* Warning: underflow should be checked *after* rounding, thus when rounding
+ away and when a > 0.111...111*2^(emin-1), or when rounding to nearest and
+ a >= 0.111...111[1]*2^(emin-1), there is no underflow. */
+ if (MPFR_UNLIKELY(ax < __gmpfr_emin))
+ {
+ if ((ax == __gmpfr_emin - 1) &&
+ (ap[2] == MPFR_LIMB_MAX) &&
+ (ap[1] == MPFR_LIMB_MAX) &&
+ (ap[0] == ~mask) &&
+ ((rnd_mode == MPFR_RNDN && rb) ||
+ (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
+ goto rounding; /* no underflow */
+ /* for RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax < __gmpfr_emin - 1 ||
+ (ap[2] == MPFR_LIMB_HIGHBIT && ap[1] == 0 && ap[0] == 0
+ && (rb | sb) == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS);
+ }
+
+ rounding:
+ MPFR_EXP (a) = ax; /* Don't use MPFR_SET_EXP since ax might be < __gmpfr_emin
+ in the cases "goto rounding" above. */
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_ASSERTD(ax >= __gmpfr_emin);
+ MPFR_RET(-MPFR_SIGN_POS);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ ap[2] += (ap[1] == 0) && (ap[0] == 0);
+ if (ap[2] == 0)
+ {
+ ap[2] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(ax + 1 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+ MPFR_ASSERTD(ax + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(ax + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (a, ax + 1);
+ }
+ MPFR_RET(MPFR_SIGN_POS);
+ }
+}
+
+#endif /* !defined(MPFR_GENERIC_ABI) && ... */
+
+/* Note: mpfr_sqr will call mpfr_mul if bn > MPFR_SQR_THRESHOLD,
+ in order to use Mulders' mulhigh, which is handled only here
+ to avoid partial code duplication. There is some overhead due
+ to the additional tests, but slowdown should not be noticeable
+ as this code is not executed in very small precisions. */
+
int
mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
{
@@ -29,7 +504,7 @@ mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
mpfr_exp_t ax;
mp_limb_t *tmp;
mp_limb_t b1;
- mpfr_prec_t bq;
+ mpfr_prec_t aq, bq;
mp_size_t bn, tn;
MPFR_TMP_DECL(marker);
@@ -53,9 +528,26 @@ mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
( MPFR_ASSERTD(MPFR_IS_ZERO(b)), MPFR_SET_ZERO(a) );
MPFR_RET(0);
}
- ax = 2 * MPFR_GET_EXP (b);
- bq = MPFR_PREC(b);
+ aq = MPFR_GET_PREC(a);
+ bq = MPFR_GET_PREC(b);
+
+#if !defined(MPFR_GENERIC_ABI) && (GMP_NUMB_BITS == 32 || GMP_NUMB_BITS == 64)
+ if (aq < GMP_NUMB_BITS && bq <= GMP_NUMB_BITS)
+ return mpfr_sqr_1 (a, b, rnd_mode, aq);
+
+ if (GMP_NUMB_BITS < aq && aq < 2 * GMP_NUMB_BITS
+ && GMP_NUMB_BITS < bq && bq <= 2 * GMP_NUMB_BITS)
+ return mpfr_sqr_2 (a, b, rnd_mode, aq);
+ if (aq == GMP_NUMB_BITS && bq <= GMP_NUMB_BITS)
+ return mpfr_sqr_1n (a, b, rnd_mode);
+
+ if (2 * GMP_NUMB_BITS < aq && aq < 3 * GMP_NUMB_BITS
+ && 2 * GMP_NUMB_BITS < bq && bq <= 3 * GMP_NUMB_BITS)
+ return mpfr_sqr_3 (a, b, rnd_mode, aq);
+#endif
+
+ ax = 2 * MPFR_GET_EXP (b);
MPFR_ASSERTN (2 * (mpfr_uprec_t) bq <= MPFR_PREC_MAX);
bn = MPFR_LIMB_SIZE (b); /* number of limbs of b */
@@ -69,7 +561,7 @@ mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
tmp = MPFR_TMP_LIMBS_ALLOC (2 * bn);
/* Multiplies the mantissa in temporary allocated space */
- mpn_sqr_n (tmp, MPFR_MANT(b), bn);
+ mpn_sqr (tmp, MPFR_MANT(b), bn);
b1 = tmp[2 * bn - 1];
/* now tmp[0]..tmp[2*bn-1] contains the product of both mantissa,
@@ -83,8 +575,7 @@ mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
if (MPFR_UNLIKELY(b1 == 0))
mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */
- cc = mpfr_round_raw (MPFR_MANT (a), tmp, 2 * bq, 0,
- MPFR_PREC (a), rnd_mode, &inexact);
+ cc = mpfr_round_raw (MPFR_MANT (a), tmp, 2 * bq, 0, aq, rnd_mode, &inexact);
/* cc = 1 ==> result is a power of two */
if (MPFR_UNLIKELY(cc))
MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] = MPFR_LIMB_HIGHBIT;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sqrt.c b/Build/source/libs/mpfr/mpfr-src/src/sqrt.c
index f3682fa4e75..7acb5f06c93 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sqrt.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sqrt.c
@@ -20,8 +20,460 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
+#if !defined(MPFR_GENERIC_ABI) && GMP_NUMB_BITS == 64
+
+#include "invsqrt_limb.h"
+
+/* Put in rp[1]*2^64+rp[0] an approximation of floor(sqrt(2^128*n)),
+ with 2^126 <= n := np[1]*2^64 + np[0] < 2^128. We have:
+ {rp, 2} - 4 <= floor(sqrt(2^128*n)) <= {rp, 2} + 26. */
+static void
+mpfr_sqrt2_approx (mpfr_limb_ptr rp, mpfr_limb_srcptr np)
+{
+ mp_limb_t x, r1, r0, h, l, t;
+
+ __gmpfr_sqrt_limb (r1, h, l, x, np[1]);
+
+ /* now r1 = floor(sqrt(n1)) and h:l = n1^2 - r1^2 with h:l <= 2*r1,
+ thus h <= 1 */
+
+ l += np[0];
+ h += (l < np[0]);
+
+ /* now h <= 2 */
+
+ /* divide by 2 */
+ l = (h << 63) | (l >> 1);
+ h = h >> 1;
+
+ /* now h <= 1 */
+
+ /* now add (2^64+x) * (h*2^64+l) / 2^64 to [r1*2^64, 0] */
+
+ umul_ppmm (r0, t, x, l); /* x * l */
+ r0 += l;
+ r1 += h + (r0 < l); /* now we have added 2^64 * (h*2^64+l) */
+ if (h)
+ {
+ r0 += x;
+ r1 += (r0 < x); /* add x */
+ }
+
+ MPFR_ASSERTD(r1 & MPFR_LIMB_HIGHBIT);
+
+ rp[0] = r0;
+ rp[1] = r1;
+}
+
+/* Special code for prec(r), prec(u) < GMP_NUMB_BITS. We cannot have
+ prec(u) = GMP_NUMB_BITS here, since when the exponent of u is odd,
+ we need to shift u by one bit to the right without losing any bit.
+ Assumes GMP_NUMB_BITS = 64. */
+static int
+mpfr_sqrt1 (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t p = MPFR_GET_PREC(r);
+ mpfr_prec_t exp_u = MPFR_EXP(u), exp_r, sh = GMP_NUMB_BITS - p;
+ mp_limb_t u0, r0, rb, sb, mask = MPFR_LIMB_MASK(sh);
+ mpfr_limb_ptr rp = MPFR_MANT(r);
+
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 64);
+
+ /* first make the exponent even */
+ u0 = MPFR_MANT(u)[0];
+ if (((unsigned int) exp_u & 1) != 0)
+ {
+ u0 >>= 1;
+ exp_u ++;
+ }
+ MPFR_ASSERTD (((unsigned int) exp_u & 1) == 0);
+ exp_r = exp_u / 2;
+
+ /* then compute an approximation of the integer square root of
+ u0*2^GMP_NUMB_BITS */
+ __gmpfr_sqrt_limb_approx (r0, u0);
+
+ sb = 1; /* when we can round correctly with the approximation, the sticky bit
+ is non-zero */
+
+ /* the exact square root is in [r0, r0 + 7] */
+ if (MPFR_UNLIKELY(((r0 + 7) & (mask >> 1)) <= 7))
+ {
+ /* first ensure r0 has its most significant bit set */
+ if (MPFR_UNLIKELY(r0 < MPFR_LIMB_HIGHBIT))
+ r0 = MPFR_LIMB_HIGHBIT;
+ umul_ppmm (rb, sb, r0, r0);
+ sub_ddmmss (rb, sb, u0, 0, rb, sb);
+ /* for the exact square root, we should have 0 <= rb:sb <= 2*r0 */
+ while (!(rb == 0 || (rb == 1 && sb <= 2 * r0)))
+ {
+ /* subtract 2*r0+1 from rb:sb: subtract r0 before incrementing r0,
+ then r0 after (which is r0+1) */
+ rb -= (sb < r0);
+ sb -= r0;
+ r0 ++;
+ rb -= (sb < r0);
+ sb -= r0;
+ }
+ /* now we should have rb*2^64 + sb <= 2*r0 */
+ MPFR_ASSERTD(rb == 0 || (rb == 1 && sb <= 2 * r0));
+ sb = rb | sb;
+ }
+
+ rb = r0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (r0 & mask) ^ rb;
+ rp[0] = r0 & ~mask;
+
+ /* rounding: sb = 0 implies rb = 0, since (rb,sb)=(1,0) is not possible */
+ MPFR_ASSERTD (rb == 0 || sb != 0);
+
+ /* Note: if 1 and 2 are in [emin,emax], no overflow nor underflow
+ is possible */
+ if (MPFR_UNLIKELY (exp_r > __gmpfr_emax))
+ return mpfr_overflow (r, rnd_mode, 1);
+
+ /* See comments in mpfr_div_1 */
+ if (MPFR_UNLIKELY (exp_r < __gmpfr_emin))
+ {
+ if (rnd_mode == MPFR_RNDN)
+ {
+ if ((exp_r == __gmpfr_emin - 1) && (rp[0] == ~mask) && rb)
+ goto rounding; /* no underflow */
+ if (exp_r < __gmpfr_emin - 1 || (rp[0] == MPFR_LIMB_HIGHBIT && sb == 0))
+ rnd_mode = MPFR_RNDZ;
+ }
+ else if (MPFR_IS_LIKE_RNDA(rnd_mode, 0))
+ {
+ if ((exp_r == __gmpfr_emin - 1) && (rp[0] == ~mask) && (rb | sb))
+ goto rounding; /* no underflow */
+ }
+ return mpfr_underflow (r, rnd_mode, 1);
+ }
+
+ rounding:
+ MPFR_EXP (r) = exp_r;
+ if (sb == 0 /* implies rb = 0 */ || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD (rb == 0 || rnd_mode == MPFR_RNDF);
+ MPFR_ASSERTD(exp_r >= __gmpfr_emin);
+ MPFR_ASSERTD(exp_r <= __gmpfr_emax);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* since sb <> 0, only rb is needed to decide how to round, and the exact
+ middle is not possible */
+ if (rb == 0)
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, 0))
+ {
+ truncate:
+ MPFR_ASSERTD(exp_r >= __gmpfr_emin);
+ MPFR_ASSERTD(exp_r <= __gmpfr_emax);
+ MPFR_RET(-1);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ rp[0] += MPFR_LIMB_ONE << sh;
+ if (rp[0] == 0)
+ {
+ rp[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(exp_r + 1 > __gmpfr_emax))
+ return mpfr_overflow (r, rnd_mode, 1);
+ MPFR_ASSERTD(exp_r + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(exp_r + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (r, exp_r + 1);
+ }
+ MPFR_RET(1);
+ }
+}
+
+/* Special code for prec(r) = GMP_NUMB_BITS and prec(u) <= GMP_NUMB_BITS. */
+static int
+mpfr_sqrt1n (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t exp_u = MPFR_EXP(u), exp_r;
+ mp_limb_t u0, r0, rb, sb, low;
+ mpfr_limb_ptr rp = MPFR_MANT(r);
+
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 64);
+ MPFR_ASSERTD(MPFR_PREC(r) == GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC(u) <= GMP_NUMB_BITS);
+
+ /* first make the exponent even */
+ u0 = MPFR_MANT(u)[0];
+ if (((unsigned int) exp_u & 1) != 0)
+ {
+ low = u0 << (GMP_NUMB_BITS - 1);
+ u0 >>= 1;
+ exp_u ++;
+ }
+ else
+ low = 0; /* low part of u0 */
+ MPFR_ASSERTD (((unsigned int) exp_u & 1) == 0);
+ exp_r = exp_u / 2;
+
+ /* then compute an approximation of the integer square root of
+ u0*2^GMP_NUMB_BITS */
+ __gmpfr_sqrt_limb_approx (r0, u0);
+
+ /* the exact square root is in [r0, r0 + 7] */
+
+ /* first ensure r0 has its most significant bit set */
+ if (MPFR_UNLIKELY(r0 < MPFR_LIMB_HIGHBIT))
+ r0 = MPFR_LIMB_HIGHBIT;
+
+ umul_ppmm (rb, sb, r0, r0);
+ sub_ddmmss (rb, sb, u0, low, rb, sb);
+ /* for the exact square root, we should have 0 <= rb:sb <= 2*r0 */
+ while (!(rb == 0 || (rb == 1 && sb <= 2 * r0)))
+ {
+ /* subtract 2*r0+1 from rb:sb: subtract r0 before incrementing r0,
+ then r0 after (which is r0+1) */
+ rb -= (sb < r0);
+ sb -= r0;
+ r0 ++;
+ rb -= (sb < r0);
+ sb -= r0;
+ }
+ /* now we have u0*2^64+low = r0^2 + rb*2^64+sb, with rb*2^64+sb <= 2*r0 */
+ MPFR_ASSERTD(rb == 0 || (rb == 1 && sb <= 2 * r0));
+
+ /* We can't have the middle case u0*2^64 = (r0 + 1/2)^2 since
+ (r0 + 1/2)^2 is not an integer.
+ We thus rb = 1 whenever u0*2^64 > (r0 + 1/2)^2, thus rb*2^64 + sb > r0
+ and the sticky bit is always 1, unless we had rb = sb = 0. */
+
+ rb = rb || (sb > r0);
+ sb = rb | sb;
+ rp[0] = r0;
+
+ /* rounding */
+
+ /* Note: if 1 and 2 are in [emin,emax], no overflow nor underflow
+ is possible */
+ if (MPFR_UNLIKELY (exp_r > __gmpfr_emax))
+ return mpfr_overflow (r, rnd_mode, 1);
+
+ /* See comments in mpfr_div_1 */
+ if (MPFR_UNLIKELY (exp_r < __gmpfr_emin))
+ {
+ if (rnd_mode == MPFR_RNDN)
+ {
+ /* the case rp[0] = 111...111 and rb = 1 cannot happen, since it
+ would imply u0 >= (2^64-1/2)^2/2^64 thus u0 >= 2^64 */
+ if (exp_r < __gmpfr_emin - 1 || (rp[0] == MPFR_LIMB_HIGHBIT && sb == 0))
+ rnd_mode = MPFR_RNDZ;
+ }
+ else if (MPFR_IS_LIKE_RNDA(rnd_mode, 0))
+ {
+ if ((exp_r == __gmpfr_emin - 1) && (rp[0] == ~MPFR_LIMB_ZERO) && (rb | sb))
+ goto rounding; /* no underflow */
+ }
+ return mpfr_underflow (r, rnd_mode, 1);
+ }
+
+ /* sb = 0 can only occur when the square root is exact, i.e., rb = 0 */
+
+ rounding:
+ MPFR_EXP (r) = exp_r;
+ if (sb == 0 /* implies rb = 0 */ || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(exp_r >= __gmpfr_emin);
+ MPFR_ASSERTD(exp_r <= __gmpfr_emax);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* we can't have sb = 0, thus rb is enough */
+ if (rb == 0)
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, 0))
+ {
+ truncate:
+ MPFR_ASSERTD(exp_r >= __gmpfr_emin);
+ MPFR_ASSERTD(exp_r <= __gmpfr_emax);
+ MPFR_RET(-1);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ rp[0] += MPFR_LIMB_ONE;
+ if (rp[0] == 0)
+ {
+ rp[0] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(exp_r + 1 > __gmpfr_emax))
+ return mpfr_overflow (r, rnd_mode, 1);
+ MPFR_ASSERTD(exp_r + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(exp_r + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (r, exp_r + 1);
+ }
+ MPFR_RET(1);
+ }
+}
+
+/* Special code for GMP_NUMB_BITS < prec(r) < 2*GMP_NUMB_BITS,
+ and GMP_NUMB_BITS < prec(u) <= 2*GMP_NUMB_BITS.
+ Assumes GMP_NUMB_BITS=64. */
+static int
+mpfr_sqrt2 (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t p = MPFR_GET_PREC(r);
+ mpfr_limb_ptr up = MPFR_MANT(u), rp = MPFR_MANT(r);
+ mp_limb_t np[4], rb, sb, mask;
+ mpfr_prec_t exp_u = MPFR_EXP(u), exp_r, sh = 2 * GMP_NUMB_BITS - p;
+
+ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 64);
+
+ if (((unsigned int) exp_u & 1) != 0)
+ {
+ np[3] = up[1] >> 1;
+ np[2] = (up[1] << (GMP_NUMB_BITS - 1)) | (up[0] >> 1);
+ np[1] = up[0] << (GMP_NUMB_BITS - 1);
+ exp_u ++;
+ }
+ else
+ {
+ np[3] = up[1];
+ np[2] = up[0];
+ np[1] = 0;
+ }
+ exp_r = exp_u / 2;
+
+ mask = MPFR_LIMB_MASK(sh);
+
+ mpfr_sqrt2_approx (rp, np + 2);
+ /* with n = np[3]*2^64+np[2], we have:
+ {rp, 2} - 4 <= floor(sqrt(2^128*n)) <= {rp, 2} + 26, thus we can round
+ correctly except when the number formed by the last sh-1 bits
+ of rp[0] is in the range [-26, 4]. */
+ if (MPFR_LIKELY(((rp[0] + 26) & (mask >> 1)) > 30))
+ sb = 1;
+ else
+ {
+ mp_limb_t tp[4], h, l;
+
+ np[0] = 0;
+ mpn_sqr (tp, rp, 2);
+ /* since we know s - 26 <= r <= s + 4 and 0 <= n^2 - s <= 2*s, we have
+ -8*s-16 <= n - r^2 <= 54*s - 676, thus it suffices to compute
+ n - r^2 modulo 2^192 */
+ mpn_sub_n (tp, np, tp, 3);
+ /* invariant: h:l = 2 * {rp, 2}, with upper bit implicit */
+ h = (rp[1] << 1) | (rp[0] >> (GMP_NUMB_BITS - 1));
+ l = rp[0] << 1;
+ while ((mp_limb_signed_t) tp[2] < 0) /* approximation was too large */
+ {
+ /* subtract 1 to {rp, 2}, thus 2 to h:l */
+ h -= (l <= MPFR_LIMB_ONE);
+ l -= 2;
+ /* add (1:h:l)+1 to {tp,3} */
+ tp[0] += l + 1;
+ tp[1] += h + (tp[0] < l);
+ /* necessarily rp[1] has its most significant bit set */
+ tp[2] += MPFR_LIMB_ONE + (tp[1] < h || (tp[1] == h && tp[0] < l));
+ }
+ /* now tp[2] >= 0 */
+ /* now we want {tp, 4} <= 2 * {rp, 2}, which implies tp[2] <= 1 */
+ while (tp[2] > 1 || (tp[2] == 1 && tp[1] > h) ||
+ (tp[2] == 1 && tp[1] == h && tp[0] > l))
+ {
+ /* subtract (1:h:l)+1 from {tp,3} */
+ tp[2] -= MPFR_LIMB_ONE + (tp[1] < h || (tp[1] == h && tp[0] <= l));
+ tp[1] -= h + (tp[0] <= l);
+ tp[0] -= l + 1;
+ /* add 2 to h:l */
+ l += 2;
+ h += (l <= MPFR_LIMB_ONE);
+ }
+ /* restore {rp, 2} from h:l */
+ rp[1] = MPFR_LIMB_HIGHBIT | (h >> 1);
+ rp[0] = (h << (GMP_NUMB_BITS - 1)) | (l >> 1);
+ sb = tp[2] | tp[0] | tp[1];
+ }
+
+ rb = rp[0] & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (rp[0] & mask) ^ rb;
+ rp[0] = rp[0] & ~mask;
+
+ /* rounding */
+ if (MPFR_UNLIKELY (exp_r > __gmpfr_emax))
+ return mpfr_overflow (r, rnd_mode, 1);
+
+ /* See comments in mpfr_div_1 */
+ if (MPFR_UNLIKELY (exp_r < __gmpfr_emin))
+ {
+ if (rnd_mode == MPFR_RNDN)
+ {
+ if (exp_r == __gmpfr_emin - 1 && (rp[1] == MPFR_LIMB_MAX &&
+ rp[0] == ~mask) && rb)
+ goto rounding; /* no underflow */
+ if (exp_r < __gmpfr_emin - 1 || (rp[1] == MPFR_LIMB_HIGHBIT &&
+ rp[0] == MPFR_LIMB_ZERO && sb == 0))
+ rnd_mode = MPFR_RNDZ;
+ }
+ else if (MPFR_IS_LIKE_RNDA(rnd_mode, 0))
+ {
+ if (exp_r == __gmpfr_emin - 1 && (rp[1] == MPFR_LIMB_MAX &&
+ rp[0] == ~mask) && (rb | sb))
+ goto rounding; /* no underflow */
+ }
+ return mpfr_underflow (r, rnd_mode, 1);
+ }
+
+ rounding:
+ MPFR_EXP (r) = exp_r;
+ if (sb == 0 /* implies rb = 0 */ || rnd_mode == MPFR_RNDF)
+ {
+ MPFR_ASSERTD(exp_r >= __gmpfr_emin);
+ MPFR_ASSERTD(exp_r <= __gmpfr_emax);
+ MPFR_RET (0);
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* since sb <> 0 now, only rb is needed */
+ if (rb == 0)
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, 0))
+ {
+ truncate:
+ MPFR_ASSERTD(exp_r >= __gmpfr_emin);
+ MPFR_ASSERTD(exp_r <= __gmpfr_emax);
+ MPFR_RET(-1);
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ rp[0] += MPFR_LIMB_ONE << sh;
+ rp[1] += rp[0] == 0;
+ if (rp[1] == 0)
+ {
+ rp[1] = MPFR_LIMB_HIGHBIT;
+ if (MPFR_UNLIKELY(exp_r + 1 > __gmpfr_emax))
+ return mpfr_overflow (r, rnd_mode, 1);
+ MPFR_ASSERTD(exp_r + 1 <= __gmpfr_emax);
+ MPFR_ASSERTD(exp_r + 1 >= __gmpfr_emin);
+ MPFR_SET_EXP (r, exp_r + 1);
+ }
+ MPFR_RET(1);
+ }
+}
+
+#endif /* !defined(MPFR_GENERIC_ABI) && GMP_NUMB_BITS == 64 */
+
int
mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
{
@@ -41,6 +493,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
int sh; /* number of extra bits in rp[0] */
int inexact; /* return ternary flag */
mpfr_exp_t expr;
+ mpfr_prec_t rq = MPFR_GET_PREC (r);
MPFR_TMP_DECL(marker);
MPFR_LOG_FUNC
@@ -83,8 +536,26 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
}
MPFR_SET_POS(r);
+#if !defined(MPFR_GENERIC_ABI) && GMP_NUMB_BITS == 64
+ {
+ mpfr_prec_t uq = MPFR_GET_PREC (u);
+
+ if (rq == uq)
+ {
+ if (rq < GMP_NUMB_BITS)
+ return mpfr_sqrt1 (r, u, rnd_mode);
+
+ if (GMP_NUMB_BITS < rq && rq < 2*GMP_NUMB_BITS)
+ return mpfr_sqrt2 (r, u, rnd_mode);
+
+ if (rq == GMP_NUMB_BITS)
+ return mpfr_sqrt1n (r, u, rnd_mode);
+ }
+ }
+#endif
+
MPFR_TMP_MARK (marker);
- MPFR_UNSIGNED_MINUS_MODULO(sh,MPFR_PREC(r));
+ MPFR_UNSIGNED_MINUS_MODULO (sh, rq);
if (sh == 0 && rnd_mode == MPFR_RNDN)
sh = GMP_NUMB_BITS; /* ugly case */
rsize = MPFR_LIMB_SIZE(r) + (sh == GMP_NUMB_BITS);
@@ -133,20 +604,14 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
/* sticky0 is non-zero iff the truncated part of the input is non-zero */
- /* mpn_rootrem with NULL 2nd argument is faster than mpn_sqrtrem, thus use
- it if available and if the user asked to use GMP internal functions */
-#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_ROOTREM)
- tsize = __gmpn_rootrem (rp, NULL, sp, rrsize, 2);
-#else
tsize = mpn_sqrtrem (rp, NULL, sp, rrsize);
-#endif
/* a return value of zero in mpn_sqrtrem indicates a perfect square */
sticky = sticky0 || tsize != 0;
/* truncate low bits of rp[0] */
sticky1 = rp[0] & ((sh < GMP_NUMB_BITS) ? MPFR_LIMB_MASK(sh)
- : ~MPFR_LIMB_ZERO);
+ : MPFR_LIMB_MAX);
rp[0] -= sticky1;
sticky = sticky || sticky1;
@@ -224,6 +689,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
MPN_COPY (rp0, rp + 1, rsize - 1);
end:
+ /* Do not use MPFR_SET_EXP because the range has not been checked yet. */
MPFR_ASSERTN (expr >= MPFR_EMIN_MIN && expr <= MPFR_EMAX_MAX);
MPFR_EXP (r) = expr;
MPFR_TMP_FREE(marker);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sqrt_ui.c b/Build/source/libs/mpfr/mpfr-src/src/sqrt_ui.c
index 44297199740..fbc46e2ae23 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sqrt_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sqrt_ui.c
@@ -30,7 +30,7 @@ mpfr_sqrt_ui (mpfr_ptr r, unsigned long u, mpfr_rnd_t rnd_mode)
{
mpfr_t uu;
mp_limb_t up[1];
- unsigned long cnt;
+ int cnt;
int inex;
MPFR_SAVE_EXPO_DECL (expo);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/strtofr.c b/Build/source/libs/mpfr/mpfr-src/src/strtofr.c
index f040ef65867..31ea01a4b4b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/strtofr.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/strtofr.c
@@ -20,7 +20,6 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-#include <stdlib.h> /* For strtol */
#include <ctype.h> /* For isspace */
#define MPFR_NEED_LONGLONG_H
@@ -220,7 +219,7 @@ fast_casecmp (const char *s1, const char *s2)
It returns:
-1 if invalid string,
0 if special string (like nan),
- 1 if the string is ok.
+ 1 if the string is OK.
2 if overflows
So it doesn't return the ternary value
BUT if it returns 0 (NAN or INF), the ternary value is also '0'
@@ -324,7 +323,7 @@ parse_string (mpfr_t x, struct parsed_string *pstr,
/* Alloc mantissa */
pstr->alloc = (size_t) strlen (str) + 1;
- pstr->mantissa = (unsigned char*) (*__gmp_allocate_func) (pstr->alloc);
+ pstr->mantissa = (unsigned char*) mpfr_allocate_func (pstr->alloc);
/* Read mantissa digits */
parse_begin:
@@ -436,7 +435,7 @@ parse_string (mpfr_t x, struct parsed_string *pstr,
*string = str;
end:
if (pstr->mantissa != NULL && res != 1)
- (*__gmp_free_func) (pstr->mantissa, pstr->alloc);
+ mpfr_free_func (pstr->mantissa, pstr->alloc);
return res;
}
@@ -533,7 +532,7 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mpfr_rnd_t rnd)
if (real_ysize != ysize)
{
if (count == 0)
- MPN_COPY_DECR (y + ysize - real_ysize, y, real_ysize);
+ mpn_copyd (y + ysize - real_ysize, y, real_ysize);
MPN_ZERO (y, ysize - real_ysize);
}
/* for each bit shift decrease exponent of y */
@@ -808,7 +807,7 @@ parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mpfr_rnd_t rnd)
static void
free_parsed_string (struct parsed_string *pstr)
{
- (*__gmp_free_func) (pstr->mantissa, pstr->alloc);
+ mpfr_free_func (pstr->mantissa, pstr->alloc);
}
int
@@ -821,11 +820,11 @@ mpfr_strtofr (mpfr_t x, const char *string, char **end, int base,
/* For base <= 36, parsing is case-insensitive. */
MPFR_ASSERTN (base == 0 || (base >= 2 && base <= 62));
- /* If an error occured, it must return 0 */
+ /* If an error occurred, it must return 0. */
MPFR_SET_ZERO (x);
MPFR_SET_POS (x);
- MPFR_ASSERTN (MPFR_MAX_BASE >= 62);
+ MPFR_STAT_STATIC_ASSERT (MPFR_MAX_BASE >= 62);
res = parse_string (x, &pstr, &string, base);
/* If res == 0, then it was exact (NAN or INF),
so it is also the ternary value */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sub.c b/Build/source/libs/mpfr/mpfr-src/src/sub.c
index 7a544a8ffdf..69c679e1d19 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sub.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sub.c
@@ -22,7 +22,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
MPFR_LOG_FUNC
@@ -31,7 +31,7 @@ mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
("a[%Pu]=%.*Rg", mpfr_get_prec (a), mpfr_log_prec, a));
- if (MPFR_ARE_SINGULAR (b,c))
+ if (MPFR_ARE_SINGULAR_OR_UBF (b,c))
{
if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
{
@@ -72,11 +72,29 @@ mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
return mpfr_neg (a, c, rnd_mode);
}
- else
+ else if (MPFR_IS_ZERO (c))
{
- MPFR_ASSERTD (MPFR_IS_ZERO (c));
return mpfr_set (a, b, rnd_mode);
}
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_UBF (c));
+ /* mpfr_sub1sp and mpfr_add1sp are not intended to support UBF,
+ for which optimization is less important. */
+ if (MPFR_SIGN(b) == MPFR_SIGN(c))
+ return mpfr_sub1 (a, b, c, rnd_mode);
+ else if (MPFR_UBF_EXP_LESS_P (b, c))
+ {
+ int inexact;
+ rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ inexact = mpfr_add1 (a, c, b, rnd_mode);
+ MPFR_CHANGE_SIGN (a);
+ return -inexact;
+ }
+ else
+ return mpfr_add1 (a, b, c, rnd_mode);
+ }
}
MPFR_ASSERTD (MPFR_IS_PURE_FP (b));
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sub1.c b/Build/source/libs/mpfr/mpfr-src/src/sub1.c
index 1d117d0599b..258e3bec6b5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sub1.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sub1.c
@@ -28,18 +28,21 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
a positive value otherwise.
*/
+/* TODO: check the code in case exp_b == MPFR_EXP_MAX. */
+
int
mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
int sign;
- mpfr_uexp_t diff_exp;
+ mpfr_exp_t diff_exp, exp_a, exp_b;
mpfr_prec_t cancel, cancel1;
mp_size_t cancel2, an, bn, cn, cn0;
mp_limb_t *ap, *bp, *cp;
mp_limb_t carry, bb, cc;
+ mpfr_prec_t aq, bq;
int inexact, shift_b, shift_c, add_exp = 0;
int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c),
- negative if low(b) < low(c), positive if low(b)>low(c) */
+ negative if low(b) < low(c), positive if low(b) > low(c) */
int sh, k;
MPFR_TMP_DECL(marker);
@@ -47,6 +50,10 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
ap = MPFR_MANT(a);
an = MPFR_LIMB_SIZE(a);
+ (void) MPFR_GET_PREC (a);
+ (void) MPFR_GET_PREC (b);
+ (void) MPFR_GET_PREC (c);
+
sign = mpfr_cmp2 (b, c, &cancel);
if (MPFR_UNLIKELY(sign == 0))
{
@@ -62,7 +69,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
* If subtraction: sign(a) = sign * sign(b)
* If addition: sign(a) = sign of the larger argument in absolute value.
*
- * Both cases can be simplidied in:
+ * Both cases can be simplified in:
* if (sign>0)
* if addition: sign(a) = sign * sign(b) = sign(b)
* if subtraction, b is greater, so sign(a) = sign(b)
@@ -82,76 +89,106 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
MPFR_SET_SAME_SIGN (a,b);
+ if (MPFR_UNLIKELY (MPFR_IS_UBF (b) || MPFR_IS_UBF (c)))
+ {
+ exp_b = MPFR_IS_UBF (b) ?
+ mpfr_ubf_zexp2exp (MPFR_ZEXP (b)) : MPFR_GET_EXP (b);
+ diff_exp = mpfr_ubf_diff_exp (b, c);
+ }
+ else
+ {
+ exp_b = MPFR_GET_EXP (b);
+ diff_exp = exp_b - MPFR_GET_EXP (c);
+ }
+ MPFR_ASSERTD (diff_exp >= 0);
+
+ aq = MPFR_GET_PREC (a);
+ bq = MPFR_GET_PREC (b);
+
/* Check if c is too small.
A more precise test is to replace 2 by
(rnd == MPFR_RNDN) + mpfr_power2_raw (b)
but it is more expensive and not very useful */
- if (MPFR_UNLIKELY (MPFR_GET_EXP (c) <= MPFR_GET_EXP (b)
- - (mpfr_exp_t) MAX (MPFR_PREC (a), MPFR_PREC (b)) - 2))
+ if (MPFR_UNLIKELY (MAX (aq, bq) + 2 <= diff_exp))
{
+ MPFR_LOG_MSG (("case c small\n", 0));
+
/* Remember, we can't have an exact result! */
/* A.AAAAAAAAAAAAAAAAA
= B.BBBBBBBBBBBBBBB
- C.CCCCCCCCCCCCC */
/* A = S*ABS(B) +/- ulp(a) */
- MPFR_SET_EXP (a, MPFR_GET_EXP (b));
- MPFR_RNDRAW_EVEN (inexact, a, MPFR_MANT (b), MPFR_PREC (b),
- rnd_mode, MPFR_SIGN (a), ++ MPFR_EXP (a));
+
+ /* since we can't have an exact result, for RNDF we can truncate b */
+ if (rnd_mode == MPFR_RNDF)
+ return mpfr_set4 (a, b, MPFR_RNDZ, MPFR_SIGN (a));
+
+ MPFR_EXP (a) = exp_b; /* may be up to MPFR_EXP_MAX */
+ MPFR_RNDRAW_EVEN (inexact, a, MPFR_MANT (b), bq,
+ rnd_mode, MPFR_SIGN (a),
+ if (MPFR_EXP (a) != MPFR_EXP_MAX)
+ ++ MPFR_EXP (a));
+ MPFR_LOG_MSG (("inexact=%d\n", inexact));
if (inexact == 0)
{
- /* a = b (Exact)
- But we know it isn't (Since we have to remove `c')
- So if we round to Zero, we have to remove one ulp.
- Otherwise the result is correctly rounded. */
- /* An overflow is not possible. */
- MPFR_ASSERTD (MPFR_EXP (a) <= __gmpfr_emax);
- if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (a)))
+ /* a = b, but the exact value of b - c is a bit below. Then,
+ except for directed rounding similar to toward zero and
+ before overflow checking: a is the correctly rounded value
+ and since |b| - |c| < |a|, the ternary value value is given
+ by the sign of a. */
+ if (! MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (a)))
{
- mpfr_nexttozero (a);
- MPFR_RET (- MPFR_INT_SIGN (a));
+ inexact = MPFR_INT_SIGN (a);
+ goto check_overflow;
}
- MPFR_RET (MPFR_INT_SIGN (a));
}
- else
+ else /* inexact != 0 */
{
/* A.AAAAAAAAAAAAAA
= B.BBBBBBBBBBBBBBB
- C.CCCCCCCCCCCCC */
- /* It isn't exact so Prec(b) > Prec(a) and the last
- Prec(b)-Prec(a) bits of `b' are not zeros.
- Which means that removing c from b can't generate a carry
- execpt in case of even rounding.
- In all other case the result and the inexact flag should be
- correct (We can't have an exact result).
- In case of EVEN rounding:
+ /* It isn't exact, so PREC(b) > PREC(a) and the last
+ PREC(b)-PREC(a) bits of b are not all zeros.
+ Subtracting c from b will not have an effect on the rounding
+ except in case of a midpoint in the round-to-nearest mode,
+ when the even rounding was done away from zero instead of
+ toward zero.
+ In case of even rounding:
1.BBBBBBBBBBBBBx10
- 1.CCCCCCCCCCCC
- = 1.BBBBBBBBBBBBBx01 Rounded to Prec(b)
- = 1.BBBBBBBBBBBBBx Nearest / Rounded to Prec(a)
+ = 1.BBBBBBBBBBBBBx01 Rounded to PREC(b)
+ = 1.BBBBBBBBBBBBBx Nearest / Rounded to PREC(a)
Set gives:
1.BBBBBBBBBBBBB0 if inexact == EVEN_INEX (x == 0)
1.BBBBBBBBBBBBB1+1 if inexact == -EVEN_INEX (x == 1)
- which means we get a wrong rounded result if x==1,
- i.e. inexact= MPFR_EVEN_INEX */
- if (MPFR_UNLIKELY (inexact == MPFR_EVEN_INEX*MPFR_INT_SIGN (a)))
- {
- if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax))
- mpfr_setmax (a, __gmpfr_emax);
- else
- mpfr_nexttozero (a);
- inexact = -MPFR_INT_SIGN (a);
- }
- else if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax))
- inexact = mpfr_overflow (a, rnd_mode, MPFR_SIGN (a));
- MPFR_RET (inexact);
+ which means we get a wrong rounded result if x == 1,
+ i.e. inexact == MPFR_EVEN_INEX (for positive numbers). */
+ if (MPFR_LIKELY (inexact != MPFR_EVEN_INEX * MPFR_INT_SIGN (a)))
+ goto check_overflow;
+ }
+ /* We need to take the value preceding |a|. We can't use
+ mpfr_nexttozero due to a possible out-of-range exponent.
+ But this will allow us to have more specific code. */
+ MPFR_LOG_MSG (("correcting the value of a\n", 0));
+ sh = (mpfr_prec_t) an * GMP_NUMB_BITS - aq;
+ mpn_sub_1 (ap, ap, an, MPFR_LIMB_ONE << sh);
+ if (MPFR_UNLIKELY (MPFR_LIMB_MSB (ap[an-1]) == 0))
+ {
+ MPFR_EXP (a) --;
+ /* The following is valid whether an = 1 or an > 1. */
+ ap[an-1] |= MPFR_LIMB_HIGHBIT;
}
+ inexact = - MPFR_INT_SIGN (a);
+ check_overflow:
+ if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN (a));
+ else
+ MPFR_RET (inexact);
}
- diff_exp = (mpfr_uexp_t) MPFR_GET_EXP (b) - MPFR_GET_EXP (c);
-
/* reserve a space to store b aligned with the result, i.e. shifted by
(-cancel) % GMP_NUMB_BITS to the right */
- bn = MPFR_LIMB_SIZE (b);
+ bn = MPFR_LIMB_SIZE (b);
MPFR_UNSIGNED_MINUS_MODULO (shift_b, cancel);
cancel1 = (cancel + shift_b) / GMP_NUMB_BITS;
@@ -173,21 +210,21 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
/* reserve a space to store c aligned with the result, i.e. shifted by
- (diff_exp-cancel) % GMP_NUMB_BITS to the right */
- cn = MPFR_LIMB_SIZE(c);
- if ((UINT_MAX % GMP_NUMB_BITS) == (GMP_NUMB_BITS-1)
- && ((-(unsigned) 1)%GMP_NUMB_BITS > 0))
+ (diff_exp-cancel) % GMP_NUMB_BITS to the right */
+ cn = MPFR_LIMB_SIZE (c);
+ if (IS_POW2 (GMP_NUMB_BITS))
shift_c = ((mpfr_uexp_t) diff_exp - cancel) % GMP_NUMB_BITS;
else
{
+ /* The above operation does not work if diff_exp - cancel < 0. */
shift_c = diff_exp - (cancel % GMP_NUMB_BITS);
shift_c = (shift_c + GMP_NUMB_BITS) % GMP_NUMB_BITS;
}
- MPFR_ASSERTD( shift_c >= 0 && shift_c < GMP_NUMB_BITS);
+ MPFR_ASSERTD (shift_c >= 0 && shift_c < GMP_NUMB_BITS);
if (MPFR_UNLIKELY(shift_c == 0))
{
- cp = MPFR_MANT(c);
+ cp = MPFR_MANT(c);
/* Ensure ap != cp */
if (ap == cp)
{
@@ -201,10 +238,10 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
cp[0] = mpn_rshift (cp + 1, MPFR_MANT(c), cn++, shift_c);
}
-#ifdef DEBUG
- printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n",
- mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
- (unsigned long) diff_exp);
+#if 0
+ MPFR_LOG_MSG (("rnd=%s shift_b=%d shift_c=%d diffexp=%" MPFR_EXP_FSPEC
+ "d\n", mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
+ (mpfr_eexp_t) diff_exp));
#endif
MPFR_ASSERTD (ap != cp);
@@ -222,7 +259,7 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
by the multiplication code), then the computation of cancel2 could
be simplified to
cancel2 = (cancel - (diff_exp - shift_c)) / GMP_NUMB_BITS;
- because cancel, diff_exp and shift_c are all non-negative and
+ because cancel, diff_exp and shift_c are all nonnegative and
these variables are signed. */
MPFR_ASSERTD (cancel >= 0);
@@ -234,9 +271,9 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
cancel2 = - (mp_size_t) ((diff_exp - cancel) / GMP_NUMB_BITS);
/* the high cancel2 limbs from b should not be taken into account */
-#ifdef DEBUG
- printf ("cancel=%lu cancel1=%lu cancel2=%ld\n",
- (unsigned long) cancel, (unsigned long) cancel1, (long) cancel2);
+#if 0
+ MPFR_LOG_MSG (("cancel=%Pd cancel1=%Pd cancel2=%Pd\n",
+ cancel, cancel1, cancel2));
#endif
/* ap[an-1] ap[0]
@@ -273,10 +310,6 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
MPN_ZERO (ap, an);
-#ifdef DEBUG
- printf("after copying high(b), a="); mpfr_print_binary(a); putchar('\n');
-#endif
-
/* subtract high(c) */
if (MPFR_LIKELY(an + cancel2 > 0)) /* otherwise c does not overlap with a */
{
@@ -318,19 +351,19 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
}
-#ifdef DEBUG
- printf("after subtracting high(c), a=");
- mpfr_print_binary(a);
- putchar('\n');
-#endif
-
/* now perform rounding */
- sh = (mpfr_prec_t) an * GMP_NUMB_BITS - MPFR_PREC(a);
+ sh = (mpfr_prec_t) an * GMP_NUMB_BITS - aq;
/* last unused bits from a */
carry = ap[0] & MPFR_LIMB_MASK (sh);
ap[0] -= carry;
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ if (rnd_mode == MPFR_RNDF)
+ {
+ inexact = 0;
+ /* truncating is always correct since -1 ulp < low(b) - low(c) < 1 ulp */
+ goto truncate;
+ }
+ else if (rnd_mode == MPFR_RNDN)
{
if (MPFR_LIKELY(sh))
{
@@ -371,9 +404,9 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
cn0 = cn;
cn -= an + cancel2;
-#ifdef DEBUG
- printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n",
- sh, (unsigned long) carry, (long) bn, (long) cn);
+#if 0
+ MPFR_LOG_MSG (("last sh=%d bits from a are %Mu, bn=%Pd, cn=%Pd\n",
+ sh, carry, (mpfr_prec_t) bn, (mpfr_prec_t) cn));
#endif
/* for rounding to nearest, we couldn't conclude up to here in the following
@@ -464,10 +497,10 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
}
-#ifdef DEBUG
- printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k,
- (unsigned long) bb, (unsigned long) cc, cmp_low);
+#if 0
+ MPFR_LOG_MSG (("k=%d bb=%Mu cc=%Mu cmp_low=%d\n", k, bb, cc, cmp_low));
#endif
+
if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract
one ulp */
{
@@ -619,42 +652,49 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* we have to set MPFR_EXP(a) to MPFR_EXP(b) - cancel + add_exp, taking
care of underflows/overflows in that computation, and of the allowed
exponent range */
+ MPFR_TMP_FREE (marker);
if (MPFR_LIKELY(cancel))
{
- mpfr_exp_t exp_a;
-
cancel -= add_exp; /* OK: add_exp is an int equal to 0 or 1 */
- exp_a = MPFR_GET_EXP (b) - cancel;
- if (MPFR_UNLIKELY(exp_a < __gmpfr_emin))
+ exp_a = exp_b - cancel;
+ /* The following assertion corresponds to a limitation of the MPFR
+ implementation. It may fail with a 32-bit ABI and huge precisions,
+ but this is practically impossible with a 64-bit ABI. This kind
+ of issue is not specific to this function. */
+ MPFR_ASSERTN (exp_b != MPFR_EXP_MAX || exp_a > __gmpfr_emax);
+ if (MPFR_UNLIKELY (exp_a < __gmpfr_emin))
{
- MPFR_TMP_FREE(marker);
+ underflow:
if (rnd_mode == MPFR_RNDN &&
(exp_a < __gmpfr_emin - 1 ||
(inexact >= 0 && mpfr_powerof2_raw (a))))
rnd_mode = MPFR_RNDZ;
return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
}
- MPFR_SET_EXP (a, exp_a);
+ if (MPFR_UNLIKELY (exp_a > __gmpfr_emax))
+ {
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN (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 */
- mpfr_exp_t exp_b;
-
- exp_b = MPFR_GET_EXP (b);
- if (MPFR_UNLIKELY(add_exp && exp_b == __gmpfr_emax))
+ MPFR_ASSERTD (add_exp == 0 || add_exp == 1);
+ /* Overflow iff exp_b + add_exp > __gmpfr_emax in Z, but we do
+ a subtraction below to avoid a potential integer overflow in
+ the case exp_b == MPFR_EXP_MAX. */
+ if (MPFR_UNLIKELY (exp_b > __gmpfr_emax - add_exp))
{
- MPFR_TMP_FREE(marker);
- return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN (a));
}
- MPFR_SET_EXP (a, exp_b + add_exp);
+ exp_a = exp_b + add_exp;
+ if (MPFR_UNLIKELY (exp_a < __gmpfr_emin))
+ goto underflow;
}
- MPFR_TMP_FREE(marker);
-#ifdef DEBUG
- printf ("result is a="); mpfr_print_binary(a); putchar('\n');
-#endif
+ MPFR_SET_EXP (a, exp_a);
/* check that result is msb-normalized */
MPFR_ASSERTD(ap[an-1] > ~ap[an-1]);
MPFR_RET (inexact * MPFR_INT_SIGN (a));
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sub1sp.c b/Build/source/libs/mpfr/mpfr-src/src/sub1sp.c
index 67d597677bb..bc776ee1b55 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sub1sp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sub1sp.c
@@ -1,4 +1,4 @@
-/* mpfr_sub1sp -- internal function to perform a "real" substraction
+/* mpfr_sub1sp -- internal function to perform a "real" subtraction
All the op must have the same precision
Copyright 2003-2017 Free Software Foundation, Inc.
@@ -25,15 +25,20 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
/* Check if we have to check the result of mpfr_sub1sp with mpfr_sub1 */
-#ifdef MPFR_WANT_ASSERT
-# if MPFR_WANT_ASSERT >= 2
+#if MPFR_WANT_ASSERT >= 2
-int mpfr_sub1sp2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode);
+int mpfr_sub1sp_ref (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
int mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
mpfr_t tmpa, tmpb, tmpc;
+ mpfr_flags_t old_flags, flags, flags2;
int inexb, inexc, inexact, inexact2;
+ if (rnd_mode == MPFR_RNDF)
+ return mpfr_sub1sp_ref (a, b, c, rnd_mode);
+
+ old_flags = __gmpfr_flags;
+
mpfr_init2 (tmpa, MPFR_PREC (a));
mpfr_init2 (tmpb, MPFR_PREC (b));
mpfr_init2 (tmpc, MPFR_PREC (c));
@@ -44,40 +49,993 @@ int mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
inexc = mpfr_set (tmpc, c, MPFR_RNDN);
MPFR_ASSERTN (inexc == 0);
+ MPFR_ASSERTN (__gmpfr_flags == old_flags);
+
inexact2 = mpfr_sub1 (tmpa, tmpb, tmpc, rnd_mode);
- inexact = mpfr_sub1sp2(a, b, c, rnd_mode);
+ flags2 = __gmpfr_flags;
- if (mpfr_cmp (tmpa, a) || inexact != inexact2)
+ __gmpfr_flags = old_flags;
+ inexact = mpfr_sub1sp_ref (a, b, c, rnd_mode);
+ flags = __gmpfr_flags;
+
+ if (! mpfr_equal_p (tmpa, a) || inexact != inexact2 || flags != flags2)
{
fprintf (stderr, "sub1 & sub1sp return different values for %s\n"
"Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
- mpfr_print_rnd_mode (rnd_mode), (unsigned long) MPFR_PREC (a),
- (unsigned long) MPFR_PREC (b), (unsigned long) MPFR_PREC (c));
- mpfr_fprint_binary (stderr, tmpb);
- fprintf (stderr, "\nC = ");
- mpfr_fprint_binary (stderr, tmpc);
- fprintf (stderr, "\nSub1 : ");
- mpfr_fprint_binary (stderr, tmpa);
- fprintf (stderr, "\nSub1sp: ");
- mpfr_fprint_binary (stderr, a);
- fprintf (stderr, "\nInexact sp = %d | Inexact = %d\n",
- inexact, inexact2);
+ mpfr_print_rnd_mode (rnd_mode),
+ (unsigned long) MPFR_PREC (a),
+ (unsigned long) MPFR_PREC (b),
+ (unsigned long) MPFR_PREC (c));
+ mpfr_fdump (stderr, tmpb);
+ fprintf (stderr, "C = ");
+ mpfr_fdump (stderr, tmpc);
+ fprintf (stderr, "sub1 : ");
+ mpfr_fdump (stderr, tmpa);
+ fprintf (stderr, "sub1sp: ");
+ mpfr_fdump (stderr, a);
+ fprintf (stderr, "Inexact sp = %d | Inexact = %d\n"
+ "Flags sp = %u | Flags = %u\n",
+ inexact, inexact2, flags, flags2);
MPFR_ASSERTN (0);
}
mpfr_clears (tmpa, tmpb, tmpc, (mpfr_ptr) 0);
return inexact;
}
-# define mpfr_sub1sp mpfr_sub1sp2
-# endif
-#endif
+# define mpfr_sub1sp mpfr_sub1sp_ref
+#endif /* MPFR_WANT_ASSERT >= 2 */
+
+#if !defined(MPFR_GENERIC_ABI)
+
+/* special code for p < GMP_NUMB_BITS */
+static int
+mpfr_sub1sp1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t cnt, INITIALIZED(sh);
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t a0;
+ mp_limb_t mask;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(p < GMP_NUMB_BITS);
+
+ if (bx == cx)
+ {
+ a0 = bp[0] - cp[0];
+ if (a0 == 0) /* result is zero */
+ {
+ if (rnd_mode == MPFR_RNDD)
+ MPFR_SET_NEG(a);
+ else
+ MPFR_SET_POS(a);
+ MPFR_SET_ZERO(a);
+ MPFR_RET (0);
+ }
+ else if (a0 > bp[0]) /* borrow: |c| > |b| */
+ {
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ a0 = -a0;
+ }
+ else /* bp[0] > cp[0] */
+ MPFR_SET_SAME_SIGN (a, b);
+
+ /* now a0 != 0 */
+ MPFR_ASSERTD(a0 != 0);
+ count_leading_zeros (cnt, a0);
+ ap[0] = a0 << cnt;
+ bx -= cnt;
+ rb = sb = 0;
+ /* Note: sh is not initialized, but will not be used in this case. */
+ }
+ else if (bx > cx)
+ {
+ MPFR_SET_SAME_SIGN (a, b);
+ BGreater1:
+ d = (mpfr_uexp_t) bx - cx;
+ sh = GMP_NUMB_BITS - p;
+ mask = MPFR_LIMB_MASK(sh);
+ if (d < GMP_NUMB_BITS)
+ {
+ sb = - (cp[0] << (GMP_NUMB_BITS - d)); /* neglected part of -c */
+ /* Note that "a0 = bp[0] - (cp[0] >> d) - (sb != 0);" is faster
+ on some other machines and has no immediate dependencies for
+ the first subtraction. In the future, make sure that the code
+ is recognized as a *single* subtraction with borrow and/or use
+ a builtin when available (currently provided by Clang, but not
+ by GCC); create a new macro for that. See the TODO later.
+ Note also that with Clang, the constant 0 for the first
+ subtraction instead of a variable breaks the optimization:
+ https://llvm.org/bugs/show_bug.cgi?id=31754 */
+ a0 = bp[0] - (sb != 0) - (cp[0] >> d);
+ /* a0 cannot be zero here since:
+ a) if d >= 2, then a0 >= 2^(w-1) - (2^(w-2)-1) with
+ w = GMP_NUMB_BITS, thus a0 - 1 >= 2^(w-2),
+ b) if d = 1, then since p < GMP_NUMB_BITS we have sb=0.
+ */
+ MPFR_ASSERTD(a0 > 0);
+ count_leading_zeros (cnt, a0);
+ if (cnt)
+ a0 = (a0 << cnt) | (sb >> (GMP_NUMB_BITS - cnt));
+ sb <<= cnt;
+ bx -= cnt;
+ /* sh > 0 since p < GMP_NUMB_BITS */
+ MPFR_ASSERTD(sh > 0);
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else /* d >= GMP_NUMB_BITS */
+ {
+ if (bp[0] > MPFR_LIMB_HIGHBIT)
+ {
+ /* We compute b - ulp(b), and the remainder ulp(b) - c satisfies:
+ 1/2 ulp(b) < ulp(b) - c < ulp(b), thus rb = sb = 1. */
+ ap[0] = bp[0] - (MPFR_LIMB_ONE << sh);
+ rb = 1;
+ }
+ else
+ {
+ /* Warning: since we have an exponent decrease, when
+ p = GMP_NUMB_BITS - 1 and d = GMP_NUMB_BITS, the round bit
+ corresponds to the upper bit of -c. In that case rb = 0 and
+ sb = 1, except when c0 = MPFR_LIMB_HIGHBIT where rb = 1 and
+ sb = 0. */
+ rb = sh > 1 || d > GMP_NUMB_BITS || cp[0] == MPFR_LIMB_HIGHBIT;
+ /* sb=1 below is incorrect when p = GMP_NUMB_BITS - 1,
+ d = GMP_NUMB_BITS and c0 = MPFR_LIMB_HIGHBIT, but in
+ that case the even rule wound round up too. */
+ ap[0] = ~mask;
+ bx --;
+ /* Warning: if d = GMP_NUMB_BITS and c0 = 1000...000, then
+ b0 - c0 = |0111...111|1000...000|, which after the shift
+ becomes |111...111|000...000| thus if p = GMP_NUMB_BITS-1
+ we have rb = 1 but sb = 0. However in this case the round
+ even rule will round up, which is what we get with sb = 1:
+ the final result will be correct, while sb is incorrect. */
+ }
+ sb = 1;
+ }
+ }
+ else /* cx > bx */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ goto BGreater1;
+ }
+
+ /* now perform rounding */
+
+ /* Warning: MPFR considers underflow *after* rounding with an unbounded
+ exponent range. However since b and c have same precision p, they are
+ multiples of 2^(emin-p), likewise for b-c. Thus if bx < emin, the
+ subtraction (with an unbounded exponent range) is exact, so that bx is
+ also the exponent after rounding with an unbounded exponent range. */
+ if (MPFR_UNLIKELY(bx < __gmpfr_emin))
+ {
+ /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either bx < emin - 1
+ (b) or bx = emin - 1 and ap[0] = 1000....000 (in this case necessarily
+ rb = sb = 0 since b-c is multiple of 2^(emin-p) */
+ if (rnd_mode == MPFR_RNDN &&
+ (bx < __gmpfr_emin - 1 || ap[0] == MPFR_LIMB_HIGHBIT))
+ {
+ MPFR_ASSERTD(rb == 0 && sb == 0);
+ rnd_mode = MPFR_RNDZ;
+ }
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET (0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ if (MPFR_UNLIKELY(ap[0] == 0))
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ /* Note: bx+1 cannot exceed __gmpfr_emax, since |a| <= |b|, thus
+ bx+1 is at most equal to the original exponent of b. */
+ MPFR_ASSERTD(bx + 1 <= __gmpfr_emax);
+ MPFR_SET_EXP (a, bx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* special code for p = GMP_NUMB_BITS */
+static int
+mpfr_sub1sp1n (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t cnt;
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t a0;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(MPFR_PREC(a) == GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC(b) == GMP_NUMB_BITS);
+ MPFR_ASSERTD(MPFR_PREC(c) == GMP_NUMB_BITS);
+
+ if (bx == cx)
+ {
+ a0 = bp[0] - cp[0];
+ if (a0 == 0) /* result is zero */
+ {
+ if (rnd_mode == MPFR_RNDD)
+ MPFR_SET_NEG(a);
+ else
+ MPFR_SET_POS(a);
+ MPFR_SET_ZERO(a);
+ MPFR_RET (0);
+ }
+ else if (a0 > bp[0]) /* borrow: |c| > |b| */
+ {
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ a0 = -a0;
+ }
+ else /* bp[0] > cp[0] */
+ MPFR_SET_SAME_SIGN (a, b);
+
+ /* now a0 != 0 */
+ MPFR_ASSERTD(a0 != 0);
+ count_leading_zeros (cnt, a0);
+ ap[0] = a0 << cnt;
+ bx -= cnt;
+ rb = sb = 0;
+ }
+ else if (bx > cx)
+ {
+ MPFR_SET_SAME_SIGN (a, b);
+ BGreater1:
+ d = (mpfr_uexp_t) bx - cx;
+ if (d < GMP_NUMB_BITS)
+ {
+ sb = - (cp[0] << (GMP_NUMB_BITS - d)); /* neglected part of -c */
+ a0 = bp[0] - (sb != 0) - (cp[0] >> d);
+ /* a0 can only be zero when d=1, b0 = B/2, and c0 = B-1, where
+ B = 2^GMP_NUMB_BITS, thus b0 - c0/2 = 1/2 */
+ if (a0 == MPFR_LIMB_ZERO)
+ {
+ bx -= GMP_NUMB_BITS;
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ rb = sb = 0;
+ }
+ else
+ {
+ count_leading_zeros (cnt, a0);
+ if (cnt)
+ a0 = (a0 << cnt) | (sb >> (GMP_NUMB_BITS - cnt));
+ sb <<= cnt;
+ bx -= cnt;
+ rb = sb & MPFR_LIMB_HIGHBIT;
+ sb &= ~MPFR_LIMB_HIGHBIT;
+ ap[0] = a0;
+ }
+ }
+ else /* d >= GMP_NUMB_BITS */
+ {
+ /* We compute b - ulp(b) */
+ if (bp[0] > MPFR_LIMB_HIGHBIT)
+ {
+ /* If d = GMP_NUMB_BITS, rb = 0 and sb = 1,
+ unless c0 = MPFR_LIMB_HIGHBIT in which case rb = 1 and sb = 0.
+ If d > GMP_NUMB_BITS, rb = sb = 1. */
+ rb = d > GMP_NUMB_BITS || cp[0] == MPFR_LIMB_HIGHBIT;
+ sb = d > GMP_NUMB_BITS || cp[0] != MPFR_LIMB_HIGHBIT;
+ ap[0] = bp[0] - MPFR_LIMB_ONE;
+ }
+ else
+ {
+ /* Warning: in this case a0 is shifted by one!
+ If d=GMP_NUMB_BITS:
+ (a) if c0 = MPFR_LIMB_HIGHBIT, a0 = 111...111, rb = sb = 0
+ (b) otherwise, a0 = 111...110, rb = -c0 >= 01000...000,
+ sb = (-c0) << 2
+ If d=GMP_NUMB_BITS+1: a0 = 111...111
+ (c) if c0 = MPFR_LIMB_HIGHBIT, rb = 1 and sb = 0
+ (d) otherwise rb = 0 and sb = 1
+ If d > GMP_NUMB_BITS+1:
+ (e) a0 = 111...111, rb = sb = 1
+ */
+ bx --;
+ if (d == GMP_NUMB_BITS && cp[0] > MPFR_LIMB_HIGHBIT)
+ { /* case (b) */
+ rb = (-cp[0]) >= (MPFR_LIMB_HIGHBIT >> 1);
+ sb = (-cp[0]) << 2;
+ ap[0] = -(MPFR_LIMB_ONE << 1);
+ }
+ else /* cases (a), (c), (d) and (e) */
+ {
+ ap[0] = -MPFR_LIMB_ONE;
+ /* rb=1 in case (e) and case (c) */
+ rb = d > GMP_NUMB_BITS + 1
+ || (d == GMP_NUMB_BITS + 1 && cp[0] == MPFR_LIMB_HIGHBIT);
+ /* sb = 1 in case (d) and (e) */
+ sb = d > GMP_NUMB_BITS + 1
+ || (d == GMP_NUMB_BITS + 1 && cp[0] > MPFR_LIMB_HIGHBIT);
+ }
+ }
+ }
+ }
+ else /* cx > bx */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ goto BGreater1;
+ }
+
+ /* now perform rounding */
+
+ /* Warning: MPFR considers underflow *after* rounding with an unbounded
+ exponent range. However since b and c have same precision p, they are
+ multiples of 2^(emin-p), likewise for b-c. Thus if bx < emin, the
+ subtraction (with an unbounded exponent range) is exact, so that bx is
+ also the exponent after rounding with an unbounded exponent range. */
+ if (MPFR_UNLIKELY(bx < __gmpfr_emin))
+ {
+ /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
+ we have to change to RNDZ. This corresponds to:
+ (a) either bx < emin - 1
+ (b) or bx = emin - 1 and ap[0] = 1000....000 (in this case necessarily
+ rb = sb = 0 since b-c is multiple of 2^(emin-p) */
+ if (rnd_mode == MPFR_RNDN &&
+ (bx < __gmpfr_emin - 1 || ap[0] == MPFR_LIMB_HIGHBIT))
+ {
+ MPFR_ASSERTD(rb == 0 && sb == 0);
+ rnd_mode = MPFR_RNDZ;
+ }
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
-/* Debugging support */
-#ifdef DEBUG
-# undef DEBUG
-# define DEBUG(x) (x)
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET (0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & MPFR_LIMB_ONE) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE;
+ if (MPFR_UNLIKELY(ap[0] == 0))
+ {
+ ap[0] = MPFR_LIMB_HIGHBIT;
+ /* Note: bx+1 cannot exceed __gmpfr_emax, since |a| <= |b|, thus
+ bx+1 is at most equal to the original exponent of b. */
+ MPFR_ASSERTD(bx + 1 <= __gmpfr_emax);
+ MPFR_SET_EXP (a, bx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* special code for GMP_NUMB_BITS < p < 2*GMP_NUMB_BITS */
+static int
+mpfr_sub1sp2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t cnt, INITIALIZED(sh);
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t mask, a0, a1;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(GMP_NUMB_BITS < p && p < 2 * GMP_NUMB_BITS);
+
+ if (bx == cx) /* subtraction is exact in this case */
+ {
+ /* first compute a0: if the compiler is smart enough, it will use the generated
+ borrow to get for free the term (bp[0] < cp[0]) */
+ a0 = bp[0] - cp[0];
+ a1 = bp[1] - cp[1] - (bp[0] < cp[0]);
+ if (a1 == 0 && a0 == 0) /* result is zero */
+ {
+ if (rnd_mode == MPFR_RNDD)
+ MPFR_SET_NEG(a);
+ else
+ MPFR_SET_POS(a);
+ MPFR_SET_ZERO(a);
+ MPFR_RET (0);
+ }
+ else if (a1 >= bp[1]) /* borrow: |c| > |b| */
+ {
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ /* a = b-c mod 2^(2*GMP_NUMB_BITS) */
+ a0 = -a0;
+ a1 = -a1 - (a0 != 0);
+ }
+ else /* bp[0] > cp[0] */
+ MPFR_SET_SAME_SIGN (a, b);
+
+ if (a1 == 0)
+ {
+ a1 = a0;
+ a0 = 0;
+ bx -= GMP_NUMB_BITS;
+ }
+
+ /* now a1 != 0 */
+ MPFR_ASSERTD(a1 != 0);
+ count_leading_zeros (cnt, a1);
+ if (cnt)
+ {
+ ap[1] = (a1 << cnt) | (a0 >> (GMP_NUMB_BITS - cnt));
+ ap[0] = a0 << cnt;
+ bx -= cnt;
+ }
+ else
+ {
+ ap[1] = a1;
+ ap[0] = a0;
+ }
+ rb = sb = 0;
+ /* Note: sh is not initialized, but will not be used in this case. */
+ }
+ else if (bx > cx)
+ {
+ mp_limb_t t;
+
+ MPFR_SET_SAME_SIGN (a, b);
+ BGreater2:
+ d = (mpfr_uexp_t) bx - cx;
+ sh = 2 * GMP_NUMB_BITS - p;
+ mask = MPFR_LIMB_MASK(sh);
+ if (d < GMP_NUMB_BITS)
+ {
+ t = (cp[1] << (GMP_NUMB_BITS - d)) | (cp[0] >> d);
+ /* TODO: Change the code to generate a full subtraction with borrow,
+ avoiding the test on sb and the corresponding correction. Note
+ that Clang has builtins:
+ http://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
+ but the generated code may not be good:
+ https://llvm.org/bugs/show_bug.cgi?id=20748
+ With the current source code, Clang generates on x86_64:
+ 1. sub %rsi,%rbx for the first subtraction in a1;
+ 2. sub %rdi,%rax for the subtraction in a0;
+ 3. sbb $0x0,%rbx for the second subtraction in a1, i.e. just
+ subtracting the borrow out from (2).
+ So, Clang recognizes the borrow, but doesn't merge (1) and (3).
+ Bug: https://llvm.org/bugs/show_bug.cgi?id=25858
+ For GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79173
+ */
+#ifndef MPFR_FULLSUB
+ a0 = bp[0] - t;
+ a1 = bp[1] - (cp[1] >> d) - (bp[0] < t);
+ sb = cp[0] << (GMP_NUMB_BITS - d); /* neglected part of c */
+ if (sb)
+ {
+ a1 -= (a0 == 0);
+ a0 --;
+ /* a = a1,a0 cannot become zero here, since:
+ a) if d >= 2, then a1 >= 2^(w-1) - (2^(w-2)-1) with
+ w = GMP_NUMB_BITS, thus a1 - 1 >= 2^(w-2),
+ b) if d = 1, then since p < 2*GMP_NUMB_BITS we have sb=0. */
+ MPFR_ASSERTD(a1 > 0 || a0 > 0);
+ sb = -sb; /* 2^GMP_NUMB_BITS - sb */
+ }
#else
-# define DEBUG(x) /**/
+ sb = - (cp[0] << (GMP_NUMB_BITS - d));
+ a0 = bp[0] - t - (sb != 0);
+ a1 = bp[1] - (cp[1] >> d) - (bp[0] < t || (bp[0] == t && sb != 0));
#endif
+ if (a1 == 0)
+ {
+ /* this implies d=1, which in turn implies sb=0 */
+ MPFR_ASSERTD(sb == 0);
+ a1 = a0;
+ a0 = 0; /* should be a0 = sb */
+ /* since sb=0 already, no need to set it to 0 */
+ bx -= GMP_NUMB_BITS;
+ }
+ /* now a1 != 0 */
+ MPFR_ASSERTD(a1 != 0);
+ count_leading_zeros (cnt, a1);
+ if (cnt)
+ {
+ ap[1] = (a1 << cnt) | (a0 >> (GMP_NUMB_BITS - cnt));
+ a0 = (a0 << cnt) | (sb >> (GMP_NUMB_BITS - cnt));
+ sb <<= cnt;
+ bx -= cnt;
+ }
+ else
+ ap[1] = a1;
+ /* sh > 0 since p < 2*GMP_NUMB_BITS */
+ MPFR_ASSERTD(sh > 0);
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else if (d < 2 * GMP_NUMB_BITS)
+ { /* GMP_NUMB_BITS <= d < 2*GMP_NUMB_BITS */
+ /* warning: the most significant bit of sb might become the least
+ significant bit of a0 below */
+ sb = (d == GMP_NUMB_BITS) ? cp[0]
+ : (cp[1] << (2*GMP_NUMB_BITS - d)) | (cp[0] != 0);
+ t = (cp[1] >> (d - GMP_NUMB_BITS)) + (sb != 0);
+ /* warning: t might overflow to 0 if d=GMP_NUMB_BITS and sb <> 0 */
+ a0 = bp[0] - t;
+ a1 = bp[1] - (bp[0] < t) - (t == 0 && sb != 0);
+ sb = -sb;
+ /* since bp[1] has its most significant bit set, we can have an
+ exponent decrease of at most one */
+ if (a1 < MPFR_LIMB_HIGHBIT)
+ {
+ ap[1] = (a1 << 1) | (a0 >> (GMP_NUMB_BITS - 1));
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ bx --;
+ }
+ else
+ ap[1] = a1;
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else /* d >= 2*GMP_NUMB_BITS */
+ {
+ /* We compute b - ulp(b), and the remainder ulp(b) - c satisfies:
+ 1/2 ulp(b) < ulp(b) - c < ulp(b), thus rb = sb = 1, unless we
+ had an exponent decrease. */
+ t = MPFR_LIMB_ONE << sh;
+ a0 = bp[0] - t;
+ a1 = bp[1] - (bp[0] < t);
+ if (a1 < MPFR_LIMB_HIGHBIT)
+ {
+ /* necessarily we had b = 1000...000 */
+ /* Warning: since we have an exponent decrease, when
+ p = 2*GMP_NUMB_BITS - 1 and d = 2*GMP_NUMB_BITS, the round bit
+ corresponds to the upper bit of -c. In that case rb = 0 and
+ sb = 1, except when c = 1000...000 where rb = 1 and sb = 0. */
+ rb = sh > 1 || d > 2 * GMP_NUMB_BITS
+ || (cp[1] == MPFR_LIMB_HIGHBIT && cp[0] == MPFR_LIMB_ZERO);
+ /* sb=1 below is incorrect when p = 2*GMP_NUMB_BITS - 1,
+ d = 2*GMP_NUMB_BITS and c = 1000...000, but in
+ that case the even rule wound round up too. */
+ ap[0] = ~mask;
+ ap[1] = MPFR_LIMB_MAX;
+ bx --;
+ }
+ else
+ {
+ ap[0] = a0;
+ ap[1] = a1;
+ rb = 1;
+ }
+ sb = 1;
+ }
+ }
+ else /* cx > bx */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ goto BGreater2;
+ }
+
+ /* now perform rounding */
+
+ /* Warning: MPFR considers underflow *after* rounding with an unbounded
+ exponent range. However since b and c have same precision p, they are
+ multiples of 2^(emin-p), likewise for b-c. Thus if bx < emin, the
+ subtraction (with an unbounded exponent range) is exact, so that bx is
+ also the exponent after rounding with an unbounded exponent range. */
+ if (MPFR_UNLIKELY(bx < __gmpfr_emin))
+ {
+ /* for RNDN, mpfr_underflow always rounds away, thus for |a|<=2^(emin-2)
+ we have to change to RNDZ */
+ if (rnd_mode == MPFR_RNDN &&
+ (bx < __gmpfr_emin - 1 ||
+ (ap[1] == MPFR_LIMB_HIGHBIT && ap[0] == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET (0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ if (MPFR_UNLIKELY(ap[1] == 0))
+ {
+ ap[1] = MPFR_LIMB_HIGHBIT;
+ /* Note: bx+1 cannot exceed __gmpfr_emax, since |a| <= |b|, thus
+ bx+1 is at most equal to the original exponent of b. */
+ MPFR_ASSERTD(bx + 1 <= __gmpfr_emax);
+ MPFR_SET_EXP (a, bx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+/* special code for 2*GMP_NUMB_BITS < p < 3*GMP_NUMB_BITS */
+static int
+mpfr_sub1sp3 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode,
+ mpfr_prec_t p)
+{
+ mpfr_exp_t bx = MPFR_GET_EXP (b);
+ mpfr_exp_t cx = MPFR_GET_EXP (c);
+ mp_limb_t *ap = MPFR_MANT(a);
+ mp_limb_t *bp = MPFR_MANT(b);
+ mp_limb_t *cp = MPFR_MANT(c);
+ mpfr_prec_t cnt, INITIALIZED(sh);
+ mp_limb_t rb; /* round bit */
+ mp_limb_t sb; /* sticky bit */
+ mp_limb_t mask, a0, a1, a2;
+ mpfr_uexp_t d;
+
+ MPFR_ASSERTD(2 * GMP_NUMB_BITS < p && p < 3 * GMP_NUMB_BITS);
+
+ if (bx == cx) /* subtraction is exact in this case */
+ {
+ a0 = bp[0] - cp[0];
+ a1 = bp[1] - cp[1] - (bp[0] < cp[0]);
+ /* a borrow is generated for a when either bp[1] < cp[1],
+ or bp[1] = cp[1] and bp[0] < cp[0] */
+ a2 = bp[2] - cp[2]
+ - (bp[1] < cp[1] || (bp[1] == cp[1] && bp[0] < cp[0]));
+ if (a2 == 0 && a1 == 0 && a0 == 0) /* result is zero */
+ {
+ if (rnd_mode == MPFR_RNDD)
+ MPFR_SET_NEG(a);
+ else
+ MPFR_SET_POS(a);
+ MPFR_SET_ZERO(a);
+ MPFR_RET (0);
+ }
+ else if (a2 >= bp[2]) /* borrow: |c| > |b| */
+ {
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ /* a = b-c mod 2^(3*GMP_NUMB_BITS) */
+ a0 = -a0;
+ a1 = -a1 - (a0 != 0);
+ a2 = -a2 - (a0 != 0 || a1 != 0);
+ }
+ else /* bp[0] > cp[0] */
+ MPFR_SET_SAME_SIGN (a, b);
+
+ if (a2 == 0)
+ {
+ a2 = a1;
+ a1 = a0;
+ a0 = 0;
+ bx -= GMP_NUMB_BITS;
+ if (a2 == 0)
+ {
+ a2 = a1;
+ a1 = 0;
+ bx -= GMP_NUMB_BITS;
+ }
+ }
+
+ /* now a2 != 0 */
+ MPFR_ASSERTD(a2 != 0);
+ count_leading_zeros (cnt, a2);
+ if (cnt)
+ {
+ ap[2] = (a2 << cnt) | (a1 >> (GMP_NUMB_BITS - cnt));
+ ap[1] = (a1 << cnt) | (a0 >> (GMP_NUMB_BITS - cnt));
+ ap[0] = a0 << cnt;
+ bx -= cnt;
+ }
+ else
+ {
+ ap[2] = a2;
+ ap[1] = a1;
+ ap[0] = a0;
+ }
+ rb = sb = 0;
+ /* Note: sh is not initialized, but will not be used in this case. */
+ }
+ else if (bx > cx)
+ {
+ MPFR_SET_SAME_SIGN (a, b);
+ BGreater2:
+ d = (mpfr_uexp_t) bx - cx;
+ sh = 3 * GMP_NUMB_BITS - p;
+ mask = MPFR_LIMB_MASK(sh);
+ if (d < GMP_NUMB_BITS)
+ {
+ mp_limb_t cy;
+ /* warning: we must have the most significant bit of sb correct
+ since it might become the round bit below */
+ sb = cp[0] << (GMP_NUMB_BITS - d); /* neglected part of c */
+ a0 = bp[0] - ((cp[1] << (GMP_NUMB_BITS - d)) | (cp[0] >> d));
+ a1 = bp[1] - ((cp[2] << (GMP_NUMB_BITS - d)) | (cp[1] >> d))
+ - (a0 > bp[0]);
+ cy = a1 > bp[1] || (a1 == bp[1] && a0 > bp[0]); /* borrow in a1 */
+ a2 = bp[2] - (cp[2] >> d) - cy;
+ /* if sb is non-zero, subtract 1 from a2, a1, a0 since we want a
+ non-negative neglected part */
+ if (sb)
+ {
+ a2 -= (a1 == 0 && a0 == 0);
+ a1 -= (a0 == 0);
+ a0 --;
+ /* a = a2,a1,a0 cannot become zero here, since:
+ a) if d >= 2, then a2 >= 2^(w-1) - (2^(w-2)-1) with
+ w = GMP_NUMB_BITS, thus a2 - 1 >= 2^(w-2),
+ b) if d = 1, then since p < 3*GMP_NUMB_BITS we have sb=0. */
+ MPFR_ASSERTD(a2 > 0 || a1 > 0 || a0 > 0);
+ sb = -sb; /* 2^GMP_NUMB_BITS - sb */
+ }
+ if (a2 == 0)
+ {
+ /* this implies d=1, which in turn implies sb=0 */
+ MPFR_ASSERTD(sb == 0);
+ a2 = a1;
+ a1 = a0;
+ a0 = 0; /* should be a0 = sb */
+ /* since sb=0 already, no need to set it to 0 */
+ bx -= GMP_NUMB_BITS;
+ if (a2 == 0)
+ {
+ a2 = a1;
+ a1 = 0; /* should be a1 = a0 */
+ bx -= GMP_NUMB_BITS;
+ }
+ }
+ /* now a1 != 0 */
+ MPFR_ASSERTD(a2 != 0);
+ count_leading_zeros (cnt, a2);
+ if (cnt)
+ {
+ ap[2] = (a2 << cnt) | (a1 >> (GMP_NUMB_BITS - cnt));
+ ap[1] = (a1 << cnt) | (a0 >> (GMP_NUMB_BITS - cnt));
+ a0 = (a0 << cnt) | (sb >> (GMP_NUMB_BITS - cnt));
+ sb <<= cnt;
+ bx -= cnt;
+ }
+ else
+ {
+ ap[2] = a2;
+ ap[1] = a1;
+ }
+ /* sh > 0 since p < 2*GMP_NUMB_BITS */
+ MPFR_ASSERTD(sh > 0);
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else if (d < 2 * GMP_NUMB_BITS)
+ {
+ mp_limb_t c0shifted;
+ /* warning: we must have the most significant bit of sb correct
+ since it might become the round bit below */
+ sb = (d == GMP_NUMB_BITS) ? cp[0]
+ : (cp[1] << (2*GMP_NUMB_BITS - d)) | (cp[0] != 0);
+ c0shifted = (d == GMP_NUMB_BITS) ? cp[1]
+ : (cp[2] << (2*GMP_NUMB_BITS-d)) | (cp[1] >> (d - GMP_NUMB_BITS));
+ a0 = bp[0] - c0shifted;
+ /* TODO: add a non-regression test for cp[2] == MPFR_LIMB_MAX,
+ d == GMP_NUMB_BITS and a0 > bp[0]. */
+ a1 = bp[1] - (cp[2] >> (d - GMP_NUMB_BITS)) - (a0 > bp[0]);
+ a2 = bp[2] - (a1 > bp[1] || (a1 == bp[1] && a0 > bp[0]));
+ /* if sb is non-zero, subtract 1 from a2, a1, a0 since we want a
+ non-negative neglected part */
+ if (sb)
+ {
+ a2 -= (a1 == 0 && a0 == 0);
+ a1 -= (a0 == 0);
+ a0 --;
+ /* a = a2,a1,a0 cannot become zero here, since:
+ a) if d >= 2, then a2 >= 2^(w-1) - (2^(w-2)-1) with
+ w = GMP_NUMB_BITS, thus a2 - 1 >= 2^(w-2),
+ b) if d = 1, then since p < 3*GMP_NUMB_BITS we have sb=0. */
+ MPFR_ASSERTD(a2 > 0 || a1 > 0 || a0 > 0);
+ sb = -sb; /* 2^GMP_NUMB_BITS - sb */
+ }
+ /* since bp[2] has its most significant bit set, we can have an
+ exponent decrease of at most one */
+ if (a2 < MPFR_LIMB_HIGHBIT)
+ {
+ ap[2] = (a2 << 1) | (a1 >> (GMP_NUMB_BITS - 1));
+ ap[1] = (a1 << 1) | (a0 >> (GMP_NUMB_BITS - 1));
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ bx --;
+ }
+ else
+ {
+ ap[2] = a2;
+ ap[1] = a1;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else if (d < 3 * GMP_NUMB_BITS) /* 2*GMP_NUMB_BITS<=d<3*GMP_NUMB_BITS */
+ {
+ MPFR_ASSERTD (2*GMP_NUMB_BITS <= d && d < 3*GMP_NUMB_BITS);
+ /* warning: we must have the most significant bit of sb correct
+ since it might become the round bit below */
+ if (d == 2 * GMP_NUMB_BITS)
+ sb = cp[1] | (cp[0] != 0);
+ else
+ sb = cp[2] << (3*GMP_NUMB_BITS - d) | (cp[1] != 0) | (cp[0] != 0);
+ sb = -sb;
+ /* TODO: add a non-regression test for cp[2] == MPFR_LIMB_MAX,
+ d == 2*GMP_NUMB_BITS and sb != 0. */
+ a0 = bp[0] - (cp[2] >> (d - 2*GMP_NUMB_BITS)) - (sb != 0);
+ a1 = bp[1] - (a0 > bp[0] || (a0 == bp[0] && sb != 0));
+ a2 = bp[2] - (a1 > bp[1]);
+ if (a2 < MPFR_LIMB_HIGHBIT)
+ {
+ ap[2] = (a2 << 1) | (a1 >> (GMP_NUMB_BITS - 1));
+ ap[1] = (a1 << 1) | (a0 >> (GMP_NUMB_BITS - 1));
+ a0 = (a0 << 1) | (sb >> (GMP_NUMB_BITS - 1));
+ sb <<= 1;
+ bx --;
+ }
+ else
+ {
+ ap[2] = a2;
+ ap[1] = a1;
+ }
+ rb = a0 & (MPFR_LIMB_ONE << (sh - 1));
+ sb |= (a0 & mask) ^ rb;
+ ap[0] = a0 & ~mask;
+ }
+ else /* d >= 3*GMP_NUMB_BITS */
+ {
+ /* We compute b - ulp(b), and the remainder ulp(b) - c satisfies:
+ 1/2 ulp(b) < ulp(b) - c < ulp(b), thus rb = sb = 1. */
+ mp_limb_t t = MPFR_LIMB_ONE << sh;
+ a0 = bp[0] - t;
+ a1 = bp[1] - (bp[0] < t);
+ a2 = bp[2] - (a1 > bp[1]);
+ if (a2 < MPFR_LIMB_HIGHBIT)
+ {
+ /* necessarily we had b = 1000...000 */
+ /* Warning: since we have an exponent decrease, when
+ p = 3*GMP_NUMB_BITS - 1 and d = 3*GMP_NUMB_BITS, the round bit
+ corresponds to the upper bit of -c. In that case rb = 0 and
+ sb = 1, except when c = 1000...000 where rb = 1 and sb = 0. */
+ rb = sh > 1 || d > 3 * GMP_NUMB_BITS
+ || (cp[2] == MPFR_LIMB_HIGHBIT && cp[1] == MPFR_LIMB_ZERO &&
+ cp[0] == MPFR_LIMB_ZERO);
+ /* sb=1 below is incorrect when p = 2*GMP_NUMB_BITS - 1,
+ d = 2*GMP_NUMB_BITS and c = 1000...000, but in
+ that case the even rule wound round up too. */
+ ap[0] = ~mask;
+ ap[1] = MPFR_LIMB_MAX;
+ ap[2] = MPFR_LIMB_MAX;
+ bx --;
+ }
+ else
+ {
+ ap[0] = a0;
+ ap[1] = a1;
+ ap[2] = a2;
+ rb = 1;
+ }
+ sb = 1;
+ }
+ }
+ else /* cx > bx */
+ {
+ mpfr_exp_t tx;
+ mp_limb_t *tp;
+ tx = bx; bx = cx; cx = tx;
+ tp = bp; bp = cp; cp = tp;
+ MPFR_SET_OPPOSITE_SIGN (a, b);
+ goto BGreater2;
+ }
+
+ /* now perform rounding */
+
+ /* Warning: MPFR considers underflow *after* rounding with an unbounded
+ exponent range. However since b and c have same precision p, they are
+ multiples of 2^(emin-p), likewise for b-c. Thus if bx < emin, the
+ subtraction (with an unbounded exponent range) is exact, so that bx is
+ also the exponent after rounding with an unbounded exponent range. */
+ if (MPFR_UNLIKELY(bx < __gmpfr_emin))
+ {
+ /* for RNDN, mpfr_underflow always rounds away, thus for |a|<=2^(emin-2)
+ we have to change to RNDZ */
+ if (rnd_mode == MPFR_RNDN &&
+ (bx < __gmpfr_emin - 1 ||
+ (ap[2] == MPFR_LIMB_HIGHBIT && ap[1] == 0 && ap[0] == 0)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+
+ MPFR_SET_EXP (a, bx);
+ if ((rb == 0 && sb == 0) || rnd_mode == MPFR_RNDF)
+ MPFR_RET (0);
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (rb == 0 || (sb == 0 && (ap[0] & (MPFR_LIMB_ONE << sh)) == 0))
+ goto truncate;
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, MPFR_IS_NEG(a)))
+ {
+ truncate:
+ MPFR_RET(-MPFR_SIGN(a));
+ }
+ else /* round away from zero */
+ {
+ add_one_ulp:
+ ap[0] += MPFR_LIMB_ONE << sh;
+ ap[1] += (ap[0] == 0);
+ ap[2] += (ap[1] == 0 && ap[0] == 0);
+ if (MPFR_UNLIKELY(ap[2] == 0))
+ {
+ ap[2] = MPFR_LIMB_HIGHBIT;
+ /* Note: bx+1 cannot exceed __gmpfr_emax, since |a| <= |b|, thus
+ bx+1 is at most equal to the original exponent of b. */
+ MPFR_ASSERTD(bx + 1 <= __gmpfr_emax);
+ MPFR_SET_EXP (a, bx + 1);
+ }
+ MPFR_RET(MPFR_SIGN(a));
+ }
+}
+
+#endif /* !defined(MPFR_GENERIC_ABI) */
/* Rounding Sub */
@@ -131,10 +1089,10 @@ int mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
*
*/
-int
+MPFR_HOT_FUNCTION_ATTR int
mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
- mpfr_exp_t bx,cx;
+ mpfr_exp_t bx, cx;
mpfr_uexp_t d;
mpfr_prec_t p, sh, cnt;
mp_size_t n;
@@ -142,34 +1100,54 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mp_limb_t limb;
int inexact;
mp_limb_t bcp,bcp1; /* Cp and C'p+1 */
- mp_limb_t bbcp = (mp_limb_t) -1, bbcp1 = (mp_limb_t) -1; /* Cp+1 and C'p+2,
+ mp_limb_t bbcp = MPFR_LIMB_MAX, bbcp1 = MPFR_LIMB_MAX; /* Cp+1 and C'p+2,
gcc claims that they might be used uninitialized. We fill them with invalid
values, which should produce a failure if so. See README.dev file. */
MPFR_TMP_DECL(marker);
- MPFR_TMP_MARK(marker);
-
MPFR_ASSERTD(MPFR_PREC(a) == MPFR_PREC(b) && MPFR_PREC(b) == MPFR_PREC(c));
MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
/* Read prec and num of limbs */
- p = MPFR_PREC (b);
- n = MPFR_PREC2LIMBS (p);
+ p = MPFR_GET_PREC (b);
+
+#if !defined(MPFR_GENERIC_ABI)
+ /* special case for p < GMP_NUMB_BITS */
+ if (p < GMP_NUMB_BITS)
+ return mpfr_sub1sp1 (a, b, c, rnd_mode, p);
+
+ /* special case for GMP_NUMB_BITS < p < 2*GMP_NUMB_BITS */
+ if (GMP_NUMB_BITS < p && p < 2 * GMP_NUMB_BITS)
+ return mpfr_sub1sp2 (a, b, c, rnd_mode, p);
+
+ /* special case for p = GMP_NUMB_BITS: we put it *after* mpfr_sub1sp2,
+ in order not to slow down mpfr_sub1sp2, which should be more frequent */
+ if (p == GMP_NUMB_BITS)
+ return mpfr_sub1sp1n (a, b, c, rnd_mode);
- /* Fast cmp of |b| and |c|*/
+ /* special case for 2*GMP_NUMB_BITS < p < 3*GMP_NUMB_BITS */
+ if (2 * GMP_NUMB_BITS < p && p < 3 * GMP_NUMB_BITS)
+ return mpfr_sub1sp3 (a, b, c, rnd_mode, p);
+#endif
+
+ n = MPFR_PREC2LIMBS (p);
+ /* Fast cmp of |b| and |c| */
bx = MPFR_GET_EXP (b);
cx = MPFR_GET_EXP (c);
- if (MPFR_UNLIKELY(bx == cx))
+
+ MPFR_TMP_MARK(marker);
+
+ if (bx == cx)
{
mp_size_t k = n - 1;
- /* Check mantissa since exponent are equals */
+ /* Check mantissa since exponents are equal */
bp = MPFR_MANT(b);
cp = MPFR_MANT(c);
- while (k>=0 && MPFR_UNLIKELY(bp[k] == cp[k]))
+ while (k >= 0 && MPFR_UNLIKELY(bp[k] == cp[k]))
k--;
- if (MPFR_UNLIKELY(k < 0))
+ if (k < 0)
/* b == c ! */
{
/* Return exact number 0 */
@@ -184,11 +1162,11 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
goto BGreater;
else
{
- MPFR_ASSERTD(bp[k]<cp[k]);
+ MPFR_ASSERTD(bp[k] < cp[k]);
goto CGreater;
}
}
- else if (MPFR_UNLIKELY(bx < cx))
+ else if (bx < cx)
{
/* Swap b and c and set sign */
mpfr_srcptr t;
@@ -200,19 +1178,19 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
else
{
- /* b > c */
+ /* |b| > |c| */
BGreater:
MPFR_SET_SAME_SIGN(a,b);
}
- /* Now b > c */
+ /* Now |b| > |c| */
MPFR_ASSERTD(bx >= cx);
d = (mpfr_uexp_t) bx - cx;
- DEBUG (printf ("New with diff=%lu\n", (unsigned long) d));
+ /* printf ("New with diff=%lu\n", (unsigned long) d); */
- if (MPFR_UNLIKELY(d <= 1))
+ if (d <= 1)
{
- if (MPFR_LIKELY(d < 1))
+ if (d == 0)
{
/* <-- b -->
<-- c --> : exact sub */
@@ -221,7 +1199,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Normalize */
ExactNormalize:
limb = ap[n-1];
- if (MPFR_LIKELY(limb))
+ if (MPFR_LIKELY (limb != 0))
{
/* First limb is not zero. */
count_leading_zeros(cnt, limb);
@@ -231,7 +1209,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpn_lshift(ap, ap, n, cnt); /* Normalize number */
bx -= cnt; /* Update final expo */
}
- /* Last limb should be ok */
+ /* Last limb should be OK */
MPFR_ASSERTD(!(ap[0] & MPFR_LIMB_MASK((unsigned int) (-p)
% GMP_NUMB_BITS)));
}
@@ -239,8 +1217,8 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
/* First limb is zero */
mp_size_t k = n-1, len;
- /* Find the first limb not equal to zero.
- FIXME:It is assume it exists (since |b| > |c| and same prec)*/
+ /* Find the first limb not equal to zero. It necessarily exists
+ since |b| > |c|. */
do
{
MPFR_ASSERTD( k > 0 );
@@ -252,28 +1230,30 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
k++;
len = n - k; /* Number of last limb */
MPFR_ASSERTD(k >= 0);
- if (MPFR_LIKELY(cnt))
- mpn_lshift(ap+len, ap, k, cnt); /* Normalize the High Limb*/
+ if (cnt)
+ mpn_lshift (ap + len, ap, k, cnt); /* Normalize the High Limb*/
else
{
- /* Must use DECR since src and dest may overlap & dest>=src*/
- MPN_COPY_DECR(ap+len, ap, k);
+ /* Must use copyd since src and dst may overlap & dst>=src */
+ mpn_copyd (ap+len, ap, k);
}
MPN_ZERO(ap, len); /* Zeroing the last limbs */
bx -= cnt + len*GMP_NUMB_BITS; /* Update Expo */
- /* Last limb should be ok */
- MPFR_ASSERTD(!(ap[len]&MPFR_LIMB_MASK((unsigned int) (-p)
- % GMP_NUMB_BITS)));
+ /* Last limb should be OK */
+ MPFR_ASSERTD(!(ap[len] & MPFR_LIMB_MASK((unsigned int) (-p)
+ % GMP_NUMB_BITS)));
}
/* Check expo underflow */
if (MPFR_UNLIKELY(bx < __gmpfr_emin))
{
MPFR_TMP_FREE(marker);
- /* inexact=0 */
- DEBUG( printf("(D==0 Underflow)\n") );
+ /* since b and c have same sign, exponent and precision, the
+ subtraction is exact */
+ /* printf("(D==0 Underflow)\n"); */
+ /* for MPFR_RNDN, mpfr_underflow always rounds away from zero,
+ thus for |a| <= 2^(emin-2) we change to RNDZ. */
if (rnd_mode == MPFR_RNDN &&
- (bx < __gmpfr_emin - 1 ||
- (/*inexact >= 0 &&*/ mpfr_powerof2_raw (a))))
+ (bx < __gmpfr_emin - 1 || mpfr_powerof2_raw (a)))
rnd_mode = MPFR_RNDZ;
return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
}
@@ -296,41 +1276,48 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
cp = MPFR_MANT(c);
k = n-1;
limb = bp[k] - cp[k]/2;
+ /* we have |b|-|c| >= limb*W^k - (2*W^k-1)/2 >= limb*W^k - W^k + 1/2
+ thus if limb > W^k/2, |b|-|c| >= 1/2*W^n.
+ Moreover if trunc(|c|) represents the first p-1 bits of |c|,
+ minus the last significant bit called c0 below, then we have
+ |b|-trunc(|c|) >= 1/2*W^n+1, thus the two mpn_sub_n calls
+ below necessarily yield a > 1/2*W^n. */
if (limb > MPFR_LIMB_HIGHBIT)
{
- /* We can't lose precision: compute b-c/2 */
+ /* The exponent cannot decrease: compute b-c/2 */
/* Shift c in the allocated temporary block */
SubD1NoLose:
- c0 = cp[0] & (MPFR_LIMB_ONE<<sh);
+ c0 = cp[0] & (MPFR_LIMB_ONE << sh);
+ mask = ~MPFR_LIMB_MASK(sh);
+ ap = MPFR_MANT(a);
cp = MPFR_TMP_LIMBS_ALLOC (n);
- mpn_rshift(cp, MPFR_MANT(c), n, 1);
+ /* FIXME: it might be faster to have one function shifting c by 1
+ to the right and adding with b to a, which would read c once
+ only, and avoid a temporary allocation. */
+ mpn_rshift (cp, MPFR_MANT(c), n, 1);
+ cp[0] &= mask; /* Zero last bit of c if set */
+ mpn_sub_n (ap, bp, cp, n);
+ MPFR_SET_EXP(a, bx); /* No expo overflow! */
+ MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
if (MPFR_LIKELY(c0 == 0))
{
/* Result is exact: no need of rounding! */
- ap = MPFR_MANT(a);
- mpn_sub_n (ap, bp, cp, n);
- MPFR_SET_EXP(a, bx); /* No expo overflow! */
- /* No truncate or normalize is needed */
- MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
- /* No rounding is necessary since the result is exact */
MPFR_TMP_FREE(marker);
return 0;
}
- ap = MPFR_MANT(a);
- mask = ~MPFR_LIMB_MASK(sh);
- cp[0] &= mask; /* Delete last bit of c */
- mpn_sub_n (ap, bp, cp, n);
- MPFR_SET_EXP(a, bx); /* No expo overflow! */
MPFR_ASSERTD( !(ap[0] & ~mask) ); /* Check last bits */
/* No normalize is needed */
- MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
- /* Rounding is necessary since c0 = 1*/
+ /* Rounding is necessary since c0 = 1 */
/* Cp =-1 and C'p+1=0 */
bcp = 1; bcp1 = 0;
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+
+ if (rnd_mode == MPFR_RNDF)
+ goto truncate; /* low(b) = 0 and low(c) is 0 or 1/2 ulp(b), thus
+ low(b) - low(c) = 0 or -1/2 ulp(b) */
+ else if (rnd_mode == MPFR_RNDN)
{
- /* Even Rule apply: Check Ap-1 */
- if (MPFR_LIKELY( (ap[0] & (MPFR_LIMB_ONE<<sh)) == 0) )
+ /* Even Rule apply: Check last bit of a. */
+ if (MPFR_LIKELY( (ap[0] & (MPFR_LIMB_ONE << sh)) == 0) )
goto truncate;
else
goto sub_one_ulp;
@@ -343,14 +1330,23 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
}
else if (MPFR_LIKELY(limb < MPFR_LIMB_HIGHBIT))
{
- /* We lose at least one bit of prec */
- /* Calcul of 2*b-c (Exact) */
- /* Shift b in the allocated temporary block */
+ /* |b| - |c| <= (W/2-1)*W^k + W^k-1 = 1/2*W^n - 1 */
+ /* The exponent decreases by one. */
SubD1Lose:
+ ap = MPFR_MANT(a);
+ /* Compute 2*b-c (Exact) */
+ /* Experiments with __gmpn_rsblsh_n show that it is not always
+ faster than mpn_lshift + mpn_sub_n, thus we don't enable it
+ for now (HAVE___GMPN_RSBLSH_N -> HAVE___GMPN_RSBLSH_Nxxx). */
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_RSBLSH_Nxxx)
+ /* {ap, n} = 2*{bp, n} - {cp, n} */
+ __gmpn_rsblsh_n (ap, MPFR_MANT(c), MPFR_MANT(b), n, 1);
+#else
bp = MPFR_TMP_LIMBS_ALLOC (n);
+ /* Shift b in the allocated temporary block */
mpn_lshift (bp, MPFR_MANT(b), n, 1);
- ap = MPFR_MANT(a);
mpn_sub_n (ap, bp, cp, n);
+#endif
bx--;
goto ExactNormalize;
}
@@ -363,42 +1359,55 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* If k==-1 => We don't lose any bit
AND the result is 100000000000 0000000000 00000000000 */
mp_limb_t carry;
- do {
- carry = cp[k]&MPFR_LIMB_ONE;
- k--;
- } while (k>=0 &&
- bp[k]==(carry=cp[k]/2+(carry<<(GMP_NUMB_BITS-1))));
- if (MPFR_UNLIKELY(k<0))
+ do
+ {
+ carry = cp[k] << (GMP_NUMB_BITS - 1);
+ if (--k < 0)
+ break;
+ carry += cp[k] >> 1;
+ }
+ while (bp[k] == carry);
+ if (MPFR_UNLIKELY(k < 0))
{
- /*If carry then (sh==0 and Virtual c'[-1] > Virtual b[-1]) */
- if (MPFR_UNLIKELY(carry)) /* carry = cp[0]&MPFR_LIMB_ONE */
+ ap = MPFR_MANT (a);
+ if (MPFR_UNLIKELY(carry))
{
- /* FIXME: Can be faster? */
- MPFR_ASSERTD(sh == 0);
- goto SubD1Lose;
+ /* If carry then necessarily the precision is an exact
+ multiple of GMP_NUMB_BITS, and we lose one bit,
+ thus the (exact) result is a power of 2 minus 1. */
+ memset (ap, -1, n * MPFR_BYTES_PER_MP_LIMB);
+ MPFR_SET_EXP (a, bx - 1);
+ /* No underflow is possible since cx = bx-1 is a valid
+ exponent. */
}
- /* Result is a power of 2 */
- ap = MPFR_MANT (a);
- MPN_ZERO (ap, n);
- ap[n-1] = MPFR_LIMB_HIGHBIT;
- MPFR_SET_EXP (a, bx); /* No expo overflow! */
- /* No Normalize is needed*/
+ else
+ {
+ /* No carry: result is a power of 2. */
+ MPN_ZERO (ap, n - 1);
+ ap[n-1] = MPFR_LIMB_HIGHBIT;
+ MPFR_SET_EXP (a, bx); /* No expo overflow! */
+ }
+ /* No Normalize is needed */
/* No Rounding is needed */
MPFR_TMP_FREE (marker);
return 0;
}
/* carry = cp[k]/2+(cp[k-1]&1)<<(GMP_NUMB_BITS-1) = c'[k]*/
else if (bp[k] > carry)
- goto SubD1NoLose;
+ goto SubD1NoLose; /* |b|-|c| >= 1/2*W^n */
else
{
- MPFR_ASSERTD(bp[k]<carry);
- goto SubD1Lose;
+ MPFR_ASSERTD(bp[k] < carry);
+ goto SubD1Lose; /* |b|-|c| <= 1/2*W^n-1 and is exact */
}
}
}
}
- else if (MPFR_UNLIKELY(d >= p))
+ else if (MPFR_UNLIKELY(d >= p)) /* the difference of exponents is larger
+ than the precision of all operands, thus
+ the result is either b or b - 1 ulp,
+ with a possible exact result when
+ d = p, b = 2^e and c = 1/2 ulp(b) */
{
ap = MPFR_MANT(a);
MPFR_UNSIGNED_MINUS_MODULO(sh, p);
@@ -419,24 +1428,31 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
{
mp_size_t k = n-1;
- do {
+ do
k--;
- } while (k>=0 && cp[k]==0);
- bcp1 = (k>=0);
+ while (k >= 0 && cp[k] == 0);
+ bcp1 = (k >= 0);
}
else
bcp1 = 1;
}
- DEBUG( printf("(D=P) Cp=-1 Cp+1=%d C'p+1=%d \n", bbcp!=0, bcp1!=0) );
+ /* printf("(D=P) Cp=-1 Cp+1=%d C'p+1=%d \n", bbcp!=0, bcp1!=0); */
bp = MPFR_MANT (b);
- /* Even if src and dest overlap, it is ok using MPN_COPY */
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ /* Even if src and dest overlap, it is OK using MPN_COPY */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDF))
+ /* then d = p, and subtracting one ulp of b is ok even in the
+ exact case b = 2^e and c = 1/2 ulp(b) */
{
- if (MPFR_UNLIKELY( bcp && bcp1==0 ))
+ MPN_COPY(ap, bp, n);
+ goto sub_one_ulp;
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ if (MPFR_UNLIKELY (bcp != 0 && bcp1 == 0))
/* Cp=-1 and C'p+1=0: Even rule Apply! */
/* Check Ap-1 = Bp-1 */
- if ((bp[0] & (MPFR_LIMB_ONE<<sh)) == 0)
+ if ((bp[0] & (MPFR_LIMB_ONE << sh)) == 0)
{
MPN_COPY(ap, bp, n);
goto truncate;
@@ -460,7 +1476,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
/* Cp=0, Cp+1=-1 if d==p+1, C'p+1=-1 */
bcp = 0; bbcp = (d==p+1); bcp1 = 1;
- DEBUG( printf("(D>P) Cp=%d Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0) );
+ /* printf("(D>P) Cp=%d Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0); */
/* Need to compute C'p+2 if d==p+1 and if rnd_mode=NEAREST
(Because of a very improbable case) */
if (MPFR_UNLIKELY(d==p+1 && rnd_mode==MPFR_RNDN))
@@ -469,19 +1485,19 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
{
mp_size_t k = n-1;
- do {
+ do
k--;
- } while (k>=0 && cp[k]==0);
- bbcp1 = (k>=0);
+ while (k >= 0 && cp[k] == 0);
+ bbcp1 = (k >= 0);
}
else
bbcp1 = 1;
- DEBUG( printf("(D>P) C'p+2=%d\n", bbcp1!=0) );
+ /* printf("(D>P) C'p+2=%d\n", bbcp1!=0); */
}
/* Copy mantissa B in A */
MPN_COPY(ap, MPFR_MANT(b), n);
/* Round */
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ if (rnd_mode == MPFR_RNDF || rnd_mode == MPFR_RNDN)
goto truncate;
MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
if (rnd_mode == MPFR_RNDZ)
@@ -490,13 +1506,12 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
goto truncate;
}
}
- else
+ else /* case 2 <= d < p */
{
mpfr_uexp_t dm;
mp_size_t m;
mp_limb_t mask;
- /* General case: 2 <= d < p */
MPFR_UNSIGNED_MINUS_MODULO(sh, p);
cp = MPFR_TMP_LIMBS_ALLOC (n);
@@ -506,7 +1521,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
if (MPFR_UNLIKELY(dm == 0))
{
/* dm = 0 and m > 0: Just copy */
- MPFR_ASSERTD(m!=0);
+ MPFR_ASSERTD(m != 0);
MPN_COPY(cp, MPFR_MANT(c)+m, n-m);
MPN_ZERO(cp+n-m, m);
}
@@ -523,16 +1538,16 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
MPN_ZERO(cp+n-m, m);
}
- DEBUG( mpfr_print_mant_binary("Before", MPFR_MANT(c), p) );
- DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
- DEBUG( mpfr_print_mant_binary("After ", cp, p) );
+ /* mpfr_print_mant_binary("Before", MPFR_MANT(c), p); */
+ /* mpfr_print_mant_binary("B= ", MPFR_MANT(b), p); */
+ /* mpfr_print_mant_binary("After ", cp, p); */
/* Compute bcp=Cp and bcp1=C'p+1 */
if (MPFR_LIKELY(sh))
{
/* Try to compute them from C' rather than C (FIXME: Faster?) */
bcp = (cp[0] & (MPFR_LIMB_ONE<<(sh-1))) ;
- if (MPFR_LIKELY( cp[0] & MPFR_LIMB_MASK(sh-1) ))
+ if (cp[0] & MPFR_LIMB_MASK(sh-1))
bcp1 = 1;
else
{
@@ -540,7 +1555,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Start from bit x=p-d+sh in mantissa C
(+sh since we have already looked sh bits in C'!) */
mpfr_prec_t x = p-d+sh-1;
- if (MPFR_LIKELY(x>p))
+ if (x > p)
/* We are already looked at all the bits of c, so C'p+1 = 0*/
bcp1 = 0;
else
@@ -548,9 +1563,8 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mp_limb_t *tp = MPFR_MANT(c);
mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
- DEBUG (printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
- (unsigned long) x, (long) kx,
- (unsigned long) sx));
+ /* printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
+ (unsigned long) x, (long) kx, (unsigned long) sx); */
/* Looks at the last bits of limb kx (if sx=0 does nothing)*/
if (tp[kx] & MPFR_LIMB_MASK(sx))
bcp1 = 1;
@@ -558,9 +1572,9 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
{
/*kx += (sx==0);*/
/*If sx==0, tp[kx] hasn't been checked*/
- do {
+ do
kx--;
- } while (kx>=0 && tp[kx]==0);
+ while (kx >= 0 && tp[kx] == 0);
bcp1 = (kx >= 0);
}
}
@@ -582,17 +1596,17 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
else
{
/*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
- do {
+ do
kx--;
- } while (kx>=0 && tp[kx]==0);
- bcp1 = (kx>=0);
+ while (kx >= 0 && tp[kx] == 0);
+ bcp1 = (kx >= 0);
}
}
- DEBUG( printf("sh=%lu Cp=%d C'p+1=%d\n", sh, bcp!=0, bcp1!=0) );
+ /* printf("sh=%lu Cp=%d C'p+1=%d\n", sh, bcp!=0, bcp1!=0); */
/* Check if we can lose a bit, and if so compute Cp+1 and C'p+2 */
bp = MPFR_MANT(b);
- if (MPFR_UNLIKELY((bp[n-1]-cp[n-1]) <= MPFR_LIMB_HIGHBIT))
+ if (MPFR_UNLIKELY (bp[n-1] - cp[n-1] <= MPFR_LIMB_HIGHBIT))
{
/* We can lose a bit so we precompute Cp+1 and C'p+2 */
/* Test for trivial case: since C'p+1=0, Cp+1=0 and C'p+2 =0 */
@@ -608,28 +1622,28 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mp_limb_t *tp = MPFR_MANT(c);
/* Start from bit x=(p+1)-d in mantissa C */
mpfr_prec_t x = p+1-d;
- mp_size_t kx = n-1 - (x/GMP_NUMB_BITS);
- mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
+ mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS-1 - (x % GMP_NUMB_BITS);
+
MPFR_ASSERTD(p > d);
- DEBUG (printf ("(pre) x=%lu Kx=%ld Sx=%lu\n",
- (unsigned long) x, (long) kx,
- (unsigned long) sx));
+ /* printf ("(pre) x=%lu Kx=%ld Sx=%lu\n",
+ (unsigned long) x, (long) kx, (unsigned long) sx); */
bbcp = (tp[kx] & (MPFR_LIMB_ONE<<sx)) ;
/* Looks at the last bits of limb kx (If sx=0, does nothing)*/
/* If Cp+1=0, since C'p+1!=0, C'p+2=1 ! */
- if (MPFR_LIKELY(bbcp==0 || (tp[kx]&MPFR_LIMB_MASK(sx))))
+ if (MPFR_LIKELY (bbcp == 0 || (tp[kx] & MPFR_LIMB_MASK(sx))))
bbcp1 = 1;
else
{
/*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
- do {
+ do
kx--;
- } while (kx>=0 && tp[kx]==0);
- bbcp1 = (kx>=0);
- DEBUG (printf ("(Pre) Scan done for %ld\n", (long) kx));
+ while (kx >= 0 && tp[kx] == 0);
+ bbcp1 = (kx >= 0);
+ /* printf ("(Pre) Scan done for %ld\n", (long) kx); */
}
} /*End of Bcp1 != 0*/
- DEBUG( printf("(Pre) Cp+1=%d C'p+2=%d\n", bbcp!=0, bbcp1!=0) );
+ /* printf("(Pre) Cp+1=%d C'p+2=%d\n", bbcp!=0, bbcp1!=0); */
} /* End of "can lose a bit" */
/* Clean shifted C' */
@@ -639,7 +1653,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Subtract the mantissa c from b in a */
ap = MPFR_MANT(a);
mpn_sub_n (ap, bp, cp, n);
- DEBUG( mpfr_print_mant_binary("Sub= ", ap, p) );
+ /* mpfr_print_mant_binary("Sub= ", ap, p); */
/* Normalize: we lose at max one bit*/
if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
@@ -648,8 +1662,8 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Ap >= 010000xxx001 */
mpn_lshift(ap, ap, n, 1);
/* Ap >= 100000xxx010 */
- if (MPFR_UNLIKELY(bcp!=0)) /* Check if Cp = -1 */
- /* Since Cp == -1, we have to substract one more */
+ if (MPFR_UNLIKELY(bcp != 0)) /* Check if Cp = -1 */
+ /* Since Cp == -1, we have to subtract one more */
{
mpn_sub_1(ap, ap, n, MPFR_LIMB_ONE<<sh);
MPFR_ASSERTD(MPFR_LIMB_MSB(ap[n-1]) != 0);
@@ -658,21 +1672,23 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Final exponent -1 since we have shifted the mantissa */
bx--;
/* Update bcp and bcp1 */
- MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
- MPFR_ASSERTN(bbcp1 != (mp_limb_t) -1);
+ MPFR_ASSERTD(bbcp != MPFR_LIMB_MAX);
+ MPFR_ASSERTD(bbcp1 != MPFR_LIMB_MAX);
bcp = bbcp;
bcp1 = bbcp1;
- /* We dont't have anymore a valid Cp+1!
+ /* We don't have anymore a valid Cp+1!
But since Ap >= 100000xxx001, the final sub can't unnormalize!*/
}
MPFR_ASSERTD( !(ap[0] & ~mask) );
/* Rounding */
- if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDF))
+ goto truncate;
+ else if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
{
- if (MPFR_LIKELY(bcp==0))
+ if (MPFR_LIKELY(bcp == 0))
goto truncate;
- else if ((bcp1) || ((ap[0] & (MPFR_LIMB_ONE<<sh)) != 0))
+ else if (bcp1 != 0 || (ap[0] & (MPFR_LIMB_ONE << sh)) != 0)
goto sub_one_ulp;
else
goto truncate;
@@ -680,7 +1696,7 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
/* Update rounding mode */
MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
- if (rnd_mode == MPFR_RNDZ && (MPFR_LIKELY(bcp || bcp1)))
+ if (rnd_mode == MPFR_RNDZ && MPFR_LIKELY (bcp != 0 || bcp1 != 0))
goto sub_one_ulp;
goto truncate;
}
@@ -691,37 +1707,40 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
/* Result should be smaller than exact value: inexact=-1 */
inexact = -1;
- /* Check normalisation */
- if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
+ /* Check normalization */
+ if (MPFR_UNLIKELY(ap[n-1] < MPFR_LIMB_HIGHBIT))
{
/* ap was a power of 2, and we lose a bit */
/* Now it is 0111111111111111111[00000 */
- mpn_lshift(ap, ap, n, 1);
+ /* The following 2 lines are equivalent to: mpn_lshift(ap, ap, n, 1); */
+ ap[0] <<= 1;
+ ap[n-1] |= MPFR_LIMB_HIGHBIT;
bx--;
/* And the lost bit x depends on Cp+1, and Cp */
- /* Compute Cp+1 if it isn't already compute (ie d==1) */
- /* FIXME: Is this case possible? */
- if (MPFR_UNLIKELY(d == 1))
- bbcp = 0;
- DEBUG( printf("(SubOneUlp)Cp=%d, Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0));
+ /* Compute Cp+1 if it isn't already computed (ie d==1) */
+ /* Note: we can't have d = 1 here, since the only "goto sub_one_ulp"
+ for d = 1 are in the "SubD1NoLose" case, and in that case
+ |b|-|c| >= 1/2*W^n, thus round(|b|-|c|) >= 1/2*W^n, and ap[n-1]
+ cannot go below MPFR_LIMB_HIGHBIT. */
+ /* printf("(SubOneUlp)Cp=%d, Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0); */
/* Compute the last bit (Since we have shifted the mantissa)
- we need one more bit!*/
- MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
- if ( (rnd_mode == MPFR_RNDZ && bcp==0)
- || (rnd_mode==MPFR_RNDN && bbcp==0)
- || (bcp && bcp1==0) ) /*Exact result*/
+ we need one more bit! */
+ MPFR_ASSERTD(bbcp != MPFR_LIMB_MAX);
+ if ((rnd_mode == MPFR_RNDZ && bcp == 0) ||
+ (rnd_mode == MPFR_RNDN && bbcp == 0) ||
+ (bcp != 0 && bcp1 == 0)) /* Exact result */
{
- ap[0] |= MPFR_LIMB_ONE<<sh;
+ ap[0] |= MPFR_LIMB_ONE << sh;
if (rnd_mode == MPFR_RNDN)
inexact = 1;
- DEBUG( printf("(SubOneUlp) Last bit set\n") );
+ /* printf("(SubOneUlp) Last bit set\n"); */
}
/* Result could be exact if C'p+1 = 0 and rnd == Zero
since we have had one more bit to the result */
/* Fixme: rnd_mode == MPFR_RNDZ needed ? */
- if (bcp1==0 && rnd_mode==MPFR_RNDZ)
+ if (rnd_mode == MPFR_RNDZ && bcp1 == 0)
{
- DEBUG( printf("(SubOneUlp) Exact result\n") );
+ /* printf("(SubOneUlp) Exact result\n"); */
inexact = 0;
}
}
@@ -744,46 +1763,43 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
if (MPFR_UNLIKELY(ap[n-1] == MPFR_LIMB_HIGHBIT))
{
mp_size_t k = n-1;
- do {
+ do
k--;
- } while (k>=0 && ap[k]==0);
- if (MPFR_UNLIKELY(k<0))
+ while (k >= 0 && ap[k] == 0);
+ if (MPFR_UNLIKELY (k < 0))
{
/* It is a power of 2! */
/* Compute Cp+1 if it isn't already compute (ie d==1) */
- /* FIXME: Is this case possible? */
- if (d == 1)
- bbcp=0;
- DEBUG( printf("(Truncate) Cp=%d, Cp+1=%d C'p+1=%d C'p+2=%d\n", \
- bcp!=0, bbcp!=0, bcp1!=0, bbcp1!=0) );
- MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
- MPFR_ASSERTN((rnd_mode != MPFR_RNDN) || (bcp != 0) || (bbcp == 0) || (bbcp1 != (mp_limb_t) -1));
- if (((rnd_mode != MPFR_RNDZ) && bcp)
- ||
- ((rnd_mode == MPFR_RNDN) && (bcp == 0) && (bbcp) && (bbcp1)))
- {
- DEBUG( printf("(Truncate) Do sub\n") );
+ /* Note: if d=1, we have {a, n} > 1/2*W^n, thus we cannot have k < 0. */
+ /* printf("(Truncate) Cp=%d, Cp+1=%d C'p+1=%d C'p+2=%d\n",
+ bcp!=0, bbcp!=0, bcp1!=0, bbcp1!=0); */
+ MPFR_ASSERTD(bbcp != MPFR_LIMB_MAX);
+ MPFR_ASSERTD(rnd_mode != MPFR_RNDN || bcp != 0 ||
+ bbcp == 0 || bbcp1 != MPFR_LIMB_MAX);
+ if ((rnd_mode != MPFR_RNDZ && bcp != 0) ||
+ (rnd_mode == MPFR_RNDN && bcp == 0 && bbcp != 0 && bbcp1 != 0))
+ {
+ /* printf("(Truncate) Do sub\n"); */
mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
- mpn_lshift(ap, ap, n, 1);
- ap[0] |= MPFR_LIMB_ONE<<sh;
+ ap[n-1] |= MPFR_LIMB_HIGHBIT;
bx--;
/* FIXME: Explain why it works (or why not)... */
- inexact = (bcp1 == 0) ? 0 : (rnd_mode==MPFR_RNDN) ? -1 : 1;
+ inexact = (bcp1 == 0) ? 0 : (rnd_mode == MPFR_RNDN) ? -1 : 1;
goto end_of_sub;
}
}
}
/* Calcul of Inexact flag.*/
- inexact = MPFR_LIKELY(bcp || bcp1) ? 1 : 0;
+ inexact = (bcp != 0 || bcp1 != 0);
end_of_sub:
- /* Update Expo */
- /* FIXME: Is this test really useful?
+ /* Update Exponent */
+ /* bx >= emin. Proof:
If d==0 : Exact case. This is never called.
if 1 < d < p : bx=MPFR_EXP(b) or MPFR_EXP(b)-1 > MPFR_EXP(c) > emin
if d == 1 : bx=MPFR_EXP(b). If we could lose any bits, the exact
- normalisation is called.
+ normalization is called.
if d >= p : bx=MPFR_EXP(b) >= MPFR_EXP(c) + p > emin
After SubOneUlp, we could have one bit less.
if 1 < d < p : bx >= MPFR_EXP(b)-2 >= MPFR_EXP(c) > emin
@@ -791,18 +1807,6 @@ mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
if d >= p : bx >= MPFR_EXP(b)-1 > emin since p>=2.
*/
MPFR_ASSERTD( bx >= __gmpfr_emin);
- /*
- if (MPFR_UNLIKELY(bx < __gmpfr_emin))
- {
- DEBUG( printf("(Final Underflow)\n") );
- if (rnd_mode == MPFR_RNDN &&
- (bx < __gmpfr_emin - 1 ||
- (inexact >= 0 && mpfr_powerof2_raw (a))))
- rnd_mode = MPFR_RNDZ;
- MPFR_TMP_FREE(marker);
- return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
- }
- */
MPFR_SET_EXP (a, bx);
MPFR_TMP_FREE(marker);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sub_d.c b/Build/source/libs/mpfr/mpfr-src/src/sub_d.c
index fc542c2f2be..b61fefb5359 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sub_d.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sub_d.c
@@ -28,6 +28,7 @@ mpfr_sub_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
{
int inexact;
mpfr_t d;
+ mp_limb_t tmp_man[MPFR_LIMBS_PER_DOUBLE];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_LOG_FUNC
@@ -37,15 +38,14 @@ mpfr_sub_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ MPFR_TMP_INIT1(tmp_man, d, IEEE_DBL_MANT_DIG);
inexact = mpfr_set_d (d, c, rnd_mode);
- MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTD (inexact == 0);
- mpfr_clear_flags ();
+ MPFR_CLEAR_FLAGS ();
inexact = mpfr_sub (a, b, d, rnd_mode);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- mpfr_clear(d);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (a, inexact, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sub_ui.c b/Build/source/libs/mpfr/mpfr-src/src/sub_ui.c
index 63689dd5d8b..9bca863a3aa 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sub_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sub_ui.c
@@ -27,35 +27,55 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
mpfr_sub_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
{
- if (MPFR_LIKELY (u != 0)) /* if u=0, do nothing */
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%lu rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
+
+ /* (unsigned long) 0 is assumed to be a real 0 (unsigned) */
+ if (MPFR_UNLIKELY (u == 0))
+ return mpfr_set (y, x, rnd_mode);
+
+ /* This block is actually useless, but this is a minor optimization. */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
{
- mpfr_t uu;
- mp_limb_t up[1];
- unsigned long cnt;
- int inex;
-
- MPFR_SAVE_EXPO_DECL (expo);
-
- MPFR_LOG_FUNC
- (("x[%Pu]=%.*Rg u=%lu rnd=%d",
- mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
- ("y[%Pu]=%.*Rg inexact=%d",
- mpfr_get_prec(y), mpfr_log_prec, y, inex));
-
- MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
- MPFR_ASSERTN (u == (mp_limb_t) u);
- count_leading_zeros (cnt, (mp_limb_t) u);
- *up = (mp_limb_t) u << cnt;
-
- /* Optimization note: Exponent save/restore operations may be
- removed if mpfr_sub works even when uu is out-of-range. */
- MPFR_SAVE_EXPO_MARK (expo);
- MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
- inex = mpfr_sub (y, x, uu, rnd_mode);
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_check_range (y, inex, rnd_mode);
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0); /* +/-infinity is exact */
+ }
+ /* The case x being zero is handled below: we can't use mpfr_set_si
+ as the opposite of u does not necessarily fit in a long. */
}
- else
- return mpfr_set (y, x, rnd_mode);
+
+ /* Main code */
+ {
+ mpfr_t uu;
+ mp_limb_t up[1];
+ int cnt;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_STAT_STATIC_ASSERT (MPFR_LIMB_MAX >= ULONG_MAX);
+ /* So, u fits in a mp_limb_t, which justifies the casts below. */
+ MPFR_ASSERTD (u != 0);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ *up = (mp_limb_t) u << cnt;
+
+ /* Optimization note: Exponent save/restore operations may be
+ removed if mpfr_sub works even when uu is out-of-range. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ inex = mpfr_sub (y, x, uu, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd_mode);
+ }
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/subnormal.c b/Build/source/libs/mpfr/mpfr-src/src/subnormal.c
index 79ef58796f8..1b75ce8b7c8 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/subnormal.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/subnormal.c
@@ -54,7 +54,7 @@ mpfr_subnormalize (mpfr_ptr y, int old_inexact, mpfr_rnd_t rnd)
__gmpfr_emin + (mpfr_exp_t) MPFR_PREC (y) - 1)))
MPFR_RET (old_inexact);
- mpfr_set_underflow ();
+ MPFR_SET_UNDERFLOW ();
sign = MPFR_SIGN (y);
/* We have to emulate one bit rounding if EXP(y) = emin */
@@ -112,7 +112,7 @@ mpfr_subnormalize (mpfr_ptr y, int old_inexact, mpfr_rnd_t rnd)
MPFR_RET (sign);
}
}
- else /* Hard case: It is more or less the same problem than mpfr_cache */
+ else /* Hard case: It is more or less the same problem as mpfr_cache */
{
mpfr_t dest;
mpfr_prec_t q;
@@ -144,8 +144,11 @@ mpfr_subnormalize (mpfr_ptr y, int old_inexact, mpfr_rnd_t rnd)
{
if (SAME_SIGN (inexact, MPFR_INT_SIGN (y)))
mpfr_nexttozero (dest);
- else
- mpfr_nexttoinf (dest);
+ else /* subnormal range, thus no overflow */
+ {
+ mpfr_nexttoinf (dest);
+ MPFR_ASSERTD(!MPFR_IS_INF (dest));
+ }
inexact = -inexact;
}
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/sum.c b/Build/source/libs/mpfr/mpfr-src/src/sum.c
index 425ce3d7512..9d6c71da9ae 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/sum.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/sum.c
@@ -1,6 +1,6 @@
/* Sum -- efficiently sum a list of floating-point numbers
-Copyright 2004-2017 Free Software Foundation, Inc.
+Copyright 2014-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
This file is part of the GNU MPFR Library.
@@ -20,316 +20,1366 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
-/* Reference: James Demmel and Yozo Hida, Fast and accurate floating-point
- summation with application to computational geometry, Numerical Algorithms,
- volume 37, number 1-4, pages 101--112, 2004. */
-
-/* Note about the 3.1 branch and earlier: the "const" in the prototypes of
- mpfr_sum and related functions is in an incorrect position. This bug is
- present in the source only (since r3642); the MPFR manual is correct.
- This is fixed in the trunk for the future MPFR 4.0.0. Let's not change
- the 3.1 branch as it may be seen as an ABI breakage and this bug does
- not have any consequence for the API.
-*/
-
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
-/* I would really like to use "mpfr_srcptr const []" but the norm is buggy:
- it doesn't automaticaly cast a "mpfr_ptr []" to "mpfr_srcptr const []"
- if necessary. So the choice are:
- mpfr_s ** : ok
- mpfr_s *const* : ok
- mpfr_s **const : ok
- mpfr_s *const*const : ok
- const mpfr_s *const* : no
- const mpfr_s **const : no
- const mpfr_s *const*const: no
- VL: this is not a bug, but a feature. See the reason here:
- http://c-faq.com/ansi/constmismatch.html
-*/
-static void heap_sort (mpfr_srcptr *const, unsigned long, mpfr_srcptr *);
-static void count_sort (mpfr_srcptr *const, unsigned long, mpfr_srcptr *,
- mpfr_exp_t, mpfr_uexp_t);
-
-/* Either sort the tab in perm and returns 0
- Or returns 1 for +INF, -1 for -INF and 2 for NAN.
- Also set *maxprec to the maximal precision of tab[0..n-1] and of the
- initial value of *maxprec.
+/* Note: In the prototypes, one uses
+ *
+ * const mpfr_ptr *x i.e.: __mpfr_struct *const *x
+ *
+ * instead of
+ *
+ * const mpfr_srcptr *x i.e.: const __mpfr_struct *const *x
+ *
+ * because here one has a double indirection and the type matching rules
+ * from the C standard in such a case are stricter and they would yield
+ * annoying errors for the user in practice. See:
+ *
+ * Why can't I pass a char ** to a function which expects a const char **?
+ *
+ * in the comp.lang.c FAQ:
+ *
+ * http://c-faq.com/ansi/constmismatch.html
+ */
+
+/* See the doc/sum.txt file for the algorithm and a part of its proof
+(this will later go into algorithms.tex).
+
+TODO [VL, after a discussion with James Demmel]: Compared to
+ James Demmel and Yozo Hida, Fast and accurate floating-point summation
+ with application to computational geometry, Numerical Algorithms,
+ volume 37, number 1-4, pages 101--112, 2004.
+sorting is not necessary here. It is not done because in the most common
+cases (where big cancellations are rare), it would take time and be
+useless. However the lack of sorting increases the worst case complexity.
+For instance, consider many inputs that cancel one another (two by two).
+One would need n/2 iterations, where each iteration reads the exponent
+of each input, therefore n*n/2 read operations. Using a worst-case sort
+in O(n log n) could give a O(n log n) worst-case complexity. As we don't
+want to slow down the most common cases, this could be done at the 3rd
+iteration. But are there practical applications which would be used as
+tests?
+
+Note: see the following paper and its references:
+http://www.eecs.berkeley.edu/~hdnguyen/public/papers/ARITH21_Fast_Sum.pdf
+VL: This is very different:
+ In MPFR In the paper & references
+ arbitrary precision fixed precision
+ correct rounding just reproducible rounding
+ integer operations floating-point operations
+ sequencial parallel (& sequential)
*/
-int
-mpfr_sum_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm,
- mpfr_prec_t *maxprec)
+
+#ifdef MPFR_COV_CHECK
+int __gmpfr_cov_sum_tmd[MPFR_RND_MAX][2][2][3][2][2] = { 0 };
+#endif
+
+/* Update minexp (V) after detecting a potential integer overflow in
+ extreme cases (only a 32-bit ABI may be concerned in practice).
+ Instead of an assertion failure below, we could
+ 1. check that the ulp of each regular input has an exponent >= MPFR_EXP_MIN
+ (with an assertion failure if this is not the case);
+ 2. set minexp to MPFR_EXP_MIN and shift the accumulator accordingly
+ (the sum will then be exact).
+ However, such cases, which involve huge precisions, will probably
+ never occur in practice (at least with a 64-bit ABI) and are not
+ easily testable due to these huge precisions. Moreover, switching
+ to a 64-bit ABI would be a better solution for such computations.
+ So, let's leave this unimplemented. */
+#define SAFE_SUB(V,E,SH) \
+ do \
+ { \
+ mpfr_prec_t sh = (SH); \
+ MPFR_ASSERTN ((E) >= MPFR_EXP_MIN + sh); \
+ V = (E) - sh; \
+ } \
+ while (0)
+
+/* Function sum_raw
+ * ================
+ *
+ * Accumulate a new [minexp,maxexp[ block into (wp,ws). If e and err denote
+ * the exponents of the computed result and of the error bound respectively,
+ * while e - err is less than some given bound (due to cancellation), shift
+ * the accumulator and reiterate.
+ *
+ * Inputs:
+ * wp: pointer to the accumulator (least significant limb first).
+ * ws: size of the accumulator (in limbs).
+ * wq: precision of the accumulator (ws * GMP_NUMB_BITS).
+ * x: array of the input numbers.
+ * n: size of this array (number of inputs, regular or not).
+ * minexp: exponent of the least significant bit of the first block.
+ * maxexp: exponent of the first block (exponent of its MSB + 1).
+ * tp: pointer to a temporary area (pre-allocated).
+ * ts: size of this temporary area.
+ * logn: ceil(log2(rn)), where rn is the number of regular inputs.
+ * prec: lower bound for e - err (as described above).
+ * ep: pointer to mpfr_exp_t (see below), or a null pointer.
+ * minexpp: pointer to mpfr_exp_t (see below), or a null pointer.
+ * maxexpp: pointer to mpfr_exp_t (see below), or a null pointer.
+ *
+ * Preconditions:
+ * prec >= 1
+ * wq >= logn + prec + 2
+ *
+ * This function returns 0 if the accumulator is 0 (which implies that
+ * the exact sum for this sum_raw invocation is 0), otherwise the number
+ * of cancelled bits (>= 1), defined as the number of identical bits on
+ * the most significant part of the accumulator. In the latter case, it
+ * also returns the following data in variables passed by reference, if
+ * the pointers are not NULL:
+ * - in ep: the exponent e of the computed result;
+ * - in minexpp: the last value of minexp;
+ * - in maxexpp: the new value of maxexp (for the next iteration after
+ * the first invocation of sum_raw in the main code).
+ *
+ * Notes:
+ * - minexp is also the exponent of the least significant bit of the
+ * accumulator;
+ * - the temporary area must be large enough to hold a shifted input
+ * block, and the value of ts is used only when the full assertions
+ * are checked (i.e. with the --enable-assert configure option), to
+ * check that a buffer overflow doesn't occur;
+ * - contrary to the returned value of minexp (the value in the last
+ * iteration), the returned value of maxexp is the one for the next
+ * iteration (= maxexp2 of the last iteration).
+ */
+static mpfr_prec_t
+sum_raw (mp_limb_t *wp, mp_size_t ws, mpfr_prec_t wq, const mpfr_ptr *x,
+ unsigned long n, mpfr_exp_t minexp, mpfr_exp_t maxexp,
+ mp_limb_t *tp, mp_size_t ts, int logn, mpfr_prec_t prec,
+ mpfr_exp_t *ep, mpfr_exp_t *minexpp, mpfr_exp_t *maxexpp)
{
- mpfr_exp_t min, max;
- mpfr_uexp_t exp_num;
- unsigned long i;
- int sign_inf;
-
- sign_inf = 0;
- min = MPFR_EMIN_MAX;
- max = MPFR_EMAX_MIN;
- for (i = 0; i < n; i++)
+ MPFR_LOG_FUNC
+ (("ws=%Pd ts=%Pd prec=%Pd", (mpfr_prec_t) ws, (mpfr_prec_t) ts, prec),
+ ("", 0));
+
+ /* The C code below requires prec >= 0 due to the use of unsigned
+ integer arithmetic on it. Actually the computation makes sense
+ only with prec >= 1 (otherwise one can't even know the sign of
+ the result), hence the following assertion. */
+ MPFR_ASSERTD (prec >= 1);
+
+ /* Consistency check. */
+ MPFR_ASSERTD (wq == (mpfr_prec_t) ws * GMP_NUMB_BITS);
+
+ /* The following precondition together with prec >= 1 will imply:
+ minexp - shiftq < maxexp2, as required by the algorithm. */
+ MPFR_ASSERTD (wq >= logn + prec + 2);
+
+ while (1)
{
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (tab[i])))
- {
- if (MPFR_IS_NAN (tab[i]))
- return 2; /* Return NAN code */
- else if (MPFR_IS_INF (tab[i]))
+ mpfr_exp_t maxexp2 = MPFR_EXP_MIN;
+ unsigned long i;
+
+ MPFR_LOG_MSG (("sum_raw loop: "
+ "maxexp=%" MPFR_EXP_FSPEC "d "
+ "minexp=%" MPFR_EXP_FSPEC "d\n",
+ (mpfr_eexp_t) maxexp, (mpfr_eexp_t) minexp));
+
+ MPFR_ASSERTD (maxexp > minexp);
+
+ for (i = 0; i < n; i++)
+ if (! MPFR_IS_SINGULAR (x[i])) /* Step 1 (see sum_raw in sum.txt) */
+ {
+ mp_limb_t *dp, *vp;
+ mp_size_t ds, vs, vds;
+ mpfr_exp_t xe, vd;
+ mpfr_prec_t xq;
+ int tr;
+
+ xe = MPFR_GET_EXP (x[i]);
+ xq = MPFR_GET_PREC (x[i]);
+
+ vp = MPFR_MANT (x[i]);
+ vs = MPFR_PREC2LIMBS (xq);
+ vd = xe - vs * GMP_NUMB_BITS - minexp;
+ /* vd is the exponent of the least significant represented bit of
+ x[i] (including the trailing bits, whose value is 0) minus the
+ exponent of the least significant bit of the accumulator. To
+ make the code simpler, we won't try to filter out the trailing
+ bits of x[i]. */
+
+ /* Steps 2, 3, 4 (see sum_raw in sum.txt) */
+
+ if (vd < 0)
+ {
+ /* This covers the following cases:
+ * [-+- accumulator ---]
+ * [---|----- x[i] ------|--]
+ * | [----- x[i] --|--]
+ * | |[----- x[i] -----]
+ * | | [----- x[i] -----]
+ * maxexp minexp
+ */
+
+ /* Step 2 for subcase vd < 0 */
+
+ if (xe <= minexp)
+ {
+ /* x[i] is entirely after the LSB of the accumulator,
+ so that it will be ignored at this iteration. */
+ if (xe > maxexp2)
+ {
+ maxexp2 = xe;
+ /* And since the exponent of x[i] is valid... */
+ MPFR_ASSERTD (maxexp2 >= MPFR_EMIN_MIN);
+ }
+ continue;
+ }
+
+ /* Step 3 for subcase vd < 0 */
+
+ /* If some significant bits of x[i] are after the LSB of the
+ accumulator, then maxexp2 will necessarily be minexp. */
+ if (MPFR_LIKELY (xe - xq < minexp))
+ maxexp2 = minexp;
+
+ /* Step 4 for subcase vd < 0 */
+
+ /* We need to ignore the least |vd| significant bits of x[i].
+ First, let's ignore the least vds = |vd| / GMP_NUMB_BITS
+ limbs. */
+ vd = - vd;
+ vds = vd / GMP_NUMB_BITS;
+ vs -= vds;
+ MPFR_ASSERTD (vs > 0); /* see xe <= minexp test above */
+ vp += vds;
+ vd -= vds * GMP_NUMB_BITS;
+ MPFR_ASSERTD (vd >= 0 && vd < GMP_NUMB_BITS);
+
+ if (xe > maxexp)
+ {
+ vs -= (xe - maxexp) / GMP_NUMB_BITS;
+ MPFR_ASSERTD (vs > 0);
+ tr = (xe - maxexp) % GMP_NUMB_BITS;
+ }
+ else
+ tr = 0;
+
+ if (vd != 0)
+ {
+ MPFR_ASSERTD (vs <= ts);
+ mpn_rshift (tp, vp, vs, vd);
+ vp = tp;
+ tr += vd;
+ if (tr >= GMP_NUMB_BITS)
+ {
+ vs--;
+ tr -= GMP_NUMB_BITS;
+ }
+ MPFR_ASSERTD (vs >= 1);
+ MPFR_ASSERTD (tr >= 0 && tr < GMP_NUMB_BITS);
+ if (tr != 0)
+ {
+ tp[vs-1] &= MPFR_LIMB_MASK (GMP_NUMB_BITS - tr);
+ tr = 0;
+ }
+ /* Truncation has now been taken into account. */
+ MPFR_ASSERTD (tr == 0);
+ }
+
+ dp = wp;
+ ds = ws;
+ }
+ else /* vd >= 0 */
+ {
+ /* This covers the following cases:
+ * [-+- accumulator ---]
+ * [- x[i] -] | |
+ * [---|-- x[i] ------] |
+ * [------|-- x[i] ---------]
+ * | [- x[i] -] |
+ * maxexp minexp
+ */
+
+ /* Steps 2 and 3 for subcase vd >= 0 */
+
+ MPFR_ASSERTD (xe - xq >= minexp); /* see definition of vd */
+
+ /* Step 4 for subcase vd >= 0 */
+
+ /* We need to ignore the least vd significant bits
+ of the accumulator. First, let's ignore the least
+ vds = vd / GMP_NUMB_BITS limbs. -> (dp,ds) */
+ vds = vd / GMP_NUMB_BITS;
+ ds = ws - vds;
+ if (ds <= 0)
+ continue;
+ dp = wp + vds;
+ vd -= vds * GMP_NUMB_BITS;
+ MPFR_ASSERTD (vd >= 0 && vd < GMP_NUMB_BITS);
+
+ /* The low part of x[i] (to be determined) will have to be
+ shifted vd bits to the left if vd != 0. */
+
+ if (xe > maxexp)
+ {
+ vs -= (xe - maxexp) / GMP_NUMB_BITS;
+ if (vs <= 0)
+ continue;
+ tr = (xe - maxexp) % GMP_NUMB_BITS;
+ }
+ else
+ tr = 0;
+
+ MPFR_ASSERTD (tr >= 0 && tr < GMP_NUMB_BITS && vs > 0);
+
+ /* We need to consider the least significant vs limbs of x[i]
+ except the most significant tr bits. */
+
+ if (vd != 0)
+ {
+ mp_limb_t carry;
+
+ MPFR_ASSERTD (vs <= ts);
+ carry = mpn_lshift (tp, vp, vs, vd);
+ tr -= vd;
+ if (tr < 0)
+ {
+ tr += GMP_NUMB_BITS;
+ MPFR_ASSERTD (vs + 1 <= ts);
+ tp[vs++] = carry;
+ }
+ MPFR_ASSERTD (tr >= 0 && tr < GMP_NUMB_BITS);
+ vp = tp;
+ }
+ } /* vd >= 0 */
+
+ MPFR_ASSERTD (vs > 0 && vs <= ds);
+
+ /* We can't truncate the most significant limb of the input
+ (in case it hasn't been shifted to the temporary area).
+ So, let's ignore it now. It will be taken into account
+ via carry propagation after the addition. */
+ if (tr != 0)
+ vs--;
+
+ /* Step 5 (see sum_raw in sum.txt) */
+
+ if (MPFR_IS_POS (x[i]))
+ {
+ mp_limb_t carry;
+
+ carry = vs > 0 ? mpn_add_n (dp, dp, vp, vs) : 0;
+ MPFR_ASSERTD (carry <= 1);
+ if (tr != 0)
+ carry += vp[vs] & MPFR_LIMB_MASK (GMP_NUMB_BITS - tr);
+ if (ds > vs)
+ mpn_add_1 (dp + vs, dp + vs, ds - vs, carry);
+ }
+ else
+ {
+ mp_limb_t borrow;
+
+ borrow = vs > 0 ? mpn_sub_n (dp, dp, vp, vs) : 0;
+ MPFR_ASSERTD (borrow <= 1);
+ if (tr != 0)
+ borrow += vp[vs] & MPFR_LIMB_MASK (GMP_NUMB_BITS - tr);
+ if (ds > vs)
+ mpn_sub_1 (dp + vs, dp + vs, ds - vs, borrow);
+ }
+ }
+
+ {
+ mpfr_prec_t cancel; /* number of cancelled bits */
+ mp_size_t wi; /* index in the accumulator */
+ mp_limb_t a, b;
+ int cnt;
+
+ cancel = 0;
+ wi = ws - 1;
+ MPFR_ASSERTD (wi >= 0);
+ a = wp[wi] >> (GMP_NUMB_BITS - 1) ? MPFR_LIMB_MAX : MPFR_LIMB_ZERO;
+
+ while (wi >= 0)
+ if ((b = wp[wi]) == a)
{
- if (sign_inf == 0) /* No previous INF */
- sign_inf = MPFR_SIGN (tab[i]);
- else if (sign_inf != MPFR_SIGN (tab[i]))
- return 2; /* Return NAN */
+ cancel += GMP_NUMB_BITS;
+ wi--;
+ }
+ else
+ {
+ b ^= a;
+ MPFR_ASSERTD (b != 0);
+ count_leading_zeros (cnt, b);
+ cancel += cnt;
+ break;
}
- }
- else
- {
- MPFR_ASSERTD (MPFR_IS_PURE_FP (tab[i]));
- if (MPFR_GET_EXP (tab[i]) < min)
- min = MPFR_GET_EXP(tab[i]);
- if (MPFR_GET_EXP (tab[i]) > max)
- max = MPFR_GET_EXP(tab[i]);
- }
- if (MPFR_PREC (tab[i]) > *maxprec)
- *maxprec = MPFR_PREC (tab[i]);
- }
- if (MPFR_UNLIKELY (sign_inf != 0))
- return sign_inf;
- exp_num = max - min + 1;
- /* FIXME : better test */
- if (exp_num > n * MPFR_INT_CEIL_LOG2 (n))
- heap_sort (tab, n, perm);
- else
- count_sort (tab, n, perm, min, exp_num);
- return 0;
+ if (wi >= 0 || a != MPFR_LIMB_ZERO) /* accumulator != 0 */
+ {
+ mpfr_exp_t e; /* exponent of the computed result */
+ mpfr_exp_t err; /* exponent of the error bound */
+
+ MPFR_LOG_MSG (("accumulator %s 0, cancel=%Pd\n",
+ a != MPFR_LIMB_ZERO ? "<" : ">", cancel));
+
+ MPFR_ASSERTD (cancel > 0);
+ e = minexp + wq - cancel;
+ MPFR_ASSERTD (e >= minexp);
+ err = maxexp2 + logn; /* OK even if maxexp2 == MPFR_EXP_MIN */
+
+ /* The absolute value of the truncated sum is in the binade
+ [2^(e-1),2^e] (closed on both ends due to two's complement).
+ The error is strictly less than 2^err (and is 0 if
+ maxexp2 == MPFR_EXP_MIN). */
+
+ /* This basically tests whether err <= e - prec without
+ potential integer overflow (since prec >= 0)...
+ Note that the maxexp2 == MPFR_EXP_MIN test is there just for
+ the potential corner case e - prec < MPFR_EXP_MIN + logn.
+ Such corner cases, involving specific huge-precision numbers,
+ are probably not supported in many places in MPFR, but this
+ test doesn't hurt... */
+ if (maxexp2 == MPFR_EXP_MIN ||
+ (err <= e && SAFE_DIFF (mpfr_uexp_t, e, err) >= prec))
+ {
+ MPFR_LOG_MSG (("(err=%" MPFR_EXP_FSPEC "d) <= (e=%"
+ MPFR_EXP_FSPEC "d) - (prec=%Pd)\n",
+ (mpfr_eexp_t) err, (mpfr_eexp_t) e, prec));
+ /* To avoid tests or copies, we consider the only two cases
+ that will occur in sum_aux. */
+ MPFR_ASSERTD ((ep != NULL &&
+ minexpp != NULL &&
+ maxexpp != NULL) ||
+ (ep == NULL &&
+ minexpp == NULL &&
+ maxexpp == NULL));
+ if (ep != NULL)
+ {
+ *ep = e;
+ *minexpp = minexp;
+ *maxexpp = maxexp2;
+ }
+ MPFR_LOG_MSG (("return with minexp=%" MPFR_EXP_FSPEC
+ "d maxexp2=%" MPFR_EXP_FSPEC "d%s\n",
+ (mpfr_eexp_t) minexp, (mpfr_eexp_t) maxexp2,
+ maxexp2 == MPFR_EXP_MIN ?
+ " (MPFR_EXP_MIN)" : ""));
+ return cancel;
+ }
+ else
+ {
+ mpfr_exp_t diffexp;
+ mpfr_prec_t shiftq;
+ mpfr_size_t shifts;
+ int shiftc;
+
+ MPFR_LOG_MSG (("e=%" MPFR_EXP_FSPEC "d err=%" MPFR_EXP_FSPEC
+ "d maxexp2=%" MPFR_EXP_FSPEC "d%s\n",
+ (mpfr_eexp_t) e, (mpfr_eexp_t) err,
+ (mpfr_eexp_t) maxexp2,
+ maxexp2 == MPFR_EXP_MIN ?
+ " (MPFR_EXP_MIN)" : ""));
+
+ diffexp = err - e;
+ if (diffexp < 0)
+ diffexp = 0;
+ /* diffexp = max(0, err - e) */
+
+ MPFR_LOG_MSG (("diffexp=%" MPFR_EXP_FSPEC "d\n",
+ (mpfr_eexp_t) diffexp));
+
+ MPFR_ASSERTD (diffexp < cancel - 2);
+ shiftq = cancel - 2 - (mpfr_prec_t) diffexp;
+ /* equivalent to: minexp + wq - 2 - max(e,err) */
+ MPFR_ASSERTD (shiftq > 0);
+ shifts = shiftq / GMP_NUMB_BITS;
+ shiftc = shiftq % GMP_NUMB_BITS;
+ MPFR_LOG_MSG (("shiftq = %Pd = %Pd * GMP_NUMB_BITS + %d\n",
+ shiftq, (mpfr_prec_t) shifts, shiftc));
+ if (MPFR_LIKELY (shiftc != 0))
+ mpn_lshift (wp + shifts, wp, ws - shifts, shiftc);
+ else
+ mpn_copyd (wp + shifts, wp, ws - shifts);
+ MPN_ZERO (wp, shifts);
+ /* Compute minexp = minexp - shiftq safely. */
+ SAFE_SUB (minexp, minexp, shiftq);
+ MPFR_ASSERTD (minexp < maxexp2);
+ }
+ }
+ else if (maxexp2 == MPFR_EXP_MIN)
+ {
+ MPFR_LOG_MSG (("accumulator = 0, maxexp2 = MPFR_EXP_MIN\n", 0));
+ return 0;
+ }
+ else
+ {
+ MPFR_LOG_MSG (("accumulator = 0, reiterate\n", 0));
+ /* Compute minexp = maxexp2 - (wq - (logn + 1)) safely. */
+ SAFE_SUB (minexp, maxexp2, wq - (logn + 1));
+ /* Note: the logn + 1 corresponds to cq in the main code. */
+ }
+ }
+
+ maxexp = maxexp2;
+ }
}
-#define GET_EXP1(x) (MPFR_IS_ZERO (x) ? min : MPFR_GET_EXP (x))
-/* Performs a count sort of the entries */
-static void
-count_sort (mpfr_srcptr *const tab, unsigned long n,
- mpfr_srcptr *perm, mpfr_exp_t min, mpfr_uexp_t exp_num)
+/**********************************************************************/
+
+/* Generic case: all the inputs are finite numbers,
+ with at least 3 regular numbers. */
+static int
+sum_aux (mpfr_ptr sum, const mpfr_ptr *x, unsigned long n, mpfr_rnd_t rnd,
+ mpfr_exp_t maxexp, unsigned long rn)
{
- unsigned long *account;
- unsigned long target_rank, i;
- MPFR_TMP_DECL(marker);
+ mp_limb_t *sump;
+ mp_limb_t *tp; /* pointer to a temporary area */
+ mp_limb_t *wp; /* pointer to the accumulator */
+ mp_size_t ts; /* size of the temporary area, in limbs */
+ mp_size_t ws; /* size of the accumulator, in limbs */
+ mp_size_t zs; /* size of the TMD accumulator, in limbs */
+ mpfr_prec_t wq; /* size of the accumulator, in bits */
+ int logn; /* ceil(log2(rn)) */
+ int cq;
+ mpfr_prec_t sq;
+ int inex;
+ MPFR_TMP_DECL (marker);
+
+ MPFR_LOG_FUNC
+ (("n=%lu rnd=%d maxexp=%" MPFR_EXP_FSPEC "d rn=%lu",
+ n, rnd, (mpfr_eexp_t) maxexp, rn),
+ ("sum[%Pu]=%.*Rg", mpfr_get_prec (sum), mpfr_log_prec, sum));
+
+ MPFR_ASSERTD (rn >= 3 && rn <= n);
+
+ /* In practice, no integer overflow on the exponent. */
+ MPFR_STAT_STATIC_ASSERT (MPFR_EXP_MAX - MPFR_EMAX_MAX >=
+ sizeof (unsigned long) * CHAR_BIT);
+
+ /* Set up some variables and the accumulator. */
+
+ sump = MPFR_MANT (sum);
+
+ /* rn is the number of regular inputs (the singular ones will be
+ ignored). Compute logn = ceil(log2(rn)). */
+ logn = MPFR_INT_CEIL_LOG2 (rn);
+ MPFR_ASSERTD (logn >= 2);
+
+ MPFR_LOG_MSG (("logn=%d maxexp=%" MPFR_EXP_FSPEC "d\n",
+ logn, (mpfr_eexp_t) maxexp));
+
+ sq = MPFR_GET_PREC (sum);
+ cq = logn + 1;
- /* Reserve a place for potential 0 (with EXP min-1)
- If there is no zero, we only lose one unused entry */
- min--;
- exp_num++;
+ /* First determine the size of the accumulator.
+ * cq + sq + logn + 2 >= logn + sq + 5, which will be used later.
+ * The assertion wq - cq - sq >= 4 is another way to check that.
+ */
+ ws = MPFR_PREC2LIMBS (cq + sq + logn + 2);
+ wq = (mpfr_prec_t) ws * GMP_NUMB_BITS;
+ MPFR_ASSERTD (wq - cq - sq >= 4);
+
+ /* TODO: timings, comparing with a larger zs. */
+ zs = MPFR_PREC2LIMBS (wq - sq);
+
+ MPFR_LOG_MSG (("cq=%d sq=%Pd logn=%d wq=%Pd\n", cq, sq, logn, wq));
+
+ /* An input block will have up to wq - cq bits, and its shifted value
+ (to be correctly aligned) may take GMP_NUMB_BITS - 1 additional bits. */
+ ts = MPFR_PREC2LIMBS (wq - cq + GMP_NUMB_BITS - 1);
- /* Performs a counting sort of the entries */
MPFR_TMP_MARK (marker);
- account = (unsigned long *) MPFR_TMP_ALLOC (exp_num * sizeof *account);
- for (i = 0; i < exp_num; i++)
- account[i] = 0;
- for (i = 0; i < n; i++)
- account[GET_EXP1 (tab[i]) - min]++;
- for (i = exp_num - 1; i >= 1; i--)
- account[i - 1] += account[i];
- for (i = 0; i < n; i++)
- {
- target_rank = --account[GET_EXP1 (tab[i]) - min];
- perm[target_rank] = tab[i];
- }
+
+ /* Note: If the TMD does not occur, which should be the case for most
+ sums, allocating zs limbs is not necessary. However, we choose to
+ do this now (thus in all cases) because zs is very small, so that
+ the difference on the memory footprint will not be noticeable.
+ More precisely, zs is at most 2 in practice with the current code;
+ we may want to increase it in order to avoid performance issues in
+ some unlikely corner cases, but even in this case, it will remain
+ small.
+ One will have:
+ [------ ts ------][------ ws ------][- zs -]
+ The following would probably be better:
+ [------ ts ------] [------ ws ------]
+ [- zs -]
+ i.e. where the TMD accumulator (partially or completely) takes
+ some unneeded part of the temporary area in order to improve
+ data locality. But
+ * in low precision, data locality is regarded as ensured even
+ with the actual choice;
+ * in high precision, data locality for TMD resolution may not
+ be that important.
+ */
+ tp = MPFR_TMP_LIMBS_ALLOC (ts + ws + zs);
+ wp = tp + ts;
+
+ MPN_ZERO (wp, ws); /* zero the accumulator */
+
+ {
+ mpfr_exp_t minexp; /* exponent of the LSB of the block for sum_raw */
+ mpfr_prec_t cancel; /* number of cancelled bits */
+ mpfr_exp_t e; /* temporary exponent of the result */
+ mpfr_exp_t u; /* temporary exponent of the ulp (quantum) */
+ mp_limb_t lbit; /* last bit (useful if even rounding) */
+ mp_limb_t rbit; /* rounding bit (corrected in halfway case) */
+ int corr; /* correction term (from -1 to 2) */
+ int sd, sh; /* shift counts */
+ mp_size_t sn; /* size of the output number */
+ int tmd; /* 0: the TMD does not occur
+ 1: the TMD occurs on a machine number
+ 2: the TMD occurs on a midpoint */
+ int neg; /* 0 if positive sum, 1 if negative */
+ int sgn; /* +1 if positive sum, -1 if negative */
+
+ MPFR_LOG_MSG (("Compute an approximation with sum_raw...\n", 0));
+
+ /* Compute minexp = maxexp - (wq - cq) safely. */
+ SAFE_SUB (minexp, maxexp, wq - cq);
+ MPFR_ASSERTD (wq >= logn + sq + 5);
+ cancel = sum_raw (wp, ws, wq, x, n, minexp, maxexp, tp, ts,
+ logn, sq + 3, &e, &minexp, &maxexp);
+
+ if (MPFR_UNLIKELY (cancel == 0))
+ {
+ /* The exact sum is zero. Since not all inputs are 0, the sum
+ * is +0 except in MPFR_RNDD, as specified according to the
+ * IEEE 754 rules for the addition of two numbers.
+ */
+ MPFR_SET_SIGN (sum, (rnd != MPFR_RNDD ?
+ MPFR_SIGN_POS : MPFR_SIGN_NEG));
+ MPFR_SET_ZERO (sum);
+ MPFR_TMP_FREE (marker);
+ MPFR_RET (0);
+ }
+
+ /* The absolute value of the truncated sum is in the binade
+ [2^(e-1),2^e] (closed on both ends due to two's complement).
+ The error is strictly less than 2^(maxexp + logn) (and is 0
+ if maxexp == MPFR_EXP_MIN). */
+
+ u = e - sq; /* e being the exponent, u is the ulp of the target */
+
+ /* neg = 1 if negative, 0 if positive. */
+ neg = wp[ws-1] >> (GMP_NUMB_BITS - 1);
+ MPFR_ASSERTD (neg == 0 || neg == 1);
+
+ sgn = neg ? -1 : 1;
+ MPFR_ASSERTN (sgn == (neg ? MPFR_SIGN_NEG : MPFR_SIGN_POS));
+
+ MPFR_LOG_MSG (("neg=%d sgn=%d cancel=%Pd"
+ " e=%" MPFR_EXP_FSPEC "d"
+ " u=%" MPFR_EXP_FSPEC "d"
+ " maxexp=%" MPFR_EXP_FSPEC "d%s\n",
+ neg, sgn, cancel, (mpfr_eexp_t) e, (mpfr_eexp_t) u,
+ (mpfr_eexp_t) maxexp,
+ maxexp == MPFR_EXP_MIN ? " (MPFR_EXP_MIN)" : ""));
+
+ if (rnd == MPFR_RNDF)
+ {
+ /* Rounding the approximate value to nearest (ties don't matter) is
+ sufficient. We need to get the rounding bit; the code is similar
+ to a part from the generic code (here, corr = rbit). */
+ if (MPFR_LIKELY (u > minexp))
+ {
+ mpfr_prec_t tq;
+ mp_size_t wi;
+ int td;
+
+ tq = u - minexp;
+ MPFR_ASSERTD (tq > 0); /* number of trailing bits */
+ MPFR_LOG_MSG (("tq=%Pd\n", tq));
+
+ wi = tq / GMP_NUMB_BITS;
+ td = tq % GMP_NUMB_BITS;
+ corr = td >= 1 ? ((wp[wi] >> (td - 1)) & MPFR_LIMB_ONE) :
+ (MPFR_ASSERTD (wi >= 1), wp[wi-1] >> (GMP_NUMB_BITS - 1));
+ }
+ else
+ corr = 0;
+ inex = 0; /* not meaningful, but needs to have a value */
+ }
+ else /* rnd != MPFR_RNDF */
+ {
+ if (MPFR_LIKELY (u > minexp))
+ {
+ mpfr_prec_t tq;
+ mp_size_t wi;
+ int td;
+
+ tq = u - minexp;
+ MPFR_ASSERTD (tq > 0); /* number of trailing bits */
+ MPFR_LOG_MSG (("tq=%Pd\n", tq));
+
+ wi = tq / GMP_NUMB_BITS;
+
+ /* Determine the rounding bit, which is represented. */
+ td = tq % GMP_NUMB_BITS;
+ lbit = (wp[wi] >> td) & MPFR_LIMB_ONE;
+ rbit = td >= 1 ? ((wp[wi] >> (td - 1)) & MPFR_LIMB_ONE) :
+ (MPFR_ASSERTD (wi >= 1), wp[wi-1] >> (GMP_NUMB_BITS - 1));
+ MPFR_ASSERTD (rbit == 0 || rbit == 1);
+ MPFR_LOG_MSG (("rbit=%d\n", (int) rbit));
+
+ if (maxexp == MPFR_EXP_MIN)
+ {
+ /* The sum in the accumulator is exact. Determine inex:
+ inex = 0 if the final sum is exact, else 1, i.e.
+ inex = rounding bit || sticky bit. In round to nearest,
+ also determine the rounding direction: obtained from
+ the rounding bit possibly except in halfway cases.
+ Halfway cases are rounded toward -inf iff the last bit
+ of the truncated significand in two's complement is 0
+ (in precision > 1, because the parity after rounding is
+ the same in two's complement and sign + magnitude; in
+ precision 1, one checks that the rule works for both
+ positive (lbit == 1) and negative (lbit == 0) numbers,
+ rounding halfway cases away from zero). */
+ if (MPFR_LIKELY (rbit == 0 || (rnd == MPFR_RNDN && lbit == 0)))
+ {
+ /* We need to determine the sticky bit, either to set inex
+ (if the rounding bit is 0) or to possibly "correct" rbit
+ (round to nearest, halfway case rounded downward) from
+ which the rounding direction will be determined. */
+ MPFR_LOG_MSG (("Determine the sticky bit...\n", 0));
+
+ inex = td >= 2 ? (wp[wi] & MPFR_LIMB_MASK (td - 1)) != 0
+ : td == 0 ?
+ (MPFR_ASSERTD (wi >= 1),
+ (wp[--wi] & MPFR_LIMB_MASK (GMP_NUMB_BITS - 1)) != 0)
+ : 0;
+
+ if (!inex)
+ {
+ while (!inex && wi > 0)
+ inex = wp[--wi] != 0;
+ if (!inex && rbit != 0)
+ {
+ /* sticky bit = 0, rounding bit = 1,
+ i.e. halfway case, which will be
+ rounded downward (see earlier if). */
+ MPFR_ASSERTD (rnd == MPFR_RNDN);
+ inex = 1;
+ rbit = 0; /* even rounding downward */
+ MPFR_LOG_MSG (("Halfway case rounded downward;"
+ " set inex=1 rbit=0\n", 0));
+ }
+ }
+ }
+ else
+ inex = 1;
+ tmd = 0; /* We can round correctly -> no TMD. */
+ }
+ else /* maxexp > MPFR_EXP_MIN */
+ {
+ mpfr_exp_t d;
+ mp_limb_t limb, mask;
+ int nbits;
+
+ /* Since maxexp was set to either the exponent of a x[i] or
+ to minexp... */
+ MPFR_ASSERTD (maxexp >= MPFR_EMIN_MIN || maxexp == minexp);
+
+ inex = 1; /* We do not know whether the sum is exact. */
+
+ MPFR_ASSERTD (u <= MPFR_EMAX_MAX && u <= minexp + wq);
+ d = u - (maxexp + logn); /* representable */
+ MPFR_ASSERTD (d >= 3); /* due to prec = sq + 3 in sum_raw */
+
+ /* Let's see whether the TMD occurs by looking at the d bits
+ following the ulp bit, or the d-1 bits after the rounding
+ bit. */
+
+ /* First chunk after the rounding bit... It starts at:
+ (wi,td-2) if td >= 2,
+ (wi-1,td-2+GMP_NUMB_BITS) if td < 2. */
+ if (td == 0)
+ {
+ MPFR_ASSERTD (wi >= 1);
+ limb = wp[--wi];
+ mask = MPFR_LIMB_MASK (GMP_NUMB_BITS - 1);
+ nbits = GMP_NUMB_BITS;
+ }
+ else if (td == 1)
+ {
+ limb = wi >= 1 ? wp[--wi] : MPFR_LIMB_ZERO;
+ mask = MPFR_LIMB_MAX;
+ nbits = GMP_NUMB_BITS + 1;
+ }
+ else /* td >= 2 */
+ {
+ MPFR_ASSERTD (td >= 2);
+ limb = wp[wi];
+ mask = MPFR_LIMB_MASK (td - 1);
+ nbits = td;
+ }
+
+ /* nbits: number of bits of the first chunk + 1
+ (the +1 is for the rounding bit). */
+
+ if (nbits > d)
+ {
+ /* Some low significant bits must be ignored. */
+ limb >>= nbits - d;
+ mask >>= nbits - d;
+ d = 0;
+ }
+ else
+ {
+ d -= nbits;
+ MPFR_ASSERTD (d >= 0);
+ }
+
+ limb &= mask;
+ tmd =
+ limb == MPFR_LIMB_ZERO ?
+ (rbit == 0 ? 1 : rnd == MPFR_RNDN ? 2 : 0) :
+ limb == mask ?
+ (limb = MPFR_LIMB_MAX,
+ rbit != 0 ? 1 : rnd == MPFR_RNDN ? 2 : 0) : 0;
+
+ while (tmd != 0 && d != 0)
+ {
+ mp_limb_t limb2;
+
+ MPFR_ASSERTD (d > 0);
+ if (wi == 0)
+ {
+ /* The non-represented bits are 0's. */
+ if (limb != MPFR_LIMB_ZERO)
+ tmd = 0;
+ break;
+ }
+ MPFR_ASSERTD (wi > 0);
+ limb2 = wp[--wi];
+ if (d < GMP_NUMB_BITS)
+ {
+ int c = GMP_NUMB_BITS - d;
+ MPFR_ASSERTD (c > 0 && c < GMP_NUMB_BITS);
+ if ((limb2 >> c) != (limb >> c))
+ tmd = 0;
+ break;
+ }
+ if (limb2 != limb)
+ tmd = 0;
+ d -= GMP_NUMB_BITS;
+ }
+ }
+ }
+ else /* u <= minexp */
+ {
+ /* The exact value of the accumulator will be copied.
+ * The TMD occurs if and only if there are bits still
+ * not taken into account, and if it occurs, this is
+ * necessarily on a machine number (-> tmd = 1).
+ */
+ lbit = u == minexp ? wp[0] & MPFR_LIMB_ONE : 0;
+ rbit = 0;
+ inex = tmd = maxexp != MPFR_EXP_MIN;
+ }
+
+ MPFR_ASSERTD (rbit == 0 || rbit == 1);
+
+ MPFR_LOG_MSG (("tmd=%d lbit=%d rbit=%d inex=%d neg=%d\n",
+ tmd, (int) lbit, (int) rbit, inex, neg));
+
+ /* Here, if the final sum is known to be exact, inex = 0, otherwise
+ * inex = 1. We have a truncated significand, a trailing term t such
+ * that 0 <= t < 1 ulp, and an error on the trailing term bounded by
+ * t' in absolute value. Thus the error e on the truncated significand
+ * satisfies -t' <= e < 1 ulp + t'. Thus one has 4 correction cases
+ * denoted by a corr value between -1 and 2 depending on e, neg, rbit,
+ * and the rounding mode:
+ * -1: equivalent to nextbelow;
+ * 0: the truncated significand is not corrected;
+ * 1: add 1 ulp;
+ * 2: add 1 ulp, then nextabove.
+ * The nextbelow and nextabove are used here since there may be a
+ * change of the binade.
+ */
+
+ if (tmd == 0) /* no TMD */
+ {
+ switch (rnd)
+ {
+ case MPFR_RNDD:
+ corr = 0;
+ break;
+ case MPFR_RNDU:
+ corr = inex;
+ break;
+ case MPFR_RNDZ:
+ corr = inex && neg;
+ break;
+ case MPFR_RNDA:
+ corr = inex && !neg;
+ break;
+ default:
+ MPFR_ASSERTN (rnd == MPFR_RNDN);
+ /* Note: for halfway cases (maxexp == MPFR_EXP_MIN) that are
+ rounded downward, rbit has been changed to 0 so that corr
+ is set correctly. */
+ corr = rbit;
+ }
+ MPFR_ASSERTD (corr == 0 || corr == 1);
+ if (inex &&
+ corr == 0) /* two's complement significand decreased */
+ inex = -1;
+ }
+ else /* tmd */
+ {
+ mpfr_exp_t minexp2;
+ mpfr_prec_t cancel2;
+ mpfr_exp_t err; /* exponent of the error bound */
+ mp_size_t zz; /* nb of limbs to zero in the TMD accumulator */
+ mp_limb_t *zp; /* pointer to the TMD accumulator */
+ mpfr_prec_t zq; /* size of the TMD accumulator, in bits */
+ int sst; /* sign of the secondary term */
+
+ /* TMD case. Here we use a new variable minexp2, with the same
+ meaning as minexp, as we want to keep the minexp value for
+ the copy to the destination. */
+
+ MPFR_ASSERTD (maxexp > MPFR_EXP_MIN);
+ MPFR_ASSERTD (tmd == 1 || tmd == 2);
+
+ /* TMD accumulator */
+ zp = wp + ws;
+ zq = (mpfr_prec_t) zs * GMP_NUMB_BITS;
+
+ err = maxexp + logn;
+
+ MPFR_LOG_MSG (("TMD with"
+ " maxexp=%" MPFR_EXP_FSPEC "d"
+ " err=%" MPFR_EXP_FSPEC "d"
+ " zs=%Pd"
+ " zq=%Pd\n",
+ (mpfr_eexp_t) maxexp, (mpfr_eexp_t) err,
+ (mpfr_prec_t) zs, zq));
+
+ /* The d-1 bits from u-2 to u-d (= err) are identical. */
+
+ if (err >= minexp)
+ {
+ mpfr_prec_t tq;
+ mp_size_t wi;
+ int td;
+
+ /* Let's keep the last 2 over the d-1 identical bits and the
+ following bits, i.e. the bits from err+1 to minexp. */
+ tq = err - minexp + 2; /* tq = number of such bits */
+ MPFR_LOG_MSG (("[TMD] tq=%Pd\n", tq));
+ MPFR_ASSERTD (tq >= 2);
+
+ wi = tq / GMP_NUMB_BITS;
+ td = tq % GMP_NUMB_BITS;
+
+ if (td != 0)
+ {
+ wi++; /* number of words with represented bits */
+ td = GMP_NUMB_BITS - td;
+ zz = zs - wi;
+ MPFR_ASSERTD (zz >= 0 && zz < zs);
+ mpn_lshift (zp + zz, wp, wi, td);
+ }
+ else
+ {
+ MPFR_ASSERTD (wi > 0);
+ zz = zs - wi;
+ MPFR_ASSERTD (zz >= 0 && zz < zs);
+ if (zz > 0)
+ MPN_COPY (zp + zz, wp, wi);
+ }
+
+ /* Compute minexp2 = minexp - (zs * GMP_NUMB_BITS + td)
+ safely. */
+ SAFE_SUB (minexp2, minexp, zz * GMP_NUMB_BITS + td);
+ MPFR_ASSERTD (minexp2 == err + 2 - zq);
+ }
+ else /* err < minexp */
+ {
+ /* At least one of the identical bits is not represented,
+ meaning that it is 0 and all these bits are 0's. Thus
+ the accumulator will be 0. The new minexp is determined
+ from maxexp, with cq bits reserved to avoid an overflow
+ (as in the early steps). */
+ MPFR_LOG_MSG (("[TMD] err < minexp\n", 0));
+ zz = zs;
+
+ /* Compute minexp2 = maxexp - (zq - cq) safely. */
+ SAFE_SUB (minexp2, maxexp, zq - cq);
+ MPFR_ASSERTD (minexp2 == err + 1 - zq);
+ }
+
+ MPN_ZERO (zp, zz);
+
+ /* We need to determine the sign sst of the secondary term.
+ In sum_raw, since the truncated sum corresponding to this
+ secondary term will be in [2^(e-1),2^e] and the error
+ strictly less than 2^err, we can stop the iterations when
+ e - err >= 1 (this bound is the 11th argument of sum_raw). */
+ cancel2 = sum_raw (zp, zs, zq, x, n, minexp2, maxexp, tp, ts,
+ logn, 1, NULL, NULL, NULL);
+
+ if (cancel2 != 0)
+ sst = MPFR_LIMB_MSB (zp[zs-1]) == 0 ? 1 : -1;
+ else if (tmd == 1)
+ sst = 0;
+ else
+ {
+ /* For halfway cases, let's virtually eliminate them
+ by setting a sst equivalent to a non-halfway case,
+ which depends on the last bit of the pre-rounded
+ result. */
+ MPFR_ASSERTD (rnd == MPFR_RNDN && tmd == 2);
+ sst = lbit != 0 ? 1 : -1;
+ }
+
+ MPFR_LOG_MSG (("[TMD] tmd=%d rbit=%d sst=%d\n",
+ tmd, (int) rbit, sst));
+
+ /* Do not consider the corrected sst for MPFR_COV_SET */
+ MPFR_COV_SET (sum_tmd[(int) rnd][tmd-1][rbit]
+ [cancel2 == 0 ? 1 : sst+1][neg][sq > MPFR_PREC_MIN]);
+
+ inex =
+ MPFR_IS_LIKE_RNDD (rnd, sgn) ? (sst ? -1 : 0) :
+ MPFR_IS_LIKE_RNDU (rnd, sgn) ? (sst ? 1 : 0) :
+ (MPFR_ASSERTD (rnd == MPFR_RNDN),
+ tmd == 1 ? - sst : sst);
+
+ if (tmd == 2 && sst == (rbit != 0 ? -1 : 1))
+ corr = 1 - (int) rbit;
+ else if (MPFR_IS_LIKE_RNDD (rnd, sgn) && sst == -1)
+ corr = (int) rbit - 1;
+ else if (MPFR_IS_LIKE_RNDU (rnd, sgn) && sst == +1)
+ corr = (int) rbit + 1;
+ else
+ corr = (int) rbit;
+ } /* tmd */
+ } /* rnd != MPFR_RNDF */
+
+ MPFR_LOG_MSG (("neg=%d corr=%d inex=%d\n", neg, corr, inex));
+
+ /* Sign handling (-> absolute value and sign), together with
+ rounding. The most common cases are corr = 0 and corr = 1
+ as this is necessarily the case when the TMD did not occur. */
+
+ MPFR_ASSERTD (corr >= -1 && corr <= 2);
+
+ MPFR_SIGN (sum) = sgn;
+
+ /* Let's copy/shift the bits [max(u,minexp),e) to the
+ most significant part of the destination, and zero
+ the least significant part (there can be one only if
+ u < minexp). The trailing bits of the destination may
+ contain garbage at this point. */
+
+ sn = MPFR_PREC2LIMBS (sq);
+ sd = (mpfr_prec_t) sn * GMP_NUMB_BITS - sq;
+ sh = cancel % GMP_NUMB_BITS;
+
+ MPFR_ASSERTD (sd >= 0 && sd < GMP_NUMB_BITS);
+
+ if (MPFR_LIKELY (u > minexp))
+ {
+ mp_size_t wi;
+
+ /* Recompute the initial value of wi. */
+ wi = (u - minexp) / GMP_NUMB_BITS;
+ if (MPFR_LIKELY (sh != 0))
+ {
+ mp_size_t fi;
+
+ fi = (e - minexp) / GMP_NUMB_BITS - (sn - 1);
+ MPFR_ASSERTD (fi == wi || fi == wi + 1);
+ mpn_lshift (sump, wp + fi, sn, sh);
+ if (fi != wi)
+ sump[0] |= wp[wi] >> (GMP_NUMB_BITS - sh);
+ }
+ else
+ {
+ MPFR_ASSERTD ((mpfr_prec_t) (ws - (wi + sn)) * GMP_NUMB_BITS
+ == cancel);
+ MPN_COPY (sump, wp + wi, sn);
+ }
+ }
+ else /* u <= minexp */
+ {
+ mp_size_t en;
+
+ en = (e - minexp + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS;
+ if (MPFR_LIKELY (sh != 0))
+ mpn_lshift (sump + sn - en, wp, en, sh);
+ else if (MPFR_UNLIKELY (en > 0))
+ MPN_COPY (sump + sn - en, wp, en);
+ if (sn > en)
+ MPN_ZERO (sump, sn - en);
+ }
+
+ /* Let's take the complement if the result is negative, and at
+ the same time, do the rounding and zero the trailing bits.
+ As this is valid only for precisions >= 2, there is special
+ code for precision 1 first. */
+
+ if (MPFR_UNLIKELY (sq == 1)) /* precision 1 */
+ {
+ sump[0] = MPFR_LIMB_HIGHBIT;
+ e += neg ? 1 - corr : corr;
+ }
+ else if (neg) /* negative result with sq > 1 */
+ {
+ MPFR_ASSERTD (MPFR_LIMB_MSB (sump[sn-1]) == 0);
+
+ /* abs(x + corr) = - (x + corr) = com(x) + (1 - corr) */
+
+ /* We want to avoid separate mpn_com (or mpn_neg) and mpn_add_1
+ (or mpn_sub_1) operations, as they could yield two loops in
+ some particular cases involving a long sequence of 0's in
+ the low significant bits (except the least significant bit,
+ which doesn't matter). */
+
+ if (corr <= 1)
+ {
+ mp_limb_t corr2;
+
+ /* Here we can just do the correction operation on the
+ least significant limb, then do either a mpn_com or
+ a mpn_neg on the remaining limbs, depending on the
+ carry (BTW, mpn_neg is just a mpn_com with an initial
+ carry propagation: after some point, mpn_neg does a
+ complement). */
+
+ corr2 = (mp_limb_t) (1 - corr) << sd;
+ /* Note: If corr = -1, this can overflow to corr2 = 0.
+ This case is taken into account below. */
+
+ sump[0] = (~ (sump[0] | MPFR_LIMB_MASK (sd))) + corr2;
+
+ if (sump[0] < corr2 || (corr2 == 0 && corr < 0))
+ {
+ if (sn == 1 || ! mpn_neg (sump + 1, sump + 1, sn - 1))
+ {
+ /* Note: The | is important when sump[sn-1] is not 0
+ (this can occur with sn = 1 and corr = -1). TODO:
+ Add something to make sure that this is tested. */
+ sump[sn-1] |= MPFR_LIMB_HIGHBIT;
+ e++;
+ }
+ }
+ else if (sn > 1)
+ mpn_com (sump + 1, sump + 1, sn - 1);
+ }
+ else /* corr == 2 */
+ {
+ mp_limb_t corr2, c;
+ mp_size_t i = 1;
+
+ /* We want to compute com(x) - 1, but GMP doesn't have an
+ operation for that. The fact is that a sequence of low
+ significant bits 1 is invariant. Starting at the first
+ low significant bit 0, we can do the complement with
+ mpn_com. */
+
+ corr2 = MPFR_LIMB_ONE << sd;
+ c = ~ (sump[0] | MPFR_LIMB_MASK (sd));
+ sump[0] = c - corr2;
+
+ if (c == 0)
+ {
+ while (MPFR_ASSERTD (i < sn), sump[i] == MPFR_LIMB_MAX)
+ i++;
+ sump[i] = (~ sump[i]) - 1;
+ i++;
+ }
+
+ if (i < sn)
+ mpn_com (sump + i, sump + i, sn - i);
+ else if (MPFR_UNLIKELY (MPFR_LIMB_MSB (sump[sn-1]) == 0))
+ {
+ /* Happens on 01111...111, whose complement is
+ 10000...000, and com(x) - 1 is 01111...111. */
+ sump[sn-1] |= MPFR_LIMB_HIGHBIT;
+ e--;
+ }
+ }
+ }
+ else /* positive result with sq > 1 */
+ {
+ MPFR_ASSERTD (MPFR_LIMB_MSB (sump[sn-1]) != 0);
+ sump[0] &= ~ MPFR_LIMB_MASK (sd);
+
+ if (corr > 0)
+ {
+ mp_limb_t corr2, carry_out;
+
+ corr2 = (mp_limb_t) corr << sd;
+ /* If corr == 2 && sd == GMP_NUMB_BITS - 1, this overflows
+ to corr2 = 0. This case is taken into account below. */
+
+ carry_out = corr2 != 0 ? mpn_add_1 (sump, sump, sn, corr2) :
+ (MPFR_ASSERTD (sn > 1),
+ mpn_add_1 (sump + 1, sump + 1, sn - 1, MPFR_LIMB_ONE));
+
+ MPFR_ASSERTD (sump[sn-1] >> (GMP_NUMB_BITS - 1) == !carry_out);
+
+ if (MPFR_UNLIKELY (carry_out))
+ {
+ /* Note: The | is important when sump[sn-1] is not 0
+ (this can occur with sn = 1 and corr = 2). TODO:
+ Add something to make sure that this is tested. */
+ sump[sn-1] |= MPFR_LIMB_HIGHBIT;
+ e++;
+ }
+ }
+
+ if (corr < 0)
+ {
+ mpn_sub_1 (sump, sump, sn, MPFR_LIMB_ONE << sd);
+
+ if (MPFR_UNLIKELY (MPFR_LIMB_MSB (sump[sn-1]) == 0))
+ {
+ sump[sn-1] |= MPFR_LIMB_HIGHBIT;
+ e--;
+ }
+ }
+ }
+
+ MPFR_ASSERTD (MPFR_LIMB_MSB (sump[sn-1]) != 0);
+ MPFR_LOG_MSG (("Set exponent e=%" MPFR_EXP_FSPEC "d\n", (mpfr_eexp_t) e));
+ /* e may be outside the current exponent range, but this will be checked
+ with mpfr_check_range below. */
+ MPFR_EXP (sum) = e;
+ } /* main block */
+
MPFR_TMP_FREE (marker);
+ return mpfr_check_range (sum, inex, rnd);
}
+/**********************************************************************/
-#define GET_EXP2(x) (MPFR_IS_ZERO (x) ? MPFR_EMIN_MIN : MPFR_GET_EXP (x))
-
-/* Performs a heap sort of the entries */
-static void
-heap_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm)
+int
+mpfr_sum (mpfr_ptr sum, const mpfr_ptr *x, unsigned long n, mpfr_rnd_t rnd)
{
- unsigned long dernier_traite;
- unsigned long i, pere;
- mpfr_srcptr tmp;
- unsigned long fils_gauche, fils_droit, fils_indigne;
- /* Reminder of a heap structure :
- node(i) has for left son node(2i +1) and right son node(2i)
- and father(node(i)) = node((i - 1) / 2)
- */
-
- /* initialize the permutation to identity */
- for (i = 0; i < n; i++)
- perm[i] = tab[i];
+ MPFR_LOG_FUNC
+ (("n=%lu rnd=%d", n, rnd),
+ ("sum[%Pu]=%.*Rg", mpfr_get_prec (sum), mpfr_log_prec, sum));
- /* insertion phase */
- for (dernier_traite = 1; dernier_traite < n; dernier_traite++)
+ if (MPFR_UNLIKELY (n <= 2))
{
- i = dernier_traite;
- while (i > 0)
+ if (n == 0)
{
- pere = (i - 1) / 2;
- if (GET_EXP2 (perm[pere]) > GET_EXP2 (perm[i]))
- {
- tmp = perm[pere];
- perm[pere] = perm[i];
- perm[i] = tmp;
- i = pere;
- }
- else
- break;
+ MPFR_SET_ZERO (sum);
+ MPFR_SET_POS (sum);
+ MPFR_RET (0);
}
+ else if (n == 1)
+ return mpfr_set (sum, x[0], rnd);
+ else
+ return mpfr_add (sum, x[0], x[1], rnd);
}
-
- /* extraction phase */
- for (dernier_traite = n - 1; dernier_traite > 0; dernier_traite--)
+ else
{
- tmp = perm[0];
- perm[0] = perm[dernier_traite];
- perm[dernier_traite] = tmp;
+ mpfr_exp_t maxexp = MPFR_EXP_MIN; /* max(Empty) */
+ unsigned long i;
+ unsigned long rn = 0; /* will be the number of regular inputs */
+ /* sign of infinities and zeros (0: currently unknown) */
+ int sign_inf = 0, sign_zero = 0;
+
+ MPFR_LOG_MSG (("Check for special inputs (n = %lu >= 3)\n", n));
- i = 0;
- while (1)
+ for (i = 0; i < n; i++)
{
- fils_gauche = 2 * i + 1;
- fils_droit = fils_gauche + 1;
- if (fils_gauche < dernier_traite)
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x[i])))
{
- if (fils_droit < dernier_traite)
+ if (MPFR_IS_NAN (x[i]))
{
- if (GET_EXP2(perm[fils_droit]) < GET_EXP2(perm[fils_gauche]))
- fils_indigne = fils_droit;
- else
- fils_indigne = fils_gauche;
-
- if (GET_EXP2 (perm[i]) > GET_EXP2 (perm[fils_indigne]))
- {
- tmp = perm[i];
- perm[i] = perm[fils_indigne];
- perm[fils_indigne] = tmp;
- i = fils_indigne;
- }
- else
- break;
+ /* The current value x[i] is NaN. Then the sum is NaN. */
+ nan:
+ MPFR_SET_NAN (sum);
+ MPFR_RET_NAN;
}
- else /* on a un fils gauche, pas de fils droit */
+ else if (MPFR_IS_INF (x[i]))
{
- if (GET_EXP2 (perm[i]) > GET_EXP2 (perm[fils_gauche]))
- {
- tmp = perm[i];
- perm[i] = perm[fils_gauche];
- perm[fils_gauche] = tmp;
- }
- break;
+ /* The current value x[i] is an infinity.
+ There are two cases:
+ 1. This is the first infinity value (sign_inf == 0).
+ Then set sign_inf to its sign, and go on.
+ 2. All the infinities found until now have the same
+ sign sign_inf. If this new infinity has a different
+ sign, then return NaN immediately, else go on. */
+ if (sign_inf == 0)
+ sign_inf = MPFR_SIGN (x[i]);
+ else if (MPFR_SIGN (x[i]) != sign_inf)
+ goto nan;
}
+ else if (MPFR_UNLIKELY (rn == 0))
+ {
+ /* The current value x[i] is a zero. The code below matters
+ only when all values found until now are zeros, otherwise
+ it is harmless (the test rn == 0 above is just a minor
+ optimization).
+ Here we track the sign of the zero result when all inputs
+ are zeros: if all zeros have the same sign, the result
+ will have this sign, otherwise (i.e. if there is at least
+ a zero of each sign), the sign of the zero result depends
+ only on the rounding mode (note that this choice is
+ sticky when new zeros are considered). */
+ MPFR_ASSERTD (MPFR_IS_ZERO (x[i]));
+ if (sign_zero == 0)
+ sign_zero = MPFR_SIGN (x[i]);
+ else if (MPFR_SIGN (x[i]) != sign_zero)
+ sign_zero = rnd == MPFR_RNDD ? -1 : 1;
+ }
+ }
+ else
+ {
+ /* The current value x[i] is a regular number. */
+ mpfr_exp_t e = MPFR_GET_EXP (x[i]);
+ if (e > maxexp)
+ maxexp = e; /* maximum exponent found until now */
+ rn++; /* current number of regular inputs */
}
- else /* on n'a pas de fils */
- break;
}
- }
-}
+ MPFR_LOG_MSG (("rn=%lu sign_inf=%d sign_zero=%d\n",
+ rn, sign_inf, sign_zero));
-/* Sum a list of float with order given by permutation perm,
- * intermediate size set to F. Return non-zero if at least one of
- * the operations is inexact (thus 0 implies that the sum is exact).
- * Internal use function.
- */
-static int
-sum_once (mpfr_ptr ret, mpfr_srcptr *const tab, unsigned long n, mpfr_prec_t F)
-{
- mpfr_t sum;
- unsigned long i;
- int error_trap;
+ /* At this point the result cannot be NaN (this case has already
+ been filtered out). */
- MPFR_ASSERTD (n >= 2);
-
- mpfr_init2 (sum, F);
- error_trap = mpfr_set (sum, tab[0], MPFR_RNDN);
- for (i = 1; i < n - 1; i++)
- {
- MPFR_ASSERTD (!MPFR_IS_NAN (sum) && !MPFR_IS_INF (sum));
- if (mpfr_add (sum, sum, tab[i], MPFR_RNDN))
- error_trap = 1;
- }
- if (mpfr_add (ret, sum, tab[n - 1], MPFR_RNDN))
- error_trap = 1;
- mpfr_clear (sum);
- return error_trap;
-}
+ if (MPFR_UNLIKELY (sign_inf != 0))
+ {
+ /* At least one infinity, and all of them have the same sign
+ sign_inf. The sum is the infinity of this sign. */
+ MPFR_SET_INF (sum);
+ MPFR_SET_SIGN (sum, sign_inf);
+ MPFR_RET (0);
+ }
-/* Sum a list of floating-point numbers.
- * If the return value is 0, then the sum is exact.
- * Otherwise the return value gives no information.
- */
-int
-mpfr_sum (mpfr_ptr ret, mpfr_ptr *const tab_p, unsigned long n, mpfr_rnd_t rnd)
-{
- mpfr_t cur_sum;
- mpfr_prec_t prec;
- mpfr_srcptr *perm, *const tab = (mpfr_srcptr *) tab_p;
- int k, error_trap;
- MPFR_ZIV_DECL (loop);
- MPFR_SAVE_EXPO_DECL (expo);
- MPFR_TMP_DECL (marker);
+ /* At this point, all the inputs are finite numbers. */
- if (MPFR_UNLIKELY (n <= 1))
- {
- if (n < 1)
+ if (MPFR_UNLIKELY (rn == 0))
{
- MPFR_SET_ZERO (ret);
- MPFR_SET_POS (ret);
- return 0;
+ /* All the numbers were zeros (and there is at least one).
+ The sum is zero with sign sign_zero. */
+ MPFR_ASSERTD (sign_zero != 0);
+ MPFR_SET_ZERO (sum);
+ MPFR_SET_SIGN (sum, sign_zero);
+ MPFR_RET (0);
}
- else
- return mpfr_set (ret, tab[0], rnd);
- }
- /* Sort and treat special cases */
- MPFR_TMP_MARK (marker);
- perm = (mpfr_srcptr *) MPFR_TMP_ALLOC (n * sizeof *perm);
- prec = MPFR_PREC (ret);
- error_trap = mpfr_sum_sort (tab, n, perm, &prec);
- /* Check if there was a NAN or a INF */
- if (MPFR_UNLIKELY (error_trap != 0))
- {
- MPFR_TMP_FREE (marker);
- if (error_trap == 2)
+ /* Optimize the case where there are only two regular numbers. */
+ if (MPFR_UNLIKELY (rn <= 2))
{
- MPFR_SET_NAN (ret);
- MPFR_RET_NAN;
- }
- MPFR_SET_INF (ret);
- MPFR_SET_SIGN (ret, error_trap);
- MPFR_RET (0);
- }
+ unsigned long h = ULONG_MAX;
- /* Initial precision is max(prec(ret),prec(tab[0]),...,prec(tab[n-1])) */
- k = MPFR_INT_CEIL_LOG2 (n) + 1;
- prec += k + 2;
- mpfr_init2 (cur_sum, prec);
+ for (i = 0; i < n; i++)
+ if (! MPFR_IS_SINGULAR (x[i]))
+ {
+ if (rn == 1)
+ return mpfr_set (sum, x[i], rnd);
+ if (h != ULONG_MAX)
+ return mpfr_add (sum, x[h], x[i], rnd);
+ h = i;
+ }
+ MPFR_RET_NEVER_GO_HERE();
+ }
- /* Ziv Loop */
- MPFR_SAVE_EXPO_MARK (expo);
- MPFR_ZIV_INIT (loop, prec);
- for (;;)
- {
- error_trap = sum_once (cur_sum, perm, n, prec + k);
- if (MPFR_LIKELY (error_trap == 0 ||
- (!MPFR_IS_ZERO (cur_sum) &&
- mpfr_can_round (cur_sum, prec - 2,
- MPFR_RNDN, rnd, MPFR_PREC (ret)))))
- break;
- MPFR_ZIV_NEXT (loop, prec);
- mpfr_set_prec (cur_sum, prec);
+ return sum_aux (sum, x, n, rnd, maxexp, rn);
}
- MPFR_ZIV_FREE (loop);
- MPFR_TMP_FREE (marker);
-
- if (mpfr_set (ret, cur_sum, rnd))
- error_trap = 1;
- mpfr_clear (cur_sum);
-
- MPFR_SAVE_EXPO_FREE (expo);
- if (mpfr_check_range (ret, 0, rnd))
- error_trap = 1;
- return error_trap; /* It doesn't return the ternary value */
}
-
-/* __END__ */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/tanh.c b/Build/source/libs/mpfr/mpfr-src/src/tanh.c
index f220321ff75..5459ecfa4d7 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/tanh.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/tanh.c
@@ -84,7 +84,7 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
For x > 0, exp(2*x) > 2^(2*x)
If 2 ^(2*x) > 2^emax or x>emax/2, there is an overflow */
if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emax/2) >= 0)) {
- /* initialise of intermediary variables
+ /* initialize of intermediary variables
since 'set_one' label assumes the variables have been
initialize */
MPFR_GROUP_INIT_2 (group, MPFR_PREC_MIN, t, te);
@@ -98,50 +98,62 @@ mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
if (MPFR_GET_EXP (x) < 0)
Nt += -MPFR_GET_EXP (x);
- /* initialise of intermediary variable */
+ /* The error analysis in algorithms.tex assumes that x is exactly
+ representable with working precision Nt.
+ FIXME: adapt the error analysis for the case Nt < PREC(x). */
+ if (Nt < MPFR_PREC(x))
+ Nt = MPFR_PREC(x);
+
+ /* initialize of intermediary variable */
MPFR_GROUP_INIT_2 (group, Nt, t, te);
MPFR_ZIV_INIT (loop, Nt);
- for (;;) {
- /* tanh = (exp(2x)-1)/(exp(2x)+1) */
- mpfr_mul_2ui (te, x, 1, MPFR_RNDN); /* 2x */
- /* since x > 0, we can only have an overflow */
- mpfr_exp (te, te, MPFR_RNDN); /* exp(2x) */
- if (MPFR_UNLIKELY (MPFR_IS_INF (te))) {
- set_one:
- inexact = MPFR_FROM_SIGN_TO_INT (sign);
- mpfr_set4 (y, __gmpfr_one, MPFR_RNDN, sign);
- if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG_SIGN (sign)))
+ for (;;)
+ {
+ /* tanh = (exp(2x)-1)/(exp(2x)+1) */
+ inexact = mpfr_mul_2ui (te, x, 1, MPFR_RNDN); /* 2x */
+ MPFR_ASSERTD(inexact == 0); /* see FIXME above */
+ /* since x > 0, we can only have an overflow */
+ mpfr_exp (te, te, MPFR_RNDN); /* exp(2x) */
+ if (MPFR_UNLIKELY (MPFR_IS_INF (te)))
{
- inexact = -inexact;
- mpfr_nexttozero (y);
+ set_one:
+ inexact = MPFR_FROM_SIGN_TO_INT (sign);
+ mpfr_set4 (y, __gmpfr_one, MPFR_RNDN, sign);
+ if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG_SIGN (sign)))
+ {
+ inexact = -inexact;
+ mpfr_nexttozero (y);
+ }
+ break;
+ }
+ d = MPFR_GET_EXP (te); /* For Error calculation */
+ mpfr_add_ui (t, te, 1, MPFR_RNDD); /* exp(2x) + 1 */
+ mpfr_sub_ui (te, te, 1, MPFR_RNDU); /* exp(2x) - 1 */
+ d = d - MPFR_GET_EXP (te);
+ mpfr_div (t, te, t, MPFR_RNDN); /* (exp(2x)-1)/(exp(2x)+1) */
+
+ /* Calculation of the error, see algorithms.tex; the current value
+ of d is k in algorithms.tex. */
+ d = MAX(3, d + 1); /* d = exponent in 2^(max(3,k+1)) */
+ err = Nt - (d + 1);
+
+ /* The inequality is the condition max(3,k+1) <= floor(p/2). */
+ if (MPFR_LIKELY (d <= Nt / 2 &&
+ MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ {
+ inexact = mpfr_set4 (y, t, rnd_mode, sign);
+ break;
}
- break;
- }
- d = MPFR_GET_EXP (te); /* For Error calculation */
- mpfr_add_ui (t, te, 1, MPFR_RNDD); /* exp(2x) + 1*/
- mpfr_sub_ui (te, te, 1, MPFR_RNDU); /* exp(2x) - 1*/
- d = d - MPFR_GET_EXP (te);
- mpfr_div (t, te, t, MPFR_RNDN); /* (exp(2x)-1)/(exp(2x)+1)*/
-
- /* Calculation of the error */
- d = MAX(3, d + 1);
- err = Nt - (d + 1);
-
- if (MPFR_LIKELY ((d <= Nt / 2) && MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
- {
- inexact = mpfr_set4 (y, t, rnd_mode, sign);
- break;
- }
- /* if t=1, we still can round since |sinh(x)| < 1 */
- if (MPFR_GET_EXP (t) == 1)
- goto set_one;
+ /* if t=1, we still can round since |sinh(x)| < 1 */
+ if (MPFR_GET_EXP (t) == 1)
+ goto set_one;
- /* Actualisation of the precision */
- MPFR_ZIV_NEXT (loop, Nt);
- MPFR_GROUP_REPREC_2 (group, Nt, t, te);
- }
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ MPFR_GROUP_REPREC_2 (group, Nt, t, te);
+ }
MPFR_ZIV_FREE (loop);
MPFR_GROUP_CLEAR (group);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ubf.c b/Build/source/libs/mpfr/mpfr-src/src/ubf.c
new file mode 100644
index 00000000000..2c01707c0c2
--- /dev/null
+++ b/Build/source/libs/mpfr/mpfr-src/src/ubf.c
@@ -0,0 +1,242 @@
+/* Functions to work with unbounded floats (limited low-level interface).
+
+Copyright 2016-2017 Free Software Foundation, Inc.
+Contributed by the AriC and Caramba projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Note: In MPFR math functions, even if UBF code is not called first,
+ we may still need to handle special values NaN and infinities here.
+ Indeed, for MAXR * MAXR + (-inf), even though this is a special case,
+ the computation will also generate an overflow due to MAXR * MAXR,
+ so that UBF code will be called anyway (except if special cases are
+ detected and handled separately, but for polynomial, this should not
+ be needed). */
+
+/* This function does not change the flags. */
+static void
+mpfr_init_get_zexp (mpz_ptr ez, mpfr_srcptr x)
+{
+ mpz_init (ez);
+
+ if (MPFR_IS_UBF (x))
+ mpz_set (ez, MPFR_ZEXP (x));
+ else
+ {
+ mp_limb_t e_limb[MPFR_EXP_LIMB_SIZE];
+ mpfr_t e;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* TODO: Once this has been tested, optimize based on whether
+ _MPFR_EXP_FORMAT <= 3. */
+ MPFR_TMP_INIT1 (e_limb, e, sizeof (mpfr_exp_t) * CHAR_BIT);
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_DBGRES (inex = mpfr_set_exp_t (e, MPFR_GET_EXP (x), MPFR_RNDN));
+ MPFR_ASSERTD (inex == 0);
+ MPFR_DBGRES (inex = mpfr_get_z (ez, e, MPFR_RNDN));
+ MPFR_ASSERTD (inex == 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+}
+
+/* Exact product. The number a is assumed to have enough allocated memory,
+ where the trailing bits are regarded as being part of the input numbers
+ (no reallocation is attempted and no check is performed as MPFR_TMP_INIT
+ could have been used). The arguments b and c may actually be UBF numbers
+ (mpfr_srcptr can be seen a bit like void *, but is stronger).
+ This function does not change the flags, except in case of NaN. */
+void
+mpfr_ubf_mul_exact (mpfr_ubf_ptr a, mpfr_srcptr b, mpfr_srcptr c)
+{
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c[%Pu]=%.*Rg",
+ mpfr_get_prec (b), mpfr_log_prec, b,
+ mpfr_get_prec (c), mpfr_log_prec, c),
+ ("a[%Pu]=%.*Rg",
+ mpfr_get_prec (a), mpfr_log_prec, a));
+
+ MPFR_ASSERTD ((mpfr_ptr) a != b);
+ MPFR_ASSERTD ((mpfr_ptr) a != c);
+ MPFR_SIGN (a) = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+
+ if (MPFR_ARE_SINGULAR (b, c))
+ {
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ MPFR_SET_NAN (a);
+ else if (MPFR_IS_INF (b))
+ {
+ if (MPFR_NOTZERO (c))
+ MPFR_SET_INF (a);
+ else
+ MPFR_SET_NAN (a);
+ }
+ else if (MPFR_IS_INF (c))
+ {
+ if (!MPFR_IS_ZERO (b))
+ MPFR_SET_INF (a);
+ else
+ MPFR_SET_NAN (a);
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO(b) || MPFR_IS_ZERO(c));
+ MPFR_SET_ZERO (a);
+ }
+ }
+ else
+ {
+ mpfr_exp_t e;
+ mp_size_t bn, cn;
+ mpfr_limb_ptr ap;
+ mp_limb_t u, v;
+ int m;
+
+ /* Note about the code below: For the choice of the precision of
+ * the result a, one could choose PREC(b) + PREC(c), instead of
+ * taking whole limbs into account, but in most cases where one
+ * would gain one limb, one would need to copy the significand
+ * instead of a no-op (see the mul.c code).
+ * But in the case MPFR_LIMB_MSB (u) == 0, if the result fits in
+ * an-1 limbs, one could actually do
+ * mpn_rshift (ap, ap, k, GMP_NUMB_BITS - 1)
+ * instead of
+ * mpn_lshift (ap, ap, k, 1)
+ * to gain one limb (and reduce the precision), replacing a shift
+ * by another one. Would this be interesting?
+ */
+
+ bn = MPFR_LIMB_SIZE (b);
+ cn = MPFR_LIMB_SIZE (c);
+
+ ap = MPFR_MANT (a);
+
+ if (bn == 1 && cn == 1)
+ {
+ umul_ppmm (ap[1], ap[0], MPFR_MANT(b)[0], MPFR_MANT(c)[0]);
+ if (ap[1] & MPFR_LIMB_HIGHBIT)
+ m = 0;
+ else
+ {
+ ap[1] = (ap[1] << 1) | (ap[0] >> (GMP_NUMB_BITS - 1));
+ ap[0] = ap[0] << 1;
+ m = 1;
+ }
+ }
+ else
+ {
+ u = (bn >= cn) ?
+ mpn_mul (ap, MPFR_MANT (b), bn, MPFR_MANT (c), cn) :
+ mpn_mul (ap, MPFR_MANT (c), cn, MPFR_MANT (b), bn);
+ if (MPFR_LIMB_MSB (u) == 0)
+ {
+ m = 1;
+ MPFR_DBGRES (v = mpn_lshift (ap, ap, bn + cn, 1));
+ MPFR_ASSERTD (v == 0);
+ }
+ else
+ m = 0;
+ }
+
+ if (! MPFR_IS_UBF (b) && ! MPFR_IS_UBF (c) &&
+ (e = MPFR_GET_EXP (b) + MPFR_GET_EXP (c) - m,
+ MPFR_EXP_IN_RANGE (e)))
+ {
+ MPFR_SET_EXP (a, e);
+ }
+ else
+ {
+ mpz_t be, ce;
+
+ mpz_init (MPFR_ZEXP (a));
+
+ /* This may involve copies of mpz_t, but exponents should not be
+ very large integers anyway. */
+ mpfr_init_get_zexp (be, b);
+ mpfr_init_get_zexp (ce, c);
+ mpz_add (MPFR_ZEXP (a), be, ce);
+ mpz_clear (be);
+ mpz_clear (ce);
+ mpz_sub_ui (MPFR_ZEXP (a), MPFR_ZEXP (a), m);
+ MPFR_SET_UBF (a);
+ }
+ }
+}
+
+int
+mpfr_ubf_exp_less_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ mpz_t xe, ye;
+ int c;
+
+ mpfr_init_get_zexp (xe, x);
+ mpfr_init_get_zexp (ye, y);
+ c = mpz_cmp (xe, ye) < 0;
+ mpz_clear (xe);
+ mpz_clear (ye);
+ return c;
+}
+
+/* Convert an mpz_t to an mpfr_exp_t, restricted to
+ the interval [MPFR_EXP_MIN,MPFR_EXP_MAX]. */
+mpfr_exp_t
+mpfr_ubf_zexp2exp (mpz_ptr ez)
+{
+ mp_size_t n;
+ mpfr_eexp_t e;
+ mpfr_t d;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ n = ABSIZ (ez); /* limb size of ez */
+ if (n == 0)
+ return 0;
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (d, n * GMP_NUMB_BITS);
+ MPFR_DBGRES (inex = mpfr_set_z (d, ez, MPFR_RNDN));
+ MPFR_ASSERTD (inex == 0);
+ e = mpfr_get_exp_t (d, MPFR_RNDZ);
+ mpfr_clear (d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ if (MPFR_UNLIKELY (e < MPFR_EXP_MIN))
+ return MPFR_EXP_MIN;
+ if (MPFR_UNLIKELY (e > MPFR_EXP_MAX))
+ return MPFR_EXP_MAX;
+ return e;
+}
+
+/* Return the difference of the exponents of x and y, restricted to
+ the interval [MPFR_EXP_MIN,MPFR_EXP_MAX]. */
+mpfr_exp_t
+mpfr_ubf_diff_exp (mpfr_srcptr x, mpfr_srcptr y)
+{
+ mpz_t xe, ye;
+ mpfr_exp_t e;
+
+ mpfr_init_get_zexp (xe, x);
+ mpfr_init_get_zexp (ye, y);
+ mpz_sub (xe, xe, ye);
+ mpz_clear (ye);
+ e = mpfr_ubf_zexp2exp (xe);
+ mpz_clear (xe);
+ return e;
+}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/uceil_exp2.c b/Build/source/libs/mpfr/mpfr-src/src/uceil_exp2.c
index b81181a53c4..c68147f5783 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/uceil_exp2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/uceil_exp2.c
@@ -29,8 +29,8 @@ double
__gmpfr_ceil_exp2 (double d)
{
long exp;
-#if _GMP_IEEE_FLOATS
- union ieee_double_extract x;
+#if _MPFR_IEEE_FLOATS
+ union mpfr_ieee_double_extract x;
#else
struct {double d;} x;
#endif
@@ -41,7 +41,7 @@ __gmpfr_ceil_exp2 (double d)
exp++;
/* now exp = ceil(d) */
x.d = 1.0;
-#if _GMP_IEEE_FLOATS
+#if _MPFR_IEEE_FLOATS
x.s.exp = exp <= -1022 ? 1 : 1023 + exp;
#else
if (exp >= 0)
@@ -60,6 +60,6 @@ __gmpfr_ceil_exp2 (double d)
exp++;
}
}
-#endif
+#endif /* _MPFR_IEEE_FLOATS */
return x.d;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/uceil_log2.c b/Build/source/libs/mpfr/mpfr-src/src/uceil_log2.c
index 9c9168a5a91..700e0172a0a 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/uceil_log2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/uceil_log2.c
@@ -24,40 +24,44 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
/* returns ceil(log(d)/log(2)) if d > 0,
-1023 if d = +0,
- and floor(log(-d)/log(2))+1 if d < 0*/
+ and floor(log(-d)/log(2))+1 if d < 0
+*/
long
__gmpfr_ceil_log2 (double d)
{
long exp;
-#if _GMP_IEEE_FLOATS
- union ieee_double_extract x;
+#if _MPFR_IEEE_FLOATS
+ union mpfr_ieee_double_extract x;
x.d = d;
- exp = x.s.exp - 1023;
+ /* The cast below is useless in theory, but let us not depend on the
+ integer promotion rules (for instance, tcc is currently wrong). */
+ exp = (long) x.s.exp - 1023;
+ MPFR_ASSERTN (exp < 1023); /* fail on infinities */
x.s.exp = 1023; /* value for 1 <= d < 2 */
if (x.d != 1.0) /* d: not a power of two? */
exp++;
return exp;
-#else
+#else /* _MPFR_IEEE_FLOATS */
double m;
if (d < 0.0)
- return __gmpfr_floor_log2(-d)+1;
+ return __gmpfr_floor_log2 (-d) + 1;
else if (d == 0.0)
return -1023;
else if (d >= 1.0)
{
exp = 0;
- for( m= 1.0 ; m < d ; m *=2.0 )
+ for (m = 1.0; m < d; m *= 2.0)
exp++;
}
else
{
exp = 1;
- for( m= 1.0 ; m >= d ; m *= (1.0/2.0) )
+ for (m = 1.0; m >= d; m *= 0.5)
exp--;
}
-#endif
+#endif /* _MPFR_IEEE_FLOATS */
return exp;
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ufloor_log2.c b/Build/source/libs/mpfr/mpfr-src/src/ufloor_log2.c
index bae86087222..5101b74ce3d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ufloor_log2.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/ufloor_log2.c
@@ -26,28 +26,32 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
long
__gmpfr_floor_log2 (double d)
{
-#if _GMP_IEEE_FLOATS
- union ieee_double_extract x;
+ long exp;
+#if _MPFR_IEEE_FLOATS
+ union mpfr_ieee_double_extract x;
x.d = d;
- return (long) x.s.exp - 1023;
-#else
- long exp;
+ /* The cast below is useless in theory, but let us not depend on the
+ integer promotion rules (for instance, tcc is currently wrong). */
+ exp = (long) x.s.exp - 1023;
+ MPFR_ASSERTN (exp < 1023); /* fail on infinities */
+ return exp;
+#else /* _MPFR_IEEE_FLOATS */
double m;
MPFR_ASSERTD (d >= 0);
if (d >= 1.0)
{
exp = -1;
- for( m= 1.0 ; m <= d ; m *=2.0 )
+ for (m = 1.0; m <= d; m *= 2.0)
exp++;
}
else
{
exp = 0;
- for( m= 1.0 ; m > d ; m *= (1.0/2.0) )
+ for (m = 1.0; m > d; m *= 0.5)
exp--;
}
return exp;
-#endif
+#endif /* _MPFR_IEEE_FLOATS */
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ui_div.c b/Build/source/libs/mpfr/mpfr-src/src/ui_div.c
index e69dfee1f3f..36121edca3b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ui_div.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/ui_div.c
@@ -1,5 +1,4 @@
/* mpfr_ui_div -- divide a machine integer by a floating-point number
- mpfr_si_div -- divide a machine number by a floating-point number
Copyright 2000-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -54,7 +53,7 @@ mpfr_ui_div (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode
/* u > 0, so y = sign(x) * Inf */
MPFR_SET_SAME_SIGN(y, x);
MPFR_SET_INF(y);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET(0);
}
else
@@ -95,20 +94,3 @@ mpfr_ui_div (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode
MPFR_RET(0);
}
}
-
-
-int
-mpfr_si_div (mpfr_ptr y, long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
-{
- int res;
-
- if (u >= 0)
- res = mpfr_ui_div (y, u, x, rnd_mode);
- else
- {
- res = - mpfr_ui_div (y, - (unsigned long) u, x,
- MPFR_INVERT_RND(rnd_mode));
- MPFR_CHANGE_SIGN (y);
- }
- return res;
-}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ui_pow.c b/Build/source/libs/mpfr/mpfr-src/src/ui_pow.c
index 9e96ba5a281..712b53d0998 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ui_pow.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/ui_pow.c
@@ -27,14 +27,14 @@ mpfr_ui_pow (mpfr_ptr y, unsigned long int n, mpfr_srcptr x, mpfr_rnd_t rnd_mode
{
mpfr_t t;
int inexact;
+ mp_limb_t tmp_mant[(sizeof (n) - 1) / sizeof (mp_limb_t) + 1];
MPFR_SAVE_EXPO_DECL (expo);
MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (t, sizeof(n) * CHAR_BIT);
+ MPFR_TMP_INIT1(tmp_mant, t, sizeof(n) * CHAR_BIT);
inexact = mpfr_set_ui (t, n, MPFR_RNDN);
- MPFR_ASSERTN (!inexact);
+ MPFR_ASSERTD (inexact == 0);
inexact = mpfr_pow (y, t, x, rnd_mode);
- mpfr_clear (t);
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (y, inexact, rnd_mode);
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ui_pow_ui.c b/Build/source/libs/mpfr/mpfr-src/src/ui_pow_ui.c
index 1198e3b54f0..654fc01e7b7 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ui_pow_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/ui_pow_ui.c
@@ -1,4 +1,4 @@
-/* mpfr_ui_pow_ui -- compute the power beetween two machine integer
+/* mpfr_ui_pow_ui -- compute the power between two machine integers
Copyright 1999-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ui_sub.c b/Build/source/libs/mpfr/mpfr-src/src/ui_sub.c
index 0ef7917c389..d5fae6e1c13 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/ui_sub.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/ui_sub.c
@@ -31,48 +31,52 @@ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode
u, mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
("y[%Pu]=%.*Rg", mpfr_get_prec(y), mpfr_log_prec, y));
+ /* (unsigned long) 0 is assumed to be a real 0 (unsigned) */
if (MPFR_UNLIKELY (u == 0))
return mpfr_neg (y, x, rnd_mode);
- if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
{
- if (MPFR_IS_NAN(x))
+ if (MPFR_IS_NAN (x))
{
- MPFR_SET_NAN(y);
+ MPFR_SET_NAN (y);
MPFR_RET_NAN;
}
- else if (MPFR_IS_INF(x))
+ if (MPFR_IS_INF (x))
{
/* u - Inf = -Inf and u - -Inf = +Inf */
- MPFR_SET_INF(y);
- MPFR_SET_OPPOSITE_SIGN(y,x);
- MPFR_RET(0); /* +/-infinity is exact */
+ MPFR_SET_INF (y);
+ MPFR_SET_OPPOSITE_SIGN (y, x);
+ MPFR_RET (0); /* +/-infinity is exact */
}
- else /* x is zero */
- /* u - 0 = u */
- return mpfr_set_ui(y, u, rnd_mode);
+ MPFR_ASSERTD (MPFR_IS_ZERO (x) && u != 0);
+ /* Note: the fact that u != 0 is important due to signed zeros. */
+ /* u - 0 = u */
+ return mpfr_set_ui (y, u, rnd_mode);
}
- else
- {
- mpfr_t uu;
- mp_limb_t up[1];
- int cnt;
- int inex;
- MPFR_SAVE_EXPO_DECL (expo);
+ /* Main code */
+ {
+ mpfr_t uu;
+ mp_limb_t up[1];
+ int cnt;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
- MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
- MPFR_ASSERTN(u == (mp_limb_t) u);
- count_leading_zeros (cnt, (mp_limb_t) u);
- up[0] = (mp_limb_t) u << cnt;
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_STAT_STATIC_ASSERT (MPFR_LIMB_MAX >= ULONG_MAX);
+ /* So, u fits in a mp_limb_t, which justifies the casts below. */
+ MPFR_ASSERTD (u != 0);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ up[0] = (mp_limb_t) u << cnt;
- /* Optimization note: Exponent save/restore operations may be
- removed if mpfr_sub works even when uu is out-of-range. */
- MPFR_SAVE_EXPO_MARK (expo);
- MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
- inex = mpfr_sub (y, uu, x, rnd_mode);
- MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
- MPFR_SAVE_EXPO_FREE (expo);
- return mpfr_check_range(y, inex, rnd_mode);
- }
+ /* Optimization note: Exponent save/restore operations may be
+ removed if mpfr_sub works even when uu is out-of-range. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ inex = mpfr_sub (y, uu, x, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd_mode);
+ }
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/urandom.c b/Build/source/libs/mpfr/mpfr-src/src/urandom.c
index a30f9a843dc..816e4b5b9b5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/urandom.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/urandom.c
@@ -27,34 +27,27 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
-/* generate one random bit */
-static int
-random_rounding_bit (gmp_randstate_t rstate)
-{
- mp_limb_t r;
-
- mpfr_rand_raw (&r, rstate, 1);
- return r & MPFR_LIMB_ONE;
-}
-
-/* NOTE: The current behavior is to consider "underflow before rounding"
- (the significand does not need to be drawn), while the rule in MPFR
- is "underflow after rounding". This is unfixable in this 3.1 branch
- without changing the behavior of the PRNG (thus breaking the ABI). */
-
-/* The mpfr_urandom() function is implemented in the following way for
- the generic case.
+/* The mpfr_urandom() function is implemented in the following way,
+ so that the exact number (the random value to be rounded) and the
+ final status of the random generator do not depend on the current
+ exponent range and on the rounding mode. However, they depend on
+ the target precision: from the same state of the random generator,
+ if the precision of the destination is changed, then the value may
+ be completely different (and the state of the random generator is
+ different too).
1. One determines the exponent exp: 0 with probability 1/2, -1 with
probability 1/4, -2 with probability 1/8, etc.
2. One draws a 1-ulp interval ]a,b[ containing the exact result (the
interval can be regarded as open since it has the same measure as
the closed interval).
+ One also draws the rounding bit. This is currently done with a
+ separate call to mpfr_rand_raw(), but it should be better to draw
+ the rounding bit as part of the significand; there is space for it
+ since the MSB is always 1.
3. Rounding is done. For the directed rounding modes, the rounded value
is uniquely determined. For rounding to nearest, ]a,m[ and ]m,b[,
where m = (a+b)/2, have the same measure, so that one gets a or b
with equal probabilities.
- Note: Only low-level functions are used (except just before a "return"),
- so that we do not need MPFR_SAVE_EXPO_*.
*/
int
@@ -65,43 +58,28 @@ mpfr_urandom (mpfr_ptr rop, gmp_randstate_t rstate, mpfr_rnd_t rnd_mode)
mp_size_t nlimbs;
mp_size_t n;
mpfr_exp_t exp;
+ mp_limb_t rbit;
int cnt;
int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* We need to extend the exponent range in order to simplify
+ the case where one rounds upward (we would not be able to
+ use mpfr_nextabove() in the case emin = max). It could be
+ partly reimplemented under a simpler form here, but it is
+ better to make the code shorter and more readable. */
+ MPFR_SAVE_EXPO_MARK (expo);
rp = MPFR_MANT (rop);
nbits = MPFR_PREC (rop);
+ MPFR_SET_EXP (rop, 0);
MPFR_SET_POS (rop);
-
- if (MPFR_UNLIKELY (__gmpfr_emin > 0))
- {
- /* The minimum positive representable number 2^(emin-1) is >= 1,
- so that we need to round to +0 or 2^(emin-1). For the directed
- rounding modes, the rounded value is uniquely determined. For
- rounding to nearest: if emin = 1, one has probability 1/2 for
- each; otherwise (i.e. if emin > 1), the rounded value is 0. */
- __gmpfr_flags |= MPFR_FLAGS_UNDERFLOW;
- if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
- || (__gmpfr_emin == 1 && rnd_mode == MPFR_RNDN
- && random_rounding_bit (rstate)))
- {
- mpfr_set_ui_2exp (rop, 1, __gmpfr_emin - 1, rnd_mode);
- MPFR_RET (+1);
- }
- else
- {
- MPFR_SET_ZERO (rop);
- MPFR_RET (-1);
- }
- }
-
exp = 0;
- MPFR_ASSERTD (exp >= __gmpfr_emin);
/* Step 1 (exponent). */
#define DRAW_BITS 8 /* we draw DRAW_BITS at a time */
- cnt = DRAW_BITS;
- MPFR_ASSERTN(DRAW_BITS <= GMP_NUMB_BITS);
- while (cnt == DRAW_BITS)
+ MPFR_STAT_STATIC_ASSERT (DRAW_BITS <= GMP_NUMB_BITS);
+ do
{
/* generate DRAW_BITS in rp[0] */
mpfr_rand_raw (rp, rstate, DRAW_BITS);
@@ -112,67 +90,49 @@ mpfr_urandom (mpfr_ptr rop, gmp_randstate_t rstate, mpfr_rnd_t rnd_mode)
count_leading_zeros (cnt, rp[0]);
cnt -= GMP_NUMB_BITS - DRAW_BITS;
}
- exp -= cnt; /* no integer overflow */
-
- if (MPFR_UNLIKELY (exp < __gmpfr_emin))
- {
- /* To get here, we have been drawing more than -emin zeros
- in a row, then return 0 or the smallest representable
- positive number.
-
- The rounding-to-nearest mode is subtle: We need to round to
- the smallest representable positive number iff the exponent
- is emin - 1. This condition can be satisfied only if the
- current emin is emin - 1. In this case, if cnt != DRAW_BITS,
- this in the final emin, so that the condition is satisfied.
- But if cnt == DRAW_BITS, we need to draw an additional bit
- to determine whether emin == emin - 1 or emin < emin - 1
- (with equal probabilities); the reason is that we return
- just below instead of doing more iterations in the "while"
- loop to find the final value of emin. */
- __gmpfr_flags |= MPFR_FLAGS_UNDERFLOW;
- if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
- || (rnd_mode == MPFR_RNDN && exp == __gmpfr_emin - 1
- && (cnt != DRAW_BITS || random_rounding_bit (rstate))))
- {
- mpfr_set_ui_2exp (rop, 1, __gmpfr_emin - 1, rnd_mode);
- MPFR_RET (+1);
- }
- else
- {
- MPFR_SET_ZERO (rop);
- MPFR_RET (-1);
- }
- }
- MPFR_ASSERTD (exp >= __gmpfr_emin);
+ /* Any value of exp < MPFR_EMIN_MIN - 1 are equivalent. So, we can
+ avoid a theoretical integer overflow in the following way. */
+ if (MPFR_LIKELY (exp >= MPFR_EMIN_MIN - 1))
+ exp -= cnt; /* no integer overflow */
}
-
- MPFR_ASSERTD (exp >= __gmpfr_emin);
- MPFR_EXP (rop) = exp; /* Warning: may be larger than emax */
+ while (cnt == DRAW_BITS);
+ /* We do not want the random generator to depend on the ABI or on the
+ exponent range. Therefore we do not use MPFR_EMIN_MIN or __gmpfr_emin
+ in the stop condition. */
/* Step 2 (significand): we need generate only nbits-1 bits, since the
most significant bit is 1. */
- mpfr_rand_raw (rp, rstate, nbits - 1);
- nlimbs = MPFR_LIMB_SIZE (rop);
- n = nlimbs * GMP_NUMB_BITS - nbits;
- if (MPFR_LIKELY (n != 0)) /* this will put the low bits to zero */
- mpn_lshift (rp, rp, nlimbs, n);
- rp[nlimbs - 1] |= MPFR_LIMB_HIGHBIT;
-
- /* Rounding */
+ if (MPFR_UNLIKELY (nbits == 1))
+ {
+ rp[0] = MPFR_LIMB_HIGHBIT;
+ }
+ else
+ {
+ mpfr_rand_raw (rp, rstate, nbits - 1);
+ nlimbs = MPFR_LIMB_SIZE (rop);
+ n = nlimbs * GMP_NUMB_BITS - nbits;
+ if (MPFR_LIKELY (n != 0)) /* this will put the low bits to zero */
+ mpn_lshift (rp, rp, nlimbs, n);
+ rp[nlimbs - 1] |= MPFR_LIMB_HIGHBIT;
+ }
+
+ /* Rounding bit */
+ mpfr_rand_raw (&rbit, rstate, 1);
+ MPFR_ASSERTD (rbit == 0 || rbit == 1);
+
+ /* Step 3 (rounding). */
if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
- || (rnd_mode == MPFR_RNDN && random_rounding_bit (rstate)))
+ || (rnd_mode == MPFR_RNDN && rbit != 0))
{
- if (MPFR_UNLIKELY (exp > __gmpfr_emax))
- mpfr_set_inf (rop, +1); /* overflow */
- else
- mpfr_nextabove (rop);
+ mpfr_nextabove (rop);
inex = +1;
- /* There is an overflow in the first case and possibly in the second
- case. If this occurs, the flag will be set by mpfr_check_range. */
}
else
- inex = -1;
+ {
+ inex = -1;
+ }
+ MPFR_EXP (rop) += exp; /* may be smaller than emin */
+ MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (rop, inex, rnd_mode);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/urandomb.c b/Build/source/libs/mpfr/mpfr-src/src/urandomb.c
index 5eea6a2f21b..b1f1c9488dc 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/urandomb.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/urandomb.c
@@ -36,16 +36,14 @@ mpfr_rand_raw (mpfr_limb_ptr mp, gmp_randstate_t rstate,
mpz_t z;
MPFR_ASSERTN (nbits >= 1);
- /* To be sure to avoid the potential allocation of mpz_urandomb */
- ALLOC(z) = SIZ(z) = MPFR_PREC2LIMBS (nbits);
- PTR(z) = mp;
-#if __MPFR_GMP(5,0,0)
/* Check for integer overflow (unless mp_bitcnt_t is signed,
but according to the GMP manual, this shouldn't happen).
Note: mp_bitcnt_t has been introduced in GMP 5.0.0. */
MPFR_ASSERTN ((mp_bitcnt_t) -1 < 0 || nbits <= (mp_bitcnt_t) -1);
-#endif
+ mpz_init (z);
mpz_urandomb (z, rstate, nbits);
+ MPN_COPY(mp, PTR(z), MPFR_PREC2LIMBS (nbits));
+ mpz_clear (z);
}
int
@@ -85,7 +83,8 @@ mpfr_urandomb (mpfr_ptr rop, gmp_randstate_t rstate)
{
count_leading_zeros (cnt, rp[nlimbs - 1]);
/* Normalization */
- if (mpfr_set_exp (rop, exp - cnt))
+ exp -= cnt;
+ if (MPFR_UNLIKELY (! MPFR_EXP_IN_RANGE (exp)))
{
/* If the exponent is not in the current exponent range, we
choose to return a NaN as this is probably a user error.
@@ -96,10 +95,11 @@ mpfr_urandomb (mpfr_ptr rop, gmp_randstate_t rstate)
__gmpfr_flags |= MPFR_FLAGS_NAN; /* Can't use MPFR_RET_NAN */
return 1;
}
+ MPFR_SET_EXP (rop, exp);
if (cnt != 0)
mpn_lshift (rp + k, rp, nlimbs, cnt);
else if (k != 0)
- MPN_COPY (rp + k, rp, nlimbs);
+ mpn_copyd (rp + k, rp, nlimbs);
if (k != 0)
MPN_ZERO (rp, k);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c b/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c
index 08855d10191..689fc82a690 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c
@@ -1,5 +1,5 @@
-/* mpfr_vasprintf -- main function for the printf functions family
- plus helper macros & functions.
+/* mpfr_vasnprintf_aux -- helper function for the formatted output functions
+ (printf functions family).
Copyright 2007-2017 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -21,12 +21,31 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+/* If the number of output characters is larger than INT_MAX, the
+ ISO C99 standard is silent, but POSIX says concerning the snprintf()
+ function:
+ "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
+ number of bytes needed to hold the output excluding the
+ terminating null is greater than {INT_MAX}." See:
+ http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
+ But it doesn't say anything concerning the other printf-like functions.
+ A defect report has been submitted to austin-review-l (item 2532).
+ So, for the time being, we return a negative value and set the erange
+ flag, and set errno to EOVERFLOW in POSIX system. */
+
+/* Note: Due to limitations from the C standard and GMP, if
+ size_t < unsigned int (which is allowed by the C standard but unlikely
+ to occur on any platform), the behavior is undefined for output that
+ would reach SIZE_MAX = (size_t) -1 (if the result cannot be delivered,
+ there should be an assertion failure, but this could not be tested). */
+
#ifdef HAVE_CONFIG_H
-#include "config.h"
+# include "config.h"
#endif
-/* The mpfr_printf-like functions are defined only if <stdarg.h> exists */
-#ifdef HAVE_STDARG
+/* The mpfr_printf-like functions are defined only if <stdarg.h> exists.
+ Since they use mpf_t, they cannot be defined with mini-gmp. */
+#if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
#include <stdarg.h>
@@ -47,7 +66,6 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#if defined (__cplusplus)
#include <cstddef>
-#define __STDC_LIMIT_MACROS /* SIZE_MAX defined with <stdint.h> inclusion */
#else
#include <stddef.h> /* for ptrdiff_t */
#endif
@@ -159,9 +177,10 @@ struct printf_spec
int width; /* Width */
int prec; /* Precision */
+ size_t size; /* Wanted size (0 iff snprintf with size=0) */
enum arg_t arg_type; /* Type of argument */
- mpfr_rnd_t rnd_mode; /* Rounding mode */
+ mpfr_rnd_t rnd_mode; /* Rounding mode */
char spec; /* Conversion specifier */
char pad; /* Padding character */
@@ -177,6 +196,7 @@ specinfo_init (struct printf_spec *specinfo)
specinfo->group = 0;
specinfo->width = 0;
specinfo->prec = 0;
+ specinfo->size = 1;
specinfo->arg_type = NONE;
specinfo->rnd_mode = MPFR_RNDN;
specinfo->spec = '\0';
@@ -276,14 +296,10 @@ parse_arg_type (const char *format, struct printf_spec *specinfo)
break;
case 'h':
if (*++format == 'h')
-#ifndef NPRINTF_HH
{
++format;
specinfo->arg_type = CHAR_ARG;
}
-#else
- specinfo->arg_type = UNSUPPORTED;
-#endif
else
specinfo->arg_type = SHORT_ARG;
break;
@@ -291,7 +307,7 @@ parse_arg_type (const char *format, struct printf_spec *specinfo)
if (*++format == 'l')
{
++format;
-#if defined (HAVE_LONG_LONG) && !defined(NPRINTF_LL)
+#if defined (HAVE_LONG_LONG)
specinfo->arg_type = LONG_LONG_ARG;
#else
specinfo->arg_type = UNSUPPORTED;
@@ -305,7 +321,7 @@ parse_arg_type (const char *format, struct printf_spec *specinfo)
}
case 'j':
++format;
-#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
+#if defined(_MPFR_H_HAVE_INTMAX_T)
specinfo->arg_type = INTMAX_ARG;
#else
specinfo->arg_type = UNSUPPORTED;
@@ -317,19 +333,11 @@ parse_arg_type (const char *format, struct printf_spec *specinfo)
break;
case 't':
++format;
-#ifndef NPRINTF_T
specinfo->arg_type = PTRDIFF_ARG;
-#else
- specinfo->arg_type = UNSUPPORTED;
-#endif
break;
case 'L':
++format;
-#ifndef NPRINTF_L
specinfo->arg_type = LONG_DOUBLE_ARG;
-#else
- specinfo->arg_type = UNSUPPORTED;
-#endif
break;
case 'F':
++format;
@@ -385,9 +393,9 @@ typedef wint_t mpfr_va_wint;
#endif
#define CASE_LONG_ARG(specinfo, ap) \
case LONG_ARG: \
- if (((specinfo).spec == 'd') || ((specinfo).spec == 'i') \
- || ((specinfo).spec == 'o') || ((specinfo).spec == 'u') \
- || ((specinfo).spec == 'x') || ((specinfo).spec == 'X')) \
+ if ((specinfo).spec == 'd' || (specinfo).spec == 'i' \
+ || (specinfo).spec == 'o' || (specinfo).spec == 'u' \
+ || (specinfo).spec == 'x' || (specinfo).spec == 'X') \
(void) va_arg ((ap), long); \
else if ((specinfo).spec == 'c') \
(void) va_arg ((ap), mpfr_va_wint); \
@@ -487,7 +495,10 @@ typedef wint_t mpfr_va_wint;
} while (0)
/* process the format part which does not deal with mpfr types,
- jump to external label 'error' if gmp_asprintf return -1. */
+ jump to external label 'error' if gmp_asprintf return -1.
+ Note: start and end are pointers to the format string, so that
+ size_t is the best type to express the difference.
+ */
#define FLUSH(flag, start, end, ap, buf_ptr) \
do { \
const size_t n = (end) - (start); \
@@ -495,16 +506,21 @@ typedef wint_t mpfr_va_wint;
/* previous specifiers are understood by gmp_printf */ \
{ \
MPFR_TMP_DECL (marker); \
- char *fmt_copy; \
+ char *fmt_copy, *s; \
+ int length; \
+ \
MPFR_TMP_MARK (marker); \
fmt_copy = (char*) MPFR_TMP_ALLOC (n + 1); \
strncpy (fmt_copy, (start), n); \
fmt_copy[n] = '\0'; \
- if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1) \
+ length = gmp_vasprintf (&s, fmt_copy, (ap)); \
+ if (length < 0) \
{ \
MPFR_TMP_FREE (marker); \
goto error; \
} \
+ buffer_cat ((buf_ptr), s, length); \
+ mpfr_free_str (s); \
(flag) = 0; \
MPFR_TMP_FREE (marker); \
} \
@@ -513,20 +529,56 @@ typedef wint_t mpfr_va_wint;
buffer_cat ((buf_ptr), (start), n); \
} while (0)
+/* Note: in case some form of %n is used in the format string,
+ we may need the maximum signed integer type for len. */
struct string_buffer
{
char *start; /* beginning of the buffer */
char *curr; /* null terminating character */
size_t size; /* buffer capacity */
+ mpfr_intmax_t len; /* string length or -1 if overflow */
};
static void
buffer_init (struct string_buffer *b, size_t s)
{
- b->start = (char *) (*__gmp_allocate_func) (s);
- b->start[0] = '\0';
- b->curr = b->start;
+ if (s != 0)
+ {
+ b->start = (char *) mpfr_allocate_func (s);
+ b->start[0] = '\0';
+ b->curr = b->start;
+ }
b->size = s;
+ b->len = 0;
+}
+
+/* Increase the len field of the buffer. Return non-zero iff overflow. */
+static int
+buffer_incr_len (struct string_buffer *b, size_t len)
+{
+ if (b->len == -1)
+ return 1;
+ else
+ {
+ /* We need to take mpfr_uintmax_t as the type must be as large
+ as both size_t (which is unsigned) and mpfr_intmax_t (which
+ is used for the 'n' format specifier). */
+ mpfr_uintmax_t newlen = (mpfr_uintmax_t) b->len + len;
+
+ /* mpfr_uintmax_t is unsigned, thus the above is valid, but one
+ has newlen < len in case of overflow. */
+
+ if (MPFR_UNLIKELY (newlen < len || newlen > MPFR_INTMAX_MAX))
+ {
+ b->len = -1;
+ return 1;
+ }
+ else
+ {
+ b->len = newlen;
+ return 0;
+ }
+ }
}
/* Increase buffer size by a number of character being the least multiple of
@@ -536,13 +588,19 @@ buffer_widen (struct string_buffer *b, size_t len)
{
const size_t pos = b->curr - b->start;
const size_t n = 0x1000 + (len & ~((size_t) 0xfff));
+
+ /* There are currently limitations here. We would need to switch to
+ the null-size behavior once there is an overflow in the buffer. */
+
+ MPFR_ASSERTN (n >= 0x1000 && n >= len);
+
+ MPFR_ASSERTD (*b->curr == '\0');
MPFR_ASSERTD (pos < b->size);
- MPFR_ASSERTN ((len & ~((size_t) 4095)) <= (size_t)(SIZE_MAX - 4096));
- MPFR_ASSERTN (b->size < SIZE_MAX - n);
+ MPFR_ASSERTN (b->size < ((size_t) -1) - n);
b->start =
- (char *) (*__gmp_reallocate_func) (b->start, b->size, b->size + n);
+ (char *) mpfr_reallocate_func (b->start, b->size, b->size + n);
b->size += n;
b->curr = b->start + pos;
@@ -551,121 +609,145 @@ buffer_widen (struct string_buffer *b, size_t len)
}
/* Concatenate the LEN first characters of the string S to the buffer B and
- expand it if needed. */
-static void
+ expand it if needed. Return non-zero if overflow. */
+static int
buffer_cat (struct string_buffer *b, const char *s, size_t len)
{
- MPFR_ASSERTD (len != 0);
+ MPFR_ASSERTD (len > 0);
MPFR_ASSERTD (len <= strlen (s));
- if (MPFR_UNLIKELY ((b->curr + len) >= (b->start + b->size)))
- buffer_widen (b, len);
+ if (buffer_incr_len (b, len))
+ return 1;
- strncat (b->curr, s, len);
- b->curr += len;
+ if (b->size != 0)
+ {
+ MPFR_ASSERTD (*b->curr == '\0');
+ MPFR_ASSERTN (b->size < ((size_t) -1) - len);
+ if (MPFR_UNLIKELY (b->curr + len >= b->start + b->size))
+ buffer_widen (b, len);
+
+ /* strncat is similar to strncpy here, except that strncat ensures
+ that the buffer will be null-terminated. */
+ strncat (b->curr, s, len);
+ b->curr += len;
+
+ MPFR_ASSERTD (b->curr < b->start + b->size);
+ MPFR_ASSERTD (*b->curr == '\0');
+ }
- MPFR_ASSERTD (b->curr < b->start + b->size);
- MPFR_ASSERTD (*b->curr == '\0');
+ return 0;
}
-/* Add N characters C to the end of buffer B */
-static void
+/* Add N characters C to the end of buffer B. Return non-zero if overflow. */
+static int
buffer_pad (struct string_buffer *b, const char c, const size_t n)
{
- MPFR_ASSERTD (n != 0);
+ MPFR_ASSERTD (n > 0);
- MPFR_ASSERTN (b->size < SIZE_MAX - n - 1);
- if (MPFR_UNLIKELY ((b->curr + n + 1) > (b->start + b->size)))
- buffer_widen (b, n);
+ if (buffer_incr_len (b, n))
+ return 1;
- if (n == 1)
- *b->curr = c;
- else
- memset (b->curr, c, n);
- b->curr += n;
- *b->curr = '\0';
+ if (b->size != 0)
+ {
+ MPFR_ASSERTD (*b->curr == '\0');
+ MPFR_ASSERTN (b->size < ((size_t) -1) - n);
+ if (MPFR_UNLIKELY (b->curr + n >= b->start + b->size))
+ buffer_widen (b, n);
+
+ if (n == 1)
+ *b->curr = c;
+ else
+ memset (b->curr, c, n);
+ b->curr += n;
+ *b->curr = '\0';
- MPFR_ASSERTD (b->curr < b->start + b->size);
+ MPFR_ASSERTD (b->curr < b->start + b->size);
+ }
+
+ return 0;
}
/* Form a string by concatenating the first LEN characters of STR to TZ
zero(s), insert into one character C each 3 characters starting from end
- to begining and concatenate the result to the buffer B. */
-static void
+ to beginning and concatenate the result to the buffer B. */
+static int
buffer_sandwich (struct string_buffer *b, char *str, size_t len,
const size_t tz, const char c)
{
- const size_t step = 3;
- const size_t size = len + tz;
- const size_t r = size % step == 0 ? step : size % step;
- const size_t q = size % step == 0 ? size / step - 1 : size / step;
- size_t i;
+ MPFR_ASSERTD (len <= strlen (str));
- MPFR_ASSERTD (size != 0);
if (c == '\0')
- {
- buffer_cat (b, str, len);
+ return
+ buffer_cat (b, str, len) ||
buffer_pad (b, '0', tz);
- return;
- }
+ else
+ {
+ const size_t step = 3;
+ const size_t size = len + tz;
+ const size_t r = size % step == 0 ? step : size % step;
+ const size_t q = size % step == 0 ? size / step - 1 : size / step;
+ const size_t fullsize = size + q;
+ size_t i;
- MPFR_ASSERTN (b->size < SIZE_MAX - size - 1 - q);
- MPFR_ASSERTD (len <= strlen (str));
- if (MPFR_UNLIKELY ((b->curr + size + 1 + q) > (b->start + b->size)))
- buffer_widen (b, size + q);
+ MPFR_ASSERTD (size > 0);
- /* first R significant digits */
- memcpy (b->curr, str, r);
- b->curr += r;
- str += r;
- len -= r;
+ if (buffer_incr_len (b, fullsize))
+ return 1;
- /* blocks of thousands. Warning: STR might end in the middle of a block */
- for (i = 0; i < q; ++i)
- {
- *b->curr++ = c;
- if (MPFR_LIKELY (len > 0))
+ if (b->size != 0)
{
- if (MPFR_LIKELY (len >= step))
- /* step significant digits */
- {
- memcpy (b->curr, str, step);
- len -= step;
- }
- else
- /* last digits in STR, fill up thousand block with zeros */
- {
- memcpy (b->curr, str, len);
- memset (b->curr + len, '0', step - len);
- len = 0;
- }
- }
- else
- /* trailing zeros */
- memset (b->curr, '0', step);
+ char *oldcurr;
- b->curr += step;
- str += step;
- }
+ MPFR_ASSERTD (*b->curr == '\0');
+ MPFR_ASSERTN (b->size < ((size_t) -1) - fullsize);
+ if (MPFR_UNLIKELY (b->curr + fullsize >= b->start + b->size))
+ buffer_widen (b, fullsize);
- *b->curr = '\0';
+ MPFR_DBGRES (oldcurr = b->curr);
- MPFR_ASSERTD (b->curr < b->start + b->size);
-}
+ /* first R significant digits */
+ memcpy (b->curr, str, r);
+ b->curr += r;
+ str += r;
+ len -= r;
-/* let gmp_xprintf process the part it can understand */
-static int
-sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap)
-{
- int length;
- char *s;
+ /* blocks of thousands. Warning: STR might end in the middle of a block */
+ for (i = 0; i < q; ++i)
+ {
+ *b->curr++ = c;
+ if (MPFR_LIKELY (len > 0))
+ {
+ if (MPFR_LIKELY (len >= step))
+ /* step significant digits */
+ {
+ memcpy (b->curr, str, step);
+ len -= step;
+ }
+ else
+ /* last digits in STR, fill up thousand block with zeros */
+ {
+ memcpy (b->curr, str, len);
+ memset (b->curr + len, '0', step - len);
+ len = 0;
+ }
+ }
+ else
+ /* trailing zeros */
+ memset (b->curr, '0', step);
- length = gmp_vasprintf (&s, fmt, ap);
- if (length > 0)
- buffer_cat (b, s, length);
+ b->curr += step;
+ str += step;
+ }
+
+ MPFR_ASSERTD (b->curr - oldcurr == fullsize);
+
+ *b->curr = '\0';
+
+ MPFR_ASSERTD (b->curr < b->start + b->size);
+ }
- mpfr_free_str (s);
- return length;
+ return 0;
+ }
}
/* Helper struct and functions for temporary strings management */
@@ -676,7 +758,7 @@ struct string_list
struct string_list *next; /* NULL in last node */
};
-/* initialisation */
+/* initialization */
static void
init_string_list (struct string_list *sl)
{
@@ -695,7 +777,7 @@ clear_string_list (struct string_list *sl)
if (sl->string)
mpfr_free_str (sl->string);
n = sl->next;
- (*__gmp_free_func) (sl, sizeof(struct string_list));
+ mpfr_free_func (sl, sizeof(struct string_list));
sl = n;
}
}
@@ -709,7 +791,7 @@ register_string (struct string_list *sl, char *new_string)
sl = sl->next;
sl->next = (struct string_list*)
- (*__gmp_allocate_func) (sizeof (struct string_list));
+ mpfr_allocate_func (sizeof (struct string_list));
sl = sl->next;
sl->next = NULL;
@@ -832,6 +914,52 @@ floor_log10 (mpfr_srcptr x)
return exp;
}
+#define NDIGITS 8
+
+static char*
+mpfr_get_str_aux (mpfr_exp_t *exp, int base, size_t n, const mpfr_t op,
+ const struct printf_spec spec)
+{
+ size_t ndigits;
+ char *str, *s, nine;
+ int neg;
+
+ if (spec.size != 0)
+ return mpfr_get_str (NULL, exp, base, n, op, spec.rnd_mode);
+
+ /* Special case size = 0, i.e., xxx_snprintf with size = 0: we only want
+ to compute the number of printed characters. Try to deduce it from
+ a small number of significant digits. */
+ nine = (base <= 10) ? '0' + base - 1
+ : (base <= 36) ? 'a' + base - 11
+ : 'a' + base - 37;
+ for (ndigits = NDIGITS; ; ndigits *= 2)
+ {
+ mpfr_rnd_t rnd = MPFR_RNDZ;
+ /* when ndigits > n, we reduce it to the target size n, and then we use
+ the wanted rounding mode, to avoid errors for example when n=1 and
+ x = 9.5 with spec.rnd_mode = RNDU */
+ if (ndigits >= n)
+ {
+ ndigits = n;
+ rnd = spec.rnd_mode;
+ }
+ str = mpfr_get_str (NULL, exp, base, ndigits, op, rnd);
+ if (ndigits == n)
+ break;
+ neg = str[0] == '-';
+ s = str + neg;
+ while (*s == nine)
+ s ++;
+ if (s < str + neg + ndigits) /* we don't have ndigits 'nines' */
+ break;
+ mpfr_free_str (str);
+ MPFR_ASSERTN (ndigits <= ((size_t) -1) / 2);
+ /* to make sure that the product by 2 is representable. */
+ }
+ return str;
+}
+
/* Determine the different parts of the string representation of the regular
number P when SPEC.SPEC is 'a', 'A', or 'b'.
@@ -857,7 +985,7 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
/* prefix part */
{
np->prefix_size = 2;
- str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
+ str = (char *) mpfr_allocate_func (1 + np->prefix_size);
str[0] = '0';
str[1] = uppercase ? 'X' : 'x';
str[2] = '\0';
@@ -875,9 +1003,11 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
/* Number of significant digits:
- if no given precision, let mpfr_get_str determine it;
- if a non-zero precision is specified, then one digit before decimal
- point plus SPEC.PREC after it. */
- nsd = spec.prec < 0 ? 0 : spec.prec + np->ip_size;
- str = mpfr_get_str (0, &exp, base, nsd, p, spec.rnd_mode);
+ point plus SPEC.PREC after it (which will give nsd > 1 below). */
+ MPFR_ASSERTD (np->ip_size == 1); /* thus no integer overflow below */
+ nsd = spec.prec < 0 ? 0 : (size_t) spec.prec + np->ip_size;
+ MPFR_ASSERTD (nsd != 1);
+ str = mpfr_get_str_aux (&exp, base, nsd, p, spec);
register_string (np->sl, str);
np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
@@ -903,7 +1033,7 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
}
else if (next_base_power_p (p, base, spec.rnd_mode))
{
- str = (char *)(*__gmp_allocate_func) (2);
+ str = (char *)mpfr_allocate_func (2);
str[0] = '1';
str[1] = '\0';
np->ip_ptr = register_string (np->sl, str);
@@ -912,7 +1042,7 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
}
else if (base == 2)
{
- str = (char *)(*__gmp_allocate_func) (2);
+ str = (char *)mpfr_allocate_func (2);
str[0] = '1';
str[1] = '\0';
np->ip_ptr = register_string (np->sl, str);
@@ -933,9 +1063,9 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
|| (spec.rnd_mode == MPFR_RNDN
&& (msl & (MPFR_LIMB_ONE << rnd_bit))))
digit++;
- MPFR_ASSERTD ((0 <= digit) && (digit <= 15));
+ MPFR_ASSERTD (0 <= digit && digit <= 15);
- str = (char *)(*__gmp_allocate_func) (1 + np->ip_size);
+ str = (char *)mpfr_allocate_func (1 + np->ip_size);
str[0] = num_to_text [digit];
str[1] = '\0';
np->ip_ptr = register_string (np->sl, str);
@@ -988,7 +1118,7 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
if (spec.prec < 0)
/* remove trailing zeros, if any */
{
- while ((*ptr == '0') && (str_len != 0))
+ while (*ptr == '0' && str_len != 0)
{
--ptr;
--str_len;
@@ -1004,13 +1134,14 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
{
np->fp_ptr = str;
np->fp_size = str_len;
+ MPFR_ASSERTD (str_len > 0 && str_len <= INT_MAX);
if ((int) str_len < spec.prec)
np->fp_trailing_zeros = spec.prec - str_len;
}
}
/* decimal point */
- if ((np->fp_size != 0) || spec.alt)
+ if (np->fp_size != 0 || spec.alt)
np->point = MPFR_DECIMAL_POINT;
/* the exponent part contains the character 'p', or 'P' plus the sign
@@ -1028,7 +1159,7 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
x /= 10;
}
}
- str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
+ str = (char *) mpfr_allocate_func (1 + np->exp_size);
np->exp_ptr = register_string (np->sl, str);
{
char exp_fmt[8]; /* contains at most 7 characters like in "p%+.1i",
@@ -1047,7 +1178,7 @@ regular_ab (struct number_parts *np, mpfr_srcptr p,
/* Determine the different parts of the string representation of the regular
number P when spec.spec is 'e', 'E', 'g', or 'G'.
- DEC_INFO contains the previously computed exponent and string or is NULL.
+ dec_info contains the previously computed exponent and string or is NULL.
return -1 if some field > INT_MAX */
static int
@@ -1080,8 +1211,9 @@ regular_eg (struct number_parts *np, mpfr_srcptr p,
plus SPEC.PREC after it.
We use the fact here that mpfr_get_str allows us to ask for only one
significant digit when the base is not a power of 2. */
- nsd = (spec.prec < 0) ? 0 : spec.prec + np->ip_size;
- str = mpfr_get_str (0, &exp, 10, nsd, p, spec.rnd_mode);
+ MPFR_ASSERTD (np->ip_size == 1); /* thus no integer overflow below */
+ nsd = spec.prec < 0 ? 0 : (size_t) spec.prec + np->ip_size;
+ str = mpfr_get_str_aux (&exp, 10, nsd, p, spec);
register_string (np->sl, str);
}
else
@@ -1105,7 +1237,7 @@ regular_eg (struct number_parts *np, mpfr_srcptr p,
if (!keep_trailing_zeros)
/* remove trailing zeros, if any */
{
- while ((*ptr == '0') && (str_len != 0))
+ while (*ptr == '0' && str_len != 0)
{
--ptr;
--str_len;
@@ -1121,8 +1253,9 @@ regular_eg (struct number_parts *np, mpfr_srcptr p,
{
np->fp_ptr = str;
np->fp_size = str_len;
- if ((!spec_g || spec.alt) && (spec.prec > 0)
- && ((int)str_len < spec.prec))
+ MPFR_ASSERTD (str_len > 0 && str_len <= INT_MAX);
+ if ((!spec_g || spec.alt) && spec.prec > 0
+ && (int) str_len < spec.prec)
/* add missing trailing zeros */
np->fp_trailing_zeros = spec.prec - str_len;
}
@@ -1155,7 +1288,7 @@ regular_eg (struct number_parts *np, mpfr_srcptr p,
if (np->exp_size < 4)
np->exp_size = 4;
- str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
+ str = (char *) mpfr_allocate_func (1 + np->exp_size);
np->exp_ptr = register_string (np->sl, str);
{
@@ -1201,7 +1334,7 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
{
/* Most of the time, integral part is 0 */
np->ip_size = 1;
- str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ str = (char *) mpfr_allocate_func (1 + np->ip_size);
str[0] = '0';
str[1] = '\0';
np->ip_ptr = register_string (np->sl, str);
@@ -1234,20 +1367,28 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
switch (spec.rnd_mode)
{
case MPFR_RNDA:
+ case MPFR_RNDF: /* round_away = 1 needed for spec_g */
round_away = 1;
break;
+ case MPFR_RNDZ:
+ round_away = 0;
+ break;
case MPFR_RNDD:
round_away = MPFR_IS_NEG (p);
break;
case MPFR_RNDU:
round_away = MPFR_IS_POS (p);
break;
- case MPFR_RNDN:
+ default:
{
/* compare |p| to y = 0.5*10^(-spec.prec) */
mpfr_t y;
mpfr_exp_t e = MAX (MPFR_PREC (p), 56);
+ int cmp;
+
+ MPFR_ASSERTN (spec.rnd_mode == MPFR_RNDN);
mpfr_init2 (y, e + 8);
+
do
{
/* find a lower approximation of
@@ -1257,14 +1398,14 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
mpfr_set_si (y, -spec.prec, MPFR_RNDN);
mpfr_exp10 (y, y, MPFR_RNDD);
mpfr_div_2ui (y, y, 1, MPFR_RNDN);
- } while (mpfr_cmpabs (y, p) == 0);
+ cmp = mpfr_cmpabs (y, p);
+ }
+ while (cmp == 0);
- round_away = mpfr_cmpabs (y, p) < 0;
+ round_away = cmp < 0;
mpfr_clear (y);
}
break;
- default:
- round_away = 0;
}
if (round_away)
@@ -1274,7 +1415,7 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
np->fp_size = 1;
str =
- (char *) (*__gmp_allocate_func) (1 + np->fp_size);
+ (char *) mpfr_allocate_func (1 + np->fp_size);
str[0] = '1';
str[1] = '\0';
np->fp_ptr = register_string (np->sl, str);
@@ -1286,21 +1427,31 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
np->fp_leading_zeros = spec.prec;
}
}
- else
+ else /* exp >= -spec.prec */
/* the most significant digits are the last
spec.prec + exp + 1 digits in fractional part */
{
char *ptr;
size_t str_len;
+
+ MPFR_ASSERTD (exp >= -spec.prec);
if (dec_info == NULL)
{
- size_t nsd = spec.prec + exp + 1;
+ size_t nsd;
+
+ /* Consequences of earlier assertions (in r11307).
+ They guarantee that the integers are representable
+ (i.e., no integer overflow), assuming size_t >= int
+ as usual. */
+ MPFR_ASSERTD (exp <= -1);
+ MPFR_ASSERTD (spec.prec + (exp + 1) >= 0);
+ nsd = spec.prec + (exp + 1);
/* WARNING: nsd may equal 1, but here we use the
fact that mpfr_get_str can return one digit with
base ten (undocumented feature, see comments in
get_str.c) */
- str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
+ str = mpfr_get_str_aux (&exp, 10, nsd, p, spec);
register_string (np->sl, str);
}
else
@@ -1331,7 +1482,7 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
if (!keep_trailing_zeros)
/* remove trailing zeros, if any */
{
- while ((*ptr == '0') && str_len)
+ while (*ptr == '0' && str_len != 0)
{
--ptr;
--str_len;
@@ -1373,8 +1524,7 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
if (dec_info == NULL)
{ /* this case occurs with mpfr_printf ("%.0RUf", x) with x=9.5 */
- str =
- mpfr_get_str (NULL, &exp, 10, spec.prec+exp+1, p, spec.rnd_mode);
+ str = mpfr_get_str_aux (&exp, 10, spec.prec+exp+1, p, spec);
register_string (np->sl, str);
}
else
@@ -1408,7 +1558,7 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
{
char *ptr = str + str_len - 1; /* pointer to the last digit of
str */
- while ((*ptr == '0') && (str_len != 0))
+ while (*ptr == '0' && str_len != 0)
{
--ptr;
--str_len;
@@ -1447,9 +1597,9 @@ regular_fg (struct number_parts *np, mpfr_srcptr p,
partition_number initializes the given structure np, so all previous
information in that variable is lost.
return the total number of characters to be written.
- return -1 if an error occured, in that case np's fields are in an undefined
+ return -1 if an error occurred, in that case np's fields are in an undefined
state but all string buffers have been freed. */
-static int
+static mpfr_intmax_t
partition_number (struct number_parts *np, mpfr_srcptr p,
struct printf_spec spec)
{
@@ -1475,7 +1625,7 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
np->exp_ptr = NULL;
np->exp_size = 0;
np->sl = (struct string_list *)
- (*__gmp_allocate_func) (sizeof (struct string_list));
+ mpfr_allocate_func (sizeof (struct string_list));
init_string_list (np->sl);
uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
@@ -1490,20 +1640,10 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
with left spaces instead */
np->pad_type = LEFT;
- if (uppercase)
- {
- np->ip_size = MPFR_NAN_STRING_LENGTH;
- str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
- strcpy (str, MPFR_NAN_STRING_UC);
- np->ip_ptr = register_string (np->sl, str);
- }
- else
- {
- np->ip_size = MPFR_NAN_STRING_LENGTH;
- str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
- strcpy (str, MPFR_NAN_STRING_LC);
- np->ip_ptr = register_string (np->sl, str);
- }
+ np->ip_size = MPFR_NAN_STRING_LENGTH;
+ str = (char *) mpfr_allocate_func (1 + np->ip_size);
+ strcpy (str, uppercase ? MPFR_NAN_STRING_UC : MPFR_NAN_STRING_LC);
+ np->ip_ptr = register_string (np->sl, str);
}
else if (MPFR_IS_INF (p))
{
@@ -1515,24 +1655,14 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
if (MPFR_IS_NEG (p))
np->sign = '-';
- if (uppercase)
- {
- np->ip_size = MPFR_INF_STRING_LENGTH;
- str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
- strcpy (str, MPFR_INF_STRING_UC);
- np->ip_ptr = register_string (np->sl, str);
- }
- else
- {
- np->ip_size = MPFR_INF_STRING_LENGTH;
- str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
- strcpy (str, MPFR_INF_STRING_LC);
- np->ip_ptr = register_string (np->sl, str);
- }
+ np->ip_size = MPFR_INF_STRING_LENGTH;
+ str = (char *) mpfr_allocate_func (1 + np->ip_size);
+ strcpy (str, uppercase ? MPFR_INF_STRING_UC : MPFR_INF_STRING_LC);
+ np->ip_ptr = register_string (np->sl, str);
}
else
- /* p == 0 */
{
+ MPFR_ASSERTD (MPFR_IS_ZERO (p));
/* note: for 'g' spec, zero is always displayed with 'f'-style with
precision spec.prec - 1 and the trailing zeros are removed unless
the flag '#' is used. */
@@ -1546,7 +1676,7 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
/* prefix part */
{
np->prefix_size = 2;
- str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
+ str = (char *) mpfr_allocate_func (1 + np->prefix_size);
str[0] = '0';
str[1] = uppercase ? 'X' : 'x';
str[2] = '\0';
@@ -1555,7 +1685,7 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
/* integral part */
np->ip_size = 1;
- str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ str = (char *) mpfr_allocate_func (1 + np->ip_size);
str[0] = '0';
str[1] = '\0';
np->ip_ptr = register_string (np->sl, str);
@@ -1576,7 +1706,7 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
/* exponent part */
{
np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
- str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
+ str = (char *) mpfr_allocate_func (1 + np->exp_size);
if (spec.spec == 'e' || spec.spec == 'E')
strcpy (str, uppercase ? "E+00" : "e+00");
else
@@ -1585,9 +1715,27 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
}
}
}
+ else if (MPFR_UNLIKELY (MPFR_IS_UBF (p)))
+ {
+ /* mpfr_get_str does not support UBF, so that UBF numbers are regarded
+ as special cases here. This is not much a problem since UBF numbers
+ are internal to MPFR and here, they only for logging. */
+ if (np->pad_type == LEADING_ZEROS)
+ /* change to right justification padding with left spaces */
+ np->pad_type = LEFT;
+
+ if (MPFR_IS_NEG (p))
+ np->sign = '-';
+
+ np->ip_size = 3;
+ str = (char *) mpfr_allocate_func (1 + np->ip_size);
+ strcpy (str, uppercase ? "UBF" : "ubf");
+ np->ip_ptr = register_string (np->sl, str);
+ /* TODO: output more information (e.g. the exponent) if need be. */
+ }
else
- /* regular p, p != 0 */
{
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (p));
if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
{
if (regular_ab (np, p, spec) == -1)
@@ -1616,12 +1764,38 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
where T is the threshold computed below and X is the exponent
that would be displayed with style 'e' and precision T-1. */
int threshold;
- mpfr_exp_t x;
+ mpfr_exp_t x, e, k;
struct decimal_info dec_info;
threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec;
- dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10, threshold,
- p, spec.rnd_mode);
+
+ /* Here we cannot call mpfr_get_str_aux since we need the full
+ significand in dec_info.str.
+ Moreover, threshold may be huge while one can know that the
+ number of digits that are not trailing zeros remains limited;
+ such a limit occurs in practical cases, e.g. with numbers
+ representable in the IEEE 754-2008 basic formats. Since the
+ trailing zeros are not necessarily output, we do not want to
+ waste time and memory by making mpfr_get_str generate them.
+ So, let us try to find a smaller threshold for mpfr_get_str.
+ |p| < 2^EXP(p) = 10^(EXP(p)*log10(2)). So, the integer part
+ takes at most ceil(EXP(p)*log10(2)) digits (unless p rounds
+ to the next power of 10, but in this case any threshold will
+ be OK). So, for the integer part, we will take:
+ max(0,floor((EXP(p)+2)/3)).
+ Let k = PREC(p) - EXP(p), so that the last bit of p has
+ weight 2^(-k). If k <= 0, then p is an integer, otherwise
+ the fractional part in base 10 may have up to k digits
+ (this bound is reached if the last bit is 1).
+ Note: The bound could be improved, but this is not critical. */
+ e = MPFR_GET_EXP (p);
+ k = MPFR_PREC (p) - e;
+ e = e <= 0 ? k : (e + 2) / 3 + (k <= 0 ? 0 : k);
+ MPFR_ASSERTD (e >= 1);
+
+ dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10,
+ e < threshold ? e : threshold,
+ p, spec.rnd_mode);
register_string (np->sl, dec_info.str);
/* mpfr_get_str corresponds to a significand between 0.1 and 1,
whereas here we want a significand between 1 and 10. */
@@ -1648,14 +1822,14 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
/* compute the number of characters to be written verifying it is not too
much */
-#define INCR_TOTAL(v) \
- do { \
- MPFR_ASSERTD ((v) >= 0); \
- if (MPFR_UNLIKELY ((v) > INT_MAX)) \
- goto error; \
- total += (v); \
- if (MPFR_UNLIKELY (total > INT_MAX)) \
- goto error; \
+#define INCR_TOTAL(v) \
+ do { \
+ MPFR_ASSERTD ((v) >= 0); \
+ if (MPFR_UNLIKELY ((v) > MPFR_INTMAX_MAX)) \
+ goto error; \
+ total += (v); \
+ if (MPFR_UNLIKELY (total > MPFR_INTMAX_MAX)) \
+ goto error; \
} while (0)
total = np->sign ? 1 : 0;
@@ -1683,7 +1857,7 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
MPFR_ASSERTD (total == spec.width);
}
- MPFR_ASSERTD (total > 0 && total <= INT_MAX);
+ MPFR_ASSERTD (total > 0 && total <= MPFR_INTMAX_MAX);
return total;
error:
@@ -1699,17 +1873,33 @@ partition_number (struct number_parts *np, mpfr_srcptr p,
return the size of the string (not counting the terminating '\0')
return -1 if the built string is too long (i.e. has more than
- INT_MAX characters). */
+ INT_MAX or MPFR_INTMAX_MAX characters).
+
+ If spec.size is 0, we only want the size of the string.
+*/
static int
sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
const struct printf_spec spec)
{
- int length;
+ mpfr_intmax_t length, start;
struct number_parts np;
length = partition_number (&np, p, spec);
if (length < 0)
- return -1;
+ {
+ buf->len = -1;
+ return -1;
+ }
+
+ if (spec.size == 0)
+ {
+ /* This is equivalent to the following code (no need to fill the buffer
+ and length is known). */
+ buffer_incr_len (buf, length);
+ goto clear_and_exit;
+ }
+
+ MPFR_DBGRES (start = buf->len);
/* right justification padding with left spaces */
if (np.pad_type == LEFT && np.pad_size != 0)
@@ -1761,19 +1951,32 @@ sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
if (np.exp_ptr)
buffer_cat (buf, np.exp_ptr, np.exp_size);
- /* left justication padding with right spaces */
+ /* left justification padding with right spaces */
if (np.pad_type == RIGHT && np.pad_size != 0)
buffer_pad (buf, ' ', np.pad_size);
+ MPFR_ASSERTD (buf->len == -1 || buf->len - start == length);
+
+ clear_and_exit:
clear_string_list (np.sl);
- return length;
+ return buf->len == -1 ? -1 : length;
}
+/* The following internal function implements both mpfr_vasprintf and
+ mpfr_vsnprintf:
+ (a) either ptr <> NULL, and then Buf and size are not used, and it
+ implements mpfr_vasprintf (ptr, fmt, ap)
+ (b) or ptr = NULL, and it implements mpfr_vsnprintf (Buf, size, fmt, ap)
+ It returns the number of characters that would have been written had 'size'
+ been sufficiently large, not counting the terminating null character, or -1
+ if this number is too large for the return type 'int' (overflow).
+*/
int
-mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
+mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt,
+ va_list ap)
{
struct string_buffer buf;
- size_t nbchar;
+ int nbchar;
/* informations on the conversion specification filled by the parser */
struct printf_spec spec;
@@ -1788,15 +1991,14 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
MPFR_SAVE_EXPO_DECL (expo);
MPFR_SAVE_EXPO_MARK (expo);
- nbchar = 0;
- buffer_init (&buf, 4096);
+ buffer_init (&buf, ptr != NULL || size != 0 ? 4096 : 0);
xgmp_fmt_flag = 0;
va_copy (ap2, ap);
start = fmt;
- while (*fmt)
+ while (*fmt != '\0')
{
/* Look for the next format specification */
- while ((*fmt) && (*fmt != '%'))
+ while (*fmt != '\0' && *fmt != '%')
++fmt;
if (*fmt == '\0')
@@ -1839,10 +2041,12 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
fmt = parse_arg_type (fmt, &spec);
if (spec.arg_type == UNSUPPORTED)
- /* the current architecture doesn't support this type */
- {
- goto error;
- }
+ /* the current architecture doesn't support the type corresponding to
+ the format specifier; according to the ISO C99 standard, the
+ behavior is undefined. We choose to print the format specifier as a
+ literal string, what may be printed after this string is
+ undefined. */
+ continue;
else if (spec.arg_type == MPFR_ARG)
{
switch (*fmt)
@@ -1878,9 +2082,13 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
spec.spec = *fmt;
if (!specinfo_is_valid (spec))
- goto error;
+ /* the format specifier is invalid; according to the ISO C99 standard,
+ the behavior is undefined. We choose to print the invalid format
+ specifier as a literal string, what may be printed after this
+ string is undefined. */
+ continue;
- if (*fmt)
+ if (*fmt != '\0')
fmt++;
/* Format processing */
@@ -1894,49 +2102,47 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
so as to be able to accept the same format strings. */
{
void *p;
- size_t nchar;
p = va_arg (ap, void *);
FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
va_end (ap2);
start = fmt;
- nchar = buf.curr - buf.start;
switch (spec.arg_type)
{
case CHAR_ARG:
- *(char *) p = (char) nchar;
+ *(char *) p = (char) buf.len;
break;
case SHORT_ARG:
- *(short *) p = (short) nchar;
+ *(short *) p = (short) buf.len;
break;
case LONG_ARG:
- *(long *) p = (long) nchar;
+ *(long *) p = (long) buf.len;
break;
#ifdef HAVE_LONG_LONG
case LONG_LONG_ARG:
- *(long long *) p = (long long) nchar;
+ *(long long *) p = (long long) buf.len;
break;
#endif
#ifdef _MPFR_H_HAVE_INTMAX_T
case INTMAX_ARG:
- *(intmax_t *) p = (intmax_t) nchar;
+ *(intmax_t *) p = (intmax_t) buf.len;
break;
#endif
case SIZE_ARG:
- *(size_t *) p = nchar;
+ *(size_t *) p = buf.len;
break;
case PTRDIFF_ARG:
- *(ptrdiff_t *) p = (ptrdiff_t) nchar;
+ *(ptrdiff_t *) p = (ptrdiff_t) buf.len;
break;
case MPF_ARG:
- mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar);
+ mpf_set_ui ((mpf_ptr) p, (unsigned long) buf.len);
break;
case MPQ_ARG:
- mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L);
+ mpq_set_ui ((mpq_ptr) p, (unsigned long) buf.len, 1L);
break;
case MP_LIMB_ARG:
- *(mp_limb_t *) p = (mp_limb_t) nchar;
+ *(mp_limb_t *) p = (mp_limb_t) buf.len;
break;
case MP_LIMB_ARRAY_ARG:
{
@@ -1949,25 +2155,25 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
break;
/* we assume here that mp_limb_t is wider than int */
- *q = (mp_limb_t) nchar;
+ *q = (mp_limb_t) buf.len;
while (--n != 0)
{
q++;
- *q = (mp_limb_t) 0;
+ *q = MPFR_LIMB_ZERO;
}
}
break;
case MPZ_ARG:
- mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar);
+ mpz_set_ui ((mpz_ptr) p, (unsigned long) buf.len);
break;
case MPFR_ARG:
- mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar,
+ mpfr_set_ui ((mpfr_ptr) p, (unsigned long) buf.len,
spec.rnd_mode);
break;
default:
- *(int *) p = (int) nchar;
+ *(int *) p = (int) buf.len;
}
va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
case */
@@ -1979,6 +2185,7 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
size_t length;
mpfr_prec_t prec;
+
prec = va_arg (ap, mpfr_prec_t);
FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
@@ -1996,22 +2203,25 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
- if (buf.size <= INT_MAX - length)
- {
- buffer_cat (&buf, s, length);
- mpfr_free_str (s);
- }
- else
- {
- mpfr_free_str (s);
- goto overflow_error;
- }
+ MPFR_ASSERTN (length >= 0); /* guaranteed by GMP 6 */
+ buffer_cat (&buf, s, length);
+ mpfr_free_str (s);
}
else if (spec.arg_type == MPFR_ARG)
/* output a mpfr_t variable */
{
mpfr_srcptr p;
+ if (spec.spec != 'a' && spec.spec != 'A'
+ && spec.spec != 'b'
+ && spec.spec != 'e' && spec.spec != 'E'
+ && spec.spec != 'f' && spec.spec != 'F'
+ && spec.spec != 'g' && spec.spec != 'G')
+ /* the format specifier is invalid; skip the invalid format
+ specifier so as to print it as a literal string. What may be
+ printed after this string is undefined. */
+ continue;
+
p = va_arg (ap, mpfr_srcptr);
FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
@@ -2019,25 +2229,9 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
va_copy (ap2, ap);
start = fmt;
- switch (spec.spec)
- {
- case 'a':
- case 'A':
- case 'b':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- if (sprnt_fp (&buf, p, spec) < 0)
- goto overflow_error;
- break;
-
- default:
- /* unsupported specifier */
- goto error;
- }
+ if (ptr == NULL)
+ spec.size = size;
+ sprnt_fp (&buf, p, spec);
}
else
/* gmp_printf specification, step forward in the va_list */
@@ -2051,42 +2245,63 @@ mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
va_end (ap2);
- nbchar = buf.curr - buf.start;
- MPFR_ASSERTD (nbchar == strlen (buf.start));
- buf.start =
- (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1);
- buf.size = nbchar + 1; /* update needed for __gmp_free_func below when
- nbchar is too large (overflow_error) */
- *ptr = buf.start;
-
- /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
- POSIX says concerning the snprintf() function:
- "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
- number of bytes needed to hold the output excluding the
- terminating null is greater than {INT_MAX}." See:
- http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
- But it doesn't say anything concerning the other printf-like functions.
- A defect report has been submitted to austin-review-l (item 2532).
- So, for the time being, we return a negative value and set the erange
- flag, and set errno to EOVERFLOW in POSIX system. */
- if (nbchar <= INT_MAX)
+
+ if (buf.len > INT_MAX) /* overflow */
+ buf.len = -1;
+
+ if (buf.len != -1)
{
+ nbchar = buf.len;
+ MPFR_ASSERTD (nbchar >= 0);
+
+ if (ptr != NULL) /* implement mpfr_vasprintf */
+ {
+ MPFR_ASSERTD (nbchar == strlen (buf.start));
+ *ptr = (char *)
+ mpfr_reallocate_func (buf.start, buf.size, nbchar + 1);
+ }
+ else if (size > 0) /* implement mpfr_vsnprintf */
+ {
+ if (nbchar < size)
+ {
+ strncpy (Buf, buf.start, nbchar);
+ Buf[nbchar] = '\0';
+ }
+ else
+ {
+ strncpy (Buf, buf.start, size - 1);
+ Buf[size-1] = '\0';
+ }
+ mpfr_free_func (buf.start, buf.size);
+ }
+
MPFR_SAVE_EXPO_FREE (expo);
- return nbchar;
+ return nbchar; /* return the number of characters that would have
+ been written had 'size' been sufficiently large,
+ not counting the terminating null character */
}
- overflow_error:
- MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE);
+ error:
+ if (buf.len == -1) /* overflow */
+ {
+ MPFR_LOG_MSG (("Overflow\n", 0));
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_ERANGE);
#ifdef EOVERFLOW
- errno = EOVERFLOW;
+ MPFR_LOG_MSG (("Setting errno to EOVERFLOW\n", 0));
+ errno = EOVERFLOW;
#endif
+ }
- error:
MPFR_SAVE_EXPO_FREE (expo);
*ptr = NULL;
- (*__gmp_free_func) (buf.start, buf.size);
+ mpfr_free_func (buf.start, buf.size);
return -1;
}
+#else /* HAVE_STDARG */
+
+/* Avoid an empty translation unit (see ISO C99, 6.9) */
+typedef int foo;
+
#endif /* HAVE_STDARG */
diff --git a/Build/source/libs/mpfr/mpfr-src/src/version.c b/Build/source/libs/mpfr/mpfr-src/src/version.c
index 12d31a5fac0..3a9ce77e7c3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/version.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/version.c
@@ -25,5 +25,5 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
const char *
mpfr_get_version (void)
{
- return "3.1.6";
+ return "4.0.0";
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/yn.c b/Build/source/libs/mpfr/mpfr-src/src/yn.c
index 9caa97749f3..7153051837f 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/yn.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/yn.c
@@ -170,7 +170,7 @@ mpfr_yn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
0. We choose to return +0 in that case. */
else if (MPFR_IS_INF (z))
{
- if (MPFR_SIGN(z) > 0)
+ if (MPFR_IS_POS (z))
return mpfr_set_ui (res, 0, r);
else /* y(n,-Inf) = NaN */
{
@@ -186,14 +186,14 @@ mpfr_yn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
MPFR_SET_NEG(res);
else
MPFR_SET_POS(res);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET(0);
}
}
/* for z < 0, y(n,z) is imaginary except when j(n,|z|) = 0, which we
assume does not happen for a rational z. */
- if (MPFR_SIGN(z) < 0)
+ if (MPFR_IS_NEG (z))
{
MPFR_SET_NAN (res);
MPFR_RET_NAN;
diff --git a/Build/source/libs/mpfr/mpfr-src/src/zeta.c b/Build/source/libs/mpfr/mpfr-src/src/zeta.c
index d9d073bf7ad..7931ce2584b 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/zeta.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/zeta.c
@@ -20,6 +20,8 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#include <float.h> /* for DBL_MAX */
+
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
@@ -201,8 +203,7 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
where gamma is Euler's constant */
{
dint = MAX (d + 3, precs);
- MPFR_TRACE (printf ("branch 1\ninternal precision=%lu\n",
- (unsigned long) dint));
+ /* branch 1, with internal precision dint */
MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f);
mpfr_div (z_pre, __gmpfr_one, s1, MPFR_RNDN);
mpfr_const_euler (f, MPFR_RNDN);
@@ -212,12 +213,12 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
{
size_t size;
- MPFR_TRACE (printf ("branch 2\n"));
+ /* branch 2 */
/* Computation of parameters n, p and working precision */
dnep = (double) d * LOG2;
sd = mpfr_get_d (s, MPFR_RNDN);
/* beta = dnep + 0.61 + sd * log (6.2832 / sd);
- but a larger value is ok */
+ but a larger value is OK */
#define LOG6dot2832 1.83787940484160805532
beta = dnep + 0.61 + sd * (LOG6dot2832 - LOG2 *
__gmpfr_floor_log2 (sd));
@@ -232,7 +233,6 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
p = 1 + (int) beta / 2;
n = 1 + (int) ((sd + 2.0 * (double) p - 1.0) / 6.2832);
}
- MPFR_TRACE (printf ("\nn=%d\np=%d\n",n,p));
/* add = 4 + floor(1.5 * log(d) / log (2)).
We should have add >= 10, which is always fulfilled since
d = precz + 11 >= 12, thus ceil(log2(d)) >= 4 */
@@ -242,37 +242,33 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
if (dint < precs)
dint = precs;
- MPFR_TRACE (printf ("internal precision=%lu\n",
- (unsigned long) dint));
+ /* internal precision is dint */
size = (p + 1) * sizeof(mpfr_t);
- tc1 = (mpfr_t*) (*__gmp_allocate_func) (size);
+ tc1 = (mpfr_t*) mpfr_allocate_func (size);
for (l=1; l<=p; l++)
mpfr_init2 (tc1[l], dint);
MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f);
- MPFR_TRACE (printf ("precision of z = %lu\n",
- (unsigned long) precz));
+ /* precision of z is precz */
/* Computation of the coefficients c_k */
mpfr_zeta_c (p, tc1);
- /* Computation of the 3 parts of the fonction Zeta. */
+ /* Computation of the 3 parts of the function Zeta. */
mpfr_zeta_part_a (z_pre, s, n);
mpfr_zeta_part_b (b, s, n, p, tc1);
/* s1 = s-1 is already computed above */
mpfr_div (c, __gmpfr_one, s1, MPFR_RNDN);
mpfr_ui_pow (f, n, s1, MPFR_RNDN);
mpfr_div (c, c, f, MPFR_RNDN);
- MPFR_TRACE (MPFR_DUMP (c));
mpfr_add (z_pre, z_pre, c, MPFR_RNDN);
mpfr_add (z_pre, z_pre, b, MPFR_RNDN);
for (l=1; l<=p; l++)
mpfr_clear (tc1[l]);
- (*__gmp_free_func) (tc1, size);
+ mpfr_free_func (tc1, size);
/* End branch 2 */
}
- MPFR_TRACE (MPFR_DUMP (z_pre));
if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, d-3, precz, rnd_mode)))
break;
MPFR_ZIV_NEXT (loop, d);
@@ -287,11 +283,141 @@ mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
return inex;
}
+/* return add = 1 + floor(log(c^3*(13+m1))/log(2))
+ where c = (1+eps)*(1+eps*max(8,m1)),
+ m1 = 1 + max(1/eps,2*sd)*(1+eps),
+ eps = 2^(-precz-14)
+ sd = abs(s-1)
+ */
+static long
+compute_add (mpfr_srcptr s, mpfr_prec_t precz)
+{
+ mpfr_t t, u, m1;
+ long add;
+
+ mpfr_inits2 (64, t, u, m1, (mpfr_ptr) 0);
+ if (mpfr_cmp_ui (s, 1) >= 0)
+ mpfr_sub_ui (t, s, 1, MPFR_RNDU);
+ else
+ mpfr_ui_sub (t, 1, s, MPFR_RNDU);
+ /* now t = sd = abs(s-1), rounded up */
+ mpfr_set_ui_2exp (u, 1, - precz - 14, MPFR_RNDU);
+ /* u = eps */
+ /* since 1/eps = 2^(precz+14), if EXP(sd) >= precz+14, then
+ sd >= 1/2*2^(precz+14) thus 2*sd >= 2^(precz+14) >= 1/eps */
+ if (mpfr_get_exp (t) >= precz + 14)
+ mpfr_mul_2exp (t, t, 1, MPFR_RNDU);
+ else
+ mpfr_set_ui_2exp (t, 1, precz + 14, MPFR_RNDU);
+ /* now t = max(1/eps,2*sd) */
+ mpfr_add_ui (u, u, 1, MPFR_RNDU); /* u = 1+eps, rounded up */
+ mpfr_mul (t, t, u, MPFR_RNDU); /* t = max(1/eps,2*sd)*(1+eps) */
+ mpfr_add_ui (m1, t, 1, MPFR_RNDU);
+ if (mpfr_get_exp (m1) <= 3)
+ mpfr_set_ui (t, 8, MPFR_RNDU);
+ else
+ mpfr_set (t, m1, MPFR_RNDU);
+ /* now t = max(8,m1) */
+ mpfr_div_2exp (t, t, precz + 14, MPFR_RNDU); /* eps*max(8,m1) */
+ mpfr_add_ui (t, t, 1, MPFR_RNDU); /* 1+eps*max(8,m1) */
+ mpfr_mul (t, t, u, MPFR_RNDU); /* t = c */
+ mpfr_add_ui (u, m1, 13, MPFR_RNDU); /* 13+m1 */
+ mpfr_mul (u, u, t, MPFR_RNDU); /* c*(13+m1) */
+ mpfr_sqr (t, t, MPFR_RNDU); /* c^2 */
+ mpfr_mul (u, u, t, MPFR_RNDU); /* c^3*(13+m1) */
+ add = mpfr_get_exp (u);
+ mpfr_clears (t, u, m1, (mpfr_ptr) 0);
+ return add;
+}
+
+/* return in z a lower bound (for rnd = RNDD) or upper bound (for rnd = RNDU)
+ of |zeta(s)|/2, using:
+ log(|zeta(s)|/2) = (s-1)*log(2*Pi) + lngamma(1-s)
+ + log(|sin(Pi*s/2)| * zeta(1-s)).
+ Assumes s < 1/2 and s1 = 1-s exactly, thus s1 > 1/2.
+ y and p are temporary variables.
+ At input, p is Pi rounded down.
+ The comments in the code are for rnd = RNDD. */
+static void
+mpfr_reflection_overflow (mpfr_t z, mpfr_t s1, const mpfr_t s, mpfr_t y,
+ mpfr_t p, mpfr_rnd_t rnd)
+{
+ mpz_t sint;
+
+ MPFR_ASSERTD (rnd == MPFR_RNDD || rnd == MPFR_RNDU);
+
+ /* Since log is increasing, we want lower bounds on |sin(Pi*s/2)| and
+ zeta(1-s). */
+ mpz_init (sint);
+ mpfr_get_z (sint, s, MPFR_RNDD); /* sint = floor(s) */
+ /* We first compute a lower bound of |sin(Pi*s/2)|, which is a periodic
+ function of period 2. Thus:
+ if 2k < s < 2k+1, then |sin(Pi*s/2)| is increasing;
+ if 2k-1 < s < 2k, then |sin(Pi*s/2)| is decreasing.
+ These cases are distinguished by testing bit 0 of floor(s) as if
+ represented in two's complement (or equivalently, as an unsigned
+ integer mod 2):
+ 0: sint = 0 mod 2, thus 2k < s < 2k+1 and |sin(Pi*s/2)| is increasing;
+ 1: sint = 1 mod 2, thus 2k-1 < s < 2k and |sin(Pi*s/2)| is decreasing.
+ Let's recall that the comments are for rnd = RNDD. */
+ if (mpz_tstbit (sint, 0) == 0) /* |sin(Pi*s/2)| is increasing: round down
+ Pi*s to get a lower bound. */
+ {
+ mpfr_mul (y, p, s, rnd);
+ if (rnd == MPFR_RNDD)
+ mpfr_nextabove (p); /* we will need p rounded above afterwards */
+ }
+ else /* |sin(Pi*s/2)| is decreasing: round up Pi*s to get a lower bound. */
+ {
+ if (rnd == MPFR_RNDD)
+ mpfr_nextabove (p);
+ mpfr_mul (y, p, s, MPFR_INVERT_RND(rnd));
+ }
+ mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* exact, rounding mode doesn't matter */
+ /* The rounding direction of sin depends on its sign. We have:
+ if -4k-2 < s < -4k, then -2k-1 < s/2 < -2k, thus sin(Pi*s/2) < 0;
+ if -4k < s < -4k+2, then -2k < s/2 < -2k+1, thus sin(Pi*s/2) > 0.
+ These cases are distinguished by testing bit 1 of floor(s) as if
+ represented in two's complement (or equivalently, as an unsigned
+ integer mod 4):
+ 0: sint = {0,1} mod 4, thus -2k < s/2 < -2k+1 and sin(Pi*s/2) > 0;
+ 1: sint = {2,3} mod 4, thus -2k-1 < s/2 < -2k and sin(Pi*s/2) < 0.
+ Let's recall that the comments are for rnd = RNDD. */
+ if (mpz_tstbit (sint, 1) == 0) /* -2k < s/2 < -2k+1; sin(Pi*s/2) > 0 */
+ {
+ /* Round sin down to get a lower bound of |sin(Pi*s/2)|. */
+ mpfr_sin (y, y, rnd);
+ }
+ else /* -2k-1 < s/2 < -2k; sin(Pi*s/2) < 0 */
+ {
+ /* Round sin up to get a lower bound of |sin(Pi*s/2)|. */
+ mpfr_sin (y, y, MPFR_INVERT_RND(rnd));
+ mpfr_abs (y, y, MPFR_RNDN); /* exact, rounding mode doesn't matter */
+ }
+ mpz_clear (sint);
+ /* now y <= |sin(Pi*s/2)| when rnd=RNDD, y >= |sin(Pi*s/2)| when rnd=RNDU */
+ mpfr_zeta_pos (z, s1, rnd); /* zeta(1-s) */
+ mpfr_mul (z, z, y, rnd);
+ /* now z <= |sin(Pi*s/2)|*zeta(1-s) */
+ mpfr_log (z, z, rnd);
+ /* now z <= log(|sin(Pi*s/2)|*zeta(1-s)) */
+ mpfr_lngamma (y, s1, rnd);
+ mpfr_add (z, z, y, rnd);
+ /* z <= lngamma(1-s) + log(|sin(Pi*s/2)|*zeta(1-s)) */
+ /* since s-1 < 0, we want to round log(2*pi) upwards */
+ mpfr_mul_2ui (y, p, 1, MPFR_INVERT_RND(rnd));
+ mpfr_log (y, y, MPFR_INVERT_RND(rnd));
+ mpfr_mul (y, y, s1, MPFR_INVERT_RND(rnd));
+ mpfr_sub (z, z, y, rnd);
+ mpfr_exp (z, z, rnd);
+ if (rnd == MPFR_RNDD)
+ mpfr_nextbelow (p); /* restore original p */
+}
+
int
mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
{
mpfr_t z_pre, s1, y, p;
- double sd, eps, m1, c;
long add;
mpfr_prec_t precz, prec1, precs, precs1;
int inex;
@@ -328,10 +454,9 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
/* s is neither Nan, nor Inf, nor Zero */
/* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0,
- and for |s| <= 0.074, we have |zeta(s) + 1/2| <= |s|.
- Thus if |s| <= 1/4*ulp(1/2), we can deduce the correct rounding
- (the 1/4 covers the case where |zeta(s)| < 1/2 and rounding to nearest).
- A sufficient condition is that EXP(s) + 1 < -PREC(z). */
+ and for |s| <= 2^(-4), we have |zeta(s) + 1/2| <= |s|.
+ EXP(s) + 1 < -PREC(z) is a sufficient condition to be able to round
+ correctly, for any PREC(z) >= 1 (see algorithms.tex for details). */
if (MPFR_GET_EXP (s) + 1 < - (mpfr_exp_t) MPFR_PREC(z))
{
int signs = MPFR_SIGN(s);
@@ -382,7 +507,7 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
{
MPFR_SET_INF (z);
MPFR_SET_POS (z);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
MPFR_RET (0);
}
@@ -402,39 +527,96 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
/* Precision precs1 needed to represent 1 - s, and s + 2,
without any truncation */
precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s));
- sd = mpfr_get_d (s, MPFR_RNDN) - 1.0;
- if (sd < 0.0)
- sd = -sd; /* now sd = abs(s-1.0) */
/* Precision prec1 is the precision on elementary computations;
it ensures a final precision prec1 - add for zeta(s) */
- /* eps = pow (2.0, - (double) precz - 14.0); */
- eps = __gmpfr_ceil_exp2 (- (double) precz - 14.0);
- m1 = 1.0 + MAX(1.0 / eps, 2.0 * sd) * (1.0 + eps);
- c = (1.0 + eps) * (1.0 + eps * MAX(8.0, m1));
- /* add = 1 + floor(log(c*c*c*(13 + m1))/log(2)); */
- add = __gmpfr_ceil_log2 (c * c * c * (13.0 + m1));
+ add = compute_add (s, precz);
prec1 = precz + add;
+ /* FIXME: To avoid that the working precision (prec1) depends on the
+ input precision, one would need to take into account the error made
+ when s1 is not exactly 1-s when computing zeta(s1) and gamma(s1)
+ below, and also in the case y=Inf (i.e. when gamma(s1) overflows).
+ Make sure that underflows do not occur in intermediate computations.
+ Due to the limited precision, they are probably not possible
+ in practice; add some MPFR_ASSERTN's to be sure that problems
+ do not remain undetected? */
prec1 = MAX (prec1, precs1) + 10;
MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p);
MPFR_ZIV_INIT (loop, prec1);
for (;;)
{
+ mpfr_exp_t ey;
+ mpfr_t z_up;
+
+ mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */
+
mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN); /* s1 = 1-s */
- mpfr_zeta_pos (z_pre, s1, MPFR_RNDN); /* zeta(1-s) */
mpfr_gamma (y, s1, MPFR_RNDN); /* gamma(1-s) */
- if (MPFR_IS_INF (y)) /* Zeta(s) < 0 for -4k-2 < s < -4k,
- Zeta(s) > 0 for -4k < s < -4k+2 */
+ if (MPFR_IS_INF (y)) /* zeta(s) < 0 for -4k-2 < s < -4k,
+ zeta(s) > 0 for -4k < s < -4k+2 */
{
- mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
- mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
- overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1;
- break;
+ /* FIXME: An overflow in gamma(s1) does not imply that
+ zeta(s) will overflow. A solution:
+ 1. Compute
+ log(|zeta(s)|/2) = (s-1)*log(2*pi) + lngamma(1-s)
+ + log(abs(sin(Pi*s/2)) * zeta(1-s))
+ (possibly sharing computations with the normal case)
+ with a rather good accuracy (see (2)).
+ Memorize the sign of sin(...) for the final sign.
+ 2. Take the exponential, ~= |zeta(s)|/2. If there is an
+ overflow, then this means an overflow on the final result
+ (due to the multiplication by 2, which has not been done
+ yet).
+ 3. Ziv test.
+ 4. Correct the sign from the sign of sin(...).
+ 5. Round then multiply by 2. Here, an overflow in either
+ operation means a real overflow. */
+ mpfr_reflection_overflow (z_pre, s1, s, y, p, MPFR_RNDD);
+ /* z_pre is a lower bound of |zeta(s)|/2, thus if it overflows,
+ or has exponent emax, then |zeta(s)| overflows too. */
+ if (MPFR_IS_INF (z_pre) || MPFR_GET_EXP(z_pre) == __gmpfr_emax)
+ { /* determine the sign of overflow */
+ mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
+ mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
+ overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1;
+ break;
+ }
+ else /* EXP(z_pre) < __gmpfr_emax */
+ {
+ int ok = 0;
+ mpfr_t z_down;
+ mpfr_init2 (z_up, mpfr_get_prec (z_pre));
+ mpfr_reflection_overflow (z_up, s1, s, y, p, MPFR_RNDU);
+ /* if the lower approximation z_pre does not overflow, but
+ z_up does, we need more precision */
+ if (MPFR_IS_INF (z_up) || MPFR_GET_EXP(z_up) == __gmpfr_emax)
+ goto next_loop;
+ /* check if z_pre and z_up round to the same number */
+ mpfr_init2 (z_down, precz);
+ mpfr_set (z_down, z_pre, rnd_mode);
+ /* Note: it might be that EXP(z_down) = emax here, in that
+ case we will have overflow below when we multiply by 2 */
+ mpfr_prec_round (z_up, precz, rnd_mode);
+ ok = mpfr_cmp (z_down, z_up) == 0;
+ mpfr_clear (z_up);
+ mpfr_clear (z_down);
+ if (ok)
+ {
+ /* get correct sign and multiply by 2 */
+ mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
+ mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
+ if (mpfr_cmp_si_2exp (s1, -1, -1) > 0)
+ mpfr_neg (z_pre, z_pre, rnd_mode);
+ mpfr_mul_2ui (z_pre, z_pre, 1, rnd_mode);
+ break;
+ }
+ else
+ goto next_loop;
+ }
}
+ mpfr_zeta_pos (z_pre, s1, MPFR_RNDN); /* zeta(1-s) */
mpfr_mul (z_pre, z_pre, y, MPFR_RNDN); /* gamma(1-s)*zeta(1-s) */
- mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */
-
/* multiply z_pre by 2^s*Pi^(s-1) where p=Pi, s1=1-s */
mpfr_mul_2ui (y, p, 1, MPFR_RNDN); /* 2*Pi */
mpfr_neg (s1, s1, MPFR_RNDN); /* s-1 */
@@ -445,11 +627,19 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
/* multiply z_pre by sin(Pi*s/2) */
mpfr_mul (y, s, p, MPFR_RNDN);
mpfr_div_2ui (p, y, 1, MPFR_RNDN); /* p = s*Pi/2 */
+ /* FIXME: sinpi will be available, we should replace the mpfr_sin
+ call below by mpfr_sinpi(s/2), where s/2 will be exact.
+ Can mpfr_sin underflow? Moreover, the code below should be
+ improved so that the "if" condition becomes unlikely, e.g.
+ by taking a slightly larger working precision. */
mpfr_sin (y, p, MPFR_RNDN); /* y = sin(Pi*s/2) */
- if (MPFR_GET_EXP(y) < 0) /* take account of cancellation in sin(p) */
+ ey = MPFR_GET_EXP (y);
+ if (ey < 0) /* take account of cancellation in sin(p) */
{
mpfr_t t;
- mpfr_init2 (t, prec1 - MPFR_GET_EXP(y));
+
+ MPFR_ASSERTN (- ey < MPFR_PREC_MAX - prec1);
+ mpfr_init2 (t, prec1 - ey);
mpfr_const_pi (t, MPFR_RNDD);
mpfr_mul (t, s, t, MPFR_RNDN);
mpfr_div_2ui (t, t, 1, MPFR_RNDN);
@@ -462,6 +652,7 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
rnd_mode)))
break;
+ next_loop:
MPFR_ZIV_NEXT (loop, prec1);
MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p);
}
diff --git a/Build/source/libs/mpfr/mpfr-src/src/zeta_ui.c b/Build/source/libs/mpfr/mpfr-src/src/zeta_ui.c
index ad8f0c06854..7fe27c292f3 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/zeta_ui.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/zeta_ui.c
@@ -32,15 +32,13 @@ mpfr_zeta_ui (mpfr_ptr z, unsigned long m, mpfr_rnd_t r)
(("m=%lu rnd=%d prec=%Pu", m, r, mpfr_get_prec (z)),
("z[%Pu]=%.*Rg", mpfr_get_prec (z), mpfr_log_prec, z));
- if (m == 0)
- {
- return mpfr_set_si_2exp (z, -1, -1, r);
- }
+ if (m == 0) /* zeta(0) = -1/2 */
+ return mpfr_set_si_2exp (z, -1, -1, r);
else if (m == 1)
{
MPFR_SET_INF (z);
MPFR_SET_POS (z);
- mpfr_set_divby0 ();
+ MPFR_SET_DIVBY0 ();
return 0;
}
else /* m >= 2 */