From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Sun, 31 May 2026 10:04:18 +0000 (+0200) Subject: [3.15] Correct frexp() docs for zero and non-finite numbers (GH-149753) (GH-150652) X-Git-Tag: v3.15.0b2~32 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=c5655dfe51764e7e4dc2ba515acd03b8c96823a9;p=thirdparty%2FPython%2Fcpython.git [3.15] Correct frexp() docs for zero and non-finite numbers (GH-149753) (GH-150652) 0.5 <= abs(m) < 1 is only true for finite nonzero numbers (cherry picked from commit 5b5ffce05c211a5b0b74cd95eeb4c463614ee136) Co-authored-by: Sergey B Kirpichev --- diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 9cc8c5d68863..41a9a0ab55d8 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -255,10 +255,12 @@ Floating point manipulation functions .. function:: frexp(x) - Return the mantissa and exponent of *x* as the pair ``(m, e)``. *m* is a float - and *e* is an integer such that ``x == m * 2**e`` exactly. If *x* is zero, - returns ``(0.0, 0)``, otherwise ``0.5 <= abs(m) < 1``. This is used to "pick - apart" the internal representation of a float in a portable way. + Return the mantissa and exponent of *x* as the pair ``(m, e)``. + If *x* is a finite nonzero number, then *m* is a float with + ``0.5 <= abs(m) < 1.0`` and an integer *e* is such that + ``x == m * 2**e`` exactly. Else, return ``(x, 0)``. + This is used to "pick apart" the internal representation of + a float in a portable way. Note that :func:`frexp` has a different call/return pattern than its C equivalents: it takes a single argument and return a pair of diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 6a1b1a45d1d9..a5e583c180de 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -198,8 +198,9 @@ PyDoc_STRVAR(math_frexp__doc__, "\n" "Return the mantissa and exponent of x, as pair (m, e).\n" "\n" -"m is a float and e is an int, such that x = m * 2.**e.\n" -"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."); +"If x is a finite nonzero number, then m is a float with\n" +"0.5 <= abs(m) < 1.0 and an integer e is such that\n" +"x == m * 2**e exactly. Else, return (x, 0)."); #define MATH_FREXP_METHODDEF \ {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__}, @@ -1163,4 +1164,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=80c666aef8d2df36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3452ce8caa2d1bd7 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index a7616ad70e4a..5636a00afe10 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1438,13 +1438,14 @@ math.frexp Return the mantissa and exponent of x, as pair (m, e). -m is a float and e is an int, such that x = m * 2.**e. -If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. +If x is a finite nonzero number, then m is a float with +0.5 <= abs(m) < 1.0 and an integer e is such that +x == m * 2**e exactly. Else, return (x, 0). [clinic start generated code]*/ static PyObject * math_frexp_impl(PyObject *module, double x) -/*[clinic end generated code: output=03e30d252a15ad4a input=96251c9e208bc6e9]*/ +/*[clinic end generated code: output=03e30d252a15ad4a input=215cf8ea28a0959b]*/ { int i; /* deal with special cases directly, to sidestep platform