Determining combination of bits

S

Sean Berry

Say I have a dictionary like the following

{1:'one',2:'two',4:'three',8:'four',16:'five', etc...}

and I am given some numbers, say 22, 25, and 9. I want to determine the
keys, powers of 2, that comprise the number.

Ex. 22 = 16+4+2
25 = 16+8+1
9 = 8+1
....etc...

How do I get these keys?
 
S

Steven Bethard

Sean Berry said:
I want to determine the keys, powers of 2, that comprise the number.

Ex. 22 = 16+4+2
25 = 16+8+1
9 = 8+1
...etc...

This sounds suspiciously like a homework, so I'm just going to give a hint here:

Hope this is helpful.

Steve
 
L

Larry Bates

You didn't say anything about how large the
numbers might get. If they stay small (e.g. <thousands)
you could just look them up directly from a dictionary.
If they can get arbitrarily large you must use bit
shifing and boolean & (and).

Sounds a lot like a homework assignment, but I'll
give you some "hints".

1) Use bit shifting operator (>>) and boolean &
operator to isolate each bit in the integer.

2) It will be either zero or one. Build up a
list of these which will represent the power
of two that each one bit represents.

Larry Bates
 
T

Terry Reedy

Sean Berry said:
and I am given some numbers, say 22, 25, and 9. I want to determine the
keys, powers of 2, that comprise the number.
How do I get these keys?

if n%2: print 'has a positive one bit'

n//2 == n>>1 deletes that bit

keep track of divisions/shifts and stop when n == 0

Terry J. Reedy
 
S

Sean Berry

Just to set everyone's mind at ease... I haven't had a homework assignment
for about four years now.

I am using two database tables. One will have some options and a code
(power of 2).

Then, someone will check off checkboxes and submit. The number will be
added and saved in a cookie. Then, later, I want to be able to redisplay
their choices by reading the value from the cookie.

I expect the values will get no bigger than 2^32 = 4294967296. Is this
getting too big???
 
S

Steven Bethard

Sean Berry said:
I am using two database tables. One will have some options and a code
(power of 2).

Then, someone will check off checkboxes and submit. The number will be
added and saved in a cookie. Then, later, I want to be able to redisplay
their choices by reading the value from the cookie.

You might look at the number_in_base thread:

http://groups.google.com/[email protected]

This gives a solution something like:
.... return '-'[:n<0]+''.join(reversed(list(
.... digits[r]
.... for q in [abs(n)]
.... for q, r in iter(lambda: divmod(q, b), (0, 0))))) or digits[0]
....
digits = number_in_base(22, 2)
[power_of_2
.... for power_of_2, digit
.... in zip(reversed([2**x for x in range(len(digits))]), digits)
.... if digit == '1']
[16, 4, 2]


Steve
 
S

Scott David Daniels

Sean said:
Just to set everyone's mind at ease... I haven't had a homework assignment
for about four years now.
OK, then here's a great little bit of education:

n & -n == least significant bit of n

So, for example:

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

-Scott David Daniels
(e-mail address removed)
 
M

Mitja

Scott said:
OK, then here's a great little bit of education:

n & -n == least significant bit of n

A lapse of mind?2

You probably meant n&1 or perhaps n%2.
 
D

Diez B. Roggisch

A lapse of mind?
2

You probably meant n&1 or perhaps n%2.

No, the exact right thing: 6 is binary

110

with the least significant bit beeing

10

thus the decimal value of 2.

Albeit I have to admit that I didn't know the trick.
 
G

Grant Edwards

No, the exact right thing: 6 is binary

110

with the least significant bit beeing

10

The least significant bit of 110 is this one here -----+
^ |
| |
+-----------------------+

It's a 0 (zero).

What I think you're trying to say is something like the value
of the rightmost 1.
 
M

Mitja

Diez said:
No, the exact right thing: 6 is binary

110

with the least significant bit beeing

10

thus the decimal value of 2.

Wow. I always thought "least significant bit" meant, in the common big-endian bit notation, the last bit - with emphasis on the bit
word, i.e. either 1 or 0.
Have I got a real mess in my head (probably not, I just googled for definitions and the onse I checked are consistent with what I
wrote, http://www.google.com/search?hl=en&lr=&q="least+significant+bit") or is the meaning of the phrase poorly defined?
 
S

Scott David Daniels

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
 
J

Josiah Carlson

Grant Edwards said:
The least significant bit of 110 is this one here -----+
^ |
| |
+-----------------------+

It's a 0 (zero).

What I think you're trying to say is something like the value
of the rightmost 1.

From what I remember of high school chemistry (7 years ago), we used to
talk about 'significant figures' quite often. If the teacher asked for
some number to 5 significant figures, it had better have them...

sig_fig(83737256,5) -> 83737000
sig_fig(1,5) -> 1.0000

etc.

Now, in the case of 'least significant bit of n', that can be
interpreted as either n&1, or the rightmost bit that is significant
(nonzero).

The n&-n produces the rightmost bit that is nonzero, which is certainly
a valid interpretation of 'least significant bit of n'.

- Josiah
 
D

Diez B. Roggisch

The least significant bit of 110 is this one here -----+
^ |
| |
+-----------------------+

It's a 0 (zero).

What I think you're trying to say is something like the value
of the rightmost 1.

Yup.
 
D

Diez B. Roggisch

Wow. I always thought "least significant bit" meant, in the common
big-endian bit notation, the last bit - with emphasis on the bit word,
i.e. either 1 or 0. Have I got a real mess in my head (probably not, I
just googled for definitions and the onse I checked are consistent with
what I wrote,
http://www.google.com/search?hl=en&lr=&q="least+significant+bit") or
is the meaning of the phrase poorly defined?

No, seems to be well defined - I was the confused one. I have to admit that
I was somewhat impressed by that neat trick that I simply extended the
meaning of LSB in my faulty wet-ware.

I've done my share of assembler coding, but never happened to have used or
seen that one.
 
G

Grant Edwards

From what I remember of high school chemistry (7 years ago), we used to
talk about 'significant figures' quite often. If the teacher asked for
some number to 5 significant figures, it had better have them...

sig_fig(83737256,5) -> 83737000
sig_fig(1,5) -> 1.0000

etc.

Now, in the case of 'least significant bit of n', that can be
interpreted as either n&1, or the rightmost bit that is significant
(nonzero).

The n&-n produces the rightmost bit that is nonzero, which is certainly
a valid interpretation of 'least significant bit of n'.

Perhaps it's "valid", but in 25+ years of doing hardware and
low-level software this is the first time I've ever heard the
phrase "least significant bit" refer to anything other than the
"rightmost" bit (the one with a weighting of 1).
 
N

news.west.cox.net

Scott David Daniels said:
OK, then here's a great little bit of education:

Better than the education I got at UCSB...
n & -n == least significant bit of n

So, for example:

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

Perfect. This not only does exactly what I wanted... but I have just
started to learn about generators, and this does great.

Thank you very much for the help everyone.
 
D

Dennis Lee Bieber

Then, someone will check off checkboxes and submit. The number will be
added and saved in a cookie. Then, later, I want to be able to redisplay
their choices by reading the value from the cookie.
I'd just save the raw number, and build the list of choices by
ANDing against the number.

I expect the values will get no bigger than 2^32 = 4294967296. Is this
getting too big???
Well, it will go to Long int in Python as I recall... 2^31 is
largest signed int...


My first cut though, was:

-=-=-=-=-=-=-=-=-

# powers of two in integer value

val = int(raw_input("Enter the integer to be evaluated> "))
val = abs(val)
sval = val

pwrs = []
bit = 0

while val:
if val & 1:
pwrs.append(bit)
val = val >> 1
bit = bit + 1

pwrs.reverse()

print sval, "=",

sequence = 0
for p in pwrs:
if sequence:
print "+",
else:
sequence = 1
print 2**p,

print

-=-=-=-=-=-=-=-=-=-
22 = 16 + 4 + 2
25 = 16 + 8 + 1
9 = 8 + 1

Note: 2^1 = 2, so your dictionary is already in error...

Now -- on the concept of rebuilding a list of choices....

CheckBoxes = { "FirstChoice" : 1,
"SecondChoice" : 2,
"ThirdChoice" : 4,
"FourthChoice": 8,
"FifthChoice" : 16,
"SixthChoice" : 32 }


for num in [22, 25, 9]:
for k,i in CheckBoxes.items():
if num & i:
print k,
print


FifthChoice SecondChoice ThirdChoice
FirstChoice FifthChoice FourthChoice
FirstChoice FourthChoice


--
 
D

Dennis Lee Bieber

(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

Ones complement turns ALL 0 bits to 1, and ALL 1 bits to 0.

00000000
1C 11111111 ones complement has a "negative zero"
+1 00000000 twos complement "overflows" back to single zero

--
 
N

news.west.cox.net

Note: 2^1 = 2, so your dictionary is already in error...
The dictionary was filled with arbitrary values, not
{ x : 2^x } values like you might have thought.

It is actually more like {1:123, 2:664, 4:323, 8:990, 16:221... etc}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,211
Messages
2,571,092
Members
47,693
Latest member
david4523

Latest Threads

Top