[Tutor] working with c_byte?
Dave Angel
d at davea.name
Sat Mar 24 09:41:38 CET 2012
On 03/24/2012 04:14 AM, Alan Gauld wrote:
> On 24/03/12 03:51, Alex Hall wrote:
>
>> Of course, 9 means the battery is high and charging, but how do I
>> interpret an arbitrary integer as the sum of its flags? Is there a
>> binary trick I can use?
>
> Dave has given the immediate answer which is a subset of a general
> technique known as bitwise masking.
>
> I discuss this with some other examples in the Operating System topic
> of my tutorial. You might find the write up interesting.
>
> Another useful bitwise operator is xor which can be used to tell is
> any flags have changed value since the last time you looked:
>
> oldflags = readFlags()
>
> while True: # look for a change
> newflags = readFlags()
> if newflags ^ oldflags:
> break # there's been a change
>
> # process newflags.
>
> And finally, the bitwise OR can be used to set a particular flag
>
> HiBattery = 8
>
> flags = flags | HiBattery # sets HiBattery, preserving the rest.
>
>
> HTH,
>
There are many useful purposes for xor, but your example could have just
used the != operator. A better example is if you want to know which
bit(s) changed, you xor the old with the new.
One other technique which I forgot about when composing my earlier reply
is to fetch individual bits. If you just want one bit at a time, and
usually there's just a single one, it can be useful to have an algorithm
which simply gives you the lowest nonzero bit.
For any nonzero value, if you AND that value with -value, you'll get a
single bit value. (only on twos-complement machines)
so if you have a dict called flag_meanings, you could do something like:
flag = flags & (-flags)
meaning = flag_meanings[ flag ]
And if flag_meanings has an entry for zero as well as for 1,2, 4, etc.,
then this will always give you a useful meaning. Now if you apply your
xor technique here, you can do something like:
flags ^= flag
to clear out the flag you've processed, and repeat to process the rest.
Something like:
while flags:
flag = flags & (-flags)
print flag_meanings[flag]
flags ^= flag
This loop will behave similarly to the for-loop I suggested earlier.
But it will loop around fewer times, and waste no cycles once the flags
have been processed. This can be especially useful if you have hundreds
of bits in your flags, rather than just 8.
(above code fragments untested; it's late here)
--
DaveA
More information about the Tutor
mailing list