[][src]Trait float_eq::FloatEqAllDebug

pub trait FloatEqAllDebug<Rhs: ?Sized = Self>: FloatEqAll<Rhs> {
    type DebugEpsilon: Debug;
    type DebugUlpsEpsilon: Debug;
    fn debug_abs_all_epsilon(
        &self,
        other: &Rhs,
        max_diff: &Self::Epsilon
    ) -> Self::DebugEpsilon;
fn debug_rel_all_epsilon(
        &self,
        other: &Rhs,
        max_diff: &Self::Epsilon
    ) -> Self::DebugEpsilon;
fn debug_ulps_all_epsilon(
        &self,
        other: &Rhs,
        max_diff: &Self::UlpsEpsilon
    ) -> Self::DebugUlpsEpsilon; }

Debug context for when an assert using FloatEqAll fails.

This is used internally by the assert_float_eq! family of macros to provide debug context information to the user when abs_all, rel_all or ulps_all checks fail.

How can I implement FloatEqAllDebug?

You should first implement FloatEqAll and FloatDiff. The outputs from FloatEqAllDebug will be the epsilon values used by the comparison widened to the structural shape of the most complex type. Most types will have implemented a custom ULPs type that mirrors their field structure. Implementation is then usually a matter of simply calling through to an underlying FloatEqDebugmethod 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, Clone, Copy, PartialEq)]
struct MyComplex32 {
    re: f32,
    im: f32,
}

#[derive(Debug, Clone, Copy, PartialEq)]
struct MyComplex32Ulps {
    re: <f32 as FloatDiff>::UlpsDiff,
    im: <f32 as FloatDiff>::UlpsDiff,
}

impl FloatEqAll for MyComplex32 {
    type Epsilon = f32;
    type UlpsEpsilon = u32;

    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_rel_all(&self, other: &Self, max_diff: &f32) -> bool {
        self.re.eq_rel_all(&other.re, max_diff) && self.im.eq_rel_all(&other.im, max_diff)
    }

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

impl FloatEqAllDebug for MyComplex32 {
    type DebugEpsilon = MyComplex32;
    type DebugUlpsEpsilon = MyComplex32Ulps;

    fn debug_abs_all_epsilon(
        &self,
        other: &Self,
        max_diff: &Self::Epsilon
    ) -> Self::DebugEpsilon {
        MyComplex32 {
            re: self.re.debug_abs_all_epsilon(&other.re, max_diff),
            im: self.im.debug_abs_all_epsilon(&other.im, max_diff),
        }
    }

    fn debug_rel_all_epsilon(
        &self,
        other: &Self,
        max_diff: &Self::Epsilon
    ) -> Self::DebugEpsilon {
        MyComplex32 {
            re: self.re.debug_rel_all_epsilon(&other.re, max_diff),
            im: self.im.debug_rel_all_epsilon(&other.im, max_diff),
        }
    }

    fn debug_ulps_all_epsilon(
        &self,
        other: &Self,
        max_diff: &Self::UlpsEpsilon,
    ) -> Self::DebugUlpsEpsilon {
        MyComplex32Ulps {
            re: self.re.debug_ulps_all_epsilon(&other.re, max_diff),
            im: self.im.debug_ulps_all_epsilon(&other.im, max_diff),
        }
    }
}

let a = MyComplex32 { re: 1.0, im: 200.0 };
let b = MyComplex32 { re: 50.0, im: 1.0 };

assert_eq!(
    a.debug_abs_all_epsilon(&b, &0.2),
    MyComplex32 { re: 0.2, im: 0.2 }
);
assert_eq!(
    a.debug_rel_all_epsilon(&b, &0.2),
    MyComplex32 { re: 10.0, im: 40.0 }
);
assert_eq!(
    a.debug_ulps_all_epsilon(&b, &8),
    MyComplex32Ulps { re: 8, im: 8 }
);

How can I compare two different types?

The type to be compared with is controlled by FloatEqDebug's parameter. Following on from our previous example, if we wanted to treat f32 as a complex number with an imaginary component of 0.0:

impl FloatEqAll<f32> for MyComplex32 {
    type Epsilon = f32;
    type UlpsEpsilon = u32;

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

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

