1*d30dc8cbSJohn Marino /* mpc-impl.h -- Internal include file for mpc. 2*d30dc8cbSJohn Marino 3*d30dc8cbSJohn Marino Copyright (C) 2002, 2004, 2005, 2008, 2009, 2010, 2011, 2012 INRIA 4*d30dc8cbSJohn Marino 5*d30dc8cbSJohn Marino This file is part of GNU MPC. 6*d30dc8cbSJohn Marino 7*d30dc8cbSJohn Marino GNU MPC is free software; you can redistribute it and/or modify it under 8*d30dc8cbSJohn Marino the terms of the GNU Lesser General Public License as published by the 9*d30dc8cbSJohn Marino Free Software Foundation; either version 3 of the License, or (at your 10*d30dc8cbSJohn Marino option) any later version. 11*d30dc8cbSJohn Marino 12*d30dc8cbSJohn Marino GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY 13*d30dc8cbSJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14*d30dc8cbSJohn Marino FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15*d30dc8cbSJohn Marino more details. 16*d30dc8cbSJohn Marino 17*d30dc8cbSJohn Marino You should have received a copy of the GNU Lesser General Public License 18*d30dc8cbSJohn Marino along with this program. If not, see http://www.gnu.org/licenses/ . 19*d30dc8cbSJohn Marino */ 20*d30dc8cbSJohn Marino 21*d30dc8cbSJohn Marino #ifndef __MPC_IMPL_H 22*d30dc8cbSJohn Marino #define __MPC_IMPL_H 23*d30dc8cbSJohn Marino #define __MPC_LIBRARY_BUILD 24*d30dc8cbSJohn Marino /* to indicate we are inside the library build */ 25*d30dc8cbSJohn Marino 26*d30dc8cbSJohn Marino #include "config.h" 27*d30dc8cbSJohn Marino #ifdef HAVE_STDLIB_H 28*d30dc8cbSJohn Marino #include <stdlib.h> 29*d30dc8cbSJohn Marino #endif 30*d30dc8cbSJohn Marino #include "mpc.h" 31*d30dc8cbSJohn Marino 32*d30dc8cbSJohn Marino /* 33*d30dc8cbSJohn Marino * Miscellaneous useful macros 34*d30dc8cbSJohn Marino */ 35*d30dc8cbSJohn Marino 36*d30dc8cbSJohn Marino #define MPC_MIN(h,i) ((h) < (i) ? (h) : (i)) 37*d30dc8cbSJohn Marino #define MPC_MAX(h,i) ((h) > (i) ? (h) : (i)) 38*d30dc8cbSJohn Marino 39*d30dc8cbSJohn Marino /* Safe absolute value (to avoid possible integer overflow) */ 40*d30dc8cbSJohn Marino /* type is the target (unsigned) type (copied from mpfr-impl.h) */ 41*d30dc8cbSJohn Marino #ifdef SAFE_ABS 42*d30dc8cbSJohn Marino #undef SAFE_ABS 43*d30dc8cbSJohn Marino #endif 44*d30dc8cbSJohn Marino #define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x)) 45*d30dc8cbSJohn Marino 46*d30dc8cbSJohn Marino 47*d30dc8cbSJohn Marino /* 48*d30dc8cbSJohn Marino * MPFR constants and macros 49*d30dc8cbSJohn Marino */ 50*d30dc8cbSJohn Marino 51*d30dc8cbSJohn Marino #ifndef BITS_PER_MP_LIMB 52*d30dc8cbSJohn Marino #define BITS_PER_MP_LIMB mp_bits_per_limb 53*d30dc8cbSJohn Marino #endif 54*d30dc8cbSJohn Marino 55*d30dc8cbSJohn Marino #define MPFR_SIGNBIT(x) (mpfr_signbit (x) ? -1 : 1) 56*d30dc8cbSJohn Marino #define MPC_MPFR_SIGN(x) (mpfr_zero_p (x) ? 0 : MPFR_SIGNBIT (x)) 57*d30dc8cbSJohn Marino /* should be called MPFR_SIGN, but this is taken in mpfr.h */ 58*d30dc8cbSJohn Marino #define MPFR_CHANGE_SIGN(x) mpfr_neg(x,x,GMP_RNDN) 59*d30dc8cbSJohn Marino #define MPFR_COPYSIGN(x,y,z,rnd) (mpfr_nan_p (z) ? \ 60*d30dc8cbSJohn Marino mpfr_setsign (x, y, 0, rnd) : \ 61*d30dc8cbSJohn Marino mpfr_copysign (x, y, z, rnd)) 62*d30dc8cbSJohn Marino /* work around spurious signs in nan */ 63*d30dc8cbSJohn Marino #define MPFR_ADD_ONE_ULP(x) mpfr_add_one_ulp (x, GMP_RNDN) 64*d30dc8cbSJohn Marino #define MPFR_SUB_ONE_ULP(x) mpfr_sub_one_ulp (x, GMP_RNDN) 65*d30dc8cbSJohn Marino /* drop unused rounding mode from macroes */ 66*d30dc8cbSJohn Marino #define MPFR_SWAP(a,b) do { mpfr_srcptr tmp; tmp = a; a = b; b = tmp; } while (0) 67*d30dc8cbSJohn Marino 68*d30dc8cbSJohn Marino 69*d30dc8cbSJohn Marino /* 70*d30dc8cbSJohn Marino * Macro implementing rounding away from zero, to ease compatibility with 71*d30dc8cbSJohn Marino * mpfr < 3. f is the complete function call with a rounding mode of 72*d30dc8cbSJohn Marino * MPFR_RNDA, rop the name of the variable containing the result; it is 73*d30dc8cbSJohn Marino * already contained in f, but needs to be repeated so that the macro can 74*d30dc8cbSJohn Marino * modify the variable. 75*d30dc8cbSJohn Marino * Usage: replace each call to a function such as 76*d30dc8cbSJohn Marino * mpfr_add (rop, a, b, MPFR_RNDA) 77*d30dc8cbSJohn Marino * by 78*d30dc8cbSJohn Marino * ROUND_AWAY (mpfr_add (rop, a, b, MPFR_RNDA), rop) 79*d30dc8cbSJohn Marino */ 80*d30dc8cbSJohn Marino #if MPFR_VERSION_MAJOR < 3 81*d30dc8cbSJohn Marino /* round towards zero, add 1 ulp if not exact */ 82*d30dc8cbSJohn Marino #define MPFR_RNDA GMP_RNDZ 83*d30dc8cbSJohn Marino #define ROUND_AWAY(f,rop) \ 84*d30dc8cbSJohn Marino ((f) ? MPFR_ADD_ONE_ULP (rop), MPFR_SIGNBIT (rop) : 0) 85*d30dc8cbSJohn Marino #else 86*d30dc8cbSJohn Marino #define ROUND_AWAY(f,rop) \ 87*d30dc8cbSJohn Marino (f) 88*d30dc8cbSJohn Marino #endif /* mpfr < 3 */ 89*d30dc8cbSJohn Marino 90*d30dc8cbSJohn Marino #if MPFR_VERSION_MAJOR < 3 91*d30dc8cbSJohn Marino /* declare missing functions, defined in get_version.c */ 92*d30dc8cbSJohn Marino __MPC_DECLSPEC void mpfr_set_zero (mpfr_ptr, int); 93*d30dc8cbSJohn Marino __MPC_DECLSPEC int mpfr_regular_p (mpfr_srcptr); 94*d30dc8cbSJohn Marino #endif /* mpfr < 3 */ 95*d30dc8cbSJohn Marino 96*d30dc8cbSJohn Marino 97*d30dc8cbSJohn Marino /* 98*d30dc8cbSJohn Marino * MPC macros 99*d30dc8cbSJohn Marino */ 100*d30dc8cbSJohn Marino 101*d30dc8cbSJohn Marino #define MPC_PREC_RE(x) (mpfr_get_prec(mpc_realref(x))) 102*d30dc8cbSJohn Marino #define MPC_PREC_IM(x) (mpfr_get_prec(mpc_imagref(x))) 103*d30dc8cbSJohn Marino #define MPC_MAX_PREC(x) MPC_MAX(MPC_PREC_RE(x), MPC_PREC_IM(x)) 104*d30dc8cbSJohn Marino 105*d30dc8cbSJohn Marino #define INV_RND(r) \ 106*d30dc8cbSJohn Marino (((r) == GMP_RNDU) ? GMP_RNDD : (((r) == GMP_RNDD) ? GMP_RNDU : (r))) 107*d30dc8cbSJohn Marino 108*d30dc8cbSJohn Marino #define mpc_inf_p(z) (mpfr_inf_p(mpc_realref(z))||mpfr_inf_p(mpc_imagref(z))) 109*d30dc8cbSJohn Marino /* Convention in C99 (G.3): z is regarded as an infinity if at least one of 110*d30dc8cbSJohn Marino its parts is infinite */ 111*d30dc8cbSJohn Marino #define mpc_zero_p(z) (mpfr_zero_p(mpc_realref(z))&&mpfr_zero_p(mpc_imagref(z))) 112*d30dc8cbSJohn Marino /* Convention in C99 (G.3): z is regarded as a zero if each of its parts is 113*d30dc8cbSJohn Marino a zero */ 114*d30dc8cbSJohn Marino #define mpc_fin_p(z) (mpfr_number_p(mpc_realref(z))&&mpfr_number_p(mpc_imagref(z))) 115*d30dc8cbSJohn Marino /* Convention in C99 (G.3): z is regarded as finite if both its parts are */ 116*d30dc8cbSJohn Marino #define mpc_nan_p(z) ((mpfr_nan_p(mpc_realref(z)) && !mpfr_inf_p(mpc_imagref(z))) || (mpfr_nan_p(mpc_imagref(z)) && !mpfr_inf_p(mpc_realref(z)))) 117*d30dc8cbSJohn Marino /* Consider as NaN all other numbers containing at least one NaN */ 118*d30dc8cbSJohn Marino 119*d30dc8cbSJohn Marino 120*d30dc8cbSJohn Marino /* 121*d30dc8cbSJohn Marino * ASSERT macros 122*d30dc8cbSJohn Marino */ 123*d30dc8cbSJohn Marino 124*d30dc8cbSJohn Marino #ifdef NDEBUG 125*d30dc8cbSJohn Marino #define MPC_ASSERT(expr) \ 126*d30dc8cbSJohn Marino do { \ 127*d30dc8cbSJohn Marino } while (0) 128*d30dc8cbSJohn Marino #else 129*d30dc8cbSJohn Marino #define MPC_ASSERT(expr) \ 130*d30dc8cbSJohn Marino do { \ 131*d30dc8cbSJohn Marino if (!(expr)) \ 132*d30dc8cbSJohn Marino { \ 133*d30dc8cbSJohn Marino fprintf (stderr, "%s:%d: MPC assertion failed: %s\n", \ 134*d30dc8cbSJohn Marino __FILE__, __LINE__, #expr); \ 135*d30dc8cbSJohn Marino abort(); \ 136*d30dc8cbSJohn Marino } \ 137*d30dc8cbSJohn Marino } while (0) 138*d30dc8cbSJohn Marino #endif 139*d30dc8cbSJohn Marino 140*d30dc8cbSJohn Marino 141*d30dc8cbSJohn Marino /* 142*d30dc8cbSJohn Marino * Debug macros 143*d30dc8cbSJohn Marino */ 144*d30dc8cbSJohn Marino 145*d30dc8cbSJohn Marino #define MPC_OUT(x) \ 146*d30dc8cbSJohn Marino do { \ 147*d30dc8cbSJohn Marino printf (#x "[%lu,%lu]=", (unsigned long int) MPC_PREC_RE (x), \ 148*d30dc8cbSJohn Marino (unsigned long int) MPC_PREC_IM (x)); \ 149*d30dc8cbSJohn Marino mpc_out_str (stdout, 2, 0, x, MPC_RNDNN); \ 150*d30dc8cbSJohn Marino printf ("\n"); \ 151*d30dc8cbSJohn Marino } while (0) 152*d30dc8cbSJohn Marino 153*d30dc8cbSJohn Marino #define MPFR_OUT(x) \ 154*d30dc8cbSJohn Marino do { \ 155*d30dc8cbSJohn Marino printf (#x "[%lu]=", (unsigned long int) mpfr_get_prec (x)); \ 156*d30dc8cbSJohn Marino mpfr_out_str (stdout, 2, 0, x, GMP_RNDN); \ 157*d30dc8cbSJohn Marino printf ("\n"); \ 158*d30dc8cbSJohn Marino } while (0) 159*d30dc8cbSJohn Marino 160*d30dc8cbSJohn Marino 161*d30dc8cbSJohn Marino /* 162*d30dc8cbSJohn Marino * Constants 163*d30dc8cbSJohn Marino */ 164*d30dc8cbSJohn Marino 165*d30dc8cbSJohn Marino #ifndef MUL_KARATSUBA_THRESHOLD 166*d30dc8cbSJohn Marino #define MUL_KARATSUBA_THRESHOLD 23 167*d30dc8cbSJohn Marino #endif 168*d30dc8cbSJohn Marino 169*d30dc8cbSJohn Marino 170*d30dc8cbSJohn Marino /* 171*d30dc8cbSJohn Marino * Define internal functions 172*d30dc8cbSJohn Marino */ 173*d30dc8cbSJohn Marino 174*d30dc8cbSJohn Marino #if defined (__cplusplus) 175*d30dc8cbSJohn Marino extern "C" { 176*d30dc8cbSJohn Marino #endif 177*d30dc8cbSJohn Marino 178*d30dc8cbSJohn Marino 179*d30dc8cbSJohn Marino __MPC_DECLSPEC int mpc_mul_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 180*d30dc8cbSJohn Marino __MPC_DECLSPEC int mpc_mul_karatsuba (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 181*d30dc8cbSJohn Marino __MPC_DECLSPEC int mpc_fma_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 182*d30dc8cbSJohn Marino __MPC_DECLSPEC int mpc_pow_usi (mpc_ptr, mpc_srcptr, unsigned long, int, mpc_rnd_t); 183*d30dc8cbSJohn Marino __MPC_DECLSPEC char* mpc_alloc_str (size_t); 184*d30dc8cbSJohn Marino __MPC_DECLSPEC char* mpc_realloc_str (char*, size_t, size_t); 185*d30dc8cbSJohn Marino __MPC_DECLSPEC void mpc_free_str (char*); 186*d30dc8cbSJohn Marino __MPC_DECLSPEC mpfr_prec_t mpc_ceil_log2 (mpfr_prec_t); 187*d30dc8cbSJohn Marino __MPC_DECLSPEC int set_pi_over_2 (mpfr_ptr, int, mpfr_rnd_t); 188*d30dc8cbSJohn Marino 189*d30dc8cbSJohn Marino #if defined (__cplusplus) 190*d30dc8cbSJohn Marino } 191*d30dc8cbSJohn Marino #endif 192*d30dc8cbSJohn Marino 193*d30dc8cbSJohn Marino 194*d30dc8cbSJohn Marino #endif 195