[][src]Trait float_eq::FloatEqAll

pub trait FloatEqAll<Rhs: ?Sized = Self> {
    type AllEpsilon: ?Sized + FloatEqUlpsEpsilon;
    fn eq_abs_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool;
fn eq_rmax_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool;
fn eq_rmin_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool;
fn eq_r1st_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool;
fn eq_r2nd_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool;
fn eq_ulps_all(
        &self,
        other: &Rhs,
        max_diff: &UlpsEpsilon<Self::AllEpsilon>
    ) -> bool; fn ne_abs_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn eq_rel_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn ne_rel_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn ne_rmax_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn ne_rmin_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn ne_r1st_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn ne_r2nd_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool { ... }
fn ne_ulps_all(
        &self,
        other: &Rhs,
        max_diff: &UlpsEpsilon<Self::AllEpsilon>
    ) -> bool { ... } }

Compare IEEE floating point values for equality using a uniform threshold.

This trait is used in the implementation of the float_eq! and assert_float_eq! families of macros. Comparison via this trait may not fit every composite type. For example, it likely ought not to be implemented for (f32, f64), which has a big difference in granularity between its fields.

Derivable

This trait can be used with #[derive]. The easiest way to do so is to use the #[derive_float_eq] helper macro, see the top level docs for example usage.

If you wish to derive this trait by itself, you will need a #[float_eq] attribute specifying all_epsilon, which is the type to be used as AllEpsilon, and is usually f32 or f64. Two instances are equal if all fields are equal, and not equal if any are not. This trait may not be derived for enums or generic structs at present.

#[derive(Debug, Clone, Copy, PartialEq, FloatEqAll)]
#[float_eq(ulps_epsilon = "PointUlps", all_epsilon = "f32")]
struct Point {
    x: f32,
    y: f32,
}

let a = Point { x: 1.0, y: -2.0 };
let b = Point { x: 1.5, y: -3.0 };
assert!(a.eq_abs_all(&b, &1.0));
assert!(a.ne_abs_all(&b, &0.9));

let c = Point { x: 1.000_000_1, y: -2.000_000_5 };
assert!(a.eq_ulps_all(&c, &2));
assert!(a.ne_ulps_all(&c, &1));

How can I implement FloatEqAll?

You will need to select an epsilon type to compare recursively with each field in your type, usually f32 or f64. Implementation is then usually a matter of calling through to an underlying FloatEqAll method for each field in turn. If not, you will need to take a close look at the descriptions of the algorithms on a method by method basis:

#[derive(Debug, Copy, Clone, PartialEq)]
struct MyComplex32 {
    re: f32,
    im: f32,
}

impl FloatEqAll for MyComplex32 {
    type AllEpsilon = f32;

    fn eq_abs_all(&self, other: &Self, max_diff: &f32) -> bool {
        self.re.eq_abs_all(&other.re, max_diff) && self.im.eq_abs_all(&other.im, max_diff)
    }

    fn eq_rmax_all(&self, other: &Self, max_diff: &f32) -> bool {
        self.re.eq_rmax_all(&other.re, max_diff) && self.im.eq_rmax_all(&other.im, max_diff)
    }

    fn eq_rmin_all(&self, other: &Self, max_diff: &f32) -> bool {
        self.re.eq_rmin_all(&other.re, max_diff) && self.im.eq_rmin_all(&other.im, max_diff)
    }

    fn eq_r1st_all(&self, other: &Self, max_diff: &f32) -> bool {
        self.re.eq_r1st_all(&other.re, max_diff) && self.im.eq_r1st_all(&other.im, max_diff)
    }

    fn eq_r2nd_all(&self, other: &Self, max_diff: &f32) -> bool {
        self.re.eq_r2nd_all(&other.re, max_diff) && self.im.eq_r2nd_all(&other.im, max_diff)
    }

    fn eq_ulps_all(&self, other: &Self, max_diff: &UlpsEpsilon<f32>) -> bool {
        self.re.eq_ulps_all(&other.re, max_diff) && self.im.eq_ulps_all(&other.im, max_diff)
    }
}

let a = MyComplex32 { re: 1.0, im: 2.000_003_6, };
let b = MyComplex32 { re: 1.000_000_1, im: 2.0, };

assert!(a.eq_abs_all(&b, &0.000_003_6));
assert!(a.ne_abs_all(&b, &0.000_003_5));

assert!(a.eq_rmax_all(&b, &0.000_001_8));
assert!(a.ne_rmax_all(&b, &0.000_001_7));

assert!(a.eq_ulps_all(&b, &15));
assert!(a.ne_ulps_all(&b, &14));

Examples

let a = [1.000_000_2f32, -2.0];
let b = [1.0f32, -2.000_002];

assert!(a.eq_abs_all(&b, &0.000_002));
assert!(a.ne_abs_all(&b, &0.000_001));

assert!(a.eq_rmax_all(&b, &0.000_001));
assert!(a.ne_rmax_all(&b, &0.000_000_5));

assert!(a.eq_ulps_all(&b, &8));
assert!(a.ne_ulps_all(&b, &7));

Associated Types

type AllEpsilon: ?Sized + FloatEqUlpsEpsilon

Type of the maximum allowed difference between each of two values' fields for them to be considered equal.

Loading content...

Required methods

fn eq_abs_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is equal to other, using an absolute epsilon comparison.

This must use the same algorithm as FloatEq::eq_abs.

fn eq_rmax_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is equal to other, using a relative epsilon comparison.

This must use the same algorithm as FloatEq::eq_rmax.

