Wed, 07 Dec 2022 07:00:27 +0200
Added tag v0.1.0 for changeset 51bfde513cfa
| 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 | } |