虽然Rust实现的所有整数类型Ord
都强调总排序,但浮点类型只能实现PartialOrd
.这意味着可能存在无法比较的浮点值.这似乎很难消化,因为浮点数可以被认为是实数的近似值,恰好是一个完全有序的集合.即使增加正负无穷大也能保持实数的整数排序.为什么这个奇怪的选择在Rust?
此限制意味着通用排序/搜索算法只能假设数字的部分排序.IEEE 754标准似乎提供了总排序谓词.
NaN在通用代码中是如此多的问题吗?
如果你有,Vec<u32>
你会使用该slice::binary_search
方法.
由于我不理解的原因,f32
并且f64
没有实施Ord
.由于基本类型来自标准库,因此您无法Ord
自己实现它们,因此您似乎无法使用此方法.
你怎么能有效地做到这一点?
我真的必须包装f64
一个包装器结构并Ord
在其上实现吗?这样做似乎非常痛苦,并且涉及大量transmute
不安全地来回传播数据块,实际上是没有理由的.
我想使用基于某个键max_by_key
从f64
s的向量中获取最大值。这是一个简单的例子,用一个小向量abs
作为关键:
let a: Vec<f64> = vec![-3.0, 0.2, 1.4];
*a.iter().max_by_key(|n| n.abs()).unwrap()
Run Code Online (Sandbox Code Playgroud)
但是,由于f64
没有实现Ord
,我得到
let a: Vec<f64> = vec![-3.0, 0.2, 1.4];
*a.iter().max_by_key(|n| n.abs()).unwrap()
Run Code Online (Sandbox Code Playgroud)
同样,sort_by_key
失败并出现相同的错误:
a.sort_by_key(|n| n.abs())
Run Code Online (Sandbox Code Playgroud)
我知道我可以绕过偏序限制来对浮点数向量进行排序 sort_by
b.sort_by(|m, n| m.partial_cmp(n).unwrap_or(Less))
Run Code Online (Sandbox Code Playgroud)
但这必须在一个向量上调用b
,我已经abs
为 的每个元素计算了键(在这种情况下)a
,然后我必须返回并找到 的相应元素a
,这看起来既复杂又缓慢。随着列表中项目数量的增加,我想尽量减少通过数据的次数。
有什么解决方法吗?