normalize ¯0

This commit is contained in:
dzaima 2023-04-14 14:45:50 +03:00
parent 2fd390ebf8
commit ee47921b43
4 changed files with 20 additions and 6 deletions

View File

@ -18,7 +18,6 @@
// Otherwise, generic hashtable
// SHOULD handle up to 64 bit cells via proper typed hash tables
// SHOULD have fast path when cell sizes or element types doesn't match
// SHOULD properly handle ¯0
#include "../core.h"
#include "../utils/hash.h"

View File

@ -82,11 +82,10 @@ static bool canCompare64_norm(B x, usz n) {
if (e == el_B) return 0;
if (e == el_f64) {
f64* pf = f64any_ptr(x);
u64* pu = (u64*)pf;
for (usz i = 0; i < n; i++) {
f64 f = pf[i];
if (f!=f) return 0;
if (pu[i] == m_f64(-0.0).u) return 0;
pf[i] = f==0? 0 : f;
}
}
return 1;

View File

@ -3,6 +3,7 @@
#include "hash.h"
#include "time.h"
NOINLINE u64 bqn_hashObj(B x, const u64 secret[4]) { // TODO manual separation of atom & arr probably won't be worth it when there are actually sane typed array hashing things
if (isArr(x)) {
usz xia = IA(x);
@ -21,7 +22,9 @@ NOINLINE u64 bqn_hashObj(B x, const u64 secret[4]) { // TODO manual separation o
case el_i8: case el_c8: data = tyany_ptr(x); bytes = xia*1; break;
case el_i16: case el_c16: data = tyany_ptr(x); bytes = xia*2; break;
case el_i32: case el_c32: data = tyany_ptr(x); bytes = xia*4; break;
case el_f64: data = f64any_ptr(x); bytes = xia*8; break;
case el_f64: data = f64any_ptr(x); bytes = xia*8;
for (ux i = 0; i < xia; i++) ((f64*)data)[i] = normalizeFloat(((f64*)data)[i]);
break;
case el_B:;
data = TALLOCP(u64, xia);
isTemp = true;

View File

@ -11,10 +11,23 @@ static void bcl(B x, usz ia) { // clean up bitarr tail bits to zero
}
}
static inline f64 normalizeFloat(f64 v) {
v = v+0;
return v==v? v+0 : 0.0/0.0;
}
u64 bqn_hashObj(B x, const u64 secret[4]);
static u64 bqn_hash(B x, const u64 secret[4]) { // doesn't consume
if (isVal(x)) return bqn_hashObj(x, secret);
return wyhash64(secret[0], x.u);
u64 h;
if (LIKELY(x.f==x.f)) {
h = m_f64(x.f+0).u;
} else if (isVal(x)) {
return bqn_hashObj(x, secret);
} else if ((x.u<<1) == (0x7FF8000000000000<<1)) {
h = secret[1];
} else {
h = x.u;
}
return wyhash64(secret[0], h);
}
static u64 bqn_hashP(B x, const u64 secret[4]) { // bqn_hash but never zero