46

why doesn't it exist?

import math
[x for x in dir(math) if 'log' in x]
>>> ['log', 'log10', 'log1p']

I know I can do log(x,2), but log2 is really common, so I'm kind of baffled.

Oh, it looks like it's only defined in C99, not C90, I guess that answers my question. Still seems kind of silly.

BCS
  • 75,627
  • 68
  • 187
  • 294
nick maxwell
  • 1,441
  • 3
  • 16
  • 22

3 Answers3

55

I think you've answered your own question. :-) There's no log2(x) because you can do log(x, 2). As The Zen of Python (PEP 20) says, "There should be one-- and preferably only one --obvious way to do it."

That said, log2 was considered in Issue3366 (scroll down to the last 3 messages) which added several other C99 math functions to the math module for Python 2.7 and 3.2.

Edit: log2 was reconsidered in Issue11888 and added in Python 3.3.

Daniel Stutzbach
  • 74,198
  • 17
  • 88
  • 77
  • 18
    That begs the question, why does `log10` exist? – Mark Ransom Jun 07 '10 at 21:31
  • 5
    log10 is C89, so it exists on all common platforms, including Windows. So it's trivial for Python to add a wrapper round it. – Mark Dickinson Jun 07 '10 at 21:31
  • 1
    Well, fair enough. I guess people like log10 enough to include it specially but not log2. It looks like it's actually in numpy, so that solves that. – nick maxwell Jun 07 '10 at 22:59
  • 1
    [The docs](http://docs.python.org/2/library/math.html#math.log10) actually recommend that you use `log10(x)` instead of `log(x, 10)`: "math.log10(x) Return the base-10 logarithm of x. This is usually more accurate than log(x, 10)" So is `log(x, 2)` less accurate than a dedicated implementation? – endolith Oct 10 '13 at 20:58
  • 3
    For example, if you try to find the power of 2 greater than or equal to 2**29 (= itself), using `2**ceil(log(n, 2))`, you'll get the wrong answer, because `math.log(n, 2)` = 29.000000000000004 instead of 29.0. `np.log2(n)` = 29.0 exactly, so produces the correct answer. – endolith Dec 09 '13 at 03:01
6

I'm not sure that there is that you want, but:

-- From math point of view you can do for example math.log(x)/math.log(2).

-- If input X has an integral type and you are waiting for the integral rounded result - you can do it rather faster with right shifting. This works with SHR command and without Taylor series + local interpolation, which is under the hood of libc log() calls.

dhanush-ai1990
  • 325
  • 4
  • 20
Konstantin Burlachenko
  • 5,233
  • 2
  • 41
  • 40
0

For anyone else arriving this late, Python 3.3 and later has math.log2. It's "usually more accurate than log(x, 2)," or log(x)/log(2), I would guess. There is also int.bit_length().

Log to the base 2 in python

https://docs.python.org/3/library/math.html