num: Migrate ~[T] to std::vec_ng::Vec

This commit is contained in:
Florian Zeitz 2014-03-16 00:01:01 +01:00
parent f496ab6a6f
commit ce2ce2410f
2 changed files with 150 additions and 148 deletions

View File

@ -27,8 +27,9 @@ use std::num::{Zero, One, ToStrRadix, FromStrRadix};
use rand::Rng;
use std::str;
use std::uint;
use std::vec;
use std::{i64, u64};
use std::vec_ng;
use std::vec_ng::Vec;
/**
A `BigDigit` is a `BigUint`'s composing element.
@ -87,7 +88,7 @@ A `BigUint`-typed value `BigUint { data: ~[a, b, c] }` represents a number
*/
#[deriving(Clone)]
pub struct BigUint {
priv data: ~[BigDigit]
priv data: Vec<BigDigit>
}
impl Eq for BigUint {
@ -187,7 +188,7 @@ impl Shr<uint, BigUint> for BigUint {
impl Zero for BigUint {
#[inline]
fn zero() -> BigUint { BigUint::new(~[]) }
fn zero() -> BigUint { BigUint::new(Vec::new()) }
#[inline]
fn is_zero(&self) -> bool { self.data.is_empty() }
@ -195,7 +196,7 @@ impl Zero for BigUint {
impl One for BigUint {
#[inline]
fn one() -> BigUint { BigUint::new(~[1]) }
fn one() -> BigUint { BigUint::new(vec!(1)) }
}
impl Unsigned for BigUint {}
@ -206,7 +207,7 @@ impl Add<BigUint, BigUint> for BigUint {
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
let mut carry = 0;
let mut sum: ~[BigDigit] = a.data.iter().zip(b.data.iter().chain(zeros)).map(|(ai, bi)| {
let mut sum: Vec<BigDigit> = a.data.iter().zip(b.data.iter().chain(zeros)).map(|(ai, bi)| {
let (hi, lo) = BigDigit::from_uint((*ai as uint) + (*bi as uint) + (carry as uint));
carry = hi;
lo
@ -223,7 +224,7 @@ impl Sub<BigUint, BigUint> for BigUint {
let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
let mut borrow = 0;
let diff: ~[BigDigit] = a.take(new_len).zip(b).map(|(ai, bi)| {
let diff: Vec<BigDigit> = a.take(new_len).zip(b).map(|(ai, bi)| {
let (hi, lo) = BigDigit::from_uint(
BigDigit::base + (*ai as uint) - (*bi as uint) - (borrow as uint)
);
@ -245,8 +246,8 @@ impl Mul<BigUint, BigUint> for BigUint {
if self.is_zero() || other.is_zero() { return Zero::zero(); }
let (s_len, o_len) = (self.data.len(), other.data.len());
if s_len == 1 { return mul_digit(other, self.data[0]); }
if o_len == 1 { return mul_digit(self, other.data[0]); }
if s_len == 1 { return mul_digit(other, self.data.as_slice()[0]); }
if o_len == 1 { return mul_digit(self, other.data.as_slice()[0]); }
// Using Karatsuba multiplication
// (a1 * base + a0) * (b1 * base + b0)
@ -277,13 +278,13 @@ impl Mul<BigUint, BigUint> for BigUint {
if n == 1 { return (*a).clone(); }
let mut carry = 0;
let mut prod = a.data.iter().map(|ai| {
let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| {
let (hi, lo) = BigDigit::from_uint(
(*ai as uint) * (n as uint) + (carry as uint)
);
carry = hi;
lo
}).collect::<~[BigDigit]>();
}).collect();
if carry != 0 { prod.push(carry); }
return BigUint::new(prod);
}
@ -441,7 +442,7 @@ impl Integer for BigUint {
let an = a.data.tailn(a.data.len() - n);
let bn = *b.data.last().unwrap();
let mut d = vec::with_capacity(an.len());
let mut d = Vec::with_capacity(an.len());
let mut carry = 0;
for elt in an.rev_iter() {
let ai = BigDigit::to_uint(carry, *elt);
@ -457,7 +458,7 @@ impl Integer for BigUint {
return (BigUint::new(d), One::one(), (*b).clone());
}
let one: BigUint = One::one();
return (BigUint::from_slice(d).shl_unit(shift),
return (BigUint::new(d).shl_unit(shift),
one.shl_unit(shift),
b.shl_unit(shift));
}
@ -495,7 +496,7 @@ impl Integer for BigUint {
#[inline]
fn is_even(&self) -> bool {
// Considering only the last digit.
match self.data.head() {
match self.data.as_slice().head() {
Some(x) => x.is_even(),
None => true
}
@ -524,20 +525,20 @@ impl ToPrimitive for BigUint {
fn to_u64(&self) -> Option<u64> {
match self.data.len() {
0 => Some(0),
1 => Some(self.data[0] as u64),
1 => Some(self.data.as_slice()[0] as u64),
2 => {
Some(BigDigit::to_uint(self.data[1], self.data[0]) as u64)
Some(BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0]) as u64)
}
3 => {
let n_lo = BigDigit::to_uint(self.data[1], self.data[0]) as
let n_lo = BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0]) as
u64;
let n_hi = self.data[2] as u64;
let n_hi = self.data.as_slice()[2] as u64;
Some((n_hi << 32) + n_lo)
}
4 => {
let n_lo = BigDigit::to_uint(self.data[1], self.data[0])
let n_lo = BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0])
as u64;
let n_hi = BigDigit::to_uint(self.data[3], self.data[2])
let n_hi = BigDigit::to_uint(self.data.as_slice()[3], self.data.as_slice()[2])
as u64;
Some((n_hi << 32) + n_lo)
}
@ -550,8 +551,8 @@ impl ToPrimitive for BigUint {
fn to_u64(&self) -> Option<u64> {
match self.data.len() {
0 => Some(0),
1 => Some(self.data[0] as u64),
2 => Some(BigDigit::to_uint(self.data[1], self.data[0]) as u64),
1 => Some(self.data.as_slice()[0] as u64),
2 => Some(BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0]) as u64),
_ => None
}
}
@ -577,10 +578,10 @@ impl FromPrimitive for BigUint {
let n = match (BigDigit::from_uint(n_hi), BigDigit::from_uint(n_lo)) {
((0, 0), (0, 0)) => Zero::zero(),
((0, 0), (0, n0)) => BigUint::new(~[n0]),
((0, 0), (n1, n0)) => BigUint::new(~[n0, n1]),
((0, n2), (n1, n0)) => BigUint::new(~[n0, n1, n2]),
((n3, n2), (n1, n0)) => BigUint::new(~[n0, n1, n2, n3]),
((0, 0), (0, n0)) => BigUint::new(vec!(n0)),
((0, 0), (n1, n0)) => BigUint::new(vec!(n0, n1)),
((0, n2), (n1, n0)) => BigUint::new(vec!(n0, n1, n2)),
((n3, n2), (n1, n0)) => BigUint::new(vec!(n0, n1, n2, n3)),
};
Some(n)
}
@ -590,8 +591,8 @@ impl FromPrimitive for BigUint {
fn from_u64(n: u64) -> Option<BigUint> {
let n = match BigDigit::from_uint(n as uint) {
(0, 0) => Zero::zero(),
(0, n0) => BigUint::new(~[n0]),
(n1, n0) => BigUint::new(~[n0, n1])
(0, n0) => BigUint::new(vec!(n0)),
(n1, n0) => BigUint::new(vec!(n0, n1))
};
Some(n)
}
@ -650,13 +651,13 @@ impl ToStrRadix for BigUint {
assert!(1 < radix && radix <= 16);
let (base, max_len) = get_radix_base(radix);
if base == BigDigit::base {
return fill_concat(self.data, radix, max_len)
return fill_concat(self.data.as_slice(), radix, max_len)
}
return fill_concat(convert_base(self, base), radix, max_len);
return fill_concat(convert_base(self, base).as_slice(), radix, max_len);
fn convert_base(n: &BigUint, base: uint) -> ~[BigDigit] {
fn convert_base(n: &BigUint, base: uint) -> Vec<BigDigit> {
let divider = FromPrimitive::from_uint(base).unwrap();
let mut result = ~[];
let mut result = Vec::new();
let mut m = n.clone();
while m >= divider {
let (d, m0) = m.div_mod_floor(&divider);
@ -694,7 +695,7 @@ impl FromStrRadix for BigUint {
impl BigUint {
/// Creates and initializes a `BigUint`.
#[inline]
pub fn new(v: ~[BigDigit]) -> BigUint {
pub fn new(v: Vec<BigDigit>) -> BigUint {
// omit trailing zeros
let new_len = v.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
@ -707,7 +708,7 @@ impl BigUint {
/// Creates and initializes a `BigUint`.
#[inline]
pub fn from_slice(slice: &[BigDigit]) -> BigUint {
return BigUint::new(slice.to_owned());
return BigUint::new(Vec::from_slice(slice));
}
/// Creates and initializes a `BigUint`.
@ -752,8 +753,8 @@ impl BigUint {
fn shl_unit(&self, n_unit: uint) -> BigUint {
if n_unit == 0 || self.is_zero() { return (*self).clone(); }
return BigUint::new(vec::from_elem(n_unit, ZERO_BIG_DIGIT)
+ self.data);
return BigUint::new(vec_ng::append(Vec::from_elem(n_unit, ZERO_BIG_DIGIT),
self.data.as_slice()));
}
#[inline]
@ -761,13 +762,13 @@ impl BigUint {
if n_bits == 0 || self.is_zero() { return (*self).clone(); }
let mut carry = 0;
let mut shifted = self.data.iter().map(|elem| {
let mut shifted: Vec<BigDigit> = self.data.iter().map(|elem| {
let (hi, lo) = BigDigit::from_uint(
(*elem as uint) << n_bits | (carry as uint)
);
carry = hi;
lo
}).collect::<~[BigDigit]>();
}).collect();
if carry != 0 { shifted.push(carry); }
return BigUint::new(shifted);
}
@ -786,7 +787,7 @@ impl BigUint {
if n_bits == 0 || self.data.is_empty() { return (*self).clone(); }
let mut borrow = 0;
let mut shifted_rev = vec::with_capacity(self.data.len());
let mut shifted_rev = Vec::with_capacity(self.data.len());
for elem in self.data.rev_iter() {
shifted_rev.push((*elem >> n_bits) | borrow);
borrow = *elem << (BigDigit::bits - n_bits);
@ -1339,7 +1340,7 @@ pub trait RandBigInt {
impl<R: Rng> RandBigInt for R {
fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
let mut data = vec::with_capacity(digits+1);
let mut data = Vec::with_capacity(digits+1);
for _ in range(0, digits) {
data.push(self.gen());
}
@ -1402,7 +1403,7 @@ impl<R: Rng> RandBigInt for R {
impl BigInt {
/// Creates and initializes a BigInt.
#[inline]
pub fn new(sign: Sign, v: ~[BigDigit]) -> BigInt {
pub fn new(sign: Sign, v: Vec<BigDigit>) -> BigInt {
BigInt::from_biguint(sign, BigUint::new(v))
}
@ -1459,14 +1460,13 @@ mod biguint_tests {
use std::num::{ToPrimitive, FromPrimitive};
use std::num::CheckedDiv;
use rand::{task_rng};
use std::str;
use std::u64;
use std::vec;
use std::vec_ng::Vec;
#[test]
fn test_from_slice() {
fn check(slice: &[BigDigit], data: &[BigDigit]) {
assert!(data == BigUint::from_slice(slice).data);
assert!(data == BigUint::from_slice(slice).data.as_slice());
}
check([1], [1]);
check([0, 0, 0], []);
@ -1478,8 +1478,8 @@ mod biguint_tests {
#[test]
fn test_cmp() {
let data: ~[BigUint] = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
.map(|v| BigUint::from_slice(*v));
let data: Vec<BigUint> = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
.iter().map(|v| BigUint::from_slice(*v)).collect();
for (i, ni) in data.iter().enumerate() {
for (j0, nj) in data.slice(i, data.len()).iter().enumerate() {
let j = j0 + i;
@ -1515,44 +1515,44 @@ mod biguint_tests {
#[test]
fn test_bitand() {
fn check(left: ~[BigDigit],
right: ~[BigDigit],
expected: ~[BigDigit]) {
assert_eq!(BigUint::new(left) & BigUint::new(right),
BigUint::new(expected));
fn check(left: &[BigDigit],
right: &[BigDigit],
expected: &[BigDigit]) {
assert_eq!(BigUint::from_slice(left) & BigUint::from_slice(right),
BigUint::from_slice(expected));
}
check(~[], ~[], ~[]);
check(~[268, 482, 17],
~[964, 54],
~[260, 34]);
check([], [], []);
check([268, 482, 17],
[964, 54],
[260, 34]);
}
#[test]
fn test_bitor() {
fn check(left: ~[BigDigit],
right: ~[BigDigit],
expected: ~[BigDigit]) {
assert_eq!(BigUint::new(left) | BigUint::new(right),
BigUint::new(expected));
fn check(left: &[BigDigit],
right: &[BigDigit],
expected: &[BigDigit]) {
assert_eq!(BigUint::from_slice(left) | BigUint::from_slice(right),
BigUint::from_slice(expected));
}
check(~[], ~[], ~[]);
check(~[268, 482, 17],
~[964, 54],
~[972, 502, 17]);
check([], [], []);
check([268, 482, 17],
[964, 54],
[972, 502, 17]);
}
#[test]
fn test_bitxor() {
fn check(left: ~[BigDigit],
right: ~[BigDigit],
expected: ~[BigDigit]) {
assert_eq!(BigUint::new(left) ^ BigUint::new(right),
BigUint::new(expected));
fn check(left: &[BigDigit],
right: &[BigDigit],
expected: &[BigDigit]) {
assert_eq!(BigUint::from_slice(left) ^ BigUint::from_slice(right),
BigUint::from_slice(expected));
}
check(~[], ~[], ~[]);
check(~[268, 482, 17],
~[964, 54],
~[712, 468, 17]);
check([], [], []);
check([268, 482, 17],
[964, 54],
[712, 468, 17]);
}
#[test]
@ -1645,20 +1645,20 @@ mod biguint_tests {
check(One::one(), 1);
check(i64::MAX.to_biguint().unwrap(), i64::MAX);
check(BigUint::new(~[ ]), 0);
check(BigUint::new(~[ 1 ]), (1 << (0*BigDigit::bits)));
check(BigUint::new(~[-1 ]), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 1 ]), (1 << (1*BigDigit::bits)));
check(BigUint::new(~[-1, -1 ]), (1 << (2*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 0, 1 ]), (1 << (2*BigDigit::bits)));
check(BigUint::new(~[-1, -1, -1 ]), (1 << (3*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 0, 0, 1 ]), (1 << (3*BigDigit::bits)));
check(BigUint::new(~[-1, -1, -1, -1 >> 1]), i64::MAX);
check(BigUint::new(vec!( )), 0);
check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 1 )), (1 << (1*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1 )), (1 << (2*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 0, 1 )), (1 << (2*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1, -1 )), (1 << (3*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 0, 0, 1 )), (1 << (3*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1, -1, -1 >> 1)), i64::MAX);
assert_eq!(i64::MIN.to_biguint(), None);
assert_eq!(BigUint::new(~[-1, -1, -1, -1 ]).to_i64(), None);
assert_eq!(BigUint::new(~[ 0, 0, 0, 0, 1]).to_i64(), None);
assert_eq!(BigUint::new(~[-1, -1, -1, -1, -1]).to_i64(), None);
assert_eq!(BigUint::new(vec!(-1, -1, -1, -1 )).to_i64(), None);
assert_eq!(BigUint::new(vec!( 0, 0, 0, 0, 1)).to_i64(), None);
assert_eq!(BigUint::new(vec!(-1, -1, -1, -1, -1)).to_i64(), None);
}
#[cfg(target_word_size = "64")]
@ -1674,16 +1674,16 @@ mod biguint_tests {
check(One::one(), 1);
check(i64::MAX.to_biguint().unwrap(), i64::MAX);
check(BigUint::new(~[ ]), 0);
check(BigUint::new(~[ 1 ]), (1 << (0*BigDigit::bits)));
check(BigUint::new(~[-1 ]), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 1 ]), (1 << (1*BigDigit::bits)));
check(BigUint::new(~[-1, -1 >> 1]), i64::MAX);
check(BigUint::new(vec!( )), 0);
check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 1 )), (1 << (1*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1 >> 1)), i64::MAX);
assert_eq!(i64::MIN.to_biguint(), None);
assert_eq!(BigUint::new(~[-1, -1 ]).to_i64(), None);
assert_eq!(BigUint::new(~[ 0, 0, 1]).to_i64(), None);
assert_eq!(BigUint::new(~[-1, -1, -1]).to_i64(), None);
assert_eq!(BigUint::new(vec!(-1, -1 )).to_i64(), None);
assert_eq!(BigUint::new(vec!( 0, 0, 1)).to_i64(), None);
assert_eq!(BigUint::new(vec!(-1, -1, -1)).to_i64(), None);
}
#[cfg(target_word_size = "32")]
@ -1700,18 +1700,18 @@ mod biguint_tests {
check(u64::MIN.to_biguint().unwrap(), u64::MIN);
check(u64::MAX.to_biguint().unwrap(), u64::MAX);
check(BigUint::new(~[ ]), 0);
check(BigUint::new(~[ 1 ]), (1 << (0*BigDigit::bits)));
check(BigUint::new(~[-1 ]), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 1 ]), (1 << (1*BigDigit::bits)));
check(BigUint::new(~[-1, -1 ]), (1 << (2*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 0, 1 ]), (1 << (2*BigDigit::bits)));
check(BigUint::new(~[-1, -1, -1 ]), (1 << (3*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 0, 0, 1]), (1 << (3*BigDigit::bits)));
check(BigUint::new(~[-1, -1, -1, -1]), u64::MAX);
check(BigUint::new(vec!( )), 0);
check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 1 )), (1 << (1*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1 )), (1 << (2*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 0, 1 )), (1 << (2*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1, -1 )), (1 << (3*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 0, 0, 1)), (1 << (3*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1, -1, -1)), u64::MAX);
assert_eq!(BigUint::new(~[ 0, 0, 0, 0, 1]).to_u64(), None);
assert_eq!(BigUint::new(~[-1, -1, -1, -1, -1]).to_u64(), None);
assert_eq!(BigUint::new(vec!( 0, 0, 0, 0, 1)).to_u64(), None);
assert_eq!(BigUint::new(vec!(-1, -1, -1, -1, -1)).to_u64(), None);
}
#[cfg(target_word_size = "64")]
@ -1728,14 +1728,14 @@ mod biguint_tests {
check(u64::MIN.to_biguint().unwrap(), u64::MIN);
check(u64::MAX.to_biguint().unwrap(), u64::MAX);
check(BigUint::new(~[ ]), 0);
check(BigUint::new(~[ 1 ]), (1 << (0*BigDigit::bits)));
check(BigUint::new(~[-1 ]), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(~[ 0, 1]), (1 << (1*BigDigit::bits)));
check(BigUint::new(~[-1, -1]), u64::MAX);
check(BigUint::new(vec!( )), 0);
check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
check(BigUint::new(vec!( 0, 1)), (1 << (1*BigDigit::bits)));
check(BigUint::new(vec!(-1, -1)), u64::MAX);
assert_eq!(BigUint::new(~[ 0, 0, 1]).to_u64(), None);
assert_eq!(BigUint::new(~[-1, -1, -1]).to_u64(), None);
assert_eq!(BigUint::new(vec!( 0, 0, 1)).to_u64(), None);
assert_eq!(BigUint::new(vec!(-1, -1, -1)).to_u64(), None);
}
#[test]
@ -1745,8 +1745,8 @@ mod biguint_tests {
assert_eq!(n.to_bigint().unwrap().to_biguint().unwrap(), n);
}
check(Zero::zero(), Zero::zero());
check(BigUint::new(~[1,2,3]),
BigInt::from_biguint(Plus, BigUint::new(~[1,2,3])));
check(BigUint::new(vec!(1,2,3)),
BigInt::from_biguint(Plus, BigUint::new(vec!(1,2,3))));
}
static sum_triples: &'static [(&'static [BigDigit],
@ -2005,11 +2005,11 @@ mod biguint_tests {
assert!(((one << 64) + one).is_odd());
}
fn to_str_pairs() -> ~[ (BigUint, ~[(uint, ~str)]) ] {
fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, ~str)>)> {
let bits = BigDigit::bits;
~[( Zero::zero(), ~[
vec!(( Zero::zero(), vec!(
(2, ~"0"), (3, ~"0")
]), ( BigUint::from_slice([ 0xff ]), ~[
)), ( BigUint::from_slice([ 0xff ]), vec!(
(2, ~"11111111"),
(3, ~"100110"),
(4, ~"3333"),
@ -2025,41 +2025,41 @@ mod biguint_tests {
(14, ~"143"),
(15, ~"120"),
(16, ~"ff")
]), ( BigUint::from_slice([ 0xfff ]), ~[
)), ( BigUint::from_slice([ 0xfff ]), vec!(
(2, ~"111111111111"),
(4, ~"333333"),
(16, ~"fff")
]), ( BigUint::from_slice([ 1, 2 ]), ~[
)), ( BigUint::from_slice([ 1, 2 ]), vec!(
(2,
~"10" +
str::from_chars(vec::from_elem(bits - 1, '0')) + "1"),
"0".repeat(bits - 1) + "1"),
(4,
~"2" +
str::from_chars(vec::from_elem(bits / 2 - 1, '0')) + "1"),
"0".repeat(bits / 2 - 1) + "1"),
(10, match bits {
32 => ~"8589934593", 16 => ~"131073", _ => fail!()
}),
(16,
~"2" +
str::from_chars(vec::from_elem(bits / 4 - 1, '0')) + "1")
]), ( BigUint::from_slice([ 1, 2, 3 ]), ~[
"0".repeat(bits / 4 - 1) + "1")
)), ( BigUint::from_slice([ 1, 2, 3 ]), vec!(
(2,
~"11" +
str::from_chars(vec::from_elem(bits - 2, '0')) + "10" +
str::from_chars(vec::from_elem(bits - 1, '0')) + "1"),
"0".repeat(bits - 2) + "10" +
"0".repeat(bits - 1) + "1"),
(4,
~"3" +
str::from_chars(vec::from_elem(bits / 2 - 1, '0')) + "2" +
str::from_chars(vec::from_elem(bits / 2 - 1, '0')) + "1"),
"0".repeat(bits / 2 - 1) + "2" +
"0".repeat(bits / 2 - 1) + "1"),
(10, match bits {
32 => ~"55340232229718589441",
16 => ~"12885032961",
_ => fail!()
}),
(16, ~"3" +
str::from_chars(vec::from_elem(bits / 4 - 1, '0')) + "2" +
str::from_chars(vec::from_elem(bits / 4 - 1, '0')) + "1")
]) ]
"0".repeat(bits / 4 - 1) + "2" +
"0".repeat(bits / 4 - 1) + "1")
)) )
}
#[test]
@ -2122,7 +2122,7 @@ mod biguint_tests {
#[test]
fn test_bits() {
assert_eq!(BigUint::new(~[0,0,0,0]).bits(), 0);
assert_eq!(BigUint::new(vec!(0,0,0,0)).bits(), 0);
let n: BigUint = FromPrimitive::from_uint(0).unwrap();
assert_eq!(n.bits(), 0);
let n: BigUint = FromPrimitive::from_uint(1).unwrap();
@ -2195,6 +2195,7 @@ mod bigint_tests {
use std::num::{ToPrimitive, FromPrimitive};
use rand::{task_rng};
use std::u64;
use std::vec_ng::Vec;
#[test]
fn test_from_biguint() {
@ -2212,12 +2213,12 @@ mod bigint_tests {
#[test]
fn test_cmp() {
let vs = [ &[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1] ];
let mut nums = ~[];
let mut nums = Vec::new();
for s in vs.rev_iter() {
nums.push(BigInt::from_slice(Minus, *s));
}
nums.push(Zero::zero());
nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s)));
nums.extend(&mut vs.iter().map(|s| BigInt::from_slice(Plus, *s)));
for (i, ni) in nums.iter().enumerate() {
for (j0, nj) in nums.slice(i, nums.len()).iter().enumerate() {
@ -2270,15 +2271,15 @@ mod bigint_tests {
None);
assert_eq!(
BigInt::from_biguint(Plus, BigUint::new(~[1, 2, 3, 4, 5])).to_i64(),
BigInt::from_biguint(Plus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_i64(),
None);
assert_eq!(
BigInt::from_biguint(Minus, BigUint::new(~[1, 0, 0, 1<<(BigDigit::bits-1)])).to_i64(),
BigInt::from_biguint(Minus, BigUint::new(vec!(1,0,0,1<<(BigDigit::bits-1)))).to_i64(),
None);
assert_eq!(
BigInt::from_biguint(Minus, BigUint::new(~[1, 2, 3, 4, 5])).to_i64(),
BigInt::from_biguint(Minus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_i64(),
None);
}
@ -2296,12 +2297,12 @@ mod bigint_tests {
check(u64::MAX.to_bigint().unwrap(), u64::MAX);
assert_eq!(
BigInt::from_biguint(Plus, BigUint::new(~[1, 2, 3, 4, 5])).to_u64(),
BigInt::from_biguint(Plus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_u64(),
None);
let max_value: BigUint = FromPrimitive::from_u64(u64::MAX).unwrap();
assert_eq!(BigInt::from_biguint(Minus, max_value).to_u64(), None);
assert_eq!(BigInt::from_biguint(Minus, BigUint::new(~[1, 2, 3, 4, 5])).to_u64(), None);
assert_eq!(BigInt::from_biguint(Minus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_u64(), None);
}
#[test]
@ -2313,11 +2314,11 @@ mod bigint_tests {
let zero: BigInt = Zero::zero();
let unsigned_zero: BigUint = Zero::zero();
let positive = BigInt::from_biguint(
Plus, BigUint::new(~[1,2,3]));
Plus, BigUint::new(vec!(1,2,3)));
let negative = -positive;
check(zero, unsigned_zero);
check(positive, BigUint::new(~[1,2,3]));
check(positive, BigUint::new(vec!(1,2,3)));
assert_eq!(negative.to_biguint(), None);
}
@ -2715,10 +2716,10 @@ mod bigint_tests {
#[test]
fn test_neg() {
assert!(-BigInt::new(Plus, ~[1, 1, 1]) ==
BigInt::new(Minus, ~[1, 1, 1]));
assert!(-BigInt::new(Minus, ~[1, 1, 1]) ==
BigInt::new(Plus, ~[1, 1, 1]));
assert!(-BigInt::new(Plus, vec!(1, 1, 1)) ==
BigInt::new(Minus, vec!(1, 1, 1)));
assert!(-BigInt::new(Minus, vec!(1, 1, 1)) ==
BigInt::new(Plus, vec!(1, 1, 1)));
let zero: BigInt = Zero::zero();
assert_eq!(-zero, zero);
}

View File

@ -16,6 +16,7 @@ use std::cmp;
use std::fmt;
use std::from_str::FromStr;
use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
use std::vec_ng::Vec;
use bigint::{BigInt, BigUint, Sign, Plus, Minus};
/// Represents the ratio between 2 numbers.
@ -295,13 +296,13 @@ impl<T: FromStr + Clone + Integer + Ord>
FromStr for Ratio<T> {
/// Parses `numer/denom`.
fn from_str(s: &str) -> Option<Ratio<T>> {
let split: ~[&str] = s.splitn('/', 1).collect();
let split: Vec<&str> = s.splitn('/', 1).collect();
if split.len() < 2 {
return None
}
let a_option: Option<T> = FromStr::from_str(split[0]);
let a_option: Option<T> = FromStr::from_str(split.as_slice()[0]);
a_option.and_then(|a| {
let b_option: Option<T> = FromStr::from_str(split[1]);
let b_option: Option<T> = FromStr::from_str(split.as_slice()[1]);
b_option.and_then(|b| {
Some(Ratio::new(a.clone(), b.clone()))
})
@ -312,15 +313,15 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
FromStrRadix for Ratio<T> {
/// Parses `numer/denom` where the numbers are in base `radix`.
fn from_str_radix(s: &str, radix: uint) -> Option<Ratio<T>> {
let split: ~[&str] = s.splitn('/', 1).collect();
let split: Vec<&str> = s.splitn('/', 1).collect();
if split.len() < 2 {
None
} else {
let a_option: Option<T> = FromStrRadix::from_str_radix(split[0],
let a_option: Option<T> = FromStrRadix::from_str_radix(split.as_slice()[0],
radix);
a_option.and_then(|a| {
let b_option: Option<T> =
FromStrRadix::from_str_radix(split[1], radix);
FromStrRadix::from_str_radix(split.as_slice()[1], radix);
b_option.and_then(|b| {
Some(Ratio::new(a.clone(), b.clone()))
})