package floatml
Install
dune-project
Dependency
Authors
Maintainers
Sources
md5=e42bdd511121f3bd65f9fbcdb71be4a8
sha512=118ef63d0a101465a788b00501d708eacfff402fdce5ca0f57f62d80ee5e585e221cc270760c7702b705a9c10e89f2bbe1b59327dcf67bf4ea25f4d8dd216fd3
Description
Deterministic, IEEE-754-compliant interface for floating point operators over f16, f32, f64 and f128, backed by Rust's rustc_apfloat. Requires a Rust toolchain (cargo, 1.77 or newer) to build.
Added to opam-repository:
README
floatml - IEEE-754 floats for OCaml
Add Float16, Float32, Float64, and Float128 types to OCaml, with full support for arithmetic, comparisons, and conversions to bit representation.
It also provides AnyFloat, which hides the specific float type but will error if mismatched sizes are used together.
This project aims at being an easy to use, correct, and efficient implementation of IEEE-754 floating point arithmetic for OCaml.
Implementation
All four formats are evaluated in software by Rust's rustc_apfloat, the LLVM APFloat port that rustc itself uses for compile-time float constant evaluation. This makes every result correctly rounded and bit-for-bit deterministic across every platform, and leans on a battle-tested soft-float rather than a hand-written one.
The numeric core lives in rust/lib.rs (macros generate the bindings for all four precisions); src/floatml.ml is a thin OCaml binding layer over it. Building therefore requires a Rust toolchain (cargo) on PATH in addition to the OCaml dependencies.
Performance and allocation
Crossing into Rust is the dominant cost of an operation, so the binding is built to make that crossing as close to free as possible. In native code an operation on Float16, Float32 or Float64 is a direct C call that touches neither the OCaml runtime nor the OCaml heap, and allocates at most the box for its result:
operation | ns/op | words allocated |
|---|---|---|
| 2–6 | 0 |
| 15 | 0 |
| 16 | 3 (the |
| 20 | 4 (one custom block) |
| 17 | 5 |
Comparisons, the classification predicates, compare and bits_equal allocate nothing at any precision. Float16 operators allocate nothing either, its bit pattern being an immediate int. Float128 carries its 128 bits whole, in a custom block. Only of_string and the integer conversions, which have to return an option of a bit pattern, allocate more than their result.
Coverage
Every operation IEEE 754 requires of a binary format is here.
Arithmetic rounds to nearest-ties-to-even; an explicit rounding direction is taken where IEEE 754 makes it a parameter (roundToIntegral, convertToInteger, convertFromInt, and convertFormat).
Note we do not implement transcendentals, because they are non-deterministic across platforms.
Dependencies (4)
-
conf-rust-2024
build -
zarith
>= "1.13" -
dune
>= "3.0" -
ocaml
>= "4.14.0"
Dev Dependencies (1)
-
odoc
with-doc
Used by
None
Conflicts
None