Skip to content

Commit d5bd0a0

Browse files
committed
gh-133895: correct values of cmath.cosh/sinh in case of overflows
This is a split-off gh-134995. The C17 standard says (cis(y) is defined as cos(y) + i sin(y)): * ccosh(+∞ + i0) returns +∞ + i0. * ccosh(+∞ + iy) returns +∞ cis(y), for finite nonzero y. and * csinh(+∞ + i0) returns +∞ + i0. * csinh(+∞ + iy) returns +∞ cis(y), for positive finite y. So far values, computed for exceptions, aren't accessible from the pure-Python world, yet we are trying to be correct in other places. The Lib/test/mathdata/cmath_testcases.txt has data points with correct numbers (see cosh0032 and sinh0032). Also, use AC magic for the rect() value.
1 parent 5b3a826 commit d5bd0a0

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

Modules/clinic/cmathmodule.c.h

Lines changed: 15 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/cmathmodule.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ cmath_cosh_impl(PyObject *module, Py_complex z)
438438
x_minus_one = z.real - copysign(1., z.real);
439439
r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E;
440440
r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E;
441+
if (isnan(r.imag)) {
442+
r.imag = copysign(0., z.real*z.imag);
443+
}
441444
} else {
442445
r.real = cos(z.imag) * cosh(z.real);
443446
r.imag = sin(z.imag) * sinh(z.real);
@@ -674,6 +677,9 @@ cmath_sinh_impl(PyObject *module, Py_complex z)
674677
x_minus_one = z.real - copysign(1., z.real);
675678
r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E;
676679
r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E;
680+
if (isnan(r.imag)) {
681+
r.imag = copysign(0., z.imag);
682+
}
677683
} else {
678684
r.real = cos(z.imag) * sinh(z.real);
679685
r.imag = sin(z.imag) * cosh(z.real);
@@ -972,7 +978,7 @@ cmath_polar_impl(PyObject *module, Py_complex z)
972978
static Py_complex rect_special_values[7][7];
973979

974980
/*[clinic input]
975-
cmath.rect
981+
cmath.rect -> Py_complex_protected
976982
977983
r: double
978984
phi: double
@@ -981,9 +987,9 @@ cmath.rect
981987
Convert from polar coordinates to rectangular coordinates.
982988
[clinic start generated code]*/
983989

984-
static PyObject *
990+
static Py_complex
985991
cmath_rect_impl(PyObject *module, double r, double phi)
986-
/*[clinic end generated code: output=385a0690925df2d5 input=24c5646d147efd69]*/
992+
/*[clinic end generated code: output=74ff3d17585f3388 input=50e60c5d28c834e6]*/
987993
{
988994
Py_complex z;
989995
errno = 0;
@@ -1027,11 +1033,7 @@ cmath_rect_impl(PyObject *module, double r, double phi)
10271033
z.imag = r * sin(phi);
10281034
errno = 0;
10291035
}
1030-
1031-
if (errno != 0)
1032-
return math_error();
1033-
else
1034-
return PyComplex_FromCComplex(z);
1036+
return z;
10351037
}
10361038

10371039
/*[clinic input]

0 commit comments

Comments
 (0)