code wiki / (root) / nx_dec_emit.nx

nx_dec_emit.nx source

↩ module page · 50 lines · 1795 B

1// nx_dec_emit.nx -- CANONICAL non-negative i64 -> decimal ASCII. 2// 3// Per the bit-level no-tool-proliferation cardinal, this is the 4// single source for emitting a non-negative integer as decimal 5// digits. Four pre-existing inline implementations 6// (nxembed::emit_dec, nx_q14_format::nx_int_to_decimal, 7// nx_tptp_emit::nx_int_to_decimal, ipaddr::ip_emit_dec) predate 8// this primitive and are queued for migration to compose it 9// (Task: dec-emit-consolidate). New code MUST compose this; never 10// inline another copy. 11// 12// Pure formatting -- no syscalls, no allocations, no imports. 13// Writes digits directly into caller-owned `out` at offset `off`. 14// Returns the number of bytes written (always positive). 15// 16// Caller responsibilities: 17// - out must have at least 20 bytes free at off (max i64 in 18// decimal is 19 digits + room for the loop's reverse step). 19// - n must be non-negative (callers needing signed-with-minus 20// should write '-' themselves then pass abs(n)). 21// 22// Algorithm: write digits LSB-first into out[off..off+k] then 23// reverse in place. No scratch buffer required. 24 25const NX_DEC_EMIT_MAX_BYTES: i64 = 20 26 27func nx_dec_emit_u63(out: *u8, off: i64, n: i64) -> i64 { 28 if n == 0 { 29 out[off] = 48 as u8 // '0' 30 return 1 31 } 32 var v: i64 = n 33 var k: i64 = 0 34 while v > 0 { 35 let d: i64 = v - (v / 10) * 10 // v % 10 via div+sub 36 out[off + k] = (48 + d) as u8 // '0' + digit 37 v = v / 10 38 k = k + 1 39 } 40 // Reverse out[off..off+k] in place. 41 var i: i64 = 0 42 while i < k / 2 { 43 let a: u8 = out[off + i] 44 let b: u8 = out[off + k - 1 - i] 45 out[off + i] = b 46 out[off + k - 1 - i] = a 47 i = i + 1 48 } 49 return k 50}