28

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?

Felix
  • 3,351
  • 6
  • 40
  • 68

2 Answers2

27

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
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • That's what I thought, but while `sys.float_info.min=2.2250738585072014e-308`, I still can do `math.log(2e-318)` on my system (and get `-731.5289...` as an answer). What's up with that? –  Sep 30 '13 at 13:55
  • @Evert: That's a ["dnormal number"](http://en.wikipedia.org/wiki/Denormal_number), and they can actually be the cause of your problem. – Sven Marnach Sep 30 '13 at 14:10
  • Ah, learned something. I suspected `epsilon` was involved, but I'm still surprised it actually throws a correct answer for `math.log(5e-324)`, even though it's an underflow. Time to read [Wikipedia on this](http://en.wikipedia.org/wiki/Double-precision_floating-point_format). –  Sep 30 '13 at 14:28
7

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')
ismail
  • 46,010
  • 9
  • 86
  • 95