Message80878
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. |
|
| Date |
User |
Action |
Args |
| 2009-01-31 16:35:30 | mark.dickinson | set | recipients:
+ mark.dickinson, tim_one, nmm1, christian.heimes |
| 2009-01-31 16:35:30 | mark.dickinson | set | messageid: <1233419730.59.0.735634760998.issue789290@psf.upfronthosting.co.za> |
| 2009-01-31 16:35:29 | mark.dickinson | link | issue789290 messages |
| 2009-01-31 16:35:28 | mark.dickinson | create | |
|