← 返回信息流
AI 资讯Hacker News·2 小时前

Rust版Beeg float浮点库发布,移植自Bellard的libbf

原标题:Beeg float library, a Rust port of Fabrice Bellard's 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、无穷大、可配置指数宽度、次正规数、五种舍入模式以及五种状态标志。
  • 超越函数:提供 explogpowsincostanatanatan2asinacos
  • 十进制浮点数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 倍。
  • 对于超越函数,libbeefsin/cos/tan/pow 上匹配或超过 C 版 libbf,在 log/atan 上差距在 15% 以内。与 MPFR 之间有统一的 3-5 倍差距(这是算法层面的:MPFR 对这些函数使用了不同的、更优的算法;C 版 libbf 也显示相同的差距)。
  • 除法和平方根与 GMP/MPFR 相比有较大的常数因子差距(~3 倍)。这是 libbf 的牛顿倒数方法相对于 GMP 经过调优的分治方法的固有特性 —— 同样的比率也出现在 C 原版中。

关键优势

  1. 纯 Rust,无系统依赖rug/GMP 需要 C 编译器、系统 GMP/MPFR 库以及探测宿主环境的构建脚本。libbeef 只需 cargo add,没有 build.rs-lmpkg-config。它可以在任何 rustc 支持的平台上构建(包括 WASM、嵌入式、交叉编译),零配置。
  2. 二进制体积小。将 GMP/MPFR 静态链接后,一个仅执行两个数相乘并计算 sin 的简单程序,libbeef 生成的二进制文件比 malachiterug 仅用于整数运算所需的体积还要小。num-bigint 的二进制更小,只是因为它根本无法计算 sin —— 它没有浮点层。
  3. 正确且完整libbeef 通过了 libbf 自身的验证套件,覆盖每个运算、精度和舍入模式。它不是「足够好」的近似库,而是实现了 IEEE 754 正确舍入的算术,带有可配置指数宽度和次正规数。
  4. no_std 就绪。只需要 alloc。无文件 I/O、无线程、无系统调用(除内存分配外)。
  5. 许可证更宽松libbeef 采用 MIT 许可证,而 GMP/MPFR 是 LGPL。这使得 libbeef 成为对许可证敏感的项目更好的选择,避免了 LGPL 带来的额外法律审查。

不适用场景

  • 如果超大精度(>10k 比特)下的吞吐量是瓶颈,建议使用 GMP/MPFR(通过 rug),它们拥有经过高度调优的 FFT 和 Toom-Cook 栈,乘法常数约好 2-3 倍,除法约好 3 倍。
  • 如果仅需要整数运算,不需要浮点、舍入或超越函数,num-bigintmalachite 提供更简单的 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-bigintmalachite 等整数库(当需要浮点运算时)。
  • 核心优势:纯 Rust、无系统库、构建简单、二进制体积小、正确性经过验证、no_std 兼容、MIT 许可证。
  • 不适合追求极致吞吐量的超大精度场景(此时应选 GMP/MPFR),也不适合纯整数工作负载或需要高性能十进制算术的场合。
  • 通过了 libbf 的验证套件,确保正确舍入和完整 IEEE 754 行为。

意义与影响

libbeef 的出现填补了 Rust 生态在高质量任意精度浮点库方面的空白。在此之前,Rust 开发者若要使用如同 GMP/MPFR 级别的正确舍入算术,通常需要依赖 `rug

查看原文 →github.com