พิกัดค่าลบทำให้การคำนวณชังก์ผิดพลาดในสองจุด ไม่ใช่จุดเดียว
การหารแบบตัดทิ้งทำให้บล็อก −1 ไปอยู่ในชังก์ 0 แทนที่จะเป็น −1 และเครื่องหมาย % ธรรมดาให้ค่าออฟเซ็ตในชังก์เป็น −1 แทนที่จะเป็น 15 ทั้งสองอย่างผิด และทั้งสองอย่างดูเหมือนถูกต้องจนกว่าคุณจะไปทางทิศตะวันตกของจุดเกิด
การคำนวณชังก์ทุกอย่างเป็นเรื่องง่ายดายในจตุภาคบวก และผิดพลาดในอีกสามจตุภาคที่เหลือ มีจุดที่มันผิดพลาดอยู่สองจุดพอดี ทั้งสองจุดเป็นอิสระต่อกัน และทั้งสองให้คำตอบที่ดูสมเหตุสมผล
การดำเนินการสองอย่าง
chunk = floor(block / 16) not trunc(block / 16)
offset = ((block % 16) + 16) % 16 not block % 16
พิกัดรีเจียนก็เป็นคู่เดียวกัน แต่เลื่อนขึ้นหนึ่งระดับ โดยใช้ 32 แทน 16:
region = floor(chunk / 32) -> r.<x>.<z>.mca
regionOff = ((chunk % 32) + 32) % 32
ดังนั้นหนึ่งรีเจียนคือ 32 × 32 ชังก์ ซึ่งเท่ากับ 512 × 512 บล็อก
แต่ละอย่างกัดตรงไหน
การหาร ภาษาโปรแกรมส่วนใหญ่ตัดทิ้งเข้าหาศูนย์ และ floor ปัดลงเข้าหาลบอนันต์ ทั้งสองเห็นตรงกันสำหรับค่าบวก และไม่ตรงกันสำหรับค่าลบทุกค่าที่ไม่ใช่ผลคูณลงตัว:
- บล็อก
−1→floor(−1/16) = −1✓ แต่trunc(−1/16) = 0✗
บล็อก −1 อยู่ทางทิศตะวันตกหนึ่งบล็อกจากจุดกำเนิด และเป็นของชังก์ −1 การตัดทิ้งทำให้มันไปอยู่ในชังก์ 0 เคียงข้างบล็อก +1 ดัชนีชังก์ค่าลบทุกค่าจึงออกมาสูงเกินไปหนึ่ง
เศษ ใน JavaScript, Java, C และภาษาอื่นส่วนใหญ่ % คงเครื่องหมายของตัวตั้งไว้:
- บล็อก
−1→ ออฟเซ็ตที่ถูกต้อง15แต่−1 % 16 = −1✗
ออฟเซ็ต −1 ไม่ใช่ตำแหน่งภายในชังก์กว้าง 16 เลย การใช้มันเป็นดัชนีอาร์เรย์บล็อกไม่โยนข้อผิดพลาดก็อ่านเซลล์ผิดอย่างเงียบ ๆ
ตัวอย่างที่คำนวณให้ดู
บล็อก −1290 บนแกนเดียว:
| ขั้นตอน | ถูกต้อง | แบบตรงไปตรงมา |
|---|---|---|
| ชังก์ | floor(−1290/16) = −81 | trunc = −80 ✗ |
| ออฟเซ็ตในชังก์ | 6 | −1290 % 16 = −10 ✗ |
| รีเจียน | floor(−81/32) = −3 | trunc = −2 ✗ |
| ออฟเซ็ตในรีเจียน | 15 | −81 % 32 = −17 ✗ |
สี่ค่า สี่คำตอบที่ผิด ไม่มีค่าใดหลุดช่วงมากพอที่จะดูพังชัด ๆ รีเจียน −3 ครอบคลุมชังก์ −96 ถึง −65 และชังก์ −81 อยู่ห่างจากจุดเริ่มต้น 15 พอดี ซึ่งเป็นสิ่งที่เศษที่แก้ไขแล้วคืนค่ากลับมา
การแปลงเนเธอร์สูญเสียข้อมูลในทิศทางเดียว
จากโอเวอร์เวิลด์ไปเนเธอร์หารด้วย 8 และปัดลงเช่นกัน:
netherX = floor(overworldX / 8)
การกลับมาคูณตำแหน่งที่แน่นอนของคุณด้วย 8 ดังนั้นบล็อกเนเธอร์ 125 ทั้งบล็อกจะแมปกลับไปยังตำแหน่งใดตำแหน่งหนึ่งในช่วง 1000–1007 ขึ้นอยู่กับว่าคุณยืนตรงไหนในบล็อกนั้น นั่น ไม่ใช่ การไปกลับที่สมบูรณ์สำหรับพิกัดบล็อก floor ทิ้งเศษไป:
- โอเวอร์เวิลด์
1000→ เนเธอร์125→ กลับมาเป็น1000✓ - โอเวอร์เวิลด์
1007→ เนเธอร์125→ พิกัดบล็อกบอกว่า1000✗ — ขาดไปเจ็ดบล็อก
ข้อผิดพลาดอยู่ที่ 0 ถึง 7 บล็อกต่อแกน ดังนั้นสูงสุด 7 บน X และ 7 บน Z พร้อมกัน นั่นคือเหตุผลทั้งหมดที่การเชื่อมportalอย่างแม่นยำต้องจดพิกัดเนเธอร์ไว้แทนที่จะคำนวณย้อนกลับ: เมื่อคุณหารไปแล้ว ตำแหน่งโอเวอร์เวิลด์ที่มันมาจากนั้นกู้คืนไม่ได้อีก
สำหรับเนเธอร์ฮับเรื่องนี้แทบไม่สำคัญ — 7 บล็อกอยู่ภายในรัศมีจับของportalเอง สำหรับการเชื่อมportalสองอันที่ต้องไม่แย่งทราฟฟิกกัน มันสำคัญมาก
พิกัดโอเวอร์เวิลด์ค่าลบทำให้แย่ลงในแบบที่คุ้นเคย: โอเวอร์เวิลด์ −1 ให้เนเธอร์ floor(−1/8) = −1 ขณะที่การตัดทิ้งให้ 0 และส่งคุณไปผิดฝั่งของแกน