Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Invalid corner cases (resulting in nan+nanj) in complex division #119372

Closed
Labels
type-bugAn unexpected behavior, bug, or error
@skirpichev

Description

@skirpichev

Bug report

Bug description:

Reproducer:

>>> (1+1j)/(cmath.inf+0j)# ok0j>>> (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 thedenom == 0.0 case) should fix the issue:

diff --git a/Objects/complexobject.c b/Objects/complexobject.cindex 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:

* University). As usual, though, we're still ignoring all IEEE
* endcases.

I'll prepare a PR, if this issue will be accepted.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp