[Python-Dev] histerical math.log(zero)
Tim Peters
tim.one at comcast.net
Mon Aug 4 13:31:28 EDT 2003
[Samuele Pedroni]
> math.log raises different unrelated exceptions depending on the type
> of a zero argument:
It may, and probably does on most platforms. Which exception gets raised
for a float 0.0, and even whether an exception gets raised at all in that
case, depends on what the platform libm does. Standard C allows a lot of
variation here.
> >>> math.log(0)
>
> Traceback (most recent call last):
> File "<pyshell#1>", line 1, in -toplevel-
> math.log(0)
> OverflowError: math range error
> >>> math.log(0L)
Python handles log(long) itself, so the exception in this case is
platform-independent.
> Traceback (most recent call last):
> File "<pyshell#2>", line 1, in -toplevel-
> math.log(0L)
> ValueError: math domain error
>
> >>> math.log(0.0)
>
> Traceback (most recent call last):
> File "<pyshell#4>", line 1, in -toplevel-
> math.log(0.0)
> OverflowError: math range error
>
> should this stay this way?
Unless we write our own libm, consistency is hopeless. Note that the 2.3
docs (for the math module) address this up-front:
Note: The math module consists mostly of thin wrappers around the
platform C math library functions. Behavior in exceptional cases is
loosely specified by the C standards, and Python inherits much of
its math-function error-reporting behavior from the platform C
implementation. As a result, the specific exceptions raised in
error cases (and even whether some arguments are considered to be
exceptional at all) are not defined in any useful cross-platform
or cross-release way. For example, whether math.log(0) returns
-Inf or raises ValueError or OverflowError isn't defined, and in
cases where math.log(0) raises OverflowError, math.log(0L) may
raise ValueError instead.
CPython started life with "classic" (pre-754) libms, where ERANGE got mapped
to OverflowError and EDOM to ValueError. I view 0 as not being in the
domain of log(), so deliberately raised ValueError for a 0L argument. The
best thing to do in an IEEE-754-ish system is probably to raise
ZeroDivisionError (whose generalized meaning isn't literally division by 0,
but "there's a singularity here"); and, indeed, the C99 standard requires
that implementations choosing to support the 754 gimmicks must raise the 754
divide-by-0 exception (and return minus infinity) for log(+0) and log(-0).
doesn't-matter-where-you-want-to-go-you-can't-get-there-from-here-ly
y'rs - tim
More information about the Python-Dev
mailing list