porting C code

L

Lucas Raab

I am currently in the process of porting some C code into Python and am
stuck. I don't claim to be the greatest C/C++ programmer; in fact, my
skills at C are rudimentary at best. My question is I have the
statement: "typedef unsigned long int word32" and later on: "word32
b[3]" referencing the third bit of the integer. How do I do the same in
Python?? If this is a stupid, I apologize. It's amazing what the lack of
sleep does to the brain.

TIA,
Lucas
 
S

Steven Bethard

Lucas said:
I am currently in the process of porting some C code into Python and am
stuck. I don't claim to be the greatest C/C++ programmer; in fact, my
skills at C are rudimentary at best. My question is I have the
statement: "typedef unsigned long int word32" and later on: "word32
b[3]" referencing the third bit of the integer. How do I do the same in
Python??

py> for x in range(16):
.... print x, (x >> 2) & 1
....
0 0
1 0
2 0
3 0
4 1
5 1
6 1
7 1
8 0
9 0
10 0
11 0
12 1
13 1
14 1
15 1

Basically, I use a right-shift by 2 to put the 3rd bit as the last bit,
and then mask off everything but the last bit by and-ing with 1. Does
that work?

Steve
 
R

Roy Smith

Lucas Raab said:
I am currently in the process of porting some C code into Python and am
stuck. I don't claim to be the greatest C/C++ programmer; in fact, my
skills at C are rudimentary at best. My question is I have the
statement: "typedef unsigned long int word32" and later on: "word32
b[3]" referencing the third bit of the integer.

Are you sure that's accessing the third bit? It looks to me like it's
accessing index 3 (counting from 0) of an array of ints.
How do I do the same in Python??

In any case, if you're doing bit-fiddling in Python, you've got two
basic sets of tools.

First, the basic arithmetic operators. Boolean and (&), or (|),
left-shift (<<) and right-shift (>>) operators work in Python just like
they do in C. Integer constants starting with 0x are in hex, and the
"%x" format specifier prints integers in hex. You can play all the
normal C bit-operation tricks. To test bit 7, you can do "word & (0x1
<< 7)". To set bit 4, use "word |= (0x1 << 4)".

