js-on-sx: high-precision number-to-string via round-trip + digit extraction
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

- js-big-int-str-loop: extract decimal digits from integer-valued float
- js-find-decimal-k: find min decimal places k where round(n*10^k)/10^k == n
- js-format-decimal-digits: insert decimal point into digit string at position (len-k)
- js-number-to-string: if 6-sig-fig round-trip fails AND n in [1e-6, 1e21),
  use digit extraction for full precision (up to 17 sig figs)
- String(1.0000001)="1.0000001", String(1/3)="0.3333333333333333"
- String test262 subset: 58→62/100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 14:42:32 +00:00
parent 79f3e1ada2
commit 5d7f931cf1
3 changed files with 64 additions and 17 deletions

View File

@@ -1194,6 +1194,53 @@
(+ i 1)
(str acc (js-to-string (nth parts i)))))))
(define
js-big-int-str-loop
(fn
(n acc)
(if
(< n 1)
(if (= acc "") "0" acc)
(let
((d (floor (- n (* 10 (floor (/ n 10)))))))
(js-big-int-str-loop
(floor (/ n 10))
(str (js-string-slice "0123456789" d (+ d 1)) acc))))))
(define
js-find-decimal-k
(fn
(n k)
(if
(> k 17)
17
(let
((big-int (round (* n (js-pow-int 10 k)))))
(if
(= (/ big-int (js-pow-int 10 k)) n)
k
(js-find-decimal-k n (+ k 1)))))))
(define
js-format-decimal-digits
(fn
(digits k)
(if
(= k 0)
digits
(let
((dlen (len digits)))
(if
(> dlen k)
(str
(js-string-slice digits 0 (- dlen k))
"."
(js-string-slice digits (- dlen k) dlen))
(if
(= dlen k)
(str "0." digits)
(str "0." (js-string-repeat "0" (- k dlen)) digits)))))))
(define
js-expand-sci-notation
(fn
@@ -1234,9 +1281,9 @@
(let
((s0 (js-normalize-num-str (str pos-n))))
(let
((ei (js-string-index-of s0 "e" 0)))
((n2 (js-to-number s0)))
(let
((precise (if (< ei 0) s0 (let ((exp-n (js-to-number (js-string-slice s0 (+ ei 1) (len s0))))) (if (and (>= exp-n -6) (<= exp-n 20)) (js-expand-sci-notation (js-string-slice s0 0 ei) exp-n) (if (>= exp-n 0) (str (js-string-slice s0 0 (+ ei 1)) "+" (str exp-n)) s0))))))
((precise (if (= n2 pos-n) (let ((ei (js-string-index-of s0 "e" 0))) (if (< ei 0) s0 (let ((exp-n (js-to-number (js-string-slice s0 (+ ei 1) (len s0))))) (if (and (>= exp-n -6) (<= exp-n 20)) (js-expand-sci-notation (js-string-slice s0 0 ei) exp-n) (if (>= exp-n 0) (str (js-string-slice s0 0 (+ ei 1)) "+" (str exp-n)) s0))))) (if (and (>= pos-n 1e-06) (< pos-n 1e+21)) (let ((k (js-find-decimal-k pos-n 0))) (let ((big-int (round (* pos-n (js-pow-int 10 k))))) (js-format-decimal-digits (js-big-int-str-loop big-int "") k))) (let ((ei (js-string-index-of s0 "e" 0))) (if (< ei 0) s0 (let ((exp-n (js-to-number (js-string-slice s0 (+ ei 1) (len s0))))) (if (>= exp-n 0) (str (js-string-slice s0 0 (+ ei 1)) "+" (str exp-n)) s0))))))))
(if (< n 0) (str "-" precise) precise)))))))))
(define