mentby.com
Blog | Jobs | Help | Signup | Login

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


Robert Berman Wed, 02 Dec 2009 10:09:40 -0800

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 Werner Wed, 02 Dec 2009 10:49:27 -0800

Wayne,

Thank you very much.

Robert


Robert Berman Wed, 02 Dec 2009 11:04:55 -0800

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


Chris Fuller Wed, 02 Dec 2009 11:15:11 -0800

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


Kent Johnson Wed, 02 Dec 2009 11:31:54 -0800

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


Alan Plum Wed, 02 Dec 2009 14:34:19 -0800

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


Gil Johnson Wed, 02 Dec 2009 16:26:37 -0800

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/


Alan Gauld Wed, 02 Dec 2009 16:55:16 -0800

<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


Emile Van Sebille Wed, 02 Dec 2009 17:19:13 -0800

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


Robert Berman Wed, 02 Dec 2009 17:40:07 -0800

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


Dave Angel Wed, 02 Dec 2009 20:06:26 -0800

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


Gil Johnson Thu, 03 Dec 2009 13:17:23 -0800



Related Topics

Post a Comment