1
0
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:
Calvin Rose 2020-12-26 16:54:14 -06:00
parent 2357b6162f
commit 13d8d11011

View File

@ -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: {