一、源码
这段代码实现了一个符合 IEEE 754-2008 标准的 minNum 函数(在 Rust 中命名为 fmin),该功能在 IEEE 754-2019 标准中已被 minimumNumber 取代。
/* SPDX-License-Identifier: MIT OR Apache-2.0 */
//! IEEE 754-2008 `minNum`. This has been superseded by IEEE 754-2019 `minimumNumber`.
//!
//! Per the spec, returns the canonicalized result of:
//! - `x` if `x < y`
//! - `y` if `y < x`
//! - The other number if one is NaN
//! - Otherwise, either `x` or `y`, canonicalized
//! - -0.0 and +0.0 may be disregarded (unlike newer operations)
//!
//! Excluded from our implementation is sNaN handling.
//!
//! More on the differences: [link].
//!
//! [link]: https://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/background/minNum_maxNum_Removal_Demotion_v3.pdfuse super::super::Float;#[inline]
pub fn fmin<F: Float>(x: F, y: F) -> F {let res = if y.is_nan() || x < y { x } else { y };// Canonicalizeres * F::ONE
}
二、功能说明
1.核心逻辑:
-
如果 y 是 NaN(非数字),或者 x 小于 y,则返回 x。
-
否则返回 y。
-
最后对结果进行“规范化”(Canonicalize),即乘以 F::ONE(可能是为了确保结果的格式一致,比如处理浮点数的符号位或特殊表示)。
- 规范行为(根据注释):
-
如果 x < y,返回 x。
-
如果 y < x,返回 y。
-
如果其中一个数是 NaN,返回另一个数(即忽略 NaN)。
-
如果 x 和 y 相等(比如 -0.0 和 +0.0),可以返回任意一个(-0.0 和 +0.0 被视为相同,不像新标准那样区分)。
-
结果会被规范化(Canonicalized)。
- 未实现的功能:
- 不处理 sNaN(Signaling NaN,触发异常的 NaN),只处理 qNaN(Quiet NaN,静默 NaN)。
三、代码解析
#[inline]
pub fn fmin<F: Float>(x: F, y: F) -> F {let res = if y.is_nan() || x < y { x } else { y };res * F::ONE // 规范化
}
-
#[inline]:提示编译器尝试内联优化该函数。
-
F: Float:泛型约束,要求 F 必须是实现了 Float trait 的类型(比如 f32 或 f64)。
-
y.is_nan():检查 y 是否是 NaN。
-
x < y:比较 x 和 y 的大小。
-
res * F::ONE:对结果进行规范化(可能是无操作,取决于 F::ONE 的具体实现)。
四、规范化(Canonicalize)
- 注释提到结果会被“Canonicalized”,但具体行为取决于 F::ONE 的实现。通常 F::ONE 是 1.0,所以 res * 1.0 可能不会改变数值,但可能会确保浮点数的二进制表示符合规范(比如清除多余的符号位或标准化 NaN 的表示形式)。
五、总结
这段代码实现了 IEEE 754-2008 的 minNum,其核心逻辑是返回两个数中较小的一个,并优先忽略 NaN。相比新标准(IEEE 754-2019),它不严格区分 -0.0 和 +0.0,并且不处理 sNaN。