所以,我的问题很简单。我正在使用从 [0-65535] 中随机选择的一组三个整数,我的工作是将这些整数编码为一个唯一的数字。到目前为止,这是我尝试过的
我已经编写了一个名为pack
的Java函数,尝试按以下方式对该数字进行编码
private long pack(long a, long b, long c) {
int N = 65535, M = 65536;
return (a + (b * N) + c * N * M);
}
我还写了另一个java函数,将打包的数字解压缩或解码回原始整数,如下所示:
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};
}
现在,当我使用示例数据{67, 8192, 7168}
在main函数中运行以上代码时,在控制台输出中得到以下结果
Packing 67, 8192, 7168
Result=30786392678467
UnPacking 30786392678467
Result=[67, 8192, 57411]
从上面可以明显看出,我的第一个和第二个值始终正确,但是最后一个值似乎总是错误的。我可能会错过什么。非常感谢您的帮助。非常感谢。
答案 0 :(得分:4)
我现在将为您提供替代解决方案,然后当我使用PC而不是手机(rgettman beat me!)时,我可以尝试调试当前的解决方案。
因为三个数字中的每个数字最多可以为65535,这意味着每个数字将适合16位。因此,您可以使用以下命令简单地构建唯一的long
:
long encoded = (a << 32L) | (b << 16) | c;
并对其进行解码,如下所示:
long a = (encoded >> 32) & 0xFFFFL;
long b = (encoded >> 16) & 0xFFFFL;
long c = encoded & 0xFFFFL;
答案 1 :(得分:3)
根据您指定的范围[0,65535],您的包装和拆包代码不正确。
有65,536个可能的数字,并且您不希望一个整数的编码更改另一个整数的编码。您应该使用一个设置为65536
的常量(即2 16 )。
public static final long PACK = 65536;
然后,您的pack
方法会稍微更改为:
private long pack(long a, long b, long c) {
return (a + (b * PACK) + c * PACK * PACK);
}
此a
打包到long的最低有效16位(第49-64位),b
打包到第33-48位,c
打包到第17-32位。 (0-16中没有包含任何内容,因此这些位保持清除状态。)
此外,您的unpack
方法更改为:
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};
}
请注意,c
的运算除以PACK
的平方,而不使用%
运算符,而是使用/
。否则M
和N
都被PACK
取代。
具有以下更改的输出:
Packing 67, 8192, 168
Result=722091376707
UnPacking 722091376707
Result=[67, 8192, 168]
答案 2 :(得分:1)
实际上,您的解决方案几乎是正确的:只需确保M == N == 65536并解决解压缩变量 c 的问题。
catch exceptionorg.elasticsearch.hadoop.EsHadoopIllegalArgumentException: Incompatible types found in multi-mapping: Field [fieldName] has conflicting types of [LONG] and [INTEGER]
此外,我将N的类型更改为 long ,尽管这无关紧要,因为Java仍会在乘法过程中将其转换为 long 。