음수 좌표가 청크 계산을 두 군데에서 망가뜨립니다 (한 군데가 아니라)
절사 나눗셈은 블록 -1을 청크 -1 대신 0에 배치하고, 일반적인 % 연산은 청크 내 오프셋을 15 대신 -1로 만듭니다. 둘 다 잘못되었으며, 스폰 지점 서쪽으로 이동하기 전까지는 둘 다 올바르게 보입니다.
모든 청크 계산은 양수 사분면에서는 사소하지만, 나머지 세 사분면에서는 잘못됩니다. 정확히 두 군데에서 잘못되며, 이들은 서로 독립적이고, 둘 다 그럴듯해 보이는 결과를 생성합니다.
두 가지 연산
chunk = floor(block / 16) not trunc(block / 16)
offset = ((block % 16) + 16) % 16 not block % 16
지역(Region) 좌표는 한 단계 위이며, 16 대신 32를 사용합니다:
region = floor(chunk / 32) -> r.<x>.<z>.mca
regionOff = ((chunk % 32) + 32) % 32
따라서 한 지역은 32 × 32 청크이며, 이는 512 × 512 블록입니다.
각각의 문제점
나눗셈. 대부분의 언어는 0을 향해 절사하고, floor는 음의 무한대를 향해 반올림합니다. 양수에서는 일치하지만, 정확한 배수가 아닌 모든 음수에서는 일치하지 않습니다:
- 블록
−1→floor(−1/16) = −1✓, 하지만trunc(−1/16) = 0✗
블록 -1은 원점 서쪽으로 한 블록 떨어져 있으며 청크 -1에 속합니다. 절사는 이를 블록 +1과 함께 청크 0에 배치합니다. 모든 음수 청크 인덱스는 하나씩 너무 높게 나옵니다.
나머지. 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을 곱합니다. 이는 왕복이 아닙니다. floor는 나머지를 버리므로, 돌아오면 8의 배수 위치에 착지하게 됩니다:
- 오버월드
1000→ 네더125→ 다시1000✓ - 오버월드
1007→ 네더125→ 다시1000✗ — 7블록 부족
오류는 축당 0에서 7블록이므로, X와 Z 축에서 동시에 최대 7블록까지 발생할 수 있습니다. 이것이 정확한 포털 연결에 네더 좌표를 다시 계산하는 대신 기록해 두어야 하는 이유입니다. 일단 나누면, 원래 오버월드 위치는 더 이상 복구할 수 없습니다.
네더 허브의 경우 이는 거의 중요하지 않습니다. 7블록은 포털 자체의 포획 반경 내에 있습니다. 서로의 트래픽을 가로채지 않아야 하는 두 포털을 연결하는 경우에는 매우 중요합니다.
음수 오버월드 좌표는 익숙한 방식으로 상황을 악화시킵니다. 오버월드 −1는 네더 floor(−1/8) = −1를 제공하는 반면, 절사는 0를 제공하여 축의 잘못된 쪽으로 보내게 됩니다.