3

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)
1
  • misspelled binary in title sorry about that, probably limits responses Commented Mar 6, 2016 at 2:30

3 Answers 3

1

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))
Sign up to request clarification or add additional context in comments.

2 Comments

In my opinion, for k in range(BITSIZE): b = (b << 1) | ((a >> k) & 1) is more direct and clear.
@Reti43 updated the answer to include your bit-reversing algorithm. thanks!
0

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]

Comments

0

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.

1 Comment

I thank you posters for your great code examples. I learned something new from each post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.