mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
libstd: correct bigint's quot/rem, div/modulo
This commit is contained in:
parent
8205f73ce6
commit
a117cf03bc
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(÷r);
|
||||
result += [r0.to_uint() as BigDigit];
|
||||
r = d;
|
||||
let mut m = n;
|
||||
while m > divider {
|
||||
let (d, m0) = m.div_mod(÷r);
|
||||
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;
|
||||
}
|
||||
@ -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()); }
|
||||
@ -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;
|
||||
}
|
||||
@ -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)
|
||||
@ -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() }
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
@ -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) {
|
||||
@ -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]),
|
||||
@ -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]),
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user