Crate approx [−] [src]
A crate that provides traits and macros for testing the approximate equality of floating-point types, using either relative difference, or units in the last place (ULPs) comparisons.
#[macro_use] extern crate approx; use std::f64; relative_eq!(1.0, 1.0); relative_eq!(1.0, 1.0, epsilon = f64::EPSILON); relative_eq!(1.0, 1.0, max_relative = 1.0); relative_eq!(1.0, 1.0, epsilon = f64::EPSILON, max_relative = 1.0); relative_eq!(1.0, 1.0, max_relative = 1.0, epsilon = f64::EPSILON);
#[macro_use] extern crate approx; use std::f64; ulps_eq!(1.0, 1.0); ulps_eq!(1.0, 1.0, epsilon = f64::EPSILON); ulps_eq!(1.0, 1.0, max_ulps = 4); ulps_eq!(1.0, 1.0, epsilon = f64::EPSILON, max_ulps = 4); ulps_eq!(1.0, 1.0, max_ulps = 4, epsilon = f64::EPSILON);
Implementing approximate equality for custom types
The ApproxEq
trait allows approximate equalities to be implemented on types, based on the
fundamental floating point implementations.
For example, we might want to be able to do approximate assertions on a complex number type:
#[derive(Debug)] struct Complex<T> { x: T, i: T, } let x = Complex { x: 1.2, i: 2.3 }; assert_relative_eq!(x, x); assert_ulps_eq!(x, x, max_ulps = 4);
To do this we can implement ApproxEq
generically in terms of a type parameter that also
implements ApproxEq
. This means that we can make comparisons for either Complex<f32>
or
Complex<f64>
:
impl<T: ApproxEq> ApproxEq for Complex<T> { type Epsilon = T::Epsilon; fn default_epsilon() -> T::Epsilon { T::default_epsilon() } fn default_max_relative() -> T::Epsilon { T::default_max_relative() } fn default_max_ulps() -> u32 { T::default_max_ulps() } fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool { T::relative_eq(&self.x, &other.x, epsilon, max_relative) && T::relative_eq(&self.i, &other.i, epsilon, max_relative) } fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool { T::ulps_eq(&self.x, &other.x, epsilon, max_ulps) && T::ulps_eq(&self.i, &other.i, epsilon, max_ulps) } }
References
Floating point is HARD! Thanks goes to these links for helping to make things a little easier to understand:
Modules
macro_support |
Functions that support the various forms of the |
Macros
assert_relative_eq! | |
assert_relative_ne! | |
assert_ulps_eq! | |
assert_ulps_ne! | |
relative_eq! | |
relative_ne! | |
ulps_eq! | |
ulps_ne! |
Traits
ApproxEq |
Equality comparisons based on floating point tolerances. |