Skip to content

Commit

Permalink
auto merge of #6013 : gifnksm/rust/bigint-quot-rem, r=graydon
Browse files Browse the repository at this point in the history
BigInt had been supported quot/rem and div/mod correctly, but after merging #5990 they have been broken.
This commit fixes it.
  • Loading branch information
bors committed Apr 23, 2013
2 parents 309f0c5 + a117cf0 commit 3867470
Showing 1 changed file with 57 additions and 56 deletions.
113 changes: 57 additions & 56 deletions src/libstd/num/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,15 +264,15 @@ impl Mul<BigUint, BigUint> for BigUint {

impl Quot<BigUint, BigUint> for BigUint {
fn quot(&self, other: &BigUint) -> BigUint {
let (d, _) = self.quot_rem(other);
return d;
let (q, _) = self.quot_rem(other);
return q;
}
}

impl Rem<BigUint, BigUint> for BigUint {
fn rem(&self, other: &BigUint) -> BigUint {
let (_, m) = self.quot_rem(other);
return m;
let (_, r) = self.quot_rem(other);
return r;
}
}

Expand Down Expand Up @@ -302,14 +302,14 @@ impl ToStrRadix for BigUint {
fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] {
let divider = BigUint::from_uint(base);
let mut result = ~[];
let mut r = n;
while r > divider {
let (d, r0) = r.quot_rem(&divider);
result += [r0.to_uint() as BigDigit];
r = d;
let mut m = n;
while m > divider {
let (d, m0) = m.div_mod(&divider);
result += [m0.to_uint() as BigDigit];
m = d;
}
if r.is_not_zero() {
result += [r.to_uint() as BigDigit];
if m.is_not_zero() {
result += [m.to_uint() as BigDigit];
}
return result;
}
Expand Down Expand Up @@ -384,7 +384,16 @@ pub impl BigUint {

fn abs(&self) -> BigUint { copy *self }

fn quot_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
fn div(&self, other: &BigUint) -> BigUint {
let (d, _) = self.div_mod(other);
return d;
}
fn modulo(&self, other: &BigUint) -> BigUint {
let (_, m) = self.div_mod(other);
return m;
}

fn div_mod(&self, other: &BigUint) -> (BigUint, BigUint) {
if other.is_zero() { fail!() }
if self.is_zero() { return (Zero::zero(), Zero::zero()); }
if *other == One::one() { return (copy *self, Zero::zero()); }
Expand All @@ -402,17 +411,17 @@ pub impl BigUint {
shift += 1;
}
assert!(shift < BigDigit::bits);
let (d, m) = quot_rem_inner(self << shift, other << shift);
let (d, m) = div_mod_inner(self << shift, other << shift);
return (d, m >> shift);

fn quot_rem_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
let mut r = a;
fn div_mod_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
let mut m = a;
let mut d = Zero::zero::<BigUint>();
let mut n = 1;
while r >= b {
let mut (d0, d_unit, b_unit) = div_estimate(&r, &b, n);
while m >= b {
let mut (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
let mut prod = b * d0;
while prod > r {
while prod > m {
d0 -= d_unit;
prod -= b_unit;
}
Expand All @@ -422,9 +431,9 @@ pub impl BigUint {
}
n = 1;
d += d0;
r -= prod;
m -= prod;
}
return (d, r);
return (d, m);
}

fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
Expand Down Expand Up @@ -455,16 +464,8 @@ pub impl BigUint {
}
}

fn quot(&self, other: &BigUint) -> BigUint {
let (q, _) = self.quotrem(other);
return q;
}
fn rem(&self, other: &BigUint) -> BigUint {
let (_, r) = self.quotrem(other);
return r;
}
fn quotrem(&self, other: &BigUint) -> (BigUint, BigUint) {
self.quot_rem(other)
fn quot_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
self.div_mod(other)
}

fn is_zero(&self) -> bool { self.data.is_empty() }
Expand Down Expand Up @@ -739,15 +740,15 @@ impl Mul<BigInt, BigInt> for BigInt {

impl Quot<BigInt, BigInt> for BigInt {
fn quot(&self, other: &BigInt) -> BigInt {
let (d, _) = self.quot_rem(other);
return d;
let (q, _) = self.quot_rem(other);
return q;
}
}

impl Rem<BigInt, BigInt> for BigInt {
fn rem(&self, other: &BigInt) -> BigInt {
let (_, m) = self.quot_rem(other);
return m;
let (_, r) = self.quot_rem(other);
return r;
}
}

Expand Down Expand Up @@ -841,7 +842,16 @@ pub impl BigInt {
BigInt::from_biguint(Plus, copy self.data)
}
fn quot_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
fn div(&self, other: &BigInt) -> BigInt {
let (d, _) = self.div_mod(other);
return d;
}
fn modulo(&self, other: &BigInt) -> BigInt {
let (_, m) = self.div_mod(other);
return m;
}
fn div_mod(&self, other: &BigInt) -> (BigInt, BigInt) {
// m.sign == other.sign
let (d_ui, m_ui) = self.data.quot_rem(&other.data);
let d = BigInt::from_biguint(Plus, d_ui),
Expand All @@ -863,18 +873,9 @@ pub impl BigInt {
}
}
fn quot(&self, other: &BigInt) -> BigInt {
let (q, _) = self.quotrem(other);
return q;
}
fn rem(&self, other: &BigInt) -> BigInt {
let (_, r) = self.quotrem(other);
return r;
}
fn quotrem(&self, other: &BigInt) -> (BigInt, BigInt) {
fn quot_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
// r.sign == self.sign
let (q_ui, r_ui) = self.data.quotrem(&other.data);
let (q_ui, r_ui) = self.data.div_mod(&other.data);
let q = BigInt::from_biguint(Plus, q_ui);
let r = BigInt::from_biguint(Plus, r_ui);
match (self.sign, other.sign) {
Expand Down Expand Up @@ -1151,9 +1152,9 @@ mod biguint_tests {
];

static quot_rem_quadruples: &'static [(&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit])]
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit])]
= &[
(&[ 1], &[ 2], &[], &[1]),
(&[ 1, 1], &[ 2], &[-1/2+1], &[1]),
Expand Down Expand Up @@ -1517,9 +1518,9 @@ mod bigint_tests {
];

static quot_rem_quadruples: &'static [(&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit])]
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit])]
= &[
(&[ 1], &[ 2], &[], &[1]),
(&[ 1, 1], &[ 2], &[-1/2+1], &[1]),
Expand Down Expand Up @@ -1556,9 +1557,9 @@ mod bigint_tests {
}

#[test]
fn test_quot_rem() {
fn test_div_mod() {
fn check_sub(a: &BigInt, b: &BigInt, ans_d: &BigInt, ans_m: &BigInt) {
let (d, m) = a.quot_rem(b);
let (d, m) = a.div_mod(b);
if m.is_not_zero() {
assert!(m.sign == b.sign);
}
Expand Down Expand Up @@ -1607,9 +1608,9 @@ mod bigint_tests {


#[test]
fn test_quotrem() {
fn test_quot_rem() {
fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) {
let (q, r) = a.quotrem(b);
let (q, r) = a.quot_rem(b);
if r.is_not_zero() {
assert!(r.sign == a.sign);
}
Expand Down

0 comments on commit 3867470

Please sign in to comment.