Skip to content

Commit 97f40c7

Browse files
authored
Merge branch 'main' into gh-127178-install-json-only
2 parents 22b4316 + 71ede11 commit 97f40c7

40 files changed

+609
-212
lines changed

Doc/c-api/complex.rst

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,36 @@ pointers. This is consistent throughout the API.
4444
representation.
4545
4646
47+
.. c:function:: Py_complex _Py_cr_sum(Py_complex left, double right)
48+
49+
Return the sum of a complex number and a real number, using the C :c:type:`Py_complex`
50+
representation.
51+
52+
.. versionadded:: 3.14
53+
54+
4755
.. c:function:: Py_complex _Py_c_diff(Py_complex left, Py_complex right)
4856
4957
Return the difference between two complex numbers, using the C
5058
:c:type:`Py_complex` representation.
5159
5260
61+
.. c:function:: Py_complex _Py_cr_diff(Py_complex left, double right)
62+
63+
Return the difference between a complex number and a real number, using the C
64+
:c:type:`Py_complex` representation.
65+
66+
.. versionadded:: 3.14
67+
68+
69+
.. c:function:: Py_complex _Py_rc_diff(double left, Py_complex right)
70+
71+
Return the difference between a real number and a complex number, using the C
72+
:c:type:`Py_complex` representation.
73+
74+
.. versionadded:: 3.14
75+
76+
5377
.. c:function:: Py_complex _Py_c_neg(Py_complex num)
5478
5579
Return the negation of the complex number *num*, using the C
@@ -62,6 +86,14 @@ pointers. This is consistent throughout the API.
6286
representation.
6387
6488
89+
.. c:function:: Py_complex _Py_cr_prod(Py_complex left, double right)
90+
91+
Return the product of a complex number and a real number, using the C
92+
:c:type:`Py_complex` representation.
93+
94+
.. versionadded:: 3.14
95+
96+
6597
.. c:function:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor)
6698
6799
Return the quotient of two complex numbers, using the C :c:type:`Py_complex`
@@ -71,6 +103,28 @@ pointers. This is consistent throughout the API.
71103
:c:data:`errno` to :c:macro:`!EDOM`.
72104
73105
106+
.. c:function:: Py_complex _Py_cr_quot(Py_complex dividend, double divisor)
107+
108+
Return the quotient of a complex number and a real number, using the C
109+
:c:type:`Py_complex` representation.
110+
111+
If *divisor* is zero, this method returns zero and sets
112+
:c:data:`errno` to :c:macro:`!EDOM`.
113+
114+
.. versionadded:: 3.14
115+
116+
117+
.. c:function:: Py_complex _Py_rc_quot(double dividend, Py_complex divisor)
118+
119+
Return the quotient of a real number and a complex number, using the C
120+
:c:type:`Py_complex` representation.
121+
122+
If *divisor* is zero, this method returns zero and sets
123+
:c:data:`errno` to :c:macro:`!EDOM`.
124+
125+
.. versionadded:: 3.14
126+
127+
74128
.. c:function:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp)
75129
76130
Return the exponentiation of *num* by *exp*, using the C :c:type:`Py_complex`

Doc/library/cmath.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ the function is then applied to the result of the conversion.
2424
imaginary axis we look at the sign of the real part.
2525

2626
For example, the :func:`cmath.sqrt` function has a branch cut along the
27-
negative real axis. An argument of ``complex(-2.0, -0.0)`` is treated as
27+
negative real axis. An argument of ``-2-0j`` is treated as
2828
though it lies *below* the branch cut, and so gives a result on the negative
2929
imaginary axis::
3030

31-
>>> cmath.sqrt(complex(-2.0, -0.0))
31+
>>> cmath.sqrt(-2-0j)
3232
-1.4142135623730951j
3333

34-
But an argument of ``complex(-2.0, 0.0)`` is treated as though it lies above
34+
But an argument of ``-2+0j`` is treated as though it lies above
3535
the branch cut::
3636

37-
>>> cmath.sqrt(complex(-2.0, 0.0))
37+
>>> cmath.sqrt(-2+0j)
3838
1.4142135623730951j
3939

