mirror of
https://review.haiku-os.org/buildtools
synced 2025-01-19 12:51:22 +01:00
b58ddff026
* merged mpfr 3.0.0 and gmp 5.0.1 in buildtools trunk git-svn-id: file:///srv/svn/repos/haiku/buildtools/trunk@37378 a95241bf-73f2-0310-859d-f6bbb57e9c96
1754 lines
77 KiB
C
1754 lines
77 KiB
C
/* Utilities for MPFR developers, not exported.
|
|
|
|
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
|
Contributed by the Arenaire and Cacao 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_IMPL_H__
|
|
#define __MPFR_IMPL_H__
|
|
|
|
/* 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
|
|
options may hide the error).
|
|
Note: If some source file must not have such a header included
|
|
(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>
|
|
#else
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#endif
|
|
#include <limits.h>
|
|
|
|
/* Check if we are inside a build of MPFR or inside the test suite.
|
|
This is needed in mpfr.h to export or import the functions.
|
|
It matters only for Windows DLL */
|
|
#ifndef __MPFR_TEST_H__
|
|
# define __MPFR_WITHIN_MPFR 1
|
|
#endif
|
|
|
|
/******************************************************
|
|
****************** Include files *********************
|
|
******************************************************/
|
|
|
|
/* Include 'config.h' before using ANY configure macros if needed
|
|
NOTE: It isn't MPFR 'config.h', but GMP's one! */
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#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
|
|
# ifdef MPFR_NEED_LONGLONG_H
|
|
# include "longlong.h"
|
|
# endif
|
|
# ifndef __MPFR_H
|
|
# include "mpfr.h"
|
|
# endif
|
|
|
|
#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"
|
|
# endif
|
|
# ifdef MPFR_NEED_LONGLONG_H
|
|
# include "mpfr-longlong.h"
|
|
# endif
|
|
|
|
#endif
|
|
#undef MPFR_NEED_LONGLONG_H
|
|
|
|
/* if mpn_sqr_n is not exported, use mpn_mul instead */
|
|
#ifndef mpn_sqr_n
|
|
# define mpn_sqr_n(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
|
|
#endif
|
|
|
|
/* 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 the use of detection macros is needed in the future, this could be
|
|
moved below (after the detection macros are defined). */
|
|
#include "mpfr-thread.h"
|
|
|
|
|
|
/******************************************************
|
|
***************** 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(__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
|
|
|
|
|
|
|
|
/******************************************************
|
|
****************** (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>. */
|
|
#ifdef _MPFR_H_HAVE_INTMAX_T
|
|
# ifdef MPFR_HAVE_INTMAX_MAX
|
|
# define MPFR_UINTMAX_MAX UINTMAX_MAX
|
|
# define MPFR_INTMAX_MAX INTMAX_MAX
|
|
# define MPFR_INTMAX_MIN INTMAX_MIN
|
|
# else
|
|
# define MPFR_UINTMAX_MAX ((uintmax_t) -1)
|
|
# define MPFR_INTMAX_MAX ((intmax_t) (MPFR_UINTMAX_MAX >> 1))
|
|
# define MPFR_INTMAX_MIN (INT_MIN + INT_MAX - MPFR_INTMAX_MAX)
|
|
# endif
|
|
#endif
|
|
|
|
|
|
|
|
/******************************************************
|
|
******************** Check GMP ***********************
|
|
******************************************************/
|
|
|
|
#if !__MPFR_GMP(4,1,0)
|
|
# error "GMP 4.1.0 or newer needed"
|
|
#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 == 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
|
|
#else
|
|
# error "Can't compute log2(GMP_NUMB_BITS)"
|
|
#endif
|
|
|
|
#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
|
|
# define MPFR_NORETURN_ATTR __attribute__ ((noreturn))
|
|
# define MPFR_CONST_ATTR __attribute__ ((const))
|
|
#else
|
|
# define MPFR_NORETURN_ATTR
|
|
# define MPFR_CONST_ATTR
|
|
#endif
|
|
|
|
/******************************************************
|
|
************* Global Internal Variables **************
|
|
******************************************************/
|
|
|
|
/* Cache struct */
|
|
struct __gmpfr_cache_s {
|
|
mpfr_t x;
|
|
int inexact;
|
|
int (*func)(mpfr_ptr, mpfr_rnd_t);
|
|
};
|
|
typedef struct __gmpfr_cache_s mpfr_cache_t[1];
|
|
|
|
#if defined (__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emin;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emax;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_prec_t __gmpfr_default_fp_bit_precision;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_rnd_t __gmpfr_default_rounding_mode;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_pi;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_log2;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_euler;
|
|
__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_catalan;
|
|
|
|
#define BASE_MAX 62
|
|
__MPFR_DECLSPEC extern const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2];
|
|
|
|
/* Note: do not use the following values when they can be outside the
|
|
current exponent range, e.g. when the exponent range has not been
|
|
extended yet; under such a condition, they can be used only in
|
|
mpfr_cmpabs. */
|
|
__MPFR_DECLSPEC extern const mpfr_t __gmpfr_one;
|
|
__MPFR_DECLSPEC extern const mpfr_t __gmpfr_two;
|
|
__MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
|
|
|
|
|
|
#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_ALL 31
|
|
|
|
/* Replace some commun functions for direct access to the global vars */
|
|
#define mpfr_get_emin() (__gmpfr_emin + 0)
|
|
#define mpfr_get_emax() (__gmpfr_emax + 0)
|
|
#define mpfr_get_default_rounding_mode() (__gmpfr_default_rounding_mode + 0)
|
|
#define mpfr_get_default_prec() (__gmpfr_default_fp_bit_precision + 0)
|
|
|
|
#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_underflow_p() \
|
|
((int) (__gmpfr_flags & MPFR_FLAGS_UNDERFLOW))
|
|
#define mpfr_overflow_p() \
|
|
((int) (__gmpfr_flags & MPFR_FLAGS_OVERFLOW))
|
|
#define mpfr_nanflag_p() \
|
|
((int) (__gmpfr_flags & MPFR_FLAGS_NAN))
|
|
#define mpfr_inexflag_p() \
|
|
((int) (__gmpfr_flags & MPFR_FLAGS_INEXACT))
|
|
#define mpfr_erangeflag_p() \
|
|
((int) (__gmpfr_flags & MPFR_FLAGS_ERANGE))
|
|
|
|
/* Testing an exception flag correctly is tricky. There are mainly two
|
|
pitfalls: First, one needs to remember to clear the corresponding
|
|
flag, in case it was set before the function call or during some
|
|
intermediate computations (in practice, one can clear all the flags).
|
|
Secondly, one needs to test the flag early enough, i.e. before it
|
|
can be modified by another function. Moreover, it is quite difficult
|
|
(if not impossible) to reliably check problems with "make check". To
|
|
avoid these pitfalls, it is recommended to use the following macros.
|
|
Other use of the exception-flag predicate functions/macros will be
|
|
detected by mpfrlint.
|
|
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(_flags,_op) \
|
|
do \
|
|
{ \
|
|
mpfr_clear_flags (); \
|
|
_op; \
|
|
(_flags) = __gmpfr_flags; \
|
|
} \
|
|
while (0)
|
|
#define MPFR_BLOCK_TEST(_flags,_f) MPFR_UNLIKELY ((_flags) & (_f))
|
|
#define MPFR_BLOCK_EXCEP (__gmpfr_flags & (MPFR_FLAGS_UNDERFLOW | \
|
|
MPFR_FLAGS_OVERFLOW | \
|
|
MPFR_FLAGS_NAN))
|
|
/* Let's use a MPFR_ prefix, because e.g. OVERFLOW is defined by glibc's
|
|
math.h, though this is not a reserved identifier! */
|
|
#define MPFR_UNDERFLOW(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_UNDERFLOW)
|
|
#define MPFR_OVERFLOW(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_OVERFLOW)
|
|
#define MPFR_NANFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_NAN)
|
|
#define MPFR_INEXFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_INEXACT)
|
|
#define MPFR_ERANGEFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_ERANGE)
|
|
|
|
|
|
/******************************************************
|
|
******************** Assertions **********************
|
|
******************************************************/
|
|
|
|
/* Compile with -DWANT_ASSERT to check all assert statements */
|
|
|
|
/* 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_ASSERTD(expr): assertions that should be checked when testing */
|
|
#ifdef WANT_ASSERT
|
|
# define MPFR_EXP_CHECK 1
|
|
# define MPFR_ASSERTD(expr) MPFR_ASSERTN (expr)
|
|
#else
|
|
# define MPFR_ASSERTD(expr) ((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;}
|
|
|
|
|
|
/******************************************************
|
|
******************** 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 \
|
|
{ \
|
|
char *q = getenv ("MPFR_QUIET"); \
|
|
if (q == NULL || *q == 0) \
|
|
fprintf (stderr, "MPFR: %s\n", W); \
|
|
} \
|
|
while (0)
|
|
#else
|
|
# define MPFR_WARNING(W) ((void) 0)
|
|
#endif
|
|
|
|
|
|
/******************************************************
|
|
****************** double macros *********************
|
|
******************************************************/
|
|
|
|
/* 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.
|
|
On all the tested machines, MPFR_DOUBLE_SPEC = 1. To have this macro
|
|
defined here, #include <float.h> is needed. If need be, other values
|
|
could be defined for other specs (once they are known). */
|
|
#if !defined(MPFR_DOUBLE_SPEC) && defined(FLT_RADIX) && \
|
|
defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) && defined(DBL_MAX_EXP)
|
|
# if FLT_RADIX == 2 && DBL_MANT_DIG == 53 && \
|
|
DBL_MIN_EXP == -1021 && DBL_MAX_EXP == 1024
|
|
# define MPFR_DOUBLE_SPEC 1
|
|
# else
|
|
# define MPFR_DOUBLE_SPEC 0
|
|
# endif
|
|
#endif
|
|
|
|
/* Debug non IEEE floats */
|
|
#ifdef XDEBUG
|
|
# undef _GMP_IEEE_FLOATS
|
|
#endif
|
|
#ifndef _GMP_IEEE_FLOATS
|
|
# define _GMP_IEEE_FLOATS 0
|
|
#endif
|
|
|
|
#ifndef IEEE_DBL_MANT_DIG
|
|
#define IEEE_DBL_MANT_DIG 53
|
|
#endif
|
|
#define MPFR_LIMBS_PER_DOUBLE ((IEEE_DBL_MANT_DIG-1)/GMP_NUMB_BITS+1)
|
|
|
|
#ifndef IEEE_FLT_MANT_DIG
|
|
#define IEEE_FLT_MANT_DIG 24
|
|
#endif
|
|
#define MPFR_LIMBS_PER_FLT ((IEEE_FLT_MANT_DIG-1)/GMP_NUMB_BITS+1)
|
|
|
|
/* Visual C++ doesn't support +1.0/.00, -1.0/0.0 and 0.0/0.0
|
|
at compile time. */
|
|
#if defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)
|
|
static double double_zero = 0.0;
|
|
# define DBL_NAN (double_zero/double_zero)
|
|
# define DBL_POS_INF ((double) 1.0/double_zero)
|
|
# define DBL_NEG_INF ((double)-1.0/double_zero)
|
|
# define DBL_NEG_ZERO (-double_zero)
|
|
#else
|
|
# define DBL_POS_INF ((double) 1.0/0.0)
|
|
# define DBL_NEG_INF ((double)-1.0/0.0)
|
|
# define DBL_NAN ((double) 0.0/0.0)
|
|
# define DBL_NEG_ZERO (-0.0)
|
|
#endif
|
|
|
|
/* Note: In the past, there was specific code for _GMP_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.
|
|
The code needed a memory transfer and was probably not better than the
|
|
macros below with a good compiler (a fix based on the NaN / Inf memory
|
|
representation would be even worse due to C limitations), and this code
|
|
could be selected only when MPFR was built with --with-gmp-build, thus
|
|
introducing a difference (bad for maintaining/testing MPFR); therefore
|
|
it has been removed. The old code required that the argument x be an
|
|
lvalue of type double. We still require that, in case one would need
|
|
to change the macros below, e.g. for some broken compiler. But the
|
|
LVALUE(x) condition could be removed if really necessary. */
|
|
/* Below, the &(x) == &(x) || &(x) != &(x) allows to make sure that x
|
|
is a lvalue without (probably) any warning from the compiler. The
|
|
&(x) != &(x) is needed to avoid a failure under Mac OS X 10.4.11
|
|
(with Xcode 2.4.1, i.e. the latest one). */
|
|
#define LVALUE(x) (&(x) == &(x) || &(x) != &(x))
|
|
#define DOUBLE_ISINF(x) (LVALUE(x) && ((x) > DBL_MAX || (x) < -DBL_MAX))
|
|
#ifdef MPFR_NANISNAN
|
|
/* 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. */
|
|
# 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 *******************
|
|
******************************************************/
|
|
|
|
/* We try to get the exact value of the precision of long double
|
|
(provided by the implementation) in order to provide correct
|
|
rounding in this case (not guaranteed if the C implementation
|
|
does not have an adequate long double arithmetic). Note that
|
|
it may be lower than the precision of some numbers that can
|
|
be represented in a long double; e.g. on FreeBSD/x86, it is
|
|
53 because the processor is configured to round in double
|
|
precision (even when using the long double type -- this is a
|
|
limitation of the x87 arithmetic), and on Mac OS X, it is 106
|
|
because the implementation is a double-double arithmetic.
|
|
Otherwise (e.g. in base 10), we get an upper bound of the
|
|
precision, and correct rounding isn't currently provided.
|
|
*/
|
|
#if defined(LDBL_MANT_DIG) && FLT_RADIX == 2
|
|
# define MPFR_LDBL_MANT_DIG LDBL_MANT_DIG
|
|
#else
|
|
# define MPFR_LDBL_MANT_DIG \
|
|
(sizeof(long double)*GMP_NUMB_BITS/sizeof(mp_limb_t))
|
|
#endif
|
|
#define MPFR_LIMBS_PER_LONG_DOUBLE \
|
|
((sizeof(long double)-1)/sizeof(mp_limb_t)+1)
|
|
|
|
/* LONGDOUBLE_NAN_ACTION executes the code "action" if x is a NaN. */
|
|
|
|
/* On hppa2.0n-hp-hpux10 with the unbundled HP cc, the test x!=x on a NaN
|
|
has been seen false, meaning NaNs are not detected. This seemed to
|
|
happen only after other comparisons, not sure what's really going on. In
|
|
any case we can pick apart the bytes to identify a NaN. */
|
|
#ifdef HAVE_LDOUBLE_IEEE_QUAD_BIG
|
|
# define LONGDOUBLE_NAN_ACTION(x, action) \
|
|
do { \
|
|
union { \
|
|
long double ld; \
|
|
struct { \
|
|
unsigned int sign : 1; \
|
|
unsigned int exp : 15; \
|
|
unsigned int man3 : 16; \
|
|
unsigned int man2 : 32; \
|
|
unsigned int man1 : 32; \
|
|
unsigned int man0 : 32; \
|
|
} s; \
|
|
} u; \
|
|
u.ld = (x); \
|
|
if (u.s.exp == 0x7FFFL \
|
|
&& (u.s.man0 | u.s.man1 | u.s.man2 | u.s.man3) != 0) \
|
|
{ action; } \
|
|
} while (0)
|
|
#endif
|
|
|
|
#ifdef HAVE_LDOUBLE_IEEE_QUAD_LITTLE
|
|
# define LONGDOUBLE_NAN_ACTION(x, action) \
|
|
do { \
|
|
union { \
|
|
long double ld; \
|
|
struct { \
|
|
unsigned int man0 : 32; \
|
|
unsigned int man1 : 32; \
|
|
unsigned int man2 : 32; \
|
|
unsigned int man3 : 16; \
|
|
unsigned int exp : 15; \
|
|
unsigned int sign : 1; \
|
|
} s; \
|
|
} u; \
|
|
u.ld = (x); \
|
|
if (u.s.exp == 0x7FFFL \
|
|
&& (u.s.man0 | u.s.man1 | u.s.man2 | u.s.man3) != 0) \
|
|
{ action; } \
|
|
} while (0)
|
|
#endif
|
|
|
|
/* Under IEEE rules, NaN is not equal to anything, including itself.
|
|
"volatile" here stops "cc" on mips64-sgi-irix6.5 from optimizing away
|
|
x!=x. */
|
|
#ifndef LONGDOUBLE_NAN_ACTION
|
|
# define LONGDOUBLE_NAN_ACTION(x, action) \
|
|
do { \
|
|
volatile long double __x = LONGDOUBLE_VOLATILE (x); \
|
|
if ((x) != __x) \
|
|
{ action; } \
|
|
} while (0)
|
|
# define WANT_LONGDOUBLE_VOLATILE 1
|
|
#endif
|
|
|
|
/* If we don't have a proper "volatile" then volatile is #defined to empty,
|
|
in this case call through an external function to stop the compiler
|
|
optimizing anything. */
|
|
#ifdef WANT_LONGDOUBLE_VOLATILE
|
|
# ifdef volatile
|
|
__MPFR_DECLSPEC long double __gmpfr_longdouble_volatile _MPFR_PROTO ((long double)) MPFR_CONST_ATTR;
|
|
# define LONGDOUBLE_VOLATILE(x) (__gmpfr_longdouble_volatile (x))
|
|
# define WANT_GMPFR_LONGDOUBLE_VOLATILE 1
|
|
# else
|
|
# define LONGDOUBLE_VOLATILE(x) (x)
|
|
# endif
|
|
#endif
|
|
|
|
/* Some special case for IEEE_EXT Litle Endian */
|
|
#if HAVE_LDOUBLE_IEEE_EXT_LITTLE
|
|
|
|
typedef union {
|
|
long double ld;
|
|
struct {
|
|
unsigned int manl : 32;
|
|
unsigned int manh : 32;
|
|
unsigned int expl : 8 ;
|
|
unsigned int exph : 7;
|
|
unsigned int sign : 1;
|
|
} s;
|
|
} mpfr_long_double_t;
|
|
|
|
/* #undef MPFR_LDBL_MANT_DIG */
|
|
#undef MPFR_LIMBS_PER_LONG_DOUBLE
|
|
/* #define MPFR_LDBL_MANT_DIG 64 */
|
|
#define MPFR_LIMBS_PER_LONG_DOUBLE ((64-1)/GMP_NUMB_BITS+1)
|
|
|
|
#endif
|
|
|
|
/******************************************************
|
|
*************** _Decimal64 support *******************
|
|
******************************************************/
|
|
|
|
#ifdef MPFR_WANT_DECIMAL_FLOATS
|
|
/* to cast between binary64 and decimal64 */
|
|
union ieee_double_decimal64 { double d; _Decimal64 d64; };
|
|
#endif
|
|
|
|
/******************************************************
|
|
**************** mpfr_t properties *******************
|
|
******************************************************/
|
|
|
|
#define MPFR_PREC(x) ((x)->_mpfr_prec)
|
|
#define MPFR_EXP(x) ((x)->_mpfr_exp)
|
|
#define MPFR_MANT(x) ((x)->_mpfr_d)
|
|
#define MPFR_LIMB_SIZE(x) ((MPFR_PREC((x))-1)/GMP_NUMB_BITS+1)
|
|
|
|
|
|
/******************************************************
|
|
***************** exponent limits ********************
|
|
******************************************************/
|
|
|
|
/* Define limits and unsigned type of exponent. The following definitions
|
|
* depend on mp_exp_t; if this type changes in GMP, these definitions will
|
|
* need to be modified.
|
|
*/
|
|
#if __GMP_MP_SIZE_T_INT == 1
|
|
typedef unsigned int mpfr_uexp_t;
|
|
# define MPFR_EXP_MAX (INT_MAX)
|
|
# define MPFR_EXP_MIN (INT_MIN)
|
|
#else
|
|
typedef unsigned long int mpfr_uexp_t;
|
|
# define MPFR_EXP_MAX (LONG_MAX)
|
|
# define MPFR_EXP_MIN (LONG_MIN)
|
|
#endif
|
|
#ifndef mp_exp_unsigned_t
|
|
# define mp_exp_unsigned_t mpfr_uexp_t
|
|
#endif
|
|
|
|
#if MPFR_EXP_MIN >= LONG_MIN && MPFR_EXP_MAX <= LONG_MAX
|
|
typedef long int mpfr_eexp_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))
|
|
#elif defined (_MPFR_H_HAVE_INTMAX_T)
|
|
typedef intmax_t mpfr_eexp_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))
|
|
#else
|
|
# error "Cannot define mpfr_get_exp_t and mpfr_set_exp_t"
|
|
#endif
|
|
|
|
/* 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))
|
|
|
|
/* Definition of the exponent limits for MPFR numbers.
|
|
* These limits are chosen so that if e is such an exponent, then 2e-1 and
|
|
* 2e+1 are representable. This is useful for intermediate computations,
|
|
* in particular the multiplication.
|
|
*/
|
|
#undef MPFR_EMIN_MIN
|
|
#undef MPFR_EMIN_MAX
|
|
#undef MPFR_EMAX_MIN
|
|
#undef MPFR_EMAX_MAX
|
|
#define MPFR_EMIN_MIN (1-MPFR_EXP_INVALID)
|
|
#define MPFR_EMIN_MAX (MPFR_EXP_INVALID-1)
|
|
#define MPFR_EMAX_MIN (1-MPFR_EXP_INVALID)
|
|
#define MPFR_EMAX_MAX (MPFR_EXP_INVALID-1)
|
|
|
|
/* Use MPFR_GET_EXP and MPFR_SET_EXP instead of MPFR_EXP directly,
|
|
unless when the exponent may be out-of-range, for instance when
|
|
setting the exponent before calling mpfr_check_range.
|
|
MPFR_EXP_CHECK is defined when WANT_ASSERT is defined, but if you
|
|
don't use WANT_ASSERT (for speed reasons), you can still define
|
|
MPFR_EXP_CHECK by setting -DMPFR_EXP_CHECK in $CFLAGS. */
|
|
|
|
#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_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_INVALID_EXP(x) ((void) 0)
|
|
#endif
|
|
|
|
|
|
|
|
/******************************************************
|
|
********** Singular Values (NAN, INF, ZERO) **********
|
|
******************************************************/
|
|
|
|
/*
|
|
* Clear flags macros are still defined and should be still used
|
|
* since the functions must not assume the internal format.
|
|
* How to deal with special values ?
|
|
* 1. Check if is a special value (Zero, Nan, Inf) wiht MPFR_IS_SINGULAR
|
|
* 2. Deal with the special value with MPFR_IS_NAN, MPFR_IS_INF, etc
|
|
* 3. Else clear the flags of the dest (it must be done after since src
|
|
* may be also the dest!)
|
|
* MPFR_SET_INF, MPFR_SET_NAN, MPFR_SET_ZERO must clear by
|
|
* themselves the other flags.
|
|
*/
|
|
|
|
/* 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_IS_NAN(x) (MPFR_EXP(x) == MPFR_EXP_NAN)
|
|
#define MPFR_SET_NAN(x) (MPFR_EXP(x) = MPFR_EXP_NAN)
|
|
#define MPFR_IS_INF(x) (MPFR_EXP(x) == MPFR_EXP_INF)
|
|
#define MPFR_SET_INF(x) (MPFR_EXP(x) = MPFR_EXP_INF)
|
|
#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_FP(x) (!MPFR_IS_NAN(x) && !MPFR_IS_INF(x))
|
|
#define MPFR_IS_SINGULAR(x) (MPFR_EXP(x) <= MPFR_EXP_INF)
|
|
#define MPFR_IS_PURE_FP(x) (!MPFR_IS_SINGULAR(x))
|
|
|
|
#define MPFR_ARE_SINGULAR(x,y) \
|
|
(MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)) || MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
|
|
|
|
|
|
|
|
/******************************************************
|
|
********************* Sign Macros ********************
|
|
******************************************************/
|
|
|
|
#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_NEG(x) (MPFR_SIGN(x) < 0)
|
|
#define MPFR_IS_POS(x) (MPFR_SIGN(x) > 0)
|
|
|
|
#define MPFR_SET_POS(x) (MPFR_SIGN(x) = MPFR_SIGN_POS)
|
|
#define MPFR_SET_NEG(x) (MPFR_SIGN(x) = MPFR_SIGN_NEG)
|
|
|
|
#define MPFR_CHANGE_SIGN(x) (MPFR_SIGN(x) = -MPFR_SIGN(x))
|
|
#define MPFR_SET_SAME_SIGN(x, y) (MPFR_SIGN(x) = MPFR_SIGN(y))
|
|
#define MPFR_SET_OPPOSITE_SIGN(x, y) (MPFR_SIGN(x) = -MPFR_SIGN(y))
|
|
#define MPFR_ASSERT_SIGN(s) \
|
|
(MPFR_ASSERTD((s) == MPFR_SIGN_POS || (s) == MPFR_SIGN_NEG))
|
|
#define MPFR_SET_SIGN(x, s) \
|
|
(MPFR_ASSERT_SIGN(s), MPFR_SIGN(x) = s)
|
|
#define MPFR_IS_POS_SIGN(s1) (s1 > 0)
|
|
#define MPFR_IS_NEG_SIGN(s1) (s1 < 0)
|
|
#define MPFR_MULT_SIGN(s1, s2) ((s1) * (s2))
|
|
/* Transform a sign to 1 or -1 */
|
|
#define MPFR_FROM_SIGN_TO_INT(s) (s)
|
|
#define MPFR_INT_SIGN(x) MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(x))
|
|
|
|
|
|
|
|
/******************************************************
|
|
***************** Ternary Value Macros ***************
|
|
******************************************************/
|
|
|
|
/* Special inexact value */
|
|
#define MPFR_EVEN_INEX 2
|
|
|
|
/* When returning the ternary inexact value, ALWAYS use one of the
|
|
following two macros, unless the flag comes from another function
|
|
returning the ternary inexact value */
|
|
#define MPFR_RET(I) return \
|
|
(I) ? ((__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))
|
|
|
|
|
|
|
|
/******************************************************
|
|
************** 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))
|
|
|
|
/* We want to test this :
|
|
* (rnd == MPFR_RNDU && test) || (rnd == RNDD && !test)
|
|
* ie it transforms RNDU or RNDD to Away or Zero according to the sign */
|
|
#define MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test) \
|
|
(((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))
|
|
|
|
#define MPFR_IS_LIKE_RNDU(rnd, sign) \
|
|
((rnd==MPFR_RNDU) || (rnd==MPFR_RNDZ && sign<0) || (rnd==MPFR_RNDA && sign>0))
|
|
|
|
#define MPFR_IS_LIKE_RNDD(rnd, sign) \
|
|
((rnd==MPFR_RNDD) || (rnd==MPFR_RNDZ && sign>0) || (rnd==MPFR_RNDA && sign<0))
|
|
|
|
/* Invert a rounding mode, RNDZ and RNDA are unchanged */
|
|
#define MPFR_INVERT_RND(rnd) ((rnd == MPFR_RNDU) ? MPFR_RNDD : \
|
|
((rnd == MPFR_RNDD) ? MPFR_RNDU : rnd))
|
|
|
|
/* Transform RNDU and RNDD to RNDZ according to test */
|
|
#define MPFR_UPDATE_RND_MODE(rnd, test) \
|
|
do { \
|
|
if (MPFR_UNLIKELY(MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test))) \
|
|
rnd = MPFR_RNDZ; \
|
|
} while (0)
|
|
|
|
/* Transform RNDU and RNDD to RNDZ or RNDA according to sign,
|
|
leave the other modes unchanged */
|
|
#define MPFR_UPDATE2_RND_MODE(rnd, sign) \
|
|
do { \
|
|
if (rnd == MPFR_RNDU) \
|
|
rnd = (sign > 0) ? MPFR_RNDA : MPFR_RNDZ; \
|
|
else if (rnd == MPFR_RNDD) \
|
|
rnd = (sign < 0) ? MPFR_RNDA : MPFR_RNDZ; \
|
|
} while (0)
|
|
|
|
|
|
/******************************************************
|
|
******************* 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
|
|
|
|
/* 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
|
|
|
|
/* Mask for the low 's' bits of a limb */
|
|
#define MPFR_LIMB_MASK(s) ((MPFR_LIMB_ONE<<(s))-MPFR_LIMB_ONE)
|
|
|
|
|
|
|
|
/******************************************************
|
|
********************** Memory ************************
|
|
******************************************************/
|
|
|
|
/* Heap Memory gestion */
|
|
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)
|
|
#define MPFR_SET_ALLOC_SIZE(x, n) \
|
|
( ((mp_size_t*) MPFR_MANT(x))[-1] = n)
|
|
#define MPFR_MALLOC_SIZE(s) \
|
|
( sizeof(mpfr_size_limb_t) + 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))
|
|
#define MPFR_GET_REAL_PTR(x) \
|
|
((mp_limb_t*) ((mpfr_size_limb_t*) MPFR_MANT(x) - 1))
|
|
|
|
/* Temporary memory gestion */
|
|
#ifndef TMP_SALLOC
|
|
/* GMP 4.1.x or below or internals */
|
|
#define MPFR_TMP_DECL TMP_DECL
|
|
#define MPFR_TMP_MARK TMP_MARK
|
|
#define MPFR_TMP_ALLOC TMP_ALLOC
|
|
#define MPFR_TMP_FREE TMP_FREE
|
|
#else
|
|
#define MPFR_TMP_DECL(x) TMP_DECL
|
|
#define MPFR_TMP_MARK(x) TMP_MARK
|
|
#define MPFR_TMP_ALLOC(s) TMP_ALLOC(s)
|
|
#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
|
|
|
|
/* temporary allocate 1 limb at xp, and initialize mpfr variable x */
|
|
/* The temporary var doesn't have any size field, but it doesn't matter
|
|
* since only functions dealing with the Heap care about it */
|
|
#define MPFR_TMP_INIT1(xp, x, p) \
|
|
( MPFR_PREC(x) = (p), \
|
|
MPFR_MANT(x) = (xp), \
|
|
MPFR_SET_POS(x), \
|
|
MPFR_SET_INVALID_EXP(x))
|
|
|
|
#define MPFR_TMP_INIT(xp, x, p, s) \
|
|
(xp = (mp_ptr) MPFR_TMP_ALLOC(BYTES_PER_MP_LIMB * ((size_t) s)), \
|
|
MPFR_TMP_INIT1(xp, x, p))
|
|
|
|
#define MPFR_TMP_INIT_ABS(d, s) \
|
|
( MPFR_PREC(d) = MPFR_PREC(s), \
|
|
MPFR_MANT(d) = MPFR_MANT(s), \
|
|
MPFR_SET_POS(d), \
|
|
MPFR_EXP(d) = MPFR_EXP(s))
|
|
|
|
|
|
|
|
/******************************************************
|
|
***************** Cache macros **********************
|
|
******************************************************/
|
|
|
|
#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)
|
|
|
|
#define MPFR_DECL_INIT_CACHE(_cache,_func) \
|
|
mpfr_cache_t MPFR_THREAD_ATTR _cache = \
|
|
{{{{0,MPFR_SIGN_POS,0,(mp_limb_t*)0}},0,_func}}
|
|
|
|
|
|
|
|
/******************************************************
|
|
******************* Threshold ***********************
|
|
******************************************************/
|
|
|
|
#include "mparam.h"
|
|
|
|
/******************************************************
|
|
***************** Useful macros *********************
|
|
******************************************************/
|
|
|
|
/* Theses macros help the compiler to determine if a test is
|
|
* likely or unlikely. */
|
|
#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))
|
|
#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__)
|
|
# define INITIALIZED(VAR) VAR = VAR
|
|
#else
|
|
# define INITIALIZED(VAR) VAR
|
|
#endif
|
|
|
|
/* Ceil log 2: If GCC, uses a GCC extension, otherwise calls a function */
|
|
/* Warning:
|
|
* Needs to define MPFR_NEED_LONGLONG.
|
|
* 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)
|
|
# define MPFR_INT_CEIL_LOG2(x) \
|
|
(MPFR_UNLIKELY ((x) == 1) ? 0 : \
|
|
__extension__ ({ int _b; mp_limb_t _limb; \
|
|
MPFR_ASSERTN ((x) > 1); \
|
|
_limb = (x) - 1; \
|
|
MPFR_ASSERTN (_limb == (x) - 1); \
|
|
count_leading_zeros (_b, _limb); \
|
|
(GMP_NUMB_BITS - _b); }))
|
|
#else
|
|
# define MPFR_INT_CEIL_LOG2(x) (__gmpfr_int_ceil_log2(x))
|
|
#endif
|
|
|
|
/* Add two integers with overflow handling */
|
|
/* Example: MPFR_SADD_OVERFLOW (c, a, b, long, unsigned long,
|
|
* LONG_MIN, LONG_MAX,
|
|
* goto overflow, goto underflow); */
|
|
#define MPFR_UADD_OVERFLOW(c,a,b,ACTION_IF_OVERFLOW) \
|
|
do { \
|
|
(c) = (a) + (b); \
|
|
if ((c) < (a)) ACTION_IF_OVERFLOW; \
|
|
} while (0)
|
|
|
|
#define MPFR_SADD_OVERFLOW(c,a,b,STYPE,UTYPE,MIN,MAX,ACTION_IF_POS_OVERFLOW,ACTION_IF_NEG_OVERFLOW) \
|
|
do { \
|
|
if ((a) >= 0 && (b) >= 0) { \
|
|
UTYPE uc,ua,ub; \
|
|
ua = (UTYPE) a; ub = (UTYPE) b; \
|
|
MPFR_UADD_OVERFLOW (uc, ua, ub, ACTION_IF_POS_OVERFLOW); \
|
|
if (uc > (UTYPE)(MAX)) ACTION_IF_POS_OVERFLOW; \
|
|
else (c) = (STYPE) uc; \
|
|
} else if ((a) < 0 && (b) < 0) { \
|
|
UTYPE uc,ua,ub; \
|
|
ua = -(UTYPE) a; ub = -(UTYPE) b; \
|
|
MPFR_UADD_OVERFLOW (uc, ua, ub, ACTION_IF_NEG_OVERFLOW); \
|
|
if (uc >= -(UTYPE)(MIN) || uc > (UTYPE)(MAX)) { \
|
|
if (uc == -(UTYPE)(MIN)) (c) = (MIN); \
|
|
else ACTION_IF_NEG_OVERFLOW; } \
|
|
else (c) = -(STYPE) uc; \
|
|
} else (c) = (a) + (b); \
|
|
} while (0)
|
|
|
|
|
|
/* Set a number to 1 (Fast) - It doesn't check if 1 is in the exponent range */
|
|
#define MPFR_SET_ONE(x) \
|
|
do { \
|
|
mp_size_t _size = MPFR_LIMB_SIZE(x) - 1; \
|
|
MPFR_SET_POS(x); \
|
|
MPFR_EXP(x) = 1; \
|
|
MPN_ZERO ( MPFR_MANT(x), _size); \
|
|
MPFR_MANT(x)[_size] = MPFR_LIMB_HIGHBIT; \
|
|
} while (0)
|
|
|
|
/* Compute s = (-a) % GMP_NUMB_BITS as unsigned */
|
|
#define MPFR_UNSIGNED_MINUS_MODULO(s, a) \
|
|
do \
|
|
{ \
|
|
if (IS_POW2 (GMP_NUMB_BITS)) \
|
|
(s) = (- (unsigned int) (a)) % GMP_NUMB_BITS; \
|
|
else \
|
|
{ \
|
|
(s) = (a) % GMP_NUMB_BITS; \
|
|
if ((s) != 0) \
|
|
(s) = GMP_NUMB_BITS - (s); \
|
|
} \
|
|
MPFR_ASSERTD ((s) >= 0 && (s) < GMP_NUMB_BITS); \
|
|
} \
|
|
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) */
|
|
/* type is the target (unsigned) type */
|
|
#define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
|
|
|
|
#define mpfr_get_d1(x) mpfr_get_d(x,__gmpfr_default_rounding_mode)
|
|
|
|
/* Store in r the size in bits of the mpz_t z */
|
|
#define MPFR_MPZ_SIZEINBASE2(r, z) \
|
|
do { \
|
|
int _cnt; \
|
|
mp_size_t _size; \
|
|
MPFR_ASSERTD (mpz_sgn (z) != 0); \
|
|
_size = ABSIZ(z); \
|
|
count_leading_zeros (_cnt, PTR(z)[_size-1]); \
|
|
(r) = _size * GMP_NUMB_BITS - _cnt; \
|
|
} while (0)
|
|
|
|
/* Needs <locale.h> */
|
|
#ifdef HAVE_LOCALE_H
|
|
#include <locale.h>
|
|
/* Warning! In case of signed char, the value of MPFR_DECIMAL_POINT may
|
|
be negative (the ISO C99 does not seem to forbid negative values). */
|
|
#define MPFR_DECIMAL_POINT (localeconv()->decimal_point[0])
|
|
#define MPFR_THOUSANDS_SEPARATOR (localeconv()->thousands_sep[0])
|
|
#else
|
|
#define MPFR_DECIMAL_POINT ((char) '.')
|
|
#define MPFR_THOUSANDS_SEPARATOR ('\0')
|
|
#endif
|
|
|
|
|
|
/* Set y to s*significand(x)*2^e, for example MPFR_ALIAS(y,x,1,MPFR_EXP(x))
|
|
sets y to |x|, and MPFR_ALIAS(y,x,MPFR_SIGN(x),0) sets y to x*2^f such
|
|
that 1/2 <= |y| < 1. Does not check y is in the valid exponent range.
|
|
WARNING! x and y share the same mantissa. So, some operations are
|
|
not valid if x has been provided via an argument, e.g., trying to
|
|
modify the mantissa of y, even temporarily, or calling mpfr_clear on y.
|
|
*/
|
|
#define MPFR_ALIAS(y,x,s,e) \
|
|
do \
|
|
{ \
|
|
MPFR_PREC(y) = MPFR_PREC(x); \
|
|
MPFR_SIGN(y) = (s); \
|
|
MPFR_EXP(y) = (e); \
|
|
MPFR_MANT(y) = MPFR_MANT(x); \
|
|
} while (0)
|
|
|
|
|
|
/******************************************************
|
|
************** Save exponent macros ****************
|
|
******************************************************/
|
|
|
|
/* See README.dev for details on how to use the macros.
|
|
They are used to set the exponent range to the maximum
|
|
temporarily */
|
|
|
|
typedef struct {
|
|
unsigned int saved_flags;
|
|
mpfr_exp_t saved_emin;
|
|
mpfr_exp_t saved_emax;
|
|
} mpfr_save_expo_t;
|
|
|
|
#define MPFR_SAVE_EXPO_DECL(x) mpfr_save_expo_t x
|
|
#define MPFR_SAVE_EXPO_MARK(x) \
|
|
((x).saved_flags = __gmpfr_flags, \
|
|
(x).saved_emin = __gmpfr_emin, \
|
|
(x).saved_emax = __gmpfr_emax, \
|
|
__gmpfr_emin = MPFR_EMIN_MIN, \
|
|
__gmpfr_emax = MPFR_EMAX_MAX)
|
|
#define MPFR_SAVE_EXPO_FREE(x) \
|
|
(__gmpfr_flags = (x).saved_flags, \
|
|
__gmpfr_emin = (x).saved_emin, \
|
|
__gmpfr_emax = (x).saved_emax)
|
|
#define MPFR_SAVE_EXPO_UPDATE_FLAGS(x, flags) \
|
|
(x).saved_flags |= (flags)
|
|
|
|
/* 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))
|
|
|
|
|
|
/******************************************************
|
|
***************** Inline Rounding *******************
|
|
******************************************************/
|
|
|
|
/*
|
|
* Note: due to the labels, one cannot use a macro MPFR_RNDRAW* more than
|
|
* once in a function (otherwise these labels would not be unique).
|
|
*/
|
|
|
|
/*
|
|
* Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
|
|
* assuming dest's sign is sign.
|
|
* 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.
|
|
*/
|
|
#define MPFR_RNDRAW_GEN(inexact, dest, srcp, sprec, rnd, sign, \
|
|
MIDDLE_HANDLER, OVERFLOW_HANDLER) \
|
|
do { \
|
|
mp_size_t _dests, _srcs; \
|
|
mp_limb_t *_destp; \
|
|
mpfr_prec_t _destprec, _srcprec; \
|
|
\
|
|
/* Check Trivial Case when Dest Mantissa has more bits than source */ \
|
|
_srcprec = sprec; \
|
|
_destprec = MPFR_PREC (dest); \
|
|
_destp = MPFR_MANT (dest); \
|
|
if (MPFR_UNLIKELY (_destprec >= _srcprec)) \
|
|
{ \
|
|
_srcs = (_srcprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS; \
|
|
_dests = (_destprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS - _srcs; \
|
|
MPN_COPY (_destp + _dests, srcp, _srcs); \
|
|
MPN_ZERO (_destp, _dests); \
|
|
inexact = 0; \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* Non trivial case: rounding needed */ \
|
|
mpfr_prec_t _sh; \
|
|
mp_limb_t *_sp; \
|
|
mp_limb_t _rb, _sb, _ulp; \
|
|
\
|
|
/* Compute Position and shift */ \
|
|
_srcs = (_srcprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS; \
|
|
_dests = (_destprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS; \
|
|
MPFR_UNSIGNED_MINUS_MODULO (_sh, _destprec); \
|
|
_sp = srcp + _srcs - _dests; \
|
|
\
|
|
/* General case when prec % GMP_NUMB_BITS != 0 */ \
|
|
if (MPFR_LIKELY (_sh != 0)) \
|
|
{ \
|
|
mp_limb_t _mask; \
|
|
/* Compute Rounding Bit and Sticky Bit */ \
|
|
_mask = MPFR_LIMB_ONE << (_sh - 1); \
|
|
_rb = _sp[0] & _mask; \
|
|
_sb = _sp[0] & (_mask - 1); \
|
|
if (MPFR_UNLIKELY (_sb == 0)) \
|
|
{ /* TODO: Improve it */ \
|
|
mp_limb_t *_tmp; \
|
|
mp_size_t _n; \
|
|
for (_tmp = _sp, _n = _srcs - _dests ; \
|
|
_n != 0 && _sb == 0 ; _n--) \
|
|
_sb = *--_tmp; \
|
|
} \
|
|
_ulp = 2 * _mask; \
|
|
} \
|
|
else /* _sh == 0 */ \
|
|
{ \
|
|
MPFR_ASSERTD (_dests < _srcs); \
|
|
/* Compute Rounding Bit and Sticky Bit */ \
|
|
_rb = _sp[-1] & MPFR_LIMB_HIGHBIT; \
|
|
_sb = _sp[-1] & (MPFR_LIMB_HIGHBIT-1); \
|
|
if (MPFR_UNLIKELY (_sb == 0)) \
|
|
{ \
|
|
mp_limb_t *_tmp; \
|
|
mp_size_t _n; \
|
|
for (_tmp = _sp - 1, _n = _srcs - _dests - 1 ; \
|
|
_n != 0 && _sb == 0 ; _n--) \
|
|
_sb = *--_tmp; \
|
|
} \
|
|
_ulp = MPFR_LIMB_ONE; \
|
|
} \
|
|
/* Rounding */ \
|
|
if (MPFR_LIKELY (rnd == MPFR_RNDN)) \
|
|
{ \
|
|
if (_rb == 0) \
|
|
{ \
|
|
trunc: \
|
|
inexact = MPFR_LIKELY ((_sb | _rb) != 0) ? -sign : 0; \
|
|
trunc_doit: \
|
|
MPN_COPY (_destp, _sp, _dests); \
|
|
_destp[0] &= ~(_ulp - 1); \
|
|
} \
|
|
else if (MPFR_UNLIKELY (_sb == 0)) \
|
|
{ /* Middle of two consecutive representable numbers */ \
|
|
MIDDLE_HANDLER; \
|
|
} \
|
|
else \
|
|
{ \
|
|
if (0) \
|
|
goto addoneulp_doit; /* dummy code to avoid warning */ \
|
|
addoneulp: \
|
|
inexact = sign; \
|
|
addoneulp_doit: \
|
|
if (MPFR_UNLIKELY (mpn_add_1 (_destp, _sp, _dests, _ulp))) \
|
|
{ \
|
|
_destp[_dests - 1] = MPFR_LIMB_HIGHBIT; \
|
|
OVERFLOW_HANDLER; \
|
|
} \
|
|
_destp[0] &= ~(_ulp - 1); \
|
|
} \
|
|
} \
|
|
else \
|
|
{ /* Directed rounding mode */ \
|
|
if (MPFR_LIKELY (MPFR_IS_LIKE_RNDZ (rnd, \
|
|
MPFR_IS_NEG_SIGN (sign)))) \
|
|
goto trunc; \
|
|
else if (MPFR_UNLIKELY ((_sb | _rb) == 0)) \
|
|
{ \
|
|
inexact = 0; \
|
|
goto trunc_doit; \
|
|
} \
|
|
else \
|
|
goto addoneulp; \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
/*
|
|
* Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
|
|
* assuming dest's sign is sign.
|
|
* Execute OVERFLOW_HANDLER in case of overflow when rounding.
|
|
*/
|
|
#define MPFR_RNDRAW(inexact, dest, srcp, sprec, rnd, sign, OVERFLOW_HANDLER) \
|
|
MPFR_RNDRAW_GEN (inexact, dest, srcp, sprec, rnd, sign, \
|
|
if ((_sp[0] & _ulp) == 0) \
|
|
{ \
|
|
inexact = -sign; \
|
|
goto trunc_doit; \
|
|
} \
|
|
else \
|
|
goto addoneulp; \
|
|
, OVERFLOW_HANDLER)
|
|
|
|
/*
|
|
* Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
|
|
* assuming dest's sign is sign.
|
|
* Execute OVERFLOW_HANDLER in case of overflow when rounding.
|
|
* Set inexact to +/- MPFR_EVEN_INEX in case of even rounding.
|
|
*/
|
|
#define MPFR_RNDRAW_EVEN(inexact, dest, srcp, sprec, rnd, sign, \
|
|
OVERFLOW_HANDLER) \
|
|
MPFR_RNDRAW_GEN (inexact, dest, srcp, sprec, rnd, sign, \
|
|
if ((_sp[0] & _ulp) == 0) \
|
|
{ \
|
|
inexact = -MPFR_EVEN_INEX * sign; \
|
|
goto trunc_doit; \
|
|
} \
|
|
else \
|
|
{ \
|
|
inexact = MPFR_EVEN_INEX * sign; \
|
|
goto addoneulp_doit; \
|
|
} \
|
|
, OVERFLOW_HANDLER)
|
|
|
|
/* Return TRUE if b is non singular and we can round it to precision 'prec'
|
|
and determine the ternary value, with rounding mode 'rnd', and with
|
|
error at most 'error' */
|
|
#define MPFR_CAN_ROUND(b,err,prec,rnd) \
|
|
(!MPFR_IS_SINGULAR (b) && mpfr_round_p (MPFR_MANT (b), MPFR_LIMB_SIZE (b), \
|
|
(err), (prec) + ((rnd)==MPFR_RNDN)))
|
|
|
|
/* TODO: fix this description (see round_near_x.c). */
|
|
/* Assuming that the function has a Taylor expansion which looks like:
|
|
y=o(f(x)) = o(v + g(x)) with |g(x)| <= 2^(EXP(v)-err)
|
|
we can quickly set y to v if x is small (ie err > prec(y)+1) in most
|
|
cases. It assumes that f(x) is not representable exactly as a FP number.
|
|
v must not be a singular value (NAN, INF or ZERO); usual values are
|
|
v=1 or v=x.
|
|
|
|
y is the destination (a mpfr_t), v the value to set (a mpfr_t),
|
|
err1+err2 with err2 <= 3 the error term (mpfr_exp_t's), dir (an int) is
|
|
the direction of the committed error (if dir = 0, it rounds toward 0,
|
|
if dir=1, it rounds away from 0), rnd the rounding mode.
|
|
|
|
It returns from the function a ternary value in case of success.
|
|
If you want to free something, you must fill the "extra" field
|
|
in consequences, otherwise put nothing in it.
|
|
|
|
The test is less restrictive than necessary, but the function
|
|
will finish the check itself.
|
|
|
|
Note: err1 + err2 is allowed to overflow as mpfr_exp_t, but it must give
|
|
its real value as mpfr_uexp_t.
|
|
*/
|
|
#define MPFR_FAST_COMPUTE_IF_SMALL_INPUT(y,v,err1,err2,dir,rnd,extra) \
|
|
do { \
|
|
mpfr_ptr _y = (y); \
|
|
mpfr_exp_t _err1 = (err1); \
|
|
mpfr_exp_t _err2 = (err2); \
|
|
if (_err1 > 0) \
|
|
{ \
|
|
mpfr_uexp_t _err = (mpfr_uexp_t) _err1 + _err2; \
|
|
if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1)) \
|
|
{ \
|
|
int _inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd)); \
|
|
if (_inexact != 0) \
|
|
{ \
|
|
extra; \
|
|
return _inexact; \
|
|
} \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
/* Variant, to be called somewhere after MPFR_SAVE_EXPO_MARK. This variant
|
|
is needed when there are some computations before or when some non-zero
|
|
real constant is used, such as __gmpfr_one for mpfr_cos. */
|
|
#define MPFR_SMALL_INPUT_AFTER_SAVE_EXPO(y,v,err1,err2,dir,rnd,expo,extra) \
|
|
do { \
|
|
mpfr_ptr _y = (y); \
|
|
mpfr_exp_t _err1 = (err1); \
|
|
mpfr_exp_t _err2 = (err2); \
|
|
if (_err1 > 0) \
|
|
{ \
|
|
mpfr_uexp_t _err = (mpfr_uexp_t) _err1 + _err2; \
|
|
if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1)) \
|
|
{ \
|
|
int _inexact; \
|
|
mpfr_clear_flags (); \
|
|
_inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd)); \
|
|
if (_inexact != 0) \
|
|
{ \
|
|
extra; \
|
|
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
|
|
MPFR_SAVE_EXPO_FREE (expo); \
|
|
return mpfr_check_range (_y, _inexact, (rnd)); \
|
|
} \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
/******************************************************
|
|
*************** Ziv Loop Macro *********************
|
|
******************************************************/
|
|
|
|
#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_FREE(x)
|
|
|
|
#else
|
|
|
|
/* The following test on glibc is there mainly for Darwin (Mac OS X), to
|
|
obtain a better error message. The real test should have been a test
|
|
concerning nested functions in gcc, which are disabled by default on
|
|
Darwin; but it is not possible to do that without a configure test. */
|
|
# if defined (__cplusplus) || !(__MPFR_GNUC(3,0) && __MPFR_GLIBC(2,0))
|
|
# error "Logging not supported (needs gcc >= 3.0 and GNU C Library >= 2.0)."
|
|
# endif
|
|
|
|
/* Use LOGGING */
|
|
#define MPFR_ZIV_DECL(_x) \
|
|
mpfr_prec_t _x; \
|
|
int _x ## _cpt = 1; \
|
|
static unsigned long _x ## _loop = 0, _x ## _bad = 0; \
|
|
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) \
|
|
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 ); }
|
|
|
|
#define MPFR_ZIV_INIT(_x, _p) ((_x) = GMP_NUMB_BITS, _x ## _loop ++); \
|
|
if (MPFR_LOG_BADCASE_F&mpfr_log_type && mpfr_log_current<=mpfr_log_level) \
|
|
fprintf (mpfr_log_file, "%s:ZIV 1st prec=%lu\n", __func__, \
|
|
(unsigned long) (_p))
|
|
|
|
#define MPFR_ZIV_NEXT(_x, _p) \
|
|
((_p)+=(_x),(_x)=(_p)/2, _x ## _bad += (_x ## _cpt == 1), _x ## _cpt ++); \
|
|
if (MPFR_LOG_BADCASE_F&mpfr_log_type && mpfr_log_current<=mpfr_log_level) \
|
|
fprintf (mpfr_log_file, "%s:ZIV new prec=%lu\n", __func__, \
|
|
(unsigned long) (_p))
|
|
|
|
#define MPFR_ZIV_FREE(_x) \
|
|
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", __func__, _x ## _cpt)
|
|
|
|
#endif
|
|
|
|
|
|
/******************************************************
|
|
*************** Logging Macros *********************
|
|
******************************************************/
|
|
|
|
/* The different kind of LOG */
|
|
#define MPFR_LOG_INPUT_F 1
|
|
#define MPFR_LOG_OUTPUT_F 2
|
|
#define MPFR_LOG_INTERNAL_F 4
|
|
#define MPFR_LOG_TIME_F 8
|
|
#define MPFR_LOG_BADCASE_F 16
|
|
#define MPFR_LOG_MSG_F 32
|
|
#define MPFR_LOG_STAT_F 64
|
|
|
|
#ifdef MPFR_USE_LOGGING
|
|
|
|
/* Check if we can support this feature */
|
|
# ifdef MPFR_USE_THREAD_SAFE
|
|
# error "Enable either `Logging' or `thread-safe', not both"
|
|
# endif
|
|
# if !__MPFR_GNUC(3,0)
|
|
# error "Logging not supported (GCC >= 3.0)"
|
|
# endif
|
|
|
|
#if defined (__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
__MPFR_DECLSPEC extern FILE *mpfr_log_file;
|
|
__MPFR_DECLSPEC extern int mpfr_log_type;
|
|
__MPFR_DECLSPEC extern int mpfr_log_level;
|
|
__MPFR_DECLSPEC extern int mpfr_log_current;
|
|
__MPFR_DECLSPEC extern int mpfr_log_base;
|
|
__MPFR_DECLSPEC extern mpfr_prec_t mpfr_log_prec;
|
|
|
|
#if defined (__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#define MPFR_LOG_VAR(x) \
|
|
if((MPFR_LOG_INTERNAL_F&mpfr_log_type)&&(mpfr_log_current<=mpfr_log_level))\
|
|
fprintf (mpfr_log_file, "%s.%d:%s[%#R]=%R\n", __func__,__LINE__, #x, x, x);
|
|
|
|
#define MPFR_LOG_MSG2(format, ...) \
|
|
if ((MPFR_LOG_MSG_F&mpfr_log_type)&&(mpfr_log_current<=mpfr_log_level)) \
|
|
fprintf (mpfr_log_file, "%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)) \
|
|
fprintf (mpfr_log_file, "%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 ();
|
|
#define MPFR_LOG_BEGIN(x) \
|
|
int __gmpfr_log_time = 0; \
|
|
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, \
|
|
mpfr_get_cputime () - __gmpfr_log_time); \
|
|
if ((MPFR_LOG_OUTPUT_F&mpfr_log_type)&&(mpfr_log_current<=mpfr_log_level)) \
|
|
fprintf (mpfr_log_file, "%s:OUT "format"\n",__mpfr_log_fname,__VA_ARGS__);\
|
|
mpfr_log_current --;
|
|
#define MPFR_LOG_END(x) \
|
|
static const char *__mpfr_log_fname = __func__; \
|
|
MPFR_LOG_END2 x
|
|
|
|
#define MPFR_LOG_FUNC(begin,end) \
|
|
static const char *__mpfr_log_fname = __func__; \
|
|
auto void __mpfr_log_cleanup (int *time); \
|
|
void __mpfr_log_cleanup (int *time) { \
|
|
int __gmpfr_log_time = *time; \
|
|
MPFR_LOG_END2 end; } \
|
|
int __gmpfr_log_time __attribute__ ((cleanup (__mpfr_log_cleanup))); \
|
|
__gmpfr_log_time = 0; \
|
|
MPFR_LOG_BEGIN2 begin
|
|
|
|
#else /* MPFR_USE_LOGGING */
|
|
|
|
/* Define void macro for logging */
|
|
|
|
#define MPFR_LOG_VAR(x)
|
|
#define MPFR_LOG_BEGIN(x)
|
|
#define MPFR_LOG_END(x)
|
|
#define MPFR_LOG_MSG(x)
|
|
#define MPFR_LOG_FUNC(x,y)
|
|
|
|
#endif /* MPFR_USE_LOGGING */
|
|
|
|
|
|
/**************************************************************
|
|
************ Group Initialize Functions Macros *************
|
|
**************************************************************/
|
|
|
|
#ifndef MPFR_GROUP_STATIC_SIZE
|
|
# define MPFR_GROUP_STATIC_SIZE 16
|
|
#endif
|
|
|
|
struct mpfr_group_t {
|
|
size_t alloc;
|
|
mp_limb_t *mant;
|
|
mp_limb_t tab[MPFR_GROUP_STATIC_SIZE];
|
|
};
|
|
|
|
#define MPFR_GROUP_DECL(g) struct mpfr_group_t g
|
|
#define MPFR_GROUP_CLEAR(g) do { \
|
|
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)) { \
|
|
MPFR_ASSERTD ((g).mant != (g).tab); \
|
|
(*__gmp_free_func) ((g).mant, (g).alloc); \
|
|
}} while (0)
|
|
|
|
#define MPFR_GROUP_INIT_TEMPLATE(g, prec, num, handler) do { \
|
|
mpfr_prec_t _prec = (prec); \
|
|
mp_size_t _size; \
|
|
MPFR_ASSERTD (_prec >= MPFR_PREC_MIN); \
|
|
if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
|
|
mpfr_abort_prec_max (); \
|
|
_size = (mpfr_prec_t) (_prec + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; \
|
|
if (MPFR_UNLIKELY (_size * (num) > MPFR_GROUP_STATIC_SIZE)) \
|
|
{ \
|
|
(g).alloc = (num) * _size * sizeof (mp_limb_t); \
|
|
(g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
|
|
} \
|
|
else \
|
|
{ \
|
|
(g).alloc = 0; \
|
|
(g).mant = (g).tab; \
|
|
} \
|
|
MPFR_LOG_MSG (("GROUP_INIT: ptr = 0x%lX, size = %lu\n", \
|
|
(unsigned long) (g).mant, (unsigned long) (g).alloc)); \
|
|
handler; \
|
|
} while (0)
|
|
#define MPFR_GROUP_TINIT(g, n, x) \
|
|
MPFR_TMP_INIT1 ((g).mant + _size * (n), x, _prec)
|
|
|
|
#define MPFR_GROUP_INIT_1(g, prec, x) \
|
|
MPFR_GROUP_INIT_TEMPLATE(g, prec, 1, MPFR_GROUP_TINIT(g, 0, x))
|
|
#define MPFR_GROUP_INIT_2(g, prec, x, y) \
|
|
MPFR_GROUP_INIT_TEMPLATE(g, prec, 2, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y))
|
|
#define MPFR_GROUP_INIT_3(g, prec, x, y, z) \
|
|
MPFR_GROUP_INIT_TEMPLATE(g, prec, 3, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z))
|
|
#define MPFR_GROUP_INIT_4(g, prec, x, y, z, t) \
|
|
MPFR_GROUP_INIT_TEMPLATE(g, prec, 4, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t))
|
|
#define MPFR_GROUP_INIT_5(g, prec, x, y, z, t, a) \
|
|
MPFR_GROUP_INIT_TEMPLATE(g, prec, 5, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
|
|
MPFR_GROUP_TINIT(g, 4, a))
|
|
#define MPFR_GROUP_INIT_6(g, prec, x, y, z, t, a, b) \
|
|
MPFR_GROUP_INIT_TEMPLATE(g, prec, 6, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
|
|
MPFR_GROUP_TINIT(g, 4, a);MPFR_GROUP_TINIT(g, 5, b))
|
|
|
|
#define MPFR_GROUP_REPREC_TEMPLATE(g, prec, num, handler) do { \
|
|
mpfr_prec_t _prec = (prec); \
|
|
size_t _oalloc = (g).alloc; \
|
|
mp_size_t _size; \
|
|
MPFR_LOG_MSG (("GROUP_REPREC: oldptr = 0x%lX, oldsize = %lu\n", \
|
|
(unsigned long) (g).mant, (unsigned long) _oalloc)); \
|
|
MPFR_ASSERTD (_prec >= MPFR_PREC_MIN); \
|
|
if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
|
|
mpfr_abort_prec_max (); \
|
|
_size = (mpfr_prec_t) (_prec + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; \
|
|
(g).alloc = (num) * _size * sizeof (mp_limb_t); \
|
|
if (MPFR_LIKELY (_oalloc == 0)) \
|
|
(g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
|
|
else \
|
|
(g).mant = (mp_limb_t *) \
|
|
(*__gmp_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; \
|
|
} while (0)
|
|
|
|
#define MPFR_GROUP_REPREC_1(g, prec, x) \
|
|
MPFR_GROUP_REPREC_TEMPLATE(g, prec, 1, MPFR_GROUP_TINIT(g, 0, x))
|
|
#define MPFR_GROUP_REPREC_2(g, prec, x, y) \
|
|
MPFR_GROUP_REPREC_TEMPLATE(g, prec, 2, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y))
|
|
#define MPFR_GROUP_REPREC_3(g, prec, x, y, z) \
|
|
MPFR_GROUP_REPREC_TEMPLATE(g, prec, 3, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z))
|
|
#define MPFR_GROUP_REPREC_4(g, prec, x, y, z, t) \
|
|
MPFR_GROUP_REPREC_TEMPLATE(g, prec, 4, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t))
|
|
#define MPFR_GROUP_REPREC_5(g, prec, x, y, z, t, a) \
|
|
MPFR_GROUP_REPREC_TEMPLATE(g, prec, 5, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
|
|
MPFR_GROUP_TINIT(g, 4, a))
|
|
#define MPFR_GROUP_REPREC_6(g, prec, x, y, z, t, a, b) \
|
|
MPFR_GROUP_REPREC_TEMPLATE(g, prec, 6, \
|
|
MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
|
|
MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
|
|
MPFR_GROUP_TINIT(g, 4, a);MPFR_GROUP_TINIT(g, 5, b))
|
|
|
|
|
|
/******************************************************
|
|
*************** 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_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_cmp2 _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr,
|
|
mpfr_prec_t *));
|
|
|
|
__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_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 int mpfr_pow_general _MPFR_PROTO ((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 long mpfr_mpn_exp _MPFR_PROTO ((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));
|
|
#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 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_4 _MPFR_PROTO ((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_DECLSPEC int mpfr_get_cputime _MPFR_PROTO ((void));
|
|
|
|
__MPFR_DECLSPEC void mpfr_nexttozero _MPFR_PROTO ((mpfr_ptr));
|
|
__MPFR_DECLSPEC void mpfr_nexttoinf _MPFR_PROTO ((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));
|
|
|
|
#if 0
|
|
__MPFR_DECLSPEC void mpfr_init_cache _MPFR_PROTO ((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_mulhigh_n _MPFR_PROTO ((mp_ptr, mp_srcptr,
|
|
mp_srcptr, mp_size_t));
|
|
__MPFR_DECLSPEC void mpfr_sqrhigh_n _MPFR_PROTO ((mp_ptr, mp_srcptr, 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 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_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_PROTO((mp_ptr, gmp_randstate_t,
|
|
unsigned long));
|
|
|
|
__MPFR_DECLSPEC mpz_t* mpfr_bernoulli_internal _MPFR_PROTO((mpz_t*,
|
|
unsigned long));
|
|
|
|
__MPFR_DECLSPEC int mpfr_sincos_fast _MPFR_PROTO((mpfr_t, mpfr_t,
|
|
mpfr_srcptr, mpfr_rnd_t));
|
|
|
|
__MPFR_DECLSPEC double mpfr_scale2 _MPFR_PROTO((double, int));
|
|
|
|
__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_PROTO((mpfr_ptr, mpfr_ptr, mp_prec_t));
|
|
|
|
#if defined (__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif
|