#平方根 #IEEE-754 #浮点数 #计算 #函数 #双精度 #rustc-apfloat

ieee-apsqrt

使用 rustc_apfloat 的 IEEE 浮点数的平方根函数

2 个版本

0.1.1 2023 年 9 月 13 日
0.1.0 2023 年 9 月 10 日

#1056 in Rust 模式

Download history 1179/week @ 2024-04-09 1256/week @ 2024-04-16 1581/week @ 2024-04-23 768/week @ 2024-04-30 3477/week @ 2024-05-07 5467/week @ 2024-05-14 6183/week @ 2024-05-21 6882/week @ 2024-05-28 1326/week @ 2024-06-04 633/week @ 2024-06-11 817/week @ 2024-06-18 589/week @ 2024-06-25 297/week @ 2024-07-02 335/week @ 2024-07-09 759/week @ 2024-07-16 981/week @ 2024-07-23

2,459 每月下载量

Apache-2.0 WITH LLVM-exception

28KB
424

这是 IEEE APSqRt,一个用于与 rustc_apfloat 的 IEEE 754 浮点数一起使用的平方根实现。

(APFloat 是任意精度浮点数的缩写。IEEE APSqRt 是 IEEE 754 APFloat Square Root 的缩写。与 APFloat 不同,它只设计用于与 IEEE 754 单精度、双精度和四精度浮点数一起工作;因此,它本身不提供任意精度。)

原因

rustc_apfloat 是一个软件浮点数库。它是 LLVM 项目的 "APFloat" 的 Rust 版本。这些库强调清晰性和正确性,但速度仍然相当快。它们分别用于 rustcclang 编译器,以进行编译时的浮点数运算。这些编译器不使用宿主机的浮点数,因为在交叉编译时,宿主机和目标机的行为可能很难或不可能协调。仿真器通常也有相同的问题。我在编写一个确定性的 RV32-G 仿真器,作为其中的一部分,我需要特别模拟 RISC-V 标准的浮点数规范。rustc_apfloat 来拯救!

因为 rustc_apfloat 实现了 RISC-V 浮点数仿真所需的几乎所有操作,这使我的生活变得更加容易——但是最后一个操作,平方根,非常重要,所以我必须自己实现它。使用宿主机的 sqrt 函数来做这些会更快、更简单,并且接受仿真的不一致性,但我的仿真器旨在适应多人游戏逻辑循环(?!?!?!),所以它必须是确定的。一个在任何平台上都是完全相同的错误的差劣算法,因此比一个即使有微小的平台之间差异的优良算法更好。

我最初实现了一个非常简单的猜测和检查算法(见 Bad APSqRt),但是一旦我完成了这个,我就有了一切需要来实现和理解牛顿-拉夫森的方法。这个包是这个结果。

算法

IEEE APSqRt实现了牛顿-拉夫森方法,也称为巴比伦方法。它首先形成初始猜测值 2^(指数/2),然后通过以下公式反复优化它: new_guess = (old_guess + square / old_guess) / 2。经过5-7次迭代后,这个值将非常接近答案。

精度

如果有精确解,IEEE APSqRt的任何形式都能找到它。对于sqrt_fast,大约70%的不精确解将是正确的,大约30%的解将偏离一个ulp,而极少数解将偏离两个ulp。对于执行更高精度操作的sqrt_slow,通常只需要再迭代一次,答案将100%正确。(遗憾的是,由于rustc_apfloat的外部接口限制,sqrt_slow仅适用于32位和64位浮点数。)

IEEE APSqRt产生的所有NaN都是符合RISC-V标准的“规范NaN”。

如何使用

使用ieee_apsqrt::sqrt_fast调用一个u32/u64/u128,或者使用ieee_apsqrt::sqrt_accurate调用一个u32/u64。前者函数精度稍低,但大约快两倍。后者函数尽可能精确,但大约慢一半。这两个函数还要求一个舍入模式。

这两个函数都返回一个元组,为(rustc_apfloat::StatusAnd<uXX>, u32),其中第一个值是计算结果,第二个值是需要的牛顿-拉夫森迭代次数。

如果您在仿真用途中计算时钟周期,请将平方根的基本成本视为一次乘法,迭代成本为一次除法、一次加法和一次乘法。将sqrt_fast视为在请求的精度下执行操作,而sqrt_accurate在两倍精度下执行(例如,单精度变为双精度,双精度变为四精度)。

法律声明

IEEE APSqRt版权所有 2023 Solra Bizna。

IEEE APSqRt采用Apache 2许可证,并带有LLVM例外条款。这是与rustc_apfloat crate相同的许可证。这是确保IEEE APSqRt可以在rustc_apfloat可以使用的地方使用的最简单方法。

依赖关系

~355KB