You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
assignee=Noneclosed_at=<Date2021-06-12.09:27:42.438>created_at=<Date2021-06-07.19:13:36.770>labels= ['type-feature', 'library', '3.11']
title='Discrepancy between math.pow(0.0, -inf) and 0.0**-inf'updated_at=<Date2021-06-12.09:27:42.438>user='https://github.com/mdickinson'
For floats x and y, x ** y and math.pow(x, y) mostly agree. There are three points of difference:
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
for cases where x ** y raises ZeroDivisionError (for example, 0.0 ** -1.0), math.pow(x, y) raises ValueError instead
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.
What about math.pow(0.0, -1.0)? Should it return -inf or raise ZeroDivisionError?
Neither: it should raise ValueError, as it does now. This matches IEEE 754 along with the math module's mapping of IEEE 754 floating-point exceptions to Python exceptions.
And what about math.pow(-0.0, -inf)?
This should return inf, the same as math.pow(0.0, -inf). The relevant clauses of the C standard and IEEE 754 cover both these cases; I should have written math.pow(±0.0, -inf) throughout my previous message.