4040

@@ -63,9 +63,9 @@ rectangular coordinates to polar coordinates and back.
6363
along the negative real axis. The sign of the result is the same as the
6464
sign of ``x.imag``, even when ``x.imag`` is zero::
6565

66-
>>> phase(complex(-1.0, 0.0))
66+
>>> phase(-1+0j)
6767
3.141592653589793
68-
>>> phase(complex(-1.0, -0.0))
68+
>>> phase(-1-0j)
6969
-3.141592653589793
7070

7171

Doc/library/stdtypes.rst

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ numeric literal yields an imaginary number (a complex number with a zero real
243243
part) which you can add to an integer or float to get a complex number with real
244244
and imaginary parts.
245245

246+
The constructors :func:`int`, :func:`float`, and
247+
:func:`complex` can be used to produce numbers of a specific type.
248+
246249
.. index::
247250
single: arithmetic
248251
pair: built-in function; int
@@ -262,12 +265,15 @@ and imaginary parts.
262265

263266
Python fully supports mixed arithmetic: when a binary arithmetic operator has
264267
operands of different numeric types, the operand with the "narrower" type is
265-
widened to that of the other, where integer is narrower than floating point,
266-
which is narrower than complex. A comparison between numbers of different types
267-
behaves as though the exact values of those numbers were being compared. [2]_
268+
widened to that of the other, where integer is narrower than floating point.
269+
Arithmetic with complex and real operands is defined by the usual mathematical
270+
formula, for example::
268271

269-
The constructors :func:`int`, :func:`float`, and
270-
:func:`complex` can be used to produce numbers of a specific type.
272+
x + complex(u, v) = complex(x + u, v)
273+
x * complex(u, v) = complex(x * u, x * v)
274+
275+
A comparison between numbers of different types behaves as though the exact
276+
values of those numbers were being compared. [2]_
271277

272278
All numeric types (except complex) support the following operations (for priorities of
273279
the operations, see :ref:`operator-summary`):

Doc/reference/expressions.rst

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@ Arithmetic conversions
2828
.. index:: pair: arithmetic; conversion
2929

3030
When a description of an arithmetic operator below uses the phrase "the numeric
31-
arguments are converted to a common type", this means that the operator
31+
arguments are converted to a common real type", this means that the operator
3232
implementation for built-in types works as follows:
3333

34-
* If either argument is a complex number, the other is converted to complex;
34+
* If both arguments are complex numbers, no conversion is performed;
3535

36-
* otherwise, if either argument is a floating-point number, the other is
37-
converted to floating point;
36+
* if either argument is a complex or a floating-point number, the other is converted to a floating-point number;
3837

3938
* otherwise, both must be integers and no conversion is necessary.
4039

@@ -1323,12 +1322,16 @@ operators and one for additive operators:
13231322
The ``*`` (multiplication) operator yields the product of its arguments. The
13241323
arguments must either both be numbers, or one argument must be an integer and
13251324
the other must be a sequence. In the former case, the numbers are converted to a
1326-
common type and then multiplied together. In the latter case, sequence
1325+
common real type and then multiplied together. In the latter case, sequence
13271326
repetition is performed; a negative repetition factor yields an empty sequence.
13281327

13291328
This operation can be customized using the special :meth:`~object.__mul__` and
13301329
:meth:`~object.__rmul__` methods.
13311330

1331+
.. versionchanged:: 3.14
1332+
If only one operand is a complex number, the other operand is converted
1333+
to a floating-point number.
1334+
13321335
.. index::
13331336
single: matrix multiplication
13341337
pair: operator; @ (at)
@@ -1396,23 +1399,31 @@ floating-point number using the :func:`abs` function if appropriate.
13961399

13971400
The ``+`` (addition) operator yields the sum of its arguments. The arguments
13981401
must either both be numbers or both be sequences of the same type. In the
1399-
former case, the numbers are converted to a common type and then added together.
1402+
former case, the numbers are converted to a common real type and then added together.
14001403
In the latter case, the sequences are concatenated.
14011404

