2016-03-05 4 views
2

Я делаю двоичную арифметику в Python. Мне кажется, это неудобно, потому что есть лучший способ. Приведенный пример кода создает список двоичных цифр, создает обратный список и создает абсолютную разницу. любые предложения по лучшей технике будут оценены.Бинарная арифметика Python

for (i, j, k, n, m) in [(i, j, k, n, m)for i in range(2) for j in range(2) \ 
       for k in range(2)for n in range(2) for m in range(2)]: 

s = [i, j, k, n, m] # binary sequence 
r = s[::-1]  # reversed sequence 

sbin = '0b'  # create binary number as string 
rbin = '0b' 
for a in range(5): 
    sbin += str(s[a]) 
    rbin += str(r[a]) 

sbb = int(sbin,2) # create binary number 
rbb = int(rbin,2) 
v = abs(sbb - rbb) # take absolute difference as integers 

dif = bin(v)   # convert back to binary 
print(sbin, rbin, dif, v) 
+0

с ошибкой в ​​названии извините, что, возможно, ограничивает ответы – Graybits

ответ

1

это вариант:

BITSIZE = 5 

for i in range(1<<BITSIZE): 
    a = i 
    b = 0 
    for k in range(BITSIZE): # b = reversed_bits(a) 
     b <<= 1 
     b ^= i&1 
     i >>= 1 
    print(' {:05b} {:05b}'.format(a, b)) 
    print(a, b, abs(a-b)) 

вместо перечисления отдельных битов, первый цикл отсчетов от 0 к 2^5-1 (1<<5 сдвигает бит до 5 мест, которые составляет 2^5). остальное - это просто вопрос об изменении битов (цикл выше k).

это выходы:

00000 00000 
0 0 0 
    00001 10000 
1 16 15 
    00010 01000 
2 8 6 
    00011 11000 
3 24 21 
    00100 00100 
4 4 0 
    00101 10100 
5 20 15 
... 
    11110 01111 
30 15 15 
    11111 11111 
31 31 0 

бинарные операции питона можно увидеть здесь: https://wiki.python.org/moin/BitwiseOperators


как указал Reti43 это может быть написано немного более компактен:

BITSIZE = 5 
for a in range(1<<BITSIZE): 
    b = 0 
    for k in range(BITSIZE): # b = reversed_bits(a) 
     b = (b << 1) | ((a >> k) & 1) 
    print(a, b, abs(a-b)) 
+0

На мой взгляд, 'for k in range (BITSIZE): b = (b << 1) | ((a >> k) & 1)' более прямой и понятный. – Reti43

+0

@ Reti43 обновил ответ, включив в него алгоритм битового реверса. благодаря! –

0

Как показывает ваша техника абсолютной разницы s, целочисленная арифметика уже выполняется в двоичном формате и поэтому должна быть максимально задействована. Хотя могут быть проблемы с подписанными количествами.

Я бы утверждать ваше вложенное 5 глубокого список постижения просто генерирует числа от 1 до 31 в двоичной системе, так почему бы не s = range(32) делать любые арифметические операции как с целыми числами и использовать bin, чтобы получить бинарную строку на результате.

Реверсирование строки цифр обычно не является обычным делом для двоичной арифметики, но представляет интересную проблему с относительно простым решением. Следующая функция не имеет проверки ошибок, так как предполагает, что вы пройдете только действительный вывод функции bin. Он учитывает, что двоичное представление всегда начинается с '0b', и вы не хотите, чтобы это было отменено.

def reverse_binstr(b): 
    return b[0:2] + b[:1:-1] 
0

Используя свой собственный код, вы можете избежать некоторых unnecesary переменных и упростить итерации:

from itertools import product 
BITS = ('0','1') 

for s in product(*[BITS]*5): 
    sbin = ''.join(s) 
    diff = abs(int(sbin, 2) - int(sbin[::-1], 2)) 
    print (sbin, sbin[::-1], diff, bin(diff)) 

делает его выглядеть менее неуклюжим. Мне нравится ответ Хиро. Очень элегантный и, возможно, быстрее. Но мне многое предстоит переварить.

+0

Я благодарю вас за плакаты для ваших замечательных примеров кода. Я узнал что-то новое из каждого поста. – Graybits

Смежные вопросы