auto merge of #6048 : bjz/rust/numeric-traits, r=pcwalton
As part of the numeric trait reform (see issue #4819), I have added the following traits to `core::num` and implemented them for floating point types: ~~~rust pub trait Round { fn floor(&self) -> Self; fn ceil(&self) -> Self; fn round(&self) -> Self; fn trunc(&self) -> Self; fn fract(&self) -> Self; } pub trait Fractional: Num + Ord + Round + Quot<Self,Self> { fn recip(&self) -> Self; } pub trait Real: Signed + Fractional { // Common Constants fn pi() -> Self; fn two_pi() -> Self; fn frac_pi_2() -> Self; fn frac_pi_3() -> Self; fn frac_pi_4() -> Self; fn frac_pi_6() -> Self; fn frac_pi_8() -> Self; fn frac_1_pi() -> Self; fn frac_2_pi() -> Self; fn frac_2_sqrtpi() -> Self; fn sqrt2() -> Self; fn frac_1_sqrt2() -> Self; fn e() -> Self; fn log2_e() -> Self; fn log10_e() -> Self; fn log_2() -> Self; fn log_10() -> Self; // Exponential functions fn pow(&self, n: Self) -> Self; fn exp(&self) -> Self; fn exp2(&self) -> Self; fn expm1(&self) -> Self; fn ldexp(&self, n: int) -> Self; fn log(&self) -> Self; fn log2(&self) -> Self; fn log10(&self) -> Self; fn log_radix(&self) -> Self; fn ilog_radix(&self) -> int; fn sqrt(&self) -> Self; fn rsqrt(&self) -> Self; fn cbrt(&self) -> Self; // Angular conversions fn to_degrees(&self) -> Self; fn to_radians(&self) -> Self; // Triganomic functions fn hypot(&self, other: Self) -> Self; fn sin(&self) -> Self; fn cos(&self) -> Self; fn tan(&self) -> Self; // Inverse triganomic functions fn asin(&self) -> Self; fn acos(&self) -> Self; fn atan(&self) -> Self; fn atan2(&self, other: Self) -> Self; // Hyperbolic triganomic functions fn sinh(&self) -> Self; fn cosh(&self) -> Self; fn tanh(&self) -> Self; } /// Methods that are harder to implement and not commonly used. pub trait RealExt: Real { // Gamma functions fn lgamma(&self) -> (int, Self); fn tgamma(&self) -> Self; // Bessel functions fn j0(&self) -> Self; fn j1(&self) -> Self; fn jn(&self, n: int) -> Self; fn y0(&self) -> Self; fn y1(&self) -> Self; fn yn(&self, n: int) -> Self; } ~~~ The constants in `Real` could be [associated items](http://smallcultfollowing.com/babysteps/blog/2013/04/03/associated-items-continued/) in the future (see issue #5527). At the moment I have left the constants in `{float|f32|f64}::consts` in case folks need to access these at compile time. There are also instances of `int` in `Real` and `RealExt`. In the future these could be replaced with an associated `INTEGER` type on `Real`. `Natural` has also been renamed to `Integer`. This is because `Natural` normally means 'positive integer' in mathematics. It is therefore strange to implement it on signed integer types. `Integer` is probably a better choice. I have also switched some of the `Integer` methods to take borrowed pointers as arguments. This brings them in line with the `Quot` and `Rem` traits, and is be better for large Integer types like `BigInt` and `BigUint` because they don't need to be copied unnecessarily. There has also been considerable discussion on the mailing list and IRC about the renaming of the `Div` and `Modulo` traits to `Quot` and `Rem`. Depending on the outcome of these discussions they might be renamed again.
This commit is contained in:
commit
ac69ee418b
12 changed files with 1146 additions and 317 deletions
|
|
@ -77,9 +77,7 @@ pub use kinds::{Const, Copy, Owned, Durable};
|
|||
pub use ops::{Drop};
|
||||
#[cfg(stage0)]
|
||||
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
pub use ops::{Add, Sub, Mul, Quot, Rem, Neg, Not};
|
||||
pub use ops::{BitAnd, BitOr, BitXor};
|
||||
pub use ops::{Shl, Shr, Index};
|
||||
|
|
@ -105,7 +103,9 @@ pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
|||
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
|
||||
pub use iter::{ExtendedMutableIter};
|
||||
|
||||
pub use num::{Num, Signed, Unsigned, Natural, NumCast};
|
||||
pub use num::{Num, NumCast};
|
||||
pub use num::{Signed, Unsigned, Integer};
|
||||
pub use num::{Round, Fractional, Real, RealExt};
|
||||
pub use ptr::Ptr;
|
||||
pub use to_str::ToStr;
|
||||
pub use clone::Clone;
|
||||
|
|
|
|||
|
|
@ -10,20 +10,10 @@
|
|||
|
||||
//! Operations and constants for `f32`
|
||||
|
||||
use num::strconv;
|
||||
use num::Signed;
|
||||
use num;
|
||||
use option::Option;
|
||||
use from_str;
|
||||
use to_str;
|
||||
|
||||
#[cfg(notest)] use cmp::{Eq, Ord};
|
||||
#[cfg(stage0,notest)]
|
||||
use ops::{Add, Sub, Mul, Div, Modulo, Neg};
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
use ops::{Add, Sub, Mul, Quot, Rem, Neg};
|
||||
use libc::c_int;
|
||||
use num::strconv;
|
||||
use prelude::*;
|
||||
|
||||
pub use cmath::c_float_targ_consts::*;
|
||||
|
||||
|
|
@ -233,6 +223,8 @@ pub fn logarithm(n: f32, b: f32) -> f32 {
|
|||
return log2(n) / log2(b);
|
||||
}
|
||||
|
||||
impl Num for f32 {}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl Eq for f32 {
|
||||
#[inline(always)]
|
||||
|
|
@ -286,10 +278,7 @@ impl Div<f32,f32> for f32 {
|
|||
#[inline(always)]
|
||||
fn div(&self, other: &f32) -> f32 { *self / *other }
|
||||
}
|
||||
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Quot<f32,f32> for f32 {
|
||||
#[inline(always)]
|
||||
fn quot(&self, other: &f32) -> f32 { *self / *other }
|
||||
|
|
@ -300,10 +289,7 @@ impl Modulo<f32,f32> for f32 {
|
|||
#[inline(always)]
|
||||
fn modulo(&self, other: &f32) -> f32 { *self % *other }
|
||||
}
|
||||
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Rem<f32,f32> for f32 {
|
||||
#[inline(always)]
|
||||
fn rem(&self, other: &f32) -> f32 { *self % *other }
|
||||
|
|
@ -341,31 +327,188 @@ impl Signed for f32 {
|
|||
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
|
||||
}
|
||||
|
||||
impl num::Round for f32 {
|
||||
#[inline(always)]
|
||||
fn round(&self, mode: num::RoundMode) -> f32 {
|
||||
match mode {
|
||||
num::RoundDown => floor(*self),
|
||||
num::RoundUp => ceil(*self),
|
||||
num::RoundToZero if self.is_negative() => ceil(*self),
|
||||
num::RoundToZero => floor(*self),
|
||||
num::RoundFromZero if self.is_negative() => floor(*self),
|
||||
num::RoundFromZero => ceil(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Round for f32 {
|
||||
/// Round half-way cases toward `neg_infinity`
|
||||
#[inline(always)]
|
||||
fn floor(&self) -> f32 { floor(*self) }
|
||||
|
||||
/// Round half-way cases toward `infinity`
|
||||
#[inline(always)]
|
||||
fn ceil(&self) -> f32 { ceil(*self) }
|
||||
|
||||
/// Round half-way cases away from `0.0`
|
||||
#[inline(always)]
|
||||
fn fract(&self) -> f32 {
|
||||
if self.is_negative() {
|
||||
(*self) - ceil(*self)
|
||||
} else {
|
||||
(*self) - floor(*self)
|
||||
}
|
||||
}
|
||||
fn round(&self) -> f32 { round(*self) }
|
||||
|
||||
/// The integer part of the number (rounds towards `0.0`)
|
||||
#[inline(always)]
|
||||
fn trunc(&self) -> f32 { trunc(*self) }
|
||||
|
||||
///
|
||||
/// The fractional part of the number, satisfying:
|
||||
///
|
||||
/// ~~~
|
||||
/// assert!(x == trunc(x) + fract(x))
|
||||
/// ~~~
|
||||
///
|
||||
#[inline(always)]
|
||||
fn fract(&self) -> f32 { *self - self.trunc() }
|
||||
}
|
||||
|
||||
impl Fractional for f32 {
|
||||
/// The reciprocal (multiplicative inverse) of the number
|
||||
#[inline(always)]
|
||||
fn recip(&self) -> f32 { 1.0 / *self }
|
||||
}
|
||||
|
||||
impl Real for f32 {
|
||||
/// Archimedes' constant
|
||||
#[inline(always)]
|
||||
fn pi() -> f32 { 3.14159265358979323846264338327950288 }
|
||||
|
||||
/// 2.0 * pi
|
||||
#[inline(always)]
|
||||
fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
|
||||
|
||||
/// pi / 2.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
|
||||
|
||||
/// pi / 3.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
|
||||
|
||||
/// pi / 4.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
|
||||
|
||||
/// pi / 6.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
|
||||
|
||||
/// pi / 8.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
|
||||
|
||||
/// 1 .0/ pi
|
||||
#[inline(always)]
|
||||
fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
|
||||
|
||||
/// 2.0 / pi
|
||||
#[inline(always)]
|
||||
fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
|
||||
|
||||
/// 2.0 / sqrt(pi)
|
||||
#[inline(always)]
|
||||
fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
|
||||
|
||||
/// sqrt(2.0)
|
||||
#[inline(always)]
|
||||
fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
|
||||
|
||||
/// 1.0 / sqrt(2.0)
|
||||
#[inline(always)]
|
||||
fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
|
||||
|
||||
/// Euler's number
|
||||
#[inline(always)]
|
||||
fn e() -> f32 { 2.71828182845904523536028747135266250 }
|
||||
|
||||
/// log2(e)
|
||||
#[inline(always)]
|
||||
fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
|
||||
|
||||
/// log10(e)
|
||||
#[inline(always)]
|
||||
fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
|
||||
|
||||
/// log(2.0)
|
||||
#[inline(always)]
|
||||
fn log_2() -> f32 { 0.693147180559945309417232121458176568 }
|
||||
|
||||
/// log(10.0)
|
||||
#[inline(always)]
|
||||
fn log_10() -> f32 { 2.30258509299404568401799145468436421 }
|
||||
|
||||
#[inline(always)]
|
||||
fn pow(&self, n: f32) -> f32 { pow(*self, n) }
|
||||
|
||||
#[inline(always)]
|
||||
fn exp(&self) -> f32 { exp(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn exp2(&self) -> f32 { exp2(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn expm1(&self) -> f32 { expm1(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn ldexp(&self, n: int) -> f32 { ldexp(*self, n as c_int) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log(&self) -> f32 { ln(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log2(&self) -> f32 { log2(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log10(&self) -> f32 { log10(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log_radix(&self) -> f32 { log_radix(*self) as f32 }
|
||||
|
||||
#[inline(always)]
|
||||
fn ilog_radix(&self) -> int { ilog_radix(*self) as int }
|
||||
|
||||
#[inline(always)]
|
||||
fn sqrt(&self) -> f32 { sqrt(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn rsqrt(&self) -> f32 { self.sqrt().recip() }
|
||||
|
||||
#[inline(always)]
|
||||
fn cbrt(&self) -> f32 { cbrt(*self) }
|
||||
|
||||
/// Converts to degrees, assuming the number is in radians
|
||||
#[inline(always)]
|
||||
fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees
|
||||
#[inline(always)]
|
||||
fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
|
||||
|
||||
#[inline(always)]
|
||||
fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
|
||||
|
||||
#[inline(always)]
|
||||
fn sin(&self) -> f32 { sin(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn cos(&self) -> f32 { cos(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn tan(&self) -> f32 { tan(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn asin(&self) -> f32 { asin(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn acos(&self) -> f32 { acos(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn atan(&self) -> f32 { atan(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
|
||||
|
||||
#[inline(always)]
|
||||
fn sinh(&self) -> f32 { sinh(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn cosh(&self) -> f32 { cosh(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn tanh(&self) -> f32 { tanh(*self) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -588,6 +731,111 @@ impl num::FromStrRadix for f32 {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use f32::*;
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
|
||||
macro_rules! assert_fuzzy_eq(
|
||||
($a:expr, $b:expr) => ({
|
||||
let a = $a, b = $b;
|
||||
if !((a - b).abs() < 1.0e-6) {
|
||||
fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10f32, 2f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_floor() {
|
||||
assert_fuzzy_eq!(1.0f32.floor(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.3f32.floor(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.5f32.floor(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.7f32.floor(), 1.0f32);
|
||||
assert_fuzzy_eq!(0.0f32.floor(), 0.0f32);
|
||||
assert_fuzzy_eq!((-0.0f32).floor(), -0.0f32);
|
||||
assert_fuzzy_eq!((-1.0f32).floor(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.3f32).floor(), -2.0f32);
|
||||
assert_fuzzy_eq!((-1.5f32).floor(), -2.0f32);
|
||||
assert_fuzzy_eq!((-1.7f32).floor(), -2.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ceil() {
|
||||
assert_fuzzy_eq!(1.0f32.ceil(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.3f32.ceil(), 2.0f32);
|
||||
assert_fuzzy_eq!(1.5f32.ceil(), 2.0f32);
|
||||
assert_fuzzy_eq!(1.7f32.ceil(), 2.0f32);
|
||||
assert_fuzzy_eq!(0.0f32.ceil(), 0.0f32);
|
||||
assert_fuzzy_eq!((-0.0f32).ceil(), -0.0f32);
|
||||
assert_fuzzy_eq!((-1.0f32).ceil(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.3f32).ceil(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.5f32).ceil(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.7f32).ceil(), -1.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_round() {
|
||||
assert_fuzzy_eq!(1.0f32.round(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.3f32.round(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.5f32.round(), 2.0f32);
|
||||
assert_fuzzy_eq!(1.7f32.round(), 2.0f32);
|
||||
assert_fuzzy_eq!(0.0f32.round(), 0.0f32);
|
||||
assert_fuzzy_eq!((-0.0f32).round(), -0.0f32);
|
||||
assert_fuzzy_eq!((-1.0f32).round(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.3f32).round(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.5f32).round(), -2.0f32);
|
||||
assert_fuzzy_eq!((-1.7f32).round(), -2.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trunc() {
|
||||
assert_fuzzy_eq!(1.0f32.trunc(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.3f32.trunc(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.5f32.trunc(), 1.0f32);
|
||||
assert_fuzzy_eq!(1.7f32.trunc(), 1.0f32);
|
||||
assert_fuzzy_eq!(0.0f32.trunc(), 0.0f32);
|
||||
assert_fuzzy_eq!((-0.0f32).trunc(), -0.0f32);
|
||||
assert_fuzzy_eq!((-1.0f32).trunc(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.3f32).trunc(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.5f32).trunc(), -1.0f32);
|
||||
assert_fuzzy_eq!((-1.7f32).trunc(), -1.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fract() {
|
||||
assert_fuzzy_eq!(1.0f32.fract(), 0.0f32);
|
||||
assert_fuzzy_eq!(1.3f32.fract(), 0.3f32);
|
||||
assert_fuzzy_eq!(1.5f32.fract(), 0.5f32);
|
||||
assert_fuzzy_eq!(1.7f32.fract(), 0.7f32);
|
||||
assert_fuzzy_eq!(0.0f32.fract(), 0.0f32);
|
||||
assert_fuzzy_eq!((-0.0f32).fract(), -0.0f32);
|
||||
assert_fuzzy_eq!((-1.0f32).fract(), -0.0f32);
|
||||
assert_fuzzy_eq!((-1.3f32).fract(), -0.3f32);
|
||||
assert_fuzzy_eq!((-1.5f32).fract(), -0.5f32);
|
||||
assert_fuzzy_eq!((-1.7f32).fract(), -0.7f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
assert_fuzzy_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
|
||||
assert_fuzzy_eq!(Real::frac_pi_2::<f32>(), Real::pi::<f32>() / 2f32);
|
||||
assert_fuzzy_eq!(Real::frac_pi_3::<f32>(), Real::pi::<f32>() / 3f32);
|
||||
assert_fuzzy_eq!(Real::frac_pi_4::<f32>(), Real::pi::<f32>() / 4f32);
|
||||
assert_fuzzy_eq!(Real::frac_pi_6::<f32>(), Real::pi::<f32>() / 6f32);
|
||||
assert_fuzzy_eq!(Real::frac_pi_8::<f32>(), Real::pi::<f32>() / 8f32);
|
||||
assert_fuzzy_eq!(Real::frac_1_pi::<f32>(), 1f32 / Real::pi::<f32>());
|
||||
assert_fuzzy_eq!(Real::frac_2_pi::<f32>(), 2f32 / Real::pi::<f32>());
|
||||
assert_fuzzy_eq!(Real::frac_2_sqrtpi::<f32>(), 2f32 / Real::pi::<f32>().sqrt());
|
||||
assert_fuzzy_eq!(Real::sqrt2::<f32>(), 2f32.sqrt());
|
||||
assert_fuzzy_eq!(Real::frac_1_sqrt2::<f32>(), 1f32 / 2f32.sqrt());
|
||||
assert_fuzzy_eq!(Real::log2_e::<f32>(), Real::e::<f32>().log2());
|
||||
assert_fuzzy_eq!(Real::log10_e::<f32>(), Real::e::<f32>().log10());
|
||||
assert_fuzzy_eq!(Real::log_2::<f32>(), 2f32.log());
|
||||
assert_fuzzy_eq!(Real::log_10::<f32>(), 10f32.log());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_signed() {
|
||||
|
|
|
|||
|
|
@ -10,20 +10,10 @@
|
|||
|
||||
//! Operations and constants for `f64`
|
||||
|
||||
use num::strconv;
|
||||
use num::Signed;
|
||||
use num;
|
||||
use option::Option;
|
||||
use to_str;
|
||||
use from_str;
|
||||
|
||||
#[cfg(notest)] use cmp::{Eq, Ord};
|
||||
#[cfg(stage0,notest)]
|
||||
use ops::{Add, Sub, Mul, Div, Modulo, Neg};
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
use ops::{Add, Sub, Mul, Quot, Rem, Neg};
|
||||
use libc::c_int;
|
||||
use num::strconv;
|
||||
use prelude::*;
|
||||
|
||||
pub use cmath::c_double_targ_consts::*;
|
||||
pub use cmp::{min, max};
|
||||
|
|
@ -254,6 +244,8 @@ pub fn logarithm(n: f64, b: f64) -> f64 {
|
|||
return log2(n) / log2(b);
|
||||
}
|
||||
|
||||
impl Num for f64 {}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl Eq for f64 {
|
||||
#[inline(always)]
|
||||
|
|
@ -300,9 +292,7 @@ impl Mul<f64,f64> for f64 {
|
|||
impl Div<f64,f64> for f64 {
|
||||
fn div(&self, other: &f64) -> f64 { *self / *other }
|
||||
}
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Quot<f64,f64> for f64 {
|
||||
#[inline(always)]
|
||||
fn quot(&self, other: &f64) -> f64 { *self / *other }
|
||||
|
|
@ -311,9 +301,7 @@ impl Quot<f64,f64> for f64 {
|
|||
impl Modulo<f64,f64> for f64 {
|
||||
fn modulo(&self, other: &f64) -> f64 { *self % *other }
|
||||
}
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Rem<f64,f64> for f64 {
|
||||
#[inline(always)]
|
||||
fn rem(&self, other: &f64) -> f64 { *self % *other }
|
||||
|
|
@ -349,31 +337,218 @@ impl Signed for f64 {
|
|||
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
|
||||
}
|
||||
|
||||
impl num::Round for f64 {
|
||||
impl Round for f64 {
|
||||
/// Round half-way cases toward `neg_infinity`
|
||||
#[inline(always)]
|
||||
fn round(&self, mode: num::RoundMode) -> f64 {
|
||||
match mode {
|
||||
num::RoundDown => floor(*self),
|
||||
num::RoundUp => ceil(*self),
|
||||
num::RoundToZero if self.is_negative() => ceil(*self),
|
||||
num::RoundToZero => floor(*self),
|
||||
num::RoundFromZero if self.is_negative() => floor(*self),
|
||||
num::RoundFromZero => ceil(*self)
|
||||
}
|
||||
fn floor(&self) -> f64 { floor(*self) }
|
||||
|
||||
/// Round half-way cases toward `infinity`
|
||||
#[inline(always)]
|
||||
fn ceil(&self) -> f64 { ceil(*self) }
|
||||
|
||||
/// Round half-way cases away from `0.0`
|
||||
#[inline(always)]
|
||||
fn round(&self) -> f64 { round(*self) }
|
||||
|
||||
/// The integer part of the number (rounds towards `0.0`)
|
||||
#[inline(always)]
|
||||
fn trunc(&self) -> f64 { trunc(*self) }
|
||||
|
||||
///
|
||||
/// The fractional part of the number, satisfying:
|
||||
///
|
||||
/// ~~~
|
||||
/// assert!(x == trunc(x) + fract(x))
|
||||
/// ~~~
|
||||
///
|
||||
#[inline(always)]
|
||||
fn fract(&self) -> f64 { *self - self.trunc() }
|
||||
}
|
||||
|
||||
impl Fractional for f64 {
|
||||
/// The reciprocal (multiplicative inverse) of the number
|
||||
#[inline(always)]
|
||||
fn recip(&self) -> f64 { 1.0 / *self }
|
||||
}
|
||||
|
||||
impl Real for f64 {
|
||||
/// Archimedes' constant
|
||||
#[inline(always)]
|
||||
fn pi() -> f64 { 3.14159265358979323846264338327950288 }
|
||||
|
||||
/// 2.0 * pi
|
||||
#[inline(always)]
|
||||
fn two_pi() -> f64 { 6.28318530717958647692528676655900576 }
|
||||
|
||||
/// pi / 2.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 }
|
||||
|
||||
/// pi / 3.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 }
|
||||
|
||||
/// pi / 4.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 }
|
||||
|
||||
/// pi / 6.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 }
|
||||
|
||||
/// pi / 8.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 }
|
||||
|
||||
/// 1.0 / pi
|
||||
#[inline(always)]
|
||||
fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 }
|
||||
|
||||
/// 2.0 / pi
|
||||
#[inline(always)]
|
||||
fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 }
|
||||
|
||||
/// 2.0 / sqrt(pi)
|
||||
#[inline(always)]
|
||||
fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
|
||||
|
||||
/// sqrt(2.0)
|
||||
#[inline(always)]
|
||||
fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
|
||||
|
||||
/// 1.0 / sqrt(2.0)
|
||||
#[inline(always)]
|
||||
fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
|
||||
|
||||
/// Euler's number
|
||||
#[inline(always)]
|
||||
fn e() -> f64 { 2.71828182845904523536028747135266250 }
|
||||
|
||||
/// log2(e)
|
||||
#[inline(always)]
|
||||
fn log2_e() -> f64 { 1.44269504088896340735992468100189214 }
|
||||
|
||||
/// log10(e)
|
||||
#[inline(always)]
|
||||
fn log10_e() -> f64 { 0.434294481903251827651128918916605082 }
|
||||
|
||||
/// log(2.0)
|
||||
#[inline(always)]
|
||||
fn log_2() -> f64 { 0.693147180559945309417232121458176568 }
|
||||
|
||||
/// log(10.0)
|
||||
#[inline(always)]
|
||||
fn log_10() -> f64 { 2.30258509299404568401799145468436421 }
|
||||
|
||||
#[inline(always)]
|
||||
fn pow(&self, n: f64) -> f64 { pow(*self, n) }
|
||||
|
||||
#[inline(always)]
|
||||
fn exp(&self) -> f64 { exp(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn exp2(&self) -> f64 { exp2(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn expm1(&self) -> f64 { expm1(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn ldexp(&self, n: int) -> f64 { ldexp(*self, n as c_int) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log(&self) -> f64 { ln(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log2(&self) -> f64 { log2(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log10(&self) -> f64 { log10(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn log_radix(&self) -> f64 { log_radix(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn ilog_radix(&self) -> int { ilog_radix(*self) as int }
|
||||
|
||||
#[inline(always)]
|
||||
fn sqrt(&self) -> f64 { sqrt(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn rsqrt(&self) -> f64 { self.sqrt().recip() }
|
||||
|
||||
#[inline(always)]
|
||||
fn cbrt(&self) -> f64 { cbrt(*self) }
|
||||
|
||||
/// Converts to degrees, assuming the number is in radians
|
||||
#[inline(always)]
|
||||
fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) }
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees
|
||||
#[inline(always)]
|
||||
fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) }
|
||||
|
||||
#[inline(always)]
|
||||
fn hypot(&self, other: f64) -> f64 { hypot(*self, other) }
|
||||
|
||||
#[inline(always)]
|
||||
fn sin(&self) -> f64 { sin(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn cos(&self) -> f64 { cos(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn tan(&self) -> f64 { tan(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn asin(&self) -> f64 { asin(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn acos(&self) -> f64 { acos(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn atan(&self) -> f64 { atan(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn atan2(&self, other: f64) -> f64 { atan2(*self, other) }
|
||||
|
||||
#[inline(always)]
|
||||
fn sinh(&self) -> f64 { sinh(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn cosh(&self) -> f64 { cosh(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn tanh(&self) -> f64 { tanh(*self) }
|
||||
}
|
||||
|
||||
impl RealExt for f64 {
|
||||
#[inline(always)]
|
||||
fn lgamma(&self) -> (int, f64) {
|
||||
let mut sign = 0;
|
||||
let result = lgamma(*self, &mut sign);
|
||||
(sign as int, result)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn floor(&self) -> f64 { floor(*self) }
|
||||
fn tgamma(&self) -> f64 { tgamma(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn ceil(&self) -> f64 { ceil(*self) }
|
||||
fn j0(&self) -> f64 { j0(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn fract(&self) -> f64 {
|
||||
if self.is_negative() {
|
||||
(*self) - ceil(*self)
|
||||
} else {
|
||||
(*self) - floor(*self)
|
||||
}
|
||||
}
|
||||
fn j1(&self) -> f64 { j1(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn jn(&self, n: int) -> f64 { jn(n as c_int, *self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn y0(&self) -> f64 { y0(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn y1(&self) -> f64 { y1(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn yn(&self, n: int) -> f64 { yn(n as c_int, *self) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -596,6 +771,112 @@ impl num::FromStrRadix for f64 {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use f64::*;
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
|
||||
macro_rules! assert_fuzzy_eq(
|
||||
($a:expr, $b:expr) => ({
|
||||
let a = $a, b = $b;
|
||||
if !((a - b).abs() < 1.0e-6) {
|
||||
fail!(fmt!("The values were not approximately equal. \
|
||||
Found: %? and expected %?", a, b));
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10f64, 2f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_floor() {
|
||||
assert_fuzzy_eq!(1.0f64.floor(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.3f64.floor(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.5f64.floor(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.7f64.floor(), 1.0f64);
|
||||
assert_fuzzy_eq!(0.0f64.floor(), 0.0f64);
|
||||
assert_fuzzy_eq!((-0.0f64).floor(), -0.0f64);
|
||||
assert_fuzzy_eq!((-1.0f64).floor(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.3f64).floor(), -2.0f64);
|
||||
assert_fuzzy_eq!((-1.5f64).floor(), -2.0f64);
|
||||
assert_fuzzy_eq!((-1.7f64).floor(), -2.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ceil() {
|
||||
assert_fuzzy_eq!(1.0f64.ceil(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.3f64.ceil(), 2.0f64);
|
||||
assert_fuzzy_eq!(1.5f64.ceil(), 2.0f64);
|
||||
assert_fuzzy_eq!(1.7f64.ceil(), 2.0f64);
|
||||
assert_fuzzy_eq!(0.0f64.ceil(), 0.0f64);
|
||||
assert_fuzzy_eq!((-0.0f64).ceil(), -0.0f64);
|
||||
assert_fuzzy_eq!((-1.0f64).ceil(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.3f64).ceil(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.5f64).ceil(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.7f64).ceil(), -1.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_round() {
|
||||
assert_fuzzy_eq!(1.0f64.round(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.3f64.round(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.5f64.round(), 2.0f64);
|
||||
assert_fuzzy_eq!(1.7f64.round(), 2.0f64);
|
||||
assert_fuzzy_eq!(0.0f64.round(), 0.0f64);
|
||||
assert_fuzzy_eq!((-0.0f64).round(), -0.0f64);
|
||||
assert_fuzzy_eq!((-1.0f64).round(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.3f64).round(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.5f64).round(), -2.0f64);
|
||||
assert_fuzzy_eq!((-1.7f64).round(), -2.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trunc() {
|
||||
assert_fuzzy_eq!(1.0f64.trunc(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.3f64.trunc(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.5f64.trunc(), 1.0f64);
|
||||
assert_fuzzy_eq!(1.7f64.trunc(), 1.0f64);
|
||||
assert_fuzzy_eq!(0.0f64.trunc(), 0.0f64);
|
||||
assert_fuzzy_eq!((-0.0f64).trunc(), -0.0f64);
|
||||
assert_fuzzy_eq!((-1.0f64).trunc(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.3f64).trunc(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.5f64).trunc(), -1.0f64);
|
||||
assert_fuzzy_eq!((-1.7f64).trunc(), -1.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fract() {
|
||||
assert_fuzzy_eq!(1.0f64.fract(), 0.0f64);
|
||||
assert_fuzzy_eq!(1.3f64.fract(), 0.3f64);
|
||||
assert_fuzzy_eq!(1.5f64.fract(), 0.5f64);
|
||||
assert_fuzzy_eq!(1.7f64.fract(), 0.7f64);
|
||||
assert_fuzzy_eq!(0.0f64.fract(), 0.0f64);
|
||||
assert_fuzzy_eq!((-0.0f64).fract(), -0.0f64);
|
||||
assert_fuzzy_eq!((-1.0f64).fract(), -0.0f64);
|
||||
assert_fuzzy_eq!((-1.3f64).fract(), -0.3f64);
|
||||
assert_fuzzy_eq!((-1.5f64).fract(), -0.5f64);
|
||||
assert_fuzzy_eq!((-1.7f64).fract(), -0.7f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
assert_fuzzy_eq!(Real::two_pi::<f64>(), 2.0 * Real::pi::<f64>());
|
||||
assert_fuzzy_eq!(Real::frac_pi_2::<f64>(), Real::pi::<f64>() / 2f64);
|
||||
assert_fuzzy_eq!(Real::frac_pi_3::<f64>(), Real::pi::<f64>() / 3f64);
|
||||
assert_fuzzy_eq!(Real::frac_pi_4::<f64>(), Real::pi::<f64>() / 4f64);
|
||||
assert_fuzzy_eq!(Real::frac_pi_6::<f64>(), Real::pi::<f64>() / 6f64);
|
||||
assert_fuzzy_eq!(Real::frac_pi_8::<f64>(), Real::pi::<f64>() / 8f64);
|
||||
assert_fuzzy_eq!(Real::frac_1_pi::<f64>(), 1f64 / Real::pi::<f64>());
|
||||
assert_fuzzy_eq!(Real::frac_2_pi::<f64>(), 2f64 / Real::pi::<f64>());
|
||||
assert_fuzzy_eq!(Real::frac_2_sqrtpi::<f64>(), 2f64 / Real::pi::<f64>().sqrt());
|
||||
assert_fuzzy_eq!(Real::sqrt2::<f64>(), 2f64.sqrt());
|
||||
assert_fuzzy_eq!(Real::frac_1_sqrt2::<f64>(), 1f64 / 2f64.sqrt());
|
||||
assert_fuzzy_eq!(Real::log2_e::<f64>(), Real::e::<f64>().log2());
|
||||
assert_fuzzy_eq!(Real::log10_e::<f64>(), Real::e::<f64>().log10());
|
||||
assert_fuzzy_eq!(Real::log_2::<f64>(), 2f64.log());
|
||||
assert_fuzzy_eq!(Real::log_10::<f64>(), 10f64.log());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_signed() {
|
||||
|
|
|
|||
|
|
@ -20,21 +20,10 @@
|
|||
|
||||
// PORT this must match in width according to architecture
|
||||
|
||||
use f64;
|
||||
use num::strconv;
|
||||
use num::Signed;
|
||||
use num;
|
||||
use option::Option;
|
||||
use to_str;
|
||||
use from_str;
|
||||
|
||||
#[cfg(notest)] use cmp::{Eq, Ord};
|
||||
#[cfg(stage0,notest)]
|
||||
use ops::{Add, Sub, Mul, Div, Modulo, Neg};
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
use ops::{Add, Sub, Mul, Quot, Rem, Neg};
|
||||
use libc::c_int;
|
||||
use num::strconv;
|
||||
use prelude::*;
|
||||
|
||||
pub use f64::{add, sub, mul, quot, rem, lt, le, eq, ne, ge, gt};
|
||||
pub use f64::logarithm;
|
||||
|
|
@ -382,6 +371,8 @@ pub fn tan(x: float) -> float {
|
|||
f64::tan(x as f64) as float
|
||||
}
|
||||
|
||||
impl Num for float {}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl Eq for float {
|
||||
#[inline(always)]
|
||||
|
|
@ -412,37 +403,218 @@ impl num::One for float {
|
|||
fn one() -> float { 1.0 }
|
||||
}
|
||||
|
||||
impl num::Round for float {
|
||||
impl Round for float {
|
||||
/// Round half-way cases toward `neg_infinity`
|
||||
#[inline(always)]
|
||||
fn round(&self, mode: num::RoundMode) -> float {
|
||||
match mode {
|
||||
num::RoundDown
|
||||
=> f64::floor(*self as f64) as float,
|
||||
num::RoundUp
|
||||
=> f64::ceil(*self as f64) as float,
|
||||
num::RoundToZero if self.is_negative()
|
||||
=> f64::ceil(*self as f64) as float,
|
||||
num::RoundToZero
|
||||
=> f64::floor(*self as f64) as float,
|
||||
num::RoundFromZero if self.is_negative()
|
||||
=> f64::floor(*self as f64) as float,
|
||||
num::RoundFromZero
|
||||
=> f64::ceil(*self as f64) as float
|
||||
}
|
||||
fn floor(&self) -> float { floor(*self as f64) as float }
|
||||
|
||||
/// Round half-way cases toward `infinity`
|
||||
#[inline(always)]
|
||||
fn ceil(&self) -> float { ceil(*self as f64) as float }
|
||||
|
||||
/// Round half-way cases away from `0.0`
|
||||
#[inline(always)]
|
||||
fn round(&self) -> float { round(*self as f64) as float }
|
||||
|
||||
/// The integer part of the number (rounds towards `0.0`)
|
||||
#[inline(always)]
|
||||
fn trunc(&self) -> float { trunc(*self as f64) as float }
|
||||
|
||||
///
|
||||
/// The fractional part of the number, satisfying:
|
||||
///
|
||||
/// ~~~
|
||||
/// assert!(x == trunc(x) + fract(x))
|
||||
/// ~~~
|
||||
///
|
||||
#[inline(always)]
|
||||
fn fract(&self) -> float { *self - self.trunc() }
|
||||
}
|
||||
|
||||
impl Fractional for float {
|
||||
/// The reciprocal (multiplicative inverse) of the number
|
||||
#[inline(always)]
|
||||
fn recip(&self) -> float { 1.0 / *self }
|
||||
}
|
||||
|
||||
impl Real for float {
|
||||
/// Archimedes' constant
|
||||
#[inline(always)]
|
||||
fn pi() -> float { 3.14159265358979323846264338327950288 }
|
||||
|
||||
/// 2.0 * pi
|
||||
#[inline(always)]
|
||||
fn two_pi() -> float { 6.28318530717958647692528676655900576 }
|
||||
|
||||
/// pi / 2.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 }
|
||||
|
||||
/// pi / 3.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 }
|
||||
|
||||
/// pi / 4.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 }
|
||||
|
||||
/// pi / 6.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 }
|
||||
|
||||
/// pi / 8.0
|
||||
#[inline(always)]
|
||||
fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 }
|
||||
|
||||
/// 1.0 / pi
|
||||
#[inline(always)]
|
||||
fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 }
|
||||
|
||||
/// 2.0 / pi
|
||||
#[inline(always)]
|
||||
fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 }
|
||||
|
||||
/// 2 .0/ sqrt(pi)
|
||||
#[inline(always)]
|
||||
fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 }
|
||||
|
||||
/// sqrt(2.0)
|
||||
#[inline(always)]
|
||||
fn sqrt2() -> float { 1.41421356237309504880168872420969808 }
|
||||
|
||||
/// 1.0 / sqrt(2.0)
|
||||
#[inline(always)]
|
||||
fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 }
|
||||
|
||||
/// Euler's number
|
||||
#[inline(always)]
|
||||
fn e() -> float { 2.71828182845904523536028747135266250 }
|
||||
|
||||
/// log2(e)
|
||||
#[inline(always)]
|
||||
fn log2_e() -> float { 1.44269504088896340735992468100189214 }
|
||||
|
||||
/// log10(e)
|
||||
#[inline(always)]
|
||||
fn log10_e() -> float { 0.434294481903251827651128918916605082 }
|
||||
|
||||
/// log(2.0)
|
||||
#[inline(always)]
|
||||
fn log_2() -> float { 0.693147180559945309417232121458176568 }
|
||||
|
||||
/// log(10.0)
|
||||
#[inline(always)]
|
||||
fn log_10() -> float { 2.30258509299404568401799145468436421 }
|
||||
|
||||
#[inline(always)]
|
||||
fn pow(&self, n: float) -> float { pow(*self as f64, n as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn exp(&self) -> float { exp(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn exp2(&self) -> float { exp2(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn expm1(&self) -> float { expm1(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn ldexp(&self, n: int) -> float { ldexp(*self as f64, n as c_int) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn log(&self) -> float { ln(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn log2(&self) -> float { log2(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn log10(&self) -> float { log10(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn log_radix(&self) -> float { log_radix(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn ilog_radix(&self) -> int { ilog_radix(*self as f64) as int }
|
||||
|
||||
#[inline(always)]
|
||||
fn sqrt(&self) -> float { sqrt(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn rsqrt(&self) -> float { self.sqrt().recip() }
|
||||
|
||||
#[inline(always)]
|
||||
fn cbrt(&self) -> float { cbrt(*self as f64) as float }
|
||||
|
||||
/// Converts to degrees, assuming the number is in radians
|
||||
#[inline(always)]
|
||||
fn to_degrees(&self) -> float { *self * (180.0 / Real::pi::<float>()) }
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees
|
||||
#[inline(always)]
|
||||
fn to_radians(&self) -> float { *self * (Real::pi::<float>() / 180.0) }
|
||||
|
||||
#[inline(always)]
|
||||
fn hypot(&self, other: float) -> float { hypot(*self as f64, other as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn sin(&self) -> float { sin(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn cos(&self) -> float { cos(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn tan(&self) -> float { tan(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn asin(&self) -> float { asin(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn acos(&self) -> float { acos(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn atan(&self) -> float { atan(*self) }
|
||||
|
||||
#[inline(always)]
|
||||
fn atan2(&self, other: float) -> float { atan2(*self as f64, other as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn sinh(&self) -> float { sinh(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn cosh(&self) -> float { cosh(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn tanh(&self) -> float { tanh(*self as f64) as float }
|
||||
}
|
||||
|
||||
impl RealExt for float {
|
||||
#[inline(always)]
|
||||
fn lgamma(&self) -> (int, float) {
|
||||
let mut sign = 0;
|
||||
let result = lgamma(*self as f64, &mut sign);
|
||||
(sign as int, result as float)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn floor(&self) -> float { f64::floor(*self as f64) as float}
|
||||
fn tgamma(&self) -> float { tgamma(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn ceil(&self) -> float { f64::ceil(*self as f64) as float}
|
||||
fn j0(&self) -> float { j0(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn fract(&self) -> float {
|
||||
if self.is_negative() {
|
||||
(*self) - (f64::ceil(*self as f64) as float)
|
||||
} else {
|
||||
(*self) - (f64::floor(*self as f64) as float)
|
||||
}
|
||||
}
|
||||
fn j1(&self) -> float { j1(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn jn(&self, n: int) -> float { jn(n as c_int, *self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn y0(&self) -> float { y0(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn y1(&self) -> float { y1(*self as f64) as float }
|
||||
|
||||
#[inline(always)]
|
||||
fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float }
|
||||
}
|
||||
|
||||
#[cfg(notest)]
|
||||
|
|
@ -468,9 +640,7 @@ impl Div<float,float> for float {
|
|||
#[inline(always)]
|
||||
fn div(&self, other: &float) -> float { *self / *other }
|
||||
}
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Quot<float,float> for float {
|
||||
#[inline(always)]
|
||||
fn quot(&self, other: &float) -> float { *self / *other }
|
||||
|
|
@ -480,9 +650,7 @@ impl Modulo<float,float> for float {
|
|||
#[inline(always)]
|
||||
fn modulo(&self, other: &float) -> float { *self % *other }
|
||||
}
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Rem<float,float> for float {
|
||||
#[inline(always)]
|
||||
fn rem(&self, other: &float) -> float { *self % *other }
|
||||
|
|
@ -524,6 +692,109 @@ mod tests {
|
|||
use super::*;
|
||||
use prelude::*;
|
||||
|
||||
macro_rules! assert_fuzzy_eq(
|
||||
($a:expr, $b:expr) => ({
|
||||
let a = $a, b = $b;
|
||||
if !((a - b).abs() < 1.0e-6) {
|
||||
fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10f, 2f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_floor() {
|
||||
assert_fuzzy_eq!(1.0f.floor(), 1.0f);
|
||||
assert_fuzzy_eq!(1.3f.floor(), 1.0f);
|
||||
assert_fuzzy_eq!(1.5f.floor(), 1.0f);
|
||||
assert_fuzzy_eq!(1.7f.floor(), 1.0f);
|
||||
assert_fuzzy_eq!(0.0f.floor(), 0.0f);
|
||||
assert_fuzzy_eq!((-0.0f).floor(), -0.0f);
|
||||
assert_fuzzy_eq!((-1.0f).floor(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.3f).floor(), -2.0f);
|
||||
assert_fuzzy_eq!((-1.5f).floor(), -2.0f);
|
||||
assert_fuzzy_eq!((-1.7f).floor(), -2.0f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ceil() {
|
||||
assert_fuzzy_eq!(1.0f.ceil(), 1.0f);
|
||||
assert_fuzzy_eq!(1.3f.ceil(), 2.0f);
|
||||
assert_fuzzy_eq!(1.5f.ceil(), 2.0f);
|
||||
assert_fuzzy_eq!(1.7f.ceil(), 2.0f);
|
||||
assert_fuzzy_eq!(0.0f.ceil(), 0.0f);
|
||||
assert_fuzzy_eq!((-0.0f).ceil(), -0.0f);
|
||||
assert_fuzzy_eq!((-1.0f).ceil(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.3f).ceil(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.5f).ceil(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.7f).ceil(), -1.0f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_round() {
|
||||
assert_fuzzy_eq!(1.0f.round(), 1.0f);
|
||||
assert_fuzzy_eq!(1.3f.round(), 1.0f);
|
||||
assert_fuzzy_eq!(1.5f.round(), 2.0f);
|
||||
assert_fuzzy_eq!(1.7f.round(), 2.0f);
|
||||
assert_fuzzy_eq!(0.0f.round(), 0.0f);
|
||||
assert_fuzzy_eq!((-0.0f).round(), -0.0f);
|
||||
assert_fuzzy_eq!((-1.0f).round(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.3f).round(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.5f).round(), -2.0f);
|
||||
assert_fuzzy_eq!((-1.7f).round(), -2.0f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trunc() {
|
||||
assert_fuzzy_eq!(1.0f.trunc(), 1.0f);
|
||||
assert_fuzzy_eq!(1.3f.trunc(), 1.0f);
|
||||
assert_fuzzy_eq!(1.5f.trunc(), 1.0f);
|
||||
assert_fuzzy_eq!(1.7f.trunc(), 1.0f);
|
||||
assert_fuzzy_eq!(0.0f.trunc(), 0.0f);
|
||||
assert_fuzzy_eq!((-0.0f).trunc(), -0.0f);
|
||||
assert_fuzzy_eq!((-1.0f).trunc(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.3f).trunc(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.5f).trunc(), -1.0f);
|
||||
assert_fuzzy_eq!((-1.7f).trunc(), -1.0f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fract() {
|
||||
assert_fuzzy_eq!(1.0f.fract(), 0.0f);
|
||||
assert_fuzzy_eq!(1.3f.fract(), 0.3f);
|
||||
assert_fuzzy_eq!(1.5f.fract(), 0.5f);
|
||||
assert_fuzzy_eq!(1.7f.fract(), 0.7f);
|
||||
assert_fuzzy_eq!(0.0f.fract(), 0.0f);
|
||||
assert_fuzzy_eq!((-0.0f).fract(), -0.0f);
|
||||
assert_fuzzy_eq!((-1.0f).fract(), -0.0f);
|
||||
assert_fuzzy_eq!((-1.3f).fract(), -0.3f);
|
||||
assert_fuzzy_eq!((-1.5f).fract(), -0.5f);
|
||||
assert_fuzzy_eq!((-1.7f).fract(), -0.7f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
assert_fuzzy_eq!(Real::two_pi::<float>(), 2f * Real::pi::<float>());
|
||||
assert_fuzzy_eq!(Real::frac_pi_2::<float>(), Real::pi::<float>() / 2f);
|
||||
assert_fuzzy_eq!(Real::frac_pi_3::<float>(), Real::pi::<float>() / 3f);
|
||||
assert_fuzzy_eq!(Real::frac_pi_4::<float>(), Real::pi::<float>() / 4f);
|
||||
assert_fuzzy_eq!(Real::frac_pi_6::<float>(), Real::pi::<float>() / 6f);
|
||||
assert_fuzzy_eq!(Real::frac_pi_8::<float>(), Real::pi::<float>() / 8f);
|
||||
assert_fuzzy_eq!(Real::frac_1_pi::<float>(), 1f / Real::pi::<float>());
|
||||
assert_fuzzy_eq!(Real::frac_2_pi::<float>(), 2f / Real::pi::<float>());
|
||||
assert_fuzzy_eq!(Real::frac_2_sqrtpi::<float>(), 2f / Real::pi::<float>().sqrt());
|
||||
assert_fuzzy_eq!(Real::sqrt2::<float>(), 2f.sqrt());
|
||||
assert_fuzzy_eq!(Real::frac_1_sqrt2::<float>(), 1f / 2f.sqrt());
|
||||
assert_fuzzy_eq!(Real::log2_e::<float>(), Real::e::<float>().log2());
|
||||
assert_fuzzy_eq!(Real::log10_e::<float>(), Real::e::<float>().log10());
|
||||
assert_fuzzy_eq!(Real::log_2::<float>(), 2f.log());
|
||||
assert_fuzzy_eq!(Real::log_10::<float>(), 10f.log());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_signed() {
|
||||
assert_eq!(infinity.abs(), infinity);
|
||||
|
|
@ -704,15 +975,6 @@ mod tests {
|
|||
assert_eq!(to_str_digits(infinity, 10u), ~"inf");
|
||||
assert_eq!(to_str_digits(-infinity, 10u), ~"-inf");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_round() {
|
||||
assert_eq!(round(5.8), 6.0);
|
||||
assert_eq!(round(5.2), 5.0);
|
||||
assert_eq!(round(3.0), 3.0);
|
||||
assert_eq!(round(2.5), 3.0);
|
||||
assert_eq!(round(-3.5), -4.0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -10,12 +10,9 @@
|
|||
|
||||
use T = self::inst::T;
|
||||
|
||||
use to_str::ToStr;
|
||||
use from_str::FromStr;
|
||||
use num::{ToStrRadix, FromStrRadix};
|
||||
use num::strconv;
|
||||
use num::Signed;
|
||||
use num;
|
||||
use prelude::*;
|
||||
|
||||
pub use cmp::{min, max};
|
||||
|
|
@ -133,6 +130,8 @@ pub fn compl(i: T) -> T {
|
|||
#[inline(always)]
|
||||
pub fn abs(i: T) -> T { i.abs() }
|
||||
|
||||
impl Num for T {}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl Ord for T {
|
||||
#[inline(always)]
|
||||
|
|
@ -186,10 +185,7 @@ impl Div<T,T> for T {
|
|||
#[inline(always)]
|
||||
fn div(&self, other: &T) -> T { *self / *other }
|
||||
}
|
||||
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Quot<T,T> for T {
|
||||
/**
|
||||
* Returns the integer quotient, truncated towards 0. As this behaviour reflects
|
||||
|
|
@ -218,10 +214,7 @@ impl Modulo<T,T> for T {
|
|||
#[inline(always)]
|
||||
fn modulo(&self, other: &T) -> T { *self % *other }
|
||||
}
|
||||
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Rem<T,T> for T {
|
||||
/**
|
||||
* Returns the integer remainder after division, satisfying:
|
||||
|
|
@ -286,7 +279,7 @@ impl Signed for T {
|
|||
fn is_negative(&self) -> bool { *self < 0 }
|
||||
}
|
||||
|
||||
impl Natural for T {
|
||||
impl Integer for T {
|
||||
/**
|
||||
* Floored integer division
|
||||
*
|
||||
|
|
@ -305,13 +298,13 @@ impl Natural for T {
|
|||
* ~~~
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn div(&self, other: T) -> T {
|
||||
fn div(&self, other: &T) -> T {
|
||||
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
|
||||
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
|
||||
match self.quot_rem(other) {
|
||||
(q, r) if (r > 0 && other < 0)
|
||||
|| (r < 0 && other > 0) => q - 1,
|
||||
(q, _) => q,
|
||||
(q, r) if (r > 0 && *other < 0)
|
||||
|| (r < 0 && *other > 0) => q - 1,
|
||||
(q, _) => q,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -337,32 +330,32 @@ impl Natural for T {
|
|||
* ~~~
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn modulo(&self, other: T) -> T {
|
||||
fn modulo(&self, other: &T) -> T {
|
||||
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
|
||||
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
|
||||
match *self % other {
|
||||
r if (r > 0 && other < 0)
|
||||
|| (r < 0 && other > 0) => r + other,
|
||||
r => r,
|
||||
match *self % *other {
|
||||
r if (r > 0 && *other < 0)
|
||||
|| (r < 0 && *other > 0) => r + *other,
|
||||
r => r,
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates `div` and `modulo` simultaneously
|
||||
#[inline(always)]
|
||||
fn div_mod(&self, other: T) -> (T,T) {
|
||||
fn div_mod(&self, other: &T) -> (T,T) {
|
||||
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
|
||||
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
|
||||
match self.quot_rem(other) {
|
||||
(q, r) if (r > 0 && other < 0)
|
||||
|| (r < 0 && other > 0) => (q - 1, r + other),
|
||||
(q, r) => (q, r),
|
||||
(q, r) if (r > 0 && *other < 0)
|
||||
|| (r < 0 && *other > 0) => (q - 1, r + *other),
|
||||
(q, r) => (q, r),
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates `quot` (`\`) and `rem` (`%`) simultaneously
|
||||
#[inline(always)]
|
||||
fn quot_rem(&self, other: T) -> (T,T) {
|
||||
(*self / other, *self % other)
|
||||
fn quot_rem(&self, other: &T) -> (T,T) {
|
||||
(*self / *other, *self % *other)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -371,9 +364,9 @@ impl Natural for T {
|
|||
* The result is always positive
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn gcd(&self, other: T) -> T {
|
||||
fn gcd(&self, other: &T) -> T {
|
||||
// Use Euclid's algorithm
|
||||
let mut m = *self, n = other;
|
||||
let mut m = *self, n = *other;
|
||||
while m != 0 {
|
||||
let temp = m;
|
||||
m = n % temp;
|
||||
|
|
@ -386,17 +379,17 @@ impl Natural for T {
|
|||
* Calculates the Lowest Common Multiple (LCM) of the number and `other`
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn lcm(&self, other: T) -> T {
|
||||
((*self * other) / self.gcd(other)).abs() // should not have to recaluculate abs
|
||||
fn lcm(&self, other: &T) -> T {
|
||||
((*self * *other) / self.gcd(other)).abs() // should not have to recaluculate abs
|
||||
}
|
||||
|
||||
/// Returns `true` if the number can be divided by `other` without leaving a remainder
|
||||
#[inline(always)]
|
||||
fn divisible_by(&self, other: T) -> bool { *self % other == 0 }
|
||||
fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 }
|
||||
|
||||
/// Returns `true` if the number is divisible by `2`
|
||||
#[inline(always)]
|
||||
fn is_even(&self) -> bool { self.divisible_by(2) }
|
||||
fn is_even(&self) -> bool { self.divisible_by(&2) }
|
||||
|
||||
/// Returns `true` if the number is not divisible by `2`
|
||||
#[inline(always)]
|
||||
|
|
@ -522,6 +515,11 @@ mod tests {
|
|||
use super::inst::T;
|
||||
use prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10 as T, 2 as T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_signed() {
|
||||
assert_eq!((1 as T).abs(), 1 as T);
|
||||
|
|
@ -564,7 +562,7 @@ mod tests {
|
|||
fn test_nd_qr(nd: (T,T), qr: (T,T)) {
|
||||
let (n,d) = nd;
|
||||
let separate_quot_rem = (n / d, n % d);
|
||||
let combined_quot_rem = n.quot_rem(d);
|
||||
let combined_quot_rem = n.quot_rem(&d);
|
||||
|
||||
assert_eq!(separate_quot_rem, qr);
|
||||
assert_eq!(combined_quot_rem, qr);
|
||||
|
|
@ -588,8 +586,8 @@ mod tests {
|
|||
fn test_div_mod() {
|
||||
fn test_nd_dm(nd: (T,T), dm: (T,T)) {
|
||||
let (n,d) = nd;
|
||||
let separate_div_mod = (n.div(d), n.modulo(d));
|
||||
let combined_div_mod = n.div_mod(d);
|
||||
let separate_div_mod = (n.div(&d), n.modulo(&d));
|
||||
let combined_div_mod = n.div_mod(&d);
|
||||
|
||||
assert_eq!(separate_div_mod, dm);
|
||||
assert_eq!(combined_div_mod, dm);
|
||||
|
|
@ -611,26 +609,26 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_gcd() {
|
||||
assert_eq!((10 as T).gcd(2), 2 as T);
|
||||
assert_eq!((10 as T).gcd(3), 1 as T);
|
||||
assert_eq!((0 as T).gcd(3), 3 as T);
|
||||
assert_eq!((3 as T).gcd(3), 3 as T);
|
||||
assert_eq!((56 as T).gcd(42), 14 as T);
|
||||
assert_eq!((3 as T).gcd(-3), 3 as T);
|
||||
assert_eq!((-6 as T).gcd(3), 3 as T);
|
||||
assert_eq!((-4 as T).gcd(-2), 2 as T);
|
||||
assert_eq!((10 as T).gcd(&2), 2 as T);
|
||||
assert_eq!((10 as T).gcd(&3), 1 as T);
|
||||
assert_eq!((0 as T).gcd(&3), 3 as T);
|
||||
assert_eq!((3 as T).gcd(&3), 3 as T);
|
||||
assert_eq!((56 as T).gcd(&42), 14 as T);
|
||||
assert_eq!((3 as T).gcd(&-3), 3 as T);
|
||||
assert_eq!((-6 as T).gcd(&3), 3 as T);
|
||||
assert_eq!((-4 as T).gcd(&-2), 2 as T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lcm() {
|
||||
assert_eq!((1 as T).lcm(0), 0 as T);
|
||||
assert_eq!((0 as T).lcm(1), 0 as T);
|
||||
assert_eq!((1 as T).lcm(1), 1 as T);
|
||||
assert_eq!((-1 as T).lcm(1), 1 as T);
|
||||
assert_eq!((1 as T).lcm(-1), 1 as T);
|
||||
assert_eq!((-1 as T).lcm(-1), 1 as T);
|
||||
assert_eq!((8 as T).lcm(9), 72 as T);
|
||||
assert_eq!((11 as T).lcm(5), 55 as T);
|
||||
assert_eq!((1 as T).lcm(&0), 0 as T);
|
||||
assert_eq!((0 as T).lcm(&1), 0 as T);
|
||||
assert_eq!((1 as T).lcm(&1), 1 as T);
|
||||
assert_eq!((-1 as T).lcm(&1), 1 as T);
|
||||
assert_eq!((1 as T).lcm(&-1), 1 as T);
|
||||
assert_eq!((-1 as T).lcm(&-1), 1 as T);
|
||||
assert_eq!((8 as T).lcm(&9), 72 as T);
|
||||
assert_eq!((11 as T).lcm(&5), 55 as T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@ use ops::{Add, Sub, Mul, Neg};
|
|||
use Quot = ops::Div;
|
||||
#[cfg(stage0)]
|
||||
use Rem = ops::Modulo;
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
use ops::{Add, Sub, Mul, Quot, Rem, Neg};
|
||||
use option::Option;
|
||||
use kinds::Copy;
|
||||
|
|
@ -33,30 +31,18 @@ pub trait Num: Eq + Zero + One
|
|||
+ Quot<Self,Self>
|
||||
+ Rem<Self,Self> {}
|
||||
|
||||
impl Num for u8 {}
|
||||
impl Num for u16 {}
|
||||
impl Num for u32 {}
|
||||
impl Num for u64 {}
|
||||
impl Num for uint {}
|
||||
impl Num for i8 {}
|
||||
impl Num for i16 {}
|
||||
impl Num for i32 {}
|
||||
impl Num for i64 {}
|
||||
impl Num for int {}
|
||||
impl Num for f32 {}
|
||||
impl Num for f64 {}
|
||||
impl Num for float {}
|
||||
|
||||
pub trait IntConvertible {
|
||||
fn to_int(&self) -> int;
|
||||
fn from_int(n: int) -> Self;
|
||||
}
|
||||
|
||||
pub trait Zero {
|
||||
// FIXME (#5527): These should be associated constants
|
||||
fn zero() -> Self;
|
||||
}
|
||||
|
||||
pub trait One {
|
||||
// FIXME (#5527): These should be associated constants
|
||||
fn one() -> Self;
|
||||
}
|
||||
|
||||
|
|
@ -75,35 +61,115 @@ pub fn abs<T:Ord + Zero + Neg<T>>(v: T) -> T {
|
|||
if v < Zero::zero() { v.neg() } else { v }
|
||||
}
|
||||
|
||||
pub trait Natural: Num
|
||||
pub trait Integer: Num
|
||||
+ Ord
|
||||
+ Quot<Self,Self>
|
||||
+ Rem<Self,Self> {
|
||||
fn div(&self, other: Self) -> Self;
|
||||
fn modulo(&self, other: Self) -> Self;
|
||||
fn div_mod(&self, other: Self) -> (Self,Self);
|
||||
fn quot_rem(&self, other: Self) -> (Self,Self);
|
||||
fn div(&self, other: &Self) -> Self;
|
||||
fn modulo(&self, other: &Self) -> Self;
|
||||
fn div_mod(&self, other: &Self) -> (Self,Self);
|
||||
fn quot_rem(&self, other: &Self) -> (Self,Self);
|
||||
|
||||
fn gcd(&self, other: Self) -> Self;
|
||||
fn lcm(&self, other: Self) -> Self;
|
||||
fn divisible_by(&self, other: Self) -> bool;
|
||||
fn gcd(&self, other: &Self) -> Self;
|
||||
fn lcm(&self, other: &Self) -> Self;
|
||||
fn divisible_by(&self, other: &Self) -> bool;
|
||||
fn is_even(&self) -> bool;
|
||||
fn is_odd(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait Round {
|
||||
fn round(&self, mode: RoundMode) -> Self;
|
||||
|
||||
fn floor(&self) -> Self;
|
||||
fn ceil(&self) -> Self;
|
||||
fn ceil(&self) -> Self;
|
||||
fn round(&self) -> Self;
|
||||
fn trunc(&self) -> Self;
|
||||
fn fract(&self) -> Self;
|
||||
}
|
||||
|
||||
pub enum RoundMode {
|
||||
RoundDown,
|
||||
RoundUp,
|
||||
RoundToZero,
|
||||
RoundFromZero
|
||||
pub trait Fractional: Num
|
||||
+ Ord
|
||||
+ Round
|
||||
+ Quot<Self,Self> {
|
||||
fn recip(&self) -> Self;
|
||||
}
|
||||
|
||||
pub trait Real: Signed
|
||||
+ Fractional {
|
||||
// FIXME (#5527): usages of `int` should be replaced with an associated
|
||||
// integer type once these are implemented
|
||||
|
||||
// Common Constants
|
||||
// FIXME (#5527): These should be associated constants
|
||||
fn pi() -> Self;
|
||||
fn two_pi() -> Self;
|
||||
fn frac_pi_2() -> Self;
|
||||
fn frac_pi_3() -> Self;
|
||||
fn frac_pi_4() -> Self;
|
||||
fn frac_pi_6() -> Self;
|
||||
fn frac_pi_8() -> Self;
|
||||
fn frac_1_pi() -> Self;
|
||||
fn frac_2_pi() -> Self;
|
||||
fn frac_2_sqrtpi() -> Self;
|
||||
fn sqrt2() -> Self;
|
||||
fn frac_1_sqrt2() -> Self;
|
||||
fn e() -> Self;
|
||||
fn log2_e() -> Self;
|
||||
fn log10_e() -> Self;
|
||||
fn log_2() -> Self;
|
||||
fn log_10() -> Self;
|
||||
|
||||
// Exponential functions
|
||||
fn pow(&self, n: Self) -> Self;
|
||||
fn exp(&self) -> Self;
|
||||
fn exp2(&self) -> Self;
|
||||
fn expm1(&self) -> Self;
|
||||
fn ldexp(&self, n: int) -> Self;
|
||||
fn log(&self) -> Self;
|
||||
fn log2(&self) -> Self;
|
||||
fn log10(&self) -> Self;
|
||||
fn log_radix(&self) -> Self;
|
||||
fn ilog_radix(&self) -> int;
|
||||
fn sqrt(&self) -> Self;
|
||||
fn rsqrt(&self) -> Self;
|
||||
fn cbrt(&self) -> Self;
|
||||
|
||||
// Angular conversions
|
||||
fn to_degrees(&self) -> Self;
|
||||
fn to_radians(&self) -> Self;
|
||||
|
||||
// Triganomic functions
|
||||
fn hypot(&self, other: Self) -> Self;
|
||||
fn sin(&self) -> Self;
|
||||
fn cos(&self) -> Self;
|
||||
fn tan(&self) -> Self;
|
||||
|
||||
// Inverse triganomic functions
|
||||
fn asin(&self) -> Self;
|
||||
fn acos(&self) -> Self;
|
||||
fn atan(&self) -> Self;
|
||||
fn atan2(&self, other: Self) -> Self;
|
||||
|
||||
// Hyperbolic triganomic functions
|
||||
fn sinh(&self) -> Self;
|
||||
fn cosh(&self) -> Self;
|
||||
fn tanh(&self) -> Self;
|
||||
}
|
||||
|
||||
/// Methods that are harder to implement and not commonly used.
|
||||
pub trait RealExt: Real {
|
||||
// FIXME (#5527): usages of `int` should be replaced with an associated
|
||||
// integer type once these are implemented
|
||||
|
||||
// Gamma functions
|
||||
fn lgamma(&self) -> (int, Self);
|
||||
fn tgamma(&self) -> Self;
|
||||
|
||||
// Bessel functions
|
||||
fn j0(&self) -> Self;
|
||||
fn j1(&self) -> Self;
|
||||
fn jn(&self, n: int) -> Self;
|
||||
fn y0(&self) -> Self;
|
||||
fn y1(&self) -> Self;
|
||||
fn yn(&self, n: int) -> Self;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -230,8 +296,9 @@ pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Quot<T,T>+Mul<T,T>>(
|
|||
total
|
||||
}
|
||||
|
||||
/// Helper function for testing numeric operations
|
||||
#[cfg(stage0,test)]
|
||||
fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
||||
pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
||||
assert_eq!(ten.add(&two), cast(12));
|
||||
assert_eq!(ten.sub(&two), cast(8));
|
||||
assert_eq!(ten.mul(&two), cast(20));
|
||||
|
|
@ -247,7 +314,7 @@ fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
|||
#[cfg(stage1,test)]
|
||||
#[cfg(stage2,test)]
|
||||
#[cfg(stage3,test)]
|
||||
fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
||||
pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
||||
assert_eq!(ten.add(&two), cast(12));
|
||||
assert_eq!(ten.sub(&two), cast(8));
|
||||
assert_eq!(ten.mul(&two), cast(20));
|
||||
|
|
@ -261,20 +328,6 @@ fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
|||
assert_eq!(ten.rem(&two), ten % two);
|
||||
}
|
||||
|
||||
#[test] fn test_u8_num() { test_num(10u8, 2u8) }
|
||||
#[test] fn test_u16_num() { test_num(10u16, 2u16) }
|
||||
#[test] fn test_u32_num() { test_num(10u32, 2u32) }
|
||||
#[test] fn test_u64_num() { test_num(10u64, 2u64) }
|
||||
#[test] fn test_uint_num() { test_num(10u, 2u) }
|
||||
#[test] fn test_i8_num() { test_num(10i8, 2i8) }
|
||||
#[test] fn test_i16_num() { test_num(10i16, 2i16) }
|
||||
#[test] fn test_i32_num() { test_num(10i32, 2i32) }
|
||||
#[test] fn test_i64_num() { test_num(10i64, 2i64) }
|
||||
#[test] fn test_int_num() { test_num(10i, 2i) }
|
||||
#[test] fn test_f32_num() { test_num(10f32, 2f32) }
|
||||
#[test] fn test_f64_num() { test_num(10f64, 2f64) }
|
||||
#[test] fn test_float_num() { test_num(10f, 2f) }
|
||||
|
||||
macro_rules! test_cast_20(
|
||||
($_20:expr) => ({
|
||||
let _20 = $_20;
|
||||
|
|
|
|||
|
|
@ -11,13 +11,9 @@
|
|||
use T = self::inst::T;
|
||||
use T_SIGNED = self::inst::T_SIGNED;
|
||||
|
||||
use to_str::ToStr;
|
||||
use from_str::FromStr;
|
||||
use num::{ToStrRadix, FromStrRadix};
|
||||
use num::strconv;
|
||||
use num::Unsigned;
|
||||
use num;
|
||||
use option::Option;
|
||||
use prelude::*;
|
||||
|
||||
pub use cmp::{min, max};
|
||||
|
|
@ -100,6 +96,8 @@ pub fn compl(i: T) -> T {
|
|||
max_value ^ i
|
||||
}
|
||||
|
||||
impl Num for T {}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl Ord for T {
|
||||
#[inline(always)]
|
||||
|
|
@ -153,10 +151,7 @@ impl Div<T,T> for T {
|
|||
#[inline(always)]
|
||||
fn div(&self, other: &T) -> T { *self / *other }
|
||||
}
|
||||
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Quot<T,T> for T {
|
||||
#[inline(always)]
|
||||
fn quot(&self, other: &T) -> T { *self / *other }
|
||||
|
|
@ -167,10 +162,7 @@ impl Modulo<T,T> for T {
|
|||
#[inline(always)]
|
||||
fn modulo(&self, other: &T) -> T { *self % *other }
|
||||
}
|
||||
|
||||
#[cfg(stage1,notest)]
|
||||
#[cfg(stage2,notest)]
|
||||
#[cfg(stage3,notest)]
|
||||
#[cfg(not(stage0),notest)]
|
||||
impl Rem<T,T> for T {
|
||||
#[inline(always)]
|
||||
fn rem(&self, other: &T) -> T { *self % *other }
|
||||
|
|
@ -184,32 +176,32 @@ impl Neg<T> for T {
|
|||
|
||||
impl Unsigned for T {}
|
||||
|
||||
impl Natural for T {
|
||||
impl Integer for T {
|
||||
/// Unsigned integer division. Returns the same result as `quot` (`/`).
|
||||
#[inline(always)]
|
||||
fn div(&self, other: T) -> T { *self / other }
|
||||
fn div(&self, other: &T) -> T { *self / *other }
|
||||
|
||||
/// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
|
||||
#[inline(always)]
|
||||
fn modulo(&self, other: T) -> T { *self / other }
|
||||
fn modulo(&self, other: &T) -> T { *self / *other }
|
||||
|
||||
/// Calculates `div` and `modulo` simultaneously
|
||||
#[inline(always)]
|
||||
fn div_mod(&self, other: T) -> (T,T) {
|
||||
(*self / other, *self % other)
|
||||
fn div_mod(&self, other: &T) -> (T,T) {
|
||||
(*self / *other, *self % *other)
|
||||
}
|
||||
|
||||
/// Calculates `quot` (`\`) and `rem` (`%`) simultaneously
|
||||
#[inline(always)]
|
||||
fn quot_rem(&self, other: T) -> (T,T) {
|
||||
(*self / other, *self % other)
|
||||
fn quot_rem(&self, other: &T) -> (T,T) {
|
||||
(*self / *other, *self % *other)
|
||||
}
|
||||
|
||||
/// Calculates the Greatest Common Divisor (GCD) of the number and `other`
|
||||
#[inline(always)]
|
||||
fn gcd(&self, other: T) -> T {
|
||||
fn gcd(&self, other: &T) -> T {
|
||||
// Use Euclid's algorithm
|
||||
let mut m = *self, n = other;
|
||||
let mut m = *self, n = *other;
|
||||
while m != 0 {
|
||||
let temp = m;
|
||||
m = n % temp;
|
||||
|
|
@ -220,17 +212,17 @@ impl Natural for T {
|
|||
|
||||
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`
|
||||
#[inline(always)]
|
||||
fn lcm(&self, other: T) -> T {
|
||||
(*self * other) / self.gcd(other)
|
||||
fn lcm(&self, other: &T) -> T {
|
||||
(*self * *other) / self.gcd(other)
|
||||
}
|
||||
|
||||
/// Returns `true` if the number can be divided by `other` without leaving a remainder
|
||||
#[inline(always)]
|
||||
fn divisible_by(&self, other: T) -> bool { *self % other == 0 }
|
||||
fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 }
|
||||
|
||||
/// Returns `true` if the number is divisible by `2`
|
||||
#[inline(always)]
|
||||
fn is_even(&self) -> bool { self.divisible_by(2) }
|
||||
fn is_even(&self) -> bool { self.divisible_by(&2) }
|
||||
|
||||
/// Returns `true` if the number is not divisible by `2`
|
||||
#[inline(always)]
|
||||
|
|
@ -356,23 +348,28 @@ mod tests {
|
|||
use super::inst::T;
|
||||
use prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10 as T, 2 as T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gcd() {
|
||||
assert_eq!((10 as T).gcd(2), 2 as T);
|
||||
assert_eq!((10 as T).gcd(3), 1 as T);
|
||||
assert_eq!((0 as T).gcd(3), 3 as T);
|
||||
assert_eq!((3 as T).gcd(3), 3 as T);
|
||||
assert_eq!((56 as T).gcd(42), 14 as T);
|
||||
assert_eq!((10 as T).gcd(&2), 2 as T);
|
||||
assert_eq!((10 as T).gcd(&3), 1 as T);
|
||||
assert_eq!((0 as T).gcd(&3), 3 as T);
|
||||
assert_eq!((3 as T).gcd(&3), 3 as T);
|
||||
assert_eq!((56 as T).gcd(&42), 14 as T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lcm() {
|
||||
assert_eq!((1 as T).lcm(0), 0 as T);
|
||||
assert_eq!((0 as T).lcm(1), 0 as T);
|
||||
assert_eq!((1 as T).lcm(1), 1 as T);
|
||||
assert_eq!((8 as T).lcm(9), 72 as T);
|
||||
assert_eq!((11 as T).lcm(5), 55 as T);
|
||||
assert_eq!((99 as T).lcm(17), 1683 as T);
|
||||
assert_eq!((1 as T).lcm(&0), 0 as T);
|
||||
assert_eq!((0 as T).lcm(&1), 0 as T);
|
||||
assert_eq!((1 as T).lcm(&1), 1 as T);
|
||||
assert_eq!((8 as T).lcm(&9), 72 as T);
|
||||
assert_eq!((11 as T).lcm(&5), 55 as T);
|
||||
assert_eq!((99 as T).lcm(&17), 1683 as T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ pub trait Div<RHS,Result> {
|
|||
fn div(&self, rhs: &RHS) -> Result;
|
||||
}
|
||||
#[lang="quot"]
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
pub trait Quot<RHS,Result> {
|
||||
fn quot(&self, rhs: &RHS) -> Result;
|
||||
}
|
||||
|
|
@ -49,9 +47,7 @@ pub trait Modulo<RHS,Result> {
|
|||
fn modulo(&self, rhs: &RHS) -> Result;
|
||||
}
|
||||
#[lang="rem"]
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
pub trait Rem<RHS,Result> {
|
||||
fn rem(&self, rhs: &RHS) -> Result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@ pub use either::{Either, Left, Right};
|
|||
pub use kinds::{Const, Copy, Owned, Durable};
|
||||
#[cfg(stage0)]
|
||||
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
pub use ops::{Add, Sub, Mul, Quot, Rem, Neg, Not};
|
||||
pub use ops::{BitAnd, BitOr, BitXor};
|
||||
pub use ops::{Drop};
|
||||
|
|
@ -39,7 +37,9 @@ pub use hash::Hash;
|
|||
pub use iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter};
|
||||
pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter};
|
||||
pub use iter::{Times, ExtendedMutableIter};
|
||||
pub use num::{Num, Signed, Unsigned, Natural, NumCast};
|
||||
pub use num::{Num, NumCast};
|
||||
pub use num::{Signed, Unsigned, Integer};
|
||||
pub use num::{Round, Fractional, Real, RealExt};
|
||||
pub use path::GenericPath;
|
||||
pub use path::Path;
|
||||
pub use path::PosixPath;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ pub trait FromBase64 {
|
|||
impl FromBase64 for ~[u8] {
|
||||
/**
|
||||
* Convert base64 `u8` vector into u8 byte values.
|
||||
* Every 4 encoded characters is converted into 3 octets, rem padding.
|
||||
* Every 4 encoded characters is converted into 3 octets, modulo padding.
|
||||
*
|
||||
* *Example*:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -204,20 +204,6 @@ impl<T: Copy + Num + Ord>
|
|||
/* Utils */
|
||||
impl<T: Copy + Num + Ord>
|
||||
Round for Ratio<T> {
|
||||
fn round(&self, mode: num::RoundMode) -> Ratio<T> {
|
||||
match mode {
|
||||
num::RoundUp => { self.ceil() }
|
||||
num::RoundDown => { self.floor()}
|
||||
num::RoundToZero => { Ratio::from_integer(self.numer / self.denom) }
|
||||
num::RoundFromZero => {
|
||||
if *self < Zero::zero() {
|
||||
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
||||
} else {
|
||||
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn floor(&self) -> Ratio<T> {
|
||||
if *self < Zero::zero() {
|
||||
|
|
@ -226,6 +212,7 @@ impl<T: Copy + Num + Ord>
|
|||
Ratio::from_integer(self.numer / self.denom)
|
||||
}
|
||||
}
|
||||
|
||||
fn ceil(&self) -> Ratio<T> {
|
||||
if *self < Zero::zero() {
|
||||
Ratio::from_integer(self.numer / self.denom)
|
||||
|
|
@ -233,6 +220,21 @@ impl<T: Copy + Num + Ord>
|
|||
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn round(&self) -> Ratio<T> {
|
||||
if *self < Zero::zero() {
|
||||
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
||||
} else {
|
||||
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn trunc(&self) -> Ratio<T> {
|
||||
Ratio::from_integer(self.numer / self.denom)
|
||||
}
|
||||
|
||||
fn fract(&self) -> Ratio<T> {
|
||||
Ratio::new_raw(self.numer % self.denom, self.denom)
|
||||
}
|
||||
|
|
@ -421,18 +423,18 @@ mod test {
|
|||
fn test_round() {
|
||||
assert_eq!(_1_2.ceil(), _1);
|
||||
assert_eq!(_1_2.floor(), _0);
|
||||
assert_eq!(_1_2.round(num::RoundToZero), _0);
|
||||
assert_eq!(_1_2.round(num::RoundFromZero), _1);
|
||||
assert_eq!(_1_2.round(), _1);
|
||||
assert_eq!(_1_2.trunc(), _0);
|
||||
|
||||
assert_eq!(_neg1_2.ceil(), _0);
|
||||
assert_eq!(_neg1_2.floor(), -_1);
|
||||
assert_eq!(_neg1_2.round(num::RoundToZero), _0);
|
||||
assert_eq!(_neg1_2.round(num::RoundFromZero), -_1);
|
||||
assert_eq!(_neg1_2.round(), -_1);
|
||||
assert_eq!(_neg1_2.trunc(), _0);
|
||||
|
||||
assert_eq!(_1.ceil(), _1);
|
||||
assert_eq!(_1.floor(), _1);
|
||||
assert_eq!(_1.round(num::RoundToZero), _1);
|
||||
assert_eq!(_1.round(num::RoundFromZero), _1);
|
||||
assert_eq!(_1.round(), _1);
|
||||
assert_eq!(_1.trunc(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -76,9 +76,7 @@ pub mod rope;
|
|||
pub mod smallintmap;
|
||||
pub mod sort;
|
||||
pub mod dlist;
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
pub mod treemap;
|
||||
|
||||
// And ... other stuff
|
||||
|
|
@ -98,19 +96,13 @@ pub mod cmp;
|
|||
pub mod base64;
|
||||
pub mod rl;
|
||||
pub mod workcache;
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
#[path="num/bigint.rs"]
|
||||
pub mod bigint;
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
#[path="num/rational.rs"]
|
||||
pub mod rational;
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
#[cfg(not(stage0))]
|
||||
#[path="num/complex.rs"]
|
||||
pub mod complex;
|
||||
pub mod stats;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue