[Patches] fix hashing take#2 (was: fix float_hash and complex_hash for 64-bit *nix)

Trent Mick trentm@ActiveState.com
Fri, 12 May 2000 22:55:26 -0700


On Thu, May 11, 2000 at 09:54:33PM -0700, Trent Mick wrote:
> diff -c3  /home/trentm/main/contrib/python/dist/src/Objects/object.c ./Objects/object.c
> *** /home/trentm/main/contrib/python/dist/src/Objects/object.c	Wed May  3 16:44:35 2000
> --- ./Objects/object.c	Thu May 11 20:30:57 2000
> ***************
> *** 506,511 ****
> --- 508,569 ----
>   	return result;
>   }
>   
> + 
> + /* Set of hash utility functions to help maintaining the invariant that
> + 	iff a==b then hash(a)==hash(b)
> + 
> +    All the utility functions (_Py_Hash*()) return "-1" to signify an error.
> + */
> + 
> + long
> + _Py_HashDouble(v)
> +     double v;
> + {
> + 	/* Use frexp to get at the bits in the double.
> + 	 * Since the VAX D double format has 56 mantissa bits, which is the
> + 	 * most of any double format in use, each of these parts may have as
> + 	 * many as (but no more than) 56 significant bits.
> + 	 * So, assuming sizeof(long) >= 4, each part can be broken into two longs;
> + 	 * frexp and multiplication are used to do that.
> + 	 * Also, since the Cray double format has 15 exponent bits, which is the
> + 	 * most of any double format in use, shifting the exponent field left by
> + 	 * 15 won't overflow a long (again assuming sizeof(long) >= 4).
> + 	 */
> +     int expo;
> +     long hipart;
> + 
> +     v = frexp(v, &expo);
> +     v = v * 2147483648.0; /* 2**31 */
> +     hipart = (long)v; /* Take the top 32 bits */
> + 	v = (v - (double)hipart) * 2147483648.0; /* Get the next 32 bits */
> + 
> +     return hipart + (long)v + (expo << 15); /* Combine everything */
> + }
> + 

Just had a thought. I suppose that I should use the PyFPE_{START|END}_PROTECT
around the middle block doing the floating point math. Correct?

Trent