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(unsig ned 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 11 2223
On Wed, 09 Jul 2008 20:56:59 -0700, Jordan 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(unsig ned 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
What business does a poker hand evaluator have doing that kind of bitwise
arithmetic? One problem with C is not the language itself, but the
culture of using bitwise tricks where they aren't really necessary.
Anyway, I believe in C unsigned bitwise arithmetic, when overflowing an
integer will simply throw away the bits that are "too big". So if python
is converting to a long when overflowing, that would cause a different
result right there.
You could try throwing in "&= 0xffffffff" all over the place if the C
code was written for a 32 bit unsigned int. unsigned int will usually be
32 or 64 bits these days. If it's a 64 bit unsigned int in C, it'd be
"&= 0xfffffffffffff fff".
I was actually just going through an example to show what was
happening each step of the way and noticed the overflow!!! bah, stupid
tricks tricks tricks!!!
The problem is def the overflow, I notice that I start to get negative
numbers in the C version, which makes me think that the & 0xffffffff
trick won't work (because it will never evaluate to negative in
python, right?)
Seeing that the problem is the overflow and the bitwise operations
returning a negative, does anyone have any suggestions...I will look
more into C bitwise tricks in the meantime haha.
And in terms of what this is doing in a poker hand evaluator: http://www.suffecool.net/poker/evaluator.html (an evaluator using
some nice tricks to evaluate for flushes, straights, and highcard with
LU tables then binary search for the rest)
then http://senzee.blogspot.com/2006/06/s...fect-hash.html (does the
same thing, but uses perfect hashing instead of a binary search)
the function I am having issues with comes up in the hashing
algorithm :)
I realize I did a pretty bad job of explaining the problem. The
problem is the python version is returning an r that is WAAAAY to big.
Here is an example run through that function in each language:
C:
u starts at 1050
u += 0xe91aaa35;
u is now -384127409
u ^= u >16;
u is now -384153771
u += u << 8;
u is now 56728661
u ^= u >4;
u is now 56067472
b = (u >8) & 0x1ff;
b is now 389
a = (u + (u << 2)) >19;
a is now 534
r = a ^ hash_adjust[b];
r is now 6366
Python:
u starts at 1050
u += 0xe91aaa35
u is now 3910839887L
rut roh...
if after the first step (u += 0xe91aaa35) you apply this function:
invert = lambda x: ~int(hex(0xffff ffff - x)[0:-1],16)
it returns the correct value (corrected the overflow)
but there is still something wrong, still looking into it, if someone
knows how to do this, feel free to comment :)
Jordan wrote:
C:
u starts at 1050
u += 0xe91aaa35;
u is now -384127409
Hm, a negative unsigned...
Python:
Â* Â*u starts at 1050
Â* Â*u += 0xe91aaa35
Â* Â*u is now Â*3910839887L
Seriously, masking off the leading ones is the way to go:
>>-384127409 & 0xffffffff == 3910839887 & 0xffffffff
True
Peter
Well, I have figured out something that works:
def findit(u):
u += 0xe91aaa35
u1 = ~(0xffffffff - u) ^ u >16
u1 += ((u1 << 8) & 0xffffffff)
u1 ^= (u1 & 0xffffffff) >4
b = (u1 >8) & 0x1ff
a = (u1 + (u1 << 2) & 0xffffffff) >19
r = int(a) ^ hash_adjust[int(b)]
return r
I feel like this cannot possibly be the best way of doing this, but it
does work!!!! haha
If anyone would care to share a more elegant solution, that would be
great :)
On Jul 10, 4:56*am, Jordan <JordanNealB... @gmail.comwrote :
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(unsig ned 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
On Jul 10, 1:35*pm, MRAB <goo...@mrabarn ett.plus.comwro te:
On Jul 10, 4:56*am, Jordan <JordanNealB... @gmail.comwrote :
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(unsig ned 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 1mask
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
On Thu, 10 Jul 2008 Jordan wrote:
>On Jul 10, 1:35*pm, MRAB <goo...@mrabarn ett.plus.comwro te:
>On Jul 10, 4:56*am, Jordan <JordanNealB... @gmail.comwrote :
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(unsig ned 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....sti ll 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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: dean |
last post by:
Hello Group:
I obtained a copy ofthe python 2.3.3 depot (binary zipped) from the hp
porting archive. I have successfully unzipped the file and installed
it using swinstall. I received the following errors when installing:
--------------------snip-----------------------------
xx * Target logfile: hermes:/var/adm/sw/swagent.log
^ x
|
by: Jon |
last post by:
I've seen the previous msg about this error, and how it's only been
reported once. (Twice now) And I have some other circumstances.
I'm also receiving this error, on a windows 2000 platform. The only
thing is, I only get it when I call sys.exit( )
The script is doing db reads/writes and some file manipulation, but
nothing really tricky.
If anyone has any ideas why this would happen, or knows if it's a
|
by: Max |
last post by:
I thought restricted mode had been removed from Python
but it seems to be active for Python 2.3.5 +.
I'm using the JEP product which allows integration
of Java with Python (see http://jepp.sourceforge.net) via
starting a Python interpreter in the same process as the
JVM.
This integrates with python via the C interface, allowing
the user to 'eval' python code (amongst other features).
|
by: Anand |
last post by:
Hi
Are there any tools that would help in porting code from
Pyton 2.3 to 2.4 ? I have gone through the whatsnew documents
and created a document comparing Python 2.4 to 2.3. But so far
has not been able to find any tool that will signal code in
Python 2.3 that can cause errors in Python 2.4 .
rgds
|
by: Raymond L. Buvel |
last post by:
I am preparing to release an extension module that interfaces Python to
the Class Library for Numbers (http://www.ginac.de/CLN/). This module
will provide Python types for arbitrary precision floating point
numbers, rational numbers, and their complex counterparts. The module
also includes most of the functions found in the Python math and cmath
libraries.
This module will be useful in applications where gmpy...
| |
by: ImamicPH |
last post by:
Hi,
My first post.
How do you resolve linker errors? I have a simple header file that contains one function declaration. This function is used in another file (.cpp) in the definition of a macro.
There is another separate .cpp file that actually defines the function. I assumed that if I had these three separate source files saved in the same directory (C:\) that my compilier would find the header file along with the other .cpp file and...
|
by: sandip desale |
last post by:
Dear All,
We have a Tcl/Tk application written using Python 2.2. Using this application we want to call some customizable Java APIs. I tried porting Tcl/Tk application to Jython but not able to do the same as TKinter library is not available with JYthon.
Can you please help me in porting Tkinter application to Jython? Also kindly let me know how to do the same.
Thanks & Regards,
Sandip Desale
|
by: Carramba |
last post by:
Hi!
I now that I can't do straight forward any bitwise operation on float
(double etc..). But I wondering what is the easiest/best way to do this?
I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
get 11111 and the preform bitwise like <<2 to get 88888 and then divide
by 1000 to go back to float 8.8888. but these seem like "nasty" way to
do it. So maybe some of you have great tips?
Thank you in advance!
L R
|
by: Carl Banks |
last post by:
Anyone with me here? (I know the deadline for P3 PEPs has passed; this
is just talk.)
Not many people are bit-fiddling these days. One of the main uses of bit
fields is flags, but that's not often done in Python because of keyword
arguments and dicts, which are lot more versatile. Another major use,
talking to hardware, is not something oft done in Python either.
It seems like this occasional usage wouldn't justify having built-in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |