.. highlight:: c

.. _complexobjects:

Complex Number Objects
----------------------

.. index:: pair: object; complex number

Python's complex number objects are implemented as two distinct types when
viewed from the C API:  one is the Python object exposed to Python programs, and
the other is a C structure which represents the actual complex number value.
The API provides functions for working with both.


Complex Numbers as C Structures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Note that the functions which accept these structures as parameters and return
them as results do so *by value* rather than dereferencing them through
pointers.  This is consistent throughout the API.


.. c:type:: Py_complex

   The C structure which corresponds to the value portion of a Python complex
   number object.  Most of the functions for dealing with complex number objects
   use structures of this type as input or output values, as appropriate.

   .. c:member:: double real
                 double imag

   The structure is defined as::

      typedef struct {
          double real;
          double imag;
      } Py_complex;


.. c:function:: Py_complex _Py_c_sum(Py_complex left, Py_complex right)

   Return the sum of two complex numbers, using the C :c:type:`Py_complex`
   representation.


.. c:function:: Py_complex _Py_cr_sum(Py_complex left, double right)

   Return the sum of a complex number and a real number, using the C :c:type:`Py_complex`
   representation.

   .. versionadded:: 3.14


.. c:function:: Py_complex _Py_c_diff(Py_complex left, Py_complex right)

   Return the difference between two complex numbers, using the C
   :c:type:`Py_complex` representation.


.. c:function:: Py_complex _Py_cr_diff(Py_complex left, double right)

   Return the difference between a complex number and a real number, using the C
   :c:type:`Py_complex` representation.

   .. versionadded:: 3.14


.. c:function:: Py_complex _Py_rc_diff(double left, Py_complex right)

   Return the difference between a real number and a complex number, using the C
   :c:type:`Py_complex` representation.

   .. versionadded:: 3.14


.. c:function:: Py_complex _Py_c_neg(Py_complex num)

   Return the negation of the complex number *num*, using the C
   :c:type:`Py_complex` representation.


.. c:function:: Py_complex _Py_c_prod(Py_complex left, Py_complex right)

   Return the product of two complex numbers, using the C :c:type:`Py_complex`
   representation.


.. c:function:: Py_complex _Py_cr_prod(Py_complex left, double right)

   Return the product of a complex number and a real number, using the C
   :c:type:`Py_complex` representation.

   .. versionadded:: 3.14


.. c:function:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor)

   Return the quotient of two complex numbers, using the C :c:type:`Py_complex`
   representation.

   If *divisor* is null, this method returns zero and sets
   :c:data:`errno` to :c:macro:`!EDOM`.


.. c:function:: Py_complex _Py_cr_quot(Py_complex dividend, double divisor)

   Return the quotient of a complex number and a real number, using the C
   :c:type:`Py_complex` representation.

   If *divisor* is zero, this method returns zero and sets
   :c:data:`errno` to :c:macro:`!EDOM`.

   .. versionadded:: 3.14


.. c:function:: Py_complex _Py_rc_quot(double dividend, Py_complex divisor)

   Return the quotient of a real number and a complex number, using the C
   :c:type:`Py_complex` representation.

   If *divisor* is zero, this method returns zero and sets
   :c:data:`errno` to :c:macro:`!EDOM`.

   .. versionadded:: 3.14


.. c:function:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp)

   Return the exponentiation of *num* by *exp*, using the C :c:type:`Py_complex`
   representation.

   If *num* is null and *exp* is not a positive real number,
   this method returns zero and sets :c:data:`errno` to :c:macro:`!EDOM`.

   Set :c:data:`errno` to :c:macro:`!ERANGE` on overflows.


Complex Numbers as Python Objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


.. c:type:: PyComplexObject

   This subtype of :c:type:`PyObject` represents a Python complex number object.


.. c:var:: PyTypeObject PyComplex_Type

   This instance of :c:type:`PyTypeObject` represents the Python complex number
   type. It is the same object as :class:`complex` in the Python layer.


.. c:function:: int PyComplex_Check(PyObject *p)

   Return true if its argument is a :c:type:`PyComplexObject` or a subtype of
   :c:type:`PyComplexObject`.  This function always succeeds.


.. c:function:: int PyComplex_CheckExact(PyObject *p)

   Return true if its argument is a :c:type:`PyComplexObject`, but not a subtype of
   :c:type:`PyComplexObject`.  This function always succeeds.


.. c:function:: PyObject* PyComplex_FromCComplex(Py_complex v)

   Create a new Python complex number object from a C :c:type:`Py_complex` value.
   Return ``NULL`` with an exception set on error.


.. c:function:: PyObject* PyComplex_FromDoubles(double real, double imag)

   Return a new :c:type:`PyComplexObject` object from *real* and *imag*.
   Return ``NULL`` with an exception set on error.


.. c:function:: double PyComplex_RealAsDouble(PyObject *op)

   Return the real part of *op* as a C :c:expr:`double`.

   If *op* is not a Python complex number object but has a
   :meth:`~object.__complex__` method, this method will first be called to
   convert *op* to a Python complex number object.  If :meth:`!__complex__` is
   not defined then it falls back to call :c:func:`PyFloat_AsDouble` and
   returns its result.

   Upon failure, this method returns ``-1.0`` with an exception set, so one
   should call :c:func:`PyErr_Occurred` to check for errors.

   .. versionchanged:: 3.13
      Use :meth:`~object.__complex__` if available.

.. c:function:: double PyComplex_ImagAsDouble(PyObject *op)

   Return the imaginary part of *op* as a C :c:expr:`double`.

   If *op* is not a Python complex number object but has a
   :meth:`~object.__complex__` method, this method will first be called to
   convert *op* to a Python complex number object.  If :meth:`!__complex__` is
   not defined then it falls back to call :c:func:`PyFloat_AsDouble` and
   returns ``0.0`` on success.

   Upon failure, this method returns ``-1.0`` with an exception set, so one
   should call :c:func:`PyErr_Occurred` to check for errors.

   .. versionchanged:: 3.13
      Use :meth:`~object.__complex__` if available.

.. c:function:: Py_complex PyComplex_AsCComplex(PyObject *op)

   Return the :c:type:`Py_complex` value of the complex number *op*.

   If *op* is not a Python complex number object but has a :meth:`~object.__complex__`
   method, this method will first be called to convert *op* to a Python complex
   number object.  If :meth:`!__complex__` is not defined then it falls back to
   :meth:`~object.__float__`.  If :meth:`!__float__` is not defined then it falls back
   to :meth:`~object.__index__`.

   Upon failure, this method returns :c:type:`Py_complex`
   with :c:member:`~Py_complex.real` set to ``-1.0`` and with an exception set, so one
   should call :c:func:`PyErr_Occurred` to check for errors.

   .. versionchanged:: 3.8
      Use :meth:`~object.__index__` if available.
