New, better hash for floating point and complex

This commit is contained in:
Guido van Rossum 1997-01-11 19:26:21 +00:00
parent 265b5b3f03
commit 919cf1aff1
2 changed files with 41 additions and 6 deletions

View File

@ -294,7 +294,7 @@ complex_hash(v)
{
double intpart, fractpart;
int expo;
long x;
long hipart, x;
/* This is designed so that Python numbers with the same
value hash to the same value, otherwise comparisons
of mapping keys will turn out weird */
@ -309,7 +309,7 @@ complex_hash(v)
fractpart = modf(v->cval.real, &intpart);
#endif
if (fractpart == 0.0) {
if (fractpart == 0.0 && v->cval.imag == 0.0) {
if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
/* Convert to long int and use its hash... */
object *w = dnewlongobject(v->cval.real);
@ -323,8 +323,36 @@ complex_hash(v)
}
else {
fractpart = frexp(fractpart, &expo);
fractpart = fractpart*2147483648.0; /* 2**31 */
x = (long) (intpart + fractpart) ^ expo; /* Rather arbitrary */
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 (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)
x = -2;

View File

@ -236,9 +236,16 @@ float_hash(v)
x = (long)intpart;
}
else {
/* Note -- if you change this code, also change the copy
in complexobject.c */
long hipart;
fractpart = frexp(fractpart, &expo);
fractpart = fractpart*2147483648.0; /* 2**31 */
x = (long) (intpart + fractpart) ^ expo; /* Rather arbitrary */
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)
x = -2;