1/* mpc-impl.h -- Internal include file for mpc.
2
3Copyright (C) 2002, 2004, 2005, 2008, 2009, 2010, 2011, 2012, 2020, 2022 INRIA
4
5This file is part of GNU MPC.
6
7GNU MPC is free software; you can redistribute it and/or modify it under
8the terms of the GNU Lesser General Public License as published by the
9Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along 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)                                              \
128do {                                                            \
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)                                             \
136do {                                                            \
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)                                           \
143do {                                                            \
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)                                         \
152do {                                                            \
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)
175extern "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