So here's how you can make it compare Value1
and Value2
, both ascending.
- Put
Value1
into the high 32 bits of a 64-bit integer.
- Flip the high bit (the sign bit) on
Value2
, and place that into the low 32 bits.
For example:
public static long getKey(int val1, int val2)
{
long key = val1;
key <<= 32;
uint flipped = (uint)val2 ^ 0x80000000;
key |= flipped;
return key;
}
That would sort Value1
and Value2
ascending. But you want Value1
to sort descending. So just flip all the bits in the first value. Change the first line to:
long key = (uint)~val1;
So how does this work? I'm going to explain using 4-bit signed integers, which have the range -8 .. 7
. The high bit is the sign bit. So the representation from low to high is:
Bit Unsigned
Binary Inverted Value Flipped Value
-8 1000 0111 7 0000 0
-7 1001 0110 6 0001 1
-6 1010 0101 5 0010 2
-5 1011 0100 4 0011 3
-4 1100 0011 3 0100 4
-3 1101 0010 2 0101 5
-2 1110 0001 1 0110 6
-1 1111 0000 0 0111 7
0 0000 1111 -1 1000 8
1 0001 1110 -2 1001 9
2 0010 1101 -3 1010 10
3 0011 1100 -4 1011 11
4 0100 1011 -5 1100 12
5 0101 1010 -6 1101 13
6 0110 1001 -7 1110 14
7 0111 1000 -8 1111 15
The first column is the number. Next column shows the two's complement binary representation. The "Inverted" column shows the binary result of inverting the bits, and the next column shows the decimal value that represents. This is the value that we place in the high bits of the result. As you can see, the numbers have switched places, with the lowest (-8) becoming the highest. That will give us a descending sort of the values.
The lower bits don't matter unless the high bits are equal. The "Bit Flipped" column shows the binary representation of the value after we flip the high bit. What this does is map the numbers -8 through 7 to the unsigned range 0 through 15, thus ensuring that the lower bits of the number are compared correctly.