Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Bitwise Slicing
#1
Hi - New to Python so please forgive any mistakes

I want to know if there is a more elegant way of slicing a byte?

I have an 8 bit result from reading a Port Expander (4 MSB's are where my inputs are connected)
In_1, In_2, In_3, In_4 will be used in the main program

def input_status(result): #gets a byte value and returns input status result = result | 15 # mask out the bottom 4 bits (not really needed) result = result >>4 #only interested in the 4 MSBs In_1 = result & 1 #check bit 0 result = result >>1 #shift 1 place right In_2 = result & 1 #check bit 1 result = result >>1 #shift 1 place right In_3 = result & 1 #check bit 2 I_result = result >>1 #shift 1 place right In_4 = I_result & 1 #check bit 3 return (In_1, In_2, In_3, In_4)
This works fine, but seems like a very cumbersome way of doing things?

I was looking for some sort of alias command where I could specify that In_1 = result.4 or something similar but I've not been able to find one.

Thanks for the help - still at the bottom of the learning curve Cool
Reply
#2
I spent ~20 minutes trying to come up with something more elegant, and I believe I've failed:
def f(result): return tuple(int(result & 2**x > 1) for x in range(4, 8)) def f2(result): result = result >> 4 return tuple(result >> x & 1 for x in range(4)) def f3(result): return tuple(result >> x & 1 for x in range(4, 8)) def f4(result): return tuple(int(digit) for digit in f"{(result >> 4) & 15:04b}"[::-1])
Solutions I gave up on but tried include using reduce() and recursion.
Reply
#3
I think the bitwise operators are the way to go. But you *could* print out the binary representation string and then index into it.

result = 231 # high bits are "1110" bits = [1 if x == "1" else 0 for x in f"{result:08b}"[-8:]] # takes only 8 LSB in case result > 2**8 for i in range(4): print(bits[i])
Output:
1 1 1 0
Reply
#4
Ok - thanks for that. Good learning for me - I'm still not fully conversant with the way Python handles data (I'm used to PIC programming - where I can break everything down to the bit level.

If I went with
bits = [1 if x == "1" else 0 for x in f"{result:08b}"[-8:]] # takes only 8 LSB in case result > 2**8
Would that not simply leave me with a string called 'bits' - so effectively just masking out the lower 4 bits of result?

I need to be able to access and act on individual bit values (input is On or Off)

Thanks again
Reply
#5
def bits(value, size=32): bit_values = [] for bit in range(size): bit_values.insert(0, value & 1) value = value >> 1 return bit_values print(bits(42, 8)) def bitslice(value, start, end): retvalue = 0 for bit in range(start, end+1): retvalue += (value & 1 << bit) >> start return retvalue print(bitslice(42, 1, 5), bits(bitslice(42, 1, 5), 5)) def bit(value, index): return (value & 1 << index) >> index print([bit(42, i) for i in range(8)]) def setbit(value, bit): return value | 1 << bit def clrbit(value, bit): mask = 1 << bit if value & mask == 0: return value return value ^ mask print(setbit(5, 1), clrbit(7, 1))
Reply
#6
(Aug-25-2020, 03:00 AM)Peter_Truman Wrote: If I went with
bits = [1 if x == "1" else 0 for x in f"{result:08b}"[-8:]] # takes only 8 LSB in case result > 2**8
Would that not simply leave me with a string called 'bits' - so effectively just masking out the lower 4 bits of result?

No, it's just compact. The first part (the f-string) converts the byte to the 8 LSB bits as a string object. f"{result:08b}"[-8:]

The next part goes through each character of the string one-by-one and converts it to a list of numbers, either 0 or 1. So the MSB is index 0 and the LSB is index 7, via a list comprehension. Expanding the loop, it would look like:

temp_list = [] for x in f"{result:08b}"[-8:]: if x == "1": temp_list.append(1) else: temp_list.append(0) bits = temp_list
So at the end, you've got the list [1, 1, 1, 0, 0, 1, 1, 1]

It looks like there's also a PyPi module called bitstring. It could be that it has some functions that would be useful.
Reply
#7
Thanks to all - the bitstring module looks much more natural to my eyes. I'll give this all a whirl in the morning.

Cheers
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Program demonstrates operations of bitwise operators without using bitwise operations ShawnYang 2 3,103 Aug-18-2021, 03:06 PM
Last Post: deanhystad
  Bitwise ~ Operator muzikman 10 7,201 Feb-07-2021, 04:07 PM
Last Post: muzikman
  not bitwise ~15 1885 3 5,366 Oct-30-2019, 03:49 AM
Last Post: 1885
  understanding exponential and bitwise operators srm 1 3,118 Jun-15-2019, 11:14 AM
Last Post: ThomasL

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.