14021405
This operation can be customized using the special :meth:`~object.__add__` and
14031406
:meth:`~object.__radd__` methods.
14041407

1408+
.. versionchanged:: 3.14
1409+
If only one operand is a complex number, the other operand is converted
1410+
to a floating-point number.
1411+
14051412
.. index::
14061413
single: subtraction
14071414
single: operator; - (minus)
14081415
single: - (minus); binary operator
14091416

14101417
The ``-`` (subtraction) operator yields the difference of its arguments. The
1411-
numeric arguments are first converted to a common type.
1418+
numeric arguments are first converted to a common real type.
14121419

14131420
This operation can be customized using the special :meth:`~object.__sub__` and
14141421
:meth:`~object.__rsub__` methods.
14151422

1423+
.. versionchanged:: 3.14
1424+
If only one operand is a complex number, the other operand is converted
1425+
to a floating-point number.
1426+
14161427

14171428
.. _shifting:
14181429

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ Other language changes
230230
They raise an error if the argument is a string.
231231
(Contributed by Serhiy Storchaka in :gh:`84978`.)
232232

233+
* Implement mixed-mode arithmetic rules combining real and complex numbers as
234+
specified by C standards since C99.
235+
(Contributed by Sergey B Kirpichev in :gh:`69639`.)
236+
233237
* All Windows code pages are now supported as "cpXXX" codecs on Windows.
234238
(Contributed by Serhiy Storchaka in :gh:`123803`.)
235239

Include/cpython/complexobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ typedef struct {
99

1010
// Operations on complex numbers.
1111
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
12+
PyAPI_FUNC(Py_complex) _Py_cr_sum(Py_complex, double);
1213
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
14+
PyAPI_FUNC(Py_complex) _Py_cr_diff(Py_complex, double);
15+
PyAPI_FUNC(Py_complex) _Py_rc_diff(double, Py_complex);
1316
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
1417
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
18+
PyAPI_FUNC(Py_complex) _Py_cr_prod(Py_complex, double);
1519
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
20+
PyAPI_FUNC(Py_complex) _Py_cr_quot(Py_complex, double);
21+
PyAPI_FUNC(Py_complex) _Py_rc_quot(double, Py_complex);
1622
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
1723
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
1824

Include/internal/pycore_floatobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ extern PyObject* _Py_string_to_number_with_underscores(
5454

5555
extern double _Py_parse_inf_or_nan(const char *p, char **endptr);
5656

57+
extern int _Py_convert_int_to_double(PyObject **v, double *dbl);
58+
5759

5860
#ifdef __cplusplus
5961
}

Lib/test/test_builtin.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from test.support.import_helper import import_module
3636
from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink)
3737
from test.support.script_helper import assert_python_ok
38+
from test.support.testcase import ComplexesAreIdenticalMixin
3839
from test.support.warnings_helper import check_warnings
3940
from test.support import requires_IEEE_754
4041
from unittest.mock import MagicMock, patch
@@ -151,7 +152,7 @@ def map_char(arg):
151152
def pack(*args):
152153
return args
153154

154-
class BuiltinTest(unittest.TestCase):
155+
class BuiltinTest(ComplexesAreIdenticalMixin, unittest.TestCase):
155156
# Helper to check picklability
156157
def check_iter_pickle(self, it, seq, proto):
157158
itorg = it
@@ -1902,6 +1903,17 @@ def __getitem__(self, index):
19021903
self.assertEqual(sum(xs), complex(sum(z.real for z in xs),
19031904
sum(z.imag for z in xs)))
19041905

1906+
# test that sum() of complex and real numbers doesn't
1907+
# smash sign of imaginary 0
1908+
self.assertComplexesAreIdentical(sum([complex(1, -0.0), 1]),
1909+
complex(2, -0.0))
1910+
self.assertComplexesAreIdentical(sum([1, complex(1, -0.0)]),
1911+
complex(2, -0.0))
1912+
self.assertComplexesAreIdentical(sum([complex(1, -0.0), 1.0]),
1913+
complex(2, -0.0))
1914+
self.assertComplexesAreIdentical(sum([1.0, complex(1, -0.0)]),
1915+
complex(2, -0.0))
1916+
19051917
@requires_IEEE_754
19061918
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
19071919
"sum accuracy not guaranteed on machines with double rounding")

