Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,12 @@ The constructors :func:`int`, :func:`float`, and
Python fully supports mixed arithmetic: when a binary arithmetic operator has
operands of different numeric types, the operand with the "narrower" type is
widened to that of the other, where integer is narrower than floating point.
Arithmetic with complex and real operands is defined by the usual mathematical
formula, for example::
Arithmetic with mixed complex and real operands is defined by::

x + complex(u, v) = complex(x + u, v)
x * complex(u, v) = complex(x * u, x * v)
x + complex(u, v) = complex(u, v) + x = complex(x + u, v)
x * complex(u, v) = complex(u, v) * x = complex(x * u, x * v)
complex(u, v) / x = complex(u / x, v / x)
x / complex(u, v) = complex(x, 0) / complex(u, v)

A comparison between numbers of different types behaves as though the exact
values of those numbers were being compared. [2]_
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,17 @@ def test_truediv(self):
self.assertComplexesAreIdentical(float(1)/complex(-INF, -INF),
complex(-0.0, 0))
self.assertComplexesAreIdentical(float(1)/complex(INF, NAN),
complex(0.0, -0.0))
complex(0.0, 0.0))
self.assertComplexesAreIdentical(float(1)/complex(-INF, NAN),
complex(-0.0, -0.0))
self.assertComplexesAreIdentical(float(1)/complex(NAN, INF),
complex(0.0, -0.0))
self.assertComplexesAreIdentical(float(INF)/complex(NAN, INF),
complex(NAN, NAN))

self.assertComplexesAreIdentical(float(-1.0)/complex(0.0, 1.0),
complex(0.0, 1))

def test_truediv_zero_division(self):
for a, b in ZERO_DIVISION:
with self.assertRaises(ZeroDivisionError):
Expand Down
46 changes: 5 additions & 41 deletions Objects/complexobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ _Py_c_quot(Py_complex a, Py_complex b)

return r;
}
#ifdef _M_ARM64
#pragma optimize("", on)
#endif

Py_complex
_Py_cr_quot(Py_complex a, double b)
Expand All @@ -260,51 +263,12 @@ _Py_cr_quot(Py_complex a, double b)
return r;
}

/* an equivalent of _Py_c_quot() function, when 1st argument is real */
Py_complex
_Py_rc_quot(double a, Py_complex b)
{
Py_complex r;
const double abs_breal = b.real < 0 ? -b.real : b.real;
const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;

if (abs_breal >= abs_bimag) {
if (abs_breal == 0.0) {
errno = EDOM;
r.real = r.imag = 0.0;
}
else {
const double ratio = b.imag / b.real;
const double denom = b.real + b.imag * ratio;
r.real = a / denom;
r.imag = (-a * ratio) / denom;
}
}
else if (abs_bimag >= abs_breal) {
const double ratio = b.real / b.imag;
const double denom = b.real * ratio + b.imag;
assert(b.imag != 0.0);
r.real = (a * ratio) / denom;
r.imag = (-a) / denom;
}
else {
r.real = r.imag = Py_NAN;
}

if (isnan(r.real) && isnan(r.imag) && isfinite(a)
&& (isinf(abs_breal) || isinf(abs_bimag)))
{
const double x = copysign(isinf(b.real) ? 1.0 : 0.0, b.real);
const double y = copysign(isinf(b.imag) ? 1.0 : 0.0, b.imag);
r.real = 0.0 * (a*x);
r.imag = 0.0 * (-a*y);
}

return r;
errno = 0;
return _Py_c_quot((Py_complex){a, 0.0}, b);
}
#ifdef _M_ARM64
#pragma optimize("", on)
#endif

Py_complex
_Py_c_pow(Py_complex a, Py_complex b)
Expand Down
Loading