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 the resulting executable will run all the tests in the crate. A test
is considered successful if its function returns; if the task running is considered successful if its function returns; if the task running
the test fails, through a call to `fail!`, a failed `check` or the test fails, through a call to `fail!`, a failed `check` or
`assert`, or some other (`assert_eq`, `assert_approx_eq`, ...) means, `assert`, or some other (`assert_eq`, ...) means, then the test fails.
then the test fails.
When compiling a crate with the '--test' flag '--cfg test' is also When compiling a crate with the '--test' flag '--cfg test' is also
implied, so that tests can be conditionally compiled. 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 ToCStr
syn keyword rustTrait Char syn keyword rustTrait Char
syn keyword rustTrait Clone DeepClone 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 rustEnumVariant Less Equal Greater
syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
syn keyword rustTrait Default syn keyword rustTrait Default

View file

@ -268,7 +268,7 @@ mod test {
#[test] #[test]
fn test_arg() { fn test_arg() {
fn test(c: Complex64, arg: f64) { 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_0i, 0.0);
test(_1_1i, 0.25 * Real::pi()); test(_1_1i, 0.25 * Real::pi());

View file

@ -439,6 +439,14 @@ mod tests {
use std::io; use std::io;
use std::str; 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) { fn check(samples: &[f64], summ: &Summary) {
let summ2 = Summary::new(samples); let summ2 = Summary::new(samples);

View file

@ -72,13 +72,6 @@ totaleq_impl!(uint)
totaleq_impl!(char) 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)] #[deriving(Clone, Eq)]
pub enum Ordering { Less = -1, Equal = 0, Greater = 1 } pub enum Ordering { Less = -1, Equal = 0, Greater = 1 }

View file

@ -85,6 +85,7 @@ pub mod prelude;
/* Primitive types */ /* Primitive types */
#[path = "num/float_macros.rs"] mod float_macros;
#[path = "num/int_macros.rs"] mod int_macros; #[path = "num/int_macros.rs"] mod int_macros;
#[path = "num/uint_macros.rs"] mod uint_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) } 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))] #[cfg(not(test))]
impl Ord for f32 { impl Ord for f32 {
#[inline] #[inline]
@ -1195,15 +1179,6 @@ mod tests {
assert!(!NAN.is_negative()); 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] #[test]
fn test_primitive() { fn test_primitive() {
let none: Option<f32> = None; let none: Option<f32> = None;

View file

@ -189,22 +189,6 @@ impl Eq for f64 {
fn eq(&self, other: &f64) -> bool { (*self) == (*other) } 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))] #[cfg(not(test))]
impl Ord for f64 { impl Ord for f64 {
#[inline] #[inline]
@ -1246,15 +1230,6 @@ mod tests {
assert!(!NAN.is_negative()); 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] #[test]
fn test_primitive() { fn test_primitive() {
let none: Option<f64> = None; 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 // file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT. // http://rust-lang.org/COPYRIGHT.
// //
@ -8,7 +8,13 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// error-pattern:left: 1.0000001f64 does not approximately equal right: 1f64 with epsilon: 0.0000001f64 #[macro_escape];
pub fn main() { #[doc(hidden)];
assert_approx_eq!(1.0000001f64, 1.0f64, 1.0e-7);
} 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)]; #[allow(missing_doc)];
use clone::{Clone, DeepClone}; use clone::{Clone, DeepClone};
use cmp::{Eq, ApproxEq, Ord}; use cmp::{Eq, Ord};
use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::{Option, Some, None}; use option::{Option, Some, None};
@ -138,60 +138,19 @@ pub trait Integer: Num
/// A collection of rounding operations. /// A collection of rounding operations.
pub trait Round { pub trait Round {
/// Return the largest integer less than or equal to a number. /// 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; fn floor(&self) -> Self;
/// Return the smallest integer greater than or equal to a number. /// 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; fn ceil(&self) -> Self;
/// Return the nearest integer to a number. Round half-way cases away from /// Return the nearest integer to a number. Round half-way cases away from
/// `0.0`. /// `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; fn round(&self) -> Self;
/// Return the integer part of a number. /// 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; fn trunc(&self) -> Self;
/// Return the fractional part of a number. /// 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; fn fract(&self) -> Self;
} }
@ -262,18 +221,7 @@ pub trait Trigonometric {
fn atan(&self) -> Self; fn atan(&self) -> Self;
/// Computes the four quadrant arctangent of a number, `y`, and another /// Computes the four quadrant arctangent of a number, `y`, and another
/// number `x`. Return value is in radians in the range [-pi, pi]; /// 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);
/// ```
fn atan2(&self, other: &Self) -> Self; fn atan2(&self, other: &Self) -> Self;
/// Simultaneously computes the sine and cosine of the number, `x`. Returns /// Simultaneously computes the sine and cosine of the number, `x`. Returns
@ -505,8 +453,7 @@ pub enum FPCategory {
/// Primitive floating point numbers /// Primitive floating point numbers
pub trait Float: Real pub trait Float: Real
+ Signed + Signed
+ Primitive + Primitive {
+ ApproxEq<Self> {
// FIXME (#5527): These should be associated constants // FIXME (#5527): These should be associated constants
fn nan() -> Self; fn nan() -> Self;
fn infinity() -> Self; fn infinity() -> Self;

View file

@ -50,7 +50,7 @@ pub use bool::Bool;
pub use c_str::ToCStr; pub use c_str::ToCStr;
pub use char::Char; pub use char::Char;
pub use clone::{Clone, DeepClone}; 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 container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
pub use default::Default; pub use default::Default;
pub use from_str::FromStr; 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 /// A utility macro for indicating unreachable code. It will fail if
/// executed. This is occasionally useful to put after loops that never /// executed. This is occasionally useful to put after loops that never
/// terminate normally, but instead directly return from a function. /// 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; // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
static a2: uint = 3 + 3; // file at the top-level directory of this distribution and at
static b: f64 = 3.0 + 2.7; // 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; #[feature(macro_rules)];
static d: uint = 3 - 3;
static e: f64 = 3.0 - 2.7;
static e2: int = -3 * 3; macro_rules! assert_approx_eq(
static f: uint = 3 * 3; ($a:expr, $b:expr) => ({
static g: f64 = 3.3 * 3.3; 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 A: int = -4 + 3;
static i: uint = 3 / 3; static A2: uint = 3 + 3;
static j: f64 = 3.3 / 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 H: int = 3 / -1;
static q: uint = 1 & 3; static I: uint = 3 / 3;
static J: f64 = 3.3 / 3.3;
static r: int = 3 | 1; static N: bool = true && false;
static s: uint = 1 | 3;
static t: int = 3 ^ 1; static O: bool = true || false;
static u: uint = 1 ^ 3;
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 // NOTE: better shr coverage
static w: int = 1024 >> 4; static W: int = 1024 >> 4;
static x: uint = 1024 >> 4; static X: uint = 1024 >> 4;
static y: bool = 1 == 1; static Y: bool = 1 == 1;
static z: bool = 1.0 == 1.0; static Z: bool = 1.0 == 1.0;
static aa: bool = 1 <= 2; static AA: bool = 1 <= 2;
static ab: bool = -1 <= 2; static AB: bool = -1 <= 2;
static ac: bool = 1.0 <= 2.0; static AC: bool = 1.0 <= 2.0;
static ad: bool = 1 < 2; static AD: bool = 1 < 2;
static ae: bool = -1 < 2; static AE: bool = -1 < 2;
static af: bool = 1.0 < 2.0; static AF: bool = 1.0 < 2.0;
static ag: bool = 1 != 2; static AG: bool = 1 != 2;
static ah: bool = -1 != 2; static AH: bool = -1 != 2;
static ai: bool = 1.0 != 2.0; static AI: bool = 1.0 != 2.0;
static aj: bool = 2 >= 1; static AJ: bool = 2 >= 1;
static ak: bool = 2 >= -2; static AK: bool = 2 >= -2;
static al: bool = 1.0 >= -2.0; static AL: bool = 1.0 >= -2.0;
static am: bool = 2 > 1; static AM: bool = 2 > 1;
static an: bool = 2 > -2; static AN: bool = 2 > -2;
static ao: bool = 1.0 > -2.0; static AO: bool = 1.0 > -2.0;
pub fn main() { pub fn main() {
assert_eq!(a, -1); assert_eq!(A, -1);
assert_eq!(a2, 6); assert_eq!(A2, 6);
assert_approx_eq!(b, 5.7); assert_approx_eq!(B, 5.7);
assert_eq!(c, -1); assert_eq!(C, -1);
assert_eq!(d, 0); assert_eq!(D, 0);
assert_approx_eq!(e, 0.3); assert_approx_eq!(E, 0.3);
assert_eq!(e2, -9); assert_eq!(E2, -9);
assert_eq!(f, 9); assert_eq!(F, 9);
assert_approx_eq!(g, 10.89); assert_approx_eq!(G, 10.89);
assert_eq!(h, -3); assert_eq!(H, -3);
assert_eq!(i, 1); assert_eq!(I, 1);
assert_approx_eq!(j, 1.0); 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!(P, 1);
assert_eq!(q, 1); assert_eq!(Q, 1);
assert_eq!(r, 3); assert_eq!(R, 3);
assert_eq!(s, 3); assert_eq!(S, 3);
assert_eq!(t, 2); assert_eq!(T, 2);
assert_eq!(u, 2); assert_eq!(U, 2);
assert_eq!(v, 8); assert_eq!(V, 8);
assert_eq!(w, 64); assert_eq!(W, 64);
assert_eq!(x, 64); assert_eq!(X, 64);
assert_eq!(y, true); assert_eq!(Y, true);
assert_eq!(z, true); assert_eq!(Z, true);
assert_eq!(aa, true); assert_eq!(AA, true);
assert_eq!(ab, true); assert_eq!(AB, true);
assert_eq!(ac, true); assert_eq!(AC, true);
assert_eq!(ad, true); assert_eq!(AD, true);
assert_eq!(ae, true); assert_eq!(AE, true);
assert_eq!(af, true); assert_eq!(AF, true);
assert_eq!(ag, true); assert_eq!(AG, true);
assert_eq!(ah, true); assert_eq!(AH, true);
assert_eq!(ai, true); assert_eq!(AI, true);
assert_eq!(aj, true); assert_eq!(AJ, true);
assert_eq!(ak, true); assert_eq!(AK, true);
assert_eq!(al, true); assert_eq!(AL, true);
assert_eq!(am, true); assert_eq!(AM, true);
assert_eq!(an, true); assert_eq!(AN, true);
assert_eq!(ao, true); assert_eq!(AO, true);
} }

View file

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