一、源碼
這段代碼實現了一個符合 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。