code wiki / (root) / nx_isqrt.nx

nx_isqrt.nx

buildroot/runtime/nx_isqrt.nx

6807 B142 linesdepth 2pulls 2 transitivereach 138 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_isqrt.nx -- integer square root, shared helper. Per cardinal feedback-15 DRY-through-shared-libraries: the same digit-by-digit binary-sqrt routine appeared inlined in nx_henyey_greenstein.nx and nx_worley_noise.nx within hours of each other. Third caller would have triggered "rule of three"; factoring at two callers + planned third (nx_distance_field_2d, nx_curl_noise magnitude, nx_atmosphere_scatter optical-depth) is the right time. Algorithm: digit-by-digit binary square root (Wikipedia "Methods of computing square roots", section "Binary numeral system (base 2)"). Returns floor(sqrt(n)) for n >= 0; refuses (returns 0) for n < 0. O(log n) iterations. No division, no multiplication except shifts -- safe on every Nishi target without depending on the host's idiv. Q10 wrapper: nx_isqrt_q10(x_q10) computes sqrt(x) where x is Q10- scaled, returning the result also in Q10. Implementation: sqrt(x) = sqrt(x_q10 / Q) = sqrt(x_q10) / sqrt(Q) = sqrt(x_q10) / sqrt(Q). To recover Q10 scaling: sqrt(x_q10) * Q / sqrt(Q) = sqrt(x_q10) * sqrt(Q) = sqrt(x_q10 * Q) -- this is the standard Q-to-Q sqrt trick. For Q = 1024, sqrt(Q) = 32, so we can alternatively compute nx_isqrt(x_q10) * 32 -- but the multiply- then-sqrt form preserves more precision for small x_q10 values. Loss audit: floor() in the integer-sqrt step truncates the fractional bit; max relative error 1 / floor(sqrt(n)) at the smallest representable values, asymptotically 0% as n grows. genealogy_id: wikipedia_binary_isqrt + abacus_long_division_sqrt lineage_id: nx_isqrt_digit_by_digit_binary nx_safety_envelope: intended_use: "Integer square root (digit-by-digit binary) + Q10 wrapper -- shared math primitive for substrate kernels (noise, distance fields, attenuation, atmospheric scattering)" sil_target: SIL2 (math primitive; correctness affects every consumer)

dependencies 2 imports · 23 importers

nx_syscalls.nx nx_tier.nx nx_isqrt.nx nx_acceleration.nx nx_audio_spatial.nx nx_audio_spatial_test.nx nx_bioacoustic_bench.nx nx_force.nx nx_gcode_extrude.nx nx_geo_buffer.nx nx_geo_distance.nx nx_geo_haversine.nx nx_geo_simplify.nx

diagram shows first 10 each side; +0 more imports, +13 more importers in the complete lists below.

imports: nx_syscalls.nxnx_tier.nx

imported by: nx_acceleration.nxnx_audio_spatial.nxnx_audio_spatial_test.nxnx_bioacoustic_bench.nxnx_force.nxnx_gcode_extrude.nxnx_geo_buffer.nxnx_geo_distance.nxnx_geo_haversine.nxnx_geo_simplify.nxnx_groupnorm.nxnx_layernorm.nxnx_mesh_qem.nxnx_mesh_sculpt.nxnx_monte_carlo.nxnx_patch_attribution.nxnx_pillar_physics.nxnx_polygon.nxnx_rmsnorm.nxnx_sdf.nxnx_squeaker.nxnx_torque.nxnx_vox_source.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main nx_isqrt nx_isqrt_q10 nx_isqrt ↻

structs

none

consts

58const NX_MAGIC_1024: i64 = 1024
59const NX_MAGIC_10000: i64 = 10000
60const NX_MAGIC_1048576: i64 = 1048576
61const NX_MAGIC_9999: i64 = 9999
62const NX_MAGIC_1000000000000: i64 = 1000000000000
63const NX_MAGIC_1000000: i64 = 1000000
64const NX_MAGIC_4096: i64 = 4096
65const NX_MAGIC_2048: i64 = 2048
96const NX_ISQRT_Q: nx_int = 1024

functions

69func nx_isqrt(n: nx_int) -> nx_int
98func nx_isqrt_q10(x_q10: nx_int) -> nx_int
104func main() -> i64