Skip to content

Instantly share code, notes, and snippets.

@matteblair
Created May 17, 2017 19:54
Show Gist options
  • Save matteblair/987dbcfec4a809e68a502bfe039b50fc to your computer and use it in GitHub Desktop.
Save matteblair/987dbcfec4a809e68a502bfe039b50fc to your computer and use it in GitHub Desktop.
Packing a map tile address into a cozy little 64-bit integer
#include <cassert>
#include <cstdio>
#include <cstdint>
struct TileAddress {
int x = 0;
int y = 0;
int z = 0;
int s = 0;
};
uint64_t AddressToId(TileAddress address) {
assert(address.x < (1 << 24));
assert(address.y < (1 << 24));
assert(address.z < (1 << 8));
assert(address.s < (1 << 8));
uint64_t out = address.s;
out = (out << 8) | address.z;
out = (out << 24) | address.y;
out = (out << 24) | address.x;
return out;
}
TileAddress IdToAddress(uint64_t id) {
TileAddress out;
out.x = (id) & 0xFFFFFF;
out.y = (id >> 24) & 0xFFFFFF;
out.z = (id >> 48) & 0xFF;
out.s = (id >> 56);
return out;
}
int main() {
TileAddress t { 2, 3, 4, 5 };
printf("sizeof TileAddress: %lu\n", sizeof(t));
printf("TileAddress: x = %d, y = %d, z = %d\n", t.x, t.y, t.z);
auto id = AddressToId(t);
printf("AddressToId: %#llx\n", id);
auto r = IdToAddress(id);
printf("Round trip: x = %d, y = %d, z = %d, s = %d\n", r.x, r.y, r.z, r.s);
TileAddress lower { 6, 4, 3, 3 };
TileAddress upper { 1, 2, 5, 5 };
auto lowerId = AddressToId(lower);
auto upperId = AddressToId(upper);
printf("lowerId = %#llx, upperId = %#llx\n", lowerId, upperId);
assert(lowerId < upperId);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment