diff options
| author | Brendan Zabarauskas <bjzaba@yahoo.com.au> | 2013-05-06 16:10:26 +1000 |
|---|---|---|
| committer | Brendan Zabarauskas <bjzaba@yahoo.com.au> | 2013-05-06 21:51:07 +1000 |
| commit | 02118330084539fdc87533d46aabeef2257ee835 (patch) | |
| tree | eb518dc22f21ed58165b43acada47e6d8fca7955 /src/libcore | |
| parent | 6e6a4be19d8e6a2cedc66be6cc602db8a1e71acd (diff) | |
| download | rust-02118330084539fdc87533d46aabeef2257ee835.tar.gz rust-02118330084539fdc87533d46aabeef2257ee835.zip | |
Move FuzzyEq trait into core::cmp and rename it to 'ApproxEq'
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/cmp.rs | 7 | ||||
| -rw-r--r-- | src/libcore/num/f32.rs | 25 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 25 | ||||
| -rw-r--r-- | src/libcore/num/float.rs | 25 | ||||
| -rw-r--r-- | src/libcore/num/num.rs | 5 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 2 |
6 files changed, 86 insertions, 3 deletions
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index b933b60a39f..80f1f05961a 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -66,6 +66,13 @@ totaleq_impl!(uint) totaleq_impl!(char) +/// Trait for testing approximate equality +pub trait ApproxEq<Eps> { + fn approx_epsilon() -> Eps; + fn approx_eq(&self, other: &Self) -> bool; + fn approx_eq_eps(&self, other: &Self, approx_epsilon: &Eps) -> bool; +} + #[deriving(Clone, Eq)] pub enum Ordering { Less = -1, Equal = 0, Greater = 1 } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 416ec2069b5..feeb2c3f836 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -211,6 +211,22 @@ impl Eq for f32 { } #[cfg(notest)] +impl ApproxEq<f32> for f32 { + #[inline(always)] + fn approx_epsilon() -> f32 { 1.0e-6 } + + #[inline(always)] + fn approx_eq(&self, other: &f32) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f32, f32>()) + } + + #[inline(always)] + fn approx_eq_eps(&self, other: &f32, approx_epsilon: &f32) -> bool { + (*self - *other).abs() < *approx_epsilon + } +} + +#[cfg(notest)] impl Ord for f32 { #[inline(always)] fn lt(&self, other: &f32) -> bool { (*self) < (*other) } @@ -975,6 +991,15 @@ mod tests { } #[test] + fn test_approx_eq() { + assert!(1.0f32.approx_eq(&1f32)); + assert!(0.9999999f32.approx_eq(&1f32)); + assert!(1.000001f32.approx_eq_eps(&1f32, &1.0e-5)); + assert!(1.0000001f32.approx_eq_eps(&1f32, &1.0e-6)); + assert!(!1.0000001f32.approx_eq_eps(&1f32, &1.0e-7)); + } + + #[test] fn test_primitive() { assert_eq!(Primitive::bits::<f32>(), sys::size_of::<f32>() * 8); assert_eq!(Primitive::bytes::<f32>(), sys::size_of::<f32>()); diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 6e09ca61a7d..08f9c341188 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -234,6 +234,22 @@ impl Eq for f64 { } #[cfg(notest)] +impl ApproxEq<f64> for f64 { + #[inline(always)] + fn approx_epsilon() -> f64 { 1.0e-6 } + + #[inline(always)] + fn approx_eq(&self, other: &f64) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f64, f64>()) + } + + #[inline(always)] + fn approx_eq_eps(&self, other: &f64, approx_epsilon: &f64) -> bool { + (*self - *other).abs() < *approx_epsilon + } +} + +#[cfg(notest)] impl Ord for f64 { #[inline(always)] fn lt(&self, other: &f64) -> bool { (*self) < (*other) } @@ -1023,6 +1039,15 @@ mod tests { } #[test] + fn test_approx_eq() { + assert!(1.0f64.approx_eq(&1f64)); + assert!(0.9999999f64.approx_eq(&1f64)); + assert!(1.000001f64.approx_eq_eps(&1f64, &1.0e-5)); + assert!(1.0000001f64.approx_eq_eps(&1f64, &1.0e-6)); + assert!(!1.0000001f64.approx_eq_eps(&1f64, &1.0e-7)); + } + + #[test] fn test_primitive() { assert_eq!(Primitive::bits::<f64>(), sys::size_of::<f64>() * 8); assert_eq!(Primitive::bytes::<f64>(), sys::size_of::<f64>()); diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index da9d03f6a7b..61dd741b671 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -372,6 +372,22 @@ impl Eq for float { } #[cfg(notest)] +impl ApproxEq<float> for float { + #[inline(always)] + fn approx_epsilon() -> float { 1.0e-6 } + + #[inline(always)] + fn approx_eq(&self, other: &float) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<float, float>()) + } + + #[inline(always)] + fn approx_eq_eps(&self, other: &float, approx_epsilon: &float) -> bool { + (*self - *other).abs() < *approx_epsilon + } +} + +#[cfg(notest)] impl Ord for float { #[inline(always)] fn lt(&self, other: &float) -> bool { (*self) < (*other) } @@ -986,6 +1002,15 @@ mod tests { } #[test] + fn test_approx_eq() { + assert!(1.0f.approx_eq(&1f)); + assert!(0.9999999f.approx_eq(&1f)); + assert!(1.000001f.approx_eq_eps(&1f, &1.0e-5)); + assert!(1.0000001f.approx_eq_eps(&1f, &1.0e-6)); + assert!(!1.0000001f.approx_eq_eps(&1f, &1.0e-7)); + } + + #[test] fn test_primitive() { assert_eq!(Primitive::bits::<float>(), sys::size_of::<float>() * 8); assert_eq!(Primitive::bytes::<float>(), sys::size_of::<float>()); diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 1a59a069df7..caa14ea802f 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -9,7 +9,7 @@ // except according to those terms. //! An interface for numeric types -use cmp::{Eq, Ord}; +use cmp::{Eq, ApproxEq, Ord}; use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use option::Option; @@ -240,7 +240,8 @@ pub trait Int: Integer /// pub trait Float: Real + Signed - + Primitive { + + Primitive + + ApproxEq<Self> { // FIXME (#5527): These should be associated constants fn NaN() -> Self; fn infinity() -> Self; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 42401ae5a1f..10b36d38d43 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -28,7 +28,7 @@ pub use io::{print, println}; /* Reexported types and traits */ pub use clone::Clone; -pub use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv}; +pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv}; pub use container::{Container, Mutable, Map, Set}; pub use hash::Hash; pub use old_iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter}; |
