Reputation: 31
I've been doing binary arithmetic in Python. It seems clumsy to me probably because there is a better way. The sample code provided creates a binary digit list, creates the reverse list and create the absolute difference. any suggestions for better technique will be appreciated.
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)
Upvotes: 3
Views: 3348
Reputation: 46869
this is an option:
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))
instead of enumerating the individual bits, the first loop counts from 0
to 2^5-1
(1<<5
shifts a bit up 5 places which equals to 2^5
). the rest is just a matter of reversing the bits (the loop over k
).
this outputs:
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
the binary operations of python can be seen here: https://wiki.python.org/moin/BitwiseOperators
as pointed out by Reti43 this could be written a little more compact:
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))
Upvotes: 1
Reputation: 2562
Using your own code, you can avoid some unnecesary variables and simplify the iteration:
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))
Making it look less clumsy. I like hiro's answer though. Very elegant and perhaps way faster. But it has a lot to digest for me.
Upvotes: 0
Reputation: 357
As your absolute difference technique demonstrates, integer arithmetic is already done in binary, and so that should be leveraged as much as possible. Although there may be issues with signed quantities.
I would claim your nested 5 deep list comprehension simply generates the numbers from 1 to 31 in binary so why not s = range(32)
do any arithmetic as integer arithmetic and use bin
to get the binary string on the result.
Reversing a string of digits is not generally a common thing done for binary arithmetic, but poses an interesting problem with a relatively easy solution. The following function has no error checking as it assumes you will only pass in valid output of the bin
function. It takes into account that binary representation always starts with '0b' and you do not want that to be reversed.
def reverse_binstr(b):
return b[0:2] + b[:1:-1]
Upvotes: 0