mirror of
https://github.com/python/cpython.git
synced 2025-09-25 01:43:11 +00:00
New, better hash for floating point and complex
This commit is contained in:
parent
265b5b3f03
commit
919cf1aff1
2 changed files with 41 additions and 6 deletions
|
@ -294,7 +294,7 @@ complex_hash(v)
|
||||||
{
|
{
|
||||||
double intpart, fractpart;
|
double intpart, fractpart;
|
||||||
int expo;
|
int expo;
|
||||||
long x;
|
long hipart, x;
|
||||||
/* This is designed so that Python numbers with the same
|
/* This is designed so that Python numbers with the same
|
||||||
value hash to the same value, otherwise comparisons
|
value hash to the same value, otherwise comparisons
|
||||||
of mapping keys will turn out weird */
|
of mapping keys will turn out weird */
|
||||||
|
@ -309,7 +309,7 @@ complex_hash(v)
|
||||||
fractpart = modf(v->cval.real, &intpart);
|
fractpart = modf(v->cval.real, &intpart);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fractpart == 0.0) {
|
if (fractpart == 0.0 && v->cval.imag == 0.0) {
|
||||||
if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
|
if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
|
||||||
/* Convert to long int and use its hash... */
|
/* Convert to long int and use its hash... */
|
||||||
object *w = dnewlongobject(v->cval.real);
|
object *w = dnewlongobject(v->cval.real);
|
||||||
|
@ -323,8 +323,36 @@ complex_hash(v)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fractpart = frexp(fractpart, &expo);
|
fractpart = frexp(fractpart, &expo);
|
||||||
fractpart = fractpart*2147483648.0; /* 2**31 */
|
fractpart = fractpart * 2147483648.0; /* 2**31 */
|
||||||
x = (long) (intpart + fractpart) ^ expo; /* Rather arbitrary */
|
hipart = (long)fractpart; /* Take the top 32 bits */
|
||||||
|
fractpart = (fractpart - (double)hipart) * 2147483648.0;
|
||||||
|
/* Get the next 32 bits */
|
||||||
|
x = hipart + (long)fractpart + (long)intpart + (expo << 15);
|
||||||
|
/* Combine everything */
|
||||||
|
|
||||||
|
if (v->cval.imag != 0.0) { /* Hash the imaginary part */
|
||||||
|
/* XXX Note that this hashes complex(x, y)
|
||||||
|
to the same value as complex(y, x).
|
||||||
|
Still better than it used to be :-) */
|
||||||
|
#ifdef MPW
|
||||||
|
{
|
||||||
|
extended e;
|
||||||
|
fractpart = modf(v->cval.imag, &e);
|
||||||
|
intpart = e;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fractpart = modf(v->cval.imag, &intpart);
|
||||||
|
#endif
|
||||||
|
fractpart = frexp(fractpart, &expo);
|
||||||
|
fractpart = fractpart * 2147483648.0; /* 2**31 */
|
||||||
|
hipart = (long)fractpart; /* Take the top 32 bits */
|
||||||
|
fractpart =
|
||||||
|
(fractpart - (double)hipart) * 2147483648.0;
|
||||||
|
/* Get the next 32 bits */
|
||||||
|
x ^= hipart + (long)fractpart +
|
||||||
|
(long)intpart + (expo << 15);
|
||||||
|
/* Combine everything */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (x == -1)
|
if (x == -1)
|
||||||
x = -2;
|
x = -2;
|
||||||
|
|
|
@ -236,9 +236,16 @@ float_hash(v)
|
||||||
x = (long)intpart;
|
x = (long)intpart;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* Note -- if you change this code, also change the copy
|
||||||
|
in complexobject.c */
|
||||||
|
long hipart;
|
||||||
fractpart = frexp(fractpart, &expo);
|
fractpart = frexp(fractpart, &expo);
|
||||||
fractpart = fractpart*2147483648.0; /* 2**31 */
|
fractpart = fractpart * 2147483648.0; /* 2**31 */
|
||||||
x = (long) (intpart + fractpart) ^ expo; /* Rather arbitrary */
|
hipart = (long)fractpart; /* Take the top 32 bits */
|
||||||
|
fractpart = (fractpart - (double)hipart) * 2147483648.0;
|
||||||
|
/* Get the next 32 bits */
|
||||||
|
x = hipart + (long)fractpart + (long)intpart + (expo << 15);
|
||||||
|
/* Combine everything */
|
||||||
}
|
}
|
||||||
if (x == -1)
|
if (x == -1)
|
||||||
x = -2;
|
x = -2;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue