簡體   English   中英

Python中正整數的位長

[英]Bit length of a positive integer in 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
>>> len(bin(1000))-2
10
>>> len(bin(100))-2
7
>>> len(bin(10))-2
4

注意:不適用於負數,可能需要減去 3 而不是 2

如果您的 Python 版本有它(Python 2 ≥2.7,Python 3 ≥3.1),請使用標准庫中的bit_length方法。

否則, 你建議的len(bin(n))-2很快(因為它是用 Python 實現的)。 請注意,這為 0 返回 1。

否則,一個簡單的方法是重復除以 2(這是一個直接的位移),並計算達到 0 需要多長時間。

def bit_length(n): # return the bit size of a non-negative integer
    bits = 0
    while n >> bits: bits += 1
    return bits

一次移動整個單詞,然后返回並處理最后一個單詞的位,速度要快得多(至少對於大數字 - 快速基准測試表明對於 1000 位數字要快 10 倍以上)。

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 一起使用

只需將值存儲在變量中並訪問它就可以訪問bit_length() 適用於Python 2和3。

n = 5
print(n.bit_length())

此解決方案利用.bit_length()如果可用),並為舊版本的 Python 回退到len(hex(a)) bin ,它的優勢在於它創建了一個更小的臨時字符串,因此它使用的內存更少。

請注意,它為 0 返回 1,但這很容易更改。

_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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM