Hi,
I am trying to represent a number as a list of bits: for example the bit
representation of the integer 8. I did find a number of articles
pertaining to a module called bitarray but I was unable to
download/install that package. I am using Linux on Ubuntu 9.10; Python
2.6.2.
I am almost certain there is a relatively easy way to convert an integer
that can be represented by 32 bits into an array of bits that I can
iterate over looking for switched on bits or switched off bits.
Any information such as recipes or past articles in this list providing
methods to create and manipulate bit arrays would be most appreciated.
Robert
Python 2.6+ (as far as I know) has the bin() function:
Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)]
on
win32
Type "help", "copyright", "credits" or "license" for more information.
And larger:
You can convert them to integers to use ^ (XOR) or & (AND) and other binary
operations on them:
http://docs.python.org/reference/expressions.html#binary-bit[..]
There may be some other way to check, but that's probably the easiest I know
of.
HTH,
Wayne
Wayne,
Thank you very much.
Robert
My approach has been to store it as an array and then build the integer as
needed. This code requires Python 2.5 or later.
def bits2int(l):
return sum([2**i if j else 0 for i,j in enumerate(l)])
To convert the other way:
def int2bits(m, n):
return [int(bool(m&(1<<i))) for i in range(n)]
Where n is the number of bits to convert. You could log2 to find this, or
count shift-rights until you get zero.
# for example, inc=4 gives log16, or the number of hexadecimal digits
# required to represent n.
def log2(n, inc=1):
i = 0
while n:
i += 1
n >>= inc
return i
floating point is so messy and slow :)
Cheers
Tutor maillist - Tutor*******
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
If all you want to do is test bits, you can do that directly using
bit-wise logical operators & and |. There is no need to convert to a
different representation. For example
In [1]: 0xff & 4
Out[1]: 4
In [2]: 0xf0 & 4
Out[2]: 0
Kent
If all you want is to treat integers as lists of bits, you could create
a wrapper class around an integer and implement the __getitem__ and
__setitem__ methods to make it behave like a list. Using the bitwise
operators, you could make the setter actually modify the bit in question
(you'd probably have to either make sure you only receive 1 or 0 as
value or you could simply use booleans instead).
For a challenge you could try to extend the built-in integer type this
way.
I'm not sure why you'd need to be able to address bits directly like
that, though. Normally the bitwise &, |, << and >> should suffice for
all intents and purposes.
Making an ACTUAL lists of ACTUAL integers representing the bits would be
overkill, though. We're talking several bytes worth of nulls to
represent a single bit. I'm all for late optimisation, but this just
doesn't feel right.
Cheers,
Alan
As`Kent Johnson pointed out, you don't need to convert anything to strings, etc.
An integer _is_ a bit array, and individual bits can be tested using the bitwise
operators. For your example, if A is an integer you can test bit 8 with:
if A & (1 << 8): dosomething
There is a simple example on the Python wiki at
http://wiki.python.org/moin/BitArrays
It uses an array of 32-bit integers as a bit array.
The advantage of using 'bitarray' or one of the other packages on the Python
Package Index is that they have implemented all of the slicing, etc. of Python
lists, strings, etc. Using an array of 32 bit integers, you have to go to some
trouble to slice out, say, bits 20 to 40.
HTH,
Gil
Numbers are already represented as arrays of bits, thats how
they are stored.
You can do that using bitmasks. For example to extract the 4th bit
use
bit4 = value & 0x08 # 0x08 = 00001000
For bit 2 use
bit2 = value & 0x02 # 0x02 = 00000010
You can iterate over each bit using
for index in range(number_of_bits):
print "bit", index + 1, "is", int(bool(value & (2**index))) #
int(bool()) prints 1/0
Or am I missing something?
--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/
<snip>
I think I agree -- if in fact it's not impossible. Tell me that's a
typo or take a moment to explain what I'm misunderstanding...
Emile
Emille,
I do think he meant bit 20 to 32 rather than 20 to 40. Unless, of
course, he's dealing with a 64 bit word.
I am delighted with all the help I have received on this topic and I am
gleefully learning anding and oring, but not too much on the EOR side.
Thanks again for all the assistance.
Robert
You posted out of order (top--osted). So I am forced to put my response
elsewhere.
Once you have an *array* of integers, you have much more than 32 bits to
work with. For example, with an array of size 10, you now have 320 bits
to work with. He's just pointing out that it's a little bit awkward to
address a group of bits that are not all in the same int. So bits 5-20
would be easy, while bits 29-40 would be much harder.
DaveA
To all, especially DaveA,
Dave is right, I'm talking about a bit array made up of integers, so it can be
of arbitrary size.
To anyone who tried _using_ the bit array on the Python Wiki, I-have to
apologize - I screwed up the listing. In the definition of makeBitArray(), the
initialization of the integer array should read:
bitArray = array.array('I') # 'I' = unsigned 32-bit integer
bitArray.extend((fill,) * intSize)
instead of the one-line:
bitArray = array.array('I', fill) * intsize
The new version works in Python 2.6 and 3.x, and the Wiki has been corrected.
Gil