error when porting C code to Python (bitwise manipulation)

Jordan JordanNealBerg at gmail.com
Thu Jul 10 13:52:53 EDT 2008


On Jul 10, 1:35 pm, MRAB <goo... at mrabarnett.plus.com> wrote:
> On Jul 10, 4:56 am, Jordan <JordanNealB... at gmail.com> wrote:
>
>
>
> > I am trying to rewrite some C source code for a poker hand evaluator
> > in Python.  Putting aside all of the comments such as just using the C
> > code, or using SWIG, etc.  I have been having problems with my Python
> > code not responding the same way as the C version.
>
> > C verison:
>
> > unsigned find_fast(unsigned u)
> > {
> >     unsigned a, b, r;
> >     u += 0xe91aaa35;
> >     u ^= u >> 16;
> >     u += u << 8;
> >     u ^= u >> 4;
> >     b  = (u >> 8) & 0x1ff;
> >     a  = (u + (u << 2)) >> 19;
> >     r  = a ^ hash_adjust[b];
> >     return r;
>
> > }
>
> > my version (Python, hopefully ;)):
>
> > def find_fast(u):
> >     u += 0xe91aaa35
> >     u ^= u >> 16
> >     u += u << 8
> >     u ^= u >> 4
> >     b  = (u >> 8) & 0x1ff
> >     a  = (u + (u << 2)) >> 19
> >     r  = a ^ hash_adjust[b]
> >     return r
>
> > As far as I understand the unsigned instructions in C just increase
> > amount of bytes the int can hold, and Python automatically converts to
> > longs which have infinite size when necessary, so I am not sure why I
> > am getting different results.
>
> > I assume that I am missing something fairly simple here, so help a
> > n00b out if you can :)
>
> > Thanks in advance,
>
> > jnb
>
> You want to restrict the values to 32 bits. The result of + or << may
> exceed 32 bits, so you need to mask off the excess bits afterwards.
>
> def find_fast(u):
>     mask = 0xffffffff
>     u  = (u + 0xe91aaa35) & mask
>     u ^= u >> 16
>     u  = (u + (u << 8)) & mask # can get away with only 1 mask here
>     u ^= u >> 4
>     b  = (u >> 8) & 0x1ff
>     a  = ((u + (u << 2)) & mask) >> 19 # can get away with only 1 mask
> here
>     r  = a ^ hash_adjust[b]
>     return r
>
> HTH

Well, I guess there are two problems....the masking and the fact the
in C it seems to for some reason overflow and become a negative
value....still not sure why it does it....So the code with just
masking doesn't work, you still need some sort of weird inversion like
the ~(0xFFFFFFFF - u).....weird

anyone?

haha



More information about the Python-list mailing list