Fri, 18 Nov 2022 10:34:04 +0200
Add some keywords and categories
5 | 1 | /*! |
2 | This module provides an artificial total order of floating point numbers. | |
3 | ||
4 | The [`NaNLeast`]`<F>` container for `F` a [`Float`] puts `F` in an [`Ord`] total order with | |
5 | `NaN` the least element. This allows the numbers to be sorted with `NaN` the “least important” | |
6 | element when looking for the maximum. Thus erroneous computations producing `NaN` can be ignored | |
7 | when there are good results. | |
8 | */ | |
9 | ||
0 | 10 | use crate::types::Float; |
11 | use std::cmp::{PartialOrd,Ord,Ordering,Ordering::*}; | |
12 | ||
5 | 13 | /// A container for floating point numbers. |
14 | /// | |
15 | /// The implementation of [`Ord`] for this type type sorts `NaN` as the least element. | |
0 | 16 | #[derive(Debug, Clone, Copy)] |
17 | pub struct NaNLeast<F : Float>(pub F); | |
18 | ||
19 | impl<F : Float> Ord for NaNLeast<F> { | |
20 | #[inline] | |
21 | fn cmp(&self, NaNLeast(b) : &Self) -> Ordering { | |
22 | let NaNLeast(a) = self; | |
23 | match a.partial_cmp(b) { | |
24 | None => match (a.is_nan(), b.is_nan()) { | |
25 | (true, false) => Less, | |
26 | (false, true) => Greater, | |
27 | _ => Equal // The case (true, true) should not occur! | |
28 | } | |
29 | Some(order) => order | |
30 | } | |
31 | } | |
32 | } | |
33 | ||
34 | impl<F : Float> PartialEq for NaNLeast<F> { | |
35 | #[inline] | |
36 | fn eq(&self, other : &Self) -> bool { self.cmp(other)==Equal } | |
37 | } | |
38 | ||
39 | impl<F : Float> Eq for NaNLeast<F> { } | |
40 | ||
41 | impl<F : Float> PartialOrd for NaNLeast<F> { | |
42 | #[inline] | |
43 | fn partial_cmp(&self, other : &Self) -> Option<Ordering> { Some(self.cmp(other)) } | |
44 | } |