Beeg float library, a Rust port of Fabrice Bellard's libbf
IEEE 754 Semantics
Full IEEE 754 semantics: signed zeros, NaN, infinities, configurable exponent width, subnormals, all five rounding modes, all five status flags.
Transcendental Functions
- exp, log, pow, sin, cos, tan, atan, atan2, asin, acos
- Decimal floating point (BigDecimal) with independent base-10 arithmetic
no_stdcompatible (requiresalloc)- Pure Rust with zero dependencies
use libbeef::format::formats;
use libbeef::Float;
type Quad = Float<f128>;
fn main() {
let a: Quad = "3.14159265358979323846".parse().unwrap();
let b: Quad = "2.71828182845904523536".parse().unwrap();
let result = (a * b).sin();
println!("{result}"); // 0.773942685266708278263054855332479932...
}
Float pairs a value with a compile-time format, so * and .sin() use 128-bit precision and round-to-nearest-even automatically - no format argument at every call site.
Algorithms
libbeef implements the same algorithms as the C libbf: NTT-based multiplication, Newton iteration for division/sqrt, and AGM/binary-splitting for transcendentals. The asymptotic complexity is optimal for each operation class:
| Operation class | Complexity | Algorithm |
|---|---|---|
| add, sub, cmp | O(n) | Linear scan |
| mul | O(n log n) | Number-theoretic transform |
| div, sqrt | O(M(n)) | Newton iteration over NTT mul |
| exp, log, sin, โฆ | O(M(n) ยท log n) | AGM / binary splitting |
Performance Benchmarks
Empirically (full data in docs/benchmark-report.md), libbeef tracks the C libbf's throughput with constant-factor overhead from Rust's bounds checking and allocation model:
| op | 256 bits | 30 000 bits | 300 000 bits | vs libbf | vs rug (GMP/MPFR) |
|---|---|---|---|---|---|
| mul | 6.7 | 84 | 100 ns/limb | 1.3โ2.0ร | 0.9โ1.3ร |
| div | 17.3 | 515 | 659 ns/limb | 1.1โ1.4ร | 2.6โ3.5ร |
| sqrt | 38.3 | 384 | 597 ns/limb | 1.2โ1.3ร | 3.2โ4.3ร |
| sin | 1051 | - | - ns/limb | 0.7ร (faster) | 3.6ร |
The mul row is the most informative: a quadratic algorithm would show ~10ร growth per decade of operand size (47 โ 469 โ 4688 limbs), but libbeef grows 4.2ร then 1.2ร - the O(n log n) NTT envelope, the same shape as the C original. At 300k bits libbeef is ~2ร libbf and 1.3ร GMP, while being 4ร faster than num-bigint's schoolbook/Toom multiplication.
For transcendentals, libbeef matches or beats the C libbf on sin/cos/tan/pow and is within 15% on log/atan. The uniform 3โ5ร gap to MPFR is algorithmic (MPFR uses different, better algorithms for these functions; the C libbf shows the same gap).
Division and sqrt show a larger constant-factor gap to GMP/MPFR (~3ร). This is an inherent property of libbf's Newton-reciprocal approach vs. GMP's tuned divide-and-conquer - the same ratio appears in the C original.
Key Advantages
Pure Rust, no system dependencies. rug/GMP requires a C compiler, system GMP/MPFR libraries, and a build script that probes the host. libbeef is a single
cargo addwith nobuild.rs,-lm, norpkg-config. It builds on any target rustc supports - including WASM, embedded, and cross-compilation - with zero configuration.Small binary footprint. With GMP/MPFR statically linked, a trivial program that multiplies two numbers and computes sin produces:
| Library | Binary size (stripped) |
|---|---|
| libbeef | 482 KiB |
| num-bigint (integers only, no trig) | 448 KiB |
| malachite (integers only, no trig) | 658 KiB |
| rug (GMP + MPFR statically linked) | 680 KiB |
libbeef delivers full floating-point arithmetic and transcendentals in less space than malachite or rug need for integers alone. The num-bigint binary is smaller only because it cannot compute sin at all - it has no floating-point layer.
Correct and complete. libbeef passes libbf's own verification suite across every operation, precision, and rounding mode. It is not a "good enough" approximation library - it implements IEEE 754 correctly-rounded arithmetic with configurable exponent width and subnormals.
no_stdready. Only requiresalloc. No file I/O, no threads, no system calls beyond allocation.More permissive license. libbeef is MIT-licensed, while GMP/MPFR are LGPL. This makes libbeef a better choice for license-sensitive projects where additional legal review for LGPL is undesirable.
When to Use Alternatives
Maximum throughput at large precisions (>10k bits): GMP/MPFR (via rug) has a heavily tuned FFT and Toom-Cook stack with ~2โ3ร better constants for multiplication and ~3ร for division. If raw ns/op at million-bit precision is the bottleneck, use rug.
Integer-only workloads: If you never need floating point, rounding, or transcendentals, num-bigint or malachite give you a simpler API focused purely on integers.
Decimal arithmetic at scale: libbeef's decimal path is functional but not yet performance-tuned (it routes through binary conversion rather than native base-10โน kernels).
Building and Testing
cargo build # build (default features: std)
cargo test # run all tests
cargo test --test bftest # libbf verification suite (quick, single-seed)
cargo doc --open # generate and view API docs
Feature Flags
| Feature | Description |
|---|---|
| std (default) | Enables std support |
| num-traits | Trait impls for the num ecosystem |
| num-integer | Additional num integer traits |
| serde | Serialization support |
License
MIT (same as in libbf)
Comments
No comments yet. Start the discussion.