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