about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/core.rc2
-rw-r--r--src/libcore/num/f32.rs114
-rw-r--r--src/libcore/num/f64.rs117
-rw-r--r--src/libcore/num/float.rs123
-rw-r--r--src/libcore/num/num.rs16
-rw-r--r--src/libcore/prelude.rs2
6 files changed, 307 insertions, 67 deletions
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 0a24fba6663..71bbaf557ce 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -105,7 +105,7 @@ pub use iter::{ExtendedMutableIter};
 
 pub use num::{Num, NumCast};
 pub use num::{Signed, Unsigned, Integer};
-pub use num::{Fractional, Real, RealExt};
+pub use num::{Round, Fractional, Real, RealExt};
 pub use ptr::Ptr;
 pub use to_str::ToStr;
 pub use clone::Clone;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 57ac6c55176..7d5807ba546 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -327,6 +327,34 @@ impl Signed for f32 {
     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
 }
 
+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 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)]
@@ -403,22 +431,6 @@ impl Real for f32 {
     fn log_10() -> f32 { 2.30258509299404568401799145468436421 }
 
     #[inline(always)]
-    fn floor(&self) -> f32 { floor(*self) }
-
-    #[inline(always)]
-    fn ceil(&self) -> f32 { ceil(*self) }
-
-    #[inline(always)]
-    fn round(&self) -> f32 { round(*self) }
-
-    #[inline(always)]
-    fn trunc(&self) -> f32 { trunc(*self) }
-
-    /// The fractional part of the number, calculated using: `n - floor(n)`
-    #[inline(always)]
-    fn fract(&self) -> f32 { *self - self.floor() }
-
-    #[inline(always)]
     fn pow(&self, n: f32) -> f32 { pow(*self, n) }
 
     #[inline(always)]
@@ -737,6 +749,76 @@ mod tests {
     }
 
     #[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);
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 53ad78c29f3..3b6198bfc47 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -337,6 +337,34 @@ impl Signed for f64 {
     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
 }
 
+impl Round for f64 {
+    /// Round half-way cases toward `neg_infinity`
+    #[inline(always)]
+    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)]
@@ -413,22 +441,6 @@ impl Real for f64 {
     fn log_10() -> f64 { 2.30258509299404568401799145468436421 }
 
     #[inline(always)]
-    fn floor(&self) -> f64 { floor(*self) }
-
-    #[inline(always)]
-    fn ceil(&self) -> f64 { ceil(*self) }
-
-    #[inline(always)]
-    fn round(&self) -> f64 { round(*self) }
-
-    #[inline(always)]
-    fn trunc(&self) -> f64 { trunc(*self) }
-
-    /// The fractional part of the number, calculated using: `n - floor(n)`
-    #[inline(always)]
-    fn fract(&self) -> f64 { *self - self.floor() }
-
-    #[inline(always)]
     fn pow(&self, n: f64) -> f64 { pow(*self, n) }
 
     #[inline(always)]
@@ -766,7 +778,8 @@ mod tests {
         ($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));
+                fail!(fmt!("The values were not approximately equal. \
+                            Found: %? and expected %?", a, b));
             }
         })
     )
@@ -777,6 +790,76 @@ mod tests {
     }
 
     #[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);
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index ae2d0ce0d71..9c0412b422f 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -403,6 +403,34 @@ impl num::One for float {
     fn one() -> float { 1.0 }
 }
 
+impl Round for float {
+    /// Round half-way cases toward `neg_infinity`
+    #[inline(always)]
+    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)]
@@ -479,22 +507,6 @@ impl Real for float {
     fn log_10() -> float { 2.30258509299404568401799145468436421 }
 
     #[inline(always)]
-    fn floor(&self) -> float { floor(*self as f64) as float }
-
-    #[inline(always)]
-    fn ceil(&self) -> float { ceil(*self as f64) as float }
-
-    #[inline(always)]
-    fn round(&self) -> float { round(*self as f64) as float }
-
-    #[inline(always)]
-    fn trunc(&self) -> float { trunc(*self as f64) as float }
-
-    /// The fractional part of the number, calculated using: `n - floor(n)`
-    #[inline(always)]
-    fn fract(&self) -> float { *self - self.floor() }
-
-    #[inline(always)]
     fn pow(&self, n: float) -> float { pow(*self as f64, n as f64) as float }
 
     #[inline(always)]
@@ -695,6 +707,76 @@ mod tests {
     }
 
     #[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);
@@ -893,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);
-    }
 }
 
 //
diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs
index 733b37e2a4a..e19afdc69c3 100644
--- a/src/libcore/num/num.rs
+++ b/src/libcore/num/num.rs
@@ -77,8 +77,17 @@ pub trait Integer: Num
     fn is_odd(&self) -> bool;
 }
 
+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;
 }
@@ -108,13 +117,6 @@ pub trait Real: Signed
     fn log_2() -> Self;
     fn log_10() -> Self;
 
-    // Rounding operations
-    fn floor(&self) -> Self;
-    fn ceil(&self) -> Self;
-    fn round(&self) -> Self;
-    fn trunc(&self) -> Self;
-    fn fract(&self) -> Self;
-
     // Exponential functions
     fn pow(&self, n: Self) -> Self;
     fn exp(&self) -> Self;
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index c161bd4cf59..553bb826810 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -39,7 +39,7 @@ pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter};
 pub use iter::{Times, ExtendedMutableIter};
 pub use num::{Num, NumCast};
 pub use num::{Signed, Unsigned, Integer};
-pub use num::{Fractional, Real, RealExt};
+pub use num::{Round, Fractional, Real, RealExt};
 pub use path::GenericPath;
 pub use path::Path;
 pub use path::PosixPath;