mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-69639: Add mixed-mode rules for complex arithmetic (C-like) (GH-124829)
"Generally, mixed-mode arithmetic combining real and complex variables should be performed directly, not by first coercing the real to complex, lest the sign of zero be rendered uninformative; the same goes for combinations of pure imaginary quantities with complex variables." (c) Kahan, W: Branch cuts for complex elementary functions. This patch implements mixed-mode arithmetic rules, combining real and complex variables as specified by C standards since C99 (in particular, there is no special version for the true division with real lhs operand). Most C compilers implementing C99+ Annex G have only these special rules (without support for imaginary type, which is going to be deprecated in C2y).
This commit is contained in:
parent
dcf629213b
commit
987311d42e
15 changed files with 449 additions and 98 deletions
|
@ -7,6 +7,7 @@ from test.test_capi.test_getargs import (BadComplex, BadComplex2, Complex,
|
|||
FloatSubclass, Float, BadFloat,
|
||||
BadFloat2, ComplexSubclass)
|
||||
from test.support import import_helper
|
||||
from test.support.testcase import ComplexesAreIdenticalMixin
|
||||
|
||||
|
||||
_testcapi = import_helper.import_module('_testcapi')
|
||||
|
@ -23,7 +24,7 @@ class BadComplex3:
|
|||
raise RuntimeError
|
||||
|
||||
|
||||
class CAPIComplexTest(unittest.TestCase):
|
||||
class CAPIComplexTest(ComplexesAreIdenticalMixin, unittest.TestCase):
|
||||
def test_check(self):
|
||||
# Test PyComplex_Check()
|
||||
check = _testlimitedcapi.complex_check
|
||||
|
@ -171,12 +172,33 @@ class CAPIComplexTest(unittest.TestCase):
|
|||
|
||||
self.assertEqual(_py_c_sum(1, 1j), (1+1j, 0))
|
||||
|
||||
def test_py_cr_sum(self):
|
||||
# Test _Py_cr_sum()
|
||||
_py_cr_sum = _testcapi._py_cr_sum
|
||||
|
||||
self.assertComplexesAreIdentical(_py_cr_sum(-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
|
||||
|
||||
self.assertEqual(_py_c_diff(1, 1j), (1-1j, 0))
|
||||
|
||||
def test_py_cr_diff(self):
|
||||
# Test _Py_cr_diff()
|
||||
_py_cr_diff = _testcapi._py_cr_diff
|
||||
|
||||
self.assertComplexesAreIdentical(_py_cr_diff(-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_c_neg(self):
|
||||
# Test _Py_c_neg()
|
||||
_py_c_neg = _testcapi._py_c_neg
|
||||
|
@ -189,6 +211,13 @@ class CAPIComplexTest(unittest.TestCase):
|
|||
|
||||
self.assertEqual(_py_c_prod(2, 1j), (2j, 0))
|
||||
|
||||
def test_py_cr_prod(self):
|
||||
# Test _Py_cr_prod()
|
||||
_py_cr_prod = _testcapi._py_cr_prod
|
||||
|
||||
self.assertComplexesAreIdentical(_py_cr_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
|
||||
|
@ -211,6 +240,20 @@ class CAPIComplexTest(unittest.TestCase):
|
|||
|
||||
self.assertEqual(_py_c_quot(1, 0j)[1], errno.EDOM)
|
||||
|
||||
def test_py_cr_quot(self):
|
||||
# Test _Py_cr_quot()
|
||||
_py_cr_quot = _testcapi._py_cr_quot
|
||||
|
||||
self.assertComplexesAreIdentical(_py_cr_quot(complex('inf+1j'), 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_c_pow(self):
|
||||
# Test _Py_c_pow()
|
||||
_py_c_pow = _testcapi._py_c_pow
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue