diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-10-23 10:31:12 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-10-23 10:31:12 -0200 |
| commit | f6ed285cf2916765d7291af19a11292f4bb8689c (patch) | |
| tree | 09579b472c9bd8ba5c8b08bf6dc8ffbfc97db89c | |
| parent | 1448e736f08e65758fd0caa0f06a3723eb1585c3 (diff) | |
| download | lua-f6ed285cf2916765d7291af19a11292f4bb8689c.tar.gz lua-f6ed285cf2916765d7291af19a11292f4bb8689c.tar.bz2 lua-f6ed285cf2916765d7291af19a11292f4bb8689c.zip | |
new hash for doubles based on frexp, to avoid low-level tricks
| -rw-r--r-- | ltable.c | 15 | ||||
| -rw-r--r-- | luaconf.h | 34 |
2 files changed, 37 insertions, 12 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.40 2009/04/17 14:40:13 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.41 2009/08/07 17:53:28 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -18,7 +18,6 @@ | |||
| 18 | ** Hence even when the load factor reaches 100%, performance remains good. | 18 | ** Hence even when the load factor reaches 100%, performance remains good. |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <math.h> | ||
| 22 | #include <string.h> | 21 | #include <string.h> |
| 23 | 22 | ||
| 24 | #define ltable_c | 23 | #define ltable_c |
| @@ -82,13 +81,13 @@ static const Node dummynode_ = { | |||
| 82 | ** hash for lua_Numbers | 81 | ** hash for lua_Numbers |
| 83 | */ | 82 | */ |
| 84 | static Node *hashnum (const Table *t, lua_Number n) { | 83 | static Node *hashnum (const Table *t, lua_Number n) { |
| 85 | unsigned int a[numints]; | ||
| 86 | int i; | 84 | int i; |
| 87 | if (luai_numeq(n, 0)) /* avoid problems with -0 */ | 85 | luai_hashnum(i, n); |
| 88 | return gnode(t, 0); | 86 | if (i < 0) { |
| 89 | memcpy(a, &n, sizeof(a)); | 87 | i = -i; /* must be a positive value */ |
| 90 | for (i = 1; i < numints; i++) a[0] += a[i]; | 88 | if (i < 0) i = 0; /* handle INT_MIN */ |
| 91 | return hashmod(t, a[0]); | 89 | } |
| 90 | return hashmod(t, i); | ||
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | 93 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: luaconf.h,v 1.110 2009/09/28 16:32:50 roberto Exp roberto $ | 2 | ** $Id: luaconf.h,v 1.111 2009/10/11 20:02:19 roberto Exp roberto $ |
| 3 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -500,14 +500,20 @@ | |||
| 500 | /* | 500 | /* |
| 501 | @@ The luai_num* macros define the primitive operations over numbers. | 501 | @@ The luai_num* macros define the primitive operations over numbers. |
| 502 | */ | 502 | */ |
| 503 | #if defined(LUA_CORE) | 503 | |
| 504 | /* the following operations need the math library */ | ||
| 505 | #if defined(lobject_c) || defined(lvm_c) | ||
| 504 | #include <math.h> | 506 | #include <math.h> |
| 507 | #define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b)) | ||
| 508 | #define luai_numpow(L,a,b) (pow(a,b)) | ||
| 509 | #endif | ||
| 510 | |||
| 511 | /* these are quite standard operations */ | ||
| 512 | #if defined(LUA_CORE) | ||
| 505 | #define luai_numadd(L,a,b) ((a)+(b)) | 513 | #define luai_numadd(L,a,b) ((a)+(b)) |
| 506 | #define luai_numsub(L,a,b) ((a)-(b)) | 514 | #define luai_numsub(L,a,b) ((a)-(b)) |
| 507 | #define luai_nummul(L,a,b) ((a)*(b)) | 515 | #define luai_nummul(L,a,b) ((a)*(b)) |
| 508 | #define luai_numdiv(L,a,b) ((a)/(b)) | 516 | #define luai_numdiv(L,a,b) ((a)/(b)) |
| 509 | #define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b)) | ||
| 510 | #define luai_numpow(L,a,b) (pow(a,b)) | ||
| 511 | #define luai_numunm(L,a) (-(a)) | 517 | #define luai_numunm(L,a) (-(a)) |
| 512 | #define luai_numeq(a,b) ((a)==(b)) | 518 | #define luai_numeq(a,b) ((a)==(b)) |
| 513 | #define luai_numlt(L,a,b) ((a)<(b)) | 519 | #define luai_numlt(L,a,b) ((a)<(b)) |
| @@ -516,6 +522,7 @@ | |||
| 516 | #endif | 522 | #endif |
| 517 | 523 | ||
| 518 | 524 | ||
| 525 | |||
| 519 | /* | 526 | /* |
| 520 | @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. | 527 | @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. |
| 521 | ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most | 528 | ** 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; }; | |||
| 574 | #define lua_uint2number(u) \ | 581 | #define lua_uint2number(u) \ |
| 575 | ((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u)) | 582 | ((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u)) |
| 576 | 583 | ||
| 584 | |||
| 585 | /* | ||
| 586 | @@ luai_hashnum is a macro do hash a lua_Number value into an integer. | ||
| 587 | @* The hash must be deterministic and give reasonable values for | ||
| 588 | @* both small and large values (outside the range of integers). | ||
| 589 | @* It is used only in ltable.c. | ||
| 590 | */ | ||
| 591 | |||
| 592 | #if defined(ltable_c) | ||
| 593 | |||
| 594 | #include <float.h> | ||
| 595 | #include <math.h> | ||
| 596 | |||
| 597 | #define luai_hashnum(i,d) { int e; \ | ||
| 598 | d = frexp(d, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ | ||
| 599 | lua_number2int(i, d); i += e; } | ||
| 600 | |||
| 601 | #endif | ||
| 602 | |||
| 577 | /* }================================================================== */ | 603 | /* }================================================================== */ |
| 578 | 604 | ||
| 579 | 605 | ||
