This is what I came up with (written in Java). The basic idea is to split 32bit-int into 2 numbers. Old bit amounts, including the effect of multiplication. The lower bits track the effect of the multiplication. It is working. It has a good distribution - also against general arguments such as (0, 1), (1, 0).
public class AssociativelyMergedIntegers { private static final int PRIME = 65521; public static int merged(int first, int second) { int firstFactor = remainderOf(first & 0x0000FFFF); int secondFactor = remainderOf(second & 0x0000FFFF); int firstSum = remainderOf(first >>> 16 & 0x0000FFFF); int secondSum = remainderOf(second >>> 16 & 0x0000FFFF); int resultSum = remainderOf(firstSum + (long) firstFactor * secondSum); int resultFactor = remainderOf((long) firstFactor * secondFactor); return resultSum << 16 ^ resultFactor; } private static int remainderOf(long number) { int rest = (int) (number % PRIME); return rest == 0 ? PRIME - 2 : rest; } }
Maciej mikosik
source share