xref: /dflybsd-src/contrib/mpfr/src/mpfr-impl.h (revision 2786097444a0124b5d33763854de247e230c6629)
14a238c70SJohn Marino /* Utilities for MPFR developers, not exported.
24a238c70SJohn Marino 
3*ab6d115fSJohn Marino Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4*ab6d115fSJohn Marino Contributed by the AriC and Caramel projects, INRIA.
54a238c70SJohn Marino 
64a238c70SJohn Marino This file is part of the GNU MPFR Library.
74a238c70SJohn Marino 
84a238c70SJohn Marino The GNU MPFR Library is free software; you can redistribute it and/or modify
94a238c70SJohn Marino it under the terms of the GNU Lesser General Public License as published by
104a238c70SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
114a238c70SJohn Marino option) any later version.
124a238c70SJohn Marino 
134a238c70SJohn Marino The GNU MPFR Library is distributed in the hope that it will be useful, but
144a238c70SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
154a238c70SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
164a238c70SJohn Marino License for more details.
174a238c70SJohn Marino 
184a238c70SJohn Marino You should have received a copy of the GNU Lesser General Public License
194a238c70SJohn Marino along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
204a238c70SJohn Marino http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
214a238c70SJohn Marino 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
224a238c70SJohn Marino 
234a238c70SJohn Marino #ifndef __MPFR_IMPL_H__
244a238c70SJohn Marino #define __MPFR_IMPL_H__
254a238c70SJohn Marino 
264a238c70SJohn Marino /* Let's include some standard headers unconditionally as they are
274a238c70SJohn Marino    already needed by several source files or when some options are
284a238c70SJohn Marino    enabled/disabled, and it is easy to forget them (some configure
294a238c70SJohn Marino    options may hide the error).
304a238c70SJohn Marino    Note: If some source file must not have such a header included
314a238c70SJohn Marino    (which is very unlikely and probably means something broken in
324a238c70SJohn Marino    this source file), we should do that with some macro (that would
334a238c70SJohn Marino    also force to disable incompatible features). */
344a238c70SJohn Marino #if defined (__cplusplus)
354a238c70SJohn Marino #include <cstdio>
364a238c70SJohn Marino #include <cstring>
374a238c70SJohn Marino #else
384a238c70SJohn Marino #include <stdio.h>
394a238c70SJohn Marino #include <string.h>
404a238c70SJohn Marino #endif
414a238c70SJohn Marino #include <limits.h>
424a238c70SJohn Marino 
434a238c70SJohn Marino #if _MPFR_EXP_FORMAT == 4
444a238c70SJohn Marino /* mpfr_exp_t will be defined as intmax_t */
454a238c70SJohn Marino # include "mpfr-intmax.h"
464a238c70SJohn Marino #endif
474a238c70SJohn Marino 
484a238c70SJohn Marino /* Check if we are inside a build of MPFR or inside the test suite.
494a238c70SJohn Marino    This is needed in mpfr.h to export or import the functions.
504a238c70SJohn Marino    It matters only for Windows DLL */
514a238c70SJohn Marino #ifndef __MPFR_TEST_H__
524a238c70SJohn Marino # define __MPFR_WITHIN_MPFR 1
534a238c70SJohn Marino #endif
544a238c70SJohn Marino 
554a238c70SJohn Marino /******************************************************
564a238c70SJohn Marino  ****************** Include files *********************
574a238c70SJohn Marino  ******************************************************/
584a238c70SJohn Marino 
594a238c70SJohn Marino /* Include 'config.h' before using ANY configure macros if needed
604a238c70SJohn Marino    NOTE: It isn't MPFR 'config.h', but GMP's one! */
614a238c70SJohn Marino #ifdef HAVE_CONFIG_H
624a238c70SJohn Marino # include "config.h"
634a238c70SJohn Marino #endif
644a238c70SJohn Marino 
654a238c70SJohn Marino #ifdef  MPFR_HAVE_GMP_IMPL /* Build with gmp internals*/
664a238c70SJohn Marino 
674a238c70SJohn Marino # ifndef __GMP_H__
684a238c70SJohn Marino #  include "gmp.h"
694a238c70SJohn Marino # endif
704a238c70SJohn Marino # ifndef __GMP_IMPL_H__
714a238c70SJohn Marino #  include "gmp-impl.h"
724a238c70SJohn Marino # endif
734a238c70SJohn Marino # ifdef MPFR_NEED_LONGLONG_H
744a238c70SJohn Marino #  include "longlong.h"
754a238c70SJohn Marino # endif
764a238c70SJohn Marino # ifndef __MPFR_H
774a238c70SJohn Marino #  include "mpfr.h"
784a238c70SJohn Marino # endif
794a238c70SJohn Marino 
804a238c70SJohn Marino #else /* Build without gmp internals */
814a238c70SJohn Marino 
824a238c70SJohn Marino # ifndef __GMP_H__
834a238c70SJohn Marino #  include "gmp.h"
844a238c70SJohn Marino # endif
854a238c70SJohn Marino # ifndef __MPFR_H
864a238c70SJohn Marino #  include "mpfr.h"
874a238c70SJohn Marino # endif
884a238c70SJohn Marino # ifndef __GMPFR_GMP_H__
894a238c70SJohn Marino #  include "mpfr-gmp.h"
904a238c70SJohn Marino # endif
914a238c70SJohn Marino # ifdef MPFR_NEED_LONGLONG_H
924a238c70SJohn Marino #  define LONGLONG_STANDALONE
934a238c70SJohn Marino #  include "mpfr-longlong.h"
944a238c70SJohn Marino # endif
954a238c70SJohn Marino 
964a238c70SJohn Marino #endif
974a238c70SJohn Marino #undef MPFR_NEED_LONGLONG_H
984a238c70SJohn Marino 
994a238c70SJohn Marino /* If a mpn_sqr_n macro is not defined, use mpn_mul. GMP 4.x defines a
1004a238c70SJohn Marino    mpn_sqr_n macro in gmp-impl.h (and this macro disappeared in GMP 5),
1014a238c70SJohn Marino    so that GMP's macro can only be used when MPFR has been configured
1024a238c70SJohn Marino    with --with-gmp-build (and only with GMP 4.x). */
1034a238c70SJohn Marino #ifndef mpn_sqr_n
1044a238c70SJohn Marino # define mpn_sqr_n(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
1054a238c70SJohn Marino #endif
1064a238c70SJohn Marino 
1074a238c70SJohn Marino /* For the definition of MPFR_THREAD_ATTR. GCC/ICC detection macros are
1084a238c70SJohn Marino    no longer used, as they sometimes gave incorrect information about
1094a238c70SJohn Marino    the support of thread-local variables. A configure check is now done.
1104a238c70SJohn Marino    If the use of detection macros is needed in the future, this could be
1114a238c70SJohn Marino    moved below (after the detection macros are defined). */
1124a238c70SJohn Marino #include "mpfr-thread.h"
1134a238c70SJohn Marino 
1144a238c70SJohn Marino 
1154a238c70SJohn Marino /******************************************************
1164a238c70SJohn Marino  ***************** Detection macros *******************
1174a238c70SJohn Marino  ******************************************************/
1184a238c70SJohn Marino 
1194a238c70SJohn Marino /* Macros to detect STDC, GCC, GLIBC, GMP and ICC version */
1204a238c70SJohn Marino #if defined(__STDC_VERSION__)
1214a238c70SJohn Marino # define __MPFR_STDC(version) (__STDC_VERSION__>=(version))
1224a238c70SJohn Marino #elif defined(__STDC__)
1234a238c70SJohn Marino # define __MPFR_STDC(version) (0 == (version))
1244a238c70SJohn Marino #else
1254a238c70SJohn Marino # define __MPFR_STDC(version) 0
1264a238c70SJohn Marino #endif
1274a238c70SJohn Marino 
1284a238c70SJohn Marino #if defined(_WIN32)
1294a238c70SJohn Marino /* Under MS Windows (e.g. with VS2008 or VS2010), Intel's compiler doesn't
1304a238c70SJohn Marino    support/enable extensions like the ones seen under GNU/Linux.
131*ab6d115fSJohn Marino    https://sympa.inria.fr/sympa/arc/mpfr/2011-02/msg00032.html */
1324a238c70SJohn Marino # define __MPFR_ICC(a,b,c) 0
1334a238c70SJohn Marino #elif defined(__ICC)
1344a238c70SJohn Marino # define __MPFR_ICC(a,b,c) (__ICC >= (a)*100+(b)*10+(c))
1354a238c70SJohn Marino #elif defined(__INTEL_COMPILER)
1364a238c70SJohn Marino # define __MPFR_ICC(a,b,c) (__INTEL_COMPILER >= (a)*100+(b)*10+(c))
1374a238c70SJohn Marino #else
1384a238c70SJohn Marino # define __MPFR_ICC(a,b,c) 0
1394a238c70SJohn Marino #endif
1404a238c70SJohn Marino 
1414a238c70SJohn Marino #if defined(__GNUC__) && defined(__GNUC_MINOR__) && ! __MPFR_ICC(0,0,0)
1424a238c70SJohn Marino # define __MPFR_GNUC(a,i) \
1434a238c70SJohn Marino  (MPFR_VERSION_NUM(__GNUC__,__GNUC_MINOR__,0) >= MPFR_VERSION_NUM(a,i,0))
1444a238c70SJohn Marino #else
1454a238c70SJohn Marino # define __MPFR_GNUC(a,i) 0
1464a238c70SJohn Marino #endif
1474a238c70SJohn Marino 
1484a238c70SJohn Marino #if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
1494a238c70SJohn Marino # define __MPFR_GLIBC(a,i) \
1504a238c70SJohn Marino  (MPFR_VERSION_NUM(__GLIBC__,__GLIBC_MINOR__,0) >= MPFR_VERSION_NUM(a,i,0))
1514a238c70SJohn Marino #else
1524a238c70SJohn Marino # define __MPFR_GLIBC(a,i) 0
1534a238c70SJohn Marino #endif
1544a238c70SJohn Marino 
1554a238c70SJohn Marino #if defined(__GNU_MP_VERSION) && \
1564a238c70SJohn Marino     defined(__GNU_MP_VERSION_MINOR) && \
1574a238c70SJohn Marino     defined(__GNU_MP_VERSION_PATCHLEVEL)
1584a238c70SJohn Marino # define __MPFR_GMP(a,b,c) \
1594a238c70SJohn Marino   (MPFR_VERSION_NUM(__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR,__GNU_MP_VERSION_PATCHLEVEL) >= MPFR_VERSION_NUM(a,b,c))
1604a238c70SJohn Marino #else
1614a238c70SJohn Marino # define __MPFR_GMP(a,b,c) 0
1624a238c70SJohn Marino #endif
1634a238c70SJohn Marino 
1644a238c70SJohn Marino 
1654a238c70SJohn Marino 
1664a238c70SJohn Marino /******************************************************
1674a238c70SJohn Marino  ************* GMP Basic Pointer Types ****************
1684a238c70SJohn Marino  ******************************************************/
1694a238c70SJohn Marino 
1704a238c70SJohn Marino typedef mp_limb_t *mpfr_limb_ptr;
1714a238c70SJohn Marino typedef __gmp_const mp_limb_t *mpfr_limb_srcptr;
1724a238c70SJohn Marino 
1734a238c70SJohn Marino 
1744a238c70SJohn Marino 
1754a238c70SJohn Marino /******************************************************
1764a238c70SJohn Marino  ****************** (U)INTMAX_MAX *********************
1774a238c70SJohn Marino  ******************************************************/
1784a238c70SJohn Marino 
1794a238c70SJohn Marino /* Let's try to fix UINTMAX_MAX and INTMAX_MAX if these macros don't work
1804a238c70SJohn Marino    (e.g. with gcc -ansi -pedantic-errors in 32-bit mode under GNU/Linux),
1814a238c70SJohn Marino    see <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582698>. */
1824a238c70SJohn Marino #ifdef _MPFR_H_HAVE_INTMAX_T
1834a238c70SJohn Marino # ifdef MPFR_HAVE_INTMAX_MAX
1844a238c70SJohn Marino #  define MPFR_UINTMAX_MAX UINTMAX_MAX
1854a238c70SJohn Marino #  define MPFR_INTMAX_MAX INTMAX_MAX
1864a238c70SJohn Marino #  define MPFR_INTMAX_MIN INTMAX_MIN
1874a238c70SJohn Marino # else
1884a238c70SJohn Marino #  define MPFR_UINTMAX_MAX ((uintmax_t) -1)
1894a238c70SJohn Marino #  define MPFR_INTMAX_MAX ((intmax_t) (MPFR_UINTMAX_MAX >> 1))
1904a238c70SJohn Marino #  define MPFR_INTMAX_MIN (INT_MIN + INT_MAX - MPFR_INTMAX_MAX)
1914a238c70SJohn Marino # endif
1924a238c70SJohn Marino #endif
1934a238c70SJohn Marino 
1944a238c70SJohn Marino 
1954a238c70SJohn Marino 
1964a238c70SJohn Marino /******************************************************
1974a238c70SJohn Marino  ******************** Check GMP ***********************
1984a238c70SJohn Marino  ******************************************************/
1994a238c70SJohn Marino 
2004a238c70SJohn Marino #if !__MPFR_GMP(4,1,0)
2014a238c70SJohn Marino # error "GMP 4.1.0 or newer needed"
2024a238c70SJohn Marino #endif
2034a238c70SJohn Marino 
2044a238c70SJohn Marino #if GMP_NAIL_BITS != 0
2054a238c70SJohn Marino # error "MPFR doesn't support nonzero values of GMP_NAIL_BITS"
2064a238c70SJohn Marino #endif
2074a238c70SJohn Marino 
2084a238c70SJohn Marino #if (GMP_NUMB_BITS<32) || (GMP_NUMB_BITS & (GMP_NUMB_BITS - 1))
2094a238c70SJohn Marino # error "GMP_NUMB_BITS must be a power of 2, and >= 32"
2104a238c70SJohn Marino #endif
2114a238c70SJohn Marino 
2124a238c70SJohn Marino #if GMP_NUMB_BITS == 16
2134a238c70SJohn Marino # define MPFR_LOG2_GMP_NUMB_BITS 4
2144a238c70SJohn Marino #elif GMP_NUMB_BITS == 32
2154a238c70SJohn Marino # define MPFR_LOG2_GMP_NUMB_BITS 5
2164a238c70SJohn Marino #elif GMP_NUMB_BITS == 64
2174a238c70SJohn Marino # define MPFR_LOG2_GMP_NUMB_BITS 6
2184a238c70SJohn Marino #elif GMP_NUMB_BITS == 128
2194a238c70SJohn Marino # define MPFR_LOG2_GMP_NUMB_BITS 7
2204a238c70SJohn Marino #elif GMP_NUMB_BITS == 256
2214a238c70SJohn Marino # define MPFR_LOG2_GMP_NUMB_BITS 8
2224a238c70SJohn Marino #else
2234a238c70SJohn Marino # error "Can't compute log2(GMP_NUMB_BITS)"
2244a238c70SJohn Marino #endif
2254a238c70SJohn Marino 
2264a238c70SJohn Marino #if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
2274a238c70SJohn Marino /* For the future: N1478: Supporting the 'noreturn' property in C1x
2284a238c70SJohn Marino    http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1478.htm */
2294a238c70SJohn Marino # define MPFR_NORETURN_ATTR __attribute__ ((noreturn))
2304a238c70SJohn Marino # define MPFR_CONST_ATTR    __attribute__ ((const))
2314a238c70SJohn Marino #else
2324a238c70SJohn Marino # define MPFR_NORETURN_ATTR
2334a238c70SJohn Marino # define MPFR_CONST_ATTR
2344a238c70SJohn Marino #endif
2354a238c70SJohn Marino 
2364a238c70SJohn Marino /******************************************************
2374a238c70SJohn Marino  ************* Global Internal Variables **************
2384a238c70SJohn Marino  ******************************************************/
2394a238c70SJohn Marino 
2404a238c70SJohn Marino /* Cache struct */
2414a238c70SJohn Marino struct __gmpfr_cache_s {
2424a238c70SJohn Marino   mpfr_t x;
2434a238c70SJohn Marino   int inexact;
2444a238c70SJohn Marino   int (*func)(mpfr_ptr, mpfr_rnd_t);
2454a238c70SJohn Marino };
2464a238c70SJohn Marino typedef struct __gmpfr_cache_s mpfr_cache_t[1];
2474a238c70SJohn Marino typedef struct __gmpfr_cache_s *mpfr_cache_ptr;
2484a238c70SJohn Marino 
2494a238c70SJohn Marino #if defined (__cplusplus)
2504a238c70SJohn Marino extern "C" {
2514a238c70SJohn Marino #endif
2524a238c70SJohn Marino 
2534a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags;
2544a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t   __gmpfr_emin;
2554a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t   __gmpfr_emax;
2564a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_prec_t  __gmpfr_default_fp_bit_precision;
2574a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_rnd_t   __gmpfr_default_rounding_mode;
2584a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_euler;
2594a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_catalan;
2604a238c70SJohn Marino 
2614a238c70SJohn Marino #ifndef MPFR_USE_LOGGING
2624a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_pi;
2634a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_log2;
2644a238c70SJohn Marino #else
2654a238c70SJohn Marino /* Two constants are used by the logging functions (via mpfr_fprintf,
2664a238c70SJohn Marino    then mpfr_log, for the base conversion): pi and log(2). Since the
2674a238c70SJohn Marino    mpfr_cache function isn't re-entrant when working on the same cache,
2684a238c70SJohn Marino    we need to define two caches for each constant. */
2694a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_normal_pi;
2704a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_normal_log2;
2714a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_logging_pi;
2724a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_logging_log2;
2734a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_ptr __gmpfr_cache_const_pi;
2744a238c70SJohn Marino __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_ptr __gmpfr_cache_const_log2;
2754a238c70SJohn Marino #endif
2764a238c70SJohn Marino 
2774a238c70SJohn Marino #define BASE_MAX 62
2784a238c70SJohn Marino __MPFR_DECLSPEC extern const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2];
2794a238c70SJohn Marino 
2804a238c70SJohn Marino /* Note: do not use the following values when they can be outside the
2814a238c70SJohn Marino    current exponent range, e.g. when the exponent range has not been
2824a238c70SJohn Marino    extended yet; under such a condition, they can be used only in
2834a238c70SJohn Marino    mpfr_cmpabs. */
2844a238c70SJohn Marino __MPFR_DECLSPEC extern const mpfr_t __gmpfr_one;
2854a238c70SJohn Marino __MPFR_DECLSPEC extern const mpfr_t __gmpfr_two;
2864a238c70SJohn Marino __MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
2874a238c70SJohn Marino 
2884a238c70SJohn Marino 
2894a238c70SJohn Marino #if defined (__cplusplus)
2904a238c70SJohn Marino  }
2914a238c70SJohn Marino #endif
2924a238c70SJohn Marino 
2934a238c70SJohn Marino /* Flags of __gmpfr_flags */
2944a238c70SJohn Marino #define MPFR_FLAGS_UNDERFLOW 1
2954a238c70SJohn Marino #define MPFR_FLAGS_OVERFLOW 2
2964a238c70SJohn Marino #define MPFR_FLAGS_NAN 4
2974a238c70SJohn Marino #define MPFR_FLAGS_INEXACT 8
2984a238c70SJohn Marino #define MPFR_FLAGS_ERANGE 16
2994a238c70SJohn Marino #define MPFR_FLAGS_DIVBY0 32
3004a238c70SJohn Marino #define MPFR_FLAGS_ALL 63
3014a238c70SJohn Marino 
3024a238c70SJohn Marino /* Replace some common functions for direct access to the global vars */
3034a238c70SJohn Marino #define mpfr_get_emin() (__gmpfr_emin + 0)
3044a238c70SJohn Marino #define mpfr_get_emax() (__gmpfr_emax + 0)
3054a238c70SJohn Marino #define mpfr_get_default_rounding_mode() (__gmpfr_default_rounding_mode + 0)
3064a238c70SJohn Marino #define mpfr_get_default_prec() (__gmpfr_default_fp_bit_precision + 0)
3074a238c70SJohn Marino 
3084a238c70SJohn Marino #define mpfr_clear_flags() \
3094a238c70SJohn Marino   ((void) (__gmpfr_flags = 0))
3104a238c70SJohn Marino #define mpfr_clear_underflow() \
3114a238c70SJohn Marino   ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW))
3124a238c70SJohn Marino #define mpfr_clear_overflow() \
3134a238c70SJohn Marino   ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW))
3144a238c70SJohn Marino #define mpfr_clear_nanflag() \
3154a238c70SJohn Marino   ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN))
3164a238c70SJohn Marino #define mpfr_clear_inexflag() \
3174a238c70SJohn Marino   ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT))
3184a238c70SJohn Marino #define mpfr_clear_erangeflag() \
3194a238c70SJohn Marino   ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE))
3204a238c70SJohn Marino #define mpfr_clear_divby0() \
3214a238c70SJohn Marino   ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0))
3224a238c70SJohn Marino #define mpfr_underflow_p() \
3234a238c70SJohn Marino   ((int) (__gmpfr_flags & MPFR_FLAGS_UNDERFLOW))
3244a238c70SJohn Marino #define mpfr_overflow_p() \
3254a238c70SJohn Marino   ((int) (__gmpfr_flags & MPFR_FLAGS_OVERFLOW))
3264a238c70SJohn Marino #define mpfr_nanflag_p() \
3274a238c70SJohn Marino   ((int) (__gmpfr_flags & MPFR_FLAGS_NAN))
3284a238c70SJohn Marino #define mpfr_inexflag_p() \
3294a238c70SJohn Marino   ((int) (__gmpfr_flags & MPFR_FLAGS_INEXACT))
3304a238c70SJohn Marino #define mpfr_erangeflag_p() \
3314a238c70SJohn Marino   ((int) (__gmpfr_flags & MPFR_FLAGS_ERANGE))
3324a238c70SJohn Marino #define mpfr_divby0_p() \
3334a238c70SJohn Marino   ((int) (__gmpfr_flags & MPFR_FLAGS_DIVBY0))
3344a238c70SJohn Marino 
3354a238c70SJohn Marino /* Testing an exception flag correctly is tricky. There are mainly two
3364a238c70SJohn Marino    pitfalls: First, one needs to remember to clear the corresponding
3374a238c70SJohn Marino    flag, in case it was set before the function call or during some
3384a238c70SJohn Marino    intermediate computations (in practice, one can clear all the flags).
3394a238c70SJohn Marino    Secondly, one needs to test the flag early enough, i.e. before it
3404a238c70SJohn Marino    can be modified by another function. Moreover, it is quite difficult
3414a238c70SJohn Marino    (if not impossible) to reliably check problems with "make check". To
3424a238c70SJohn Marino    avoid these pitfalls, it is recommended to use the following macros.
3434a238c70SJohn Marino    Other use of the exception-flag predicate functions/macros will be
3444a238c70SJohn Marino    detected by mpfrlint.
3454a238c70SJohn Marino    Note: _op can be either a statement or an expression.
3464a238c70SJohn Marino    MPFR_BLOCK_EXCEP should be used only inside a block; it is useful to
3474a238c70SJohn Marino    detect some exception in order to exit the block as soon as possible. */
3484a238c70SJohn Marino #define MPFR_BLOCK_DECL(_flags) unsigned int _flags
3494a238c70SJohn Marino /* The (void) (_flags) makes sure that _flags is read at least once (it
3504a238c70SJohn Marino    makes sense to use MPFR_BLOCK while _flags will never be read in the
3514a238c70SJohn Marino    source, so that we wish to avoid the corresponding warning). */
3524a238c70SJohn Marino #define MPFR_BLOCK(_flags,_op)          \
3534a238c70SJohn Marino   do                                    \
3544a238c70SJohn Marino     {                                   \
3554a238c70SJohn Marino       mpfr_clear_flags ();              \
3564a238c70SJohn Marino       _op;                              \
3574a238c70SJohn Marino       (_flags) = __gmpfr_flags;         \
3584a238c70SJohn Marino       (void) (_flags);                  \
3594a238c70SJohn Marino     }                                   \
3604a238c70SJohn Marino   while (0)
3614a238c70SJohn Marino #define MPFR_BLOCK_TEST(_flags,_f) MPFR_UNLIKELY ((_flags) & (_f))
3624a238c70SJohn Marino #define MPFR_BLOCK_EXCEP (__gmpfr_flags & (MPFR_FLAGS_UNDERFLOW | \
3634a238c70SJohn Marino                                            MPFR_FLAGS_OVERFLOW | \
3644a238c70SJohn Marino                                            MPFR_FLAGS_DIVBY0 | \
3654a238c70SJohn Marino                                            MPFR_FLAGS_NAN))
3664a238c70SJohn Marino /* Let's use a MPFR_ prefix, because e.g. OVERFLOW is defined by glibc's
3674a238c70SJohn Marino    math.h, though this is not a reserved identifier! */
3684a238c70SJohn Marino #define MPFR_UNDERFLOW(_flags)  MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_UNDERFLOW)
3694a238c70SJohn Marino #define MPFR_OVERFLOW(_flags)   MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_OVERFLOW)
3704a238c70SJohn Marino #define MPFR_NANFLAG(_flags)    MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_NAN)
3714a238c70SJohn Marino #define MPFR_INEXFLAG(_flags)   MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_INEXACT)
3724a238c70SJohn Marino #define MPFR_ERANGEFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_ERANGE)
3734a238c70SJohn Marino #define MPFR_DIVBY0(_flags)     MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_DIVBY0)
3744a238c70SJohn Marino 
3754a238c70SJohn Marino 
3764a238c70SJohn Marino /******************************************************
3774a238c70SJohn Marino  ******************** Assertions **********************
3784a238c70SJohn Marino  ******************************************************/
3794a238c70SJohn Marino 
3804a238c70SJohn Marino /* Compile with -DWANT_ASSERT to check all assert statements */
3814a238c70SJohn Marino 
3824a238c70SJohn Marino /* Note: do not use GMP macros ASSERT_ALWAYS and ASSERT as they are not
3834a238c70SJohn Marino    expressions, and as a consequence, they cannot be used in a for(),
3844a238c70SJohn Marino    with a comma operator and so on. */
3854a238c70SJohn Marino 
3864a238c70SJohn Marino /* MPFR_ASSERTN(expr): assertions that should always be checked */
3874a238c70SJohn Marino #define MPFR_ASSERTN(expr)  \
3884a238c70SJohn Marino    ((void) ((MPFR_UNLIKELY(expr)) || MPFR_UNLIKELY( (ASSERT_FAIL(expr),0) )))
3894a238c70SJohn Marino 
3904a238c70SJohn Marino /* MPFR_ASSERTD(expr): assertions that should be checked when testing */
3914a238c70SJohn Marino #ifdef WANT_ASSERT
3924a238c70SJohn Marino # define MPFR_EXP_CHECK 1
3934a238c70SJohn Marino # define MPFR_ASSERTD(expr)  MPFR_ASSERTN (expr)
3944a238c70SJohn Marino #else
3954a238c70SJohn Marino # define MPFR_ASSERTD(expr)  ((void) 0)
3964a238c70SJohn Marino #endif
3974a238c70SJohn Marino 
3984a238c70SJohn Marino /* Code to deal with impossible
3994a238c70SJohn Marino    WARNING: It doesn't use do { } while (0) for Insure++*/
4004a238c70SJohn Marino #define MPFR_RET_NEVER_GO_HERE()  {MPFR_ASSERTN(0); return 0;}
4014a238c70SJohn Marino 
4024a238c70SJohn Marino 
4034a238c70SJohn Marino /******************************************************
4044a238c70SJohn Marino  ******************** Warnings ************************
4054a238c70SJohn Marino  ******************************************************/
4064a238c70SJohn Marino 
4074a238c70SJohn Marino /* MPFR_WARNING is no longer useful, but let's keep the macro in case
4084a238c70SJohn Marino    it needs to be used again in the future. */
4094a238c70SJohn Marino 
4104a238c70SJohn Marino #ifdef MPFR_USE_WARNINGS
4114a238c70SJohn Marino # include <stdlib.h>
4124a238c70SJohn Marino # define MPFR_WARNING(W)                    \
4134a238c70SJohn Marino   do                                        \
4144a238c70SJohn Marino     {                                       \
4154a238c70SJohn Marino       char *q = getenv ("MPFR_QUIET");      \
4164a238c70SJohn Marino       if (q == NULL || *q == 0)             \
4174a238c70SJohn Marino         fprintf (stderr, "MPFR: %s\n", W);  \
4184a238c70SJohn Marino     }                                       \
4194a238c70SJohn Marino   while (0)
4204a238c70SJohn Marino #else
4214a238c70SJohn Marino # define MPFR_WARNING(W)  ((void) 0)
4224a238c70SJohn Marino #endif
4234a238c70SJohn Marino 
4244a238c70SJohn Marino 
4254a238c70SJohn Marino /******************************************************
4264a238c70SJohn Marino  ****************** double macros *********************
4274a238c70SJohn Marino  ******************************************************/
4284a238c70SJohn Marino 
4294a238c70SJohn Marino /* Precision used for lower precision computations */
4304a238c70SJohn Marino #define MPFR_SMALL_PRECISION 32
4314a238c70SJohn Marino 
4324a238c70SJohn Marino /* Definition of constants */
4334a238c70SJohn Marino #define LOG2 0.69314718055994528622 /* log(2) rounded to zero on 53 bits */
4344a238c70SJohn Marino #define ALPHA 4.3191365662914471407 /* a+2 = a*log(a), rounded to +infinity */
4354a238c70SJohn Marino #define EXPM1 0.36787944117144227851 /* exp(-1), rounded to zero */
4364a238c70SJohn Marino 
4374a238c70SJohn Marino /* MPFR_DOUBLE_SPEC = 1 if the C type 'double' corresponds to IEEE-754
4384a238c70SJohn Marino    double precision, 0 if it doesn't, and undefined if one doesn't know.
4394a238c70SJohn Marino    On all the tested machines, MPFR_DOUBLE_SPEC = 1. To have this macro
4404a238c70SJohn Marino    defined here, #include <float.h> is needed. If need be, other values
4414a238c70SJohn Marino    could be defined for other specs (once they are known). */
4424a238c70SJohn Marino #if !defined(MPFR_DOUBLE_SPEC) && defined(FLT_RADIX) && \
4434a238c70SJohn Marino     defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) && defined(DBL_MAX_EXP)
4444a238c70SJohn Marino # if FLT_RADIX == 2 && DBL_MANT_DIG == 53 && \
4454a238c70SJohn Marino      DBL_MIN_EXP == -1021 && DBL_MAX_EXP == 1024
4464a238c70SJohn Marino #  define MPFR_DOUBLE_SPEC 1
4474a238c70SJohn Marino # else
4484a238c70SJohn Marino #  define MPFR_DOUBLE_SPEC 0
4494a238c70SJohn Marino # endif
4504a238c70SJohn Marino #endif
4514a238c70SJohn Marino 
4524a238c70SJohn Marino /* Debug non IEEE floats */
4534a238c70SJohn Marino #ifdef XDEBUG
4544a238c70SJohn Marino # undef _GMP_IEEE_FLOATS
4554a238c70SJohn Marino #endif
4564a238c70SJohn Marino #ifndef _GMP_IEEE_FLOATS
4574a238c70SJohn Marino # define _GMP_IEEE_FLOATS 0
4584a238c70SJohn Marino #endif
4594a238c70SJohn Marino 
4604a238c70SJohn Marino #ifndef IEEE_DBL_MANT_DIG
4614a238c70SJohn Marino #define IEEE_DBL_MANT_DIG 53
4624a238c70SJohn Marino #endif
4634a238c70SJohn Marino #define MPFR_LIMBS_PER_DOUBLE ((IEEE_DBL_MANT_DIG-1)/GMP_NUMB_BITS+1)
4644a238c70SJohn Marino 
4654a238c70SJohn Marino #ifndef IEEE_FLT_MANT_DIG
4664a238c70SJohn Marino #define IEEE_FLT_MANT_DIG 24
4674a238c70SJohn Marino #endif
4684a238c70SJohn Marino #define MPFR_LIMBS_PER_FLT ((IEEE_FLT_MANT_DIG-1)/GMP_NUMB_BITS+1)
4694a238c70SJohn Marino 
4704a238c70SJohn Marino /* Visual C++ doesn't support +1.0/0.0, -1.0/0.0 and 0.0/0.0
4714a238c70SJohn Marino    at compile time. */
4724a238c70SJohn Marino #if defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)
4734a238c70SJohn Marino static double double_zero = 0.0;
4744a238c70SJohn Marino # define DBL_NAN (double_zero/double_zero)
4754a238c70SJohn Marino # define DBL_POS_INF ((double) 1.0/double_zero)
4764a238c70SJohn Marino # define DBL_NEG_INF ((double)-1.0/double_zero)
4774a238c70SJohn Marino # define DBL_NEG_ZERO (-double_zero)
4784a238c70SJohn Marino #else
4794a238c70SJohn Marino # define DBL_POS_INF ((double) 1.0/0.0)
4804a238c70SJohn Marino # define DBL_NEG_INF ((double)-1.0/0.0)
4814a238c70SJohn Marino # define DBL_NAN     ((double) 0.0/0.0)
4824a238c70SJohn Marino # define DBL_NEG_ZERO (-0.0)
4834a238c70SJohn Marino #endif
4844a238c70SJohn Marino 
4854a238c70SJohn Marino /* Note: In the past, there was specific code for _GMP_IEEE_FLOATS, which
4864a238c70SJohn Marino    was based on NaN and Inf memory representations. This code was breaking
4874a238c70SJohn Marino    the aliasing rules (see ISO C99, 6.5#6 and 6.5#7 on the effective type)
4884a238c70SJohn Marino    and for this reason it did not behave correctly with GCC 4.5.0 20091119.
4894a238c70SJohn Marino    The code needed a memory transfer and was probably not better than the
4904a238c70SJohn Marino    macros below with a good compiler (a fix based on the NaN / Inf memory
4914a238c70SJohn Marino    representation would be even worse due to C limitations), and this code
4924a238c70SJohn Marino    could be selected only when MPFR was built with --with-gmp-build, thus
4934a238c70SJohn Marino    introducing a difference (bad for maintaining/testing MPFR); therefore
4944a238c70SJohn Marino    it has been removed. The old code required that the argument x be an
4954a238c70SJohn Marino    lvalue of type double. We still require that, in case one would need
4964a238c70SJohn Marino    to change the macros below, e.g. for some broken compiler. But the
4974a238c70SJohn Marino    LVALUE(x) condition could be removed if really necessary. */
4984a238c70SJohn Marino /* Below, the &(x) == &(x) || &(x) != &(x) allows to make sure that x
4994a238c70SJohn Marino    is a lvalue without (probably) any warning from the compiler.  The
5004a238c70SJohn Marino    &(x) != &(x) is needed to avoid a failure under Mac OS X 10.4.11
5014a238c70SJohn Marino    (with Xcode 2.4.1, i.e. the latest one). */
5024a238c70SJohn Marino #define LVALUE(x) (&(x) == &(x) || &(x) != &(x))
5034a238c70SJohn Marino #define DOUBLE_ISINF(x) (LVALUE(x) && ((x) > DBL_MAX || (x) < -DBL_MAX))
5044a238c70SJohn Marino #ifdef MPFR_NANISNAN
5054a238c70SJohn Marino /* Avoid MIPSpro / IRIX64 / gcc -ffast-math (incorrect) optimizations.
5064a238c70SJohn Marino    The + must not be replaced by a ||. With gcc -ffast-math, NaN is
5074a238c70SJohn Marino    regarded as a positive number or something like that; the second
5084a238c70SJohn Marino    test catches this case. */
5094a238c70SJohn Marino # define DOUBLE_ISNAN(x) \
5104a238c70SJohn Marino     (LVALUE(x) && !((((x) >= 0.0) + ((x) <= 0.0)) && -(x)*(x) <= 0.0))
5114a238c70SJohn Marino #else
5124a238c70SJohn Marino # define DOUBLE_ISNAN(x) (LVALUE(x) && (x) != (x))
5134a238c70SJohn Marino #endif
5144a238c70SJohn Marino 
5154a238c70SJohn Marino /******************************************************
5164a238c70SJohn Marino  *************** Long double macros *******************
5174a238c70SJohn Marino  ******************************************************/
5184a238c70SJohn Marino 
5194a238c70SJohn Marino /* We try to get the exact value of the precision of long double
5204a238c70SJohn Marino    (provided by the implementation) in order to provide correct
5214a238c70SJohn Marino    rounding in this case (not guaranteed if the C implementation
5224a238c70SJohn Marino    does not have an adequate long double arithmetic). Note that
5234a238c70SJohn Marino    it may be lower than the precision of some numbers that can
5244a238c70SJohn Marino    be represented in a long double; e.g. on FreeBSD/x86, it is
5254a238c70SJohn Marino    53 because the processor is configured to round in double
5264a238c70SJohn Marino    precision (even when using the long double type -- this is a
5274a238c70SJohn Marino    limitation of the x87 arithmetic), and on Mac OS X, it is 106
5284a238c70SJohn Marino    because the implementation is a double-double arithmetic.
5294a238c70SJohn Marino    Otherwise (e.g. in base 10), we get an upper bound of the
5304a238c70SJohn Marino    precision, and correct rounding isn't currently provided.
5314a238c70SJohn Marino */
5324a238c70SJohn Marino #if defined(LDBL_MANT_DIG) && FLT_RADIX == 2
5334a238c70SJohn Marino # define MPFR_LDBL_MANT_DIG LDBL_MANT_DIG
5344a238c70SJohn Marino #else
5354a238c70SJohn Marino # define MPFR_LDBL_MANT_DIG \
5364a238c70SJohn Marino   (sizeof(long double)*GMP_NUMB_BITS/sizeof(mp_limb_t))
5374a238c70SJohn Marino #endif
5384a238c70SJohn Marino #define MPFR_LIMBS_PER_LONG_DOUBLE \
5394a238c70SJohn Marino   ((sizeof(long double)-1)/sizeof(mp_limb_t)+1)
5404a238c70SJohn Marino 
5414a238c70SJohn Marino /* LONGDOUBLE_NAN_ACTION executes the code "action" if x is a NaN. */
5424a238c70SJohn Marino 
5434a238c70SJohn Marino /* On hppa2.0n-hp-hpux10 with the unbundled HP cc, the test x!=x on a NaN
5444a238c70SJohn Marino    has been seen false, meaning NaNs are not detected.  This seemed to
5454a238c70SJohn Marino    happen only after other comparisons, not sure what's really going on.  In
5464a238c70SJohn Marino    any case we can pick apart the bytes to identify a NaN.  */
5474a238c70SJohn Marino #ifdef HAVE_LDOUBLE_IEEE_QUAD_BIG
5484a238c70SJohn Marino # define LONGDOUBLE_NAN_ACTION(x, action)                       \
5494a238c70SJohn Marino   do {                                                          \
5504a238c70SJohn Marino     union {                                                     \
5514a238c70SJohn Marino       long double    ld;                                        \
5524a238c70SJohn Marino       struct {                                                  \
5534a238c70SJohn Marino         unsigned int sign : 1;                                  \
5544a238c70SJohn Marino         unsigned int exp  : 15;                                 \
5554a238c70SJohn Marino         unsigned int man3 : 16;                                 \
5564a238c70SJohn Marino         unsigned int man2 : 32;                                 \
5574a238c70SJohn Marino         unsigned int man1 : 32;                                 \
5584a238c70SJohn Marino         unsigned int man0 : 32;                                 \
5594a238c70SJohn Marino       } s;                                                      \
5604a238c70SJohn Marino     } u;                                                        \
5614a238c70SJohn Marino     u.ld = (x);                                                 \
5624a238c70SJohn Marino     if (u.s.exp == 0x7FFFL                                      \
5634a238c70SJohn Marino         && (u.s.man0 | u.s.man1 | u.s.man2 | u.s.man3) != 0)    \
5644a238c70SJohn Marino       { action; }                                               \
5654a238c70SJohn Marino   } while (0)
5664a238c70SJohn Marino #endif
5674a238c70SJohn Marino 
5684a238c70SJohn Marino #ifdef HAVE_LDOUBLE_IEEE_QUAD_LITTLE
5694a238c70SJohn Marino # define LONGDOUBLE_NAN_ACTION(x, action)                       \
5704a238c70SJohn Marino   do {                                                          \
5714a238c70SJohn Marino     union {                                                     \
5724a238c70SJohn Marino       long double    ld;                                        \
5734a238c70SJohn Marino       struct {                                                  \
5744a238c70SJohn Marino         unsigned int man0 : 32;                                 \
5754a238c70SJohn Marino         unsigned int man1 : 32;                                 \
5764a238c70SJohn Marino         unsigned int man2 : 32;                                 \
5774a238c70SJohn Marino         unsigned int man3 : 16;                                 \
5784a238c70SJohn Marino         unsigned int exp  : 15;                                 \
5794a238c70SJohn Marino         unsigned int sign : 1;                                  \
5804a238c70SJohn Marino       } s;                                                      \
5814a238c70SJohn Marino     } u;                                                        \
5824a238c70SJohn Marino     u.ld = (x);                                                 \
5834a238c70SJohn Marino     if (u.s.exp == 0x7FFFL                                      \
5844a238c70SJohn Marino         && (u.s.man0 | u.s.man1 | u.s.man2 | u.s.man3) != 0)    \
5854a238c70SJohn Marino       { action; }                                               \
5864a238c70SJohn Marino   } while (0)
5874a238c70SJohn Marino #endif
5884a238c70SJohn Marino 
5894a238c70SJohn Marino /* Under IEEE rules, NaN is not equal to anything, including itself.
5904a238c70SJohn Marino    "volatile" here stops "cc" on mips64-sgi-irix6.5 from optimizing away
5914a238c70SJohn Marino    x!=x. */
5924a238c70SJohn Marino #ifndef LONGDOUBLE_NAN_ACTION
5934a238c70SJohn Marino # define LONGDOUBLE_NAN_ACTION(x, action)               \
5944a238c70SJohn Marino   do {                                                  \
5954a238c70SJohn Marino     volatile long double __x = LONGDOUBLE_VOLATILE (x); \
5964a238c70SJohn Marino     if ((x) != __x)                                     \
5974a238c70SJohn Marino       { action; }                                       \
5984a238c70SJohn Marino   } while (0)
5994a238c70SJohn Marino # define WANT_LONGDOUBLE_VOLATILE 1
6004a238c70SJohn Marino #endif
6014a238c70SJohn Marino 
6024a238c70SJohn Marino /* If we don't have a proper "volatile" then volatile is #defined to empty,
6034a238c70SJohn Marino    in this case call through an external function to stop the compiler
6044a238c70SJohn Marino    optimizing anything. */
6054a238c70SJohn Marino #ifdef WANT_LONGDOUBLE_VOLATILE
6064a238c70SJohn Marino # ifdef volatile
6074a238c70SJohn Marino __MPFR_DECLSPEC long double __gmpfr_longdouble_volatile _MPFR_PROTO ((long double)) MPFR_CONST_ATTR;
6084a238c70SJohn Marino #  define LONGDOUBLE_VOLATILE(x)  (__gmpfr_longdouble_volatile (x))
6094a238c70SJohn Marino #  define WANT_GMPFR_LONGDOUBLE_VOLATILE 1
6104a238c70SJohn Marino # else
6114a238c70SJohn Marino #  define LONGDOUBLE_VOLATILE(x)  (x)
6124a238c70SJohn Marino # endif
6134a238c70SJohn Marino #endif
6144a238c70SJohn Marino 
6154a238c70SJohn Marino /* Some special case for IEEE_EXT Litle Endian */
6164a238c70SJohn Marino #if HAVE_LDOUBLE_IEEE_EXT_LITTLE
6174a238c70SJohn Marino 
6184a238c70SJohn Marino typedef union {
6194a238c70SJohn Marino   long double    ld;
6204a238c70SJohn Marino   struct {
6214a238c70SJohn Marino     unsigned int manl : 32;
6224a238c70SJohn Marino     unsigned int manh : 32;
6234a238c70SJohn Marino     unsigned int expl : 8 ;
6244a238c70SJohn Marino     unsigned int exph : 7;
6254a238c70SJohn Marino     unsigned int sign : 1;
6264a238c70SJohn Marino   } s;
6274a238c70SJohn Marino } mpfr_long_double_t;
6284a238c70SJohn Marino 
6294a238c70SJohn Marino /* #undef MPFR_LDBL_MANT_DIG */
6304a238c70SJohn Marino #undef MPFR_LIMBS_PER_LONG_DOUBLE
6314a238c70SJohn Marino /* #define MPFR_LDBL_MANT_DIG   64 */
6324a238c70SJohn Marino #define MPFR_LIMBS_PER_LONG_DOUBLE ((64-1)/GMP_NUMB_BITS+1)
6334a238c70SJohn Marino 
6344a238c70SJohn Marino #endif
6354a238c70SJohn Marino 
6364a238c70SJohn Marino /******************************************************
6374a238c70SJohn Marino  *************** _Decimal64 support *******************
6384a238c70SJohn Marino  ******************************************************/
6394a238c70SJohn Marino 
6404a238c70SJohn Marino #ifdef MPFR_WANT_DECIMAL_FLOATS
6414a238c70SJohn Marino /* to cast between binary64 and decimal64 */
6424a238c70SJohn Marino union ieee_double_decimal64 { double d; _Decimal64 d64; };
6434a238c70SJohn Marino #endif
6444a238c70SJohn Marino 
6454a238c70SJohn Marino /******************************************************
6464a238c70SJohn Marino  **************** mpfr_t properties *******************
6474a238c70SJohn Marino  ******************************************************/
6484a238c70SJohn Marino 
649*ab6d115fSJohn Marino /* In the following macro, p is usually a mpfr_prec_t, but this macro
650*ab6d115fSJohn Marino    works with other integer types (without integer overflow). Checking
651*ab6d115fSJohn Marino    that p >= 1 in debug mode is useful here because this macro can be
652*ab6d115fSJohn Marino    used on a computed precision (in particular, this formula does not
653*ab6d115fSJohn Marino    work for a degenerate case p = 0, and could give different results
654*ab6d115fSJohn Marino    on different platforms). But let us not use an assertion checking
655*ab6d115fSJohn Marino    in the MPFR_LAST_LIMB() and MPFR_LIMB_SIZE() macros below to avoid
656*ab6d115fSJohn Marino    too much expansion for assertions (in practice, this should be a
657*ab6d115fSJohn Marino    problem just when testing MPFR with the --enable-assert configure
658*ab6d115fSJohn Marino    option and the -ansi -pedantic-errors gcc compiler flags). */
659*ab6d115fSJohn Marino #define MPFR_PREC2LIMBS(p) \
660*ab6d115fSJohn Marino   (MPFR_ASSERTD ((p) >= 1), ((p) - 1) / GMP_NUMB_BITS + 1)
661*ab6d115fSJohn Marino 
6624a238c70SJohn Marino #define MPFR_PREC(x)      ((x)->_mpfr_prec)
6634a238c70SJohn Marino #define MPFR_EXP(x)       ((x)->_mpfr_exp)
6644a238c70SJohn Marino #define MPFR_MANT(x)      ((x)->_mpfr_d)
665*ab6d115fSJohn Marino #define MPFR_LAST_LIMB(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS)
666*ab6d115fSJohn Marino #define MPFR_LIMB_SIZE(x) (MPFR_LAST_LIMB (x) + 1)
6674a238c70SJohn Marino 
6684a238c70SJohn Marino 
6694a238c70SJohn Marino /******************************************************
6704a238c70SJohn Marino  **************** exponent properties *****************
6714a238c70SJohn Marino  ******************************************************/
6724a238c70SJohn Marino 
6734a238c70SJohn Marino /* Limits of the mpfr_exp_t type (NOT those of valid exponent values).
6744a238c70SJohn Marino    These macros can be used in preprocessor directives. */
6754a238c70SJohn Marino #if   _MPFR_EXP_FORMAT == 1
6764a238c70SJohn Marino # define MPFR_EXP_MAX (SHRT_MAX)
6774a238c70SJohn Marino # define MPFR_EXP_MIN (SHRT_MIN)
6784a238c70SJohn Marino #elif _MPFR_EXP_FORMAT == 2
6794a238c70SJohn Marino # define MPFR_EXP_MAX (INT_MAX)
6804a238c70SJohn Marino # define MPFR_EXP_MIN (INT_MIN)
6814a238c70SJohn Marino #elif _MPFR_EXP_FORMAT == 3
6824a238c70SJohn Marino # define MPFR_EXP_MAX (LONG_MAX)
6834a238c70SJohn Marino # define MPFR_EXP_MIN (LONG_MIN)
6844a238c70SJohn Marino #elif _MPFR_EXP_FORMAT == 4
6854a238c70SJohn Marino # define MPFR_EXP_MAX (MPFR_INTMAX_MAX)
6864a238c70SJohn Marino # define MPFR_EXP_MIN (MPFR_INTMAX_MIN)
6874a238c70SJohn Marino #else
6884a238c70SJohn Marino # error "Invalid MPFR Exp format"
6894a238c70SJohn Marino #endif
6904a238c70SJohn Marino 
6914a238c70SJohn Marino /* Before doing a cast to mpfr_uexp_t, make sure that the value is
6924a238c70SJohn Marino    nonnegative. */
6934a238c70SJohn Marino #define MPFR_UEXP(X) (MPFR_ASSERTD ((X) >= 0), (mpfr_uexp_t) (X))
6944a238c70SJohn Marino 
6954a238c70SJohn Marino #if MPFR_EXP_MIN >= LONG_MIN && MPFR_EXP_MAX <= LONG_MAX
6964a238c70SJohn Marino typedef long int mpfr_eexp_t;
6974a238c70SJohn Marino # define mpfr_get_exp_t(x,r) mpfr_get_si((x),(r))
6984a238c70SJohn Marino # define mpfr_set_exp_t(x,e,r) mpfr_set_si((x),(e),(r))
6994a238c70SJohn Marino # define MPFR_EXP_FSPEC "l"
7004a238c70SJohn Marino #elif defined (_MPFR_H_HAVE_INTMAX_T)
7014a238c70SJohn Marino typedef intmax_t mpfr_eexp_t;
7024a238c70SJohn Marino # define mpfr_get_exp_t(x,r) mpfr_get_sj((x),(r))
7034a238c70SJohn Marino # define mpfr_set_exp_t(x,e,r) mpfr_set_sj((x),(e),(r))
7044a238c70SJohn Marino # define MPFR_EXP_FSPEC "j"
7054a238c70SJohn Marino #else
7064a238c70SJohn Marino # error "Cannot define mpfr_get_exp_t and mpfr_set_exp_t"
7074a238c70SJohn Marino #endif
7084a238c70SJohn Marino 
7094a238c70SJohn Marino /* Invalid exponent value (to track bugs...) */
7104a238c70SJohn Marino #define MPFR_EXP_INVALID \
7114a238c70SJohn Marino  ((mpfr_exp_t) 1 << (GMP_NUMB_BITS*sizeof(mpfr_exp_t)/sizeof(mp_limb_t)-2))
7124a238c70SJohn Marino 
7134a238c70SJohn Marino /* Definition of the exponent limits for MPFR numbers.
7144a238c70SJohn Marino  * These limits are chosen so that if e is such an exponent, then 2e-1 and
7154a238c70SJohn Marino  * 2e+1 are representable. This is useful for intermediate computations,
7164a238c70SJohn Marino  * in particular the multiplication.
7174a238c70SJohn Marino  */
7184a238c70SJohn Marino #undef MPFR_EMIN_MIN
7194a238c70SJohn Marino #undef MPFR_EMIN_MAX
7204a238c70SJohn Marino #undef MPFR_EMAX_MIN
7214a238c70SJohn Marino #undef MPFR_EMAX_MAX
7224a238c70SJohn Marino #define MPFR_EMIN_MIN (1-MPFR_EXP_INVALID)
7234a238c70SJohn Marino #define MPFR_EMIN_MAX (MPFR_EXP_INVALID-1)
7244a238c70SJohn Marino #define MPFR_EMAX_MIN (1-MPFR_EXP_INVALID)
7254a238c70SJohn Marino #define MPFR_EMAX_MAX (MPFR_EXP_INVALID-1)
7264a238c70SJohn Marino 
7274a238c70SJohn Marino /* Use MPFR_GET_EXP and MPFR_SET_EXP instead of MPFR_EXP directly,
7284a238c70SJohn Marino    unless when the exponent may be out-of-range, for instance when
7294a238c70SJohn Marino    setting the exponent before calling mpfr_check_range.
7304a238c70SJohn Marino    MPFR_EXP_CHECK is defined when WANT_ASSERT is defined, but if you
7314a238c70SJohn Marino    don't use WANT_ASSERT (for speed reasons), you can still define
7324a238c70SJohn Marino    MPFR_EXP_CHECK by setting -DMPFR_EXP_CHECK in $CFLAGS. */
7334a238c70SJohn Marino 
7344a238c70SJohn Marino #ifdef MPFR_EXP_CHECK
7354a238c70SJohn Marino # define MPFR_GET_EXP(x)          (mpfr_get_exp) (x)
7364a238c70SJohn Marino # define MPFR_SET_EXP(x, exp)     MPFR_ASSERTN (!mpfr_set_exp ((x), (exp)))
7374a238c70SJohn Marino # define MPFR_SET_INVALID_EXP(x)  ((void) (MPFR_EXP (x) = MPFR_EXP_INVALID))
7384a238c70SJohn Marino #else
7394a238c70SJohn Marino # define MPFR_GET_EXP(x)          MPFR_EXP (x)
7404a238c70SJohn Marino # define MPFR_SET_EXP(x, exp)     ((void) (MPFR_EXP (x) = (exp)))
7414a238c70SJohn Marino # define MPFR_SET_INVALID_EXP(x)  ((void) 0)
7424a238c70SJohn Marino #endif
7434a238c70SJohn Marino 
7444a238c70SJohn Marino 
7454a238c70SJohn Marino 
7464a238c70SJohn Marino /******************************************************
7474a238c70SJohn Marino  ********** Singular Values (NAN, INF, ZERO) **********
7484a238c70SJohn Marino  ******************************************************/
7494a238c70SJohn Marino 
7504a238c70SJohn Marino /* Enum special value of exponent. */
7514a238c70SJohn Marino # define MPFR_EXP_ZERO (MPFR_EXP_MIN+1)
7524a238c70SJohn Marino # define MPFR_EXP_NAN  (MPFR_EXP_MIN+2)
7534a238c70SJohn Marino # define MPFR_EXP_INF  (MPFR_EXP_MIN+3)
7544a238c70SJohn Marino 
7554a238c70SJohn Marino #define MPFR_IS_NAN(x)   (MPFR_EXP(x) == MPFR_EXP_NAN)
7564a238c70SJohn Marino #define MPFR_SET_NAN(x)  (MPFR_EXP(x) =  MPFR_EXP_NAN)
7574a238c70SJohn Marino #define MPFR_IS_INF(x)   (MPFR_EXP(x) == MPFR_EXP_INF)
7584a238c70SJohn Marino #define MPFR_SET_INF(x)  (MPFR_EXP(x) =  MPFR_EXP_INF)
7594a238c70SJohn Marino #define MPFR_IS_ZERO(x)  (MPFR_EXP(x) == MPFR_EXP_ZERO)
7604a238c70SJohn Marino #define MPFR_SET_ZERO(x) (MPFR_EXP(x) =  MPFR_EXP_ZERO)
7614a238c70SJohn Marino #define MPFR_NOTZERO(x)  (MPFR_EXP(x) != MPFR_EXP_ZERO)
7624a238c70SJohn Marino 
7634a238c70SJohn Marino #define MPFR_IS_FP(x)       (!MPFR_IS_NAN(x) && !MPFR_IS_INF(x))
7644a238c70SJohn Marino #define MPFR_IS_SINGULAR(x) (MPFR_EXP(x) <= MPFR_EXP_INF)
7654a238c70SJohn Marino #define MPFR_IS_PURE_FP(x)  (!MPFR_IS_SINGULAR(x) && \
766*ab6d115fSJohn Marino   (MPFR_ASSERTD ((MPFR_MANT(x)[MPFR_LAST_LIMB(x)]  \
767*ab6d115fSJohn Marino                   & MPFR_LIMB_HIGHBIT) != 0), 1))
7684a238c70SJohn Marino 
7694a238c70SJohn Marino #define MPFR_ARE_SINGULAR(x,y) \
7704a238c70SJohn Marino   (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)) || MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
7714a238c70SJohn Marino 
7724a238c70SJohn Marino #define MPFR_IS_POWER_OF_2(x) \
7734a238c70SJohn Marino   (mpfr_cmp_ui_2exp ((x), 1, MPFR_GET_EXP (x) - 1) == 0)
7744a238c70SJohn Marino 
7754a238c70SJohn Marino 
7764a238c70SJohn Marino /******************************************************
7774a238c70SJohn Marino  ********************* Sign Macros ********************
7784a238c70SJohn Marino  ******************************************************/
7794a238c70SJohn Marino 
7804a238c70SJohn Marino #define MPFR_SIGN_POS (1)
7814a238c70SJohn Marino #define MPFR_SIGN_NEG (-1)
7824a238c70SJohn Marino 
7834a238c70SJohn Marino #define MPFR_IS_STRICTPOS(x)  (MPFR_NOTZERO((x)) && MPFR_SIGN(x) > 0)
7844a238c70SJohn Marino #define MPFR_IS_STRICTNEG(x)  (MPFR_NOTZERO((x)) && MPFR_SIGN(x) < 0)
7854a238c70SJohn Marino 
7864a238c70SJohn Marino #define MPFR_IS_NEG(x) (MPFR_SIGN(x) < 0)
7874a238c70SJohn Marino #define MPFR_IS_POS(x) (MPFR_SIGN(x) > 0)
7884a238c70SJohn Marino 
7894a238c70SJohn Marino #define MPFR_SET_POS(x) (MPFR_SIGN(x) = MPFR_SIGN_POS)
7904a238c70SJohn Marino #define MPFR_SET_NEG(x) (MPFR_SIGN(x) = MPFR_SIGN_NEG)
7914a238c70SJohn Marino 
7924a238c70SJohn Marino #define MPFR_CHANGE_SIGN(x) (MPFR_SIGN(x) = -MPFR_SIGN(x))
7934a238c70SJohn Marino #define MPFR_SET_SAME_SIGN(x, y) (MPFR_SIGN(x) = MPFR_SIGN(y))
7944a238c70SJohn Marino #define MPFR_SET_OPPOSITE_SIGN(x, y) (MPFR_SIGN(x) = -MPFR_SIGN(y))
7954a238c70SJohn Marino #define MPFR_ASSERT_SIGN(s) \
7964a238c70SJohn Marino  (MPFR_ASSERTD((s) == MPFR_SIGN_POS || (s) == MPFR_SIGN_NEG))
7974a238c70SJohn Marino #define MPFR_SET_SIGN(x, s) \
7984a238c70SJohn Marino   (MPFR_ASSERT_SIGN(s), MPFR_SIGN(x) = s)
7994a238c70SJohn Marino #define MPFR_IS_POS_SIGN(s1) (s1 > 0)
8004a238c70SJohn Marino #define MPFR_IS_NEG_SIGN(s1) (s1 < 0)
8014a238c70SJohn Marino #define MPFR_MULT_SIGN(s1, s2) ((s1) * (s2))
8024a238c70SJohn Marino /* Transform a sign to 1 or -1 */
8034a238c70SJohn Marino #define MPFR_FROM_SIGN_TO_INT(s) (s)
8044a238c70SJohn Marino #define MPFR_INT_SIGN(x) MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(x))
8054a238c70SJohn Marino 
8064a238c70SJohn Marino 
8074a238c70SJohn Marino 
8084a238c70SJohn Marino /******************************************************
8094a238c70SJohn Marino  ***************** Ternary Value Macros ***************
8104a238c70SJohn Marino  ******************************************************/
8114a238c70SJohn Marino 
8124a238c70SJohn Marino /* Special inexact value */
8134a238c70SJohn Marino #define MPFR_EVEN_INEX 2
8144a238c70SJohn Marino 
8154a238c70SJohn Marino /* Macros for functions returning two inexact values in an 'int' */
8164a238c70SJohn Marino #define INEXPOS(y) ((y) == 0 ? 0 : (((y) > 0) ? 1 : 2))
8174a238c70SJohn Marino #define INEX(y,z) (INEXPOS(y) | (INEXPOS(z) << 2))
8184a238c70SJohn Marino 
8194a238c70SJohn Marino /* When returning the ternary inexact value, ALWAYS use one of the
8204a238c70SJohn Marino    following two macros, unless the flag comes from another function
8214a238c70SJohn Marino    returning the ternary inexact value */
8224a238c70SJohn Marino #define MPFR_RET(I) return \
8234a238c70SJohn Marino   (I) ? ((__gmpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0
8244a238c70SJohn Marino #define MPFR_RET_NAN return (__gmpfr_flags |= MPFR_FLAGS_NAN), 0
8254a238c70SJohn Marino 
8264a238c70SJohn Marino #define MPFR_SET_ERANGE() (__gmpfr_flags |= MPFR_FLAGS_ERANGE)
8274a238c70SJohn Marino 
8284a238c70SJohn Marino #define SIGN(I) ((I) < 0 ? -1 : (I) > 0)
8294a238c70SJohn Marino #define SAME_SIGN(I1,I2) (SIGN (I1) == SIGN (I2))
8304a238c70SJohn Marino 
8314a238c70SJohn Marino 
8324a238c70SJohn Marino 
8334a238c70SJohn Marino /******************************************************
8344a238c70SJohn Marino  ************** Rounding mode macros  *****************
8354a238c70SJohn Marino  ******************************************************/
8364a238c70SJohn Marino 
8374a238c70SJohn Marino /* MPFR_RND_MAX gives the number of supported rounding modes by all functions.
8384a238c70SJohn Marino  * Once faithful rounding is implemented, MPFR_RNDA should be changed
8394a238c70SJohn Marino  * to MPFR_RNDF. But this will also require more changes in the tests.
8404a238c70SJohn Marino  */
8414a238c70SJohn Marino #define MPFR_RND_MAX ((mpfr_rnd_t)((MPFR_RNDA)+1))
8424a238c70SJohn Marino 
8434a238c70SJohn Marino /* We want to test this :
8444a238c70SJohn Marino  *  (rnd == MPFR_RNDU && test) || (rnd == RNDD && !test)
8454a238c70SJohn Marino  * ie it transforms RNDU or RNDD to Away or Zero according to the sign */
8464a238c70SJohn Marino #define MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test) \
8474a238c70SJohn Marino   (((rnd) + (test)) == MPFR_RNDD)
8484a238c70SJohn Marino 
8494a238c70SJohn Marino /* We want to test if rnd = Zero, or Away.
8504a238c70SJohn Marino    'test' is 1 if negative, and 0 if positive. */
8514a238c70SJohn Marino #define MPFR_IS_LIKE_RNDZ(rnd, test) \
8524a238c70SJohn Marino   ((rnd==MPFR_RNDZ) || MPFR_IS_RNDUTEST_OR_RNDDNOTTEST (rnd, test))
8534a238c70SJohn Marino 
8544a238c70SJohn Marino #define MPFR_IS_LIKE_RNDU(rnd, sign) \
8554a238c70SJohn Marino   ((rnd==MPFR_RNDU) || (rnd==MPFR_RNDZ && sign<0) || (rnd==MPFR_RNDA && sign>0))
8564a238c70SJohn Marino 
8574a238c70SJohn Marino #define MPFR_IS_LIKE_RNDD(rnd, sign) \
8584a238c70SJohn Marino   ((rnd==MPFR_RNDD) || (rnd==MPFR_RNDZ && sign>0) || (rnd==MPFR_RNDA && sign<0))
8594a238c70SJohn Marino 
8604a238c70SJohn Marino /* Invert a rounding mode, RNDZ and RNDA are unchanged */
8614a238c70SJohn Marino #define MPFR_INVERT_RND(rnd) ((rnd == MPFR_RNDU) ? MPFR_RNDD : \
8624a238c70SJohn Marino                              ((rnd == MPFR_RNDD) ? MPFR_RNDU : rnd))
8634a238c70SJohn Marino 
8644a238c70SJohn Marino /* Transform RNDU and RNDD to RNDZ according to test */
8654a238c70SJohn Marino #define MPFR_UPDATE_RND_MODE(rnd, test)                            \
8664a238c70SJohn Marino   do {                                                             \
8674a238c70SJohn Marino     if (MPFR_UNLIKELY(MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test))) \
8684a238c70SJohn Marino       rnd = MPFR_RNDZ;                                              \
8694a238c70SJohn Marino   } while (0)
8704a238c70SJohn Marino 
8714a238c70SJohn Marino /* Transform RNDU and RNDD to RNDZ or RNDA according to sign,
8724a238c70SJohn Marino    leave the other modes unchanged */
8734a238c70SJohn Marino #define MPFR_UPDATE2_RND_MODE(rnd, sign)        \
8744a238c70SJohn Marino   do {                                          \
8754a238c70SJohn Marino   if (rnd == MPFR_RNDU)                          \
8764a238c70SJohn Marino     rnd = (sign > 0) ? MPFR_RNDA : MPFR_RNDZ;     \
8774a238c70SJohn Marino   else if (rnd == MPFR_RNDD)                     \
8784a238c70SJohn Marino     rnd = (sign < 0) ? MPFR_RNDA : MPFR_RNDZ;     \
8794a238c70SJohn Marino   } while (0)
8804a238c70SJohn Marino 
8814a238c70SJohn Marino 
8824a238c70SJohn Marino /******************************************************
8834a238c70SJohn Marino  ******************* Limb Macros **********************
8844a238c70SJohn Marino  ******************************************************/
8854a238c70SJohn Marino 
8864a238c70SJohn Marino  /* Definition of MPFR_LIMB_HIGHBIT */
8874a238c70SJohn Marino #if defined(GMP_LIMB_HIGHBIT)
8884a238c70SJohn Marino # define MPFR_LIMB_HIGHBIT GMP_LIMB_HIGHBIT
8894a238c70SJohn Marino #elif defined(MP_LIMB_T_HIGHBIT)
8904a238c70SJohn Marino # define MPFR_LIMB_HIGHBIT MP_LIMB_T_HIGHBIT
8914a238c70SJohn Marino #else
8924a238c70SJohn Marino # error "Neither GMP_LIMB_HIGHBIT nor MP_LIMB_T_HIGHBIT defined in GMP"
8934a238c70SJohn Marino #endif
8944a238c70SJohn Marino 
8954a238c70SJohn Marino /* Mask to get the Most Significant Bit of a limb */
8964a238c70SJohn Marino #define MPFR_LIMB_MSB(l) ((l)&MPFR_LIMB_HIGHBIT)
8974a238c70SJohn Marino 
8984a238c70SJohn Marino /* Definition of MPFR_LIMB_ONE & MPFR_LIMB_ZERO */
8994a238c70SJohn Marino #ifdef CNST_LIMB
9004a238c70SJohn Marino # define MPFR_LIMB_ONE  CNST_LIMB(1)
9014a238c70SJohn Marino # define MPFR_LIMB_ZERO CNST_LIMB(0)
9024a238c70SJohn Marino #else
9034a238c70SJohn Marino # define MPFR_LIMB_ONE  ((mp_limb_t) 1L)
9044a238c70SJohn Marino # define MPFR_LIMB_ZERO ((mp_limb_t) 0L)
9054a238c70SJohn Marino #endif
9064a238c70SJohn Marino 
9074a238c70SJohn Marino /* Mask for the low 's' bits of a limb */
9084a238c70SJohn Marino #define MPFR_LIMB_MASK(s) ((MPFR_LIMB_ONE<<(s))-MPFR_LIMB_ONE)
9094a238c70SJohn Marino 
9104a238c70SJohn Marino 
9114a238c70SJohn Marino 
9124a238c70SJohn Marino /******************************************************
9134a238c70SJohn Marino  ********************** Memory ************************
9144a238c70SJohn Marino  ******************************************************/
9154a238c70SJohn Marino 
9164a238c70SJohn Marino /* Heap Memory gestion */
9174a238c70SJohn Marino typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t;
9184a238c70SJohn Marino #define MPFR_GET_ALLOC_SIZE(x) \
9194a238c70SJohn Marino  ( ((mp_size_t*) MPFR_MANT(x))[-1] + 0)
9204a238c70SJohn Marino #define MPFR_SET_ALLOC_SIZE(x, n) \
9214a238c70SJohn Marino  ( ((mp_size_t*) MPFR_MANT(x))[-1] = n)
9224a238c70SJohn Marino #define MPFR_MALLOC_SIZE(s) \
9234a238c70SJohn Marino   ( sizeof(mpfr_size_limb_t) + BYTES_PER_MP_LIMB * ((size_t) s) )
9244a238c70SJohn Marino #define MPFR_SET_MANT_PTR(x,p) \
9254a238c70SJohn Marino    (MPFR_MANT(x) = (mp_limb_t*) ((mpfr_size_limb_t*) p + 1))
9264a238c70SJohn Marino #define MPFR_GET_REAL_PTR(x) \
9274a238c70SJohn Marino    ((mp_limb_t*) ((mpfr_size_limb_t*) MPFR_MANT(x) - 1))
9284a238c70SJohn Marino 
9294a238c70SJohn Marino /* Temporary memory gestion */
9304a238c70SJohn Marino #ifndef TMP_SALLOC
9314a238c70SJohn Marino /* GMP 4.1.x or below or internals */
9324a238c70SJohn Marino #define MPFR_TMP_DECL TMP_DECL
9334a238c70SJohn Marino #define MPFR_TMP_MARK TMP_MARK
9344a238c70SJohn Marino #define MPFR_TMP_ALLOC TMP_ALLOC
9354a238c70SJohn Marino #define MPFR_TMP_FREE TMP_FREE
9364a238c70SJohn Marino #else
9374a238c70SJohn Marino #define MPFR_TMP_DECL(x) TMP_DECL
9384a238c70SJohn Marino #define MPFR_TMP_MARK(x) TMP_MARK
9394a238c70SJohn Marino #define MPFR_TMP_ALLOC(s) TMP_ALLOC(s)
9404a238c70SJohn Marino #define MPFR_TMP_FREE(x) TMP_FREE
9414a238c70SJohn Marino #endif
9424a238c70SJohn Marino 
9434a238c70SJohn Marino /* This code is experimental: don't use it */
9444a238c70SJohn Marino #ifdef MPFR_USE_OWN_MPFR_TMP_ALLOC
9454a238c70SJohn Marino extern unsigned char *mpfr_stack;
9464a238c70SJohn Marino #undef MPFR_TMP_DECL
9474a238c70SJohn Marino #undef MPFR_TMP_MARK
9484a238c70SJohn Marino #undef MPFR_TMP_ALLOC
9494a238c70SJohn Marino #undef MPFR_TMP_FREE
9504a238c70SJohn Marino #define MPFR_TMP_DECL(_x) unsigned char *(_x)
9514a238c70SJohn Marino #define MPFR_TMP_MARK(_x) ((_x) = mpfr_stack)
9524a238c70SJohn Marino #define MPFR_TMP_ALLOC(_s) (mpfr_stack += (_s), mpfr_stack - (_s))
9534a238c70SJohn Marino #define MPFR_TMP_FREE(_x) (mpfr_stack = (_x))
9544a238c70SJohn Marino #endif
9554a238c70SJohn Marino 
9564a238c70SJohn Marino #define MPFR_TMP_LIMBS_ALLOC(N) \
9574a238c70SJohn Marino   ((mp_limb_t *) MPFR_TMP_ALLOC ((size_t) (N) * BYTES_PER_MP_LIMB))
9584a238c70SJohn Marino 
9594a238c70SJohn Marino /* temporary allocate 1 limb at xp, and initialize mpfr variable x */
9604a238c70SJohn Marino /* The temporary var doesn't have any size field, but it doesn't matter
9614a238c70SJohn Marino  * since only functions dealing with the Heap care about it */
9624a238c70SJohn Marino #define MPFR_TMP_INIT1(xp, x, p)                                     \
9634a238c70SJohn Marino  ( MPFR_PREC(x) = (p),                                               \
9644a238c70SJohn Marino    MPFR_MANT(x) = (xp),                                              \
9654a238c70SJohn Marino    MPFR_SET_POS(x),                                                  \
9664a238c70SJohn Marino    MPFR_SET_INVALID_EXP(x))
9674a238c70SJohn Marino 
9684a238c70SJohn Marino #define MPFR_TMP_INIT(xp, x, p, s)                                   \
9694a238c70SJohn Marino   (xp = MPFR_TMP_LIMBS_ALLOC(s),                                     \
9704a238c70SJohn Marino    MPFR_TMP_INIT1(xp, x, p))
9714a238c70SJohn Marino 
9724a238c70SJohn Marino #define MPFR_TMP_INIT_ABS(d, s)                                      \
9734a238c70SJohn Marino  ( MPFR_PREC(d) = MPFR_PREC(s),                                      \
9744a238c70SJohn Marino    MPFR_MANT(d) = MPFR_MANT(s),                                      \
9754a238c70SJohn Marino    MPFR_SET_POS(d),                                                  \
9764a238c70SJohn Marino    MPFR_EXP(d)  = MPFR_EXP(s))
9774a238c70SJohn Marino 
9784a238c70SJohn Marino 
9794a238c70SJohn Marino 
9804a238c70SJohn Marino /******************************************************
9814a238c70SJohn Marino  *****************  Cache macros **********************
9824a238c70SJohn Marino  ******************************************************/
9834a238c70SJohn Marino 
9844a238c70SJohn Marino #define mpfr_const_pi(_d,_r)    mpfr_cache(_d, __gmpfr_cache_const_pi,_r)
9854a238c70SJohn Marino #define mpfr_const_log2(_d,_r)  mpfr_cache(_d, __gmpfr_cache_const_log2, _r)
9864a238c70SJohn Marino #define mpfr_const_euler(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_euler, _r)
9874a238c70SJohn Marino #define mpfr_const_catalan(_d,_r) mpfr_cache(_d,__gmpfr_cache_const_catalan,_r)
9884a238c70SJohn Marino 
9894a238c70SJohn Marino #define MPFR_DECL_INIT_CACHE(_cache,_func)                           \
9904a238c70SJohn Marino  mpfr_cache_t MPFR_THREAD_ATTR _cache =                              \
9914a238c70SJohn Marino     {{{{0,MPFR_SIGN_POS,0,(mp_limb_t*)0}},0,_func}}
9924a238c70SJohn Marino 
9934a238c70SJohn Marino 
9944a238c70SJohn Marino 
9954a238c70SJohn Marino /******************************************************
9964a238c70SJohn Marino  *******************  Threshold ***********************
9974a238c70SJohn Marino  ******************************************************/
9984a238c70SJohn Marino 
9994a238c70SJohn Marino #include "mparam.h"
10004a238c70SJohn Marino 
10014a238c70SJohn Marino /******************************************************
10024a238c70SJohn Marino  *****************  Useful macros *********************
10034a238c70SJohn Marino  ******************************************************/
10044a238c70SJohn Marino 
10054a238c70SJohn Marino /* Theses macros help the compiler to determine if a test is
1006*ab6d115fSJohn Marino    likely or unlikely. The !! is necessary in case x is larger
1007*ab6d115fSJohn Marino    than a long. */
10084a238c70SJohn Marino #if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
10094a238c70SJohn Marino # define MPFR_LIKELY(x) (__builtin_expect(!!(x),1))
1010*ab6d115fSJohn Marino # define MPFR_UNLIKELY(x) (__builtin_expect(!!(x),0))
10114a238c70SJohn Marino #else
10124a238c70SJohn Marino # define MPFR_LIKELY(x) (x)
10134a238c70SJohn Marino # define MPFR_UNLIKELY(x) (x)
10144a238c70SJohn Marino #endif
10154a238c70SJohn Marino 
10164a238c70SJohn Marino /* Declare that some variable is initialized before being used (without a
10174a238c70SJohn Marino    dummy initialization) in order to avoid some compiler warnings. Use the
10184a238c70SJohn Marino    VAR = VAR trick (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36296)
10194a238c70SJohn Marino    only with gcc as this is undefined behavior, and we don't know what
10204a238c70SJohn Marino    other compilers do (they may also be smarter). This trick could be
10214a238c70SJohn Marino    disabled with future gcc versions. */
10224a238c70SJohn Marino #if defined(__GNUC__)
10234a238c70SJohn Marino # define INITIALIZED(VAR) VAR = VAR
10244a238c70SJohn Marino #else
10254a238c70SJohn Marino # define INITIALIZED(VAR) VAR
10264a238c70SJohn Marino #endif
10274a238c70SJohn Marino 
10284a238c70SJohn Marino /* Ceil log 2: If GCC, uses a GCC extension, otherwise calls a function */
10294a238c70SJohn Marino /* Warning:
10304a238c70SJohn Marino  *   Needs to define MPFR_NEED_LONGLONG.
10314a238c70SJohn Marino  *   Computes ceil(log2(x)) only for x integer (unsigned long)
10324a238c70SJohn Marino  *   Undefined if x is 0 */
10334a238c70SJohn Marino #if __MPFR_GNUC(2,95) || __MPFR_ICC(8,1,0)
10344a238c70SJohn Marino # define MPFR_INT_CEIL_LOG2(x)                            \
10354a238c70SJohn Marino     (MPFR_UNLIKELY ((x) == 1) ? 0 :                       \
10364a238c70SJohn Marino      __extension__ ({ int _b; mp_limb_t _limb;            \
10374a238c70SJohn Marino       MPFR_ASSERTN ((x) > 1);                             \
10384a238c70SJohn Marino       _limb = (x) - 1;                                    \
10394a238c70SJohn Marino       MPFR_ASSERTN (_limb == (x) - 1);                    \
10404a238c70SJohn Marino       count_leading_zeros (_b, _limb);                    \
10414a238c70SJohn Marino       (GMP_NUMB_BITS - _b); }))
10424a238c70SJohn Marino #else
10434a238c70SJohn Marino # define MPFR_INT_CEIL_LOG2(x) (__gmpfr_int_ceil_log2(x))
10444a238c70SJohn Marino #endif
10454a238c70SJohn Marino 
10464a238c70SJohn Marino /* Add two integers with overflow handling */
10474a238c70SJohn Marino /* Example: MPFR_SADD_OVERFLOW (c, a, b, long, unsigned long,
10484a238c70SJohn Marino  *                              LONG_MIN, LONG_MAX,
10494a238c70SJohn Marino  *                              goto overflow, goto underflow); */
10504a238c70SJohn Marino #define MPFR_UADD_OVERFLOW(c,a,b,ACTION_IF_OVERFLOW)                  \
10514a238c70SJohn Marino  do {                                                                 \
10524a238c70SJohn Marino   (c) = (a) + (b);                                                    \
10534a238c70SJohn Marino   if ((c) < (a)) ACTION_IF_OVERFLOW;                                  \
10544a238c70SJohn Marino  } while (0)
10554a238c70SJohn Marino 
10564a238c70SJohn Marino #define MPFR_SADD_OVERFLOW(c,a,b,STYPE,UTYPE,MIN,MAX,ACTION_IF_POS_OVERFLOW,ACTION_IF_NEG_OVERFLOW) \
10574a238c70SJohn Marino   do {                                                                \
10584a238c70SJohn Marino   if ((a) >= 0 && (b) >= 0) {                                         \
10594a238c70SJohn Marino          UTYPE uc,ua,ub;                                              \
10604a238c70SJohn Marino          ua = (UTYPE) (a); ub = (UTYPE) (b);                          \
10614a238c70SJohn Marino          MPFR_UADD_OVERFLOW (uc, ua, ub, ACTION_IF_POS_OVERFLOW);     \
10624a238c70SJohn Marino          if (uc > (UTYPE)(MAX)) ACTION_IF_POS_OVERFLOW;               \
10634a238c70SJohn Marino          else (c) = (STYPE) uc;                                       \
10644a238c70SJohn Marino   } else if ((a) < 0 && (b) < 0) {                                    \
10654a238c70SJohn Marino          UTYPE uc,ua,ub;                                              \
10664a238c70SJohn Marino          ua = -(UTYPE) (a); ub = -(UTYPE) (b);                        \
10674a238c70SJohn Marino          MPFR_UADD_OVERFLOW (uc, ua, ub, ACTION_IF_NEG_OVERFLOW);     \
10684a238c70SJohn Marino          if (uc >= -(UTYPE)(MIN) || uc > (UTYPE)(MAX)) {              \
10694a238c70SJohn Marino            if (uc ==  -(UTYPE)(MIN)) (c) = (MIN);                     \
10704a238c70SJohn Marino            else  ACTION_IF_NEG_OVERFLOW; }                            \
10714a238c70SJohn Marino          else (c) = -(STYPE) uc;                                      \
10724a238c70SJohn Marino   } else (c) = (a) + (b);                                             \
10734a238c70SJohn Marino  } while (0)
10744a238c70SJohn Marino 
10754a238c70SJohn Marino 
10764a238c70SJohn Marino /* Set a number to 1 (Fast) - It doesn't check if 1 is in the exponent range */
10774a238c70SJohn Marino #define MPFR_SET_ONE(x)                                               \
10784a238c70SJohn Marino do {                                                                  \
1079*ab6d115fSJohn Marino   mp_size_t _size = MPFR_LAST_LIMB(x);                                \
10804a238c70SJohn Marino   MPFR_SET_POS(x);                                                    \
10814a238c70SJohn Marino   MPFR_EXP(x) = 1;                                                    \
10824a238c70SJohn Marino   MPN_ZERO ( MPFR_MANT(x), _size);                                    \
10834a238c70SJohn Marino   MPFR_MANT(x)[_size] = MPFR_LIMB_HIGHBIT;                            \
10844a238c70SJohn Marino } while (0)
10854a238c70SJohn Marino 
10864a238c70SJohn Marino /* Compute s = (-a) % GMP_NUMB_BITS as unsigned */
10874a238c70SJohn Marino #define MPFR_UNSIGNED_MINUS_MODULO(s, a)                              \
10884a238c70SJohn Marino   do                                                                  \
10894a238c70SJohn Marino     {                                                                 \
10904a238c70SJohn Marino       if (IS_POW2 (GMP_NUMB_BITS))                                    \
10914a238c70SJohn Marino         (s) = (- (unsigned int) (a)) % GMP_NUMB_BITS;                 \
10924a238c70SJohn Marino       else                                                            \
10934a238c70SJohn Marino         {                                                             \
10944a238c70SJohn Marino           (s) = (a) % GMP_NUMB_BITS;                                  \
10954a238c70SJohn Marino           if ((s) != 0)                                               \
10964a238c70SJohn Marino             (s) = GMP_NUMB_BITS - (s);                                \
10974a238c70SJohn Marino         }                                                             \
10984a238c70SJohn Marino       MPFR_ASSERTD ((s) >= 0 && (s) < GMP_NUMB_BITS);                 \
10994a238c70SJohn Marino     }                                                                 \
11004a238c70SJohn Marino   while (0)
11014a238c70SJohn Marino 
11024a238c70SJohn Marino /* Use it only for debug reasons */
11034a238c70SJohn Marino /*   MPFR_TRACE (operation) : execute operation iff DEBUG flag is set */
11044a238c70SJohn Marino /*   MPFR_DUMP (x) : print x (a mpfr_t) on stdout */
11054a238c70SJohn Marino #ifdef DEBUG
11064a238c70SJohn Marino # define MPFR_TRACE(x) x
11074a238c70SJohn Marino #else
11084a238c70SJohn Marino # define MPFR_TRACE(x) (void) 0
11094a238c70SJohn Marino #endif
11104a238c70SJohn Marino #define MPFR_DUMP(x) ( printf(#x"="), mpfr_dump(x) )
11114a238c70SJohn Marino 
11124a238c70SJohn Marino /* Test if X (positive) is a power of 2 */
11134a238c70SJohn Marino #define IS_POW2(X) (((X) & ((X) - 1)) == 0)
11144a238c70SJohn Marino #define NOT_POW2(X) (((X) & ((X) - 1)) != 0)
11154a238c70SJohn Marino 
11164a238c70SJohn Marino /* Safe absolute value (to avoid possible integer overflow) */
11174a238c70SJohn Marino /* type is the target (unsigned) type */
11184a238c70SJohn Marino #define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
11194a238c70SJohn Marino 
11204a238c70SJohn Marino #define mpfr_get_d1(x) mpfr_get_d(x,__gmpfr_default_rounding_mode)
11214a238c70SJohn Marino 
11224a238c70SJohn Marino /* Store in r the size in bits of the mpz_t z */
11234a238c70SJohn Marino #define MPFR_MPZ_SIZEINBASE2(r, z)              \
11244a238c70SJohn Marino   do {                                          \
11254a238c70SJohn Marino    int _cnt;                                    \
11264a238c70SJohn Marino    mp_size_t _size;                             \
11274a238c70SJohn Marino    MPFR_ASSERTD (mpz_sgn (z) != 0);             \
11284a238c70SJohn Marino    _size = ABSIZ(z);                            \
11294a238c70SJohn Marino    count_leading_zeros (_cnt, PTR(z)[_size-1]); \
11304a238c70SJohn Marino    (r) = _size * GMP_NUMB_BITS - _cnt;       \
11314a238c70SJohn Marino   } while (0)
11324a238c70SJohn Marino 
11334a238c70SJohn Marino /* Needs <locale.h> */
11344a238c70SJohn Marino #ifdef HAVE_LOCALE_H
11354a238c70SJohn Marino #include <locale.h>
11364a238c70SJohn Marino /* Warning! In case of signed char, the value of MPFR_DECIMAL_POINT may
11374a238c70SJohn Marino    be negative (the ISO C99 does not seem to forbid negative values). */
11384a238c70SJohn Marino #define MPFR_DECIMAL_POINT (localeconv()->decimal_point[0])
11394a238c70SJohn Marino #define MPFR_THOUSANDS_SEPARATOR (localeconv()->thousands_sep[0])
11404a238c70SJohn Marino #else
11414a238c70SJohn Marino #define MPFR_DECIMAL_POINT ((char) '.')
11424a238c70SJohn Marino #define MPFR_THOUSANDS_SEPARATOR ('\0')
11434a238c70SJohn Marino #endif
11444a238c70SJohn Marino 
11454a238c70SJohn Marino 
11464a238c70SJohn Marino /* Set y to s*significand(x)*2^e, for example MPFR_ALIAS(y,x,1,MPFR_EXP(x))
11474a238c70SJohn Marino    sets y to |x|, and MPFR_ALIAS(y,x,MPFR_SIGN(x),0) sets y to x*2^f such
11484a238c70SJohn Marino    that 1/2 <= |y| < 1. Does not check y is in the valid exponent range.
11494a238c70SJohn Marino    WARNING! x and y share the same mantissa. So, some operations are
11504a238c70SJohn Marino    not valid if x has been provided via an argument, e.g., trying to
11514a238c70SJohn Marino    modify the mantissa of y, even temporarily, or calling mpfr_clear on y.
11524a238c70SJohn Marino */
11534a238c70SJohn Marino #define MPFR_ALIAS(y,x,s,e)                     \
11544a238c70SJohn Marino   do                                            \
11554a238c70SJohn Marino     {                                           \
11564a238c70SJohn Marino       MPFR_PREC(y) = MPFR_PREC(x);              \
11574a238c70SJohn Marino       MPFR_SIGN(y) = (s);                       \
11584a238c70SJohn Marino       MPFR_EXP(y) = (e);                        \
11594a238c70SJohn Marino       MPFR_MANT(y) = MPFR_MANT(x);              \
11604a238c70SJohn Marino     } while (0)
11614a238c70SJohn Marino 
11624a238c70SJohn Marino 
11634a238c70SJohn Marino /******************************************************
11644a238c70SJohn Marino  **************  Save exponent macros  ****************
11654a238c70SJohn Marino  ******************************************************/
11664a238c70SJohn Marino 
11674a238c70SJohn Marino /* See README.dev for details on how to use the macros.
11684a238c70SJohn Marino    They are used to set the exponent range to the maximum
11694a238c70SJohn Marino    temporarily */
11704a238c70SJohn Marino 
11714a238c70SJohn Marino typedef struct {
11724a238c70SJohn Marino   unsigned int saved_flags;
11734a238c70SJohn Marino   mpfr_exp_t saved_emin;
11744a238c70SJohn Marino   mpfr_exp_t saved_emax;
11754a238c70SJohn Marino } mpfr_save_expo_t;
11764a238c70SJohn Marino 
11774a238c70SJohn Marino /* Minimum and maximum exponents of the extended exponent range. */
11784a238c70SJohn Marino #define MPFR_EXT_EMIN MPFR_EMIN_MIN
11794a238c70SJohn Marino #define MPFR_EXT_EMAX MPFR_EMAX_MAX
11804a238c70SJohn Marino 
11814a238c70SJohn Marino #define MPFR_SAVE_EXPO_DECL(x) mpfr_save_expo_t x
11824a238c70SJohn Marino #define MPFR_SAVE_EXPO_MARK(x)     \
11834a238c70SJohn Marino  ((x).saved_flags = __gmpfr_flags, \
11844a238c70SJohn Marino   (x).saved_emin = __gmpfr_emin,   \
11854a238c70SJohn Marino   (x).saved_emax = __gmpfr_emax,   \
11864a238c70SJohn Marino   __gmpfr_emin = MPFR_EXT_EMIN,    \
11874a238c70SJohn Marino   __gmpfr_emax = MPFR_EXT_EMAX)
11884a238c70SJohn Marino #define MPFR_SAVE_EXPO_FREE(x)     \
11894a238c70SJohn Marino  (__gmpfr_flags = (x).saved_flags, \
11904a238c70SJohn Marino   __gmpfr_emin = (x).saved_emin,   \
11914a238c70SJohn Marino   __gmpfr_emax = (x).saved_emax)
11924a238c70SJohn Marino #define MPFR_SAVE_EXPO_UPDATE_FLAGS(x, flags)  \
11934a238c70SJohn Marino   (x).saved_flags |= (flags)
11944a238c70SJohn Marino 
11954a238c70SJohn Marino /* Speed up final checking */
11964a238c70SJohn Marino #define mpfr_check_range(x,t,r) \
11974a238c70SJohn Marino  (MPFR_LIKELY (MPFR_EXP (x) >= __gmpfr_emin && MPFR_EXP (x) <= __gmpfr_emax) \
11984a238c70SJohn Marino   ? ((t) ? (__gmpfr_flags |= MPFR_FLAGS_INEXACT, (t)) : 0)                   \
11994a238c70SJohn Marino   : mpfr_check_range(x,t,r))
12004a238c70SJohn Marino 
12014a238c70SJohn Marino 
12024a238c70SJohn Marino /******************************************************
12034a238c70SJohn Marino  *****************  Inline Rounding *******************
12044a238c70SJohn Marino  ******************************************************/
12054a238c70SJohn Marino 
12064a238c70SJohn Marino /*
12074a238c70SJohn Marino  * Note: due to the labels, one cannot use a macro MPFR_RNDRAW* more than
12084a238c70SJohn Marino  * once in a function (otherwise these labels would not be unique).
12094a238c70SJohn Marino  */
12104a238c70SJohn Marino 
12114a238c70SJohn Marino /*
12124a238c70SJohn Marino  * Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
12134a238c70SJohn Marino  * assuming dest's sign is sign.
12144a238c70SJohn Marino  * In rounding to nearest mode, execute MIDDLE_HANDLER when the value
12154a238c70SJohn Marino  * is the middle of two consecutive numbers in dest precision.
12164a238c70SJohn Marino  * Execute OVERFLOW_HANDLER in case of overflow when rounding.
12174a238c70SJohn Marino  */
12184a238c70SJohn Marino #define MPFR_RNDRAW_GEN(inexact, dest, srcp, sprec, rnd, sign,              \
12194a238c70SJohn Marino                         MIDDLE_HANDLER, OVERFLOW_HANDLER)                   \
12204a238c70SJohn Marino   do {                                                                      \
12214a238c70SJohn Marino     mp_size_t _dests, _srcs;                                                \
12224a238c70SJohn Marino     mp_limb_t *_destp;                                                      \
12234a238c70SJohn Marino     mpfr_prec_t _destprec, _srcprec;                                        \
12244a238c70SJohn Marino                                                                             \
12254a238c70SJohn Marino     /* Check Trivial Case when Dest Mantissa has more bits than source */   \
12264a238c70SJohn Marino     _srcprec = (sprec);                                                     \
12274a238c70SJohn Marino     _destprec = MPFR_PREC (dest);                                           \
12284a238c70SJohn Marino     _destp = MPFR_MANT (dest);                                              \
12294a238c70SJohn Marino     if (MPFR_UNLIKELY (_destprec >= _srcprec))                              \
12304a238c70SJohn Marino       {                                                                     \
1231*ab6d115fSJohn Marino         _srcs  = MPFR_PREC2LIMBS (_srcprec);                                \
1232*ab6d115fSJohn Marino         _dests = MPFR_PREC2LIMBS (_destprec) - _srcs;                       \
12334a238c70SJohn Marino         MPN_COPY (_destp + _dests, srcp, _srcs);                            \
12344a238c70SJohn Marino         MPN_ZERO (_destp, _dests);                                          \
12354a238c70SJohn Marino         inexact = 0;                                                        \
12364a238c70SJohn Marino       }                                                                     \
12374a238c70SJohn Marino     else                                                                    \
12384a238c70SJohn Marino       {                                                                     \
12394a238c70SJohn Marino         /* Non trivial case: rounding needed */                             \
12404a238c70SJohn Marino         mpfr_prec_t _sh;                                                    \
12414a238c70SJohn Marino         mp_limb_t *_sp;                                                     \
12424a238c70SJohn Marino         mp_limb_t _rb, _sb, _ulp;                                           \
12434a238c70SJohn Marino                                                                             \
12444a238c70SJohn Marino         /* Compute Position and shift */                                    \
1245*ab6d115fSJohn Marino         _srcs  = MPFR_PREC2LIMBS (_srcprec);                                \
1246*ab6d115fSJohn Marino         _dests = MPFR_PREC2LIMBS (_destprec);                               \
12474a238c70SJohn Marino         MPFR_UNSIGNED_MINUS_MODULO (_sh, _destprec);                        \
12484a238c70SJohn Marino         _sp = (srcp) + _srcs - _dests;                                      \
12494a238c70SJohn Marino                                                                             \
12504a238c70SJohn Marino         /* General case when prec % GMP_NUMB_BITS != 0 */                   \
12514a238c70SJohn Marino         if (MPFR_LIKELY (_sh != 0))                                         \
12524a238c70SJohn Marino           {                                                                 \
12534a238c70SJohn Marino             mp_limb_t _mask;                                                \
12544a238c70SJohn Marino             /* Compute Rounding Bit and Sticky Bit */                       \
12554a238c70SJohn Marino             /* Note: in directed rounding modes, if the rounding bit */     \
12564a238c70SJohn Marino             /* is 1, the behavior does not depend on the sticky bit; */     \
12574a238c70SJohn Marino             /* thus we will not try to compute it in this case (this */     \
12584a238c70SJohn Marino             /* can be much faster and avoids to read uninitialized   */     \
12594a238c70SJohn Marino             /* data in the current mpfr_mul implementation). We just */     \
12604a238c70SJohn Marino             /* make sure that _sb is initialized.                    */     \
12614a238c70SJohn Marino             _mask = MPFR_LIMB_ONE << (_sh - 1);                             \
12624a238c70SJohn Marino             _rb = _sp[0] & _mask;                                           \
12634a238c70SJohn Marino             _sb = _sp[0] & (_mask - 1);                                     \
12644a238c70SJohn Marino             if (MPFR_UNLIKELY (_sb == 0) &&                                 \
12654a238c70SJohn Marino                 ((rnd) == MPFR_RNDN || _rb == 0))                           \
12664a238c70SJohn Marino               { /* TODO: Improve it */                                      \
12674a238c70SJohn Marino                 mp_limb_t *_tmp;                                            \
12684a238c70SJohn Marino                 mp_size_t _n;                                               \
12694a238c70SJohn Marino                 for (_tmp = _sp, _n = _srcs - _dests ;                      \
12704a238c70SJohn Marino                      _n != 0 && _sb == 0 ; _n--)                            \
12714a238c70SJohn Marino                   _sb = *--_tmp;                                            \
12724a238c70SJohn Marino               }                                                             \
12734a238c70SJohn Marino             _ulp = 2 * _mask;                                               \
12744a238c70SJohn Marino           }                                                                 \
12754a238c70SJohn Marino         else /* _sh == 0 */                                                 \
12764a238c70SJohn Marino           {                                                                 \
12774a238c70SJohn Marino             MPFR_ASSERTD (_dests < _srcs);                                  \
12784a238c70SJohn Marino             /* Compute Rounding Bit and Sticky Bit - see note above */      \
12794a238c70SJohn Marino             _rb = _sp[-1] & MPFR_LIMB_HIGHBIT;                              \
12804a238c70SJohn Marino             _sb = _sp[-1] & (MPFR_LIMB_HIGHBIT-1);                          \
12814a238c70SJohn Marino             if (MPFR_UNLIKELY (_sb == 0) &&                                 \
12824a238c70SJohn Marino                 ((rnd) == MPFR_RNDN || _rb == 0))                           \
12834a238c70SJohn Marino               {                                                             \
12844a238c70SJohn Marino                 mp_limb_t *_tmp;                                            \
12854a238c70SJohn Marino                 mp_size_t _n;                                               \
12864a238c70SJohn Marino                 for (_tmp = _sp - 1, _n = _srcs - _dests - 1 ;              \
12874a238c70SJohn Marino                      _n != 0 && _sb == 0 ; _n--)                            \
12884a238c70SJohn Marino                   _sb = *--_tmp;                                            \
12894a238c70SJohn Marino               }                                                             \
12904a238c70SJohn Marino             _ulp = MPFR_LIMB_ONE;                                           \
12914a238c70SJohn Marino           }                                                                 \
12924a238c70SJohn Marino         /* Rounding */                                                      \
12934a238c70SJohn Marino         if (MPFR_LIKELY (rnd == MPFR_RNDN))                                 \
12944a238c70SJohn Marino           {                                                                 \
12954a238c70SJohn Marino             if (_rb == 0)                                                   \
12964a238c70SJohn Marino               {                                                             \
12974a238c70SJohn Marino               trunc:                                                        \
12984a238c70SJohn Marino                 inexact = MPFR_LIKELY ((_sb | _rb) != 0) ? -sign : 0;       \
12994a238c70SJohn Marino               trunc_doit:                                                   \
13004a238c70SJohn Marino                 MPN_COPY (_destp, _sp, _dests);                             \
13014a238c70SJohn Marino                 _destp[0] &= ~(_ulp - 1);                                   \
13024a238c70SJohn Marino               }                                                             \
13034a238c70SJohn Marino             else if (MPFR_UNLIKELY (_sb == 0))                              \
13044a238c70SJohn Marino               { /* Middle of two consecutive representable numbers */       \
13054a238c70SJohn Marino                 MIDDLE_HANDLER;                                             \
13064a238c70SJohn Marino               }                                                             \
13074a238c70SJohn Marino             else                                                            \
13084a238c70SJohn Marino               {                                                             \
13094a238c70SJohn Marino                 if (0)                                                      \
13104a238c70SJohn Marino                   goto addoneulp_doit; /* dummy code to avoid warning */    \
13114a238c70SJohn Marino               addoneulp:                                                    \
13124a238c70SJohn Marino                 inexact = sign;                                             \
13134a238c70SJohn Marino               addoneulp_doit:                                               \
13144a238c70SJohn Marino                 if (MPFR_UNLIKELY (mpn_add_1 (_destp, _sp, _dests, _ulp)))  \
13154a238c70SJohn Marino                   {                                                         \
13164a238c70SJohn Marino                     _destp[_dests - 1] = MPFR_LIMB_HIGHBIT;                 \
13174a238c70SJohn Marino                     OVERFLOW_HANDLER;                                       \
13184a238c70SJohn Marino                   }                                                         \
13194a238c70SJohn Marino                 _destp[0] &= ~(_ulp - 1);                                   \
13204a238c70SJohn Marino               }                                                             \
13214a238c70SJohn Marino           }                                                                 \
13224a238c70SJohn Marino         else                                                                \
13234a238c70SJohn Marino           { /* Directed rounding mode */                                    \
13244a238c70SJohn Marino             if (MPFR_LIKELY (MPFR_IS_LIKE_RNDZ (rnd,                        \
13254a238c70SJohn Marino                                                 MPFR_IS_NEG_SIGN (sign))))  \
13264a238c70SJohn Marino               goto trunc;                                                   \
13274a238c70SJohn Marino              else if (MPFR_UNLIKELY ((_sb | _rb) == 0))                     \
13284a238c70SJohn Marino                {                                                            \
13294a238c70SJohn Marino                  inexact = 0;                                               \
13304a238c70SJohn Marino                  goto trunc_doit;                                           \
13314a238c70SJohn Marino                }                                                            \
13324a238c70SJohn Marino              else                                                           \
13334a238c70SJohn Marino               goto addoneulp;                                               \
13344a238c70SJohn Marino           }                                                                 \
13354a238c70SJohn Marino       }                                                                     \
13364a238c70SJohn Marino   } while (0)
13374a238c70SJohn Marino 
13384a238c70SJohn Marino /*
13394a238c70SJohn Marino  * Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
13404a238c70SJohn Marino  * assuming dest's sign is sign.
13414a238c70SJohn Marino  * Execute OVERFLOW_HANDLER in case of overflow when rounding.
13424a238c70SJohn Marino  */
13434a238c70SJohn Marino #define MPFR_RNDRAW(inexact, dest, srcp, sprec, rnd, sign, OVERFLOW_HANDLER) \
13444a238c70SJohn Marino    MPFR_RNDRAW_GEN (inexact, dest, srcp, sprec, rnd, sign,                   \
13454a238c70SJohn Marino      if ((_sp[0] & _ulp) == 0)                                               \
13464a238c70SJohn Marino        {                                                                     \
13474a238c70SJohn Marino          inexact = -sign;                                                    \
13484a238c70SJohn Marino          goto trunc_doit;                                                    \
13494a238c70SJohn Marino        }                                                                     \
13504a238c70SJohn Marino      else                                                                    \
13514a238c70SJohn Marino        goto addoneulp;                                                       \
13524a238c70SJohn Marino      , OVERFLOW_HANDLER)
13534a238c70SJohn Marino 
13544a238c70SJohn Marino /*
13554a238c70SJohn Marino  * Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
13564a238c70SJohn Marino  * assuming dest's sign is sign.
13574a238c70SJohn Marino  * Execute OVERFLOW_HANDLER in case of overflow when rounding.
13584a238c70SJohn Marino  * Set inexact to +/- MPFR_EVEN_INEX in case of even rounding.
13594a238c70SJohn Marino  */
13604a238c70SJohn Marino #define MPFR_RNDRAW_EVEN(inexact, dest, srcp, sprec, rnd, sign, \
13614a238c70SJohn Marino                          OVERFLOW_HANDLER)                      \
13624a238c70SJohn Marino    MPFR_RNDRAW_GEN (inexact, dest, srcp, sprec, rnd, sign,      \
13634a238c70SJohn Marino      if ((_sp[0] & _ulp) == 0)                                  \
13644a238c70SJohn Marino        {                                                        \
13654a238c70SJohn Marino          inexact = -MPFR_EVEN_INEX * sign;                      \
13664a238c70SJohn Marino          goto trunc_doit;                                       \
13674a238c70SJohn Marino        }                                                        \
13684a238c70SJohn Marino      else                                                       \
13694a238c70SJohn Marino        {                                                        \
13704a238c70SJohn Marino          inexact = MPFR_EVEN_INEX * sign;                       \
13714a238c70SJohn Marino          goto addoneulp_doit;                                   \
13724a238c70SJohn Marino        }                                                        \
13734a238c70SJohn Marino      , OVERFLOW_HANDLER)
13744a238c70SJohn Marino 
13754a238c70SJohn Marino /* Return TRUE if b is non singular and we can round it to precision 'prec'
13764a238c70SJohn Marino    and determine the ternary value, with rounding mode 'rnd', and with
13774a238c70SJohn Marino    error at most 'error' */
13784a238c70SJohn Marino #define MPFR_CAN_ROUND(b,err,prec,rnd)                                       \
13794a238c70SJohn Marino  (!MPFR_IS_SINGULAR (b) && mpfr_round_p (MPFR_MANT (b), MPFR_LIMB_SIZE (b),  \
13804a238c70SJohn Marino                                          (err), (prec) + ((rnd)==MPFR_RNDN)))
13814a238c70SJohn Marino 
13824a238c70SJohn Marino /* Copy the sign and the significand, and handle the exponent in exp. */
13834a238c70SJohn Marino #define MPFR_SETRAW(inexact,dest,src,exp,rnd)                           \
13844a238c70SJohn Marino   if (MPFR_UNLIKELY (dest != src))                                      \
13854a238c70SJohn Marino     {                                                                   \
13864a238c70SJohn Marino       MPFR_SET_SIGN (dest, MPFR_SIGN (src));                            \
13874a238c70SJohn Marino       if (MPFR_LIKELY (MPFR_PREC (dest) == MPFR_PREC (src)))            \
13884a238c70SJohn Marino         {                                                               \
13894a238c70SJohn Marino           MPN_COPY (MPFR_MANT (dest), MPFR_MANT (src),                  \
1390*ab6d115fSJohn Marino                     MPFR_LIMB_SIZE (src));                              \
13914a238c70SJohn Marino           inexact = 0;                                                  \
13924a238c70SJohn Marino         }                                                               \
13934a238c70SJohn Marino       else                                                              \
13944a238c70SJohn Marino         {                                                               \
13954a238c70SJohn Marino           MPFR_RNDRAW (inexact, dest, MPFR_MANT (src), MPFR_PREC (src), \
13964a238c70SJohn Marino                        rnd, MPFR_SIGN (src), exp++);                    \
13974a238c70SJohn Marino         }                                                               \
13984a238c70SJohn Marino     }                                                                   \
13994a238c70SJohn Marino   else                                                                  \
14004a238c70SJohn Marino     inexact = 0;
14014a238c70SJohn Marino 
14024a238c70SJohn Marino /* TODO: fix this description (see round_near_x.c). */
14034a238c70SJohn Marino /* Assuming that the function has a Taylor expansion which looks like:
14044a238c70SJohn Marino     y=o(f(x)) = o(v + g(x)) with |g(x)| <= 2^(EXP(v)-err)
14054a238c70SJohn Marino    we can quickly set y to v if x is small (ie err > prec(y)+1) in most
14064a238c70SJohn Marino    cases. It assumes that f(x) is not representable exactly as a FP number.
14074a238c70SJohn Marino    v must not be a singular value (NAN, INF or ZERO); usual values are
14084a238c70SJohn Marino    v=1 or v=x.
14094a238c70SJohn Marino 
14104a238c70SJohn Marino    y is the destination (a mpfr_t), v the value to set (a mpfr_t),
14114a238c70SJohn Marino    err1+err2 with err2 <= 3 the error term (mpfr_exp_t's), dir (an int) is
14124a238c70SJohn Marino    the direction of the committed error (if dir = 0, it rounds toward 0,
14134a238c70SJohn Marino    if dir=1, it rounds away from 0), rnd the rounding mode.
14144a238c70SJohn Marino 
14154a238c70SJohn Marino    It returns from the function a ternary value in case of success.
14164a238c70SJohn Marino    If you want to free something, you must fill the "extra" field
14174a238c70SJohn Marino    in consequences, otherwise put nothing in it.
14184a238c70SJohn Marino 
14194a238c70SJohn Marino    The test is less restrictive than necessary, but the function
14204a238c70SJohn Marino    will finish the check itself.
14214a238c70SJohn Marino 
14224a238c70SJohn Marino    Note: err1 + err2 is allowed to overflow as mpfr_exp_t, but it must give
14234a238c70SJohn Marino    its real value as mpfr_uexp_t.
14244a238c70SJohn Marino */
14254a238c70SJohn Marino #define MPFR_FAST_COMPUTE_IF_SMALL_INPUT(y,v,err1,err2,dir,rnd,extra)   \
14264a238c70SJohn Marino   do {                                                                  \
14274a238c70SJohn Marino     mpfr_ptr _y = (y);                                                  \
14284a238c70SJohn Marino     mpfr_exp_t _err1 = (err1);                                          \
14294a238c70SJohn Marino     mpfr_exp_t _err2 = (err2);                                          \
14304a238c70SJohn Marino     if (_err1 > 0)                                                      \
14314a238c70SJohn Marino       {                                                                 \
14324a238c70SJohn Marino         mpfr_uexp_t _err = (mpfr_uexp_t) _err1 + _err2;                 \
14334a238c70SJohn Marino         if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1))                  \
14344a238c70SJohn Marino           {                                                             \
14354a238c70SJohn Marino             int _inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd)); \
14364a238c70SJohn Marino             if (_inexact != 0)                                          \
14374a238c70SJohn Marino               {                                                         \
14384a238c70SJohn Marino                 extra;                                                  \
14394a238c70SJohn Marino                 return _inexact;                                        \
14404a238c70SJohn Marino               }                                                         \
14414a238c70SJohn Marino           }                                                             \
14424a238c70SJohn Marino       }                                                                 \
14434a238c70SJohn Marino   } while (0)
14444a238c70SJohn Marino 
14454a238c70SJohn Marino /* Variant, to be called somewhere after MPFR_SAVE_EXPO_MARK. This variant
14464a238c70SJohn Marino    is needed when there are some computations before or when some non-zero
14474a238c70SJohn Marino    real constant is used, such as __gmpfr_one for mpfr_cos. */
14484a238c70SJohn Marino #define MPFR_SMALL_INPUT_AFTER_SAVE_EXPO(y,v,err1,err2,dir,rnd,expo,extra) \
14494a238c70SJohn Marino   do {                                                                  \
14504a238c70SJohn Marino     mpfr_ptr _y = (y);                                                  \
14514a238c70SJohn Marino     mpfr_exp_t _err1 = (err1);                                          \
14524a238c70SJohn Marino     mpfr_exp_t _err2 = (err2);                                          \
14534a238c70SJohn Marino     if (_err1 > 0)                                                      \
14544a238c70SJohn Marino       {                                                                 \
14554a238c70SJohn Marino         mpfr_uexp_t _err = (mpfr_uexp_t) _err1 + _err2;                 \
14564a238c70SJohn Marino         if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1))                  \
14574a238c70SJohn Marino           {                                                             \
14584a238c70SJohn Marino             int _inexact;                                               \
14594a238c70SJohn Marino             mpfr_clear_flags ();                                        \
14604a238c70SJohn Marino             _inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd));     \
14614a238c70SJohn Marino             if (_inexact != 0)                                          \
14624a238c70SJohn Marino               {                                                         \
14634a238c70SJohn Marino                 extra;                                                  \
14644a238c70SJohn Marino                 MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);      \
14654a238c70SJohn Marino                 MPFR_SAVE_EXPO_FREE (expo);                             \
14664a238c70SJohn Marino                 return mpfr_check_range (_y, _inexact, (rnd));          \
14674a238c70SJohn Marino               }                                                         \
14684a238c70SJohn Marino           }                                                             \
14694a238c70SJohn Marino       }                                                                 \
14704a238c70SJohn Marino   } while (0)
14714a238c70SJohn Marino 
14724a238c70SJohn Marino /******************************************************
14734a238c70SJohn Marino  ***************  Ziv Loop Macro  *********************
14744a238c70SJohn Marino  ******************************************************/
14754a238c70SJohn Marino 
14764a238c70SJohn Marino #ifndef MPFR_USE_LOGGING
14774a238c70SJohn Marino 
14784a238c70SJohn Marino #define MPFR_ZIV_DECL(_x) mpfr_prec_t _x
14794a238c70SJohn Marino #define MPFR_ZIV_INIT(_x, _p) (_x) = GMP_NUMB_BITS
14804a238c70SJohn Marino #define MPFR_ZIV_NEXT(_x, _p) ((_p) += (_x), (_x) = (_p)/2)
14814a238c70SJohn Marino #define MPFR_ZIV_FREE(x)
14824a238c70SJohn Marino 
14834a238c70SJohn Marino #else
14844a238c70SJohn Marino 
14854a238c70SJohn Marino /* The following test on glibc is there mainly for Darwin (Mac OS X), to
14864a238c70SJohn Marino    obtain a better error message. The real test should have been a test
14874a238c70SJohn Marino    concerning nested functions in gcc, which are disabled by default on
14884a238c70SJohn Marino    Darwin; but it is not possible to do that without a configure test. */
14894a238c70SJohn Marino # if defined (__cplusplus) || !(__MPFR_GNUC(3,0) && __MPFR_GLIBC(2,0))
14904a238c70SJohn Marino #  error "Logging not supported (needs gcc >= 3.0 and GNU C Library >= 2.0)."
14914a238c70SJohn Marino # endif
14924a238c70SJohn Marino 
14934a238c70SJohn Marino /* Use LOGGING */
14944a238c70SJohn Marino 
14954a238c70SJohn Marino /* Note: the mpfr_log_level >= 0 below avoids to take into account
14964a238c70SJohn Marino    Ziv loops used by the MPFR functions called by the mpfr_fprintf
14974a238c70SJohn Marino    in LOG_PRINT. */
14984a238c70SJohn Marino 
14994a238c70SJohn Marino #define MPFR_ZIV_DECL(_x)                                               \
15004a238c70SJohn Marino   mpfr_prec_t _x;                                                       \
15014a238c70SJohn Marino   int _x ## _cpt = 1;                                                   \
15024a238c70SJohn Marino   static unsigned long  _x ## _loop = 0, _x ## _bad = 0;                \
15034a238c70SJohn Marino   static const char *_x ## _fname = __func__;                           \
15044a238c70SJohn Marino   auto void __attribute__ ((destructor)) x ## _f  (void);               \
15054a238c70SJohn Marino   void __attribute__ ((destructor)) x ## _f  (void) {                   \
15064a238c70SJohn Marino     if (_x ## _loop != 0 && (MPFR_LOG_STAT_F & mpfr_log_type))          \
15074a238c70SJohn Marino       fprintf (mpfr_log_file,                                           \
15084a238c70SJohn Marino                "%s: Ziv failed %2.2f%% (%lu bad cases / %lu calls)\n",  \
15094a238c70SJohn Marino                _x ## _fname, (double) 100.0 * _x ## _bad / _x ## _loop, \
15104a238c70SJohn Marino                _x ## _bad, _x ## _loop ); }
15114a238c70SJohn Marino 
15124a238c70SJohn Marino #define MPFR_ZIV_INIT(_x, _p)                                           \
15134a238c70SJohn Marino   do                                                                    \
15144a238c70SJohn Marino     {                                                                   \
15154a238c70SJohn Marino       (_x) = GMP_NUMB_BITS;                                             \
15164a238c70SJohn Marino       if (mpfr_log_level >= 0)                                          \
15174a238c70SJohn Marino         _x ## _loop ++;                                                 \
15184a238c70SJohn Marino       if ((MPFR_LOG_BADCASE_F & mpfr_log_type) &&                       \
15194a238c70SJohn Marino           (mpfr_log_current <= mpfr_log_level))                         \
15204a238c70SJohn Marino         LOG_PRINT ("%s:ZIV 1st prec=%Pd\n",                             \
15214a238c70SJohn Marino                    __func__, (mpfr_prec_t) (_p));                       \
15224a238c70SJohn Marino     }                                                                   \
15234a238c70SJohn Marino   while (0)
15244a238c70SJohn Marino 
15254a238c70SJohn Marino #define MPFR_ZIV_NEXT(_x, _p)                                           \
15264a238c70SJohn Marino   do                                                                    \
15274a238c70SJohn Marino     {                                                                   \
15284a238c70SJohn Marino       (_p) += (_x);                                                     \
15294a238c70SJohn Marino       (_x) = (_p) / 2;                                                  \
15304a238c70SJohn Marino       if (mpfr_log_level >= 0)                                          \
15314a238c70SJohn Marino         _x ## _bad += (_x ## _cpt == 1);                                \
15324a238c70SJohn Marino       _x ## _cpt ++;                                                    \
15334a238c70SJohn Marino       if ((MPFR_LOG_BADCASE_F & mpfr_log_type) &&                       \
15344a238c70SJohn Marino           (mpfr_log_current <= mpfr_log_level))                         \
15354a238c70SJohn Marino         LOG_PRINT ("%s:ZIV new prec=%Pd\n",                             \
15364a238c70SJohn Marino                    __func__, (mpfr_prec_t) (_p));                       \
15374a238c70SJohn Marino     }                                                                   \
15384a238c70SJohn Marino   while (0)
15394a238c70SJohn Marino 
15404a238c70SJohn Marino #define MPFR_ZIV_FREE(_x)                                               \
15414a238c70SJohn Marino   do                                                                    \
15424a238c70SJohn Marino     {                                                                   \
15434a238c70SJohn Marino       if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && _x ## _cpt > 1 &&     \
15444a238c70SJohn Marino           (mpfr_log_current <= mpfr_log_level))                         \
15454a238c70SJohn Marino         fprintf (mpfr_log_file, "%s:ZIV %d loops\n",                    \
15464a238c70SJohn Marino                  __func__, _x ## _cpt);                                 \
15474a238c70SJohn Marino     }                                                                   \
15484a238c70SJohn Marino   while (0)
15494a238c70SJohn Marino 
15504a238c70SJohn Marino #endif
15514a238c70SJohn Marino 
15524a238c70SJohn Marino 
15534a238c70SJohn Marino /******************************************************
15544a238c70SJohn Marino  ***************  Logging Macros  *********************
15554a238c70SJohn Marino  ******************************************************/
15564a238c70SJohn Marino 
15574a238c70SJohn Marino /* The different kind of LOG */
15584a238c70SJohn Marino #define MPFR_LOG_INPUT_F    1
15594a238c70SJohn Marino #define MPFR_LOG_OUTPUT_F   2
15604a238c70SJohn Marino #define MPFR_LOG_INTERNAL_F 4
15614a238c70SJohn Marino #define MPFR_LOG_TIME_F     8
15624a238c70SJohn Marino #define MPFR_LOG_BADCASE_F  16
15634a238c70SJohn Marino #define MPFR_LOG_MSG_F      32
15644a238c70SJohn Marino #define MPFR_LOG_STAT_F     64
15654a238c70SJohn Marino 
15664a238c70SJohn Marino #ifdef MPFR_USE_LOGGING
15674a238c70SJohn Marino 
15684a238c70SJohn Marino /* Check if we can support this feature */
15694a238c70SJohn Marino # ifdef MPFR_USE_THREAD_SAFE
15704a238c70SJohn Marino #  error "Enable either `Logging' or `thread-safe', not both"
15714a238c70SJohn Marino # endif
15724a238c70SJohn Marino # if !__MPFR_GNUC(3,0)
15734a238c70SJohn Marino #  error "Logging not supported (GCC >= 3.0)"
15744a238c70SJohn Marino # endif
15754a238c70SJohn Marino 
15764a238c70SJohn Marino #if defined (__cplusplus)
15774a238c70SJohn Marino extern "C" {
15784a238c70SJohn Marino #endif
15794a238c70SJohn Marino 
15804a238c70SJohn Marino __MPFR_DECLSPEC extern FILE *mpfr_log_file;
15814a238c70SJohn Marino __MPFR_DECLSPEC extern int   mpfr_log_type;
15824a238c70SJohn Marino __MPFR_DECLSPEC extern int   mpfr_log_level;
15834a238c70SJohn Marino __MPFR_DECLSPEC extern int   mpfr_log_current;
15844a238c70SJohn Marino __MPFR_DECLSPEC extern mpfr_prec_t mpfr_log_prec;
15854a238c70SJohn Marino 
15864a238c70SJohn Marino #if defined (__cplusplus)
15874a238c70SJohn Marino  }
15884a238c70SJohn Marino #endif
15894a238c70SJohn Marino 
15904a238c70SJohn Marino /* LOG_PRINT calls mpfr_fprintf on mpfr_log_file with logging disabled
15914a238c70SJohn Marino    (recursive logging is not wanted and freezes MPFR). */
15924a238c70SJohn Marino #define LOG_PRINT(format, ...)                                          \
15934a238c70SJohn Marino   do                                                                    \
15944a238c70SJohn Marino     {                                                                   \
15954a238c70SJohn Marino       int old_level = mpfr_log_level;                                   \
15964a238c70SJohn Marino       mpfr_log_level = -1;  /* disable logging in mpfr_fprintf */       \
15974a238c70SJohn Marino       __gmpfr_cache_const_pi = __gmpfr_logging_pi;                      \
15984a238c70SJohn Marino       __gmpfr_cache_const_log2 = __gmpfr_logging_log2;                  \
15994a238c70SJohn Marino       mpfr_fprintf (mpfr_log_file, format, __VA_ARGS__);                \
16004a238c70SJohn Marino       mpfr_log_level = old_level;                                       \
16014a238c70SJohn Marino       __gmpfr_cache_const_pi = __gmpfr_normal_pi;                       \
16024a238c70SJohn Marino       __gmpfr_cache_const_log2 = __gmpfr_normal_log2;                   \
16034a238c70SJohn Marino     }                                                                   \
16044a238c70SJohn Marino   while (0)
16054a238c70SJohn Marino 
16064a238c70SJohn Marino #define MPFR_LOG_VAR(x)                                                 \
16074a238c70SJohn Marino   do                                                                    \
16084a238c70SJohn Marino     if ((MPFR_LOG_INTERNAL_F & mpfr_log_type) &&                        \
16094a238c70SJohn Marino         (mpfr_log_current <= mpfr_log_level))                           \
1610*ab6d115fSJohn Marino       LOG_PRINT ("%s.%d:%s[%#Pu]=%.*Rg\n", __func__, __LINE__,          \
16114a238c70SJohn Marino                  #x, mpfr_get_prec (x), mpfr_log_prec, x);              \
16124a238c70SJohn Marino   while (0)
16134a238c70SJohn Marino 
16144a238c70SJohn Marino #define MPFR_LOG_MSG2(format, ...)                                      \
16154a238c70SJohn Marino   do                                                                    \
16164a238c70SJohn Marino     if ((MPFR_LOG_MSG_F & mpfr_log_type) &&                             \
16174a238c70SJohn Marino         (mpfr_log_current <= mpfr_log_level))                           \
16184a238c70SJohn Marino       LOG_PRINT ("%s.%d: "format, __func__, __LINE__, __VA_ARGS__);     \
16194a238c70SJohn Marino   while (0)
16204a238c70SJohn Marino #define MPFR_LOG_MSG(x) MPFR_LOG_MSG2 x
16214a238c70SJohn Marino 
16224a238c70SJohn Marino #define MPFR_LOG_BEGIN2(format, ...)                                    \
16234a238c70SJohn Marino   mpfr_log_current ++;                                                  \
16244a238c70SJohn Marino   if ((MPFR_LOG_INPUT_F & mpfr_log_type) &&                             \
16254a238c70SJohn Marino       (mpfr_log_current <= mpfr_log_level))                             \
16264a238c70SJohn Marino     LOG_PRINT ("%s:IN  "format"\n", __func__, __VA_ARGS__);             \
16274a238c70SJohn Marino   if ((MPFR_LOG_TIME_F & mpfr_log_type) &&                              \
16284a238c70SJohn Marino       (mpfr_log_current <= mpfr_log_level))                             \
16294a238c70SJohn Marino     __gmpfr_log_time = mpfr_get_cputime ();
16304a238c70SJohn Marino #define MPFR_LOG_BEGIN(x)                                               \
16314a238c70SJohn Marino   int __gmpfr_log_time = 0;                                             \
16324a238c70SJohn Marino   MPFR_LOG_BEGIN2 x
16334a238c70SJohn Marino 
16344a238c70SJohn Marino #define MPFR_LOG_END2(format, ...)                                      \
16354a238c70SJohn Marino   if ((MPFR_LOG_TIME_F & mpfr_log_type) &&                              \
16364a238c70SJohn Marino       (mpfr_log_current <= mpfr_log_level))                             \
16374a238c70SJohn Marino     fprintf (mpfr_log_file, "%s:TIM %dms\n", __mpfr_log_fname,          \
16384a238c70SJohn Marino              mpfr_get_cputime () - __gmpfr_log_time);                   \
16394a238c70SJohn Marino   if ((MPFR_LOG_OUTPUT_F & mpfr_log_type) &&                            \
16404a238c70SJohn Marino       (mpfr_log_current <= mpfr_log_level))                             \
16414a238c70SJohn Marino     LOG_PRINT ("%s:OUT "format"\n", __mpfr_log_fname, __VA_ARGS__);     \
16424a238c70SJohn Marino   mpfr_log_current --;
16434a238c70SJohn Marino #define MPFR_LOG_END(x)                                                 \
16444a238c70SJohn Marino   static const char *__mpfr_log_fname = __func__;                       \
16454a238c70SJohn Marino   MPFR_LOG_END2 x
16464a238c70SJohn Marino 
16474a238c70SJohn Marino #define MPFR_LOG_FUNC(begin,end)                                        \
16484a238c70SJohn Marino   static const char *__mpfr_log_fname = __func__;                       \
16494a238c70SJohn Marino   auto void __mpfr_log_cleanup (int *time);                             \
16504a238c70SJohn Marino   void __mpfr_log_cleanup (int *time) {                                 \
16514a238c70SJohn Marino     int __gmpfr_log_time = *time;                                       \
16524a238c70SJohn Marino     MPFR_LOG_END2 end; }                                                \
16534a238c70SJohn Marino   int __gmpfr_log_time __attribute__ ((cleanup (__mpfr_log_cleanup)));  \
16544a238c70SJohn Marino   __gmpfr_log_time = 0;                                                 \
16554a238c70SJohn Marino   MPFR_LOG_BEGIN2 begin
16564a238c70SJohn Marino 
16574a238c70SJohn Marino #else /* MPFR_USE_LOGGING */
16584a238c70SJohn Marino 
16594a238c70SJohn Marino /* Define void macro for logging */
16604a238c70SJohn Marino 
16614a238c70SJohn Marino #define MPFR_LOG_VAR(x)
16624a238c70SJohn Marino #define MPFR_LOG_BEGIN(x)
16634a238c70SJohn Marino #define MPFR_LOG_END(x)
16644a238c70SJohn Marino #define MPFR_LOG_MSG(x)
16654a238c70SJohn Marino #define MPFR_LOG_FUNC(x,y)
16664a238c70SJohn Marino 
16674a238c70SJohn Marino #endif /* MPFR_USE_LOGGING */
16684a238c70SJohn Marino 
16694a238c70SJohn Marino 
16704a238c70SJohn Marino /**************************************************************
16714a238c70SJohn Marino  ************  Group Initialize Functions Macros  *************
16724a238c70SJohn Marino  **************************************************************/
16734a238c70SJohn Marino 
16744a238c70SJohn Marino #ifndef MPFR_GROUP_STATIC_SIZE
16754a238c70SJohn Marino # define MPFR_GROUP_STATIC_SIZE 16
16764a238c70SJohn Marino #endif
16774a238c70SJohn Marino 
16784a238c70SJohn Marino struct mpfr_group_t {
16794a238c70SJohn Marino   size_t     alloc;
16804a238c70SJohn Marino   mp_limb_t *mant;
16814a238c70SJohn Marino   mp_limb_t  tab[MPFR_GROUP_STATIC_SIZE];
16824a238c70SJohn Marino };
16834a238c70SJohn Marino 
16844a238c70SJohn Marino #define MPFR_GROUP_DECL(g) struct mpfr_group_t g
16854a238c70SJohn Marino #define MPFR_GROUP_CLEAR(g) do {                                 \
16864a238c70SJohn Marino  MPFR_LOG_MSG (("GROUP_CLEAR: ptr = 0x%lX, size = %lu\n",        \
16874a238c70SJohn Marino                 (unsigned long) (g).mant,                        \
16884a238c70SJohn Marino                 (unsigned long) (g).alloc));                     \
16894a238c70SJohn Marino  if (MPFR_UNLIKELY ((g).alloc != 0)) {                           \
16904a238c70SJohn Marino    MPFR_ASSERTD ((g).mant != (g).tab);                           \
16914a238c70SJohn Marino    (*__gmp_free_func) ((g).mant, (g).alloc);                     \
16924a238c70SJohn Marino  }} while (0)
16934a238c70SJohn Marino 
16944a238c70SJohn Marino #define MPFR_GROUP_INIT_TEMPLATE(g, prec, num, handler) do {            \
16954a238c70SJohn Marino  mpfr_prec_t _prec = (prec);                                            \
16964a238c70SJohn Marino  mp_size_t _size;                                                       \
16974a238c70SJohn Marino  MPFR_ASSERTD (_prec >= MPFR_PREC_MIN);                                 \
16984a238c70SJohn Marino  if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX))                             \
16994a238c70SJohn Marino    mpfr_abort_prec_max ();                                              \
1700*ab6d115fSJohn Marino  _size = MPFR_PREC2LIMBS (_prec);                                       \
17014a238c70SJohn Marino  if (MPFR_UNLIKELY (_size * (num) > MPFR_GROUP_STATIC_SIZE))            \
17024a238c70SJohn Marino    {                                                                    \
17034a238c70SJohn Marino      (g).alloc = (num) * _size * sizeof (mp_limb_t);                    \
17044a238c70SJohn Marino      (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc);       \
17054a238c70SJohn Marino    }                                                                    \
17064a238c70SJohn Marino  else                                                                   \
17074a238c70SJohn Marino    {                                                                    \
17084a238c70SJohn Marino      (g).alloc = 0;                                                     \
17094a238c70SJohn Marino      (g).mant = (g).tab;                                                \
17104a238c70SJohn Marino    }                                                                    \
17114a238c70SJohn Marino  MPFR_LOG_MSG (("GROUP_INIT: ptr = 0x%lX, size = %lu\n",                \
17124a238c70SJohn Marino                 (unsigned long) (g).mant, (unsigned long) (g).alloc));  \
17134a238c70SJohn Marino  handler;                                                               \
17144a238c70SJohn Marino  } while (0)
17154a238c70SJohn Marino #define MPFR_GROUP_TINIT(g, n, x)                       \
17164a238c70SJohn Marino   MPFR_TMP_INIT1 ((g).mant + _size * (n), x, _prec)
17174a238c70SJohn Marino 
17184a238c70SJohn Marino #define MPFR_GROUP_INIT_1(g, prec, x)                            \
17194a238c70SJohn Marino  MPFR_GROUP_INIT_TEMPLATE(g, prec, 1, MPFR_GROUP_TINIT(g, 0, x))
17204a238c70SJohn Marino #define MPFR_GROUP_INIT_2(g, prec, x, y)                         \
17214a238c70SJohn Marino  MPFR_GROUP_INIT_TEMPLATE(g, prec, 2,                            \
17224a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y))
17234a238c70SJohn Marino #define MPFR_GROUP_INIT_3(g, prec, x, y, z)                      \
17244a238c70SJohn Marino  MPFR_GROUP_INIT_TEMPLATE(g, prec, 3,                            \
17254a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17264a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z))
17274a238c70SJohn Marino #define MPFR_GROUP_INIT_4(g, prec, x, y, z, t)                   \
17284a238c70SJohn Marino  MPFR_GROUP_INIT_TEMPLATE(g, prec, 4,                            \
17294a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17304a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t))
17314a238c70SJohn Marino #define MPFR_GROUP_INIT_5(g, prec, x, y, z, t, a)                \
17324a238c70SJohn Marino  MPFR_GROUP_INIT_TEMPLATE(g, prec, 5,                            \
17334a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17344a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t);          \
17354a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 4, a))
17364a238c70SJohn Marino #define MPFR_GROUP_INIT_6(g, prec, x, y, z, t, a, b)             \
17374a238c70SJohn Marino  MPFR_GROUP_INIT_TEMPLATE(g, prec, 6,                            \
17384a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17394a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t);          \
17404a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 4, a);MPFR_GROUP_TINIT(g, 5, b))
17414a238c70SJohn Marino 
17424a238c70SJohn Marino #define MPFR_GROUP_REPREC_TEMPLATE(g, prec, num, handler) do {          \
17434a238c70SJohn Marino  mpfr_prec_t _prec = (prec);                                            \
17444a238c70SJohn Marino  size_t    _oalloc = (g).alloc;                                         \
17454a238c70SJohn Marino  mp_size_t _size;                                                       \
17464a238c70SJohn Marino  MPFR_LOG_MSG (("GROUP_REPREC: oldptr = 0x%lX, oldsize = %lu\n",        \
17474a238c70SJohn Marino                 (unsigned long) (g).mant, (unsigned long) _oalloc));    \
17484a238c70SJohn Marino  MPFR_ASSERTD (_prec >= MPFR_PREC_MIN);                                 \
17494a238c70SJohn Marino  if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX))                             \
17504a238c70SJohn Marino    mpfr_abort_prec_max ();                                              \
1751*ab6d115fSJohn Marino  _size = MPFR_PREC2LIMBS (_prec);                                       \
17524a238c70SJohn Marino  (g).alloc = (num) * _size * sizeof (mp_limb_t);                        \
17534a238c70SJohn Marino  if (MPFR_LIKELY (_oalloc == 0))                                        \
17544a238c70SJohn Marino    (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc);         \
17554a238c70SJohn Marino  else                                                                   \
17564a238c70SJohn Marino    (g).mant = (mp_limb_t *)                                             \
17574a238c70SJohn Marino      (*__gmp_reallocate_func) ((g).mant, _oalloc, (g).alloc);           \
17584a238c70SJohn Marino  MPFR_LOG_MSG (("GROUP_REPREC: newptr = 0x%lX, newsize = %lu\n",        \
17594a238c70SJohn Marino                 (unsigned long) (g).mant, (unsigned long) (g).alloc));  \
17604a238c70SJohn Marino  handler;                                                               \
17614a238c70SJohn Marino  } while (0)
17624a238c70SJohn Marino 
17634a238c70SJohn Marino #define MPFR_GROUP_REPREC_1(g, prec, x)                          \
17644a238c70SJohn Marino  MPFR_GROUP_REPREC_TEMPLATE(g, prec, 1, MPFR_GROUP_TINIT(g, 0, x))
17654a238c70SJohn Marino #define MPFR_GROUP_REPREC_2(g, prec, x, y)                       \
17664a238c70SJohn Marino  MPFR_GROUP_REPREC_TEMPLATE(g, prec, 2,                          \
17674a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y))
17684a238c70SJohn Marino #define MPFR_GROUP_REPREC_3(g, prec, x, y, z)                    \
17694a238c70SJohn Marino  MPFR_GROUP_REPREC_TEMPLATE(g, prec, 3,                          \
17704a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17714a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z))
17724a238c70SJohn Marino #define MPFR_GROUP_REPREC_4(g, prec, x, y, z, t)                 \
17734a238c70SJohn Marino  MPFR_GROUP_REPREC_TEMPLATE(g, prec, 4,                          \
17744a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17754a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t))
17764a238c70SJohn Marino #define MPFR_GROUP_REPREC_5(g, prec, x, y, z, t, a)              \
17774a238c70SJohn Marino  MPFR_GROUP_REPREC_TEMPLATE(g, prec, 5,                          \
17784a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17794a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t);          \
17804a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 4, a))
17814a238c70SJohn Marino #define MPFR_GROUP_REPREC_6(g, prec, x, y, z, t, a, b)           \
17824a238c70SJohn Marino  MPFR_GROUP_REPREC_TEMPLATE(g, prec, 6,                          \
17834a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y);          \
17844a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t);          \
17854a238c70SJohn Marino    MPFR_GROUP_TINIT(g, 4, a);MPFR_GROUP_TINIT(g, 5, b))
17864a238c70SJohn Marino 
17874a238c70SJohn Marino 
17884a238c70SJohn Marino /******************************************************
17894a238c70SJohn Marino  ***************  Internal Functions  *****************
17904a238c70SJohn Marino  ******************************************************/
17914a238c70SJohn Marino 
17924a238c70SJohn Marino #if defined (__cplusplus)
17934a238c70SJohn Marino extern "C" {
17944a238c70SJohn Marino #endif
17954a238c70SJohn Marino 
17964a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_underflow _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t, int));
17974a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_overflow _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t, int));
17984a238c70SJohn Marino 
17994a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_add1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
18004a238c70SJohn Marino                                             mpfr_srcptr, mpfr_rnd_t));
18014a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_sub1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
18024a238c70SJohn Marino                                             mpfr_srcptr, mpfr_rnd_t));
18034a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_add1sp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
18044a238c70SJohn Marino                                               mpfr_srcptr, mpfr_rnd_t));
18054a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_sub1sp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
18064a238c70SJohn Marino                                               mpfr_srcptr, mpfr_rnd_t));
18074a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_can_round_raw _MPFR_PROTO ((const mp_limb_t *,
18084a238c70SJohn Marino              mp_size_t, int, mpfr_exp_t, mpfr_rnd_t, mpfr_rnd_t, mpfr_prec_t));
18094a238c70SJohn Marino 
18104a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_cmp2 _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr,
18114a238c70SJohn Marino                                             mpfr_prec_t *));
18124a238c70SJohn Marino 
18134a238c70SJohn Marino __MPFR_DECLSPEC long          __gmpfr_ceil_log2     _MPFR_PROTO ((double));
18144a238c70SJohn Marino __MPFR_DECLSPEC long          __gmpfr_floor_log2    _MPFR_PROTO ((double));
18154a238c70SJohn Marino __MPFR_DECLSPEC double        __gmpfr_ceil_exp2     _MPFR_PROTO ((double));
18164a238c70SJohn Marino __MPFR_DECLSPEC unsigned long __gmpfr_isqrt     _MPFR_PROTO ((unsigned long));
18174a238c70SJohn Marino __MPFR_DECLSPEC unsigned long __gmpfr_cuberoot  _MPFR_PROTO ((unsigned long));
18184a238c70SJohn Marino __MPFR_DECLSPEC int       __gmpfr_int_ceil_log2 _MPFR_PROTO ((unsigned long));
18194a238c70SJohn Marino 
18204a238c70SJohn Marino __MPFR_DECLSPEC mpfr_exp_t mpfr_ceil_mul _MPFR_PROTO ((mpfr_exp_t, int, int));
18214a238c70SJohn Marino 
18224a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_exp_2 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
18234a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_exp_3 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
18244a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_powerof2_raw _MPFR_PROTO ((mpfr_srcptr));
18254a238c70SJohn Marino 
18264a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_pow_general _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
18274a238c70SJohn Marino                            mpfr_srcptr, mpfr_rnd_t, int, mpfr_save_expo_t *));
18284a238c70SJohn Marino 
18294a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_setmax _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
18304a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_setmin _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
18314a238c70SJohn Marino 
18324a238c70SJohn Marino __MPFR_DECLSPEC long mpfr_mpn_exp _MPFR_PROTO ((mp_limb_t *, mpfr_exp_t *, int,
18334a238c70SJohn Marino                                                 mpfr_exp_t, size_t));
18344a238c70SJohn Marino 
18354a238c70SJohn Marino #ifdef _MPFR_H_HAVE_FILE
18364a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_fprint_binary _MPFR_PROTO ((FILE *, mpfr_srcptr));
18374a238c70SJohn Marino #endif
18384a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_print_binary _MPFR_PROTO ((mpfr_srcptr));
18394a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_print_mant_binary _MPFR_PROTO ((const char*,
18404a238c70SJohn Marino                                           const mp_limb_t*, mpfr_prec_t));
18414a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_set_str_binary _MPFR_PROTO((mpfr_ptr, const char*));
18424a238c70SJohn Marino 
18434a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_round_raw _MPFR_PROTO ((mp_limb_t *,
18444a238c70SJohn Marino        const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *));
18454a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_round_raw_2 _MPFR_PROTO ((const mp_limb_t *,
18464a238c70SJohn Marino              mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t));
18474a238c70SJohn Marino /* No longer defined (see round_prec.c).
18484a238c70SJohn Marino    Uncomment if it needs to be defined again.
18494a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_round_raw_3 _MPFR_PROTO ((const mp_limb_t *,
18504a238c70SJohn Marino              mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *));
18514a238c70SJohn Marino */
18524a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_round_raw_4 _MPFR_PROTO ((mp_limb_t *,
18534a238c70SJohn Marino        const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t));
18544a238c70SJohn Marino 
18554a238c70SJohn Marino #define mpfr_round_raw2(xp, xn, neg, r, prec) \
18564a238c70SJohn Marino   mpfr_round_raw_2((xp),(xn)*GMP_NUMB_BITS,(neg),(prec),(r))
18574a238c70SJohn Marino 
18584a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_check _MPFR_PROTO ((mpfr_srcptr));
18594a238c70SJohn Marino 
18604a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_sum_sort _MPFR_PROTO ((mpfr_srcptr *const,
18614a238c70SJohn Marino                                                 unsigned long, mpfr_srcptr *));
18624a238c70SJohn Marino 
18634a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_get_cputime _MPFR_PROTO ((void));
18644a238c70SJohn Marino 
18654a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_nexttozero _MPFR_PROTO ((mpfr_ptr));
18664a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_nexttoinf _MPFR_PROTO ((mpfr_ptr));
18674a238c70SJohn Marino 
18684a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_const_pi_internal _MPFR_PROTO ((mpfr_ptr,mpfr_rnd_t));
18694a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_const_log2_internal _MPFR_PROTO((mpfr_ptr,mpfr_rnd_t));
18704a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_const_euler_internal _MPFR_PROTO((mpfr_ptr, mpfr_rnd_t));
18714a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_const_catalan_internal _MPFR_PROTO((mpfr_ptr, mpfr_rnd_t));
18724a238c70SJohn Marino 
18734a238c70SJohn Marino #if 0
18744a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_init_cache _MPFR_PROTO ((mpfr_cache_t,
18754a238c70SJohn Marino                                            int(*)(mpfr_ptr,mpfr_rnd_t)));
18764a238c70SJohn Marino #endif
18774a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_clear_cache _MPFR_PROTO ((mpfr_cache_t));
18784a238c70SJohn Marino __MPFR_DECLSPEC int  mpfr_cache _MPFR_PROTO ((mpfr_ptr, mpfr_cache_t,
18794a238c70SJohn Marino                                               mpfr_rnd_t));
18804a238c70SJohn Marino 
18814a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_mulhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
18824a238c70SJohn Marino                         mpfr_limb_srcptr, mpfr_limb_srcptr, mp_size_t));
18834a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_mullow_n  _MPFR_PROTO ((mpfr_limb_ptr,
18844a238c70SJohn Marino                         mpfr_limb_srcptr, mpfr_limb_srcptr, mp_size_t));
18854a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_sqrhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
18864a238c70SJohn Marino                         mpfr_limb_srcptr, mp_size_t));
18874a238c70SJohn Marino __MPFR_DECLSPEC mp_limb_t mpfr_divhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
18884a238c70SJohn Marino                         mpfr_limb_ptr, mpfr_limb_ptr, mp_size_t));
18894a238c70SJohn Marino 
18904a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_round_p _MPFR_PROTO ((mp_limb_t *, mp_size_t,
18914a238c70SJohn Marino                                                mpfr_exp_t, mpfr_prec_t));
18924a238c70SJohn Marino 
18934a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_dump_mant _MPFR_PROTO ((const mp_limb_t *,
18944a238c70SJohn Marino                                                   mpfr_prec_t, mpfr_prec_t,
18954a238c70SJohn Marino                                                   mpfr_prec_t));
18964a238c70SJohn Marino 
18974a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_round_near_x _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
18984a238c70SJohn Marino                                                     mpfr_uexp_t, int,
18994a238c70SJohn Marino                                                     mpfr_rnd_t));
19004a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_abort_prec_max _MPFR_PROTO ((void))
19014a238c70SJohn Marino        MPFR_NORETURN_ATTR;
19024a238c70SJohn Marino 
19034a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_rand_raw _MPFR_PROTO((mpfr_limb_ptr, gmp_randstate_t,
1904*ab6d115fSJohn Marino                                                 mpfr_prec_t));
19054a238c70SJohn Marino 
19064a238c70SJohn Marino __MPFR_DECLSPEC mpz_t* mpfr_bernoulli_internal _MPFR_PROTO((mpz_t*,
19074a238c70SJohn Marino                                                             unsigned long));
19084a238c70SJohn Marino 
19094a238c70SJohn Marino __MPFR_DECLSPEC int mpfr_sincos_fast _MPFR_PROTO((mpfr_t, mpfr_t,
19104a238c70SJohn Marino                                                   mpfr_srcptr, mpfr_rnd_t));
19114a238c70SJohn Marino 
19124a238c70SJohn Marino __MPFR_DECLSPEC double mpfr_scale2 _MPFR_PROTO((double, int));
19134a238c70SJohn Marino 
19144a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_div_ui2 _MPFR_PROTO((mpfr_ptr, mpfr_srcptr,
19154a238c70SJohn Marino                                                unsigned long int, unsigned long int,
19164a238c70SJohn Marino                                                mpfr_rnd_t));
19174a238c70SJohn Marino 
19184a238c70SJohn Marino __MPFR_DECLSPEC void mpfr_gamma_one_and_two_third _MPFR_PROTO((mpfr_ptr, mpfr_ptr, mpfr_prec_t));
19194a238c70SJohn Marino 
19204a238c70SJohn Marino #if defined (__cplusplus)
19214a238c70SJohn Marino }
19224a238c70SJohn Marino #endif
19234a238c70SJohn Marino 
19244a238c70SJohn Marino #endif
1925