Udi
Udi

Reputation: 30492

Precise math.log(x, 2) in Python

In python, I need to get the rounded down logarithm of positive integers for base 2, including big numbers.

However, since floating point math is used, I might get bad results, for example:

>>> import math
>>> int(math.log(281474976710655, 2))
48

However:

>>> 2 ** 48
281474976710656

So the correct result, rounded down, should be 47.

How can I get the correct value?

Upvotes: 3

Views: 287

Answers (2)

Udi
Udi

Reputation: 30492

In python 3 ints even have an efficient .bit_length() method!

>>> (281474976710655).bit_length()
48
>>> (281474976710656).bit_length()
49

In python 2, instead of using floating point math, count the number of bits:

def log2(n):
    assert n >= 1
    return len(bin(n)) - 3  # bin() returns a string starting with '0b'

(Edited following this comment)

Upvotes: 2

PM 2Ring
PM 2Ring

Reputation: 55469

In Python 3, integers have a .bit_length method, so you should use that to get your rounded down base 2 logarithm.

Here's a short demo:

m = 2 ** 1000
for n in (281474976710655, m-1, m, m+1):
    a = n.bit_length() - 1
    b = 2 ** a
    print(a, b <= n < 2 * b)

output

47 True
999 True
1000 True
1000 True

Upvotes: 4

Related Questions