Python инвертирует двоичный шаблон в целое число
Есть ли быстрая возможность перевернуть двоичное число в Python?
Пример: у меня есть число 11 в двоичном формате 0000000000001011 с 16 битами. Теперь я ищу быструю функцию f, которая возвращает 1101000000000000 (десятичное число 53248). Таблицы поиска не являются решениями, поскольку я хочу масштабировать их до 32-битных чисел. Спасибо за ваши усилия.
Редактировать:
Спектакли . Я тестировал код для всех шаблонов 2 ^ 16 несколько раз.
победителем являются частично справочные таблицы: 30 мс
2-й
int(format(num, '016b')[::-1], 2)из комментариев: 56 мс3-е место
x = ((x & 0x00FF) << 8) | (x >> 8): 65 мсЯ не ожидал, что мой подход будет настолько ужасно медленным, но это так. ок. 320 мс. Небольшое улучшение за счет использования + вместо | 300 мс
bytes(str(num).encode('utf-8'))боролся за 2-е место, но почему-то код не давал правильных ответов. Скорее всего, потому что я ошибся, снова преобразовав их в целое число.
большое спасибо за ваш вклад. Я был очень удивлен.
Ответы
Это может быть быстрее при использовании небольшой 8-битной таблицы поиска:
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
Я думаю, вы можете просто использовать нарезку, чтобы получить то, что вы ищете:
b=bytes('0000000000001011'.encode('utf-8'))
>>> b
b'0000000000001011'
>>> b[::-1]
b'1101000000000000'
Это есть, но в Python это кажется медленнее, чем предложенное Маттиасом решение 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)
Мой текущий подход состоит в том, чтобы получить доступ к битам с помощью сдвига битов и маски и сдвинуть их в зеркальном номере, пока они не достигнут места назначения. Тем не менее я чувствую, что есть возможности для улучшения.
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'))