diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 3bcaba0b3e1eba..fdb130a2a9607b 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -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]_ diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 0c7e7341f13d4e..e128595d63c76c 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -187,7 +187,7 @@ 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), @@ -195,6 +195,9 @@ def test_truediv(self): 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): diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 3612c2699a557d..721c6a10cc359c 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -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) @@ -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)