[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Hashing numbers
- From: RLake@...
- Date: Thu, 20 Mar 2003 16:09:20 -0500
What about someting like this?
If lua_Number is floating point:
#define lua_modf modf
#define lua_frexp frexp
#define lua_ldexp ldexp
if lua_Number is integer:
#define lua_modf(n, i) (*i = n, 0)
#define lua_frexp(n, exp) (*exp = 0, n)
#define lua_ldexp(n, exp) (n)
in either case:
/* adjust this if necessary. It is not that critical, but a small
* value will restrict the number of possible numeric hashbuckets
*/
#define LUA_HASHBITS 30
in mainposition:
switch (ttype(key)) {
case LUA_TNUMBER: {
lua_Number fpart, ipart;
lua_Number n = nvalue(key);
int bits = t->lsizenode;
int old_bits = 0;
int new_bits = bits;
fpart = lua_modf(n, &ipart);
if (fpart == 0) {
/* n is an integer; use it if it is not too big.
* Otherwise, use the high-order HASH_BITS bits of it
*/
n = lua_frexp(ipart, &new_bits);
if (new_bits > LUA_HASHBITS) {
old_bits = new_bits - LUA_HASHBITS;
new_bits = LUA_HASHBITS;
}
} else {
/* n is not an integer. Ignore the high order bit (which
* is guaranteed to be "1", and use the next "bits" bits).
*/
n = lua_frexp(n, &old_bits);
new_bits = bits + 1;
}
if (n < 0) n = -n;
return (cast(lu_hash, lua_ldexp(n, new_bits)) + old_bits)
& (twoto(bits) - 1);
}