New submission from Mark Dickinson <dicki...@gmail.com>:

For floats x and y, x ** y and math.pow(x, y) mostly agree. There are three 
points of difference:

1. if x is finite and negative and y is finite and non-integral, then x ** y 
returns a complex number, while math.pow(x, y) raises ValueError
2. for cases where x ** y raises ZeroDivisionError (for example, 0.0 ** -1.0), 
math.pow(x, y) raises ValueError instead
3. the special cases 0.0 ** -inf and (-0.0) ** -inf return inf, but the 
equivalent math.pow calls raise ValueError

That third discrepancy is a surprising one: in particular, it's the only case 
where math.pow does not follow IEEE 754 rules.

Note that the math.pow behaviour is not accidental. The special cases were 
based on C99 Annex F (and are documented to do so), but the standards 
themselves have evolved here. In chronological order:

- IEEE 754-1985 did not cover transcendental functions, so has nothing to say 
on the topic of special values for pow.
- C99 §F.9.4.4 implies that pow(0, -inf) should raise the "divide-by-zero" 
exception; the relevant clause covers pow(0, y) for any y satisfying y < 0 and 
y not an odd integer
- IEEE 754-2008 §9.2.1 has an explicit clause specifying that pow(0, -inf) 
should be inf and that the operation does not raise any exception.
- C11 §F.10.4.4 mentions the case pow(0, -inf) explicitly and now says "may 
raise the divide-by-zero floating-point exception". The "may" is significant: 
other clauses simply say "raises the "divide-by-zero" floating-point exception".
- IEEE 754-2019 §9.2.1 is unchanged from IEEE 754-2008 for this particular 
special case.
- Similarly, C17 is unchanged from C11 in this respect.

For Python 3.11, I propose changing the behaviour of math.pow in this corner 
case so that it returns inf instead of raising. This would make math.pow 
conformant with IEEE 754, consistent with C11 and later, and consistent with 
the built-in pow function.

----------
messages: 395277
nosy: mark.dickinson
priority: normal
severity: normal
status: open
title: Discrepancy between math.pow(0.0, -inf) and 0.0**-inf
versions: Python 3.11

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue44339>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to