1 /*************************************************
2 
3 Documentation of symbols defined by Math::MPC
4 
5 NV_IS_DOUBLE             : Automatically defined by Makefile.PL iff
6                            $Config{nvtype} is 'double'.
7 
8 NV_IS_LONG_DOUBLE        : Automatically defined by Makefile.PL iff
9                            $Config{nvtype} is 'long double'.
10 
11 NV_IS_FLOAT128           : Automatically defined by Makefile.PL iff
12                            $Config{nvtype} is __float128
13                            If NV_IS_FLOAT128 is defined we include the
14                            quadmath.h header.
15 
16 MPFR_WANT_FLOAT128       : Defined by Makefile.PL if $have_float128 is
17                            set to a true value. $have_float128 can be set
18                            to a true value by either editing the Makefile.PL
19                            appropriately or by specifying F128=1 in the
20                            Makefile.PL's @ARGV.
21                            The quadmath.h header is included if this symbol
22                            is defined.
23                            NOTE: If MPFR_WANT_FLOAT128 is defined, it is
24                            assumed that the mpfr library was built with
25                            __float128 support - ie was configured with the
26                            '--enable-float128' option.
27                            MPFR_WANT_FLOAT128 must NOT be defined if the
28                            mpfr library has NOT been built with __float128
29                            support.
30                            MPFR_WANT_FLOAT128 does not imply that NV_IS_FLOAT128
31                            has been defined - perhaps we have defined
32                            MPFR_WANT_FLOAT128 solely because we wish to make
33                            use of the Math::Float128-Math::MPFR interface.
34 
35 MPC_CAN_PASS_FLOAT128    : Defined only when both MPFR_WANT_FLOAT128 and
36                            NV_IS_FLOAT128 is defined, and then only if the mpfr
37                            library is at version 4.0.0 or later. (There was no
38                            __float128 support in the mpfr library prior to
39                            4.0.0.)
40                            DANGER: The assumption is that if MPFR_WANT_FLOAT128
41                            is defined then the mpfr library has been built
42                            with __float128 support, which won't be the case if
43                            the mpfr library wasn't configured with
44                            '--enable-float128'.
45                            I haven't yet found a way of managing this - it's
46                            instead left up to the person building Math::MPFR to
47                            NOT define MATH_MPFR_WANT_FLOAT128 unless mpfr WAS
48                            configured with --enable-float128.
49 
50 
51 MATH_MPC_NEED_LONG_LONG_INT
52                          : Defined by Makefile.PL if
53                            $Config{ivsize} >= 8 && $Config{ivtype} is not
54                            'long' && $use_64_bit_int (in the Makefile.PL)
55                            has not been set to -1. This symbol will also be
56                            defined if $use_64_bit_int is set to 1.
57                            The setting of this symbol is taken to imply that
58                            the mpc/mpfr _uj/_sj functions are needed for
59                            converting mpfr integer values to perl integers.
60                            Conversely, if the symbol is not defined, then
61                            the implication is that the _uj/sj functions are
62                            not needed (because the _ui/_si functions, which
63                            are alway available) provide the same
64                            functionality) - and therefore those _uj/_sj
65                            functions are then not made available.
66 
67 _WIN32_BIZARRE_INFNAN    : Defined (on Windows only) when the perl version
68                            (as expressed by $]) is less than 5.022.
69                            These earlier perl versions generally stringified
70                            NaNs as (-)1.#IND and (-)1.#INF.
71 
72 _Complex_I               : Defined by complex.h. Attempts to define _DO_COMPLEX
73                            (see below) will not succeed if _Complex_I is not
74                            defined.
75 
76 _DO_COMPLEX              : Automatically defined if at least one of Math::Complex_C,
77                            Math::Complex_C::L and Math::Complex_C::Q is installed.
78                            complex.h will be included iff _DO_COMPLEX is defined.
79                            Can also be defined in the Makefile.PL by setting
80                            $do_complex_h to 1 - though I can't envisage a situation
81                            where doing so will be advantageous.
82                            (Will be automatically undefined if _Complex_I is not
83                            defined following the inclusion of complex.h.)
84 
85 
86 *************************************************/
87 
88 #include <stdio.h>
89 
90 #ifndef _MSC_VER
91 #include <inttypes.h>
92 #include <limits.h>
93 #ifdef _DO_COMPLEX_H
94 #include <complex.h>
95 #endif
96 #endif
97 
98 /*
99  * In mpfr-4.1.0, the _Float128 type is exposed in mpfr.h if MPFR_WANT_FLOAT128 is defined.
100  * We fall back to defining it to __float128 if the _Float128 type is unknown.
101 */
102 
103 #if defined(MPFR_WANT_FLOAT128) && defined(__GNUC__) && !defined(__FLT128_MAX__) && !defined(_BITS_FLOATN_H)
104 #define _Float128 __float128
105 #endif
106 
107 #include <gmp.h>
108 #include <mpfr.h>
109 #include <mpc.h>
110 
111 #include <float.h>
112 
113 #if defined(MPFR_WANT_FLOAT128) || defined(NV_IS_FLOAT128)
114 #include <quadmath.h>
115 #if defined(NV_IS_FLOAT128) && defined(MPFR_WANT_FLOAT128) && defined(MPFR_VERSION) && MPFR_VERSION >= MPFR_VERSION_NUM(4,0,0)
116 #define MPC_CAN_PASS_FLOAT128
117 #endif
118 #if defined(__MINGW32__) && !defined(__MINGW64__)
119 typedef __float128 float128 __attribute__ ((aligned(32)));
120 #elif defined(__MINGW64__) || (defined(DEBUGGING) && defined(NV_IS_DOUBLE))
121 typedef __float128 float128 __attribute__ ((aligned(8)));
122 #else
123 typedef __float128 float128;
124 #endif
125 #endif
126 
127 #if LDBL_MANT_DIG == 106
128 #define REQUIRED_LDBL_MANT_DIG 2098
129 #else
130 #define REQUIRED_LDBL_MANT_DIG LDBL_MANT_DIG
131 #endif
132 
133 /* complex.h should have defined _Complex_I */
134 #ifndef _Complex_I
135 #undef _DO_COMPLEX_H
136 #endif
137 
138 #ifdef _MSC_VER
139 #pragma warning(disable:4700 4715 4716)
140 #define intmax_t __int64
141 #endif
142 
143 #ifdef OLDPERL
144 #define SvUOK SvIsUV
145 #endif
146 
147 #ifndef Newx
148 #  define Newx(v,n,t) New(0,v,n,t)
149 #endif
150 
151 #ifndef Newxz
152 #  define Newxz(v,n,t) Newz(0,v,n,t)
153 #endif
154 
155 #if MPC_VERSION_MAJOR > 0 || MPC_VERSION_MINOR > 8
156 #define SIN_COS_AVAILABLE 1
157 #endif
158 
159 #define SV_IS_IOK(x) \
160      SvIOK(x)
161 
162 #define SV_IS_POK(x) \
163      SvPOK(x)
164 
165 #define SV_IS_NOK(x) \
166      SvNOK(x)
167 
168 #define NOK_POK_DUALVAR_CHECK \
169         if(SV_IS_NOK(b)) { \
170          nok_pok++; \
171          if(SvIV(get_sv("Math::MPC::NOK_POK", 0))) \
172            warn("Scalar passed to %s is both NV and PV. Using PV (string) value"
173 
174 #define MPC_RE(x) ((x)->re)
175 #define MPC_IM(x) ((x)->im)
176 
177 #define VOID_MPC_SET_X_Y(real_t, imag_t, z, real_value, imag_value, rnd)     \
178    {                                                                     \
179      int _inex_re, _inex_im;                                             \
180      _inex_re = (mpfr_set_ ## real_t) (MPC_RE (z), (real_value), MPC_RND_RE (rnd)); \
181      _inex_im = (mpfr_set_ ## imag_t) (MPC_IM (z), (imag_value), MPC_RND_IM (rnd)); \
182    }
183 
184 #define SV_MPC_SET_X_Y(real_t, imag_t, z, real_value, imag_value, rnd)     \
185   {                                                                     \
186     int _inex_re, _inex_im;                                             \
187     _inex_re = (mpfr_set_ ## real_t) (mpc_realref (z), (real_value), MPC_RND_RE (rnd)); \
188     _inex_im = (mpfr_set_ ## imag_t) (mpc_imagref (z), (imag_value), MPC_RND_IM (rnd)); \
189     return newSViv(MPC_INEX (_inex_re, _inex_im));                               \
190   }
191 
192