Change the float hashing

This commit is contained in:
Gregory Lirent 2022-08-15 17:29:33 +03:00
parent 4bd9a4556f
commit d42dcc4a07
2 changed files with 31 additions and 9 deletions

View File

@ -65,7 +65,7 @@ typedef vtype_hash hash_t;
extern int libcdsb_vtype_compare_values(const void* s0, vtype t0, const void* s1, vtype t1);
extern int libcdsb_vtype_compare_values_eq(const void* s0, const void* s1, vtype t);
extern hash_t libcdsb_vtype_hash(void* value, vtype type);
extern hash_t libcdsb_vtype_hash(const void* value, vtype type);
#define vtype_stringify libcdsb_vtype_stringify
#define vtype_name libcdsb_vtype_name

View File

@ -31,14 +31,32 @@ static ldbl_t normalize_value(const void* v, vtype t) {
}
static hash_t ldouble_hash(ldbl_t s) {
hash_t x, y;
ldbl_t m;
hash_t hash;
m = modfl(s, &s);
x = llrintl(s);
y = floorl(m * 10000);
if (sizeof(hash_t) == sizeof(u64_t)) {
if (is_little_endian) {
hash = *((u64_t*)&s);
hash ^= *((u16_t*)(((u64_t*)&s) + 1));
} else {
memcpy(&hash, ((char*)&s) + sizeof(u16_t), sizeof(u64_t));
hash ^= *((u16_t*)&s);
}
} else {
if (is_little_endian) {
hash = *((u32_t*)&s) ^ *((u32_t*)&s + 1);
hash ^= *((u16_t*)(((u32_t*)&s) + 2));
} else {
u32_t x;
return x ^ y;
memcpy(&hash, ((char*)&s) + sizeof(u16_t), sizeof(u32_t));
memcpy(&x, ((char*)&s) + sizeof(u16_t) + sizeof(u32_t), sizeof(u32_t));
hash ^= x;
hash ^= *((u16_t*)&s);
}
}
return hash;
}
/*#####################################################################################################################*/
@ -99,7 +117,7 @@ int libcdsb_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) {
/*#####################################################################################################################*/
hash_t libcdsb_vtype_hash(void* v, vtype t) {
hash_t libcdsb_vtype_hash(const void* v, vtype t) {
switch (t) { default: abort();
@ -116,7 +134,11 @@ hash_t libcdsb_vtype_hash(void* v, vtype t) {
case VTYPE_POINTER: if (!is_x64) goto x86_ptr;
case VTYPE_INT64:
case VTYPE_UINT64: return (hash_t)(*(u64_t*)v);
case VTYPE_UINT64: if (sizeof(hash_t) == sizeof(u64_t)) {
return (hash_t)(*(u64_t*)v);
} else {
return (hash_t)(*(u32_t*)v) ^ (*((u32_t*)v + 1));
}
case VTYPE_STRING: return string_hash(v);
case VTYPE_ARRAY: return array_hash(v);