Remove ApproxEq and assert_approx_eq!

This trait seems to stray too far from the mandate of a standard library as implementations may vary between use cases.
This commit is contained in:
Brendan Zabarauskas 2014-01-08 22:57:31 +11:00
parent 7613b15fdb
commit ceea85a148
18 changed files with 164 additions and 299 deletions

View File

@ -48,8 +48,7 @@ value. To run the tests in a crate, it must be compiled with the
the resulting executable will run all the tests in the crate. A test
is considered successful if its function returns; if the task running
the test fails, through a call to `fail!`, a failed `check` or
`assert`, or some other (`assert_eq`, `assert_approx_eq`, ...) means,
then the test fails.
`assert`, or some other (`assert_eq`, ...) means, then the test fails.
When compiling a crate with the '--test' flag '--cfg test' is also
implied, so that tests can be conditionally compiled.

View File

@ -71,7 +71,7 @@ syn keyword rustTrait Bool
syn keyword rustTrait ToCStr
syn keyword rustTrait Char
syn keyword rustTrait Clone DeepClone
syn keyword rustTrait Eq ApproxEq Ord TotalEq TotalOrd Ordering Equiv
syn keyword rustTrait Eq Ord TotalEq TotalOrd Ordering Equiv
syn keyword rustEnumVariant Less Equal Greater
syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
syn keyword rustTrait Default

View File

