diff options
-rw-r--r-- | otherlibs/num/nat_stubs.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/otherlibs/num/nat_stubs.c b/otherlibs/num/nat_stubs.c index 18cbdd2e4..d56ee2ddb 100644 --- a/otherlibs/num/nat_stubs.c +++ b/otherlibs/num/nat_stubs.c @@ -395,11 +395,24 @@ static uintnat deserialize_nat(void * dst) static intnat hash_nat(value v) { - mlsize_t len = Wosize_val(v) - 1; - mlsize_t i; - uint32 h = len; + bngsize len, i; + uint32 h; + + len = bng_num_digits(&Digit_val(v,0), Wosize_val(v) - 1); + h = 0; for (i = 0; i < len; i++) { - h = caml_hash_mix_intnat(h, Digit_val(v, i)); + bngdigit d = Digit_val(v, i); +#ifdef ARCH_SIXTYFOUR + /* Mix the two 32-bit halves as if we were on a 32-bit platform, + namely low 32 bits first, then high 32 bits. + Also, ignore final 32 bits if they are zero. */ + h = caml_hash_mix_uint32(h, (uint32) d); + d = d >> 32; + if (d == 0 && i + 1 == len) break; + h = caml_hash_mix_uint32(h, (uint32) d); +#else + h = caml_hash_mix_uint32(h, d); +#endif } return h; } |