xref: /dflybsd-src/contrib/mpc/src/mpc-impl.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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