summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--otherlibs/num/nat_stubs.c21
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;
}