Skip to content
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Merge branch 'main' into complex_powi
  • Loading branch information
serhiy-storchaka committed Nov 26, 2024
commit 5b5320ada8ff8fc4f3ba24018b20a94b429d0456
60 changes: 30 additions & 30 deletions Objects/complexobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,18 +190,31 @@ _Py_c_quot(Py_complex a, Py_complex b)

return r;
}

Py_complex
_Py_dc_quot(double a, Py_complex b)
_Py_cr_quot(Py_complex a, double b)
{
/* Divide a real number by a complex number.
* Same as _Py_c_quot(), but without imaginary part.
*/
Py_complex r; /* the result */
const double abs_breal = b.real < 0 ? -b.real : b.real;
const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
Py_complex r = a;
if (b) {
r.real /= b;
r.imag /= b;
}
else {
errno = EDOM;
r.real = r.imag = 0.0;
}
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) {
/* divide tops and bottom by b.real */
if (abs_breal == 0.0) {
errno = EDOM;
r.real = r.imag = 0.0;
Expand All @@ -210,40 +223,27 @@ _Py_dc_quot(double a, Py_complex b)
const double ratio = b.imag / b.real;
const double denom = b.real + b.imag * ratio;
r.real = a / denom;
r.imag = (- a * ratio) / denom;
r.imag = (-a * ratio) / denom;
}
}
else if (abs_bimag >= abs_breal) {
/* divide tops and bottom by b.imag */
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 {
/* 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. See e.g.
the C11, Annex G.5.2, routine _Cdivd(). */
if (isnan(r.real) && isnan(r.imag)) {
if (isinf(a)
&& isfinite(b.real) && isfinite(b.imag))
{
const double x = copysign(isinf(a) ? 1.0 : 0.0, a);
r.real = Py_INFINITY * (x*b.real);
r.imag = Py_INFINITY * (- x*b.imag);
}
else if ((isinf(abs_breal) || isinf(abs_bimag))
&& isfinite(a))
{
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);
}
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;
Expand Down Expand Up @@ -314,7 +314,7 @@ c_powi(Py_complex x, long n)
if (n > 0)
return c_powu(x, n);
else if (n < 0)
return _Py_dc_quot(1.0, c_powu(x, -n));
return _Py_rc_quot(1.0, c_powu(x, -n));
else
return c_1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me a while to remember that this was 1 + 0j (maybe rename that variable in a separate issue, e.g., ONE_AS_COMPLEX).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now used just in one place. If we need this branch - it's better to inline struct value here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the case, then yes, let's inline it.

}
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.