    fn eq_ulps_all(&self, other: &f32, max_diff: &u32) -> bool {
        self.re.eq_ulps_all(other, max_diff) && self.im.eq_ulps_all(&0.0, max_diff)
    }
}

impl FloatEqAllDebug<f32> for MyComplex32 {
    type DebugEpsilon = MyComplex32;
    type DebugUlpsEpsilon = MyComplex32Ulps;

    fn debug_abs_all_epsilon(
        &self,
        other: &f32,
        max_diff: &Self::Epsilon
    ) -> Self::DebugEpsilon {
        MyComplex32 {
            re: self.re.debug_abs_all_epsilon(other, max_diff),
            im: self.im.debug_abs_all_epsilon(&0.0, max_diff),
        }
    }

    fn debug_rel_all_epsilon(
        &self,
        other: &f32,
        max_diff: &Self::Epsilon
    ) -> Self::DebugEpsilon {
        MyComplex32 {
            re: self.re.debug_rel_all_epsilon(other, max_diff),
            im: self.im.debug_rel_all_epsilon(&0.0, max_diff),
        }
    }

    fn debug_ulps_all_epsilon(
        &self,
        other: &f32,
        max_diff: &Self::UlpsEpsilon,
    ) -> Self::DebugUlpsEpsilon {
        MyComplex32Ulps {
            re: self.re.debug_ulps_all_epsilon(other, max_diff),
            im: self.im.debug_ulps_all_epsilon(&0.0, max_diff),
        }
    }
}

let a = MyComplex32 { re: 1.0, im: 200.0 };
let b = 9000.0_f32;

assert_eq!(
    a.debug_abs_all_epsilon(&b, &0.2),
    MyComplex32 { re: 0.2, im: 0.2 }
);
assert_eq!(
    a.debug_rel_all_epsilon(&b, &0.2),
    MyComplex32 { re: 1800.0, im: 40.0 }
);
assert_eq!(
    a.debug_ulps_all_epsilon(&b, &8),
    MyComplex32Ulps { re: 8, im: 8 }
);

Associated Types

type DebugEpsilon: Debug

Displayed to the user when an assert fails, using fmt::Debug.

This should match the fields of the the most complex type in the comparison.

type DebugUlpsEpsilon: Debug

Displayed to the user when an assert fails, using fmt::Debug.

This should match the fields of the the ULPs diff type for the most complex type in the comparison.

Loading content...

Required methods

fn debug_abs_all_epsilon(
    &self,
    other: &Rhs,
    max_diff: &Self::Epsilon
) -> Self::DebugEpsilon

The epsilon used by an abs_all absolute epsilon comparison, displayed when an assert fails.

fn debug_rel_all_epsilon(
    &self,
    other: &Rhs,
    max_diff: &Self::Epsilon
) -> Self::DebugEpsilon

The epsilon used by a rel_all relative epsilon comparison, displayed when an assert fails.

This should take into account the fact that the epsilon values are scaled based on the size of their inputs.

fn debug_ulps_all_epsilon(
    &self,
    other: &Rhs,
    max_diff: &Self::UlpsEpsilon
) -> Self::DebugUlpsEpsilon

The epsilon used by an ulps_all ULPs comparison, displayed when an assert fails.

Loading content...

Implementations on Foreign Types

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 0]> for [T; 0][src]

type DebugEpsilon = [T::DebugEpsilon; 0]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 0]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 1]> for [T; 1][src]

type DebugEpsilon = [T::DebugEpsilon; 1]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 1]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 2]> for [T; 2][src]

type DebugEpsilon = [T::DebugEpsilon; 2]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 2]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 3]> for [T; 3][src]

type DebugEpsilon = [T::DebugEpsilon; 3]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 3]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 4]> for [T; 4][src]

type DebugEpsilon = [T::DebugEpsilon; 4]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 4]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 5]> for [T; 5][src]

type DebugEpsilon = [T::DebugEpsilon; 5]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 5]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 6]> for [T; 6][src]

type DebugEpsilon = [T::DebugEpsilon; 6]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 6]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 7]> for [T; 7][src]

type DebugEpsilon = [T::DebugEpsilon; 7]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 7]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 8]> for [T; 8][src]

type DebugEpsilon = [T::DebugEpsilon; 8]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 8]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 9]> for [T; 9][src]

type DebugEpsilon = [T::DebugEpsilon; 9]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 9]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 10]> for [T; 10][src]

type DebugEpsilon = [T::DebugEpsilon; 10]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 10]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 11]> for [T; 11][src]

type DebugEpsilon = [T::DebugEpsilon; 11]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 11]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 12]> for [T; 12][src]

type DebugEpsilon = [T::DebugEpsilon; 12]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 12]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 13]> for [T; 13][src]

type DebugEpsilon = [T::DebugEpsilon; 13]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 13]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 14]> for [T; 14][src]

type DebugEpsilon = [T::DebugEpsilon; 14]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 14]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 15]> for [T; 15][src]

type DebugEpsilon = [T::DebugEpsilon; 15]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 15]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 16]> for [T; 16][src]

type DebugEpsilon = [T::DebugEpsilon; 16]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 16]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 17]> for [T; 17][src]

type DebugEpsilon = [T::DebugEpsilon; 17]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 17]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 18]> for [T; 18][src]

type DebugEpsilon = [T::DebugEpsilon; 18]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 18]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 19]> for [T; 19][src]

type DebugEpsilon = [T::DebugEpsilon; 19]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 19]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 20]> for [T; 20][src]

type DebugEpsilon = [T::DebugEpsilon; 20]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 20]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 21]> for [T; 21][src]

type DebugEpsilon = [T::DebugEpsilon; 21]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 21]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 22]> for [T; 22][src]

type DebugEpsilon = [T::DebugEpsilon; 22]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 22]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 23]> for [T; 23][src]

type DebugEpsilon = [T::DebugEpsilon; 23]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 23]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 24]> for [T; 24][src]

type DebugEpsilon = [T::DebugEpsilon; 24]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 24]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 25]> for [T; 25][src]

type DebugEpsilon = [T::DebugEpsilon; 25]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 25]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 26]> for [T; 26][src]

type DebugEpsilon = [T::DebugEpsilon; 26]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 26]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 27]> for [T; 27][src]

type DebugEpsilon = [T::DebugEpsilon; 27]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 27]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 28]> for [T; 28][src]

type DebugEpsilon = [T::DebugEpsilon; 28]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 28]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 29]> for [T; 29][src]

type DebugEpsilon = [T::DebugEpsilon; 29]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 29]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 30]> for [T; 30][src]

type DebugEpsilon = [T::DebugEpsilon; 30]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 30]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 31]> for [T; 31][src]

type DebugEpsilon = [T::DebugEpsilon; 31]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 31]

impl<T: FloatEqAllDebug> FloatEqAllDebug<[T; 32]> for [T; 32][src]

type DebugEpsilon = [T::DebugEpsilon; 32]

type DebugUlpsEpsilon = [T::DebugUlpsEpsilon; 32]

impl FloatEqAllDebug<f32> for f32[src]

type DebugEpsilon = Self::Epsilon

type DebugUlpsEpsilon = Self::UlpsEpsilon

impl FloatEqAllDebug<f64> for f64[src]

type DebugEpsilon = Self::Epsilon

type DebugUlpsEpsilon = Self::UlpsEpsilon

impl<T> FloatEqAllDebug<Complex<T>> for Complex<T> where
    T: FloatEqAllDebug
[src]

type DebugEpsilon = Complex<T::DebugEpsilon>

type DebugUlpsEpsilon = ComplexUlps<T::DebugUlpsEpsilon>

Loading content...

Implementors

Loading content...