Use borrowed pointers for Integer methods

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.
This commit is contained in:
Brendan Zabarauskas 2013-04-24 22:50:56 +10:00
parent 024bf2ec72
commit 6fa054df96
3 changed files with 70 additions and 70 deletions

View file

@ -298,12 +298,12 @@ impl Integer for T {
* ~~~
*/
#[inline(always)]
fn div(&self, other: T) -> T {
fn div(&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.quot_rem(other) {
(q, r) if (r > 0 && other < 0)
|| (r < 0 && other > 0) => q - 1,
(q, r) if (r > 0 && *other < 0)
|| (r < 0 && *other > 0) => q - 1,
(q, _) => q,
}
}
@ -330,32 +330,32 @@ impl Integer for T {
* ~~~
*/
#[inline(always)]
fn modulo(&self, other: T) -> T {
fn modulo(&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,
match *self % *other {
r if (r > 0 && *other < 0)
|| (r < 0 && *other > 0) => r + *other,
r => r,
}
}
/// Calculates `div` and `modulo` simultaneously
#[inline(always)]
fn div_mod(&self, other: T) -> (T,T) {
fn div_mod(&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.quot_rem(other) {
(q, r) if (r > 0 && other < 0)
|| (r < 0 && other > 0) => (q - 1, r + other),
(q, r) if (r > 0 && *other < 0)
|| (r < 0 && *other > 0) => (q - 1, r + *other),
(q, r) => (q, r),
}
}
/// Calculates `quot` (`\`) and `rem` (`%`) simultaneously
#[inline(always)]
fn quot_rem(&self, other: T) -> (T,T) {
(*self / other, *self % other)
fn quot_rem(&self, other: &T) -> (T,T) {
(*self / *other, *self % *other)
}
/**
@ -364,9 +364,9 @@ impl Integer for T {
* The result is always positive
*/
#[inline(always)]
fn gcd(&self, other: T) -> T {
fn gcd(&self, other: &T) -> T {
// Use Euclid's algorithm
let mut m = *self, n = other;
let mut m = *self, n = *other;
while m != 0 {
let temp = m;
m = n % temp;
@ -379,17 +379,17 @@ impl Integer for T {
* Calculates the Lowest Common Multiple (LCM) of the number and `other`
*/
#[inline(always)]
fn lcm(&self, other: T) -> T {
((*self * other) / self.gcd(other)).abs() // should not have to recaluculate abs
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(always)]
fn divisible_by(&self, other: T) -> bool { *self % other == 0 }
fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 }
/// Returns `true` if the number is divisible by `2`
#[inline(always)]
fn is_even(&self) -> bool { self.divisible_by(2) }
fn is_even(&self) -> bool { self.divisible_by(&2) }
/// Returns `true` if the number is not divisible by `2`
#[inline(always)]
@ -562,7 +562,7 @@ mod tests {
fn test_nd_qr(nd: (T,T), qr: (T,T)) {
let (n,d) = nd;
let separate_quot_rem = (n / d, n % d);
let combined_quot_rem = n.quot_rem(d);
let combined_quot_rem = n.quot_rem(&d);
assert_eq!(separate_quot_rem, qr);
assert_eq!(combined_quot_rem, qr);
@ -586,8 +586,8 @@ mod tests {
fn test_div_mod() {
fn test_nd_dm(nd: (T,T), dm: (T,T)) {
let (n,d) = nd;
let separate_div_mod = (n.div(d), n.modulo(d));
let combined_div_mod = n.div_mod(d);
let separate_div_mod = (n.div(&d), n.modulo(&d));
let combined_div_mod = n.div_mod(&d);
assert_eq!(separate_div_mod, dm);
assert_eq!(combined_div_mod, dm);
@ -609,26 +609,26 @@ mod tests {
#[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);
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);
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]

View file

@ -65,14 +65,14 @@ pub trait Integer: Num
+ Ord
+ Quot<Self,Self>
+ Rem<Self,Self> {
fn div(&self, other: Self) -> Self;
fn modulo(&self, other: Self) -> Self;
fn div_mod(&self, other: Self) -> (Self,Self);
fn quot_rem(&self, other: Self) -> (Self,Self);
fn div(&self, other: &Self) -> Self;
fn modulo(&self, other: &Self) -> Self;
fn div_mod(&self, other: &Self) -> (Self,Self);
fn quot_rem(&self, other: &Self) -> (Self,Self);
fn gcd(&self, other: Self) -> Self;
fn lcm(&self, other: Self) -> Self;
fn divisible_by(&self, other: Self) -> bool;
fn gcd(&self, other: &Self) -> Self;
fn lcm(&self, other: &Self) -> Self;
fn divisible_by(&self, other: &Self) -> bool;
fn is_even(&self) -> bool;
fn is_odd(&self) -> bool;
}

View file

@ -179,29 +179,29 @@ impl Unsigned for T {}
impl Integer for T {
/// Unsigned integer division. Returns the same result as `quot` (`/`).
#[inline(always)]
fn div(&self, other: T) -> T { *self / other }
fn div(&self, other: &T) -> T { *self / *other }
/// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
#[inline(always)]
fn modulo(&self, other: T) -> T { *self / other }
fn modulo(&self, other: &T) -> T { *self / *other }
/// Calculates `div` and `modulo` simultaneously
#[inline(always)]
fn div_mod(&self, other: T) -> (T,T) {
(*self / other, *self % other)
fn div_mod(&self, other: &T) -> (T,T) {
(*self / *other, *self % *other)
}
/// Calculates `quot` (`\`) and `rem` (`%`) simultaneously
#[inline(always)]
fn quot_rem(&self, other: T) -> (T,T) {
(*self / other, *self % other)
fn quot_rem(&self, other: &T) -> (T,T) {
(*self / *other, *self % *other)
}
/// Calculates the Greatest Common Divisor (GCD) of the number and `other`
#[inline(always)]
fn gcd(&self, other: T) -> T {
fn gcd(&self, other: &T) -> T {
// Use Euclid's algorithm
let mut m = *self, n = other;
let mut m = *self, n = *other;
while m != 0 {
let temp = m;
m = n % temp;
@ -212,17 +212,17 @@ impl Integer for T {
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`
#[inline(always)]
fn lcm(&self, other: T) -> T {
(*self * other) / self.gcd(other)
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(always)]
fn divisible_by(&self, other: T) -> bool { *self % other == 0 }
fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 }
/// Returns `true` if the number is divisible by `2`
#[inline(always)]
fn is_even(&self) -> bool { self.divisible_by(2) }
fn is_even(&self) -> bool { self.divisible_by(&2) }
/// Returns `true` if the number is not divisible by `2`
#[inline(always)]
@ -355,21 +355,21 @@ mod tests {
#[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!((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);
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]