error when porting C code to Python (bitwise manipulation)

Jordan JordanNealBerg at gmail.com
Thu Jul 10 22:26:28 CEST 2008


On Jul 10, 4:04 pm, Harald Luessen <harald.lues... at gmx.de> wrote:
> On Thu, 10 Jul 2008 Jordan wrote:
>
>
>
> >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?
>
> In C unsigned can not be negative. Why do you believe
> the numbers are negative? If your debugger is telling
> you this thow away the debugger and use printf.
> If printf is telling you this then use the right format.
> printf("%u", u); // for unsigned int u
> printf("%lu", u); // for unsigned long u
> printf("%x", u);
> or
> printf("0x%08x", u); // to see u in hex
>
> Harald

haha....I was using printf, but for some reason I decided not to use
%u...hmm...looking back over things now...



More information about the Python-list mailing list