As you say the algorithm was correct.
As you say the algorithm was correct.
There is a 64bit version as well (2x64bit -> 64bit), that when compiled using 128bit multiplication is quite fast too.
The method made it's way into .NET runtime[2]. It is used in HashSet, Dictionary and ConcurrentDictionary today.
[1] https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-...
[2] https://github.com/dotnet/runtime/blob/c22f7f8c73766830b3262...
In this section of CLR the hash function is multiplication by A where 0 < A < 1, and take the fractional part of the result. In practice, as they explain, you can multiply by A * 2^32 and keep only the lower 32 bits of the result. Anyway, that gives you a full 32 bit hash (if A is good).
Then multiply by m (the size of the hash table) and take the floor (or drop the lower 32 bits of a 64 bit integer result). In CLR they discuss the case where m is a power of 2 and you don’t have a double-width multiply, so they pull the modulus out of the lower word, but the basic idea is still there.