2017-03-24 36 views
0

我试图找出将4D向量转换为有界长的方法。然而,矢量及其结果长有一定的限制。向量本身由4个整数组成:第一个整数可以是Java能力内的任何东西(因此Integer.MIN_VALUE一直到Integer.MAX_VALUE)。第二个和第四个整数总是在-2999984和2999984之间(包括两端)。最后,第三个总是在0到255之间(再次,包括两者)。因此,它的格式如下:将4D向量转换为长

([Integer min - Integer max], [-2999984 - 2999984], [0 - 255], [-2999984 - 2999984]) 

该向量需要被转换为长-824629322721380016和824629339968358064.

我知道之间的有可能是没有的功能,结果在一个1:1的匹配,但我试图找出一个函数,尽可能减少碰撞。

如果您想知道,vector和long的这些界限并不是任意的。正如我用Minecraft给帖子贴上标签,我应该解释为什么。我试图将一个维度中的某个blockpos与另一个维度中的blockpos相匹配。 4D向量是[dimension id,x pos,y pos,z pos],结果long是BlockPos(BlockPos#fromLong)的序列化形式。你可以看到this论坛帖子,引发了我的询问。我在这里问,因为我的queston必须是MC专用的,因为它主要是数学和基于代码的。

+0

这个函数是否需要很容易被逆转?或者它可以是一种方式? –

+0

不,该功能不需要是可逆的。只要矢量转化为具有上述限制的长整型。 – TheMasterGabriel

回答

0

我建议将你的4d向量转换为位,将该位表示转换为BigInteger,并使用设计用于低碰撞的哈希算法对该整数进行哈希运算。

你的'水桶'数量实际上是长的范围。

根据这一Murmur2似乎是号码最好的散列: https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed

您可以谷歌为Murmur2 Java实现,但这里是这个答案的写作时一个这样的例子: https://github.com/sangupta/murmur值得注意的是,如果您可以将维度数量限制为65536(16位) - 您可以单独使用1到1的散列值。可能通过限制用户可以进入的虚拟世界的数量来做到这一点?

0

不幸的是,这是不能做到的。一长只有64位,但你的4D矢量需要32 + 23 + 8 + 23> 64.

如果你可以限制你的输入一点点,使它适合,你可以转换它类似于下面的代码(2D-int-Vector < - > long转换的例子):

long toLong(int int1, int int2) { 
    return ((long) int1 << 32) | (int2 & (-1L >>> 32)); 
} 

int[] toInts(long l) { 
    int[] ints = new int[2]; 
    int[0] = (int) (both >> 32); 
    int[1] = (int) both; 
    return ints; 
}