如何做一个浮点数的二进制search?

如果你有一个Vec<u32>你可以使用slice::binary_search方法。

由于我不明白的原因, f32f64不执行Ord 。 由于原始types来自标准库,所以你Ord实现Ord ,所以不会出现你可以使用这个方法。

你怎么能有效地做到这一点?

我真的必须在包装结构中包装f64并实现Ord吗? 要做到这一点似乎是非常痛苦的,并且涉及到大量的transmute ,无意中无意地来回传递大量数据。

由于我不明白的原因,f32和f64不实现Ord。

因为浮点很难 ! 简短的版本是浮点数有一个特殊的值NaN – 不是一个数字。 IEEE浮点数规范指出1 < NaN1 > NaNNaN == NaN都是false

Ord说:

构成总订单的types的特质。

这意味着比较需要有整体性

a≤b或b≤a

但是我们只是看到浮点没有这个属性。

所以是的,你将需要创build一个包装types,以某种方式处理比较大量的NaN值 。 也许你的情况下,你可以断言,浮动值是从来没有NaN,然后​​调用到正常的PartialOrd特质。 这是一个例子:

 use std::cmp::Ordering; #[derive(PartialEq,PartialOrd)] struct NonNan(f64); impl NonNan { fn new(val: f64) -> Option<NonNan> { if val.is_nan() { None } else { Some(NonNan(val)) } } } impl Eq for NonNan {} impl Ord for NonNan { fn cmp(&self, other: &NonNan) -> Ordering { self.partial_cmp(other).unwrap() } } fn main() { let mut v: Vec<_> = [2.0, 1.0, 3.0].iter().map(|v| NonNan::new(*v).unwrap()).collect(); v.sort(); let r = v.binary_search(&NonNan::new(2.0).unwrap()); println!("{:?}", r); } 

其中一个切片方法是binary_search_by ,您可以使用它。 f32 / f64实现PartialOrd ,所以如果你知道他们永远不可能NaN ,你可以解开partial_cmp的结果:

 fn main() { let values = [1.0, 2.0, 3.0, 4.0, 5.0]; let location = values.binary_search_by(|v| { v.partial_cmp(&3.14).expect("Couldn't compare values") }); match location { Ok(i) => println!("Found at {}", i), Err(i) => println!("Not found, could be inserted at {}", i), } }