Negatif koordinatlar blok matematiğini tek değil, iki yerde bozuyor
Kesirli bölme, -1 bloğunu -1 yerine 0. bloğa yerleştirir ve düz bir % işlemi, blok içi ofseti 15 yerine -1 olarak verir. Her ikisi de hatalıdır ve spawn noktasının batısına gidene kadar doğru görünürler.
Her blok hesaplaması pozitif çeyrekte önemsiz, diğer üçünde ise yanlıştır. Tam olarak iki yerde yanlış gider, bunlar birbirinden bağımsızdır ve her ikisi de makul görünen sonuçlar üretir.
İki işlem
chunk = floor(block / 16) not trunc(block / 16)
offset = ((block % 16) + 16) % 16 not block % 16
Bölge koordinatları, bir seviye yukarıda, 16 yerine 32 ile aynı çifttir:
region = floor(chunk / 32) -> r.<x>.<z>.mca
regionOff = ((chunk % 32) + 32) % 32
Yani bir bölge 32 × 32 bloktur, bu da 512 × 512 bloktur.
Her birinin sorun çıkardığı yerler
Bölme. Çoğu dil sıfıra doğru keser ve floor negatif Sonsuzluk'a (Infinity) doğru yuvarlar. Pozitifler için aynı fikirde olsalar da, tam kat olmayan her negatif sayı için farklılık gösterirler:
- blok
−1→floor(−1/16) = −1✓, ancaktrunc(−1/16) = 0✗
-1 bloğu, başlangıç noktasının bir blok batısındadır ve -1. bloğa aittir. Kesme işlemi onu +1 bloğuyla birlikte 0. bloğa yerleştirir. Her negatif blok indeksi bir fazla çıkar.
Kalan. JavaScript, Java, C ve çoğu dilde, % sol işlenenin işaretini korur:
- blok
−1→ doğru ofset15, ancak−1 % 16 = −1✗
-1'lik bir ofset, 16 genişliğindeki bir bloğun içinde bir konum değildir. Bir blok dizisini bununla indekslemek ya hata verir ya da yanlış hücreyi sessizce okur.
Örnek bir çalışma
Bir eksende -1290 bloğu:
| adım | doğru | basit |
|---|---|---|
| blok | floor(−1290/16) = -81 | trunc = -80 ✗ |
| blok içi ofset | 6 | −1290 % 16 = -10 ✗ |
| bölge | floor(−81/32) = -3 | trunc = -2 ✗ |
| bölge içi ofset | 15 | −81 % 32 = -17 ✗ |
Dört değer, dört yanlış cevap, hiçbiri açıkça bozuk görünecek kadar aralık dışı değil. -3. bölge -96'dan -65'e kadar blokları kapsar ve -81. blok başlangıcından 15 içeride yer alır — bu da düzeltilmiş kalanın tam olarak döndürdüğü şeydir.
Nether dönüşümü tek yönde kayıplıdır
Overworld'den Nether'a 8'e bölünür ve aynı zamanda tabana yuvarlanır:
netherX = floor(overworldX / 8)
Geri dönerken 8 ile çarpılır. Bu bir gidiş-dönüş değildir. floor kalanı atar, bu nedenle geri dönüş sizi 8'in bir katına indirir:
- Overworld
1000→ Nether125→ geri1000✓ - Overworld
1007→ Nether125→ geri1000✗ — yedi blok eksik
Hata eksen başına 0 ila 7 bloktur, yani X'te ve Z'de aynı anda 7'ye kadar olabilir. Hassas portal bağlama için Nether koordinatının yeniden türetmek yerine yazılmasının tüm nedeni budur: bir kez böldüğünüzde, geldiği overworld konumu artık kurtarılamaz.
Bir Nether merkezi için bu nadiren önemlidir — 7 blok bir portalın kendi yakalama yarıçapının içindedir. Birbirlerinin trafiğini çalmaması gereken iki portalı bağlamak için ise çok önemlidir.
Negatif overworld koordinatları durumu bildiğimiz şekilde kötüleştirir: overworld −1 Nether floor(−1/8) = −1 verirken, kesme işlemi 0 verir ve sizi eksenin yanlış tarafına gönderir.