复数对象
********

从 C API 看，Python 的复数对象由两个不同的类型实现：一个是在 Python 程
序中使用的 Python 对象，另一个是代表真正复数值的 C 结构体。API 提供了
操作两者的函数。


表示复数的 C 结构体
===================

需要注意的是接受这些结构体作为参数并当做结果返回的函数，都是 *按值* 传
递而不是通过指针解引用。此规则适用于整个 API。

type Py_complex

   对应于 Python 复数对象的值部分的 C 结构体。大部分用于处理复数对象的
   函数都使用该类型的结构体作为相应的输入或输出值。

   double real
   double imag

   其结构定义如下:

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

Py_complex _Py_c_sum(Py_complex left, Py_complex right)

   返回两个复数的和，用 C 类型 "Py_complex" 表示。

Py_complex _Py_c_diff(Py_complex left, Py_complex right)

   返回两个复数的差，用 C 类型 "Py_complex" 表示。

Py_complex _Py_c_neg(Py_complex num)

   返回复数 *num* 的负值，用 C "Py_complex" 表示。

Py_complex _Py_c_prod(Py_complex left, Py_complex right)

   返回两个复数的乘积，用 C 类型 "Py_complex" 表示。

Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor)

   返回两个复数的商，用 C 类型 "Py_complex" 表示。

   如果 *divisor* 为空，则此方法将返回零并将 "errno" 设为 "EDOM"。

Py_complex _Py_c_pow(Py_complex num, Py_complex exp)

   返回 *num* 的 *exp* 次幂，用 C 类型 "Py_complex" 表示。

   如果 *num* 为空且 *exp* 不是正实数，则此方法将返回零并将 "errno" 设
   为 "EDOM"。

   当溢出时将 "errno" 设为 "ERANGE"。


表示复数的 Python 对象
======================

type PyComplexObject

   这个 C 类型 "PyObject" 的子类型代表一个 Python 复数对象。

PyTypeObject PyComplex_Type
    * 属于 稳定 ABI.*

   这是个属于 "PyTypeObject" 的代表 Python 复数类型的实例。在 Python
   层面的类型 "complex" 是同一个对象。

int PyComplex_Check(PyObject *p)

   如果它的参数是一个 "PyComplexObject" 或者 "PyComplexObject" 的子类
   型则返回真值。 此函数总是会成功执行。

int PyComplex_CheckExact(PyObject *p)

   如果它的参数是一个 "PyComplexObject" 但不是 "PyComplexObject" 的子
   类型则返回真值。 此函数总是会成功执行。

PyObject *PyComplex_FromCComplex(Py_complex v)
    *返回值：新的引用。*

   根据一个 C "Py_complex" 值新建 Python 复数对象。当发生错误时将返回
   "NULL" 并设置一个异常。

PyObject *PyComplex_FromDoubles(double real, double imag)
    *返回值：新的引用。** 属于 稳定 ABI.*

   根据 *real* 和 *imag* 返回一个新的 "PyComplexObject" 对象。当发生错
   误时将返回 "NULL" 并设置一个异常。

double PyComplex_RealAsDouble(PyObject *op)
    * 属于 稳定 ABI.*

   以 C 类型 double 返回 *op* 的实部。

   如果 *op* 不是一个 Python 复数对象但是具有 "__complex__()" 方法，则
   会先调用该方法将 *op* 转换为 Python 复数对象。如果未定义
   "__complex__()" 则将回退为调用 "PyFloat_AsDouble()" 并返回其结果。

   当失败时，此方法将返回 "-1.0" 并设置一个异常，因此开发者应当调用
   "PyErr_Occurred()" 来检查错误。

   在 3.13 版本发生变更: 如果可能将使用 "__complex__()"。

double PyComplex_ImagAsDouble(PyObject *op)
    * 属于 稳定 ABI.*

   以 C 类型 double 返回 *op* 的虚部。

   如果 *op* 不是一个 Python 复数对象但是具有 "__complex__()" 方法，则
   会先调用该方法将 *op* 转换为 Python 复数对象。如果未定义
   "__complex__()" 则将回退为调用 "PyFloat_AsDouble()" 并在成功时返回
   "0.0"。

   当失败时，此方法将返回 "-1.0" 并设置一个异常，因此开发者应当调用
   "PyErr_Occurred()" 来检查错误。

   在 3.13 版本发生变更: 如果可能将使用 "__complex__()"。

Py_complex PyComplex_AsCComplex(PyObject *op)

   返回复数 *op* 的 C 类型 "Py_complex" 值。

   如果 *op* 不是一个 Python 复数对象但是具有 "__complex__()" 方法，则
   会先调用该方法将 *op* 转换为 Python 复数对象。如果未定义
   "__complex__()" 则将回退至 "__float__()"。 如果未定义 "__float__()"
   则将回退至 "__index__()"。

   当失败时，此方法将返回 "Py_complex" 其中 "real" 为 "-1.0" 并设置一
   个异常，因此开发者应当调用 "PyErr_Occurred()" 来检查错误。

   在 3.8 版本发生变更: 如果可能将使用 "__index__()"。