Lib/test/test_capi/test_complex.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
FloatSubclass, Float, BadFloat,
88
BadFloat2, ComplexSubclass)
99
from test.support import import_helper
10+
from test.support.testcase import ComplexesAreIdenticalMixin
1011

1112

1213
_testcapi = import_helper.import_module('_testcapi')
@@ -23,7 +24,7 @@ def __complex__(self):
2324
raise RuntimeError
2425

2526

26-
class CAPIComplexTest(unittest.TestCase):
27+
class CAPIComplexTest(ComplexesAreIdenticalMixin, unittest.TestCase):
2728
def test_check(self):
2829
# Test PyComplex_Check()
2930
check = _testlimitedcapi.complex_check
@@ -171,12 +172,33 @@ def test_py_c_sum(self):
171172

172173
self.assertEqual(_py_c_sum(1, 1j), (1+1j, 0))
173174

175+
def test_py_cr_sum(self):
176+
# Test _Py_cr_sum()
177+
_py_cr_sum = _testcapi._py_cr_sum
178+
179+
self.assertComplexesAreIdentical(_py_cr_sum(-0j, -0.0)[0],
180+
complex(-0.0, -0.0))
181+
174182
def test_py_c_diff(self):
175183
# Test _Py_c_diff()
176184
_py_c_diff = _testcapi._py_c_diff
177185

178186
self.assertEqual(_py_c_diff(1, 1j), (1-1j, 0))
179187

188+
def test_py_cr_diff(self):
189+
# Test _Py_cr_diff()
190+
_py_cr_diff = _testcapi._py_cr_diff
191+
192+
self.assertComplexesAreIdentical(_py_cr_diff(-0j, 0.0)[0],
193+
complex(-0.0, -0.0))
194+
195+
def test_py_rc_diff(self):
196+
# Test _Py_rc_diff()
197+
_py_rc_diff = _testcapi._py_rc_diff
198+
199+
self.assertComplexesAreIdentical(_py_rc_diff(-0.0, 0j)[0],
200+
complex(-0.0, -0.0))
201+
180202
def test_py_c_neg(self):
181203
# Test _Py_c_neg()
182204
_py_c_neg = _testcapi._py_c_neg
@@ -189,6 +211,13 @@ def test_py_c_prod(self):
189211

190212
self.assertEqual(_py_c_prod(2, 1j), (2j, 0))
191213

214+
def test_py_cr_prod(self):
215+
# Test _Py_cr_prod()
216+
_py_cr_prod = _testcapi._py_cr_prod
217+
218+
self.assertComplexesAreIdentical(_py_cr_prod(complex('inf+1j'), INF)[0],
219+
complex('inf+infj'))
220+
192221
def test_py_c_quot(self):
193222
# Test _Py_c_quot()
194223
_py_c_quot = _testcapi._py_c_quot
@@ -211,6 +240,20 @@ def test_py_c_quot(self):
211240

212241
self.assertEqual(_py_c_quot(1, 0j)[1], errno.EDOM)
213242

243+
def test_py_cr_quot(self):
244+
# Test _Py_cr_quot()
245+
_py_cr_quot = _testcapi._py_cr_quot
246+
247+
self.assertComplexesAreIdentical(_py_cr_quot(complex('inf+1j'), 2**1000)[0],
248+
INF + 2**-1000*1j)
249+
250+
def test_py_rc_quot(self):
251+
# Test _Py_rc_quot()
252+
_py_rc_quot = _testcapi._py_rc_quot
253+
254+
self.assertComplexesAreIdentical(_py_rc_quot(1.0, complex('nan-infj'))[0],
255+
0j)
256+
214257
def test_py_c_pow(self):
215258
# Test _Py_c_pow()
216259
_py_c_pow = _testcapi._py_c_pow

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy