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}