ocaml: phase 4 integer division semantics + Int module + max_int/min_int (+5 tests, 525 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Three things in this commit: 1. Integer / is now truncate-toward-zero on ints, IEEE on floats. The eval-op handler for '/' checks (number? + (= (round x) x)) on both sides; if both integral, applies host floor/ceil based on sign; otherwise falls through to host '/'. 2. Fixes Int.rem, which was returning 0 because (a - b * (a / b)) was using float division: 17 - 5 * 3.4 = 0.0. Now Int.rem 17 5 = 2. 3. Int module fleshed out: max_int / min_int / zero / one / minus_one, succ / pred / neg, add / sub / mul / div / rem, equal, compare. Also adds globals: max_int, min_int, abs_float, float_of_int, int_of_float (the latter two are identity in our dynamic runtime). 17 / 5 = 3 -17 / 5 = -3 (trunc toward zero) Int.rem 17 5 = 2 Int.compare 5 3 = 1
This commit is contained in:
@@ -418,7 +418,15 @@
|
||||
((= op "+") (+ lhs rhs))
|
||||
((= op "-") (- lhs rhs))
|
||||
((= op "*") (* lhs rhs))
|
||||
((= op "/") (/ lhs rhs))
|
||||
((= op "/")
|
||||
;; OCaml's `/` is integer division on ints, float on floats.
|
||||
;; Pick floor on ints.
|
||||
(cond
|
||||
((and (number? lhs) (number? rhs)
|
||||
(= (round lhs) lhs) (= (round rhs) rhs))
|
||||
(let ((q (/ lhs rhs)))
|
||||
(if (>= q 0) (floor q) (ceil q))))
|
||||
(else (/ lhs rhs))))
|
||||
((= op "+.") (+ lhs rhs))
|
||||
((= op "-.") (- lhs rhs))
|
||||
((= op "*.") (* lhs rhs))
|
||||
|
||||
Reference in New Issue
Block a user