Determining combination of bits

Scott David Daniels Scott.Daniels at Acm.Org
Mon Nov 8 18:33:01 EST 2004


I wrote:
 > def bits(n):
 >        assert n >= 0 # This is an infinite loop if n < 0
 >        while n:
 >            lsb = n & -b
 >            yield lsb
 >            n ^= lsb

Diez B. Roggisch wrote:
>>A lapse of mind?
>>>>>n = 6
>>>>>n & (-n)
>>2

Stupid typo, should be:
     def bits(n):
         assert n >= 0 # This is an infinite loop if n < 0
         while n:
             lsb = n & -n  ### Here was ... & -b, which is clearly wrong
             yield lsb
             n ^= lsb

list(bits(6)) == [2, 4]
sum(bits(6)) == 6
list(bits(5000)) == [8, 128, 256, 512, 4096]
sum(bits(5000)) == 5000

> Albeit I have to admit that I didn't know the trick.
In fact I wouldn't know it if I hadn't worked on ancient machines
with "exposed guts".  One machine (a PDP-8, if I remember correctly)
did not have a "negate" operation.  Instead you did, "ones complement
(OCA) and increment (INA)".  Note that a ones complement turns all of
the least significant zeros to ones, and the least significant one to
a zero.  When you increment that the carry propagates back to the 0 for
the least one.  The carry stops there.  This will exactly match all the
low bits, and none of the bits above the least significant 1.  For the
least significant 1 bit, the calculation is 1 == 1 & 1,
for the others it is one of  0 == 0&1 == 1&0 == 0&0

Sample:
         123456 = ...000 011 110 001 001 000 000
        ~123456 = ...111 100 001 110 110 111 111
      1+~123456 = ...111 100 001 110 111 000 000

         123456 = ...000 011 110 001 001 000 000
        -123456 = ...111 100 001 110 111 000 000
123456^-123456 = ...000 000 000 000 001 000 000



More information about the Python-list mailing list