diff options
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h')
-rw-r--r-- | Build/source/libs/mpfr/mpfr-src/src/mpfr-impl.h | 1313 |
1 files changed, 850 insertions, 463 deletions
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__ */ |