Second, the struct module
(http://docs.python.org/lib/module-struct.html) is useful for packing
and unpacking C structures written out into binary files.
 
P

Peter Hansen

Lucas said:
I have the
statement: "typedef unsigned long int word32" and later on: "word32
b[3]" referencing the third bit of the integer.

If that's really exactly what you have, then you actually have
something defining an array of three unsigned long integers
named "b". And even if you didn't have precisely "word32 b[3]",
but merely a "b[3]" reference somewhere, it would be referencing
the third element of an array called "b", which is possibly a byte,
maybe a long, but definitely not a bit.

Maybe showing it as code rather than inline in your text
would avoid the possibility of confusion.

-Peter
 
P

Peter Hansen

Peter said:
but merely a "b[3]" reference somewhere, it would be referencing
the third element of an array called "b", which is possibly a byte,

"*Fourth* element... I'll come in again. Amongst our elements..."

-Peter
 
L

Lucas Raab

Peter said:
Lucas said:
I have the statement: "typedef unsigned long int word32" and later
on: "word32 b[3]" referencing the third bit of the integer.


If that's really exactly what you have, then you actually have
something defining an array of three unsigned long integers
named "b". And even if you didn't have precisely "word32 b[3]",
but merely a "b[3]" reference somewhere, it would be referencing
the third element of an array called "b", which is possibly a byte,
maybe a long, but definitely not a bit.

Maybe showing it as code rather than inline in your text
would avoid the possibility of confusion.

-Peter

Sorry, the third "byte" is what I meant. As for code samples, I hope the
following will work:

typedef unsigned long int word32 ;
void mu(word32 *a)
{
int i ;
word32 b[3] ;

b[0] = b[1] = b[2] = 0 ;
for( i=0 ; i<32 ; i++ )
{
b[0] <<= 1 ; b[1] <<= 1 ; b[2] <<= 1 ;
if(a[0]&1) b[2] |= 1 ;
if(a[1]&1) b[1] |= 1 ;
if(a[2]&1) b[0] |= 1 ;
a[0] >>= 1 ; a[1] >>= 1 ; a[2] >>= 1 ;
}

a[0] = b[0] ; a[1] = b[1] ; a[2] = b[2] ;
}

The "a[#]" and "b[#]" are the parts that are giving me trouble.
 
D

Duncan Booth

Lucas said:
Sorry, the third "byte" is what I meant. As for code samples, I hope the
following will work:

typedef unsigned long int word32 ;
void mu(word32 *a)
{
int i ;
word32 b[3] ;

b[0] = b[1] = b[2] = 0 ;
for( i=0 ; i<32 ; i++ )
{
b[0] <<= 1 ; b[1] <<= 1 ; b[2] <<= 1 ;
if(a[0]&1) b[2] |= 1 ;
if(a[1]&1) b[1] |= 1 ;
if(a[2]&1) b[0] |= 1 ;
a[0] >>= 1 ; a[1] >>= 1 ; a[2] >>= 1 ;
}

a[0] = b[0] ; a[1] = b[1] ; a[2] = b[2] ;
}

The "a[#]" and "b[#]" are the parts that are giving me trouble.

So far as I can tell, the function takes an array of 3 32bit values,
reverses the order of the bits in each value, and swaps the first and last
elements of the array. All of this seems to be being done in an attempt to
make the process as obscure and inefficient as possible both by using
meaningless names, and by doing both operations simultaneously.

To convert this to Python I might try something like:

rev2 = [ 0, 0x02, 0x01, 0x03 ]
rev4 = [ (lo|hi<<2) for lo in rev2 for hi in rev2 ]
rev8 = [ (lo|hi<<4) for lo in rev4 for hi in rev4 ]

def rev32(n):
'''Reverse the low 32bits of an integer'''
return (rev8[(n>>24)&0xff]|
(rev8[(n>>16)&0xff]<<8)|
(rev8[(n>>8)&0xff]<<16)|
(rev8[n&0xff]<<24))

def mu(a):
'''Reverse the bit order of a list of 32bit integers while
also reversing the list itself'''
return [rev32(n) for n in reversed(a)]

print [hex(n) for n in mu([0x10203040, 0x50607080, 0x90a0b0c0])]

Although if 'a' really is just being used as a 96 bit integer I could add a
96 bit variant of the reversal function and use it directly:

def rev96(n):
'''Reverse the low 96bits of an integer'''
return rev32(n>>64)|(rev32(n>>32)<<32)|(rev32(n)<<64)

print hex(rev96(0x102030405060708090a0b0c0L))
 
P

Peter Hansen

Lucas said:
Sorry, the third "byte" is what I meant.

Fair enough. Note, however, that as someone pointed out,
it's actually the *fourth* of something, and it would not
necessarily be a byte. In fact, in your case, it's not:
typedef unsigned long int word32 ;
void mu(word32 *a)
{
int i ;
word32 b[3] ;

This defines an array of *3* long (32-bit) integers.
b[0] = b[1] = b[2] = 0 ;

Each of these is just indexing into that array, starting
as Python does with an index origin of zero.
The "a[#]" and "b[#]" are the parts that are giving me trouble.

Between the clarifications you've got and Duncan's post,
you shouldn't have much more trouble now. :)

-Peter
 
L

Lucas Raab

Peter said:
Lucas said:
Sorry, the third "byte" is what I meant.


Fair enough. Note, however, that as someone pointed out,
it's actually the *fourth* of something, and it would not
necessarily be a byte. In fact, in your case, it's not:
typedef unsigned long int word32 ;
void mu(word32 *a)
{
int i ;
word32 b[3] ;


This defines an array of *3* long (32-bit) integers.
b[0] = b[1] = b[2] = 0 ;


Each of these is just indexing into that array, starting
as Python does with an index origin of zero.
The "a[#]" and "b[#]" are the parts that are giving me trouble.


Between the clarifications you've got and Duncan's post,
you shouldn't have much more trouble now. :)

-Peter

Thanks.
 

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
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top