nx_fp32_q14.nx
buildroot/runtime/nx_fp32_q14.nx
about
nx_fp32_q14.nx -- IEEE 754 binary32 bit pattern -> Q14 fixed-point
i64, all-integer. Reads STL coords + any other binary format that
stores 32-bit floats in millimetres-scale magnitudes.
Why integer-only conversion:
Per cardinal feedback-bits-up-exceed-never-match, slicing math
should be deterministic. Float ops drift per-platform; integer
shift+add ops give bit-exact results on every backend nxc2
targets (x86_64, riscv64, arm64, ...). We pay the float price
exactly once at parse-time and then operate in Q14 fixed-point
for the entire slicer pipeline.
Why Q14:
Q14 = 1 unit = 1/16384. Matches nx_mesh's existing coord
convention (defined in nx_mesh.nx) so STL-loaded meshes compose
directly with nx_voxel_mesh / nx_render_pass / our slicer.
Range note:
At Q14, max representable mm value before i64 overflow is ~5.6e14
mm = 5.6e11 m. Any STL coord with magnitude > 2^40 mm = ~1e9 mm
is clamped to the saturation sentinel. Real-world 3D-print STL
coords are < 1000mm typically; Christus is 305mm. No risk.
IEEE 754 binary32 layout (little-endian byte order in STL files):
bit 31 : sign
bits 30..23 : exponent (8 bits, biased by 127)
bits 22..0 : mantissa (23 bits, implicit leading 1)
value = (-1)^sign * (1 + mantissa/2^23) * 2^(exp - 127)
For Q14 scaling we want: q14_value = value * 2^14
= (-1)^sign
* (2^23 + mantissa)
* 2^(exp - 127 - 23 + 14)
= (-1)^sign
* (2^23 + mantissa)
* 2^(exp - 136)
If exp - 136 >= 0: shift full_mantissa left by (exp - 136)
If exp - 136 < 0: shift full_mantissa right by (136 - exp)
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: nx_f32_q14_encode_test.nxnx_fp32_q14_test.nxnx_stl.nx
structs
| none |
consts
| 60 | const NX_FP32_Q14_INVALID: i64 = 0x7fffffffffffffff // Inf/NaN sentinel |
functions
| 64 | func nx_fp32_bits_to_q14(bits32: i64) -> i64 |
| 97 | func nx_fp32_bytes_to_q14(buf: *u8, off: i64, n: i64, out: *i64) -> i64 |