python inverte un pattern binario all'interno di un intero

Sep 02 2020

C'è una rapida possibilità di invertire un numero binario in Python?

Esempio: ho il numero 11 in binario 0000000000001011 con 16 bit. Ora sto cercando una funzione veloce f, che restituisce 1101000000000000 (53248 decimale). Le tabelle di ricerca non sono soluzioni poiché voglio che si riduca a numeri a 32 bit. Grazie per l'impegno.

Modificare:

Spettacoli . Ho testato più volte il codice per tutti i pattern 2 ^ 16.

  • vincenti sono le tabelle di ricerca parziale: 30 ms

  • 2 ° int(format(num, '016b')[::-1], 2)dai commenti: 56ms

  • 3 ° x = ((x & 0x00FF) << 8) | (x >> 8): 65 ms

  • Non mi aspettavo che il mio approccio fosse così orribilmente lento, ma lo è. ca. 320 ms. Piccolo miglioramento utilizzando + invece di | 300 ms

  • bytes(str(num).encode('utf-8'))lottato per il 2 ° posto ma in qualche modo il codice non ha fornito risposte valide. Molto probabilmente perché ho commesso un errore trasformandoli di nuovo in un numero intero.

grazie mille per il tuo contributo. Sono rimasto piuttosto sorpreso.

Risposte

3 HL Sep 02 2020 at 04:36

Questo potrebbe essere più veloce utilizzando una piccola tabella di ricerca a 8 bit:

num = 11
# One time creation of 8bit lookup
rev = [int(format(b, '08b')[::-1], base=2) for b in range(256)]

# Run for each number to be flipped.
lower_rev = rev[num & 0xFF] << 8
upper_rev = rev[(num & 0xFF00) >> 8]
flipped = lower_rev + upper_rev
1 Ethan Sep 02 2020 at 03:55

Penso che puoi semplicemente usare l'affettatura per ottenere ciò che stai cercando:

b=bytes('0000000000001011'.encode('utf-8'))
>>> b
b'0000000000001011'
>>> b[::-1]
b'1101000000000000'
1 superbrain Sep 02 2020 at 04:27

C'è questo, ma in Python sembra più lento della soluzione proposta da Matthias int-> str-> int.

x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1)
x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2)
x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4)
x = ((x & 0x00FF) << 8) | (x >> 8)
1 DuDa Sep 02 2020 at 03:48

Il mio approccio attuale consiste nell'accedere ai bit tramite spostamento di bit e maschera e spostarli nel numero dello specchio finché non raggiungono la loro destinazione. Ho ancora la sensazione che ci siano margini di miglioramento.

num = 11
print(format(num, '016b'))

right = num
left = 0
for i in range(16):
  tmp = right & 1
  left = (left << 1 ) | tmp
  right = right >> 1


print(format(left, '016b'))