mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
new hash for doubles based on frexp, to avoid low-level tricks
This commit is contained in:
parent
1448e736f0
commit
f6ed285cf2
15
ltable.c
15
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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
34
luaconf.h
34
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 <math.h>
|
||||
#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 <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#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
|
||||
|
||||
/* }================================================================== */
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user