Encoding a set of three integers to one unique number

mekings :

So, my problem set is very simple. I am working with a set of three integers randomly selected from [0-65535] and my Job is to encode this integers into one unique number. Here is what I have tried so far

I have written a java function called pack to try and encode this numbers as follows

 private long pack(long a, long b, long c) {
        int N = 65535, M = 65536;
        return (a + (b * N) + c * N * M);
    }

And I have also written another java function to unpack or decode the packed number back to the original integers as follows

private long[] unpack(long packed) {
    int N = 65535, M = 65536;
    long a = (packed % N);
    long b = (packed / N) % M;
    long c = (packed % (N * M));
    return new long[]{a, b, c};
}

Now when I ran the code above in my main function using sample data {67, 8192, 7168} I am getting the following as result in my console output

Packing 67, 8192, 7168
Result=30786392678467

UnPacking 30786392678467
Result=[67, 8192, 57411]

From the above, clearly my first and second values are always correct but the last value always appear to be wrong. What am I possibly missing out.Your help is greatly appreciated. Thanks alot.

rgettman :

Your packing and unpacking code is incorrect according to the range [0, 65535] you've given.

There are 65,536 possible numbers, and you don't want the encoding of one integer to change the encoding of another integer. You should use one constant set to 65536 (which is 216).

public static final long PACK = 65536;

Then your pack method changes slightly to:

private long pack(long a, long b, long c) {
    return (a + (b * PACK) + c * PACK * PACK);
}

This "packs" a into the least significant 16 bits of the long (bits 49-64), b into bits 33-48, and c into bits 17-32. (Nothing is packed into bits 0-16, so those bits remain cleared.)

Also, your unpack method changes to:

private static long[] unpack(long packed) {
    long a = (packed % PACK);
    long b = (packed / PACK) % PACK;
    long c = (packed / (PACK * PACK));  // Use / not %.
    return new long[]{a, b, c};
}

Notice that c's operation divides by PACK squared, not using the % operator, but using /. Otherwise both M and N have each been replaced by PACK.

Output with these changes:

Packing 67, 8192, 168
Result=722091376707

UnPacking 722091376707
Result=[67, 8192, 168]

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=99085&siteId=1