2017-03-24 77 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; 
}