From f6ed285cf2916765d7291af19a11292f4bb8689c Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 23 Oct 2009 10:31:12 -0200 Subject: [PATCH] new hash for doubles based on frexp, to avoid low-level tricks --- ltable.c | 15 +++++++-------- luaconf.h | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/ltable.c b/ltable.c index 1c2b2b6f..826dd194 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.40 2009/04/17 14:40:13 roberto Exp roberto $ +** $Id: ltable.c,v 2.41 2009/08/07 17:53:28 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -18,7 +18,6 @@ ** Hence even when the load factor reaches 100%, performance remains good. */ -#include #include #define ltable_c @@ -82,13 +81,13 @@ static const Node dummynode_ = { ** hash for lua_Numbers */ static Node *hashnum (const Table *t, lua_Number n) { - unsigned int a[numints]; int i; - if (luai_numeq(n, 0)) /* avoid problems with -0 */ - return gnode(t, 0); - memcpy(a, &n, sizeof(a)); - for (i = 1; i < numints; i++) a[0] += a[i]; - return hashmod(t, a[0]); + luai_hashnum(i, n); + if (i < 0) { + i = -i; /* must be a positive value */ + if (i < 0) i = 0; /* handle INT_MIN */ + } + return hashmod(t, i); } diff --git a/luaconf.h b/luaconf.h index f9cd7283..bb6077c5 100644 --- a/luaconf.h +++ b/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.110 2009/09/28 16:32:50 roberto Exp roberto $ +** $Id: luaconf.h,v 1.111 2009/10/11 20:02:19 roberto Exp roberto $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -500,14 +500,20 @@ /* @@ The luai_num* macros define the primitive operations over numbers. */ -#if defined(LUA_CORE) + +/* the following operations need the math library */ +#if defined(lobject_c) || defined(lvm_c) #include +#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(L,a,b) (pow(a,b)) +#endif + +/* these are quite standard operations */ +#if defined(LUA_CORE) #define luai_numadd(L,a,b) ((a)+(b)) #define luai_numsub(L,a,b) ((a)-(b)) #define luai_nummul(L,a,b) ((a)*(b)) #define luai_numdiv(L,a,b) ((a)/(b)) -#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b)) -#define luai_numpow(L,a,b) (pow(a,b)) #define luai_numunm(L,a) (-(a)) #define luai_numeq(a,b) ((a)==(b)) #define luai_numlt(L,a,b) ((a)<(b)) @@ -516,6 +522,7 @@ #endif + /* @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most @@ -574,6 +581,25 @@ union luai_Cast { double l_d; long l_l; }; #define lua_uint2number(u) \ ((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u)) + +/* +@@ luai_hashnum is a macro do hash a lua_Number value into an integer. +@* The hash must be deterministic and give reasonable values for +@* both small and large values (outside the range of integers). +@* It is used only in ltable.c. +*/ + +#if defined(ltable_c) + +#include +#include + +#define luai_hashnum(i,d) { int e; \ + d = frexp(d, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ + lua_number2int(i, d); i += e; } + +#endif + /* }================================================================== */