]> git.lizzy.rs Git - rust.git/commitdiff
Move std::num::Integer to libnum
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>
Sun, 16 Feb 2014 20:20:01 +0000 (07:20 +1100)
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>
Fri, 21 Feb 2014 14:45:29 +0000 (01:45 +1100)
12 files changed:
src/etc/vim/syntax/rust.vim
src/libnum/bigint.rs
src/libnum/lib.rs
src/libnum/rational.rs
src/libstd/iter.rs
src/libstd/num/int_macros.rs
src/libstd/num/mod.rs
src/libstd/num/strconv.rs
src/libstd/num/uint_macros.rs
src/libstd/prelude.rs
src/libstd/vec.rs
src/test/bench/shootout-pidigits.rs

index 511e0c9f74cc35be5a132f6fa8ab3a4c9fb99533..d17f8fc2d877e6f149bb3bf026b5c8de9b309af9 100644 (file)
@@ -85,7 +85,7 @@ syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator Cloneabl
 syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
 
 syn keyword rustTrait Algebraic Trigonometric Exponential Hyperbolic
-syn keyword rustTrait Bitwise Bounded Integer
+syn keyword rustTrait Bitwise Bounded Fractional
 syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv
 syn keyword rustTrait Orderable Signed Unsigned Round
 syn keyword rustTrait Primitive Int Float ToStrRadix ToPrimitive FromPrimitive
index 21726d28e0ca2921f9a7e1dc6d413c6fd9cee978..0418c61d361b4d7ff3c6f12d0d732f843405e0a5 100644 (file)
@@ -16,6 +16,8 @@
 A `BigInt` is a combination of `BigUint` and `Sign`.
 */
 
+use Integer;
+
 use std::cmp;
 use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
 use std::num::{Zero, One, ToStrRadix, FromStrRadix};
@@ -461,7 +463,7 @@ fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other))
 
     /// Returns `true` if the number can be divided by `other` without leaving a remainder
     #[inline]
-    fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
+    fn divides(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
 
     /// Returns `true` if the number is divisible by `2`
     #[inline]
@@ -1118,7 +1120,7 @@ fn lcm(&self, other: &BigInt) -> BigInt {
 
     /// Returns `true` if the number can be divided by `other` without leaving a remainder
     #[inline]
-    fn is_multiple_of(&self, other: &BigInt) -> bool { self.data.is_multiple_of(&other.data) }
+    fn divides(&self, other: &BigInt) -> bool { self.data.divides(&other.data) }
 
     /// Returns `true` if the number is divisible by `2`
     #[inline]
@@ -1388,6 +1390,7 @@ pub fn to_biguint(&self) -> Option<BigUint> {
 
 #[cfg(test)]
 mod biguint_tests {
+    use Integer;
     use super::{BigDigit, BigUint, ToBigUint};
     use super::{Plus, BigInt, RandBigInt, ToBigInt};
 
@@ -2045,6 +2048,7 @@ fn test_negative_rand_range() {
 
 #[cfg(test)]
 mod bigint_tests {
+    use Integer;
     use super::{BigDigit, BigUint, ToBigUint};
     use super::{Sign, Minus, Zero, Plus, BigInt, RandBigInt, ToBigInt};
 
index 8d5338451bd93bbcd708dc7f6ac5cb8bba45b975..e9e93cc29d6fe2906ea8b05b67ece030b12dceae 100644 (file)
 pub mod bigint;
 pub mod rational;
 pub mod complex;
+
+pub trait Integer: Num + Ord
+                 + Div<Self, Self>
+                 + Rem<Self, Self> {
+    /// Simultaneous truncated integer division and modulus
+    #[inline]
+    fn div_rem(&self, other: &Self) -> (Self, Self) {
+        (*self / *other, *self % *other)
+    }
+
+    /// Floored integer division
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert!(( 8i).div_floor(& 3) ==  2);
+    /// assert!(( 8i).div_floor(&-3) == -3);
+    /// assert!((-8i).div_floor(& 3) == -3);
+    /// assert!((-8i).div_floor(&-3) ==  2);
+    ///
+    /// assert!(( 1i).div_floor(& 2) ==  0);
+    /// assert!(( 1i).div_floor(&-2) == -1);
+    /// assert!((-1i).div_floor(& 2) == -1);
+    /// assert!((-1i).div_floor(&-2) ==  0);
+    /// ~~~
+    fn div_floor(&self, other: &Self) -> Self;
+
+    /// Floored integer modulo, satisfying:
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// # let n = 1i; let d = 1i;
+    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
+    /// ~~~
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert!(( 8i).mod_floor(& 3) ==  2);
+    /// assert!(( 8i).mod_floor(&-3) == -1);
+    /// assert!((-8i).mod_floor(& 3) ==  1);
+    /// assert!((-8i).mod_floor(&-3) == -2);
+    ///
+    /// assert!(( 1i).mod_floor(& 2) ==  1);
+    /// assert!(( 1i).mod_floor(&-2) == -1);
+    /// assert!((-1i).mod_floor(& 2) ==  1);
+    /// assert!((-1i).mod_floor(&-2) == -1);
+    /// ~~~
+    fn mod_floor(&self, other: &Self) -> Self;
+
+    /// Simultaneous floored integer division and modulus
+    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
+        (self.div_floor(other), self.mod_floor(other))
+    }
+
+    /// Greatest Common Divisor (GCD)
+    fn gcd(&self, other: &Self) -> Self;
+
+    /// Lowest Common Multiple (LCM)
+    fn lcm(&self, other: &Self) -> Self;
+
+    /// Returns `true` if `other` divides evenly into `self`
+    fn divides(&self, other: &Self) -> bool;
+
+    /// Returns `true` if the number is even
+    fn is_even(&self) -> bool;
+
+    /// Returns `true` if the number is odd
+    fn is_odd(&self) -> bool;
+}
+
+/// Simultaneous integer division and modulus
+#[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
+/// Floored integer division
+#[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
+/// Floored integer modulus
+#[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
+/// Simultaneous floored integer division and modulus
+#[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
+
+/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
+/// result is always positive.
+#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
+/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
+#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
+
+macro_rules! impl_integer_for_int {
+    ($T:ty, $test_mod:ident) => (
+        impl Integer for $T {
+            /// Floored integer division
+            #[inline]
+            fn div_floor(&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.div_rem(other) {
+                    (d, r) if (r > 0 && *other < 0)
+                           || (r < 0 && *other > 0) => d - 1,
+                    (d, _)                          => d,
+                }
+            }
+
+            /// Floored integer modulo
+            #[inline]
+            fn mod_floor(&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,
+                }
+            }
+
+            /// Calculates `div_floor` and `mod_floor` simultaneously
+            #[inline]
+            fn div_mod_floor(&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.div_rem(other) {
+                    (d, r) if (r > 0 && *other < 0)
+                           || (r < 0 && *other > 0) => (d - 1, r + *other),
+                    (d, r)                          => (d, r),
+                }
+            }
+
+            /// Calculates the Greatest Common Divisor (GCD) of the number and
+            /// `other`. The result is always positive.
+            #[inline]
+            fn gcd(&self, other: &$T) -> $T {
+                // Use Euclid's algorithm
+                let mut m = *self;
+                let mut n = *other;
+                while m != 0 {
+                    let temp = m;
+                    m = n % temp;
+                    n = temp;
+                }
+                n.abs()
+            }
+
+            /// Calculates the Lowest Common Multiple (LCM) of the number and
+            /// `other`.
+            #[inline]
+            fn lcm(&self, other: &$T) -> $T {
+                // should not have to recaluculate abs
+                ((*self * *other) / self.gcd(other)).abs()
+            }
+
+            /// Returns `true` if the number can be divided by `other` without
+            /// leaving a remainder
+            #[inline]
+            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
+
+            /// Returns `true` if the number is divisible by `2`
+            #[inline]
+            fn is_even(&self) -> bool { self & 1 == 0 }
+
+            /// Returns `true` if the number is not divisible by `2`
+            #[inline]
+            fn is_odd(&self) -> bool { !self.is_even() }
+        }
+
+        #[cfg(test)]
+        mod $test_mod {
+            use Integer;
+
+            /// Checks that the division rule holds for:
+            ///
+            /// - `n`: numerator (dividend)
+            /// - `d`: denominator (divisor)
+            /// - `qr`: quotient and remainder
+            #[cfg(test)]
+            fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
+                assert_eq!(d * q + r, n);
+            }
+
+            #[test]
+            fn test_div_rem() {
+                fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
+                    let (n,d) = nd;
+                    let separate_div_rem = (n / d, n % d);
+                    let combined_div_rem = n.div_rem(&d);
+
+                    assert_eq!(separate_div_rem, qr);
+                    assert_eq!(combined_div_rem, qr);
+
+                    test_division_rule(nd, separate_div_rem);
+                    test_division_rule(nd, combined_div_rem);
+                }
+
+                test_nd_dr(( 8,  3), ( 2,  2));
+                test_nd_dr(( 8, -3), (-2,  2));
+                test_nd_dr((-8,  3), (-2, -2));
+                test_nd_dr((-8, -3), ( 2, -2));
+
+                test_nd_dr(( 1,  2), ( 0,  1));
+                test_nd_dr(( 1, -2), ( 0,  1));
+                test_nd_dr((-1,  2), ( 0, -1));
+                test_nd_dr((-1, -2), ( 0, -1));
+            }
+
+            #[test]
+            fn test_div_mod_floor() {
+                fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
+                    let (n,d) = nd;
+                    let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
+                    let combined_div_mod_floor = n.div_mod_floor(&d);
+
+                    assert_eq!(separate_div_mod_floor, dm);
+                    assert_eq!(combined_div_mod_floor, dm);
+
+                    test_division_rule(nd, separate_div_mod_floor);
+                    test_division_rule(nd, combined_div_mod_floor);
+                }
+
+                test_nd_dm(( 8,  3), ( 2,  2));
+                test_nd_dm(( 8, -3), (-3, -1));
+                test_nd_dm((-8,  3), (-3,  1));
+                test_nd_dm((-8, -3), ( 2, -2));
+
+                test_nd_dm(( 1,  2), ( 0,  1));
+                test_nd_dm(( 1, -2), (-1, -1));
+                test_nd_dm((-1,  2), (-1,  1));
+                test_nd_dm((-1, -2), ( 0, -1));
+            }
+
+            #[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);
+            }
+
+            #[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);
+            }
+
+            #[test]
+            fn test_even() {
+                assert_eq!((-4 as $T).is_even(), true);
+                assert_eq!((-3 as $T).is_even(), false);
+                assert_eq!((-2 as $T).is_even(), true);
+                assert_eq!((-1 as $T).is_even(), false);
+                assert_eq!((0 as $T).is_even(), true);
+                assert_eq!((1 as $T).is_even(), false);
+                assert_eq!((2 as $T).is_even(), true);
+                assert_eq!((3 as $T).is_even(), false);
+                assert_eq!((4 as $T).is_even(), true);
+            }
+
+            #[test]
+            fn test_odd() {
+                assert_eq!((-4 as $T).is_odd(), false);
+                assert_eq!((-3 as $T).is_odd(), true);
+                assert_eq!((-2 as $T).is_odd(), false);
+                assert_eq!((-1 as $T).is_odd(), true);
+                assert_eq!((0 as $T).is_odd(), false);
+                assert_eq!((1 as $T).is_odd(), true);
+                assert_eq!((2 as $T).is_odd(), false);
+                assert_eq!((3 as $T).is_odd(), true);
+                assert_eq!((4 as $T).is_odd(), false);
+            }
+        }
+    )
+}
+
+impl_integer_for_int!(i8,   test_integer_i8)
+impl_integer_for_int!(i16,  test_integer_i16)
+impl_integer_for_int!(i32,  test_integer_i32)
+impl_integer_for_int!(i64,  test_integer_i64)
+impl_integer_for_int!(int,  test_integer_int)
+
+macro_rules! impl_integer_for_uint {
+    ($T:ty, $test_mod:ident) => (
+        impl Integer for $T {
+            /// Unsigned integer division. Returns the same result as `div` (`/`).
+            #[inline]
+            fn div_floor(&self, other: &$T) -> $T { *self / *other }
+
+            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
+            #[inline]
+            fn mod_floor(&self, other: &$T) -> $T { *self % *other }
+
+            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
+            #[inline]
+            fn gcd(&self, other: &$T) -> $T {
+                // Use Euclid's algorithm
+                let mut m = *self;
+                let mut n = *other;
+                while m != 0 {
+                    let temp = m;
+                    m = n % temp;
+                    n = temp;
+                }
+                n
+            }
+
+            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
+            #[inline]
+            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]
+            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
+
+            /// Returns `true` if the number is divisible by `2`
+            #[inline]
+            fn is_even(&self) -> bool { self & 1 == 0 }
+
+            /// Returns `true` if the number is not divisible by `2`
+            #[inline]
+            fn is_odd(&self) -> bool { !self.is_even() }
+        }
+
+        #[cfg(test)]
+        mod $test_mod {
+            use Integer;
+
+            #[test]
+            fn test_div_mod_floor() {
+                assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
+                assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
+                assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
+                assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
+                assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
+                assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
+                assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
+                assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
+                assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 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);
+            }
+
+            #[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);
+            }
+
+            #[test]
+            fn test_divides() {
+                assert!((6 as $T).divides(&(6 as $T)));
+                assert!((6 as $T).divides(&(3 as $T)));
+                assert!((6 as $T).divides(&(1 as $T)));
+            }
+
+            #[test]
+            fn test_even() {
+                assert_eq!((0 as $T).is_even(), true);
+                assert_eq!((1 as $T).is_even(), false);
+                assert_eq!((2 as $T).is_even(), true);
+                assert_eq!((3 as $T).is_even(), false);
+                assert_eq!((4 as $T).is_even(), true);
+            }
+
+            #[test]
+            fn test_odd() {
+                assert_eq!((0 as $T).is_odd(), false);
+                assert_eq!((1 as $T).is_odd(), true);
+                assert_eq!((2 as $T).is_odd(), false);
+                assert_eq!((3 as $T).is_odd(), true);
+                assert_eq!((4 as $T).is_odd(), false);
+            }
+        }
+    )
+}
+
+impl_integer_for_uint!(u8,   test_integer_u8)
+impl_integer_for_uint!(u16,  test_integer_u16)
+impl_integer_for_uint!(u32,  test_integer_u32)
+impl_integer_for_uint!(u64,  test_integer_u64)
+impl_integer_for_uint!(uint, test_integer_uint)
index a483946322f804a89104aff53a356c249cd8dc5a..5f1868b48c5196e1d832794434b0c4d628972e50 100644 (file)
@@ -10,6 +10,8 @@
 
 //! Rational numbers
 
+use Integer;
+
 use std::cmp;
 use std::from_str::FromStr;
 use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
index 7516a3ddf543eb1a802e3d5f10d7e603aff647a6..5e919e4ac0a4d66ee931fe5d038ace4cd9b20fd6 100644 (file)
@@ -65,7 +65,7 @@ trait defined in this module. For loops can be viewed as a syntactical expansion
 */
 
 use cmp;
-use num::{Zero, One, Integer, CheckedAdd, CheckedSub, Saturating, ToPrimitive};
+use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int};
 use option::{Option, Some, None};
 use ops::{Add, Mul, Sub};
 use cmp::{Eq, Ord};
@@ -2005,9 +2005,9 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-/// `Integer` is required to ensure the range will be the same regardless of
+/// `Int` is required to ensure the range will be the same regardless of
 /// the direction it is consumed.
-impl<A: Integer + Ord + Clone + ToPrimitive> DoubleEndedIterator<A> for Range<A> {
+impl<A: Int + Ord + Clone + ToPrimitive> DoubleEndedIterator<A> for Range<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         if self.stop > self.state {
@@ -2065,7 +2065,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-impl<A: Sub<A, A> + Integer + Ord + Clone + ToPrimitive> DoubleEndedIterator<A>
+impl<A: Sub<A, A> + Int + Ord + Clone + ToPrimitive> DoubleEndedIterator<A>
     for RangeInclusive<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
@@ -2381,7 +2381,7 @@ fn test_iterator_chain() {
     #[test]
     fn test_filter_map() {
         let mut it = count(0u, 1u).take(10)
-            .filter_map(|x| if x.is_even() { Some(x*x) } else { None });
+            .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
         assert_eq!(it.collect::<~[uint]>(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
     }
 
@@ -2648,7 +2648,7 @@ fn test_collect() {
     fn test_all() {
         let v: ~&[int] = ~&[1, 2, 3, 4, 5];
         assert!(v.iter().all(|&x| x < 10));
-        assert!(!v.iter().all(|&x| x.is_even()));
+        assert!(!v.iter().all(|&x| x % 2 == 0));
         assert!(!v.iter().all(|&x| x > 100));
         assert!(v.slice(0, 0).iter().all(|_| fail!()));
     }
@@ -2657,7 +2657,7 @@ fn test_all() {
     fn test_any() {
         let v: ~&[int] = ~&[1, 2, 3, 4, 5];
         assert!(v.iter().any(|&x| x < 10));
-        assert!(v.iter().any(|&x| x.is_even()));
+        assert!(v.iter().any(|&x| x % 2 == 0));
         assert!(!v.iter().any(|&x| x > 100));
         assert!(!v.slice(0, 0).iter().any(|_| fail!()));
     }
index 3ecc6f32017ea77b727c1c847ce62b2054394828..7f45b5deb187c03e03f8fc48e4afcdf31a665b63 100644 (file)
@@ -91,53 +91,48 @@ fn mul(&self, other: &$T) -> $T { *self * *other }
 
 #[cfg(not(test))]
 impl Div<$T,$T> for $T {
-    ///
-    /// Integer division, truncated towards 0. As this behaviour reflects the underlying
-    /// machine implementation it is more efficient than `Integer::div_floor`.
+    /// Integer division, truncated towards 0.
     ///
     /// # Examples
     ///
-    /// ```
+    /// ~~~
     /// assert!( 8 /  3 ==  2);
     /// assert!( 8 / -3 == -2);
     /// assert!(-8 /  3 == -2);
     /// assert!(-8 / -3 ==  2);
-
+    ///
     /// assert!( 1 /  2 ==  0);
     /// assert!( 1 / -2 ==  0);
     /// assert!(-1 /  2 ==  0);
     /// assert!(-1 / -2 ==  0);
-    /// ```
-    ///
+    /// ~~~
     #[inline]
     fn div(&self, other: &$T) -> $T { *self / *other }
 }
 
 #[cfg(not(test))]
 impl Rem<$T,$T> for $T {
-    ///
     /// Returns the integer remainder after division, satisfying:
     ///
-    /// ```
+    /// ~~~
     /// # let n = 1;
     /// # let d = 2;
     /// assert!((n / d) * d + (n % d) == n)
-    /// ```
+    /// ~~~
     ///
     /// # Examples
     ///
-    /// ```
+    /// ~~~
     /// assert!( 8 %  3 ==  2);
     /// assert!( 8 % -3 ==  2);
     /// assert!(-8 %  3 == -2);
     /// assert!(-8 % -3 == -2);
-
+    ///
     /// assert!( 1 %  2 ==  1);
     /// assert!( 1 % -2 ==  1);
     /// assert!(-1 %  2 == -1);
     /// assert!(-1 % -2 == -1);
-    /// ```
-    ///
+    /// ~~~
     #[inline]
     fn rem(&self, other: &$T) -> $T { *self % *other }
 }
@@ -189,125 +184,6 @@ fn is_positive(&self) -> bool { *self > 0 }
     fn is_negative(&self) -> bool { *self < 0 }
 }
 
-impl Integer for $T {
-    ///
-    /// Floored integer division
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// assert!(( 8i).div_floor(& 3) ==  2);
-    /// assert!(( 8i).div_floor(&-3) == -3);
-    /// assert!((-8i).div_floor(& 3) == -3);
-    /// assert!((-8i).div_floor(&-3) ==  2);
-    ///
-    /// assert!(( 1i).div_floor(& 2) ==  0);
-    /// assert!(( 1i).div_floor(&-2) == -1);
-    /// assert!((-1i).div_floor(& 2) == -1);
-    /// assert!((-1i).div_floor(&-2) ==  0);
-    /// ```
-    ///
-    #[inline]
-    fn div_floor(&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.div_rem(other) {
-            (d, r) if (r > 0 && *other < 0)
-                   || (r < 0 && *other > 0) => d - 1,
-            (d, _)                          => d,
-        }
-    }
-
-    ///
-    /// Integer modulo, satisfying:
-    ///
-    /// ```
-    /// # let n = 1i; let d = 1i;
-    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
-    /// ```
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// assert!(( 8i).mod_floor(& 3) ==  2);
-    /// assert!(( 8i).mod_floor(&-3) == -1);
-    /// assert!((-8i).mod_floor(& 3) ==  1);
-    /// assert!((-8i).mod_floor(&-3) == -2);
-    ///
-    /// assert!(( 1i).mod_floor(& 2) ==  1);
-    /// assert!(( 1i).mod_floor(&-2) == -1);
-    /// assert!((-1i).mod_floor(& 2) ==  1);
-    /// assert!((-1i).mod_floor(&-2) == -1);
-    /// ```
-    ///
-    #[inline]
-    fn mod_floor(&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,
-        }
-    }
-
-    /// Calculates `div_floor` and `mod_floor` simultaneously
-    #[inline]
-    fn div_mod_floor(&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.div_rem(other) {
-            (d, r) if (r > 0 && *other < 0)
-                   || (r < 0 && *other > 0) => (d - 1, r + *other),
-            (d, r)                          => (d, r),
-        }
-    }
-
-    /// Calculates `div` (`/`) and `rem` (`%`) simultaneously
-    #[inline]
-    fn div_rem(&self, other: &$T) -> ($T,$T) {
-        (*self / *other, *self % *other)
-    }
-
-    ///
-    /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
-    ///
-    /// The result is always positive
-    ///
-    #[inline]
-    fn gcd(&self, other: &$T) -> $T {
-        // Use Euclid's algorithm
-        let mut m = *self;
-        let mut n = *other;
-        while m != 0 {
-            let temp = m;
-            m = n % temp;
-            n = temp;
-        }
-        n.abs()
-    }
-
-    ///
-    /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
-    ///
-    #[inline]
-    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]
-    fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
-
-    /// Returns `true` if the number is divisible by `2`
-    #[inline]
-    fn is_even(&self) -> bool { self & 1 == 0 }
-
-    /// Returns `true` if the number is not divisible by `2`
-    #[inline]
-    fn is_odd(&self) -> bool { !self.is_even() }
-}
-
 #[cfg(not(test))]
 impl BitOr<$T,$T> for $T {
     #[inline]
@@ -481,92 +357,6 @@ fn test_is_negative() {
         assert!((-1 as $T).is_negative());
     }
 
-    ///
-    /// Checks that the division rule holds for:
-    ///
-    /// - `n`: numerator (dividend)
-    /// - `d`: denominator (divisor)
-    /// - `qr`: quotient and remainder
-    ///
-    #[cfg(test)]
-    fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
-        assert_eq!(d * q + r, n);
-    }
-
-    #[test]
-    fn test_div_rem() {
-        fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
-            let (n,d) = nd;
-            let separate_div_rem = (n / d, n % d);
-            let combined_div_rem = n.div_rem(&d);
-
-            assert_eq!(separate_div_rem, qr);
-            assert_eq!(combined_div_rem, qr);
-
-            test_division_rule(nd, separate_div_rem);
-            test_division_rule(nd, combined_div_rem);
-        }
-
-        test_nd_dr(( 8,  3), ( 2,  2));
-        test_nd_dr(( 8, -3), (-2,  2));
-        test_nd_dr((-8,  3), (-2, -2));
-        test_nd_dr((-8, -3), ( 2, -2));
-
-        test_nd_dr(( 1,  2), ( 0,  1));
-        test_nd_dr(( 1, -2), ( 0,  1));
-        test_nd_dr((-1,  2), ( 0, -1));
-        test_nd_dr((-1, -2), ( 0, -1));
-    }
-
-    #[test]
-    fn test_div_mod_floor() {
-        fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
-            let (n,d) = nd;
-            let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
-            let combined_div_mod_floor = n.div_mod_floor(&d);
-
-            assert_eq!(separate_div_mod_floor, dm);
-            assert_eq!(combined_div_mod_floor, dm);
-
-            test_division_rule(nd, separate_div_mod_floor);
-            test_division_rule(nd, combined_div_mod_floor);
-        }
-
-        test_nd_dm(( 8,  3), ( 2,  2));
-        test_nd_dm(( 8, -3), (-3, -1));
-        test_nd_dm((-8,  3), (-3,  1));
-        test_nd_dm((-8, -3), ( 2, -2));
-
-        test_nd_dm(( 1,  2), ( 0,  1));
-        test_nd_dm(( 1, -2), (-1, -1));
-        test_nd_dm((-1,  2), (-1,  1));
-        test_nd_dm((-1, -2), ( 0, -1));
-    }
-
-    #[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);
-    }
-
-    #[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);
-    }
-
     #[test]
     fn test_bitwise() {
         assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
@@ -577,42 +367,6 @@ fn test_bitwise() {
         assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
     }
 
-    #[test]
-    fn test_multiple_of() {
-        assert!((6 as $T).is_multiple_of(&(6 as $T)));
-        assert!((6 as $T).is_multiple_of(&(3 as $T)));
-        assert!((6 as $T).is_multiple_of(&(1 as $T)));
-        assert!((-8 as $T).is_multiple_of(&(4 as $T)));
-        assert!((8 as $T).is_multiple_of(&(-1 as $T)));
-        assert!((-8 as $T).is_multiple_of(&(-2 as $T)));
-    }
-
-    #[test]
-    fn test_even() {
-        assert_eq!((-4 as $T).is_even(), true);
-        assert_eq!((-3 as $T).is_even(), false);
-        assert_eq!((-2 as $T).is_even(), true);
-        assert_eq!((-1 as $T).is_even(), false);
-        assert_eq!((0 as $T).is_even(), true);
-        assert_eq!((1 as $T).is_even(), false);
-        assert_eq!((2 as $T).is_even(), true);
-        assert_eq!((3 as $T).is_even(), false);
-        assert_eq!((4 as $T).is_even(), true);
-    }
-
-    #[test]
-    fn test_odd() {
-        assert_eq!((-4 as $T).is_odd(), false);
-        assert_eq!((-3 as $T).is_odd(), true);
-        assert_eq!((-2 as $T).is_odd(), false);
-        assert_eq!((-1 as $T).is_odd(), true);
-        assert_eq!((0 as $T).is_odd(), false);
-        assert_eq!((1 as $T).is_odd(), true);
-        assert_eq!((2 as $T).is_odd(), false);
-        assert_eq!((3 as $T).is_odd(), true);
-        assert_eq!((4 as $T).is_odd(), false);
-    }
-
     #[test]
     fn test_count_ones() {
         assert_eq!((0b0101100 as $T).count_ones(), 3);
index 8a417096c3ea7522aaf98ccafe7e55cfdfde8117..332eb62b0c63a09d411d3186066c3ac2c272bfdb 100644 (file)
@@ -33,6 +33,12 @@ pub trait Num: Eq + Zero + One
              + Div<Self,Self>
              + Rem<Self,Self> {}
 
+/// Simultaneous division and remainder
+#[inline]
+pub fn div_rem<T: Div<T, T> + Rem<T, T>>(x: T, y: T) -> (T, T) {
+    (x / y, x % y)
+}
+
 /// Defines an additive identity element for `Self`.
 ///
 /// # Deriving
@@ -122,31 +128,6 @@ pub trait Signed: Num
 
 pub trait Unsigned: Num {}
 
-pub trait Integer: Num
-                 + Ord
-                 + Div<Self,Self>
-                 + Rem<Self,Self> {
-    fn div_rem(&self, other: &Self) -> (Self,Self);
-
-    fn div_floor(&self, other: &Self) -> Self;
-    fn mod_floor(&self, other: &Self) -> Self;
-    fn div_mod_floor(&self, other: &Self) -> (Self,Self);
-
-    fn gcd(&self, other: &Self) -> Self;
-    fn lcm(&self, other: &Self) -> Self;
-
-    fn is_multiple_of(&self, other: &Self) -> bool;
-    fn is_even(&self) -> bool;
-    fn is_odd(&self) -> bool;
-}
-
-/// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
-///
-/// The result is always positive.
-#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
-/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
-#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
-
 /// A collection of rounding operations.
 pub trait Round {
     /// Return the largest integer less than or equal to a number.
@@ -270,8 +251,7 @@ pub trait Primitive: Clone
                    + Bounded {}
 
 /// A collection of traits relevant to primitive signed and unsigned integers
-pub trait Int: Integer
-             + Primitive
+pub trait Int: Primitive
              + Bitwise
              + CheckedAdd
              + CheckedSub
index 6be829f51d73c858d164a207859aa8866f9005f7..bc79ec9a4af38c6b60c30f6eed4f6191afcde44c 100644 (file)
@@ -21,7 +21,7 @@
 use vec::{CloneableVector, ImmutableVector, MutableVector};
 use vec::OwnedVector;
 use num;
-use num::{NumCast, Zero, One, cast, Integer};
+use num::{NumCast, Zero, One, cast, Int};
 use num::{Round, Float, FPNaN, FPInfinite, ToPrimitive};
 
 pub enum ExponentFormat {
@@ -133,19 +133,7 @@ impl NumStrConv for $t {
  * # Failure
  * - Fails if `radix` < 2 or `radix` > 36.
  */
-pub fn int_to_str_bytes_common<T:NumCast
-                                +Zero
-                                +Eq
-                                +Ord
-                                +Integer
-                                +Div<T,T>
-                                +Neg<T>
-                                +Rem<T,T>
-                                +Mul<T,T>>(
-                                num: T,
-                                radix: uint,
-                                sign: SignFormat,
-                                f: |u8|) {
+pub fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
     assert!(2 <= radix && radix <= 36);
 
     let _0: T = Zero::zero();
index 4fc30b43895e41f570ac81a2c5c46f840d28abf0..33fcdcc426adfd7c1f526b3a15816ef52b0d9d1a 100644 (file)
@@ -100,60 +100,6 @@ fn neg(&self) -> $T { -*self }
 
 impl Unsigned for $T {}
 
-impl Integer for $T {
-    /// Calculates `div` (`/`) and `rem` (`%`) simultaneously
-    #[inline]
-    fn div_rem(&self, other: &$T) -> ($T,$T) {
-        (*self / *other, *self % *other)
-    }
-
-    /// Unsigned integer division. Returns the same result as `div` (`/`).
-    #[inline]
-    fn div_floor(&self, other: &$T) -> $T { *self / *other }
-
-    /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
-    #[inline]
-    fn mod_floor(&self, other: &$T) -> $T { *self % *other }
-
-    /// Calculates `div_floor` and `mod_floor` simultaneously
-    #[inline]
-    fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
-        (*self / *other, *self % *other)
-    }
-
-    /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
-    #[inline]
-    fn gcd(&self, other: &$T) -> $T {
-        // Use Euclid's algorithm
-        let mut m = *self;
-        let mut n = *other;
-        while m != 0 {
-            let temp = m;
-            m = n % temp;
-            n = temp;
-        }
-        n
-    }
-
-    /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
-    #[inline]
-    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]
-    fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
-
-    /// Returns `true` if the number is divisible by `2`
-    #[inline]
-    fn is_even(&self) -> bool { self & 1 == 0 }
-
-    /// Returns `true` if the number is not divisible by `2`
-    #[inline]
-    fn is_odd(&self) -> bool { !self.is_even() }
-}
-
 #[cfg(not(test))]
 impl BitOr<$T,$T> for $T {
     #[inline]
@@ -309,63 +255,6 @@ fn test_num() {
         num::test_num(10 as $T, 2 as $T);
     }
 
-    #[test]
-    fn test_div_mod_floor() {
-        assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
-        assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
-        assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
-        assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
-        assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
-        assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
-        assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
-        assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
-        assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 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);
-    }
-
-    #[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);
-    }
-
-    #[test]
-    fn test_multiple_of() {
-        assert!((6 as $T).is_multiple_of(&(6 as $T)));
-        assert!((6 as $T).is_multiple_of(&(3 as $T)));
-        assert!((6 as $T).is_multiple_of(&(1 as $T)));
-    }
-
-    #[test]
-    fn test_even() {
-        assert_eq!((0 as $T).is_even(), true);
-        assert_eq!((1 as $T).is_even(), false);
-        assert_eq!((2 as $T).is_even(), true);
-        assert_eq!((3 as $T).is_even(), false);
-        assert_eq!((4 as $T).is_even(), true);
-    }
-
-    #[test]
-    fn test_odd() {
-        assert_eq!((0 as $T).is_odd(), false);
-        assert_eq!((1 as $T).is_odd(), true);
-        assert_eq!((2 as $T).is_odd(), false);
-        assert_eq!((3 as $T).is_odd(), true);
-        assert_eq!((4 as $T).is_odd(), false);
-    }
-
     #[test]
     fn test_bitwise() {
         assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
index 3f61f2484a57e1e8526992b73bd93e688933bb5c..8fc4b985359e83f17439116157d657766897b307 100644 (file)
@@ -49,7 +49,7 @@
 pub use iter::{FromIterator, Extendable};
 pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
 pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
-pub use num::{Integer, Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
+pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
 pub use num::{Signed, Unsigned, Round};
 pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive};
 pub use path::{GenericPath, Path, PosixPath, WindowsPath};
index 5a42df0a38937f225ac176e6c1d6461cfb8b4a0c..0adc6083f6b817f6265b9404a56c99374d4a812f 100644 (file)
 use default::Default;
 use fmt;
 use iter::*;
-use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two};
+use num::{CheckedAdd, Saturating, checked_next_power_of_two, div_rem};
 use option::{None, Option, Some};
 use ptr;
 use ptr::RawPtr;
@@ -575,7 +575,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
         if self.v.len() == 0 {
             (0, Some(0))
         } else {
-            let (n, rem) = self.v.len().div_rem(&self.size);
+            let (n, rem) = div_rem(self.v.len(), self.size);
             let n = if rem > 0 { n+1 } else { n };
             (n, Some(n))
         }
@@ -2859,7 +2859,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
         if self.v.len() == 0 {
             (0, Some(0))
         } else {
-            let (n, rem) = self.v.len().div_rem(&self.chunk_size);
+            let (n, rem) = div_rem(self.v.len(), self.chunk_size);
             let n = if rem > 0 { n + 1 } else { n };
             (n, Some(n))
         }
index 93ef2b7bb82510cac24c6309e894ad33c6f19911..71cd176a836ff86c0e9b941088f1afb43de3054b 100644 (file)
@@ -14,6 +14,7 @@
 use std::num::One;
 use std::num::Zero;
 use std::num::FromPrimitive;
+use num::Integer;
 use num::bigint::BigInt;
 
 struct Context {