From 90418c120b7c4c01de2bb1d6af4e4b2e00ad7511 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 07:19:52 +0000 Subject: [PATCH] ocaml: phase 5.1 pi_leibniz.ml baseline + int_of_float fix (1000 terms x 100 = 314) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pi_leibniz.ml: Leibniz formula for pi. pi/4 = 1 - 1/3 + 1/5 - 1/7 + ... pi ~= 4 * sum_{k=0}^{n-1} (-1)^k / (2k+1) For n=1000, pi ~= 3.140593. Multiply by 100 and int_of_float -> 314. Side-quest: int_of_float was wrongly defined as identity in iteration 94. Fixed to: let int_of_float f = if f < 0.0 then _float_ceil f else _float_floor f (truncate toward zero, mirroring real OCaml's int_of_float). The identity definition was a stub from when integer/float dispatch was not yet split — now they're separate, the stub is wrong. Float.to_int still uses floor since OCaml's docs say the result is unspecified for nan / out-of-range; close enough for our scope. 32 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/pi_leibniz.ml | 10 ++++++++++ lib/ocaml/runtime.sx | 3 ++- plans/ocaml-on-sx.md | 8 ++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 lib/ocaml/baseline/pi_leibniz.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 47733ffd..9e36ca4a 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -23,6 +23,7 @@ "module_use.ml": 3, "mutable_record.ml": 10, "option_match.ml": 5, + "pi_leibniz.ml": 314, "poly_stack.ml": 5, "queens.ml": 2, "quicksort.ml": 44, diff --git a/lib/ocaml/baseline/pi_leibniz.ml b/lib/ocaml/baseline/pi_leibniz.ml new file mode 100644 index 00000000..343acfe0 --- /dev/null +++ b/lib/ocaml/baseline/pi_leibniz.ml @@ -0,0 +1,10 @@ +let pi_approx n = + let total = ref 0.0 in + for k = 0 to n - 1 do + let sign = if k mod 2 = 0 then 1.0 else -1.0 in + total := !total +. sign /. float_of_int (2 * k + 1) + done; + 4.0 *. !total +;; + +int_of_float (pi_approx 1000 *. 100.0) diff --git a/lib/ocaml/runtime.sx b/lib/ocaml/runtime.sx index 6f233907..d734a29d 100644 --- a/lib/ocaml/runtime.sx +++ b/lib/ocaml/runtime.sx @@ -1180,7 +1180,8 @@ let min_int = -4611686018427387904 let abs_float f = if f < 0.0 then 0.0 -. f else f let float_of_int n = n - let int_of_float f = f + let int_of_float f = + if f < 0.0 then _float_ceil f else _float_floor f ") (define ocaml-stdlib-loaded false) diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index da8230e0..5c8df858 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,14 @@ _Newest first._ binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree`) with insert + in-order traversal. Tests parametric ADT, recursive match, List.append, List.fold_left. +- 2026-05-09 Phase 5.1 — pi_leibniz.ml baseline (Leibniz formula, + 1000 terms × 100 → 314). Side-quest: `int_of_float` was wrong — + defined as identity in iteration 94 instead of truncation. Fixed + to `if f < 0.0 then ceil else floor` (truncate toward zero, real + OCaml semantics). Float.to_int still uses floor since OCaml's + documentation says "result is unspecified if the argument is nan + or falls outside the int range" — close enough for our scope. 32 + baseline programs total. - 2026-05-09 Phase 6 — Float module fleshed out (+6 tests, 598 total). New Float members: zero, one, minus_one, abs, neg, add, sub, mul, div, max, min, equal, compare, to_int, of_int,