lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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);
    }