code wiki / (root) / nx_f32_encode.nx

nx_f32_encode.nx source

↩ module page · 43 lines · 2233 B

1// nx_f32_encode.nx -- the ENCODE half of f32: integer value -> IEEE-754 single 2// bit pattern. nx_f32.nx has arithmetic + nx_fp32_q14 DECODES (f32->Q14), but 3// nothing ENCODES a value to f32 bits -- the exact primitive an STL writer needs 4// to emit mesh vertices (then nx_le_write_u32 the bits). This fills that gap (no 5// duplicate -- verified nx_f32/nx_fp32_q14 lack it). license_tier: ORIGINAL. 6 7import "nx_syscalls.nx" 8const K_MAGIC_8388607: i64 = 8388607 9 10// IEEE-754 single-precision bit pattern (as i64, 0..2^32-1) for integer v. 11func f32_from_i64(v: i64) -> i64 { 12 if v == 0 { return 0 } 13 var sign: i64 = 0 14 var a: i64 = v 15 if a < 0 { sign = 1; a = 0 - a } 16 // highest set bit position of a 17 var msb: i64 = 0 18 var t: i64 = a 19 while t > 1 { t = t / 2; msb = msb + 1 } 20 let exp: i64 = 127 + msb // biased exponent 21 var mant: i64 = 0 // 23-bit mantissa (leading 1 implicit -> masked off) 22 if msb <= 23 { mant = (a << (23 - msb)) & K_MAGIC_8388607 } 23 else { mant = (a >> (msb - 23)) & K_MAGIC_8388607 } 24 return (sign << 31) | (exp << 23) | mant 25} 26 27// IEEE-754 single-precision bit pattern for the REAL number (q14 / 16384), 28// where q14 is a Q14 fixed-point value (1 unit = 1/16384, the canonical mm 29// unit of the mesh/slicer/gcode pipeline). Dividing by 2^14 = 16384 is an 30// EXACT downward shift of the binary exponent -- the mantissa and sign are 31// untouched -- so this is the precise inverse of nx_fp32_bytes_to_q14 for 32// |q14| < 2^24 (i.e. |value| < 1024 mm, well above any print bed). This is 33// the sub-mm units bridge an arbitrary-mesh STL writer needs: f32_from_i64 34// only encodes whole millimetres, losing all sculpt/CAD detail below 1 mm. 35func f32_from_q14(q14: i64) -> i64 { 36 if q14 == 0 { return 0 } 37 let bits: i64 = f32_from_i64(q14) // f32 of the integer q14 38 let sign: i64 = (bits >> 31) & 1 39 let exp: i64 = (bits >> 23) & 255 // biased exponent of integer q14 40 let mant: i64 = bits & K_MAGIC_8388607 // 23-bit mantissa 41 let new_exp: i64 = exp - 14 // / 2^14 (exact, no rounding) 42 return (sign << 31) | (new_exp << 23) | mant 43}