# 複數物件

從 C API 來看，Python 的複數物件被實作為兩種不同的型別：一種是公開給 Python 程式的 Python 物件，另一種是表示實際複數值的 C 結構。API 提供了與兩者一起作用的函式。

## 作為 C 結構的複數

請注意，接受這些結構作為參數並將它們作為結果回傳的函式是按值 (by value) 執行的，而不是透過指標取消參照 (dereference) 它們。這在整個 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)

  以 C 的 `Py_complex` 表示形式來回傳複數 num 的相反數 (negation)。

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 為 null，則此方法會回傳零並將 `errno` 設定為 `EDOM`。

Py_complex _Py_c_pow(Py_complex num, Py_complex exp)

  以 C 的 `Py_complex` 表示形式來回傳 num 的 exp 次方的結果。

  如果 num 為 null 且 exp 不是正實數，則此方法會回傳零並將 `errno` 設定為 `EDOM`。

  Set `errno` to `ERANGE` on overflows.

## 作為 Python 物件的複數

type PyComplexObject

  這個 `PyObject` 的子型別代表一個 Python 複數物件。

PyTypeObject PyComplex_Type
  為 穩定 ABI 的一部分.

  這個 `PyTypeObject` 的實例代表 Python 複數型別。它與 Python 層中的 `complex` 是同一個物件。

int PyComplex_Check(PyObject *p)

  如果其引數是一個 `PyComplexObject` 或者是 `PyComplexObject` 的子型別，則會回傳 true。這個函式不會失敗。

int PyComplex_CheckExact(PyObject *p)

  如果其引數是一個 `PyComplexObject`，但不是 `PyComplexObject` 的子型別，則會回傳 true。這個函式不會失敗。

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 的一部分.

  將 op 的虛部作為 C 的 double 回傳。

  如果 op 不是 Python 複數物件，但有一個 `__complex__()` 方法，則首先會呼叫該方法將 op 轉換為 Python 複數物件。如果 `__complex__()` 並未定義，那麼它會回退到呼叫 `PyFloat_AsDouble()` 並於成功時回傳 `0.0`。

  失敗時，此方法回傳 `-1.0` 並設定例外，因此應該呼叫 `PyErr_Occurred()` 來檢查錯誤。

  在 3.13 版的變更: 如果可用則使用 `__complex__()`。

Py_complex PyComplex_AsCComplex(PyObject *op)

  回傳複數 op 的 `Py_complex` 值。

  如果 op 不是 Python 複數物件，但有一個 `__complex__()` 方法，則首先會呼叫該方法將 op 轉換為 Python 複數物件。如果 `__complex__()` 並未定義，那麼它會回退到 `__float__()`。如果 `__float__()` 未定義，則它將繼續回退為 `__index__()`。

  失敗時，此方法回傳 `Py_complex` 並將 `real` 設為 `-1.0`，並設定例外，因此應該呼叫 `PyErr_Occurred()` 來檢查錯誤。

  在 3.8 版的變更: 如果可用則使用 `__index__()`。