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
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};
/// 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]
/// 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]
#[cfg(test)]
mod biguint_tests {
+ use Integer;
use super::{BigDigit, BigUint, ToBigUint};
use super::{Plus, BigInt, RandBigInt, ToBigInt};
#[cfg(test)]
mod bigint_tests {
+ use Integer;
use super::{BigDigit, BigUint, ToBigUint};
use super::{Sign, Minus, Zero, Plus, BigInt, RandBigInt, ToBigInt};
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)
//! Rational numbers
+use Integer;
+
use std::cmp;
use std::from_str::FromStr;
use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
*/
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};
}
}
-/// `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 {
}
}
-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> {
#[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]);
}
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!()));
}
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!()));
}
#[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 }
}
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]
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)));
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);
+ 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
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.
+ Bounded {}
/// A collection of traits relevant to primitive signed and unsigned integers
-pub trait Int: Integer
- + Primitive
+pub trait Int: Primitive
+ Bitwise
+ CheckedAdd
+ CheckedSub
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 {
* # 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();
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]
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)));
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};
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;
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))
}
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))
}
use std::num::One;
use std::num::Zero;
use std::num::FromPrimitive;
+use num::Integer;
use num::bigint::BigInt;
struct Context {