python math domain errors in math.log function
Question:
I have to use Python math.log(x)
function with values of x from (0, …, 1). Sometimes x may be too close to zero, and Python gives me an error:
ValueError: math domain error
How can I know, what is the domain of definition of math.log
function?
Answers:
You are going over the supported precision, use Decimal class instead.
>>> from math import log
>>> from decimal import Decimal
>>> d = Decimal('1E-1024')
>>> log(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> d.ln()
Decimal('-2357.847135225902780434423250')
As long as your input is within the half-open interval (0, 1] (not including 0), you are fine. You can’t be too close to zero:
>>> math.log(sys.float_info.min)
-708.3964185322641
So simply checking for exactly zero (maybe as the result of an underflow) should be enough, or alternatively catch the exception and handle it.
EDIT: This also holds for the denormal minimum floating point number:
>>> math.log(sys.float_info.min * sys.float_info.epsilon)
-744.4400719213812
I have to use Python math.log(x)
function with values of x from (0, …, 1). Sometimes x may be too close to zero, and Python gives me an error:
ValueError: math domain error
How can I know, what is the domain of definition of math.log
function?
You are going over the supported precision, use Decimal class instead.
>>> from math import log
>>> from decimal import Decimal
>>> d = Decimal('1E-1024')
>>> log(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> d.ln()
Decimal('-2357.847135225902780434423250')
As long as your input is within the half-open interval (0, 1] (not including 0), you are fine. You can’t be too close to zero:
>>> math.log(sys.float_info.min)
-708.3964185322641
So simply checking for exactly zero (maybe as the result of an underflow) should be enough, or alternatively catch the exception and handle it.
EDIT: This also holds for the denormal minimum floating point number:
>>> math.log(sys.float_info.min * sys.float_info.epsilon)
-744.4400719213812