I said:
> def bits(n):
> assert n >= 0 # This is an infinite loop if n < 0
> while n:
> lsb = n & -b
> yield lsb
> n ^= lsb
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