Import Upstream version 0.8.2
[platform/upstream/mpc.git] / src / mpc-impl.h
1 /* mpc-impl.h -- Internal include file for mpc.
2
3 Copyright (C) 2002, 2004, 2005, 2008, 2009 Andreas Enge, Philippe Th\'eveny, Paul Zimmermann
4
5 This file is part of the MPC Library.
6
7 The MPC Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or (at your
10 option) any later version.
11
12 The MPC Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the MPC Library; see the file COPYING.LIB.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 MA 02111-1307, USA. */
21
22 #ifndef __MPC_IMPL_H
23 #define __MPC_IMPL_H
24
25 #include <stdlib.h>
26
27 #include "config.h" /* for MPC_USE_LOGGING */
28
29 #ifndef __MPC_TESTS_H
30 #define __MPC_WITHIN_MPC 1
31 #endif
32
33 #include "mpc.h"
34
35 #define MPC_RE(x) ((x)->re)
36 #define MPC_IM(x) ((x)->im)
37
38 /*
39  * Miscelaneous useful macros
40  */
41
42 #define MPC_MAX(h,i) ((h) > (i) ? (h) : (i))
43
44 /* Safe absolute value (to avoid possible integer overflow) */
45 /* type is the target (unsigned) type (copied from mpfr-impl.h) */
46 #ifdef SAFE_ABS
47 #undef SAFE_ABS
48 #endif
49 #define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
50
51
52 /*
53  * MPFR constants and macros
54  */
55
56 #ifndef BITS_PER_MP_LIMB
57 #define BITS_PER_MP_LIMB mp_bits_per_limb
58 #endif
59
60 #define MPFR_PREC(x) mpfr_get_prec(x)
61 #define MPFR_EXP(x)  mpfr_get_exp(x)
62
63 #define MPFR_SIGNBIT(x) (mpfr_signbit (x) ? -1 : 1)
64 #define MPC_MPFR_SIGN(x) (mpfr_zero_p (x)? 0 : MPFR_SIGNBIT (x))
65    /* should be called MPFR_SIGN, but this is taken in mpfr.h */
66 #define MPFR_CHANGE_SIGN(x) mpfr_neg(x,x,GMP_RNDN)
67 #define MPFR_IS_SINGULAR(x) (mpfr_nan_p(x) || mpfr_inf_p(x) || mpfr_zero_p(x))
68 #define MPFR_COPYSIGN(x,y,z,rnd) (mpfr_nan_p (z) ? \
69    mpfr_setsign (x, y, 0, rnd) : \
70    mpfr_copysign (x, y, z, rnd))
71    /* work around spurious signs in nan */
72 #define MPFR_SWAP(a,b) do { mpfr_srcptr tmp; tmp = a; a = b; b = tmp; } while (0)
73
74
75 /*
76  * MPC macros
77  */
78
79 #define MPC_PREC_RE(x) (MPFR_PREC(MPC_RE(x)))
80 #define MPC_PREC_IM(x) (MPFR_PREC(MPC_IM(x)))
81 #define MPC_MAX_PREC(x) MPC_MAX(MPC_PREC_RE(x), MPC_PREC_IM(x))
82
83 #define INV_RND(r) \
84    (((r) == GMP_RNDU) ? GMP_RNDD : (((r) == GMP_RNDD) ? GMP_RNDU : (r)))
85
86 #define mpc_inf_p(z) (mpfr_inf_p(MPC_RE(z))||mpfr_inf_p(MPC_IM(z)))
87    /* Convention in C99 (G.3): z is regarded as an infinity if at least one of
88       its parts is infinite */
89 #define mpc_zero_p(z) (mpfr_zero_p(MPC_RE(z))&&mpfr_zero_p(MPC_IM(z)))
90    /* Convention in C99 (G.3): z is regarded as a zero if each of its parts is
91       a zero */
92 #define mpc_fin_p(z) (mpfr_number_p(MPC_RE(z))&&mpfr_number_p(MPC_IM(z)))
93    /* Convention in C99 (G.3): z is regarded as finite if both its parts are */
94 #define mpc_nan_p(z) ((mpfr_nan_p(MPC_RE(z)) && !mpfr_inf_p(MPC_IM(z))) || (mpfr_nan_p(MPC_IM(z)) && !mpfr_inf_p(MPC_RE(z))))
95    /* Consider as NaN all other numbers containing at least one NaN */
96
97
98 #define OUT(x)                                                  \
99 do {                                                            \
100   printf (#x "[%lu,%lu]=", (unsigned long int) MPC_PREC_RE (x), \
101       (unsigned long int) MPC_PREC_IM (x));                     \
102   mpc_out_str (stdout, 2, 0, x, MPC_RNDNN);                     \
103   printf ("\n");                                                \
104 } while (0)
105
106 /* C++ iterator on mpfr_rnd_t */
107 #if defined (__cplusplus)
108 inline
109 mpfr_rnd_t & operator++(mpfr_rnd_t &rnd)
110 {
111   return rnd = mpfr_rnd_t(rnd + 1);
112 }
113 #endif
114
115
116 /*
117  * ASSERT macros
118  */
119
120 #define MPC_ASSERT(expr)                                        \
121   do {                                                          \
122     if (!(expr))                                                \
123       {                                                         \
124         fprintf (stderr, "%s:%d: MPC assertion failed: %s\n",   \
125                  __FILE__, __LINE__, #expr);                    \
126         abort();                                                \
127       }                                                         \
128   } while (0)
129
130
131 /*
132  * Constants
133  */
134
135 #ifndef MUL_KARATSUBA_THRESHOLD
136 #define MUL_KARATSUBA_THRESHOLD 23
137 #endif
138
139
140 /*
141  * Define internal functions
142  */
143
144 #if defined (__cplusplus)
145 extern "C" {
146 #endif
147
148 __MPC_DECLSPEC int  mpc_mul_naive     __MPC_PROTO ((mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t));
149 __MPC_DECLSPEC int  mpc_mul_karatsuba __MPC_PROTO ((mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t));
150 __MPC_DECLSPEC char* mpc_alloc_str __MPC_PROTO ((size_t));
151 __MPC_DECLSPEC char* mpc_realloc_str __MPC_PROTO ((char*, size_t, size_t));
152 __MPC_DECLSPEC void mpc_free_str __MPC_PROTO ((char*));
153 __MPC_DECLSPEC unsigned long mpc_ceil_log2 __MPC_PROTO ((unsigned long));
154
155 #if defined (__cplusplus)
156 }
157 #endif
158
159
160 #endif