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