| 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 |
|
| 10 use crate::types::Float; |
|
| 11 use std::cmp::{PartialOrd,Ord,Ordering,Ordering::*}; |
|
| 12 |
|
| 13 /// A container for floating point numbers. |
|
| 14 /// |
|
| 15 /// The implementation of [`Ord`] for this type type sorts `NaN` as the least element. |
|
| 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 } |
|