about summary refs log tree commit diff
path: root/src/libstd/num
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-25 11:36:36 -0700
committerbors <bors@rust-lang.org>2013-04-25 11:36:36 -0700
commitac69ee418b495a25ff5019d2fd08ff97a4cb34e3 (patch)
treedaafa5bc9ec9ac2211afecdf388758bca14352de /src/libstd/num
parent1d53babd2f23439975518fda94d9122b15e779c9 (diff)
parent225ac216157cf530332cef1c926875e2023e48e6 (diff)
downloadrust-ac69ee418b495a25ff5019d2fd08ff97a4cb34e3.tar.gz
rust-ac69ee418b495a25ff5019d2fd08ff97a4cb34e3.zip
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.
Diffstat (limited to 'src/libstd/num')
-rw-r--r--src/libstd/num/rational.rs42
1 files changed, 22 insertions, 20 deletions
diff --git a/src/libstd/num/rational.rs b/src/libstd/num/rational.rs
index 36652380bff..8af1d99fa47 100644
--- a/src/libstd/num/rational.rs
+++ b/src/libstd/num/rational.rs
@@ -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]