LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - cmathmodule.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 407 0.0 %
Date: 2012-12-17 Functions: 0 43 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Complex math module */
       2             : 
       3             : /* much code borrowed from mathmodule.c */
       4             : 
       5             : #include "Python.h"
       6             : #include "_math.h"
       7             : /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from
       8             :    float.h.  We assume that FLT_RADIX is either 2 or 16. */
       9             : #include <float.h>
      10             : 
      11             : #if (FLT_RADIX != 2 && FLT_RADIX != 16)
      12             : #error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16"
      13             : #endif
      14             : 
      15             : #ifndef M_LN2
      16             : #define M_LN2 (0.6931471805599453094) /* natural log of 2 */
      17             : #endif
      18             : 
      19             : #ifndef M_LN10
      20             : #define M_LN10 (2.302585092994045684) /* natural log of 10 */
      21             : #endif
      22             : 
      23             : /*
      24             :    CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log,
      25             :    inverse trig and inverse hyperbolic trig functions.  Its log is used in the
      26             :    evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unnecessary
      27             :    overflow.
      28             :  */
      29             : 
      30             : #define CM_LARGE_DOUBLE (DBL_MAX/4.)
      31             : #define CM_SQRT_LARGE_DOUBLE (sqrt(CM_LARGE_DOUBLE))
      32             : #define CM_LOG_LARGE_DOUBLE (log(CM_LARGE_DOUBLE))
      33             : #define CM_SQRT_DBL_MIN (sqrt(DBL_MIN))
      34             : 
      35             : /*
      36             :    CM_SCALE_UP is an odd integer chosen such that multiplication by
      37             :    2**CM_SCALE_UP is sufficient to turn a subnormal into a normal.
      38             :    CM_SCALE_DOWN is (-(CM_SCALE_UP+1)/2).  These scalings are used to compute
      39             :    square roots accurately when the real and imaginary parts of the argument
      40             :    are subnormal.
      41             : */
      42             : 
      43             : #if FLT_RADIX==2
      44             : #define CM_SCALE_UP (2*(DBL_MANT_DIG/2) + 1)
      45             : #elif FLT_RADIX==16
      46             : #define CM_SCALE_UP (4*DBL_MANT_DIG+1)
      47             : #endif
      48             : #define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2)
      49             : 
      50             : /* forward declarations */
      51             : static Py_complex c_asinh(Py_complex);
      52             : static Py_complex c_atanh(Py_complex);
      53             : static Py_complex c_cosh(Py_complex);
      54             : static Py_complex c_sinh(Py_complex);
      55             : static Py_complex c_sqrt(Py_complex);
      56             : static Py_complex c_tanh(Py_complex);
      57             : static PyObject * math_error(void);
      58             : 
      59             : /* Code to deal with special values (infinities, NaNs, etc.). */
      60             : 
      61             : /* special_type takes a double and returns an integer code indicating
      62             :    the type of the double as follows:
      63             : */
      64             : 
      65             : enum special_types {
      66             :     ST_NINF,            /* 0, negative infinity */
      67             :     ST_NEG,             /* 1, negative finite number (nonzero) */
      68             :     ST_NZERO,           /* 2, -0. */
      69             :     ST_PZERO,           /* 3, +0. */
      70             :     ST_POS,             /* 4, positive finite number (nonzero) */
      71             :     ST_PINF,            /* 5, positive infinity */
      72             :     ST_NAN              /* 6, Not a Number */
      73             : };
      74             : 
      75             : static enum special_types
      76           0 : special_type(double d)
      77             : {
      78           0 :     if (Py_IS_FINITE(d)) {
      79           0 :         if (d != 0) {
      80           0 :             if (copysign(1., d) == 1.)
      81           0 :                 return ST_POS;
      82             :             else
      83           0 :                 return ST_NEG;
      84             :         }
      85             :         else {
      86           0 :             if (copysign(1., d) == 1.)
      87           0 :                 return ST_PZERO;
      88             :             else
      89           0 :                 return ST_NZERO;
      90             :         }
      91             :     }
      92           0 :     if (Py_IS_NAN(d))
      93           0 :         return ST_NAN;
      94           0 :     if (copysign(1., d) == 1.)
      95           0 :         return ST_PINF;
      96             :     else
      97           0 :         return ST_NINF;
      98             : }
      99             : 
     100             : #define SPECIAL_VALUE(z, table)                                         \
     101             :     if (!Py_IS_FINITE((z).real) || !Py_IS_FINITE((z).imag)) {           \
     102             :         errno = 0;                                              \
     103             :         return table[special_type((z).real)]                            \
     104             :                     [special_type((z).imag)];                           \
     105             :     }
     106             : 
     107             : #define P Py_MATH_PI
     108             : #define P14 0.25*Py_MATH_PI
     109             : #define P12 0.5*Py_MATH_PI
     110             : #define P34 0.75*Py_MATH_PI
     111             : #define INF Py_HUGE_VAL
     112             : #define N Py_NAN
     113             : #define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
     114             : 
     115             : /* First, the C functions that do the real work.  Each of the c_*
     116             :    functions computes and returns the C99 Annex G recommended result
     117             :    and also sets errno as follows: errno = 0 if no floating-point
     118             :    exception is associated with the result; errno = EDOM if C99 Annex
     119             :    G recommends raising divide-by-zero or invalid for this result; and
     120             :    errno = ERANGE where the overflow floating-point signal should be
     121             :    raised.
     122             : */
     123             : 
     124             : static Py_complex acos_special_values[7][7];
     125             : 
     126             : static Py_complex
     127           0 : c_acos(Py_complex z)
     128             : {
     129             :     Py_complex s1, s2, r;
     130             : 
     131           0 :     SPECIAL_VALUE(z, acos_special_values);
     132             : 
     133           0 :     if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
     134             :         /* avoid unnecessary overflow for large arguments */
     135           0 :         r.real = atan2(fabs(z.imag), z.real);
     136             :         /* split into cases to make sure that the branch cut has the
     137             :            correct continuity on systems with unsigned zeros */
     138           0 :         if (z.real < 0.) {
     139           0 :             r.imag = -copysign(log(hypot(z.real/2., z.imag/2.)) +
     140             :                                M_LN2*2., z.imag);
     141             :         } else {
     142           0 :             r.imag = copysign(log(hypot(z.real/2., z.imag/2.)) +
     143           0 :                               M_LN2*2., -z.imag);
     144             :         }
     145             :     } else {
     146           0 :         s1.real = 1.-z.real;
     147           0 :         s1.imag = -z.imag;
     148           0 :         s1 = c_sqrt(s1);
     149           0 :         s2.real = 1.+z.real;
     150           0 :         s2.imag = z.imag;
     151           0 :         s2 = c_sqrt(s2);
     152           0 :         r.real = 2.*atan2(s1.real, s2.real);
     153           0 :         r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real);
     154             :     }
     155           0 :     errno = 0;
     156           0 :     return r;
     157             : }
     158             : 
     159             : PyDoc_STRVAR(c_acos_doc,
     160             : "acos(x)\n"
     161             : "\n"
     162             : "Return the arc cosine of x.");
     163             : 
     164             : 
     165             : static Py_complex acosh_special_values[7][7];
     166             : 
     167             : static Py_complex
     168           0 : c_acosh(Py_complex z)
     169             : {
     170             :     Py_complex s1, s2, r;
     171             : 
     172           0 :     SPECIAL_VALUE(z, acosh_special_values);
     173             : 
     174           0 :     if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
     175             :         /* avoid unnecessary overflow for large arguments */
     176           0 :         r.real = log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.;
     177           0 :         r.imag = atan2(z.imag, z.real);
     178             :     } else {
     179           0 :         s1.real = z.real - 1.;
     180           0 :         s1.imag = z.imag;
     181           0 :         s1 = c_sqrt(s1);
     182           0 :         s2.real = z.real + 1.;
     183           0 :         s2.imag = z.imag;
     184           0 :         s2 = c_sqrt(s2);
     185           0 :         r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag);
     186           0 :         r.imag = 2.*atan2(s1.imag, s2.real);
     187             :     }
     188           0 :     errno = 0;
     189           0 :     return r;
     190             : }
     191             : 
     192             : PyDoc_STRVAR(c_acosh_doc,
     193             : "acosh(x)\n"
     194             : "\n"
     195             : "Return the hyperbolic arccosine of x.");
     196             : 
     197             : 
     198             : static Py_complex
     199           0 : c_asin(Py_complex z)
     200             : {
     201             :     /* asin(z) = -i asinh(iz) */
     202             :     Py_complex s, r;
     203           0 :     s.real = -z.imag;
     204           0 :     s.imag = z.real;
     205           0 :     s = c_asinh(s);
     206           0 :     r.real = s.imag;
     207           0 :     r.imag = -s.real;
     208           0 :     return r;
     209             : }
     210             : 
     211             : PyDoc_STRVAR(c_asin_doc,
     212             : "asin(x)\n"
     213             : "\n"
     214             : "Return the arc sine of x.");
     215             : 
     216             : 
     217             : static Py_complex asinh_special_values[7][7];
     218             : 
     219             : static Py_complex
     220           0 : c_asinh(Py_complex z)
     221             : {
     222             :     Py_complex s1, s2, r;
     223             : 
     224           0 :     SPECIAL_VALUE(z, asinh_special_values);
     225             : 
     226           0 :     if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
     227           0 :         if (z.imag >= 0.) {
     228           0 :             r.real = copysign(log(hypot(z.real/2., z.imag/2.)) +
     229             :                               M_LN2*2., z.real);
     230             :         } else {
     231           0 :             r.real = -copysign(log(hypot(z.real/2., z.imag/2.)) +
     232           0 :                                M_LN2*2., -z.real);
     233             :         }
     234           0 :         r.imag = atan2(z.imag, fabs(z.real));
     235             :     } else {
     236           0 :         s1.real = 1.+z.imag;
     237           0 :         s1.imag = -z.real;
     238           0 :         s1 = c_sqrt(s1);
     239           0 :         s2.real = 1.-z.imag;
     240           0 :         s2.imag = z.real;
     241           0 :         s2 = c_sqrt(s2);
     242           0 :         r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag);
     243           0 :         r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag);
     244             :     }
     245           0 :     errno = 0;
     246           0 :     return r;
     247             : }
     248             : 
     249             : PyDoc_STRVAR(c_asinh_doc,
     250             : "asinh(x)\n"
     251             : "\n"
     252             : "Return the hyperbolic arc sine of x.");
     253             : 
     254             : 
     255             : static Py_complex
     256           0 : c_atan(Py_complex z)
     257             : {
     258             :     /* atan(z) = -i atanh(iz) */
     259             :     Py_complex s, r;
     260           0 :     s.real = -z.imag;
     261           0 :     s.imag = z.real;
     262           0 :     s = c_atanh(s);
     263           0 :     r.real = s.imag;
     264           0 :     r.imag = -s.real;
     265           0 :     return r;
     266             : }
     267             : 
     268             : /* Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't follow
     269             :    C99 for atan2(0., 0.). */
     270             : static double
     271           0 : c_atan2(Py_complex z)
     272             : {
     273           0 :     if (Py_IS_NAN(z.real) || Py_IS_NAN(z.imag))
     274           0 :         return Py_NAN;
     275           0 :     if (Py_IS_INFINITY(z.imag)) {
     276           0 :         if (Py_IS_INFINITY(z.real)) {
     277           0 :             if (copysign(1., z.real) == 1.)
     278             :                 /* atan2(+-inf, +inf) == +-pi/4 */
     279           0 :                 return copysign(0.25*Py_MATH_PI, z.imag);
     280             :             else
     281             :                 /* atan2(+-inf, -inf) == +-pi*3/4 */
     282           0 :                 return copysign(0.75*Py_MATH_PI, z.imag);
     283             :         }
     284             :         /* atan2(+-inf, x) == +-pi/2 for finite x */
     285           0 :         return copysign(0.5*Py_MATH_PI, z.imag);
     286             :     }
     287           0 :     if (Py_IS_INFINITY(z.real) || z.imag == 0.) {
     288           0 :         if (copysign(1., z.real) == 1.)
     289             :             /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */
     290           0 :             return copysign(0., z.imag);
     291             :         else
     292             :             /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */
     293           0 :             return copysign(Py_MATH_PI, z.imag);
     294             :     }
     295           0 :     return atan2(z.imag, z.real);
     296             : }
     297             : 
     298             : PyDoc_STRVAR(c_atan_doc,
     299             : "atan(x)\n"
     300             : "\n"
     301             : "Return the arc tangent of x.");
     302             : 
     303             : 
     304             : static Py_complex atanh_special_values[7][7];
     305             : 
     306             : static Py_complex
     307           0 : c_atanh(Py_complex z)
     308             : {
     309             :     Py_complex r;
     310             :     double ay, h;
     311             : 
     312           0 :     SPECIAL_VALUE(z, atanh_special_values);
     313             : 
     314             :     /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */
     315           0 :     if (z.real < 0.) {
     316           0 :         return c_neg(c_atanh(c_neg(z)));
     317             :     }
     318             : 
     319           0 :     ay = fabs(z.imag);
     320           0 :     if (z.real > CM_SQRT_LARGE_DOUBLE || ay > CM_SQRT_LARGE_DOUBLE) {
     321             :         /*
     322             :            if abs(z) is large then we use the approximation
     323             :            atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign
     324             :            of z.imag)
     325             :         */
     326           0 :         h = hypot(z.real/2., z.imag/2.);  /* safe from overflow */
     327           0 :         r.real = z.real/4./h/h;
     328             :         /* the two negations in the next line cancel each other out
     329             :            except when working with unsigned zeros: they're there to
     330             :            ensure that the branch cut has the correct continuity on
     331             :            systems that don't support signed zeros */
     332           0 :         r.imag = -copysign(Py_MATH_PI/2., -z.imag);
     333           0 :         errno = 0;
     334           0 :     } else if (z.real == 1. && ay < CM_SQRT_DBL_MIN) {
     335             :         /* C99 standard says:  atanh(1+/-0.) should be inf +/- 0i */
     336           0 :         if (ay == 0.) {
     337           0 :             r.real = INF;
     338           0 :             r.imag = z.imag;
     339           0 :             errno = EDOM;
     340             :         } else {
     341           0 :             r.real = -log(sqrt(ay)/sqrt(hypot(ay, 2.)));
     342           0 :             r.imag = copysign(atan2(2., -ay)/2, z.imag);
     343           0 :             errno = 0;
     344             :         }
     345             :     } else {
     346           0 :         r.real = m_log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.;
     347           0 :         r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.;
     348           0 :         errno = 0;
     349             :     }
     350           0 :     return r;
     351             : }
     352             : 
     353             : PyDoc_STRVAR(c_atanh_doc,
     354             : "atanh(x)\n"
     355             : "\n"
     356             : "Return the hyperbolic arc tangent of x.");
     357             : 
     358             : 
     359             : static Py_complex
     360           0 : c_cos(Py_complex z)
     361             : {
     362             :     /* cos(z) = cosh(iz) */
     363             :     Py_complex r;
     364           0 :     r.real = -z.imag;
     365           0 :     r.imag = z.real;
     366           0 :     r = c_cosh(r);
     367           0 :     return r;
     368             : }
     369             : 
     370             : PyDoc_STRVAR(c_cos_doc,
     371             : "cos(x)\n"
     372             : "\n"
     373             : "Return the cosine of x.");
     374             : 
     375             : 
     376             : /* cosh(infinity + i*y) needs to be dealt with specially */
     377             : static Py_complex cosh_special_values[7][7];
     378             : 
     379             : static Py_complex
     380           0 : c_cosh(Py_complex z)
     381             : {
     382             :     Py_complex r;
     383             :     double x_minus_one;
     384             : 
     385             :     /* special treatment for cosh(+/-inf + iy) if y is not a NaN */
     386           0 :     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
     387           0 :         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) &&
     388           0 :             (z.imag != 0.)) {
     389           0 :             if (z.real > 0) {
     390           0 :                 r.real = copysign(INF, cos(z.imag));
     391           0 :                 r.imag = copysign(INF, sin(z.imag));
     392             :             }
     393             :             else {
     394           0 :                 r.real = copysign(INF, cos(z.imag));
     395           0 :                 r.imag = -copysign(INF, sin(z.imag));
     396             :             }
     397             :         }
     398             :         else {
     399           0 :             r = cosh_special_values[special_type(z.real)]
     400           0 :                                    [special_type(z.imag)];
     401             :         }
     402             :         /* need to set errno = EDOM if y is +/- infinity and x is not
     403             :            a NaN */
     404           0 :         if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real))
     405           0 :             errno = EDOM;
     406             :         else
     407           0 :             errno = 0;
     408           0 :         return r;
     409             :     }
     410             : 
     411           0 :     if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
     412             :         /* deal correctly with cases where cosh(z.real) overflows but
     413             :            cosh(z) does not. */
     414           0 :         x_minus_one = z.real - copysign(1., z.real);
     415           0 :         r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E;
     416           0 :         r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E;
     417             :     } else {
     418           0 :         r.real = cos(z.imag) * cosh(z.real);
     419           0 :         r.imag = sin(z.imag) * sinh(z.real);
     420             :     }
     421             :     /* detect overflow, and set errno accordingly */
     422           0 :     if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
     423           0 :         errno = ERANGE;
     424             :     else
     425           0 :         errno = 0;
     426           0 :     return r;
     427             : }
     428             : 
     429             : PyDoc_STRVAR(c_cosh_doc,
     430             : "cosh(x)\n"
     431             : "\n"
     432             : "Return the hyperbolic cosine of x.");
     433             : 
     434             : 
     435             : /* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for
     436             :    finite y */
     437             : static Py_complex exp_special_values[7][7];
     438             : 
     439             : static Py_complex
     440           0 : c_exp(Py_complex z)
     441             : {
     442             :     Py_complex r;
     443             :     double l;
     444             : 
     445           0 :     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
     446           0 :         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
     447           0 :             && (z.imag != 0.)) {
     448           0 :             if (z.real > 0) {
     449           0 :                 r.real = copysign(INF, cos(z.imag));
     450           0 :                 r.imag = copysign(INF, sin(z.imag));
     451             :             }
     452             :             else {
     453           0 :                 r.real = copysign(0., cos(z.imag));
     454           0 :                 r.imag = copysign(0., sin(z.imag));
     455             :             }
     456             :         }
     457             :         else {
     458           0 :             r = exp_special_values[special_type(z.real)]
     459           0 :                                   [special_type(z.imag)];
     460             :         }
     461             :         /* need to set errno = EDOM if y is +/- infinity and x is not
     462             :            a NaN and not -infinity */
     463           0 :         if (Py_IS_INFINITY(z.imag) &&
     464           0 :             (Py_IS_FINITE(z.real) ||
     465           0 :              (Py_IS_INFINITY(z.real) && z.real > 0)))
     466           0 :             errno = EDOM;
     467             :         else
     468           0 :             errno = 0;
     469           0 :         return r;
     470             :     }
     471             : 
     472           0 :     if (z.real > CM_LOG_LARGE_DOUBLE) {
     473           0 :         l = exp(z.real-1.);
     474           0 :         r.real = l*cos(z.imag)*Py_MATH_E;
     475           0 :         r.imag = l*sin(z.imag)*Py_MATH_E;
     476             :     } else {
     477           0 :         l = exp(z.real);
     478           0 :         r.real = l*cos(z.imag);
     479           0 :         r.imag = l*sin(z.imag);
     480             :     }
     481             :     /* detect overflow, and set errno accordingly */
     482           0 :     if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
     483           0 :         errno = ERANGE;
     484             :     else
     485           0 :         errno = 0;
     486           0 :     return r;
     487             : }
     488             : 
     489             : PyDoc_STRVAR(c_exp_doc,
     490             : "exp(x)\n"
     491             : "\n"
     492             : "Return the exponential value e**x.");
     493             : 
     494             : 
     495             : static Py_complex log_special_values[7][7];
     496             : 
     497             : static Py_complex
     498           0 : c_log(Py_complex z)
     499             : {
     500             :     /*
     501             :        The usual formula for the real part is log(hypot(z.real, z.imag)).
     502             :        There are four situations where this formula is potentially
     503             :        problematic:
     504             : 
     505             :        (1) the absolute value of z is subnormal.  Then hypot is subnormal,
     506             :        so has fewer than the usual number of bits of accuracy, hence may
     507             :        have large relative error.  This then gives a large absolute error
     508             :        in the log.  This can be solved by rescaling z by a suitable power
     509             :        of 2.
     510             : 
     511             :        (2) the absolute value of z is greater than DBL_MAX (e.g. when both
     512             :        z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX)
     513             :        Again, rescaling solves this.
     514             : 
     515             :        (3) the absolute value of z is close to 1.  In this case it's
     516             :        difficult to achieve good accuracy, at least in part because a
     517             :        change of 1ulp in the real or imaginary part of z can result in a
     518             :        change of billions of ulps in the correctly rounded answer.
     519             : 
     520             :        (4) z = 0.  The simplest thing to do here is to call the
     521             :        floating-point log with an argument of 0, and let its behaviour
     522             :        (returning -infinity, signaling a floating-point exception, setting
     523             :        errno, or whatever) determine that of c_log.  So the usual formula
     524             :        is fine here.
     525             : 
     526             :      */
     527             : 
     528             :     Py_complex r;
     529             :     double ax, ay, am, an, h;
     530             : 
     531           0 :     SPECIAL_VALUE(z, log_special_values);
     532             : 
     533           0 :     ax = fabs(z.real);
     534           0 :     ay = fabs(z.imag);
     535             : 
     536           0 :     if (ax > CM_LARGE_DOUBLE || ay > CM_LARGE_DOUBLE) {
     537           0 :         r.real = log(hypot(ax/2., ay/2.)) + M_LN2;
     538           0 :     } else if (ax < DBL_MIN && ay < DBL_MIN) {
     539           0 :         if (ax > 0. || ay > 0.) {
     540             :             /* catch cases where hypot(ax, ay) is subnormal */
     541           0 :             r.real = log(hypot(ldexp(ax, DBL_MANT_DIG),
     542           0 :                      ldexp(ay, DBL_MANT_DIG))) - DBL_MANT_DIG*M_LN2;
     543             :         }
     544             :         else {
     545             :             /* log(+/-0. +/- 0i) */
     546           0 :             r.real = -INF;
     547           0 :             r.imag = atan2(z.imag, z.real);
     548           0 :             errno = EDOM;
     549           0 :             return r;
     550             :         }
     551             :     } else {
     552           0 :         h = hypot(ax, ay);
     553           0 :         if (0.71 <= h && h <= 1.73) {
     554           0 :             am = ax > ay ? ax : ay;  /* max(ax, ay) */
     555           0 :             an = ax > ay ? ay : ax;  /* min(ax, ay) */
     556           0 :             r.real = m_log1p((am-1)*(am+1)+an*an)/2.;
     557             :         } else {
     558           0 :             r.real = log(h);
     559             :         }
     560             :     }
     561           0 :     r.imag = atan2(z.imag, z.real);
     562           0 :     errno = 0;
     563           0 :     return r;
     564             : }
     565             : 
     566             : 
     567             : static Py_complex
     568           0 : c_log10(Py_complex z)
     569             : {
     570             :     Py_complex r;
     571             :     int errno_save;
     572             : 
     573           0 :     r = c_log(z);
     574           0 :     errno_save = errno; /* just in case the divisions affect errno */
     575           0 :     r.real = r.real / M_LN10;
     576           0 :     r.imag = r.imag / M_LN10;
     577           0 :     errno = errno_save;
     578           0 :     return r;
     579             : }
     580             : 
     581             : PyDoc_STRVAR(c_log10_doc,
     582             : "log10(x)\n"
     583             : "\n"
     584             : "Return the base-10 logarithm of x.");
     585             : 
     586             : 
     587             : static Py_complex
     588           0 : c_sin(Py_complex z)
     589             : {
     590             :     /* sin(z) = -i sin(iz) */
     591             :     Py_complex s, r;
     592           0 :     s.real = -z.imag;
     593           0 :     s.imag = z.real;
     594           0 :     s = c_sinh(s);
     595           0 :     r.real = s.imag;
     596           0 :     r.imag = -s.real;
     597           0 :     return r;
     598             : }
     599             : 
     600             : PyDoc_STRVAR(c_sin_doc,
     601             : "sin(x)\n"
     602             : "\n"
     603             : "Return the sine of x.");
     604             : 
     605             : 
     606             : /* sinh(infinity + i*y) needs to be dealt with specially */
     607             : static Py_complex sinh_special_values[7][7];
     608             : 
     609             : static Py_complex
     610           0 : c_sinh(Py_complex z)
     611             : {
     612             :     Py_complex r;
     613             :     double x_minus_one;
     614             : 
     615             :     /* special treatment for sinh(+/-inf + iy) if y is finite and
     616             :        nonzero */
     617           0 :     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
     618           0 :         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
     619           0 :             && (z.imag != 0.)) {
     620           0 :             if (z.real > 0) {
     621           0 :                 r.real = copysign(INF, cos(z.imag));
     622           0 :                 r.imag = copysign(INF, sin(z.imag));
     623             :             }
     624             :             else {
     625           0 :                 r.real = -copysign(INF, cos(z.imag));
     626           0 :                 r.imag = copysign(INF, sin(z.imag));
     627             :             }
     628             :         }
     629             :         else {
     630           0 :             r = sinh_special_values[special_type(z.real)]
     631           0 :                                    [special_type(z.imag)];
     632             :         }
     633             :         /* need to set errno = EDOM if y is +/- infinity and x is not
     634             :            a NaN */
     635           0 :         if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real))
     636           0 :             errno = EDOM;
     637             :         else
     638           0 :             errno = 0;
     639           0 :         return r;
     640             :     }
     641             : 
     642           0 :     if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
     643           0 :         x_minus_one = z.real - copysign(1., z.real);
     644           0 :         r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E;
     645           0 :         r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E;
     646             :     } else {
     647           0 :         r.real = cos(z.imag) * sinh(z.real);
     648           0 :         r.imag = sin(z.imag) * cosh(z.real);
     649             :     }
     650             :     /* detect overflow, and set errno accordingly */
     651           0 :     if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
     652           0 :         errno = ERANGE;
     653             :     else
     654           0 :         errno = 0;
     655           0 :     return r;
     656             : }
     657             : 
     658             : PyDoc_STRVAR(c_sinh_doc,
     659             : "sinh(x)\n"
     660             : "\n"
     661             : "Return the hyperbolic sine of x.");
     662             : 
     663             : 
     664             : static Py_complex sqrt_special_values[7][7];
     665             : 
     666             : static Py_complex
     667           0 : c_sqrt(Py_complex z)
     668             : {
     669             :     /*
     670             :        Method: use symmetries to reduce to the case when x = z.real and y
     671             :        = z.imag are nonnegative.  Then the real part of the result is
     672             :        given by
     673             : 
     674             :          s = sqrt((x + hypot(x, y))/2)
     675             : 
     676             :        and the imaginary part is
     677             : 
     678             :          d = (y/2)/s
     679             : 
     680             :        If either x or y is very large then there's a risk of overflow in
     681             :        computation of the expression x + hypot(x, y).  We can avoid this
     682             :        by rewriting the formula for s as:
     683             : 
     684             :          s = 2*sqrt(x/8 + hypot(x/8, y/8))
     685             : 
     686             :        This costs us two extra multiplications/divisions, but avoids the
     687             :        overhead of checking for x and y large.
     688             : 
     689             :        If both x and y are subnormal then hypot(x, y) may also be
     690             :        subnormal, so will lack full precision.  We solve this by rescaling
     691             :        x and y by a sufficiently large power of 2 to ensure that x and y
     692             :        are normal.
     693             :     */
     694             : 
     695             : 
     696             :     Py_complex r;
     697             :     double s,d;
     698             :     double ax, ay;
     699             : 
     700           0 :     SPECIAL_VALUE(z, sqrt_special_values);
     701             : 
     702           0 :     if (z.real == 0. && z.imag == 0.) {
     703           0 :         r.real = 0.;
     704           0 :         r.imag = z.imag;
     705           0 :         return r;
     706             :     }
     707             : 
     708           0 :     ax = fabs(z.real);
     709           0 :     ay = fabs(z.imag);
     710             : 
     711           0 :     if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) {
     712             :         /* here we catch cases where hypot(ax, ay) is subnormal */
     713           0 :         ax = ldexp(ax, CM_SCALE_UP);
     714           0 :         s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))),
     715             :                   CM_SCALE_DOWN);
     716             :     } else {
     717           0 :         ax /= 8.;
     718           0 :         s = 2.*sqrt(ax + hypot(ax, ay/8.));
     719             :     }
     720           0 :     d = ay/(2.*s);
     721             : 
     722           0 :     if (z.real >= 0.) {
     723           0 :         r.real = s;
     724           0 :         r.imag = copysign(d, z.imag);
     725             :     } else {
     726           0 :         r.real = d;
     727           0 :         r.imag = copysign(s, z.imag);
     728             :     }
     729           0 :     errno = 0;
     730           0 :     return r;
     731             : }
     732             : 
     733             : PyDoc_STRVAR(c_sqrt_doc,
     734             : "sqrt(x)\n"
     735             : "\n"
     736             : "Return the square root of x.");
     737             : 
     738             : 
     739             : static Py_complex
     740           0 : c_tan(Py_complex z)
     741             : {
     742             :     /* tan(z) = -i tanh(iz) */
     743             :     Py_complex s, r;
     744           0 :     s.real = -z.imag;
     745           0 :     s.imag = z.real;
     746           0 :     s = c_tanh(s);
     747           0 :     r.real = s.imag;
     748           0 :     r.imag = -s.real;
     749           0 :     return r;
     750             : }
     751             : 
     752             : PyDoc_STRVAR(c_tan_doc,
     753             : "tan(x)\n"
     754             : "\n"
     755             : "Return the tangent of x.");
     756             : 
     757             : 
     758             : /* tanh(infinity + i*y) needs to be dealt with specially */
     759             : static Py_complex tanh_special_values[7][7];
     760             : 
     761             : static Py_complex
     762           0 : c_tanh(Py_complex z)
     763             : {
     764             :     /* Formula:
     765             : 
     766             :        tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) /
     767             :        (1+tan(y)^2 tanh(x)^2)
     768             : 
     769             :        To avoid excessive roundoff error, 1-tanh(x)^2 is better computed
     770             :        as 1/cosh(x)^2.  When abs(x) is large, we approximate 1-tanh(x)^2
     771             :        by 4 exp(-2*x) instead, to avoid possible overflow in the
     772             :        computation of cosh(x).
     773             : 
     774             :     */
     775             : 
     776             :     Py_complex r;
     777             :     double tx, ty, cx, txty, denom;
     778             : 
     779             :     /* special treatment for tanh(+/-inf + iy) if y is finite and
     780             :        nonzero */
     781           0 :     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
     782           0 :         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
     783           0 :             && (z.imag != 0.)) {
     784           0 :             if (z.real > 0) {
     785           0 :                 r.real = 1.0;
     786           0 :                 r.imag = copysign(0.,
     787           0 :                                   2.*sin(z.imag)*cos(z.imag));
     788             :             }
     789             :             else {
     790           0 :                 r.real = -1.0;
     791           0 :                 r.imag = copysign(0.,
     792           0 :                                   2.*sin(z.imag)*cos(z.imag));
     793             :             }
     794             :         }
     795             :         else {
     796           0 :             r = tanh_special_values[special_type(z.real)]
     797           0 :                                    [special_type(z.imag)];
     798             :         }
     799             :         /* need to set errno = EDOM if z.imag is +/-infinity and
     800             :            z.real is finite */
     801           0 :         if (Py_IS_INFINITY(z.imag) && Py_IS_FINITE(z.real))
     802           0 :             errno = EDOM;
     803             :         else
     804           0 :             errno = 0;
     805           0 :         return r;
     806             :     }
     807             : 
     808             :     /* danger of overflow in 2.*z.imag !*/
     809           0 :     if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
     810           0 :         r.real = copysign(1., z.real);
     811           0 :         r.imag = 4.*sin(z.imag)*cos(z.imag)*exp(-2.*fabs(z.real));
     812             :     } else {
     813           0 :         tx = tanh(z.real);
     814           0 :         ty = tan(z.imag);
     815           0 :         cx = 1./cosh(z.real);
     816           0 :         txty = tx*ty;
     817           0 :         denom = 1. + txty*txty;
     818           0 :         r.real = tx*(1.+ty*ty)/denom;
     819           0 :         r.imag = ((ty/denom)*cx)*cx;
     820             :     }
     821           0 :     errno = 0;
     822           0 :     return r;
     823             : }
     824             : 
     825             : PyDoc_STRVAR(c_tanh_doc,
     826             : "tanh(x)\n"
     827             : "\n"
     828             : "Return the hyperbolic tangent of x.");
     829             : 
     830             : 
     831             : static PyObject *
     832           0 : cmath_log(PyObject *self, PyObject *args)
     833             : {
     834             :     Py_complex x;
     835             :     Py_complex y;
     836             : 
     837           0 :     if (!PyArg_ParseTuple(args, "D|D", &x, &y))
     838           0 :         return NULL;
     839             : 
     840           0 :     errno = 0;
     841             :     PyFPE_START_PROTECT("complex function", return 0)
     842           0 :     x = c_log(x);
     843           0 :     if (PyTuple_GET_SIZE(args) == 2) {
     844           0 :         y = c_log(y);
     845           0 :         x = c_quot(x, y);
     846             :     }
     847             :     PyFPE_END_PROTECT(x)
     848           0 :     if (errno != 0)
     849           0 :         return math_error();
     850           0 :     return PyComplex_FromCComplex(x);
     851             : }
     852             : 
     853             : PyDoc_STRVAR(cmath_log_doc,
     854             : "log(x[, base]) -> the logarithm of x to the given base.\n\
     855             : If the base not specified, returns the natural logarithm (base e) of x.");
     856             : 
     857             : 
     858             : /* And now the glue to make them available from Python: */
     859             : 
     860             : static PyObject *
     861           0 : math_error(void)
     862             : {
     863           0 :     if (errno == EDOM)
     864           0 :         PyErr_SetString(PyExc_ValueError, "math domain error");
     865           0 :     else if (errno == ERANGE)
     866           0 :         PyErr_SetString(PyExc_OverflowError, "math range error");
     867             :     else    /* Unexpected math error */
     868           0 :         PyErr_SetFromErrno(PyExc_ValueError);
     869           0 :     return NULL;
     870             : }
     871             : 
     872             : static PyObject *
     873           0 : math_1(PyObject *args, Py_complex (*func)(Py_complex))
     874             : {
     875             :     Py_complex x,r ;
     876           0 :     if (!PyArg_ParseTuple(args, "D", &x))
     877           0 :         return NULL;
     878           0 :     errno = 0;
     879             :     PyFPE_START_PROTECT("complex function", return 0);
     880           0 :     r = (*func)(x);
     881             :     PyFPE_END_PROTECT(r);
     882           0 :     if (errno == EDOM) {
     883           0 :         PyErr_SetString(PyExc_ValueError, "math domain error");
     884           0 :         return NULL;
     885             :     }
     886           0 :     else if (errno == ERANGE) {
     887           0 :         PyErr_SetString(PyExc_OverflowError, "math range error");
     888           0 :         return NULL;
     889             :     }
     890             :     else {
     891           0 :         return PyComplex_FromCComplex(r);
     892             :     }
     893             : }
     894             : 
     895             : #define FUNC1(stubname, func) \
     896             :     static PyObject * stubname(PyObject *self, PyObject *args) { \
     897             :         return math_1(args, func); \
     898             :     }
     899             : 
     900           0 : FUNC1(cmath_acos, c_acos)
     901           0 : FUNC1(cmath_acosh, c_acosh)
     902           0 : FUNC1(cmath_asin, c_asin)
     903           0 : FUNC1(cmath_asinh, c_asinh)
     904           0 : FUNC1(cmath_atan, c_atan)
     905           0 : FUNC1(cmath_atanh, c_atanh)
     906           0 : FUNC1(cmath_cos, c_cos)
     907           0 : FUNC1(cmath_cosh, c_cosh)
     908           0 : FUNC1(cmath_exp, c_exp)
     909           0 : FUNC1(cmath_log10, c_log10)
     910           0 : FUNC1(cmath_sin, c_sin)
     911           0 : FUNC1(cmath_sinh, c_sinh)
     912           0 : FUNC1(cmath_sqrt, c_sqrt)
     913           0 : FUNC1(cmath_tan, c_tan)
     914           0 : FUNC1(cmath_tanh, c_tanh)
     915             : 
     916             : static PyObject *
     917           0 : cmath_phase(PyObject *self, PyObject *args)
     918             : {
     919             :     Py_complex z;
     920             :     double phi;
     921           0 :     if (!PyArg_ParseTuple(args, "D:phase", &z))
     922           0 :         return NULL;
     923           0 :     errno = 0;
     924             :     PyFPE_START_PROTECT("arg function", return 0)
     925           0 :     phi = c_atan2(z);
     926             :     PyFPE_END_PROTECT(phi)
     927           0 :     if (errno != 0)
     928           0 :         return math_error();
     929             :     else
     930           0 :         return PyFloat_FromDouble(phi);
     931             : }
     932             : 
     933             : PyDoc_STRVAR(cmath_phase_doc,
     934             : "phase(z) -> float\n\n\
     935             : Return argument, also known as the phase angle, of a complex.");
     936             : 
     937             : static PyObject *
     938           0 : cmath_polar(PyObject *self, PyObject *args)
     939             : {
     940             :     Py_complex z;
     941             :     double r, phi;
     942           0 :     if (!PyArg_ParseTuple(args, "D:polar", &z))
     943           0 :         return NULL;
     944             :     PyFPE_START_PROTECT("polar function", return 0)
     945           0 :     phi = c_atan2(z); /* should not cause any exception */
     946           0 :     r = c_abs(z); /* sets errno to ERANGE on overflow;  otherwise 0 */
     947             :     PyFPE_END_PROTECT(r)
     948           0 :     if (errno != 0)
     949           0 :         return math_error();
     950             :     else
     951           0 :         return Py_BuildValue("dd", r, phi);
     952             : }
     953             : 
     954             : PyDoc_STRVAR(cmath_polar_doc,
     955             : "polar(z) -> r: float, phi: float\n\n\
     956             : Convert a complex from rectangular coordinates to polar coordinates. r is\n\
     957             : the distance from 0 and phi the phase angle.");
     958             : 
     959             : /*
     960             :   rect() isn't covered by the C99 standard, but it's not too hard to
     961             :   figure out 'spirit of C99' rules for special value handing:
     962             : 
     963             :     rect(x, t) should behave like exp(log(x) + it) for positive-signed x
     964             :     rect(x, t) should behave like -exp(log(-x) + it) for negative-signed x
     965             :     rect(nan, t) should behave like exp(nan + it), except that rect(nan, 0)
     966             :       gives nan +- i0 with the sign of the imaginary part unspecified.
     967             : 
     968             : */
     969             : 
     970             : static Py_complex rect_special_values[7][7];
     971             : 
     972             : static PyObject *
     973           0 : cmath_rect(PyObject *self, PyObject *args)
     974             : {
     975             :     Py_complex z;
     976             :     double r, phi;
     977           0 :     if (!PyArg_ParseTuple(args, "dd:rect", &r, &phi))
     978           0 :         return NULL;
     979           0 :     errno = 0;
     980             :     PyFPE_START_PROTECT("rect function", return 0)
     981             : 
     982             :     /* deal with special values */
     983           0 :     if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) {
     984             :         /* if r is +/-infinity and phi is finite but nonzero then
     985             :            result is (+-INF +-INF i), but we need to compute cos(phi)
     986             :            and sin(phi) to figure out the signs. */
     987           0 :         if (Py_IS_INFINITY(r) && (Py_IS_FINITE(phi)
     988           0 :                                   && (phi != 0.))) {
     989           0 :             if (r > 0) {
     990           0 :                 z.real = copysign(INF, cos(phi));
     991           0 :                 z.imag = copysign(INF, sin(phi));
     992             :             }
     993             :             else {
     994           0 :                 z.real = -copysign(INF, cos(phi));
     995           0 :                 z.imag = -copysign(INF, sin(phi));
     996             :             }
     997             :         }
     998             :         else {
     999           0 :             z = rect_special_values[special_type(r)]
    1000           0 :                                    [special_type(phi)];
    1001             :         }
    1002             :         /* need to set errno = EDOM if r is a nonzero number and phi
    1003             :            is infinite */
    1004           0 :         if (r != 0. && !Py_IS_NAN(r) && Py_IS_INFINITY(phi))
    1005           0 :             errno = EDOM;
    1006             :         else
    1007           0 :             errno = 0;
    1008             :     }
    1009             :     else {
    1010           0 :         z.real = r * cos(phi);
    1011           0 :         z.imag = r * sin(phi);
    1012           0 :         errno = 0;
    1013             :     }
    1014             : 
    1015             :     PyFPE_END_PROTECT(z)
    1016           0 :     if (errno != 0)
    1017           0 :         return math_error();
    1018             :     else
    1019           0 :         return PyComplex_FromCComplex(z);
    1020             : }
    1021             : 
    1022             : PyDoc_STRVAR(cmath_rect_doc,
    1023             : "rect(r, phi) -> z: complex\n\n\
    1024             : Convert from polar coordinates to rectangular coordinates.");
    1025             : 
    1026             : static PyObject *
    1027           0 : cmath_isfinite(PyObject *self, PyObject *args)
    1028             : {
    1029             :     Py_complex z;
    1030           0 :     if (!PyArg_ParseTuple(args, "D:isfinite", &z))
    1031           0 :         return NULL;
    1032           0 :     return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag));
    1033             : }
    1034             : 
    1035             : PyDoc_STRVAR(cmath_isfinite_doc,
    1036             : "isfinite(z) -> bool\n\
    1037             : Return True if both the real and imaginary parts of z are finite, else False.");
    1038             : 
    1039             : static PyObject *
    1040           0 : cmath_isnan(PyObject *self, PyObject *args)
    1041             : {
    1042             :     Py_complex z;
    1043           0 :     if (!PyArg_ParseTuple(args, "D:isnan", &z))
    1044           0 :         return NULL;
    1045           0 :     return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag));
    1046             : }
    1047             : 
    1048             : PyDoc_STRVAR(cmath_isnan_doc,
    1049             : "isnan(z) -> bool\n\
    1050             : Checks if the real or imaginary part of z not a number (NaN)");
    1051             : 
    1052             : static PyObject *
    1053           0 : cmath_isinf(PyObject *self, PyObject *args)
    1054             : {
    1055             :     Py_complex z;
    1056           0 :     if (!PyArg_ParseTuple(args, "D:isnan", &z))
    1057           0 :         return NULL;
    1058           0 :     return PyBool_FromLong(Py_IS_INFINITY(z.real) ||
    1059           0 :                            Py_IS_INFINITY(z.imag));
    1060             : }
    1061             : 
    1062             : PyDoc_STRVAR(cmath_isinf_doc,
    1063             : "isinf(z) -> bool\n\
    1064             : Checks if the real or imaginary part of z is infinite.");
    1065             : 
    1066             : 
    1067             : PyDoc_STRVAR(module_doc,
    1068             : "This module is always available. It provides access to mathematical\n"
    1069             : "functions for complex numbers.");
    1070             : 
    1071             : static PyMethodDef cmath_methods[] = {
    1072             :     {"acos",   cmath_acos,  METH_VARARGS, c_acos_doc},
    1073             :     {"acosh",  cmath_acosh, METH_VARARGS, c_acosh_doc},
    1074             :     {"asin",   cmath_asin,  METH_VARARGS, c_asin_doc},
    1075             :     {"asinh",  cmath_asinh, METH_VARARGS, c_asinh_doc},
    1076             :     {"atan",   cmath_atan,  METH_VARARGS, c_atan_doc},
    1077             :     {"atanh",  cmath_atanh, METH_VARARGS, c_atanh_doc},
    1078             :     {"cos",    cmath_cos,   METH_VARARGS, c_cos_doc},
    1079             :     {"cosh",   cmath_cosh,  METH_VARARGS, c_cosh_doc},
    1080             :     {"exp",    cmath_exp,   METH_VARARGS, c_exp_doc},
    1081             :     {"isfinite", cmath_isfinite, METH_VARARGS, cmath_isfinite_doc},
    1082             :     {"isinf",  cmath_isinf, METH_VARARGS, cmath_isinf_doc},
    1083             :     {"isnan",  cmath_isnan, METH_VARARGS, cmath_isnan_doc},
    1084             :     {"log",    cmath_log,   METH_VARARGS, cmath_log_doc},
    1085             :     {"log10",  cmath_log10, METH_VARARGS, c_log10_doc},
    1086             :     {"phase",  cmath_phase, METH_VARARGS, cmath_phase_doc},
    1087             :     {"polar",  cmath_polar, METH_VARARGS, cmath_polar_doc},
    1088             :     {"rect",   cmath_rect,  METH_VARARGS, cmath_rect_doc},
    1089             :     {"sin",    cmath_sin,   METH_VARARGS, c_sin_doc},
    1090             :     {"sinh",   cmath_sinh,  METH_VARARGS, c_sinh_doc},
    1091             :     {"sqrt",   cmath_sqrt,  METH_VARARGS, c_sqrt_doc},
    1092             :     {"tan",    cmath_tan,   METH_VARARGS, c_tan_doc},
    1093             :     {"tanh",   cmath_tanh,  METH_VARARGS, c_tanh_doc},
    1094             :     {NULL,              NULL}           /* sentinel */
    1095             : };
    1096             : 
    1097             : 
    1098             : static struct PyModuleDef cmathmodule = {
    1099             :     PyModuleDef_HEAD_INIT,
    1100             :     "cmath",
    1101             :     module_doc,
    1102             :     -1,
    1103             :     cmath_methods,
    1104             :     NULL,
    1105             :     NULL,
    1106             :     NULL,
    1107             :     NULL
    1108             : };
    1109             : 
    1110             : PyMODINIT_FUNC
    1111           0 : PyInit_cmath(void)
    1112             : {
    1113             :     PyObject *m;
    1114             : 
    1115           0 :     m = PyModule_Create(&cmathmodule);
    1116           0 :     if (m == NULL)
    1117           0 :         return NULL;
    1118             : 
    1119           0 :     PyModule_AddObject(m, "pi",
    1120             :                        PyFloat_FromDouble(Py_MATH_PI));
    1121           0 :     PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
    1122             : 
    1123             :     /* initialize special value tables */
    1124             : 
    1125             : #define INIT_SPECIAL_VALUES(NAME, BODY) { Py_complex* p = (Py_complex*)NAME; BODY }
    1126             : #define C(REAL, IMAG) p->real = REAL; p->imag = IMAG; ++p;
    1127             : 
    1128           0 :     INIT_SPECIAL_VALUES(acos_special_values, {
    1129             :       C(P34,INF) C(P,INF)  C(P,INF)  C(P,-INF)  C(P,-INF)  C(P34,-INF) C(N,INF)
    1130             :       C(P12,INF) C(U,U)    C(U,U)    C(U,U)     C(U,U)     C(P12,-INF) C(N,N)
    1131             :       C(P12,INF) C(U,U)    C(P12,0.) C(P12,-0.) C(U,U)     C(P12,-INF) C(P12,N)
    1132             :       C(P12,INF) C(U,U)    C(P12,0.) C(P12,-0.) C(U,U)     C(P12,-INF) C(P12,N)
    1133             :       C(P12,INF) C(U,U)    C(U,U)    C(U,U)     C(U,U)     C(P12,-INF) C(N,N)
    1134             :       C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF)
    1135             :       C(N,INF)   C(N,N)    C(N,N)    C(N,N)     C(N,N)     C(N,-INF)   C(N,N)
    1136             :     })
    1137             : 
    1138           0 :     INIT_SPECIAL_VALUES(acosh_special_values, {
    1139             :       C(INF,-P34) C(INF,-P)  C(INF,-P)  C(INF,P)  C(INF,P)  C(INF,P34) C(INF,N)
    1140             :       C(INF,-P12) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,P12) C(N,N)
    1141             :       C(INF,-P12) C(U,U)     C(0.,-P12) C(0.,P12) C(U,U)    C(INF,P12) C(N,N)
    1142             :       C(INF,-P12) C(U,U)     C(0.,-P12) C(0.,P12) C(U,U)    C(INF,P12) C(N,N)
    1143             :       C(INF,-P12) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,P12) C(N,N)
    1144             :       C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N)
    1145             :       C(INF,N)    C(N,N)     C(N,N)     C(N,N)    C(N,N)    C(INF,N)   C(N,N)
    1146             :     })
    1147             : 
    1148           0 :     INIT_SPECIAL_VALUES(asinh_special_values, {
    1149             :       C(-INF,-P14) C(-INF,-0.) C(-INF,-0.) C(-INF,0.) C(-INF,0.) C(-INF,P14) C(-INF,N)
    1150             :       C(-INF,-P12) C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(-INF,P12) C(N,N)
    1151             :       C(-INF,-P12) C(U,U)      C(-0.,-0.)  C(-0.,0.)  C(U,U)     C(-INF,P12) C(N,N)
    1152             :       C(INF,-P12)  C(U,U)      C(0.,-0.)   C(0.,0.)   C(U,U)     C(INF,P12)  C(N,N)
    1153             :       C(INF,-P12)  C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(INF,P12)  C(N,N)
    1154             :       C(INF,-P14)  C(INF,-0.)  C(INF,-0.)  C(INF,0.)  C(INF,0.)  C(INF,P14)  C(INF,N)
    1155             :       C(INF,N)     C(N,N)      C(N,-0.)    C(N,0.)    C(N,N)     C(INF,N)    C(N,N)
    1156             :     })
    1157             : 
    1158           0 :     INIT_SPECIAL_VALUES(atanh_special_values, {
    1159             :       C(-0.,-P12) C(-0.,-P12) C(-0.,-P12) C(-0.,P12) C(-0.,P12) C(-0.,P12) C(-0.,N)
    1160             :       C(-0.,-P12) C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(-0.,P12) C(N,N)
    1161             :       C(-0.,-P12) C(U,U)      C(-0.,-0.)  C(-0.,0.)  C(U,U)     C(-0.,P12) C(-0.,N)
    1162             :       C(0.,-P12)  C(U,U)      C(0.,-0.)   C(0.,0.)   C(U,U)     C(0.,P12)  C(0.,N)
    1163             :       C(0.,-P12)  C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(0.,P12)  C(N,N)
    1164             :       C(0.,-P12)  C(0.,-P12)  C(0.,-P12)  C(0.,P12)  C(0.,P12)  C(0.,P12)  C(0.,N)
    1165             :       C(0.,-P12)  C(N,N)      C(N,N)      C(N,N)     C(N,N)     C(0.,P12)  C(N,N)
    1166             :     })
    1167             : 
    1168           0 :     INIT_SPECIAL_VALUES(cosh_special_values, {
    1169             :       C(INF,N) C(U,U) C(INF,0.)  C(INF,-0.) C(U,U) C(INF,N) C(INF,N)
    1170             :       C(N,N)   C(U,U) C(U,U)     C(U,U)     C(U,U) C(N,N)   C(N,N)
    1171             :       C(N,0.)  C(U,U) C(1.,0.)   C(1.,-0.)  C(U,U) C(N,0.)  C(N,0.)
    1172             :       C(N,0.)  C(U,U) C(1.,-0.)  C(1.,0.)   C(U,U) C(N,0.)  C(N,0.)
    1173             :       C(N,N)   C(U,U) C(U,U)     C(U,U)     C(U,U) C(N,N)   C(N,N)
    1174             :       C(INF,N) C(U,U) C(INF,-0.) C(INF,0.)  C(U,U) C(INF,N) C(INF,N)
    1175             :       C(N,N)   C(N,N) C(N,0.)    C(N,0.)    C(N,N) C(N,N)   C(N,N)
    1176             :     })
    1177             : 
    1178           0 :     INIT_SPECIAL_VALUES(exp_special_values, {
    1179             :       C(0.,0.) C(U,U) C(0.,-0.)  C(0.,0.)  C(U,U) C(0.,0.) C(0.,0.)
    1180             :       C(N,N)   C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)   C(N,N)
    1181             :       C(N,N)   C(U,U) C(1.,-0.)  C(1.,0.)  C(U,U) C(N,N)   C(N,N)
    1182             :       C(N,N)   C(U,U) C(1.,-0.)  C(1.,0.)  C(U,U) C(N,N)   C(N,N)
    1183             :       C(N,N)   C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)   C(N,N)
    1184             :       C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N)
    1185             :       C(N,N)   C(N,N) C(N,-0.)   C(N,0.)   C(N,N) C(N,N)   C(N,N)
    1186             :     })
    1187             : 
    1188           0 :     INIT_SPECIAL_VALUES(log_special_values, {
    1189             :       C(INF,-P34) C(INF,-P)  C(INF,-P)   C(INF,P)   C(INF,P)  C(INF,P34)  C(INF,N)
    1190             :       C(INF,-P12) C(U,U)     C(U,U)      C(U,U)     C(U,U)    C(INF,P12)  C(N,N)
    1191             :       C(INF,-P12) C(U,U)     C(-INF,-P)  C(-INF,P)  C(U,U)    C(INF,P12)  C(N,N)
    1192             :       C(INF,-P12) C(U,U)     C(-INF,-0.) C(-INF,0.) C(U,U)    C(INF,P12)  C(N,N)
    1193             :       C(INF,-P12) C(U,U)     C(U,U)      C(U,U)     C(U,U)    C(INF,P12)  C(N,N)
    1194             :       C(INF,-P14) C(INF,-0.) C(INF,-0.)  C(INF,0.)  C(INF,0.) C(INF,P14)  C(INF,N)
    1195             :       C(INF,N)    C(N,N)     C(N,N)      C(N,N)     C(N,N)    C(INF,N)    C(N,N)
    1196             :     })
    1197             : 
    1198           0 :     INIT_SPECIAL_VALUES(sinh_special_values, {
    1199             :       C(INF,N) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,N) C(INF,N)
    1200             :       C(N,N)   C(U,U) C(U,U)      C(U,U)     C(U,U) C(N,N)   C(N,N)
    1201             :       C(0.,N)  C(U,U) C(-0.,-0.)  C(-0.,0.)  C(U,U) C(0.,N)  C(0.,N)
    1202             :       C(0.,N)  C(U,U) C(0.,-0.)   C(0.,0.)   C(U,U) C(0.,N)  C(0.,N)
    1203             :       C(N,N)   C(U,U) C(U,U)      C(U,U)     C(U,U) C(N,N)   C(N,N)
    1204             :       C(INF,N) C(U,U) C(INF,-0.)  C(INF,0.)  C(U,U) C(INF,N) C(INF,N)
    1205             :       C(N,N)   C(N,N) C(N,-0.)    C(N,0.)    C(N,N) C(N,N)   C(N,N)
    1206             :     })
    1207             : 
    1208           0 :     INIT_SPECIAL_VALUES(sqrt_special_values, {
    1209             :       C(INF,-INF) C(0.,-INF) C(0.,-INF) C(0.,INF) C(0.,INF) C(INF,INF) C(N,INF)
    1210             :       C(INF,-INF) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,INF) C(N,N)
    1211             :       C(INF,-INF) C(U,U)     C(0.,-0.)  C(0.,0.)  C(U,U)    C(INF,INF) C(N,N)
    1212             :       C(INF,-INF) C(U,U)     C(0.,-0.)  C(0.,0.)  C(U,U)    C(INF,INF) C(N,N)
    1213             :       C(INF,-INF) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,INF) C(N,N)
    1214             :       C(INF,-INF) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,INF) C(INF,N)
    1215             :       C(INF,-INF) C(N,N)     C(N,N)     C(N,N)    C(N,N)    C(INF,INF) C(N,N)
    1216             :     })
    1217             : 
    1218           0 :     INIT_SPECIAL_VALUES(tanh_special_values, {
    1219             :       C(-1.,0.) C(U,U) C(-1.,-0.) C(-1.,0.) C(U,U) C(-1.,0.) C(-1.,0.)
    1220             :       C(N,N)    C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)    C(N,N)
    1221             :       C(N,N)    C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(N,N)    C(N,N)
    1222             :       C(N,N)    C(U,U) C(0.,-0.)  C(0.,0.)  C(U,U) C(N,N)    C(N,N)
    1223             :       C(N,N)    C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)    C(N,N)
    1224             :       C(1.,0.)  C(U,U) C(1.,-0.)  C(1.,0.)  C(U,U) C(1.,0.)  C(1.,0.)
    1225             :       C(N,N)    C(N,N) C(N,-0.)   C(N,0.)   C(N,N) C(N,N)    C(N,N)
    1226             :     })
    1227             : 
    1228           0 :     INIT_SPECIAL_VALUES(rect_special_values, {
    1229             :       C(INF,N) C(U,U) C(-INF,0.) C(-INF,-0.) C(U,U) C(INF,N) C(INF,N)
    1230             :       C(N,N)   C(U,U) C(U,U)     C(U,U)      C(U,U) C(N,N)   C(N,N)
    1231             :       C(0.,0.) C(U,U) C(-0.,0.)  C(-0.,-0.)  C(U,U) C(0.,0.) C(0.,0.)
    1232             :       C(0.,0.) C(U,U) C(0.,-0.)  C(0.,0.)    C(U,U) C(0.,0.) C(0.,0.)
    1233             :       C(N,N)   C(U,U) C(U,U)     C(U,U)      C(U,U) C(N,N)   C(N,N)
    1234             :       C(INF,N) C(U,U) C(INF,-0.) C(INF,0.)   C(U,U) C(INF,N) C(INF,N)
    1235             :       C(N,N)   C(N,N) C(N,0.)    C(N,0.)     C(N,N) C(N,N)   C(N,N)
    1236             :     })
    1237           0 :     return m;
    1238             : }

Generated by: LCOV version 1.10