# \[ANN\] New package: floatml

**URL:** <https://discuss.ocaml.org/t/ann-new-package-floatml/18431>\
**Category:** Ecosystem\
**Tags:** floating-point, opam\
**Created:** [August 9, 2026, 11:28am UTC](https://discuss.ocaml.org/t/ann-new-package-floatml/18431 "2026-08-09T11:28:02Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![N1ark](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/n1ark/32/6207_2.png) [@N1ark](https://discuss.ocaml.org/u/N1ark)\
**Post date:** [August 9, 2026, 11:28am UTC](https://discuss.ocaml.org/t/ann-new-package-floatml/18431/1 "2026-08-09T11:28:02Z")

</div>

Hi :​) Wanted to announce a new package I worked on over the past week I just published, **[floatml](https://github.com/N1ark/floatml)**! It’s a tiny wrapper around Rust’s soft float library ([`rustc_apfloat`](https://github.com/rust-lang/rustc_apfloat)), enabling fast and efficient IEEE-754 `float16`, `float32`, `float64` and `float128` in OCaml. I also made sure the code allocates as little as possible, so it should be reasonably efficient.

**Disclaimer:** a good chunk of the code is LLM-authored. I chose the interface I wanted and guided it, but the glue code with Rust is LLM generated (and extensively tested!)

I had to create it for [Soteria](https://soteria-tools.com), where we need reductions for concrete float operations, to avoid using Z3 when possible. Maybe you’ll find a use for it too!

---

<div class="post-metadata">

**Author:** ![sim642](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sim642/32/3597_2.png) [@sim642](https://discuss.ocaml.org/u/sim642)\
**Post date:** [August 10, 2026, 7:24pm UTC](https://discuss.ocaml.org/t/ann-new-package-floatml/18431/2 "2026-08-10T19:24:18Z")

</div>

The README says:

> Because `Float128`’s bit pattern is an `(int64 * int64)` pair, every result costs a tuple and two boxed words.

Here’s a (possibly very bad) idea: use a record with two `float` fields (or just a 2-element `floatarray`) to make use of the flat float array/record optimization, but just store the `int64` bits in them, i.e., really just all the bits of a `float128` contiguously. (Like poor man’s OxCaml unboxing.)  
If you never look at their contents as `float` on the OCaml side, it might be fine??

**EDIT:** Or at that point it would probably be better to use a custom block like a boxed `int64` is as well.

---

<div class="post-metadata">

**Author:** ![N1ark](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/n1ark/32/6207_2.png) [@N1ark](https://discuss.ocaml.org/u/N1ark)\
**Post date:** [August 11, 2026, 4:10pm UTC](https://discuss.ocaml.org/t/ann-new-package-floatml/18431/3 "2026-08-11T16:10:33Z")

</div>

Oh that’s clever! The issue with using a record of `float`s or an array is that for polymorphic comparisons we inherit `float`’s comparison, which would break some stuff (since all NaNs are equal, and +0 == -0). Ended up going with a custom block, which drops allocations of `F128.add` from 9 to 4 :​D
