error when porting C code to Python (bitwise manipulation)
MRAB
google at mrabarnett.plus.com
Thu Jul 10 13:35:33 EDT 2008
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
More information about the Python-list
mailing list