commit
9428f0f100
|
@ -70,24 +70,24 @@ impl Context {
|
||||||
fn extract_digit(&self) -> int {
|
fn extract_digit(&self) -> int {
|
||||||
if self.numer > self.accum {return -1;}
|
if self.numer > self.accum {return -1;}
|
||||||
let (q, r) =
|
let (q, r) =
|
||||||
(self.numer * Context::from_int(3) + self.accum)
|
(&self.numer * Context::from_int(3) + &self.accum)
|
||||||
.div_rem(&self.denom);
|
.div_rem(&self.denom);
|
||||||
if r + self.numer >= self.denom {return -1;}
|
if r + &self.numer >= self.denom {return -1;}
|
||||||
q.to_int().unwrap()
|
q.to_int().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_term(&mut self, k: int) {
|
fn next_term(&mut self, k: int) {
|
||||||
let y2 = Context::from_int(k * 2 + 1);
|
let y2 = Context::from_int(k * 2 + 1);
|
||||||
self.accum = (self.accum + (self.numer << 1)) * y2;
|
self.accum = (&self.accum + (&self.numer << 1)) * &y2;
|
||||||
self.numer = self.numer * Context::from_int(k);
|
self.numer = &self.numer * Context::from_int(k);
|
||||||
self.denom = self.denom * y2;
|
self.denom = &self.denom * y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eliminate_digit(&mut self, d: int) {
|
fn eliminate_digit(&mut self, d: int) {
|
||||||
let d = Context::from_int(d);
|
let d = Context::from_int(d);
|
||||||
let ten = Context::from_int(10);
|
let ten = Context::from_int(10);
|
||||||
self.accum = (self.accum - self.denom * d) * ten;
|
self.accum = (&self.accum - &self.denom * d) * &ten;
|
||||||
self.numer = self.numer * ten;
|
self.numer = &self.numer * ten;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
330
src/bigint.rs
330
src/bigint.rs
|
@ -27,7 +27,7 @@
|
||||||
//! let mut f0: BigUint = Zero::zero();
|
//! let mut f0: BigUint = Zero::zero();
|
||||||
//! let mut f1: BigUint = One::one();
|
//! let mut f1: BigUint = One::one();
|
||||||
//! for _ in range(0, n) {
|
//! for _ in range(0, n) {
|
||||||
//! let f2 = f0 + f1;
|
//! let f2 = f0 + &f1;
|
||||||
//! // This is a low cost way of swapping f0 with f1 and f1 with f2.
|
//! // This is a low cost way of swapping f0 with f1 and f1 with f2.
|
||||||
//! f0 = replace(&mut f1, f2);
|
//! f0 = replace(&mut f1, f2);
|
||||||
//! }
|
//! }
|
||||||
|
@ -183,14 +183,60 @@ impl FromStr for BigUint {
|
||||||
|
|
||||||
impl Num for BigUint {}
|
impl Num for BigUint {}
|
||||||
|
|
||||||
impl BitAnd<BigUint, BigUint> for BigUint {
|
macro_rules! forward_val_val_binop {
|
||||||
fn bitand(&self, other: &BigUint) -> BigUint {
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
impl $imp<$res, $res> for $res {
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: $res) -> $res {
|
||||||
|
(&self).$method(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_ref_val_binop {
|
||||||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
impl<'a> $imp<$res, $res> for &'a $res {
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: $res) -> $res {
|
||||||
|
self.$method(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_val_ref_binop {
|
||||||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
impl<'a> $imp<&'a $res, $res> for $res {
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: &$res) -> $res {
|
||||||
|
(&self).$method(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_all_binop {
|
||||||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||||||
|
forward_val_val_binop!(impl $imp for $res, $method)
|
||||||
|
forward_ref_val_binop!(impl $imp for $res, $method)
|
||||||
|
forward_val_ref_binop!(impl $imp for $res, $method)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_all_binop!(impl BitAnd for BigUint, bitand)
|
||||||
|
|
||||||
|
impl<'a, 'b> BitAnd<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
|
#[inline]
|
||||||
|
fn bitand(self, other: &BigUint) -> BigUint {
|
||||||
BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect())
|
BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitOr<BigUint, BigUint> for BigUint {
|
forward_all_binop!(impl BitOr for BigUint, bitor)
|
||||||
fn bitor(&self, other: &BigUint) -> BigUint {
|
|
||||||
|
impl<'a, 'b> BitOr<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
|
fn bitor(self, other: &BigUint) -> BigUint {
|
||||||
let zeros = ZERO_VEC.iter().cycle();
|
let zeros = ZERO_VEC.iter().cycle();
|
||||||
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
|
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
|
||||||
let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
|
let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
|
||||||
|
@ -200,8 +246,10 @@ impl BitOr<BigUint, BigUint> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitXor<BigUint, BigUint> for BigUint {
|
forward_all_binop!(impl BitXor for BigUint, bitxor)
|
||||||
fn bitxor(&self, other: &BigUint) -> BigUint {
|
|
||||||
|
impl<'a, 'b> BitXor<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
|
fn bitxor(self, other: &BigUint) -> BigUint {
|
||||||
let zeros = ZERO_VEC.iter().cycle();
|
let zeros = ZERO_VEC.iter().cycle();
|
||||||
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
|
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
|
||||||
let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
|
let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
|
||||||
|
@ -213,18 +261,28 @@ impl BitXor<BigUint, BigUint> for BigUint {
|
||||||
|
|
||||||
impl Shl<uint, BigUint> for BigUint {
|
impl Shl<uint, BigUint> for BigUint {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shl(&self, rhs: &uint) -> BigUint {
|
fn shl(self, rhs: uint) -> BigUint { (&self) << rhs }
|
||||||
let n_unit = *rhs / BigDigit::BITS;
|
}
|
||||||
let n_bits = *rhs % BigDigit::BITS;
|
|
||||||
|
impl<'a> Shl<uint, BigUint> for &'a BigUint {
|
||||||
|
#[inline]
|
||||||
|
fn shl(self, rhs: uint) -> BigUint {
|
||||||
|
let n_unit = rhs / BigDigit::BITS;
|
||||||
|
let n_bits = rhs % BigDigit::BITS;
|
||||||
return self.shl_unit(n_unit).shl_bits(n_bits);
|
return self.shl_unit(n_unit).shl_bits(n_bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shr<uint, BigUint> for BigUint {
|
impl Shr<uint, BigUint> for BigUint {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shr(&self, rhs: &uint) -> BigUint {
|
fn shr(self, rhs: uint) -> BigUint { (&self) >> rhs }
|
||||||
let n_unit = *rhs / BigDigit::BITS;
|
}
|
||||||
let n_bits = *rhs % BigDigit::BITS;
|
|
||||||
|
impl<'a> Shr<uint, BigUint> for &'a BigUint {
|
||||||
|
#[inline]
|
||||||
|
fn shr(self, rhs: uint) -> BigUint {
|
||||||
|
let n_unit = rhs / BigDigit::BITS;
|
||||||
|
let n_bits = rhs % BigDigit::BITS;
|
||||||
return self.shr_unit(n_unit).shr_bits(n_bits);
|
return self.shr_unit(n_unit).shr_bits(n_bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,8 +302,10 @@ impl One for BigUint {
|
||||||
|
|
||||||
impl Unsigned for BigUint {}
|
impl Unsigned for BigUint {}
|
||||||
|
|
||||||
impl Add<BigUint, BigUint> for BigUint {
|
forward_all_binop!(impl Add for BigUint, add)
|
||||||
fn add(&self, other: &BigUint) -> BigUint {
|
|
||||||
|
impl<'a, 'b> Add<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
|
fn add(self, other: &BigUint) -> BigUint {
|
||||||
let zeros = ZERO_VEC.iter().cycle();
|
let zeros = ZERO_VEC.iter().cycle();
|
||||||
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
|
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
|
||||||
|
|
||||||
|
@ -261,8 +321,10 @@ impl Add<BigUint, BigUint> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub<BigUint, BigUint> for BigUint {
|
forward_all_binop!(impl Sub for BigUint, sub)
|
||||||
fn sub(&self, other: &BigUint) -> BigUint {
|
|
||||||
|
impl<'a, 'b> Sub<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
|
fn sub(self, other: &BigUint) -> BigUint {
|
||||||
let new_len = cmp::max(self.data.len(), other.data.len());
|
let new_len = cmp::max(self.data.len(), other.data.len());
|
||||||
let zeros = ZERO_VEC.iter().cycle();
|
let zeros = ZERO_VEC.iter().cycle();
|
||||||
let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
|
let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
|
||||||
|
@ -289,8 +351,11 @@ impl Sub<BigUint, BigUint> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<BigUint, BigUint> for BigUint {
|
|
||||||
fn mul(&self, other: &BigUint) -> BigUint {
|
forward_all_binop!(impl Mul for BigUint, mul)
|
||||||
|
|
||||||
|
impl<'a, 'b> Mul<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
|
fn mul(self, other: &BigUint) -> BigUint {
|
||||||
if self.is_zero() || other.is_zero() { return Zero::zero(); }
|
if self.is_zero() || other.is_zero() { return Zero::zero(); }
|
||||||
|
|
||||||
let (s_len, o_len) = (self.data.len(), other.data.len());
|
let (s_len, o_len) = (self.data.len(), other.data.len());
|
||||||
|
@ -306,15 +371,15 @@ impl Mul<BigUint, BigUint> for BigUint {
|
||||||
let (s_hi, s_lo) = cut_at(self, half_len);
|
let (s_hi, s_lo) = cut_at(self, half_len);
|
||||||
let (o_hi, o_lo) = cut_at(other, half_len);
|
let (o_hi, o_lo) = cut_at(other, half_len);
|
||||||
|
|
||||||
let ll = s_lo * o_lo;
|
let ll = &s_lo * &o_lo;
|
||||||
let hh = s_hi * o_hi;
|
let hh = &s_hi * &o_hi;
|
||||||
let mm = {
|
let mm = {
|
||||||
let (s1, n1) = sub_sign(s_hi, s_lo);
|
let (s1, n1) = sub_sign(s_hi, s_lo);
|
||||||
let (s2, n2) = sub_sign(o_hi, o_lo);
|
let (s2, n2) = sub_sign(o_hi, o_lo);
|
||||||
match (s1, s2) {
|
match (s1, s2) {
|
||||||
(Equal, _) | (_, Equal) => hh + ll,
|
(Equal, _) | (_, Equal) => &hh + &ll,
|
||||||
(Less, Greater) | (Greater, Less) => hh + ll + (n1 * n2),
|
(Less, Greater) | (Greater, Less) => &hh + &ll + (n1 * n2),
|
||||||
(Less, Less) | (Greater, Greater) => hh + ll - (n1 * n2)
|
(Less, Less) | (Greater, Greater) => &hh + &ll - (n1 * n2)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -323,7 +388,7 @@ impl Mul<BigUint, BigUint> for BigUint {
|
||||||
|
|
||||||
fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
|
fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
|
||||||
if n == 0 { return Zero::zero(); }
|
if n == 0 { return Zero::zero(); }
|
||||||
if n == 1 { return (*a).clone(); }
|
if n == 1 { return a.clone(); }
|
||||||
|
|
||||||
let mut carry = 0;
|
let mut carry = 0;
|
||||||
let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| {
|
let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| {
|
||||||
|
@ -355,17 +420,22 @@ impl Mul<BigUint, BigUint> for BigUint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<BigUint, BigUint> for BigUint {
|
|
||||||
|
forward_all_binop!(impl Div for BigUint, div)
|
||||||
|
|
||||||
|
impl<'a, 'b> Div<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div(&self, other: &BigUint) -> BigUint {
|
fn div(self, other: &BigUint) -> BigUint {
|
||||||
let (q, _) = self.div_rem(other);
|
let (q, _) = self.div_rem(other);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rem<BigUint, BigUint> for BigUint {
|
forward_all_binop!(impl Rem for BigUint, rem)
|
||||||
|
|
||||||
|
impl<'a, 'b> Rem<&'b BigUint, BigUint> for &'a BigUint {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rem(&self, other: &BigUint) -> BigUint {
|
fn rem(self, other: &BigUint) -> BigUint {
|
||||||
let (_, r) = self.div_rem(other);
|
let (_, r) = self.div_rem(other);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -446,7 +516,7 @@ impl Integer for BigUint {
|
||||||
shift += 1;
|
shift += 1;
|
||||||
}
|
}
|
||||||
assert!(shift < BigDigit::BITS);
|
assert!(shift < BigDigit::BITS);
|
||||||
let (d, m) = div_mod_floor_inner(*self << shift, *other << shift);
|
let (d, m) = div_mod_floor_inner(self << shift, other << shift);
|
||||||
return (d, m >> shift);
|
return (d, m >> shift);
|
||||||
|
|
||||||
|
|
||||||
|
@ -457,14 +527,14 @@ impl Integer for BigUint {
|
||||||
while m >= b {
|
while m >= b {
|
||||||
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
||||||
let mut d0 = d0;
|
let mut d0 = d0;
|
||||||
let mut prod = b * d0;
|
let mut prod = &b * &d0;
|
||||||
while prod > m {
|
while prod > m {
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// d0 -= d_unit
|
// d0 -= &d_unit
|
||||||
d0 = d0 - d_unit;
|
d0 = d0 - &d_unit;
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// prod -= b_unit;
|
// prod -= &b_unit;
|
||||||
prod = prod - b_unit
|
prod = prod - &b_unit
|
||||||
}
|
}
|
||||||
if d0.is_zero() {
|
if d0.is_zero() {
|
||||||
n = 2;
|
n = 2;
|
||||||
|
@ -522,7 +592,7 @@ impl Integer for BigUint {
|
||||||
let mut n = (*other).clone();
|
let mut n = (*other).clone();
|
||||||
while !m.is_zero() {
|
while !m.is_zero() {
|
||||||
let temp = m;
|
let temp = m;
|
||||||
m = n % temp;
|
m = n % &temp;
|
||||||
n = temp;
|
n = temp;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
@ -530,16 +600,16 @@ impl Integer for BigUint {
|
||||||
|
|
||||||
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
|
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) }
|
fn lcm(&self, other: &BigUint) -> BigUint { ((self * other) / self.gcd(other)) }
|
||||||
|
|
||||||
/// Deprecated, use `is_multiple_of` instead.
|
/// Deprecated, use `is_multiple_of` instead.
|
||||||
#[deprecated = "function renamed to `is_multiple_of`"]
|
#[deprecated = "function renamed to `is_multiple_of`"]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn divides(&self, other: &BigUint) -> bool { return self.is_multiple_of(other); }
|
fn divides(&self, other: &BigUint) -> bool { self.is_multiple_of(other) }
|
||||||
|
|
||||||
/// Returns `true` if the number is a multiple of `other`.
|
/// Returns `true` if the number is a multiple of `other`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
|
fn is_multiple_of(&self, other: &BigUint) -> bool { (self % other).is_zero() }
|
||||||
|
|
||||||
/// Returns `true` if the number is divisible by `2`.
|
/// Returns `true` if the number is divisible by `2`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -720,8 +790,8 @@ impl FromStrRadix for BigUint {
|
||||||
match d {
|
match d {
|
||||||
Some(d) => {
|
Some(d) => {
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// n += d * power;
|
// n += d * &power;
|
||||||
n = n + d * power;
|
n = n + d * &power;
|
||||||
}
|
}
|
||||||
None => { return None; }
|
None => { return None; }
|
||||||
}
|
}
|
||||||
|
@ -733,8 +803,8 @@ impl FromStrRadix for BigUint {
|
||||||
}
|
}
|
||||||
end -= unit_len;
|
end -= unit_len;
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// power *= base_num;
|
// power *= &base_num;
|
||||||
power = power * base_num;
|
power = power * &base_num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,15 +1008,25 @@ impl Num for BigInt {}
|
||||||
|
|
||||||
impl Shl<uint, BigInt> for BigInt {
|
impl Shl<uint, BigInt> for BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shl(&self, rhs: &uint) -> BigInt {
|
fn shl(self, rhs: uint) -> BigInt { (&self) << rhs }
|
||||||
BigInt::from_biguint(self.sign, self.data << *rhs)
|
}
|
||||||
|
|
||||||
|
impl<'a> Shl<uint, BigInt> for &'a BigInt {
|
||||||
|
#[inline]
|
||||||
|
fn shl(self, rhs: uint) -> BigInt {
|
||||||
|
BigInt::from_biguint(self.sign, &self.data << rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shr<uint, BigInt> for BigInt {
|
impl Shr<uint, BigInt> for BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shr(&self, rhs: &uint) -> BigInt {
|
fn shr(self, rhs: uint) -> BigInt { (&self) >> rhs }
|
||||||
BigInt::from_biguint(self.sign, self.data >> *rhs)
|
}
|
||||||
|
|
||||||
|
impl<'a> Shr<uint, BigInt> for &'a BigInt {
|
||||||
|
#[inline]
|
||||||
|
fn shr(self, rhs: uint) -> BigInt {
|
||||||
|
BigInt::from_biguint(self.sign, &self.data >> rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,7 +1058,7 @@ impl Signed for BigInt {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_sub(&self, other: &BigInt) -> BigInt {
|
fn abs_sub(&self, other: &BigInt) -> BigInt {
|
||||||
if *self <= *other { Zero::zero() } else { *self - *other }
|
if *self <= *other { Zero::zero() } else { self - other }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -997,64 +1077,74 @@ impl Signed for BigInt {
|
||||||
fn is_negative(&self) -> bool { self.sign == Minus }
|
fn is_negative(&self) -> bool { self.sign == Minus }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<BigInt, BigInt> for BigInt {
|
forward_all_binop!(impl Add for BigInt, add)
|
||||||
|
|
||||||
|
impl<'a, 'b> Add<&'b BigInt, BigInt> for &'a BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, other: &BigInt) -> BigInt {
|
fn add(self, other: &BigInt) -> BigInt {
|
||||||
match (self.sign, other.sign) {
|
match (self.sign, other.sign) {
|
||||||
(NoSign, _) => other.clone(),
|
(NoSign, _) => other.clone(),
|
||||||
(_, NoSign) => self.clone(),
|
(_, NoSign) => self.clone(),
|
||||||
(Plus, Plus) => BigInt::from_biguint(Plus, self.data + other.data),
|
(Plus, Plus) => BigInt::from_biguint(Plus, &self.data + &other.data),
|
||||||
(Plus, Minus) => *self - (-*other),
|
(Plus, Minus) => self - (-*other),
|
||||||
(Minus, Plus) => *other - (-*self),
|
(Minus, Plus) => other - (-*self),
|
||||||
(Minus, Minus) => -((-*self) + (-*other))
|
(Minus, Minus) => -((-*self) + (-*other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub<BigInt, BigInt> for BigInt {
|
forward_all_binop!(impl Sub for BigInt, sub)
|
||||||
|
|
||||||
|
impl<'a, 'b> Sub<&'b BigInt, BigInt> for &'a BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(&self, other: &BigInt) -> BigInt {
|
fn sub(self, other: &BigInt) -> BigInt {
|
||||||
match (self.sign, other.sign) {
|
match (self.sign, other.sign) {
|
||||||
(NoSign, _) => -*other,
|
(NoSign, _) => -*other,
|
||||||
(_, NoSign) => self.clone(),
|
(_, NoSign) => self.clone(),
|
||||||
(Plus, Plus) => match self.data.cmp(&other.data) {
|
(Plus, Plus) => match self.data.cmp(&other.data) {
|
||||||
Less => BigInt::from_biguint(Minus, other.data - self.data),
|
Less => BigInt::from_biguint(Minus, &other.data - &self.data),
|
||||||
Greater => BigInt::from_biguint(Plus, self.data - other.data),
|
Greater => BigInt::from_biguint(Plus, &self.data - &other.data),
|
||||||
Equal => Zero::zero()
|
Equal => Zero::zero()
|
||||||
},
|
},
|
||||||
(Plus, Minus) => *self + (-*other),
|
(Plus, Minus) => self + (-*other),
|
||||||
(Minus, Plus) => -((-*self) + *other),
|
(Minus, Plus) => -((-*self) + other),
|
||||||
(Minus, Minus) => (-*other) - (-*self)
|
(Minus, Minus) => (-*other) - (-*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<BigInt, BigInt> for BigInt {
|
forward_all_binop!(impl Mul for BigInt, mul)
|
||||||
|
|
||||||
|
impl<'a, 'b> Mul<&'b BigInt, BigInt> for &'a BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, other: &BigInt) -> BigInt {
|
fn mul(self, other: &BigInt) -> BigInt {
|
||||||
match (self.sign, other.sign) {
|
match (self.sign, other.sign) {
|
||||||
(NoSign, _) | (_, NoSign) => Zero::zero(),
|
(NoSign, _) | (_, NoSign) => Zero::zero(),
|
||||||
(Plus, Plus) | (Minus, Minus) => {
|
(Plus, Plus) | (Minus, Minus) => {
|
||||||
BigInt::from_biguint(Plus, self.data * other.data)
|
BigInt::from_biguint(Plus, &self.data * &other.data)
|
||||||
},
|
},
|
||||||
(Plus, Minus) | (Minus, Plus) => {
|
(Plus, Minus) | (Minus, Plus) => {
|
||||||
BigInt::from_biguint(Minus, self.data * other.data)
|
BigInt::from_biguint(Minus, &self.data * &other.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<BigInt, BigInt> for BigInt {
|
forward_all_binop!(impl Div for BigInt, div)
|
||||||
|
|
||||||
|
impl<'a, 'b> Div<&'b BigInt, BigInt> for &'a BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div(&self, other: &BigInt) -> BigInt {
|
fn div(self, other: &BigInt) -> BigInt {
|
||||||
let (q, _) = self.div_rem(other);
|
let (q, _) = self.div_rem(other);
|
||||||
q
|
q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rem<BigInt, BigInt> for BigInt {
|
forward_all_binop!(impl Rem for BigInt, rem)
|
||||||
|
|
||||||
|
impl<'a, 'b> Rem<&'b BigInt, BigInt> for &'a BigInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rem(&self, other: &BigInt) -> BigInt {
|
fn rem(self, other: &BigInt) -> BigInt {
|
||||||
let (_, r) = self.div_rem(other);
|
let (_, r) = self.div_rem(other);
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
@ -1131,19 +1221,24 @@ impl Integer for BigInt {
|
||||||
let (d_ui, m_ui) = self.data.div_rem(&other.data);
|
let (d_ui, m_ui) = self.data.div_rem(&other.data);
|
||||||
let d = BigInt::from_biguint(Plus, d_ui);
|
let d = BigInt::from_biguint(Plus, d_ui);
|
||||||
let m = BigInt::from_biguint(Plus, m_ui);
|
let m = BigInt::from_biguint(Plus, m_ui);
|
||||||
|
let one: BigInt = One::one();
|
||||||
match (self.sign, other.sign) {
|
match (self.sign, other.sign) {
|
||||||
(_, NoSign) => panic!(),
|
(_, NoSign) => panic!(),
|
||||||
(Plus, Plus) | (NoSign, Plus) => (d, m),
|
(Plus, Plus) | (NoSign, Plus) => (d, m),
|
||||||
(Plus, Minus) | (NoSign, Minus) => if m.is_zero() {
|
(Plus, Minus) | (NoSign, Minus) => {
|
||||||
|
if m.is_zero() {
|
||||||
(-d, Zero::zero())
|
(-d, Zero::zero())
|
||||||
} else {
|
} else {
|
||||||
(-d - One::one(), m + *other)
|
(-d - one, m + other)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(Minus, Plus) => if m.is_zero() {
|
(Minus, Plus) => {
|
||||||
|
if m.is_zero() {
|
||||||
(-d, Zero::zero())
|
(-d, Zero::zero())
|
||||||
} else {
|
} else {
|
||||||
(-d - One::one(), *other - m)
|
(-d - one, other - m)
|
||||||
},
|
}
|
||||||
|
}
|
||||||
(Minus, Minus) => (d, -m)
|
(Minus, Minus) => (d, -m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1374,7 +1469,7 @@ impl<R: Rng> RandBigInt for R {
|
||||||
ubound: &BigUint)
|
ubound: &BigUint)
|
||||||
-> BigUint {
|
-> BigUint {
|
||||||
assert!(*lbound < *ubound);
|
assert!(*lbound < *ubound);
|
||||||
return *lbound + self.gen_biguint_below(&(*ubound - *lbound));
|
return lbound + self.gen_biguint_below(&(ubound - lbound));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_bigint_range(&mut self,
|
fn gen_bigint_range(&mut self,
|
||||||
|
@ -1382,8 +1477,8 @@ impl<R: Rng> RandBigInt for R {
|
||||||
ubound: &BigInt)
|
ubound: &BigInt)
|
||||||
-> BigInt {
|
-> BigInt {
|
||||||
assert!(*lbound < *ubound);
|
assert!(*lbound < *ubound);
|
||||||
let delta = (*ubound - *lbound).to_biguint().unwrap();
|
let delta = (ubound - lbound).to_biguint().unwrap();
|
||||||
return *lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
|
return lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1912,8 +2007,8 @@ mod biguint_tests {
|
||||||
let b = BigUint::from_slice(b_vec);
|
let b = BigUint::from_slice(b_vec);
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
assert!(a + b == c);
|
assert!(&a + &b == c);
|
||||||
assert!(b + a == c);
|
assert!(&b + &a == c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1925,8 +2020,8 @@ mod biguint_tests {
|
||||||
let b = BigUint::from_slice(b_vec);
|
let b = BigUint::from_slice(b_vec);
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
assert!(c - a == b);
|
assert!(&c - &a == b);
|
||||||
assert!(c - b == a);
|
assert!(&c - &b == a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1983,8 +2078,8 @@ mod biguint_tests {
|
||||||
let b = BigUint::from_slice(b_vec);
|
let b = BigUint::from_slice(b_vec);
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
|
|
||||||
assert!(a * b == c);
|
assert!(&a * &b == c);
|
||||||
assert!(b * a == c);
|
assert!(&b * &a == c);
|
||||||
}
|
}
|
||||||
|
|
||||||
for elm in DIV_REM_QUADRUPLES.iter() {
|
for elm in DIV_REM_QUADRUPLES.iter() {
|
||||||
|
@ -1994,8 +2089,8 @@ mod biguint_tests {
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
let d = BigUint::from_slice(d_vec);
|
let d = BigUint::from_slice(d_vec);
|
||||||
|
|
||||||
assert!(a == b * c + d);
|
assert!(a == &b * &c + &d);
|
||||||
assert!(a == c * b + d);
|
assert!(a == &c * &b + &d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2078,8 +2173,8 @@ mod biguint_tests {
|
||||||
let c = BigUint::from_slice(c_vec);
|
let c = BigUint::from_slice(c_vec);
|
||||||
let d = BigUint::from_slice(d_vec);
|
let d = BigUint::from_slice(d_vec);
|
||||||
|
|
||||||
assert!(a == b.checked_mul(&c).unwrap() + d);
|
assert!(a == b.checked_mul(&c).unwrap() + &d);
|
||||||
assert!(a == c.checked_mul(&b).unwrap() + d);
|
assert!(a == c.checked_mul(&b).unwrap() + &d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2149,8 +2244,8 @@ mod biguint_tests {
|
||||||
assert!(thousand.is_even());
|
assert!(thousand.is_even());
|
||||||
assert!(big.is_even());
|
assert!(big.is_even());
|
||||||
assert!(bigger.is_odd());
|
assert!(bigger.is_odd());
|
||||||
assert!((one << 64).is_even());
|
assert!((&one << 64).is_even());
|
||||||
assert!(((one << 64) + one).is_odd());
|
assert!(((&one << 64) + one).is_odd());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, String)>)> {
|
fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, String)>)> {
|
||||||
|
@ -2252,7 +2347,8 @@ mod biguint_tests {
|
||||||
for i in range(2, n + 1) {
|
for i in range(2, n + 1) {
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// f *= FromPrimitive::from_uint(i);
|
// f *= FromPrimitive::from_uint(i);
|
||||||
f = f * FromPrimitive::from_uint(i).unwrap();
|
let bu: BigUint = FromPrimitive::from_uint(i).unwrap();
|
||||||
|
f = f * bu;
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@ -2513,14 +2609,14 @@ mod bigint_tests {
|
||||||
let b = BigInt::from_slice(Plus, b_vec);
|
let b = BigInt::from_slice(Plus, b_vec);
|
||||||
let c = BigInt::from_slice(Plus, c_vec);
|
let c = BigInt::from_slice(Plus, c_vec);
|
||||||
|
|
||||||
assert!(a + b == c);
|
assert!(&a + &b == c);
|
||||||
assert!(b + a == c);
|
assert!(&b + &a == c);
|
||||||
assert!(c + (-a) == b);
|
assert!(&c + (-a) == b);
|
||||||
assert!(c + (-b) == a);
|
assert!(&c + (-b) == a);
|
||||||
assert!(a + (-c) == (-b));
|
assert!(&a + (-c) == (-b));
|
||||||
assert!(b + (-c) == (-a));
|
assert!(&b + (-c) == (-a));
|
||||||
assert!((-a) + (-b) == (-c))
|
assert!((-a) + (-b) == (-c))
|
||||||
assert!(a + (-a) == Zero::zero());
|
assert!(&a + (-a) == Zero::zero());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2532,14 +2628,14 @@ mod bigint_tests {
|
||||||
let b = BigInt::from_slice(Plus, b_vec);
|
let b = BigInt::from_slice(Plus, b_vec);
|
||||||
let c = BigInt::from_slice(Plus, c_vec);
|
let c = BigInt::from_slice(Plus, c_vec);
|
||||||
|
|
||||||
assert!(c - a == b);
|
assert!(&c - &a == b);
|
||||||
assert!(c - b == a);
|
assert!(&c - &b == a);
|
||||||
assert!((-b) - a == (-c))
|
assert!((-b) - &a == (-c))
|
||||||
assert!((-a) - b == (-c))
|
assert!((-a) - &b == (-c))
|
||||||
assert!(b - (-a) == c);
|
assert!(&b - (-a) == c);
|
||||||
assert!(a - (-b) == c);
|
assert!(&a - (-b) == c);
|
||||||
assert!((-c) - (-a) == (-b));
|
assert!((-c) - (-a) == (-b));
|
||||||
assert!(a - a == Zero::zero());
|
assert!(&a - &a == Zero::zero());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2589,11 +2685,11 @@ mod bigint_tests {
|
||||||
let b = BigInt::from_slice(Plus, b_vec);
|
let b = BigInt::from_slice(Plus, b_vec);
|
||||||
let c = BigInt::from_slice(Plus, c_vec);
|
let c = BigInt::from_slice(Plus, c_vec);
|
||||||
|
|
||||||
assert!(a * b == c);
|
assert!(&a * &b == c);
|
||||||
assert!(b * a == c);
|
assert!(&b * &a == c);
|
||||||
|
|
||||||
assert!((-a) * b == -c);
|
assert!((-a) * &b == -c);
|
||||||
assert!((-b) * a == -c);
|
assert!((-b) * &a == -c);
|
||||||
}
|
}
|
||||||
|
|
||||||
for elm in DIV_REM_QUADRUPLES.iter() {
|
for elm in DIV_REM_QUADRUPLES.iter() {
|
||||||
|
@ -2603,8 +2699,8 @@ mod bigint_tests {
|
||||||
let c = BigInt::from_slice(Plus, c_vec);
|
let c = BigInt::from_slice(Plus, c_vec);
|
||||||
let d = BigInt::from_slice(Plus, d_vec);
|
let d = BigInt::from_slice(Plus, d_vec);
|
||||||
|
|
||||||
assert!(a == b * c + d);
|
assert!(a == &b * &c + &d);
|
||||||
assert!(a == c * b + d);
|
assert!(a == &c * &b + &d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2616,7 +2712,7 @@ mod bigint_tests {
|
||||||
assert_eq!(m.sign, b.sign);
|
assert_eq!(m.sign, b.sign);
|
||||||
}
|
}
|
||||||
assert!(m.abs() <= b.abs());
|
assert!(m.abs() <= b.abs());
|
||||||
assert!(*a == (*b) * d + m);
|
assert!(*a == b * &d + &m);
|
||||||
assert!(d == *ans_d);
|
assert!(d == *ans_d);
|
||||||
assert!(m == *ans_m);
|
assert!(m == *ans_m);
|
||||||
}
|
}
|
||||||
|
@ -2628,9 +2724,10 @@ mod bigint_tests {
|
||||||
check_sub(&a.neg(), b, &d.neg(), m);
|
check_sub(&a.neg(), b, &d.neg(), m);
|
||||||
check_sub(&a.neg(), &b.neg(), d, m);
|
check_sub(&a.neg(), &b.neg(), d, m);
|
||||||
} else {
|
} else {
|
||||||
|
let one: BigInt = One::one();
|
||||||
check_sub(a, b, d, m);
|
check_sub(a, b, d, m);
|
||||||
check_sub(a, &b.neg(), &(d.neg() - One::one()), &(*m - *b));
|
check_sub(a, &b.neg(), &(d.neg() - &one), &(m - b));
|
||||||
check_sub(&a.neg(), b, &(d.neg() - One::one()), &(*b - *m));
|
check_sub(&a.neg(), b, &(d.neg() - &one), &(b - m));
|
||||||
check_sub(&a.neg(), &b.neg(), d, &m.neg());
|
check_sub(&a.neg(), &b.neg(), d, &m.neg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2667,7 +2764,7 @@ mod bigint_tests {
|
||||||
assert_eq!(r.sign, a.sign);
|
assert_eq!(r.sign, a.sign);
|
||||||
}
|
}
|
||||||
assert!(r.abs() <= b.abs());
|
assert!(r.abs() <= b.abs());
|
||||||
assert!(*a == (*b) * q + r);
|
assert!(*a == b * &q + &r);
|
||||||
assert!(q == *ans_q);
|
assert!(q == *ans_q);
|
||||||
assert!(r == *ans_r);
|
assert!(r == *ans_r);
|
||||||
}
|
}
|
||||||
|
@ -2761,8 +2858,8 @@ mod bigint_tests {
|
||||||
let c = BigInt::from_slice(Plus, c_vec);
|
let c = BigInt::from_slice(Plus, c_vec);
|
||||||
let d = BigInt::from_slice(Plus, d_vec);
|
let d = BigInt::from_slice(Plus, d_vec);
|
||||||
|
|
||||||
assert!(a == b.checked_mul(&c).unwrap() + d);
|
assert!(a == b.checked_mul(&c).unwrap() + &d);
|
||||||
assert!(a == c.checked_mul(&b).unwrap() + d);
|
assert!(a == c.checked_mul(&b).unwrap() + &d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -2943,7 +3040,8 @@ mod bench {
|
||||||
fn factorial(n: uint) -> BigUint {
|
fn factorial(n: uint) -> BigUint {
|
||||||
let mut f: BigUint = One::one();
|
let mut f: BigUint = One::one();
|
||||||
for i in iter::range_inclusive(1, n) {
|
for i in iter::range_inclusive(1, n) {
|
||||||
f = f * FromPrimitive::from_uint(i).unwrap();
|
let bu: BigUint = FromPrimitive::from_uint(i).unwrap();
|
||||||
|
f = f * bu;
|
||||||
}
|
}
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
|
@ -2952,7 +3050,7 @@ mod bench {
|
||||||
let mut f0: BigUint = Zero::zero();
|
let mut f0: BigUint = Zero::zero();
|
||||||
let mut f1: BigUint = One::one();
|
let mut f1: BigUint = One::one();
|
||||||
for _ in range(0, n) {
|
for _ in range(0, n) {
|
||||||
let f2 = f0 + f1;
|
let f2 = f0 + &f1;
|
||||||
f0 = replace(&mut f1, f2);
|
f0 = replace(&mut f1, f2);
|
||||||
}
|
}
|
||||||
f0
|
f0
|
||||||
|
|
111
src/complex.rs
111
src/complex.rs
|
@ -43,7 +43,7 @@ impl<T: Clone + Num> Complex<T> {
|
||||||
/// have a sqrt function), i.e. `re^2 + im^2`.
|
/// have a sqrt function), i.e. `re^2 + im^2`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm_sqr(&self) -> T {
|
pub fn norm_sqr(&self) -> T {
|
||||||
self.re * self.re + self.im * self.im
|
self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,21 +57,21 @@ impl<T: Clone + Num> Complex<T> {
|
||||||
/// Multiplies `self` by the scalar `t`.
|
/// Multiplies `self` by the scalar `t`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn scale(&self, t: T) -> Complex<T> {
|
pub fn scale(&self, t: T) -> Complex<T> {
|
||||||
Complex::new(self.re * t, self.im * t)
|
Complex::new(self.re.clone() * t.clone(), self.im.clone() * t)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divides `self` by the scalar `t`.
|
/// Divides `self` by the scalar `t`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unscale(&self, t: T) -> Complex<T> {
|
pub fn unscale(&self, t: T) -> Complex<T> {
|
||||||
Complex::new(self.re / t, self.im / t)
|
Complex::new(self.re.clone() / t.clone(), self.im.clone() / t)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1/self`
|
/// Returns `1/self`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inv(&self) -> Complex<T> {
|
pub fn inv(&self) -> Complex<T> {
|
||||||
let norm_sqr = self.norm_sqr();
|
let norm_sqr = self.norm_sqr();
|
||||||
Complex::new(self.re / norm_sqr,
|
Complex::new(self.re.clone() / norm_sqr.clone(),
|
||||||
-self.im / norm_sqr)
|
-self.im.clone() / norm_sqr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ impl<T: Clone + FloatMath> Complex<T> {
|
||||||
/// Calculate |self|
|
/// Calculate |self|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm(&self) -> T {
|
pub fn norm(&self) -> T {
|
||||||
self.re.hypot(self.im)
|
self.re.clone().hypot(self.im.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ impl<T: Clone + FloatMath + Num> Complex<T> {
|
||||||
/// Calculate the principal Arg of self.
|
/// Calculate the principal Arg of self.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn arg(&self) -> T {
|
pub fn arg(&self) -> T {
|
||||||
self.im.atan2(self.re)
|
self.im.clone().atan2(self.re.clone())
|
||||||
}
|
}
|
||||||
/// Convert to polar form (r, theta), such that `self = r * exp(i
|
/// Convert to polar form (r, theta), such that `self = r * exp(i
|
||||||
/// * theta)`
|
/// * theta)`
|
||||||
|
@ -102,38 +102,91 @@ impl<T: Clone + FloatMath + Num> Complex<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arithmetic */
|
macro_rules! forward_val_val_binop {
|
||||||
// (a + i b) + (c + i d) == (a + c) + i (b + d)
|
(impl $imp:ident, $method:ident) => {
|
||||||
impl<T: Clone + Num> Add<Complex<T>, Complex<T>> for Complex<T> {
|
impl<T: Clone + Num> $imp<Complex<T>, Complex<T>> for Complex<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, other: &Complex<T>) -> Complex<T> {
|
fn $method(self, other: Complex<T>) -> Complex<T> {
|
||||||
Complex::new(self.re + other.re, self.im + other.im)
|
(&self).$method(&other)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// (a + i b) - (c + i d) == (a - c) + i (b - d)
|
|
||||||
impl<T: Clone + Num> Sub<Complex<T>, Complex<T>> for Complex<T> {
|
|
||||||
#[inline]
|
|
||||||
fn sub(&self, other: &Complex<T>) -> Complex<T> {
|
|
||||||
Complex::new(self.re - other.re, self.im - other.im)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
|
|
||||||
impl<T: Clone + Num> Mul<Complex<T>, Complex<T>> for Complex<T> {
|
|
||||||
#[inline]
|
|
||||||
fn mul(&self, other: &Complex<T>) -> Complex<T> {
|
|
||||||
Complex::new(self.re*other.re - self.im*other.im,
|
|
||||||
self.re*other.im + self.im*other.re)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_ref_val_binop {
|
||||||
|
(impl $imp:ident, $method:ident) => {
|
||||||
|
impl<'a, T: Clone + Num> $imp<Complex<T>, Complex<T>> for &'a Complex<T> {
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: Complex<T>) -> Complex<T> {
|
||||||
|
self.$method(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_val_ref_binop {
|
||||||
|
(impl $imp:ident, $method:ident) => {
|
||||||
|
impl<'a, T: Clone + Num> $imp<&'a Complex<T>, Complex<T>> for Complex<T> {
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: &Complex<T>) -> Complex<T> {
|
||||||
|
(&self).$method(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_all_binop {
|
||||||
|
(impl $imp:ident, $method:ident) => {
|
||||||
|
forward_val_val_binop!(impl $imp, $method)
|
||||||
|
forward_ref_val_binop!(impl $imp, $method)
|
||||||
|
forward_val_ref_binop!(impl $imp, $method)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* arithmetic */
|
||||||
|
forward_all_binop!(impl Add, add)
|
||||||
|
|
||||||
|
// (a + i b) + (c + i d) == (a + c) + i (b + d)
|
||||||
|
impl<'a, 'b, T: Clone + Num> Add<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: &Complex<T>) -> Complex<T> {
|
||||||
|
Complex::new(self.re.clone() + other.re.clone(),
|
||||||
|
self.im.clone() + other.im.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_all_binop!(impl Sub, sub)
|
||||||
|
|
||||||
|
// (a + i b) - (c + i d) == (a - c) + i (b - d)
|
||||||
|
impl<'a, 'b, T: Clone + Num> Sub<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: &Complex<T>) -> Complex<T> {
|
||||||
|
Complex::new(self.re.clone() - other.re.clone(),
|
||||||
|
self.im.clone() - other.im.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_all_binop!(impl Mul, mul)
|
||||||
|
|
||||||
|
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
|
||||||
|
impl<'a, 'b, T: Clone + Num> Mul<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: &Complex<T>) -> Complex<T> {
|
||||||
|
Complex::new(self.re.clone() * other.re.clone() - self.im.clone() * other.im.clone(),
|
||||||
|
self.re.clone() * other.im.clone() + self.im.clone() * other.re.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_all_binop!(impl Div, div)
|
||||||
|
|
||||||
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
|
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
|
||||||
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
|
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
|
||||||
impl<T: Clone + Num> Div<Complex<T>, Complex<T>> for Complex<T> {
|
impl<'a, 'b, T: Clone + Num> Div<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div(&self, other: &Complex<T>) -> Complex<T> {
|
fn div(self, other: &Complex<T>) -> Complex<T> {
|
||||||
let norm_sqr = other.norm_sqr();
|
let norm_sqr = other.norm_sqr();
|
||||||
Complex::new((self.re*other.re + self.im*other.im) / norm_sqr,
|
Complex::new((self.re.clone() * other.re.clone() + self.im.clone() * other.im.clone()) / norm_sqr.clone(),
|
||||||
(self.im*other.re - self.re*other.im) / norm_sqr)
|
(self.im.clone() * other.re.clone() - self.re.clone() * other.im.clone()) / norm_sqr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,9 +134,7 @@ pub trait Integer: Num + PartialOrd
|
||||||
/// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
|
/// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
|
||||||
/// ~~~
|
/// ~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_rem(&self, other: &Self) -> (Self, Self) {
|
fn div_rem(&self, other: &Self) -> (Self, Self);
|
||||||
(*self / *other, *self % *other)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simultaneous floored integer division and modulus.
|
/// Simultaneous floored integer division and modulus.
|
||||||
/// Returns `(quotient, remainder)`.
|
/// Returns `(quotient, remainder)`.
|
||||||
|
@ -253,6 +251,12 @@ macro_rules! impl_integer_for_int {
|
||||||
/// Returns `true` if the number is not divisible by `2`
|
/// Returns `true` if the number is not divisible by `2`
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_odd(&self) -> bool { !self.is_even() }
|
fn is_odd(&self) -> bool { !self.is_even() }
|
||||||
|
|
||||||
|
/// Simultaneous truncated integer division and modulus.
|
||||||
|
#[inline]
|
||||||
|
fn div_rem(&self, other: &$T) -> ($T, $T) {
|
||||||
|
(*self / *other, *self % *other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -425,6 +429,12 @@ macro_rules! impl_integer_for_uint {
|
||||||
/// Returns `true` if the number is not divisible by `2`.
|
/// Returns `true` if the number is not divisible by `2`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_odd(&self) -> bool { !(*self).is_even() }
|
fn is_odd(&self) -> bool { !(*self).is_even() }
|
||||||
|
|
||||||
|
/// Simultaneous truncated integer division and modulus.
|
||||||
|
#[inline]
|
||||||
|
fn div_rem(&self, other: &$T) -> ($T, $T) {
|
||||||
|
(*self / *other, *self % *other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
10
src/iter.rs
10
src/iter.rs
|
@ -45,7 +45,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
|
||||||
fn next(&mut self) -> Option<A> {
|
fn next(&mut self) -> Option<A> {
|
||||||
if self.state < self.stop {
|
if self.state < self.stop {
|
||||||
let result = self.state.clone();
|
let result = self.state.clone();
|
||||||
self.state = self.state + self.one;
|
self.state = self.state.clone() + self.one.clone();
|
||||||
Some(result)
|
Some(result)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -91,7 +91,7 @@ impl<A: Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedIterator<A> for R
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<A> {
|
fn next_back(&mut self) -> Option<A> {
|
||||||
if self.stop > self.state {
|
if self.stop > self.state {
|
||||||
self.stop = self.stop - self.one;
|
self.stop = self.stop.clone() - self.one.clone();
|
||||||
Some(self.stop.clone())
|
Some(self.stop.clone())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -151,7 +151,7 @@ impl<A: Sub<A, A> + Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedItera
|
||||||
fn next_back(&mut self) -> Option<A> {
|
fn next_back(&mut self) -> Option<A> {
|
||||||
if self.range.stop > self.range.state {
|
if self.range.stop > self.range.state {
|
||||||
let result = self.range.stop.clone();
|
let result = self.range.stop.clone();
|
||||||
self.range.stop = self.range.stop - self.range.one;
|
self.range.stop = self.range.stop.clone() - self.range.one.clone();
|
||||||
Some(result)
|
Some(result)
|
||||||
} else if !self.done && self.range.state == self.range.stop {
|
} else if !self.done && self.range.state == self.range.stop {
|
||||||
self.done = true;
|
self.done = true;
|
||||||
|
@ -246,7 +246,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<Foo, Foo> for Foo {
|
impl Add<Foo, Foo> for Foo {
|
||||||
fn add(&self, _: &Foo) -> Foo {
|
fn add(self, _: Foo) -> Foo {
|
||||||
Foo
|
Foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<Foo, Foo> for Foo {
|
impl Mul<Foo, Foo> for Foo {
|
||||||
fn mul(&self, _: &Foo) -> Foo {
|
fn mul(self, _: Foo) -> Foo {
|
||||||
Foo
|
Foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
//! let mut approx = start.clone();
|
//! let mut approx = start.clone();
|
||||||
//!
|
//!
|
||||||
//! for _ in range(0, iterations) {
|
//! for _ in range(0, iterations) {
|
||||||
//! approx = (approx + (start / approx)) /
|
//! approx = (&approx + (&start / &approx)) /
|
||||||
//! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
|
//! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
|
@ -123,15 +123,15 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
|
||||||
/// assert_eq!(num::pow(2i, 4), 16);
|
/// assert_eq!(num::pow(2i, 4), 16);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
|
pub fn pow<T: Clone + One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
|
||||||
if exp == 1 { base }
|
if exp == 1 { base }
|
||||||
else {
|
else {
|
||||||
let mut acc = one::<T>();
|
let mut acc = one::<T>();
|
||||||
while exp > 0 {
|
while exp > 0 {
|
||||||
if (exp & 1) == 1 {
|
if (exp & 1) == 1 {
|
||||||
acc = acc * base;
|
acc = acc * base.clone();
|
||||||
}
|
}
|
||||||
base = base * base;
|
base = base.clone() * base;
|
||||||
exp = exp >> 1;
|
exp = exp >> 1;
|
||||||
}
|
}
|
||||||
acc
|
acc
|
||||||
|
|
111
src/rational.rs
111
src/rational.rs
|
@ -92,10 +92,10 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
|
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// self.numer /= g;
|
// self.numer /= g;
|
||||||
self.numer = self.numer / g;
|
self.numer = self.numer.clone() / g.clone();
|
||||||
// FIXME(#5992): assignment operator overloads
|
// FIXME(#5992): assignment operator overloads
|
||||||
// self.denom /= g;
|
// self.denom /= g;
|
||||||
self.denom = self.denom / g;
|
self.denom = self.denom.clone() / g;
|
||||||
|
|
||||||
// keep denom positive!
|
// keep denom positive!
|
||||||
if self.denom < Zero::zero() {
|
if self.denom < Zero::zero() {
|
||||||
|
@ -121,9 +121,10 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn floor(&self) -> Ratio<T> {
|
pub fn floor(&self) -> Ratio<T> {
|
||||||
if *self < Zero::zero() {
|
if *self < Zero::zero() {
|
||||||
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
let one: T = One::one();
|
||||||
|
Ratio::from_integer((self.numer.clone() - self.denom.clone() + one) / self.denom.clone())
|
||||||
} else {
|
} else {
|
||||||
Ratio::from_integer(self.numer / self.denom)
|
Ratio::from_integer(self.numer.clone() / self.denom.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,9 +132,10 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ceil(&self) -> Ratio<T> {
|
pub fn ceil(&self) -> Ratio<T> {
|
||||||
if *self < Zero::zero() {
|
if *self < Zero::zero() {
|
||||||
Ratio::from_integer(self.numer / self.denom)
|
Ratio::from_integer(self.numer.clone() / self.denom.clone())
|
||||||
} else {
|
} else {
|
||||||
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
let one: T = One::one();
|
||||||
|
Ratio::from_integer((self.numer.clone() + self.denom.clone() - one) / self.denom.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +143,7 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn round(&self) -> Ratio<T> {
|
pub fn round(&self) -> Ratio<T> {
|
||||||
let one: T = One::one();
|
let one: T = One::one();
|
||||||
let two: T = one + one;
|
let two: T = one.clone() + one.clone();
|
||||||
|
|
||||||
// Find unsigned fractional part of rational number
|
// Find unsigned fractional part of rational number
|
||||||
let fractional = self.fract().abs();
|
let fractional = self.fract().abs();
|
||||||
|
@ -150,16 +152,17 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
// is, a/b >= 1/2, or a >= b/2. For odd denominators, we use
|
// is, a/b >= 1/2, or a >= b/2. For odd denominators, we use
|
||||||
// a >= (b/2)+1. This avoids overflow issues.
|
// a >= (b/2)+1. This avoids overflow issues.
|
||||||
let half_or_larger = if fractional.denom().is_even() {
|
let half_or_larger = if fractional.denom().is_even() {
|
||||||
*fractional.numer() >= *fractional.denom() / two
|
*fractional.numer() >= fractional.denom().clone() / two.clone()
|
||||||
} else {
|
} else {
|
||||||
*fractional.numer() >= (*fractional.denom() / two) + one
|
*fractional.numer() >= (fractional.denom().clone() / two.clone()) + one.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
if half_or_larger {
|
if half_or_larger {
|
||||||
|
let one: Ratio<T> = One::one();
|
||||||
if *self >= Zero::zero() {
|
if *self >= Zero::zero() {
|
||||||
self.trunc() + One::one()
|
self.trunc() + one
|
||||||
} else {
|
} else {
|
||||||
self.trunc() - One::one()
|
self.trunc() - one
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.trunc()
|
self.trunc()
|
||||||
|
@ -169,13 +172,13 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
/// Rounds towards zero.
|
/// Rounds towards zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn trunc(&self) -> Ratio<T> {
|
pub fn trunc(&self) -> Ratio<T> {
|
||||||
Ratio::from_integer(self.numer / self.denom)
|
Ratio::from_integer(self.numer.clone() / self.denom.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the fractional part of a number.
|
/// Returns the fractional part of a number.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fract(&self) -> Ratio<T> {
|
pub fn fract(&self) -> Ratio<T> {
|
||||||
Ratio::new_raw(self.numer % self.denom, self.denom.clone())
|
Ratio::new_raw(self.numer.clone() % self.denom.clone(), self.denom.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,11 +215,11 @@ macro_rules! cmp_impl {
|
||||||
};
|
};
|
||||||
// return something other than a Ratio<T>
|
// return something other than a Ratio<T>
|
||||||
(impl $imp:ident, $($method:ident -> $res:ty),*) => {
|
(impl $imp:ident, $($method:ident -> $res:ty),*) => {
|
||||||
impl<T: Mul<T,T> + $imp> $imp for Ratio<T> {
|
impl<T: Clone + Mul<T,T> + $imp> $imp for Ratio<T> {
|
||||||
$(
|
$(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(&self, other: &Ratio<T>) -> $res {
|
fn $method(&self, other: &Ratio<T>) -> $res {
|
||||||
(self.numer * other.denom). $method (&(self.denom*other.numer))
|
(self.numer.clone() * other.denom.clone()). $method (&(self.denom.clone()*other.numer.clone()))
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
@ -228,34 +231,78 @@ cmp_impl!(impl PartialOrd, lt -> bool, gt -> bool, le -> bool, ge -> bool,
|
||||||
cmp_impl!(impl Eq, )
|
cmp_impl!(impl Eq, )
|
||||||
cmp_impl!(impl Ord, cmp -> cmp::Ordering)
|
cmp_impl!(impl Ord, cmp -> cmp::Ordering)
|
||||||
|
|
||||||
/* Arithmetic */
|
macro_rules! forward_val_val_binop {
|
||||||
// a/b * c/d = (a*c)/(b*d)
|
(impl $imp:ident, $method:ident) => {
|
||||||
impl<T: Clone + Integer + PartialOrd>
|
impl<T: Clone + Integer + PartialOrd> $imp<Ratio<T>, Ratio<T>> for Ratio<T> {
|
||||||
Mul<Ratio<T>,Ratio<T>> for Ratio<T> {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, rhs: &Ratio<T>) -> Ratio<T> {
|
fn $method(self, other: Ratio<T>) -> Ratio<T> {
|
||||||
Ratio::new(self.numer * rhs.numer, self.denom * rhs.denom)
|
(&self).$method(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (a/b) / (c/d) = (a*d)/(b*c)
|
macro_rules! forward_ref_val_binop {
|
||||||
impl<T: Clone + Integer + PartialOrd>
|
(impl $imp:ident, $method:ident) => {
|
||||||
Div<Ratio<T>,Ratio<T>> for Ratio<T> {
|
impl<'a, T: Clone + Integer + PartialOrd> $imp<Ratio<T>, Ratio<T>> for &'a Ratio<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div(&self, rhs: &Ratio<T>) -> Ratio<T> {
|
fn $method(self, other: Ratio<T>) -> Ratio<T> {
|
||||||
Ratio::new(self.numer * rhs.denom, self.denom * rhs.numer)
|
self.$method(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_val_ref_binop {
|
||||||
|
(impl $imp:ident, $method:ident) => {
|
||||||
|
impl<'a, T: Clone + Integer + PartialOrd> $imp<&'a Ratio<T>, Ratio<T>> for Ratio<T> {
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: &Ratio<T>) -> Ratio<T> {
|
||||||
|
(&self).$method(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_all_binop {
|
||||||
|
(impl $imp:ident, $method:ident) => {
|
||||||
|
forward_val_val_binop!(impl $imp, $method)
|
||||||
|
forward_ref_val_binop!(impl $imp, $method)
|
||||||
|
forward_val_ref_binop!(impl $imp, $method)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arithmetic */
|
||||||
|
forward_all_binop!(impl Mul, mul)
|
||||||
|
// a/b * c/d = (a*c)/(b*d)
|
||||||
|
impl<'a, 'b, T: Clone + Integer + PartialOrd>
|
||||||
|
Mul<&'b Ratio<T>, Ratio<T>> for &'a Ratio<T> {
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, rhs: &Ratio<T>) -> Ratio<T> {
|
||||||
|
Ratio::new(self.numer.clone() * rhs.numer.clone(), self.denom.clone() * rhs.denom.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_all_binop!(impl Div, div)
|
||||||
|
// (a/b) / (c/d) = (a*d)/(b*c)
|
||||||
|
impl<'a, 'b, T: Clone + Integer + PartialOrd>
|
||||||
|
Div<&'b Ratio<T>, Ratio<T>> for &'a Ratio<T> {
|
||||||
|
#[inline]
|
||||||
|
fn div(self, rhs: &Ratio<T>) -> Ratio<T> {
|
||||||
|
Ratio::new(self.numer.clone() * rhs.denom.clone(), self.denom.clone() * rhs.numer.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
|
// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
|
||||||
macro_rules! arith_impl {
|
macro_rules! arith_impl {
|
||||||
(impl $imp:ident, $method:ident) => {
|
(impl $imp:ident, $method:ident) => {
|
||||||
impl<T: Clone + Integer + PartialOrd>
|
forward_all_binop!(impl $imp, $method)
|
||||||
$imp<Ratio<T>,Ratio<T>> for Ratio<T> {
|
impl<'a, 'b, T: Clone + Integer + PartialOrd>
|
||||||
|
$imp<&'b Ratio<T>,Ratio<T>> for &'a Ratio<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(&self, rhs: &Ratio<T>) -> Ratio<T> {
|
fn $method(self, rhs: &Ratio<T>) -> Ratio<T> {
|
||||||
Ratio::new((self.numer * rhs.denom).$method(&(self.denom * rhs.numer)),
|
Ratio::new((self.numer.clone() * rhs.denom.clone()).$method(self.denom.clone() * rhs.numer.clone()),
|
||||||
self.denom * rhs.denom)
|
self.denom.clone() * rhs.denom.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,7 +359,7 @@ impl<T: Clone + Integer + PartialOrd>
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
|
fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
|
||||||
if *self <= *other { Zero::zero() } else { *self - *other }
|
if *self <= *other { Zero::zero() } else { self - other }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Reference in New Issue