Author mark.dickinson
Recipients christian.heimes, mark.dickinson, nmm1, tim_one
Date 2009-01-31.16:35:28
SpamBayes Score 9.67702e-07
Marked as misclassified No
Message-id <1233419730.59.0.735634760998.issue789290@psf.upfronthosting.co.za>
In-reply-to
Content
I'll take this.

I think there *is* a problem here: on a system with 64-bit long, 
_Py_HashDouble can end up trying to cast the float value 2.**63 to a C 
long.  Since 2.**63 doesn't fit in a long, we get undefined behaviour, 
according to the C standards.

In more detail: when computing the hash of the floating-point value x = 
2.**63 on a 64-bit system, we end up in _Py_HashDouble in 
Objects/object.c.  The intpart of x will be 2.**63, and fractpart is 0.0.  
The comparison:

  if (intpart > LONG_MAX || -intpart > LONG_MAX) {

*fails*, because LONG_MAX (== 2**63-1) is implicitly converted to the 
float value 2.**63 before the comparison.  So we end up at the line:

  x = (long)intpart;

which attempts to convert intpart(== 2.0**63) to a long.  Even if this 
conversion doesn't signal, it could return some random long number, so 
unless we're very lucky, hash(2**63) == hash(2.**63) will fail.

On my system (OS X 10.5.4/x86_64), I *am* lucky:  when 2.**63 is cast to 
long I get LONG_MIN (!).  And it just so happens that hash(LONG_MIN) == 
hash(2**63), so we're okay.
History
Date User Action Args
2009-01-31 16:35:30mark.dickinsonsetrecipients: + mark.dickinson, tim_one, nmm1, christian.heimes
2009-01-31 16:35:30mark.dickinsonsetmessageid: <1233419730.59.0.735634760998.issue789290@psf.upfronthosting.co.za>
2009-01-31 16:35:29mark.dickinsonlinkissue789290 messages
2009-01-31 16:35:28mark.dickinsoncreate