mirror of
https://github.com/janet-lang/janet
synced 2024-12-01 04:19:55 +00:00
Try new number hashing with frexp.
This may be a bit slower in some cases but generally should have much better hashing for numbers.
This commit is contained in:
parent
2357b6162f
commit
13d8d11011
@ -28,6 +28,8 @@
|
|||||||
#include <janet.h>
|
#include <janet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
JANET_THREAD_LOCAL JanetTraversalNode *janet_vm_traversal = NULL;
|
JANET_THREAD_LOCAL JanetTraversalNode *janet_vm_traversal = NULL;
|
||||||
JANET_THREAD_LOCAL JanetTraversalNode *janet_vm_traversal_top = NULL;
|
JANET_THREAD_LOCAL JanetTraversalNode *janet_vm_traversal_top = NULL;
|
||||||
JANET_THREAD_LOCAL JanetTraversalNode *janet_vm_traversal_base = NULL;
|
JANET_THREAD_LOCAL JanetTraversalNode *janet_vm_traversal_base = NULL;
|
||||||
@ -262,10 +264,19 @@ int32_t janet_hash(Janet x) {
|
|||||||
hash = janet_struct_hash(janet_unwrap_struct(x));
|
hash = janet_struct_hash(janet_unwrap_struct(x));
|
||||||
break;
|
break;
|
||||||
case JANET_NUMBER: {
|
case JANET_NUMBER: {
|
||||||
uint64_t i = janet_u64(x);
|
double num = janet_unwrap_number(x);
|
||||||
uint32_t lo = (uint32_t)(i & 0xFFFFFFFF);
|
if (isnan(num) || isinf(num) || num == 0) {
|
||||||
uint32_t hi = (uint32_t)(i >> 32);
|
hash = 0;
|
||||||
hash = (int32_t)(hi ^ lo);
|
} else {
|
||||||
|
int e = 0;
|
||||||
|
double rest = frexp(num, &e);
|
||||||
|
int64_t intrest = (int64_t)(rest * JANET_INTMAX_DOUBLE);
|
||||||
|
uint32_t accum = (uint32_t)((intrest >> 22) ^ intrest);
|
||||||
|
accum ^= 0x9e3779b9 + (accum << 3) + (accum >> 2);
|
||||||
|
accum += (int32_t)(e);
|
||||||
|
accum ^= 0x9e3779b9 + (accum << 3) + (accum >> 2);
|
||||||
|
hash = (int32_t) accum;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JANET_ABSTRACT: {
|
case JANET_ABSTRACT: {
|
||||||
|
Loading…
Reference in New Issue
Block a user