Closed
Description
Bug report
Bug description:
Reproducer:
>>> (1+1j)/(cmath.inf+0j) # ok
0j
>>> (1+1j)/cmath.infj # ok
-0j
>>> (1+1j)/(cmath.inf+cmath.infj) # should be 0j, isn't?
(nan+nanj)
c.f. MPC:
>>> gmpy2.mpc('(1+1j)')/gmpy2.mpc('(inf+infj)')
mpc('0.0+0.0j')
It seems, there are not so much such cases (i.e. when the numerator is finite and the denominator has infinite and infinite/nan components, or if the numerator has infinite components and the denominator has zeros). Following patch (mostly literally taken from the C11 Annex G.5.1 _Cdivd()
's example, except for the denom == 0.0
case) should fix the issue:
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index b3d57b8337..9041cbb8ae 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -122,6 +122,27 @@ _Py_c_quot(Py_complex a, Py_complex b)
/* At least one of b.real or b.imag is a NaN */
r.real = r.imag = Py_NAN;
}
+
+ /* Recover infinities and zeros that computed as nan+nanj */
+ if (isnan(r.real) && isnan(r.imag)) {
+ if ((isinf(a.real) || isinf(a.imag))
+ && isfinite(b.real) && isfinite(b.imag))
+ {
+ const double x = copysign(isinf(a.real) ? 1.0 : 0.0, a.real);
+ const double y = copysign(isinf(a.imag) ? 1.0 : 0.0, a.imag);
+ r.real = Py_INFINITY * (x*b.real + y*b.imag);
+ r.imag = Py_INFINITY * (y*b.real - x*b.imag);
+ }
+ else if ((fmax(abs_breal, abs_bimag) == Py_INFINITY)
+ && isfinite(a.real) && isfinite(a.imag))
+ {
+ 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.real*x + a.imag*y);
+ r.imag = 0.0 * (a.imag*x - a.real*y);
+ }
+ }
+
return r;
}
Perhaps, we could also clear ending remark in _Py_c_quot()
comment:
cpython/Objects/complexobject.c
Lines 91 to 92 in d065edf
I'll prepare a PR, if this issue will be accepted.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response