@ -268,7 +268,7 @@ mod test {
#[test]
fn test_arg() {
fn test(c: Complex64, arg: f64) {
assert!(c.arg().approx_eq(&arg))
assert!((c.arg() - arg).abs() < 1.0e-6)
}
test(_1_0i, 0.0);
test(_1_1i, 0.25 * Real::pi());

View File

@ -439,6 +439,14 @@ mod tests {
use std::io;
use std::str;
macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
)
fn check(samples: &[f64], summ: &Summary) {
let summ2 = Summary::new(samples);

View File

@ -72,13 +72,6 @@ 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 }

View File

@ -85,6 +85,7 @@ pub mod prelude;
/* Primitive types */
#[path = "num/float_macros.rs"] mod float_macros;
#[path = "num/int_macros.rs"] mod int_macros;
#[path = "num/uint_macros.rs"] mod uint_macros;

View File

@ -166,22 +166,6 @@ impl Eq for f32 {
fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
}
#[cfg(not(test))]
impl ApproxEq<f32> for f32 {
#[inline]
fn approx_epsilon() -> f32 { 1.0e-6 }
#[inline]
fn approx_eq(&self, other: &f32) -> bool {
self.approx_eq_eps(other, &1.0e-6)
}
#[inline]
fn approx_eq_eps(&self, other: &f32, approx_epsilon: &f32) -> bool {
(*self - *other).abs() < *approx_epsilon
}
}
#[cfg(not(test))]
impl Ord for f32 {
#[inline]
@ -1195,15 +1179,6 @@ mod tests {
assert!(!NAN.is_negative());
}
#[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() {
let none: Option<f32> = None;

View File

@ -189,22 +189,6 @@ impl Eq for f64 {
fn eq(&self, other: &f64) -> bool { (*self) == (*other) }
}
#[cfg(not(test))]
impl ApproxEq<f64> for f64 {
#[inline]
fn approx_epsilon() -> f64 { 1.0e-6 }
#[inline]
fn approx_eq(&self, other: &f64) -> bool {
self.approx_eq_eps(other, &1.0e-6)
}
#[inline]
fn approx_eq_eps(&self, other: &f64, approx_epsilon: &f64) -> bool {
(*self - *other).abs() < *approx_epsilon
}
}
#[cfg(not(test))]
impl Ord for f64 {
#[inline]
@ -1246,15 +1230,6 @@ mod tests {
assert!(!NAN.is_negative());
}
#[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() {
let none: Option<f64> = None;

View File

@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -8,7 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:left: 1.0000001f64 does not approximately equal right: 1f64 with epsilon: 0.0000001f64
pub fn main() {
assert_approx_eq!(1.0000001f64, 1.0f64, 1.0e-7);
}
#[macro_escape];
#[doc(hidden)];
macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
)

View File

@ -16,7 +16,7 @@
#[allow(missing_doc)];
use clone::{Clone, DeepClone};
use cmp::{Eq, ApproxEq, Ord};
use cmp::{Eq, Ord};
use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::{Option, Some, None};
@ -138,60 +138,19 @@ pub trait Integer: Num
/// A collection of rounding operations.
pub trait Round {
/// Return the largest integer less than or equal to a number.
///
/// # Example
///
/// ```rust
/// assert_approx_eq!(1.3f32.floor(), 1.0);
/// assert_approx_eq!((-1.3f32).floor(), -2.0);
/// ```
fn floor(&self) -> Self;
/// Return the smallest integer greater than or equal to a number.
///
/// # Example
///
/// ```rust
/// assert_approx_eq!(1.3f32.ceil(), 2.0);
/// assert_approx_eq!((-1.3f32).ceil(), -1.0);
/// ```
fn ceil(&self) -> Self;
/// Return the nearest integer to a number. Round half-way cases away from
/// `0.0`.
///
/// # Example
///
/// ```rust
/// assert_approx_eq!(1.3f32.round(), 1.0);
/// assert_approx_eq!((-1.3f32).round(), -1.0);
/// assert_approx_eq!(1.5f32.round(), 2.0);
/// assert_approx_eq!((-1.5f32).round(), -2.0);
/// ```
fn round(&self) -> Self;
/// Return the integer part of a number.
///
/// # Example
///
/// ```rust
/// assert_approx_eq!(1.3f32.trunc(), 1.0);
/// assert_approx_eq!((-1.3f32).trunc(), -1.0);
/// assert_approx_eq!(1.5f32.trunc(), 1.0);
/// assert_approx_eq!((-1.5f32).trunc(), -1.0);
/// ```
fn trunc(&self) -> Self;
/// Return the fractional part of a number.
///
/// # Example
///
/// ```rust
/// assert_approx_eq!(1.3f32.fract(), 0.3);
/// assert_approx_eq!((-1.3f32).fract(), -0.3);
/// assert_approx_eq!(1.5f32.fract(), 0.5);
/// assert_approx_eq!((-1.5f32).fract(), -0.5);
/// ```
fn fract(&self) -> Self;
}
@ -262,18 +221,7 @@ pub trait Trigonometric {
fn atan(&self) -> Self;
/// Computes the four quadrant arctangent of a number, `y`, and another
/// number `x`. Return value is in radians in the range [-pi, pi];
///
/// # Example
///
/// ```rust
/// use std::f32;
///
/// let y = 3f32.sqrt();
/// let x = 1f32;
/// assert_approx_eq!(y.atan2(&x), f32::consts::PI / 3f32);
/// assert_approx_eq!((-y).atan2(&(-x)), - 2f32 * f32::consts::PI / 3f32);
/// ```
/// number `x`. Return value is in radians in the range [-pi, pi].
fn atan2(&self, other: &Self) -> Self;
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
@ -505,8 +453,7 @@ pub enum FPCategory {
/// Primitive floating point numbers
pub trait Float: Real
+ Signed
+ Primitive
+ ApproxEq<Self> {
+ Primitive {
// FIXME (#5527): These should be associated constants
fn nan() -> Self;
fn infinity() -> Self;

View File

@ -50,7 +50,7 @@ pub use bool::Bool;
pub use c_str::ToCStr;
pub use char::Char;
pub use clone::{Clone, DeepClone};
pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
pub use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
pub use default::Default;
pub use from_str::FromStr;

View File

@ -741,43 +741,6 @@ pub fn std_macros() -> @str {
)
)
macro_rules! assert_approx_eq (
($given:expr , $expected:expr) => (
{
use std::cmp::ApproxEq;
let given_val = $given;
let expected_val = $expected;
// check both directions of equality....
if !(
given_val.approx_eq(&expected_val) &&
expected_val.approx_eq(&given_val)
) {
fail!("left: {:?} does not approximately equal right: {:?}",
given_val, expected_val);
}
}
);
($given:expr , $expected:expr , $epsilon:expr) => (
{
use std::cmp::ApproxEq;
let given_val = $given;
let expected_val = $expected;
let epsilon_val = $epsilon;
// check both directions of equality....
if !(
given_val.approx_eq_eps(&expected_val, &epsilon_val) &&
expected_val.approx_eq_eps(&given_val, &epsilon_val)
) {
fail!("left: {:?} does not approximately equal right: \
{:?} with epsilon: {:?}",
given_val, expected_val, epsilon_val);
}
}
)
)
/// A utility macro for indicating unreachable code. It will fail if
/// executed. This is occasionally useful to put after loops that never
/// terminate normally, but instead directly return from a function.

View File

@ -1,14 +0,0 @@
// Copyright 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.
// error-pattern:left: 1.00001f64 does not approximately equal right: 1f64
pub fn main() {
assert_approx_eq!(1.00001f64, 1.0);
}

View File

@ -1,16 +0,0 @@
// Copyright 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.
pub fn main() {
assert_approx_eq!(1.0f64, 1.0);
assert_approx_eq!(1.0000001f64, 1.0);
assert_approx_eq!(1.0000001f64, 1.0, 1.0e-6);
assert_approx_eq!(1.000001f64, 1.0, 1.0e-5);
}

View File

@ -1,116 +1,136 @@
static a: int = -4 + 3;
static a2: uint = 3 + 3;
static b: f64 = 3.0 + 2.7;
// Copyright 2014 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.
static c: int = 3 - 4;
static d: uint = 3 - 3;
static e: f64 = 3.0 - 2.7;
#[feature(macro_rules)];
static e2: int = -3 * 3;
static f: uint = 3 * 3;
static g: f64 = 3.3 * 3.3;
macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
)
static h: int = 3 / -1;
static i: uint = 3 / 3;
static j: f64 = 3.3 / 3.3;
static A: int = -4 + 3;
static A2: uint = 3 + 3;
static B: f64 = 3.0 + 2.7;
static n: bool = true && false;
static C: int = 3 - 4;
static D: uint = 3 - 3;
static E: f64 = 3.0 - 2.7;
static o: bool = true || false;
static E2: int = -3 * 3;
static F: uint = 3 * 3;
static G: f64 = 3.3 * 3.3;
static p: int = 3 & 1;
static q: uint = 1 & 3;
static H: int = 3 / -1;
static I: uint = 3 / 3;
static J: f64 = 3.3 / 3.3;
static r: int = 3 | 1;
static s: uint = 1 | 3;
static N: bool = true && false;
static t: int = 3 ^ 1;
static u: uint = 1 ^ 3;
static O: bool = true || false;
static v: int = 1 << 3;
static P: int = 3 & 1;
static Q: uint = 1 & 3;
static R: int = 3 | 1;
static S: uint = 1 | 3;
static T: int = 3 ^ 1;
static U: uint = 1 ^ 3;
static V: int = 1 << 3;
// NOTE: better shr coverage
static w: int = 1024 >> 4;
static x: uint = 1024 >> 4;
static W: int = 1024 >> 4;
static X: uint = 1024 >> 4;
static y: bool = 1 == 1;
static z: bool = 1.0 == 1.0;
static Y: bool = 1 == 1;
static Z: bool = 1.0 == 1.0;
static aa: bool = 1 <= 2;
static ab: bool = -1 <= 2;
static ac: bool = 1.0 <= 2.0;
static AA: bool = 1 <= 2;
static AB: bool = -1 <= 2;
static AC: bool = 1.0 <= 2.0;
static ad: bool = 1 < 2;
static ae: bool = -1 < 2;
static af: bool = 1.0 < 2.0;
static AD: bool = 1 < 2;
static AE: bool = -1 < 2;
static AF: bool = 1.0 < 2.0;
static ag: bool = 1 != 2;
static ah: bool = -1 != 2;
static ai: bool = 1.0 != 2.0;
static AG: bool = 1 != 2;
static AH: bool = -1 != 2;
static AI: bool = 1.0 != 2.0;
static aj: bool = 2 >= 1;
static ak: bool = 2 >= -2;
static al: bool = 1.0 >= -2.0;
static AJ: bool = 2 >= 1;
static AK: bool = 2 >= -2;
static AL: bool = 1.0 >= -2.0;
static am: bool = 2 > 1;
static an: bool = 2 > -2;
static ao: bool = 1.0 > -2.0;
static AM: bool = 2 > 1;
static AN: bool = 2 > -2;
static AO: bool = 1.0 > -2.0;
pub fn main() {
assert_eq!(a, -1);
assert_eq!(a2, 6);
assert_approx_eq!(b, 5.7);
assert_eq!(A, -1);
assert_eq!(A2, 6);
assert_approx_eq!(B, 5.7);
assert_eq!(c, -1);
assert_eq!(d, 0);
assert_approx_eq!(e, 0.3);
assert_eq!(C, -1);
assert_eq!(D, 0);
assert_approx_eq!(E, 0.3);
assert_eq!(e2, -9);
assert_eq!(f, 9);
assert_approx_eq!(g, 10.89);
assert_eq!(E2, -9);
assert_eq!(F, 9);
assert_approx_eq!(G, 10.89);
assert_eq!(h, -3);
assert_eq!(i, 1);
assert_approx_eq!(j, 1.0);
assert_eq!(H, -3);
assert_eq!(I, 1);
assert_approx_eq!(J, 1.0);
assert_eq!(n, false);
assert_eq!(N, false);
assert_eq!(o, true);
assert_eq!(O, true);
assert_eq!(p, 1);
assert_eq!(q, 1);
assert_eq!(P, 1);
assert_eq!(Q, 1);
assert_eq!(r, 3);
assert_eq!(s, 3);
assert_eq!(R, 3);
assert_eq!(S, 3);
assert_eq!(t, 2);
assert_eq!(u, 2);
assert_eq!(T, 2);
assert_eq!(U, 2);
assert_eq!(v, 8);
assert_eq!(V, 8);
assert_eq!(w, 64);
assert_eq!(x, 64);
assert_eq!(W, 64);
assert_eq!(X, 64);
assert_eq!(y, true);
assert_eq!(z, true);
assert_eq!(Y, true);
assert_eq!(Z, true);
assert_eq!(aa, true);
assert_eq!(ab, true);
assert_eq!(ac, true);
assert_eq!(AA, true);
assert_eq!(AB, true);
assert_eq!(AC, true);
assert_eq!(ad, true);
assert_eq!(ae, true);
assert_eq!(af, true);
assert_eq!(AD, true);
assert_eq!(AE, true);
assert_eq!(AF, true);
assert_eq!(ag, true);
assert_eq!(ah, true);
assert_eq!(ai, true);
assert_eq!(AG, true);
assert_eq!(AH, true);
assert_eq!(AI, true);
assert_eq!(aj, true);
assert_eq!(ak, true);
assert_eq!(al, true);
assert_eq!(AJ, true);
assert_eq!(AK, true);
assert_eq!(AL, true);
assert_eq!(am, true);
assert_eq!(an, true);
assert_eq!(ao, true);
assert_eq!(AM, true);
assert_eq!(AN, true);
assert_eq!(AO, true);
}

View File

@ -10,7 +10,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(globs)];
#[feature(globs, macro_rules)];
macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
)
mod rusti {
extern "rust-intrinsic" {
@ -54,44 +62,44 @@ pub fn main() {
use std::f32;
use std::f64;
assert!((sqrtf32(64f32).approx_eq(&8f32)));
assert!((sqrtf64(64f64).approx_eq(&8f64)));
assert_approx_eq!(sqrtf32(64f32), 8f32);
assert_approx_eq!(sqrtf64(64f64), 8f64);
assert!((powif32(25f32, -2i32).approx_eq(&0.0016f32)));
assert!((powif64(23.2f64, 2i32).approx_eq(&538.24f64)));
assert_approx_eq!(powif32(25f32, -2i32), 0.0016f32);
assert_approx_eq!(powif64(23.2f64, 2i32), 538.24f64);
assert!((sinf32(0f32).approx_eq(&0f32)));
assert!((sinf64(f64::consts::PI / 2f64).approx_eq(&1f64)));
assert_approx_eq!(sinf32(0f32), 0f32);
assert_approx_eq!(sinf64(f64::consts::PI / 2f64), 1f64);
assert!((cosf32(0f32).approx_eq(&1f32)));
assert!((cosf64(f64::consts::PI * 2f64).approx_eq(&1f64)));
assert_approx_eq!(cosf32(0f32), 1f32);
assert_approx_eq!(cosf64(f64::consts::PI * 2f64), 1f64);
assert!((powf32(25f32, -2f32).approx_eq(&0.0016f32)));
assert!((powf64(400f64, 0.5f64).approx_eq(&20f64)));
assert_approx_eq!(powf32(25f32, -2f32), 0.0016f32);
assert_approx_eq!(powf64(400f64, 0.5f64), 20f64);
assert!((fabsf32(expf32(1f32) - f32::consts::E).approx_eq(&0f32)));
assert!((expf64(1f64).approx_eq(&f64::consts::E)));
assert_approx_eq!(fabsf32(expf32(1f32) - f32::consts::E), 0f32);
assert_approx_eq!(expf64(1f64), f64::consts::E);
assert!((exp2f32(10f32).approx_eq(&1024f32)));
assert!((exp2f64(50f64).approx_eq(&1125899906842624f64)));
assert_approx_eq!(exp2f32(10f32), 1024f32);
assert_approx_eq!(exp2f64(50f64), 1125899906842624f64);
assert!((fabsf32(logf32(f32::consts::E) - 1f32).approx_eq(&0f32)));
assert!((logf64(1f64).approx_eq(&0f64)));
assert_approx_eq!(fabsf32(logf32(f32::consts::E) - 1f32), 0f32);
assert_approx_eq!(logf64(1f64), 0f64);
assert!((log10f32(10f32).approx_eq(&1f32)));
assert!((log10f64(f64::consts::E).approx_eq(&f64::consts::LOG10_E)));
assert_approx_eq!(log10f32(10f32), 1f32);
assert_approx_eq!(log10f64(f64::consts::E), f64::consts::LOG10_E);
assert!((log2f32(8f32).approx_eq(&3f32)));
assert!((log2f64(f64::consts::E).approx_eq(&f64::consts::LOG2_E)));
assert_approx_eq!(log2f32(8f32), 3f32);
assert_approx_eq!(log2f64(f64::consts::E), f64::consts::LOG2_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_approx_eq!(fmaf32(1.0f32, 2.0f32, 5.0f32), 7.0f32);
assert_approx_eq!(fmaf64(0.0f64, -2.0f64, f64::consts::E), f64::consts::E);
assert!((fabsf32(-1.0f32).approx_eq(&1.0f32)));
assert!((fabsf64(34.2f64).approx_eq(&34.2f64)));
assert_approx_eq!(fabsf32(-1.0f32), 1.0f32);
assert_approx_eq!(fabsf64(34.2f64), 34.2f64);
assert!((floorf32(3.8f32).approx_eq(&3.0f32)));
assert!((floorf64(-1.1f64).approx_eq(&-2.0f64)));
assert_approx_eq!(floorf32(3.8f32), 3.0f32);
assert_approx_eq!(floorf64(-1.1f64), -2.0f64);
// Causes linker error
// undefined reference to llvm.ceil.f32/64

View File

@ -17,7 +17,7 @@ use std::num::NumCast;
pub trait NumExt: Num + NumCast + Eq + Ord {}
pub trait FloatExt: NumExt + ApproxEq<Self> {}
pub trait FloatExt: NumExt {}
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > NumCast::from(1).unwrap() }
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > NumCast::from(1).unwrap() }

View File

@ -89,7 +89,7 @@ impl IntegerExt for i64 {}
impl IntegerExt for int {}
pub trait FloatExt: NumExt + ApproxEq<Self> {}
pub trait FloatExt: NumExt {}
impl FloatExt for f32 {}
impl FloatExt for f64 {}