Octants become intervals.
The low octant shown above occupies Morton addresses 0–7. The same coordinates occupy 0, 1, 4, 5, 16, 17, 20, 21 in naïve x-major storage: a non-linear access pattern for this local region.
Morton codes for .NET
Encode two- and three-dimensional unsigned coordinates as compact Z-order values. The API is allocation-free and selects BMI2 intrinsics when the processor supports them.
Low three bits of X and Y
Each coordinate uses its least significant 16 bits.
2D + 3DCoordinate overloads
32 + 64 bitMorton code widths
BMI2Automatic PDEP and PEXT dispatch
0 allocationsStatic value-type API
Spatial locality in linear memory
A Morton code interleaves coordinate bits so that each aligned octant is a contiguous code interval. When records are sorted or indexed by that code, spatial queries tend to read compact memory ranges instead of widely separated rows.
Encoding is the address key, not the storage policy. Cache locality changes only when payloads are stored, sorted, indexed, or traversed in Morton order. Calculating a code while retaining another layout does not reorganize memory.
Mouse or touch: drag the lattice to inspect the coordinates.
Exact address comparison
Select a naive or Morton address to locate the same coordinate in all three views; select “Run demo” to compare the eight neighbors.
Illustration: 8-byte payloads and 64-byte cache lines. A compact address run can reduce cache-line fragmentation and gives a sequential hardware prefetcher a more useful access stream.
The low octant shown above occupies Morton addresses 0–7. The same coordinates occupy 0, 1, 4, 5, 16, 17, 20, 21 in naïve x-major storage: a non-linear access pattern for this local region.
Compact ranges can increase useful bytes per fetched cache line and can make sequential prefetch more effective. The actual gain depends on payload size, query shape, and traversal order.
Z-order is not globally distance-preserving. Nearby points can be separated at interval boundaries; the representation favors recursive regions rather than every possible neighborhood.
Defined coordinate capacity
Morton encoding distributes each coordinate across fixed bit lanes. Unsupported high coordinate bits are masked to keep the hot path free of validation branches.
| API | Dimensions | Capacity per axis | Morton code |
|---|---|---|---|
Encode / Decode | 2D | 16 bits0–65,535 | uint |
Encode / Decode | 3D | 10 bits0–1,023 | uint |
Encode64 / Decode64 | 2D | 32 bitsfull uint range | ulong |
Encode64 / Decode64 | 3D | 21 bits0–2,097,151 | ulongbit 63 unused |
Lane assignment
X occupies bit positions 0, 2, 4, … in two dimensions and 0, 3, 6, … in three dimensions. Y and Z occupy the subsequent positions in each group.
Small surface area
The static API accepts unsigned integers and returns unsigned Morton codes. Decoders write coordinates through out parameters.
using Tedd;
uint x = 10;
uint y = 20;
uint code = MortonEncoding.Encode(x, y);
MortonEncoding.Decode(code,
out uint decodedX,
out uint decodedY);
ulong code3D = MortonEncoding.Encode64(
1_000_000, 1_500_000, 2_000_000);
Runtime-selected implementation
The dispatcher selects an implementation from processor capability and target framework. The encoded representation remains identical.
Supported x86 and x64 processors
Concrete .NET Core and modern .NET assets use PDEP for encoding and PEXT for decoding when BMI2 is available.
Portable and non-BMI2 environments
The portable assets use deterministic bit spreading and compaction. The fallback methods expose this path directly.
Broad runtime coverage
NuGet package
Install the current stable package from NuGet.org. Package symbols and XML documentation are included.
dotnet add package Tedd.MortonEncoding