I’m trying to adapt this answer to arbitrary numeric values.
Let’s say we have 3 (unsigned) numbers:
v1
, v2
, v3
and we know the respective max values they may have:
max1
, max2
, max3
.
max1 * max2 * max3 < 2^32
,
so the result (packed value) is to be within 32 bits.
How to pack/unpack them without “magic” hardcoding?
Advertisement
Answer
Here is a slightly different way to do it.
int max1 = 1000; int max2 = 500; int max3 = 500;
shift values determined based on most significant set bit of maximums.
int size1 = 32-Integer.numberOfLeadingZeros(max1); int size2 = 32-Integer.numberOfLeadingZeros(max2); int size3 = 32-Integer.numberOfLeadingZeros(max3);
mask values determined by complementing -1 shifted size bits.
int mask1 = ~(-1<<size1); int mask2 = ~(-1<<size2); int mask3 = ~(-1<<size3); int v1 = 934; int v2 = 293; int v3 = 349;
Nothing really new here. Second shift shifts both first and second values.
int packed = (((v3<<size2)|v2)<<size1)|v1;
Now reverse it
v1 = packed&mask1; // this saves the shifted packed version for the next step v2 = (packed = packed>>>size1)&mask2; v3 = (packed>>>size2)&mask3; System.out.println(v1); System.out.println(v2); System.out.println(v3);
Prints
934 293 349