[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