python inverte un pattern binario all'interno di un intero
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: 56ms3 °
x = ((x & 0x00FF) << 8) | (x >> 8): 65 msNon 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
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
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'
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)
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'))