spec: rational numbers — 1/3 literals, arithmetic, numeric tower integration
SxRational type in OCaml (Rational of int * int, stored reduced, denom>0) and JS (SxRational class with _rational marker). n/d reader syntax in spec/parser.sx. Arithmetic contagion: int op rational → rational, rational op float → float. JS keeps int/int → float for CSS backward compatibility. OCaml as_number + safe_eq extended for cross-type rational equality so (= 2.5 5/2) → true. 62 tests in test-rationals.sx, all pass. JS: 2232 passed. OCaml: 4532 passed (+11 vs pre-fix baseline). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
;; ==========================================================================
|
||||
;; test-numeric-tower.sx — Numeric tower: Integer vs Float distinction
|
||||
;;
|
||||
@@ -52,15 +51,20 @@
|
||||
(assert (float? (exact->inexact 5)))))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Division always returns float
|
||||
;; Division
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(defsuite
|
||||
"numeric-tower:division"
|
||||
(deftest "int / int = float" (assert (float? (/ 6 2))))
|
||||
(deftest "exact division value" (assert= (/ 6 2) 3))
|
||||
(deftest "inexact division" (assert= (/ 1 4) 0.25))
|
||||
(deftest "float / float = float" (assert (float? (/ 3.5 2.5)))))
|
||||
(deftest
|
||||
"exact division value"
|
||||
(assert= (/ 6 2) 3))
|
||||
(deftest "inexact division value" (assert= (/ 1 4) 0.25))
|
||||
(deftest "float / float = float" (assert (float? (/ 3.5 2.5))))
|
||||
(deftest
|
||||
"rational / int = rational"
|
||||
(assert (rational? (/ 1/2 2))))
|
||||
(deftest "rational division value" (assert= (/ 1/2 2) 1/4)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Type predicates
|
||||
@@ -82,8 +86,10 @@
|
||||
(deftest "float? on int" (assert (not (float? 42))))
|
||||
(deftest "number? on int" (assert (number? 42)))
|
||||
(deftest "number? on float" (assert (number? 3.14)))
|
||||
(deftest "number? on rational" (assert (number? 1/3)))
|
||||
(deftest "number? on string" (assert (not (number? "42"))))
|
||||
(deftest "exact? on int" (assert (exact? 1)))
|
||||
(deftest "exact? on rational" (assert (exact? 1/3)))
|
||||
(deftest
|
||||
"exact? on exact->inexact"
|
||||
(assert (not (exact? (exact->inexact 1)))))
|
||||
@@ -96,13 +102,16 @@
|
||||
|
||||
(defsuite
|
||||
"numeric-tower:coercions"
|
||||
(deftest "exact->inexact int" (assert= (exact->inexact 3) 3))
|
||||
(deftest
|
||||
"exact->inexact int"
|
||||
(assert= (exact->inexact 3) 3))
|
||||
(deftest
|
||||
"exact->inexact produces float"
|
||||
(assert (float? (exact->inexact 5))))
|
||||
(deftest
|
||||
"exact->inexact float passthrough"
|
||||
(assert= (exact->inexact 1.5) 1.5))
|
||||
(deftest "exact->inexact rational" (assert= (exact->inexact 1/4) 0.25))
|
||||
(deftest "inexact->exact 1.5" (assert= (inexact->exact 1.5) 2))
|
||||
(deftest
|
||||
"inexact->exact produces int"
|
||||
|
||||
Reference in New Issue
Block a user