js-on-sx: Math.hypot and Math.cbrt honour NaN/Infinity/+-0 edges
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
This commit is contained in:
@@ -3987,25 +3987,47 @@
|
||||
(x)
|
||||
(let
|
||||
((n (js-to-number x)))
|
||||
(if
|
||||
(< n 0)
|
||||
(- 0 (pow (- 0 n) (/ 1 3)))
|
||||
(pow n (/ 1 3))))))
|
||||
(cond
|
||||
((js-number-is-nan n) (js-nan-value))
|
||||
((= n (js-infinity-value)) (js-infinity-value))
|
||||
((= n (- 0 (js-infinity-value))) n)
|
||||
((= n 0) n)
|
||||
((< n 0) (- 0 (pow (- 0 n) (/ 1.0 3.0))))
|
||||
(else (pow n (/ 1.0 3.0)))))))
|
||||
|
||||
(define
|
||||
js-math-hypot
|
||||
(fn (&rest args) (sqrt (js-math-hypot-loop args 0))))
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((status (js-math-hypot-scan args false false 0)))
|
||||
(cond
|
||||
((= (first status) "inf") (js-infinity-value))
|
||||
((= (first status) "nan") (js-nan-value))
|
||||
(else (sqrt (nth status 1)))))))
|
||||
|
||||
(define
|
||||
js-math-hypot-loop
|
||||
js-math-hypot-scan
|
||||
(fn
|
||||
(args acc)
|
||||
(if
|
||||
(empty? args)
|
||||
acc
|
||||
(let
|
||||
((n (js-to-number (first args))))
|
||||
(js-math-hypot-loop (rest args) (+ acc (* n n)))))))
|
||||
(args saw-inf? saw-nan? acc)
|
||||
(cond
|
||||
((empty? args)
|
||||
(cond
|
||||
(saw-inf? (list "inf"))
|
||||
(saw-nan? (list "nan"))
|
||||
(else (list "ok" acc))))
|
||||
(else
|
||||
(let
|
||||
((n (js-to-number (first args))))
|
||||
(cond
|
||||
((= n (js-infinity-value))
|
||||
(js-math-hypot-scan (rest args) true saw-nan? acc))
|
||||
((= n (- 0 (js-infinity-value)))
|
||||
(js-math-hypot-scan (rest args) true saw-nan? acc))
|
||||
((js-number-is-nan n)
|
||||
(js-math-hypot-scan (rest args) saw-inf? true acc))
|
||||
(else
|
||||
(js-math-hypot-scan (rest args) saw-inf? saw-nan? (+ acc (* n n))))))))))
|
||||
|
||||
(begin
|
||||
(define js-math-sin (fn (x) (sin (js-to-number x))))
|
||||
|
||||
@@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green.
|
||||
|
||||
Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta.
|
||||
|
||||
- 2026-05-10 — **`Math.hypot` and `Math.cbrt` honour spec edges for NaN, ±Infinity, and ±0.** `Math.hypot(NaN, Infinity)` was returning NaN instead of +Infinity (spec: any ±Infinity arg dominates NaN). Rewrote `js-math-hypot` to scan args once tracking inf/nan flags, return +Infinity if any arg is ±Infinity, else NaN if any was NaN, else `sqrt(sum of squares)`. `Math.cbrt(NaN)` was 0 (because `pow(NaN, 1/3)` produced 0 in our path); also `Math.cbrt(-0)` returned +0 instead of -0. Added explicit short-circuits: NaN→NaN, ±Infinity→arg, ±0→arg, plus changed `(/ 1 3)` (rational) to `(/ 1.0 3.0)` (inexact) to avoid rational fractional-power oddities. Result: built-ins/Math/hypot 9/11 → 10/11. Math/cbrt 3/4 → 4/4. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-10 — **`globalThis.globalThis === globalThis`; `Number.prototype.toFixed` honours digit-range and ≥1e21 fallback.** (1) `globalThis` was bound to `nil` in the global object literal (originally to dodge an inspect-cycle hang) — added `(dict-set! js-global "globalThis" js-global)` after the literal so `globalThis.globalThis === globalThis` per spec. (2) `Number.prototype.toFixed` rewrites: RangeError when fractionDigits is NaN or outside `[0,100]` (was silently producing garbage), and for `|x| >= 1e21` returns `js-number-to-string` (the value's own ToString) per spec step 9. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-10 — **`delete <ident>` returns `false` instead of `true` per non-strict spec.** ES non-strict semantics: `delete x` where `x` is a declared binding (variable / function / parameter) returns `false` and does not unbind. Our transpiler was emitting `true` for any `delete <expr>` whose argument wasn't a member or index access. Now `delete <js-ident>` → `false`, and `delete <js-paren expr>` recurses on the inner expression so `delete (1+2)` still works. Result: language/expressions/delete 14/30 → 18/30 (+4). conformance.sh: 148/148.
|
||||
|
||||
Reference in New Issue
Block a user