Skip to content

Commit

Permalink
+ _Py_ci/ic* functions
Browse files Browse the repository at this point in the history
  • Loading branch information
skirpichev committed Nov 30, 2024
1 parent 42ab221 commit c0dcb3a
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 113 deletions.
54 changes: 54 additions & 0 deletions Doc/c-api/complex.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ pointers. This is consistent throughout the API.
.. versionadded:: 3.14
.. c:function:: Py_complex _Py_ci_sum(Py_complex left, double right)
Return the sum of a complex number and an imaginary number, using the C
:c:type:`Py_complex` representation.
.. versionadded:: next
.. c:function:: Py_complex _Py_c_diff(Py_complex left, Py_complex right)
Return the difference between two complex numbers, using the C
Expand All @@ -74,6 +82,22 @@ pointers. This is consistent throughout the API.
.. versionadded:: 3.14
.. c:function:: Py_complex _Py_ci_diff(Py_complex left, double right)
Return the difference between a complex number and an imaginary number,
using the C :c:type:`Py_complex` representation.
.. versionadded:: next
.. c:function:: Py_complex _Py_ic_diff(double left, Py_complex right)
Return the difference between an imaginary number and a complex number,
using the C :c:type:`Py_complex` representation.
.. versionadded:: next
.. c:function:: Py_complex _Py_c_neg(Py_complex num)
Return the negation of the complex number *num*, using the C
Expand All @@ -94,6 +118,14 @@ pointers. This is consistent throughout the API.
.. versionadded:: 3.14
.. c:function:: Py_complex _Py_ci_prod(Py_complex left, double right)
Return the product of a complex number and an imaginary number, using the C
:c:type:`Py_complex` representation.
.. versionadded:: next
.. 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`
Expand Down Expand Up @@ -125,6 +157,28 @@ pointers. This is consistent throughout the API.
.. versionadded:: 3.14
.. c:function:: Py_complex _Py_ci_quot(Py_complex dividend, double divisor)
Return the quotient of a complex number and an imaginary 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:: next
.. c:function:: Py_complex _Py_ic_quot(double dividend, Py_complex divisor)
Return the quotient of an imaginary 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:: next
.. 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`
Expand Down
6 changes: 6 additions & 0 deletions Include/cpython/complexobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,21 @@ typedef struct {
// Operations on complex numbers.
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_cr_sum(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_ci_sum(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_cr_diff(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_rc_diff(double, Py_complex);
PyAPI_FUNC(Py_complex) _Py_ci_diff(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_ic_diff(double, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_cr_prod(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_ci_prod(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_cr_quot(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_rc_quot(double, Py_complex);
PyAPI_FUNC(Py_complex) _Py_ci_quot(Py_complex, double);
PyAPI_FUNC(Py_complex) _Py_ic_quot(double, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
PyAPI_FUNC(double) _Py_c_abs(Py_complex);

Expand Down
42 changes: 42 additions & 0 deletions Lib/test/test_capi/test_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ def test_py_cr_sum(self):
self.assertComplexesAreIdentical(_py_cr_sum(-0.0 - 0j, -0.0)[0],
complex(-0.0, -0.0))

def test_py_ci_sum(self):
# Test _Py_cr_sum()
_py_ci_sum = _testcapi._py_ci_sum

self.assertComplexesAreIdentical(_py_ci_sum(-0.0 - 0j, -0.0)[0],
complex(-0.0, -0.0))

def test_py_c_diff(self):
# Test _Py_c_diff()
_py_c_diff = _testcapi._py_c_diff
Expand All @@ -195,13 +202,27 @@ def test_py_cr_diff(self):
self.assertComplexesAreIdentical(_py_cr_diff(-0.0 - 0j, 0.0)[0],
complex(-0.0, -0.0))

def test_py_ci_diff(self):
# Test _Py_ci_diff()
_py_ci_diff = _testcapi._py_ci_diff

self.assertComplexesAreIdentical(_py_ci_diff(-0.0 - 0j, 0.0)[0],
complex(-0.0, -0.0))

def test_py_rc_diff(self):
# Test _Py_rc_diff()
_py_rc_diff = _testcapi._py_rc_diff

self.assertComplexesAreIdentical(_py_rc_diff(-0.0, 0j)[0],
complex(-0.0, -0.0))

def test_py_ic_diff(self):
# Test _Py_ic_diff()
_py_ic_diff = _testcapi._py_ic_diff

self.assertComplexesAreIdentical(_py_ic_diff(-0.0, 0j)[0],
complex(-0.0, -0.0))

def test_py_c_neg(self):
# Test _Py_c_neg()
_py_c_neg = _testcapi._py_c_neg
Expand All @@ -221,6 +242,13 @@ def test_py_cr_prod(self):
self.assertComplexesAreIdentical(_py_cr_prod(complex('inf+1j'), INF)[0],
complex('inf+infj'))

def test_py_ci_prod(self):
# Test _Py_ci_prod()
_py_ci_prod = _testcapi._py_ci_prod

self.assertComplexesAreIdentical(_py_ci_prod(complex('inf+1j'), INF)[0],
complex('-inf+infj'))

def test_py_c_quot(self):
# Test _Py_c_quot()
_py_c_quot = _testcapi._py_c_quot
Expand Down Expand Up @@ -250,13 +278,27 @@ def test_py_cr_quot(self):
self.assertComplexesAreIdentical(_py_cr_quot(complex('inf+1j'), 2**1000)[0],
INF + 2**-1000*1j)

def test_py_ci_quot(self):
# Test _Py_ci_quot()
_py_ci_quot = _testcapi._py_ci_quot

self.assertComplexesAreIdentical(_py_ci_quot(complex('1+infj'), 2**1000)[0],
INF - 2**-1000*1j)

def test_py_rc_quot(self):
# Test _Py_rc_quot()
_py_rc_quot = _testcapi._py_rc_quot

self.assertComplexesAreIdentical(_py_rc_quot(1.0, complex('nan-infj'))[0],
0j)

def test_py_ic_quot(self):
# Test _Py_ic_quot()
_py_ic_quot = _testcapi._py_ic_quot

self.assertComplexesAreIdentical(_py_ic_quot(1.0, complex('inf-nanj'))[0],
-0.0)

def test_py_c_pow(self):
# Test _Py_c_pow()
_py_c_pow = _testcapi._py_c_pow
Expand Down
80 changes: 46 additions & 34 deletions Modules/_testcapi/complex.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,48 +57,54 @@ _py_c_neg(PyObject *Py_UNUSED(module), PyObject *num)
return Py_BuildValue("Di", &res, errno); \
};

#define _PY_CR_FUNC2(suffix) \
static PyObject * \
_py_cr_##suffix(PyObject *Py_UNUSED(module), PyObject *args) \
{ \
Py_complex a, res; \
double b; \
\
if (!PyArg_ParseTuple(args, "Dd", &a, &b)) { \
return NULL; \
} \
\
errno = 0; \
res = _Py_cr_##suffix(a, b); \
return Py_BuildValue("Di", &res, errno); \
#define _PY_CX_FUNC2(suffix, prefix) \
static PyObject * \
_py_##prefix##_##suffix(PyObject *Py_UNUSED(module), PyObject *args) \
{ \
Py_complex a, res; \
double b; \
\
if (!PyArg_ParseTuple(args, "Dd", &a, &b)) { \
return NULL; \
} \
\
errno = 0; \
res = _Py_##prefix##_##suffix(a, b); \
return Py_BuildValue("Di", &res, errno); \
};

#define _PY_RC_FUNC2(suffix) \
static PyObject * \
_py_rc_##suffix(PyObject *Py_UNUSED(module), PyObject *args) \
{ \
Py_complex b, res; \
double a; \
\
if (!PyArg_ParseTuple(args, "dD", &a, &b)) { \
return NULL; \
} \
\
errno = 0; \
res = _Py_rc_##suffix(a, b); \
return Py_BuildValue("Di", &res, errno); \
#define _PY_XC_FUNC2(suffix, prefix) \
static PyObject * \
_py_##prefix##_##suffix(PyObject *Py_UNUSED(module), PyObject *args) \
{ \
Py_complex b, res; \
double a; \
\
if (!PyArg_ParseTuple(args, "dD", &a, &b)) { \
return NULL; \
} \
\
errno = 0; \
res = _Py_##prefix##_##suffix(a, b); \
return Py_BuildValue("Di", &res, errno); \
};

_PY_C_FUNC2(sum)
_PY_CR_FUNC2(sum)
_PY_CX_FUNC2(sum, cr)
_PY_CX_FUNC2(sum, ci)
_PY_C_FUNC2(diff)
_PY_CR_FUNC2(diff)
_PY_RC_FUNC2(diff)
_PY_CX_FUNC2(diff, cr)
_PY_CX_FUNC2(diff, ci)
_PY_XC_FUNC2(diff, rc)
_PY_XC_FUNC2(diff, ic)
_PY_C_FUNC2(prod)
_PY_CR_FUNC2(prod)
_PY_CX_FUNC2(prod, cr)
_PY_CX_FUNC2(prod, ci)
_PY_C_FUNC2(quot)
_PY_CR_FUNC2(quot)
_PY_RC_FUNC2(quot)
_PY_CX_FUNC2(quot, cr)
_PY_CX_FUNC2(quot, ci)
_PY_XC_FUNC2(quot, rc)
_PY_XC_FUNC2(quot, ic)
_PY_C_FUNC2(pow)

static PyObject*
Expand All @@ -125,15 +131,21 @@ static PyMethodDef test_methods[] = {
{"complex_asccomplex", complex_asccomplex, METH_O},
{"_py_c_sum", _py_c_sum, METH_VARARGS},
{"_py_cr_sum", _py_cr_sum, METH_VARARGS},
{"_py_ci_sum", _py_ci_sum, METH_VARARGS},
{"_py_c_diff", _py_c_diff, METH_VARARGS},
{"_py_cr_diff", _py_cr_diff, METH_VARARGS},
{"_py_ci_diff", _py_ci_diff, METH_VARARGS},
{"_py_rc_diff", _py_rc_diff, METH_VARARGS},
{"_py_ic_diff", _py_ic_diff, METH_VARARGS},
{"_py_c_neg", _py_c_neg, METH_O},
{"_py_c_prod", _py_c_prod, METH_VARARGS},
{"_py_cr_prod", _py_cr_prod, METH_VARARGS},
{"_py_ci_prod", _py_ci_prod, METH_VARARGS},
{"_py_c_quot", _py_c_quot, METH_VARARGS},
{"_py_cr_quot", _py_cr_quot, METH_VARARGS},
{"_py_ci_quot", _py_ci_quot, METH_VARARGS},
{"_py_rc_quot", _py_rc_quot, METH_VARARGS},
{"_py_ic_quot", _py_ic_quot, METH_VARARGS},
{"_py_c_pow", _py_c_pow, METH_VARARGS},
{"_py_c_abs", _py_c_abs, METH_O},
{NULL},
Expand Down
Loading

0 comments on commit c0dcb3a

Please sign in to comment.