Если ваша версия Python имеет его (≥2.7 для Python 2, ≥3.1 для Python 3), используйте метод bit_length
из стандартной библиотеки.
В противном случае len(bin(n))-2
в соответствии с предложением ВАС быстро (потому что оно реализовано в Python). Обратите внимание, что это возвращает 1 для 0.
В противном случае простой метод состоит в том, чтобы повторно делить на 2 (что является прямым сдвигом битов) и подсчитывать, сколько времени требуется для достижения 0.
def bit_length(n): # return the bit size of a non-negative integer
bits = 0
while n >> bits: bits += 1
return bits
Это значительно быстрее (по крайней мере, для больших чисел - быстрые тесты говорят, что более чем в 10 раз быстрее для 1000 цифр) сдвигаться на целые слова за раз, затем возвращаться и работать с битами последнего слова.
def bit_length(n): # return the bit size of a non-negative integer
if n == 0: return 0
bits = -32
m = 0
while n:
m = n
n >>= 32; bits += 32
while m: m >>= 1; bits += 1
return bits
В моем быстром тесте len(bin(n))
вышел значительно быстрее, чем даже версия с размером слова. Хотя bin(n)
создает строку, которая немедленно отбрасывается, она выходит на первое место благодаря наличию внутреннего цикла, скомпилированного для машинного кода. (math.log
еще быстрее, но это не важно, поскольку это неправильно.)