Rust版Beeg float浮点库发布,移植自Bellard的libbf
速览
Beeg float是Rust语言对Fabrice Bellard的libbf的完整移植,提供高精度浮点运算能力。该库支持多种浮点格式,适用于科学计算和数值模拟场景。作为Rust生态中的重要数值库,它将增强Rust在科学计算领域的应用潜力。
AI 深度解读
背景
Fabrice Bellard 是一位知名的软件工程师,他开发了 libbf —— 一个轻量级的任意精度浮点运算库,采用 C 语言编写,以其高效实现 IEEE 754 语义和超越函数而著称。近日,开发者将该库完整移植到了 Rust,命名为 libbeef(全称 "Beeg Float Library")。该项目出现在 Hacker News 上,旨在为 Rust 生态提供一个纯 Rust、零依赖、无系统库依赖的高精度浮点运算替代方案,填补 Rust 在正确舍入浮点算术与超越函数方面的空白。
核心内容
libbeef 是对 Fabrice Bellard 的 libbf 的 Rust 翻译,实现了一个紧凑的任意精度浮点库。其核心特性包括:
- 完整的 IEEE 754 语义:支持有符号零、NaN、无穷大、可配置指数宽度、次正规数、五种舍入模式以及五种状态标志。
- 超越函数:提供
exp、log、pow、sin、cos、tan、atan、atan2、asin、acos。 - 十进制浮点数(
BigDecimal),支持独立的十进制算术。兼容no_std(但需要alloc支持)。 - 纯 Rust,零依赖。
使用示例(来自 README):
use libbeef::format::formats;
use libbeef::Float;
type Quad = Float<formats::Binary128>;
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<F> 将数值与编译期格式绑定,因此 * 和 .sin() 会自动使用 128 位精度和 round-to-nearest-even 模式,无需在每个调用点传递格式参数。
算法实现:libbeef 实现了与 C 版 libbf 相同的算法:基于 NTT(数论变换)的乘法、用于除法和平方根的牛顿迭代、用于超越函数的 AGM(算术-几何平均)/二分拆分。每种运算的渐近复杂度均为最优。
性能对比(详细数据见 docs/benchmark-report.md):
libbeef在吞吐量上跟踪 C 版libbf,但由于 Rust 的边界检查和内存分配模型,存在常数因子的开销。- 乘法是信息量最大的测试:二次算法在操作数大小每增加 10 倍时会增长约 10 倍(47 → 469 → 4688 个 limb),但
libbeef分别增长 4.2 倍和 1.2 倍 —— 这也符合 O(n log n) NTT 包络,与 C 原版形状相同。在 30 万比特时,libbeef速度约为libbf的 2 倍,约为 GMP 的 1.3 倍,比num-bigint的 schoolbook/Toom 乘法快 4 倍。 - 对于超越函数,
libbeef在sin/cos/tan/pow上匹配或超过 C 版libbf,在log/atan上差距在 15% 以内。与 MPFR 之间有统一的 3-5 倍差距(这是算法层面的:MPFR 对这些函数使用了不同的、更优的算法;C 版libbf也显示相同的差距)。 - 除法和平方根与 GMP/MPFR 相比有较大的常数因子差距(~3 倍)。这是
libbf的牛顿倒数方法相对于 GMP 经过调优的分治方法的固有特性 —— 同样的比率也出现在 C 原版中。
关键优势:
- 纯 Rust,无系统依赖。
rug/GMP 需要 C 编译器、系统 GMP/MPFR 库以及探测宿主环境的构建脚本。libbeef只需cargo add,没有build.rs、-lm或pkg-config。它可以在任何rustc支持的平台上构建(包括 WASM、嵌入式、交叉编译),零配置。 - 二进制体积小。将 GMP/MPFR 静态链接后,一个仅执行两个数相乘并计算 sin 的简单程序,
libbeef生成的二进制文件比malachite或rug仅用于整数运算所需的体积还要小。num-bigint的二进制更小,只是因为它根本无法计算 sin —— 它没有浮点层。 - 正确且完整。
libbeef通过了libbf自身的验证套件,覆盖每个运算、精度和舍入模式。它不是「足够好」的近似库,而是实现了 IEEE 754 正确舍入的算术,带有可配置指数宽度和次正规数。 no_std就绪。只需要alloc。无文件 I/O、无线程、无系统调用(除内存分配外)。- 许可证更宽松。
libbeef采用 MIT 许可证,而 GMP/MPFR 是 LGPL。这使得libbeef成为对许可证敏感的项目更好的选择,避免了 LGPL 带来的额外法律审查。
不适用场景:
- 如果超大精度(>10k 比特)下的吞吐量是瓶颈,建议使用 GMP/MPFR(通过
rug),它们拥有经过高度调优的 FFT 和 Toom-Cook 栈,乘法常数约好 2-3 倍,除法约好 3 倍。 - 如果仅需要整数运算,不需要浮点、舍入或超越函数,
num-bigint或malachite提供更简单的 API。 - 如果需要大规模十进制算术,
libbeef的十进制路径目前功能可用但未经性能调优(它通过二进制转换路由,而非原生 base-10⁹ 内核)。
构建与测试命令:
cargo build # 构建(默认特性:std)
cargo test # 运行所有测试
cargo test --test bftest # libbf 验证套件(快速,单种子)
cargo doc --open # 生成并查看 API 文档
许可证:MIT(与 libbf 相同)。
关键要点
libbeef是 Fabrice Bellard 的libbf的 Rust 移植,提供任意精度浮点运算和超越函数,完全在 Rust 中实现,零外部依赖。- 全面支持 IEEE 754 语义(有符号零、NaN、无穷大、次正规数、五种舍入模式和五种状态标志)。
- 算法上沿用 C 原版的 NTT 乘法、牛顿迭代、AGM/二分拆分,渐近复杂度最优。
- 性能在大部分操作上与 C 版
libbf相当,乘法在 30 万比特时甚至快 2 倍;与 GMP/MPFR 相比主要受限于常数因子,但超越了num-bigint和malachite等整数库(当需要浮点运算时)。 - 核心优势:纯 Rust、无系统库、构建简单、二进制体积小、正确性经过验证、
no_std兼容、MIT 许可证。 - 不适合追求极致吞吐量的超大精度场景(此时应选 GMP/MPFR),也不适合纯整数工作负载或需要高性能十进制算术的场合。
- 通过了
libbf的验证套件,确保正确舍入和完整 IEEE 754 行为。
意义与影响
libbeef 的出现填补了 Rust 生态在高质量任意精度浮点库方面的空白。在此之前,Rust 开发者若要使用如同 GMP/MPFR 级别的正确舍入算术,通常需要依赖 `rug