fn eq_rmin_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is equal to other, using a relative epsilon comparison.

This must use the same algorithm as FloatEq::eq_rmin.

fn eq_r1st_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is equal to other, using a relative epsilon comparison.

This must use the same algorithm as FloatEq::eq_r1st.

fn eq_r2nd_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is equal to other, using a relative epsilon comparison.

This must use the same algorithm as FloatEq::eq_r2nd.

fn eq_ulps_all(
    &self,
    other: &Rhs,
    max_diff: &UlpsEpsilon<Self::AllEpsilon>
) -> bool

Check whether self is equal to other, using an ULPs comparison.

This must use the same algorithm as FloatEq::eq_ulps.

Loading content...

Provided methods

fn ne_abs_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is not equal to other, using an absolute epsilon comparison.

Equal to !self.eq_abs_all(other, max_diff), there is no need to reimplement this for your own types.

fn eq_rel_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is equal to other, using a relative epsilon comparison.

Equal to self.eq_rmax_all(other, max_diff), there is no need to reimplement this for your own types.

fn ne_rel_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is not equal to other, using a relative epsilon comparison.

Equal to !self.eq_rel_all(other, max_diff), there is no need to reimplement this for your own types.

fn ne_rmax_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is not equal to other, using a relative epsilon comparison.

Equal to !self.eq_rmax_all(other, max_diff), there is no need to reimplement this for your own types.

fn ne_rmin_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is not equal to other, using a relative epsilon comparison.

Equal to !self.eq_rmin_all(other, max_diff), there is no need to reimplement this for your own types.

fn ne_r1st_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is not equal to other, using a relative epsilon comparison.

Equal to !self.eq_r1st_all(other, max_diff), there is no need to reimplement this for your own types.

fn ne_r2nd_all(&self, other: &Rhs, max_diff: &Self::AllEpsilon) -> bool

Check whether self is not equal to other, using a relative epsilon comparison.

Equal to !self.eq_r2nd_all(other, max_diff), there is no need to reimplement this for your own types.

fn ne_ulps_all(
    &self,
    other: &Rhs,
    max_diff: &UlpsEpsilon<Self::AllEpsilon>
) -> bool

Check whether self is not equal to other, using an ULPs comparison.

Equal to !self.eq_ulps_all(other, max_diff), there is no need to reimplement this for your own types.

Loading content...

Implementations on Foreign Types

impl<A, B> FloatEqAll<[B; 0]> for [A; 0] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 1]> for [A; 1] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 2]> for [A; 2] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 3]> for [A; 3] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 4]> for [A; 4] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 5]> for [A; 5] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 6]> for [A; 6] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 7]> for [A; 7] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 8]> for [A; 8] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 9]> for [A; 9] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 10]> for [A; 10] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 11]> for [A; 11] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 12]> for [A; 12] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 13]> for [A; 13] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 14]> for [A; 14] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 15]> for [A; 15] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 16]> for [A; 16] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 17]> for [A; 17] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 18]> for [A; 18] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 19]> for [A; 19] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 20]> for [A; 20] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 21]> for [A; 21] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 22]> for [A; 22] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 23]> for [A; 23] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 24]> for [A; 24] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 25]> for [A; 25] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 26]> for [A; 26] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 27]> for [A; 27] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 28]> for [A; 28] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 29]> for [A; 29] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 30]> for [A; 30] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 31]> for [A; 31] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B; 32]> for [A; 32] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized, '_, '_> FloatEqAll<&'_ B> for &'_ A where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized, '_, '_> FloatEqAll<&'_ mut B> for &'_ A where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized, '_, '_> FloatEqAll<&'_ B> for &'_ mut A where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized, '_, '_> FloatEqAll<&'_ mut B> for &'_ mut A where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<T: FloatEqAll> FloatEqAll<Option<T>> for Option<T> where
    T::AllEpsilon: Sized,
    UlpsEpsilon<T::AllEpsilon>: Sized
[src]

type AllEpsilon = Option<T::AllEpsilon>

impl<A, B> FloatEqAll<Cell<B>> for Cell<A> where
    A: FloatEqAll<B> + Copy,
    B: Copy
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized> FloatEqAll<RefCell<B>> for RefCell<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<[B]> for [A] where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl FloatEqAll<f32> for f32[src]

type AllEpsilon = f32

impl FloatEqAll<f64> for f64[src]

type AllEpsilon = f64

impl<A: ?Sized, B: ?Sized> FloatEqAll<Arc<B>> for Arc<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized> FloatEqAll<Box<B>> for Box<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A: ?Sized, B: ?Sized> FloatEqAll<Rc<B>> for Rc<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<Vec<B>> for Vec<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<VecDeque<B>> for VecDeque<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<A, B> FloatEqAll<LinkedList<B>> for LinkedList<A> where
    A: FloatEqAll<B>, 
[src]

type AllEpsilon = A::AllEpsilon

impl<K, VA, VB, S> FloatEqAll<HashMap<K, VB, S>> for HashMap<K, VA, S> where
    K: Eq + Hash,
    S: BuildHasher,
    VA: FloatEqAll<VB>, 
[src]

type AllEpsilon = VA::AllEpsilon

impl<K, VA, VB> FloatEqAll<BTreeMap<K, VB>> for BTreeMap<K, VA> where
    K: Eq + Ord,
    VA: FloatEqAll<VB>, 
[src]

type AllEpsilon = VA::AllEpsilon

impl<T: FloatEqAll> FloatEqAll<Complex<T>> for Complex<T>[src]

type AllEpsilon = T::AllEpsilon

Loading content...

Implementors

Loading content...