1 = 0b1 -> 1
5 = 0b101 -> 3
10 = 0b1010 -> 4
100 = 0b1100100 -> 7
1000 = 0b1111101000 -> 10
…
Как я могу получить длину в битах целого числа, то есть количество битов, необходимых для представления положительного целого числа в Python?
1 = 0b1 -> 1
5 = 0b101 -> 3
10 = 0b1010 -> 4
100 = 0b1100100 -> 7
1000 = 0b1111101000 -> 10
…
Как я могу получить длину в битах целого числа, то есть количество битов, необходимых для представления положительного целого числа в Python?
В python 2.7+ есть метод int.bit_length()
:
>>> a = 100
>>> a.bit_length()
7
bit_length()
для целочисленного литерала.
- person Eric Walker; 27.10.2019
2.
, это литерал с плавающей запятой, а не целочисленный литерал, за которым следует оператор доступа к полю. Поставьте пробел 2 .bit_length()
или используйте круглые скобки (2).bit_length()
.
- person Gilles 'SO- stop being evil'; 11.11.2019
>>> len(bin(1000))-2
10
>>> len(bin(100))-2
7
>>> len(bin(10))-2
4
Примечание: не работает с отрицательными числами, возможно, потребуется вычесть 3 вместо 2.
len(bin(abs(n)))-2
- person endolith; 12.12.2013
0
.
- person phihag; 13.07.2015
len("{:b}".format(x))
, чтобы не выполнять вычитание.
- person pech0rin; 24.11.2015
bin(n).lstrip('-0b')
отлично работает с отрицательными числами, что эквивалентно bit_length
.
- person Tab; 20.09.2019
Если в вашей версии Python он есть (≥2.7 для Python 2, ≥3.1 для Python 3), используйте _ 1_ из стандартной библиотеки.
В противном случае 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
даже быстрее, но это не важно, так как это неправильно.)
Здесь мы также можем использовать нарезку.
Для положительных целых чисел мы начинаем с 2:
len(bin(1)[2:])
len(bin(5)[2:])
len(bin(10)[2:])
len(bin(100)[2:])
len(bin(1000)[2:])
который напечатает:
1
3
4
7
10
Для отрицательных целых чисел мы начинаем с 3:
len(bin(-1)[3:])
len(bin(-5)[3:])
len(bin(-10)[3:])
len(bin(-100)[3:])
len(bin(-1000)[3:])
который напечатает:
1
3
4
7
10
Вот еще один способ:
def number_of_bits(n):
return len('{:b}'.format(n))
Я полагаю, не так эффективно, но не отображается ни в одном из предыдущих ответов ...
def bitcounter(n):
return math.floor(math.log(n,2)) + 1
РЕДАКТИРОВАТЬ исправлено, теперь он работает с 1
math.log(n, 2)
не дает совершенно правильного результата. math.log(2**29, 2)
= 29.000000000000004, например.
- person endolith; 09.12.2013
math.log2
для Python 3, который действительно дает точные результаты для чисел с плавающей запятой, которые являются точными степенями двойки.
- person Mark Dickinson; 09.12.2013
log(2**n, 2) >= n
для всех неотрицательных n
, так что math.floor(math.log(n, 2)) + 1
по-прежнему дает правильный результат для степеней 2. Хотя, конечно, не для всех n
; n = 2**48 - 1
кажется наименьшим значением, для которого он не работает.
- person Mark Dickinson; 09.12.2013
Это решение использует .bit_length()
, если доступно, и возвращается к len(hex(a))
для более старых версий Python. Его преимущество перед bin
в том, что он создает временную строку меньшего размера, поэтому использует меньше памяти.
Обратите внимание, что он возвращает 1 вместо 0, но это легко изменить.
_HEX_BIT_COUNT_MAP = {
'0': 0, '1': 1, '2': 2, '3': 2, '4': 3, '5': 3, '6': 3, '7': 3}
def bit_count(a):
"""Returns the number of bits needed to represent abs(a). Returns 1 for 0."""
if not isinstance(a, (int, long)):
raise TypeError
if not a:
return 1
# Example: hex(-0xabc) == '-0xabc'. 'L' is appended for longs.
s = hex(a)
d = len(s)
if s[-1] == 'L':
d -= 1
if s[0] == '-':
d -= 4
c = s[3]
else:
d -= 3
c = s[2]
return _HEX_BIT_COUNT_MAP.get(c, 4) + (d << 2)
# Use int.bit_length and long.bit_length introduced in Python 2.7 and 3.x.
if getattr(0, 'bit_length', None):
__doc = bit_count.__doc__
def bit_count(a):
return a.bit_length() or 1
bit_count.__doc__ = __doc
assert bit_count(0) == 1
assert bit_count(1) == 1
assert bit_count(2) == 2
assert bit_count(3) == 2
assert bit_count(63) == 6
assert bit_count(64) == 7
assert bit_count(75) == 7
assert bit_count(2047) == 11
assert bit_count(2048) == 12
assert bit_count(-4007) == 12
assert bit_count(4095) == 12
assert bit_count(4096) == 13
assert bit_count(1 << 1203) == 1204
assert bit_count(-(1 << 1203)) == 1204
assert bit_count(1 << 1204) == 1205
assert bit_count(1 << 1205) == 1206
assert bit_count(1 << 1206) == 1207
except AttributeError
?
- person endolith; 12.12.2013
AttributeError
считается более Pythonic. например, stackoverflow.com/a/12265860/687467
- person yati sagade; 18.04.2015