porting C code

Discussion in 'Python' started by Lucas Raab, Jan 14, 2005.

  1. Lucas Raab

    Lucas Raab Guest

    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
     
    Lucas Raab, Jan 14, 2005
    #1
    1. Advertising

  2. Lucas Raab wrote:
    > 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
     
    Steven Bethard, Jan 14, 2005
    #2
    1. Advertising

  3. Lucas Raab

    Roy Smith Guest

    Lucas Raab <> wrote:
    > 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.
     
    Roy Smith, Jan 14, 2005
    #3
  4. Lucas Raab

    Peter Hansen Guest

    Lucas Raab wrote:
    > 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
     
    Peter Hansen, Jan 14, 2005
    #4
  5. Lucas Raab

    Peter Hansen Guest

    Peter Hansen wrote:
    > 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
     
    Peter Hansen, Jan 14, 2005
    #5
  6. Lucas Raab

    Lucas Raab Guest

    Peter Hansen wrote:
    > Lucas Raab wrote:
    >
    >> 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.
     
    Lucas Raab, Jan 14, 2005
    #6
  7. Lucas Raab

    Duncan Booth Guest

    Lucas Raab wrote:

    > 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))
     
    Duncan Booth, Jan 14, 2005
    #7
  8. Lucas Raab

    Peter Hansen Guest

    Lucas Raab wrote:
    > 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
     
    Peter Hansen, Jan 15, 2005
    #8
  9. Lucas Raab

    Lucas Raab Guest

    Peter Hansen wrote:
    > Lucas Raab wrote:
    >
    >> 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.
     
    Lucas Raab, Jan 15, 2005
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DevBoy
    Replies:
    0
    Views:
    339
    DevBoy
    May 6, 2004
  2. =?Utf-8?B?QmlsbA==?=

    Problem with porting 1.1 code to 2.0

    =?Utf-8?B?QmlsbA==?=, Jan 5, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    2,007
    Steven Cheng[MSFT]
    Jan 6, 2006
  3. Harald Hein
    Replies:
    0
    Views:
    496
    Harald Hein
    Jul 22, 2003
  4. Roedy Green
    Replies:
    0
    Views:
    407
    Roedy Green
    Jul 22, 2003
  5. Enis
    Replies:
    2
    Views:
    346
    David R. Conrad
    Apr 3, 2004
Loading...

Share This Page