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

Appearance settings

Commit 4a42ceb

Browse filesBrowse files
authored
bpo-44339: Fix math.pow corner case to comply with IEEE 754 (GH-26606)
Change the behaviour of `math.pow(0.0, -math.inf)` and `math.pow(-0.0, -math.inf)` to return positive infinity instead of raising `ValueError`. This makes `math.pow` consistent with the built-in `pow` (and the `**` operator) for this particular special case, and brings the `math.pow` special-case handling into compliance with IEEE 754.
1 parent 3ec3ee7 commit 4a42ceb
Copy full SHA for 4a42ceb

File tree

Expand file treeCollapse file tree

6 files changed

+21
-11
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+21
-11
lines changed

‎Doc/library/math.rst

Copy file name to clipboardExpand all lines: Doc/library/math.rst
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ Power and logarithmic functions
409409
.. function:: pow(x, y)
410410

411411
Return ``x`` raised to the power ``y``. Exceptional cases follow
412-
Annex 'F' of the C99 standard as far as possible. In particular,
412+
the IEEE 754 standard as far as possible. In particular,
413413
``pow(1.0, x)`` and ``pow(x, 0.0)`` always return ``1.0``, even
414414
when ``x`` is a zero or a NaN. If both ``x`` and ``y`` are finite,
415415
``x`` is negative, and ``y`` is not an integer then ``pow(x, y)``
@@ -419,6 +419,11 @@ Power and logarithmic functions
419419
its arguments to type :class:`float`. Use ``**`` or the built-in
420420
:func:`pow` function for computing exact integer powers.
421421

422+
.. versionchanged:: 3.11
423+
The special cases ``pow(0.0, -inf)`` and ``pow(-0.0, -inf)`` were
424+
changed to return ``inf`` instead of raising :exc:`ValueError`,
425+
for consistency with IEEE 754.
426+
422427

423428
.. function:: sqrt(x)
424429

‎Doc/whatsnew/3.11.rst

Copy file name to clipboardExpand all lines: Doc/whatsnew/3.11.rst
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,14 @@ string. (Contributed by Sergey B Kirpichev in :issue:`44258`.)
9696
math
9797
----
9898

99-
Add :func:`math.cbrt()`: return the cube root of x.
100-
(Contributed by Ajith Ramachandran in :issue:`44357`.)
99+
* Add :func:`math.cbrt`: return the cube root of x.
100+
(Contributed by Ajith Ramachandran in :issue:`44357`.)
101+
102+
* The behaviour of two :func:`math.pow` corner cases was changed, for
103+
consistency with the IEEE 754 specification. The operations
104+
``math.pow(0.0, -math.inf)`` and ``math.pow(-0.0, -math.inf)`` now return
105+
``inf``. Previously they raised :exc:`ValueError`. (Contributed by Mark
106+
Dickinson in :issue:`44339`.)
101107

102108

103109
Removed

‎Lib/test/ieee754.txt

Copy file name to clipboardExpand all lines: Lib/test/ieee754.txt
+2-4Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,15 @@ infinity and NaN.
104104
1.0
105105

106106
The power of 0 raised to x is defined as 0, if x is positive. Negative
107-
values are a domain error or zero division error and NaN result in a
107+
finite values are a domain error or zero division error and NaN result in a
108108
silent NaN.
109109

110110
>>> pow(0, 0)
111111
1.0
112112
>>> pow(0, INF)
113113
0.0
114114
>>> pow(0, -INF)
115-
Traceback (most recent call last):
116-
...
117-
ValueError: math domain error
115+
inf
118116
>>> 0 ** -1
119117
Traceback (most recent call last):
120118
...

‎Lib/test/test_math.py

Copy file name to clipboardExpand all lines: Lib/test/test_math.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ def testPow(self):
12301230
self.assertRaises(ValueError, math.pow, 0., -2.)
12311231
self.assertRaises(ValueError, math.pow, 0., -2.3)
12321232
self.assertRaises(ValueError, math.pow, 0., -3.)
1233-
self.assertRaises(ValueError, math.pow, 0., NINF)
1233+
self.assertEqual(math.pow(0., NINF), INF)
12341234
self.assertTrue(math.isnan(math.pow(0., NAN)))
12351235

12361236
# pow(INF, x)
@@ -1256,7 +1256,7 @@ def testPow(self):
12561256
self.assertRaises(ValueError, math.pow, -0., -2.)
12571257
self.assertRaises(ValueError, math.pow, -0., -2.3)
12581258
self.assertRaises(ValueError, math.pow, -0., -3.)
1259-
self.assertRaises(ValueError, math.pow, -0., NINF)
1259+
self.assertEqual(math.pow(-0., NINF), INF)
12601260
self.assertTrue(math.isnan(math.pow(-0., NAN)))
12611261

12621262
# pow(NINF, x)
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Change ``math.pow(±0.0, -math.inf)`` to return ``inf`` instead of raising
2+
``ValueError``. This brings the special-case handling of ``math.pow`` into
3+
compliance with the IEEE 754 standard.

‎Modules/mathmodule.c

Copy file name to clipboardExpand all lines: Modules/mathmodule.c
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2810,8 +2810,6 @@ math_pow_impl(PyObject *module, double x, double y)
28102810
r = y;
28112811
else if (y < 0. && fabs(x) < 1.0) {
28122812
r = -y; /* result is +inf */
2813-
if (x == 0.) /* 0**-inf: divide-by-zero */
2814-
errno = EDOM;
28152813
}
28162814
else
28172815
r = 0.;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.