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 | |
| 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')
| -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 | ||||
| -rw-r--r-- | src/libstd/cmp.rs | 102 | ||||
| -rw-r--r-- | src/libstd/std.rc | 1 | ||||
| -rw-r--r-- | src/test/run-pass/intrinsics-math.rs | 56 | ||||
| -rw-r--r-- | src/test/run-pass/trait-inheritance-num.rs | 3 | ||||
| -rw-r--r-- | src/test/run-pass/trait-inheritance-num2.rs | 3 |
11 files changed, 114 insertions, 140 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}; diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs deleted file mode 100644 index ea3793c1374..00000000000 --- a/src/libstd/cmp.rs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the -// COPYRIGHT file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Additional general-purpose comparison functionality. - -use core::f32; -use core::f64; -use core::float; - -pub static FUZZY_EPSILON: float = 1.0e-6; - -pub trait FuzzyEq<Eps> { - fn fuzzy_eq(&self, other: &Self) -> bool; - fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool; -} - -impl FuzzyEq<float> for float { - fn fuzzy_eq(&self, other: &float) -> bool { - self.fuzzy_eq_eps(other, &FUZZY_EPSILON) - } - - fn fuzzy_eq_eps(&self, other: &float, epsilon: &float) -> bool { - float::abs(*self - *other) < *epsilon - } -} - -impl FuzzyEq<f32> for f32 { - fn fuzzy_eq(&self, other: &f32) -> bool { - self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f32)) - } - - fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { - f32::abs(*self - *other) < *epsilon - } -} - -impl FuzzyEq<f64> for f64 { - fn fuzzy_eq(&self, other: &f64) -> bool { - self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f64)) - } - - fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { - f64::abs(*self - *other) < *epsilon - } -} - -#[test] -fn test_fuzzy_equals() { - assert!((&1.0f).fuzzy_eq(&1.0)); - assert!((&1.0f32).fuzzy_eq(&1.0f32)); - assert!((&1.0f64).fuzzy_eq(&1.0f64)); -} - -#[test] -fn test_fuzzy_eq_eps() { - assert!((&1.2f).fuzzy_eq_eps(&0.9, &0.5)); - assert!(!(&1.5f).fuzzy_eq_eps(&0.9, &0.5)); -} - -#[cfg(test)] -mod test_complex{ - use cmp::*; - - struct Complex { r: float, i: float } - - impl FuzzyEq<float> for Complex { - fn fuzzy_eq(&self, other: &Complex) -> bool { - self.fuzzy_eq_eps(other, &FUZZY_EPSILON) - } - - fn fuzzy_eq_eps(&self, other: &Complex, - epsilon: &float) -> bool { - self.r.fuzzy_eq_eps(&other.r, epsilon) && - self.i.fuzzy_eq_eps(&other.i, epsilon) - } - } - - #[test] - fn test_fuzzy_equals() { - let a = Complex {r: 0.9, i: 0.9}; - let b = Complex {r: 0.9, i: 0.9}; - - assert!((a.fuzzy_eq(&b))); - } - - #[test] - fn test_fuzzy_eq_eps() { - let other = Complex {r: 0.9, i: 0.9}; - - assert!((&Complex {r: 0.9, i: 1.2}).fuzzy_eq_eps(&other, &0.5)); - assert!((&Complex {r: 1.2, i: 0.9}).fuzzy_eq_eps(&other, &0.5)); - assert!(!(&Complex {r: 0.9, i: 1.5}).fuzzy_eq_eps(&other, &0.5)); - assert!(!(&Complex {r: 1.5, i: 0.9}).fuzzy_eq_eps(&other, &0.5)); - } -} diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 4f9de29e726..32c7c82a312 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -86,7 +86,6 @@ pub mod term; pub mod time; pub mod arena; pub mod par; -pub mod cmp; pub mod base64; pub mod rl; pub mod workcache; diff --git a/src/test/run-pass/intrinsics-math.rs b/src/test/run-pass/intrinsics-math.rs index 6f9179bc89d..c73df8209e8 100644 --- a/src/test/run-pass/intrinsics-math.rs +++ b/src/test/run-pass/intrinsics-math.rs @@ -10,10 +10,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern mod std; - -use std::cmp::FuzzyEq; - mod rusti { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { @@ -54,44 +50,44 @@ pub fn main() { unsafe { use rusti::*; - assert!((sqrtf32(64f32).fuzzy_eq(&8f32))); - assert!((sqrtf64(64f64).fuzzy_eq(&8f64))); + assert!((sqrtf32(64f32).approx_eq(&8f32))); + assert!((sqrtf64(64f64).approx_eq(&8f64))); - assert!((powif32(25f32, -2i32).fuzzy_eq(&0.0016f32))); - assert!((powif64(23.2f64, 2i32).fuzzy_eq(&538.24f64))); + assert!((powif32(25f32, -2i32).approx_eq(&0.0016f32))); + assert!((powif64(23.2f64, 2i32).approx_eq(&538.24f64))); - assert!((sinf32(0f32).fuzzy_eq(&0f32))); - assert!((sinf64(f64::consts::pi / 2f64).fuzzy_eq(&1f64))); + assert!((sinf32(0f32).approx_eq(&0f32))); + assert!((sinf64(f64::consts::pi / 2f64).approx_eq(&1f64))); - assert!((cosf32(0f32).fuzzy_eq(&1f32))); - assert!((cosf64(f64::consts::pi * 2f64).fuzzy_eq(&1f64))); + assert!((cosf32(0f32).approx_eq(&1f32))); + assert!((cosf64(f64::consts::pi * 2f64).approx_eq(&1f64))); - assert!((powf32(25f32, -2f32).fuzzy_eq(&0.0016f32))); - assert!((powf64(400f64, 0.5f64).fuzzy_eq(&20f64))); + assert!((powf32(25f32, -2f32).approx_eq(&0.0016f32))); + assert!((powf64(400f64, 0.5f64).approx_eq(&20f64))); - assert!((fabsf32(expf32(1f32) - f32::consts::e).fuzzy_eq(&0f32))); - assert!((expf64(1f64).fuzzy_eq(&f64::consts::e))); + assert!((fabsf32(expf32(1f32) - f32::consts::e).approx_eq(&0f32))); + assert!((expf64(1f64).approx_eq(&f64::consts::e))); - assert!((exp2f32(10f32).fuzzy_eq(&1024f32))); - assert!((exp2f64(50f64).fuzzy_eq(&1125899906842624f64))); + assert!((exp2f32(10f32).approx_eq(&1024f32))); + assert!((exp2f64(50f64).approx_eq(&1125899906842624f64))); - assert!((fabsf32(logf32(f32::consts::e) - 1f32).fuzzy_eq(&0f32))); - assert!((logf64(1f64).fuzzy_eq(&0f64))); + assert!((fabsf32(logf32(f32::consts::e) - 1f32).approx_eq(&0f32))); + assert!((logf64(1f64).approx_eq(&0f64))); - assert!((log10f32(10f32).fuzzy_eq(&1f32))); - assert!((log10f64(f64::consts::e).fuzzy_eq(&f64::consts::log10_e))); + assert!((log10f32(10f32).approx_eq(&1f32))); + assert!((log10f64(f64::consts::e).approx_eq(&f64::consts::log10_e))); - assert!((log2f32(8f32).fuzzy_eq(&3f32))); - assert!((log2f64(f64::consts::e).fuzzy_eq(&f64::consts::log2_e))); + assert!((log2f32(8f32).approx_eq(&3f32))); + assert!((log2f64(f64::consts::e).approx_eq(&f64::consts::log2_e))); - assert!((fmaf32(1.0f32, 2.0f32, 5.0f32).fuzzy_eq(&7.0f32))); - assert!((fmaf64(0.0f64, -2.0f64, f64::consts::e).fuzzy_eq(&f64::consts::e))); + assert!((fmaf32(1.0f32, 2.0f32, 5.0f32).approx_eq(&7.0f32))); + assert!((fmaf64(0.0f64, -2.0f64, f64::consts::e).approx_eq(&f64::consts::e))); - assert!((fabsf32(-1.0f32).fuzzy_eq(&1.0f32))); - assert!((fabsf64(34.2f64).fuzzy_eq(&34.2f64))); + assert!((fabsf32(-1.0f32).approx_eq(&1.0f32))); + assert!((fabsf64(34.2f64).approx_eq(&34.2f64))); - assert!((floorf32(3.8f32).fuzzy_eq(&3.0f32))); - assert!((floorf64(-1.1f64).fuzzy_eq(&-2.0f64))); + assert!((floorf32(3.8f32).approx_eq(&3.0f32))); + assert!((floorf64(-1.1f64).approx_eq(&-2.0f64))); // Causes linker error // undefined reference to llvm.ceil.f32/64 diff --git a/src/test/run-pass/trait-inheritance-num.rs b/src/test/run-pass/trait-inheritance-num.rs index 0fb2a6b2e72..5179d13813c 100644 --- a/src/test/run-pass/trait-inheritance-num.rs +++ b/src/test/run-pass/trait-inheritance-num.rs @@ -14,11 +14,10 @@ extern mod std; use core::cmp::{Eq, Ord}; use core::num::NumCast::from; -use std::cmp::FuzzyEq; pub trait NumExt: Num + NumCast + Eq + Ord {} -pub trait FloatExt: NumExt + FuzzyEq<Self> {} +pub trait FloatExt: NumExt + ApproxEq<Self> {} fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > from(1) } fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > from(1) } diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index b40f647814f..f7edd2855a4 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -16,7 +16,6 @@ extern mod std; use core::cmp::{Eq, Ord}; use core::num::NumCast::from; -use std::cmp::FuzzyEq; pub trait TypeExt {} @@ -94,7 +93,7 @@ impl IntegerExt for i64 {} impl IntegerExt for int {} -pub trait FloatExt: NumExt + FuzzyEq<Self> {} +pub trait FloatExt: NumExt + ApproxEq<Self> {} impl FloatExt for f32 {} impl FloatExt for f64 {} |
