about summary refs log tree commit diff
path: root/src/libcore/num/float.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/num/float.rs')
-rw-r--r--src/libcore/num/float.rs249
1 files changed, 223 insertions, 26 deletions
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index 88321e6b8bf..ae2d0ce0d71 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -403,37 +403,206 @@ impl num::One for float {
     fn one() -> float { 1.0 }
 }
 
-impl num::Round for float {
-    #[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
-        }
-    }
+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 floor(&self) -> float { f64::floor(*self as f64) as float}
+    fn pi() -> float { 3.14159265358979323846264338327950288 }
+
+    /// 2.0 * pi
     #[inline(always)]
-    fn ceil(&self) -> float { f64::ceil(*self as f64) as float}
+    fn two_pi() -> float { 6.28318530717958647692528676655900576 }
+
+    /// pi / 2.0
     #[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 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 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)]
+    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 tgamma(&self) -> float { tgamma(*self as f64) as float }
+
+    #[inline(always)]
+    fn j0(&self) -> float { j0(*self as f64) as float }
+
+    #[inline(always)]
+    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)]
@@ -511,12 +680,40 @@ 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_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);
         assert_eq!(1f.abs(), 1f);