Merge pull request #22 from gifnksm/master

bigint: Remove `parse_bytes` method
This commit is contained in:
Alex Crichton 2014-11-04 17:16:33 -06:00
commit b27db91313
4 changed files with 66 additions and 66 deletions

View File

@ -67,7 +67,7 @@ use std::num::{ToPrimitive, FromPrimitive};
use std::num::{Zero, One, FromStrRadix}; use std::num::{Zero, One, FromStrRadix};
use std::str; use std::str;
use std::string::String; use std::string::String;
use std::{uint, i64, u64}; use std::{i64, u64};
/// A `BigDigit` is a `BigUint`'s composing element. /// A `BigDigit` is a `BigUint`'s composing element.
pub type BigDigit = u32; pub type BigDigit = u32;
@ -294,8 +294,8 @@ impl Mul<BigUint, BigUint> for 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());
if s_len == 1 { return mul_digit(other, self.data.as_slice()[0]); } if s_len == 1 { return mul_digit(other, self.data[0]); }
if o_len == 1 { return mul_digit(self, other.data.as_slice()[0]); } if o_len == 1 { return mul_digit(self, other.data[0]); }
// Using Karatsuba multiplication // Using Karatsuba multiplication
// (a1 * base + a0) * (b1 * base + b0) // (a1 * base + a0) * (b1 * base + b0)
@ -340,8 +340,8 @@ impl Mul<BigUint, BigUint> for BigUint {
#[inline] #[inline]
fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) {
let mid = cmp::min(a.data.len(), n); let mid = cmp::min(a.data.len(), n);
return (BigUint::from_slice(a.data.slice(mid, a.data.len())), (BigUint::from_slice(a.data[mid ..]),
BigUint::from_slice(a.data.slice(0, mid))); BigUint::from_slice(a.data[.. mid]))
} }
#[inline] #[inline]
@ -488,7 +488,7 @@ impl Integer for BigUint {
return (Zero::zero(), Zero::zero(), (*a).clone()); return (Zero::zero(), Zero::zero(), (*a).clone());
} }
let an = a.data.slice_from(a.data.len() - n); let an = a.data[a.data.len() - n ..];
let bn = *b.data.last().unwrap(); 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; let mut carry = 0;
@ -545,7 +545,7 @@ impl Integer for BigUint {
#[inline] #[inline]
fn is_even(&self) -> bool { fn is_even(&self) -> bool {
// Considering only the last digit. // Considering only the last digit.
match self.data.as_slice().head() { match self.data.head() {
Some(x) => x.is_even(), Some(x) => x.is_even(),
None => true None => true
} }
@ -574,8 +574,8 @@ impl ToPrimitive for BigUint {
fn to_u64(&self) -> Option<u64> { fn to_u64(&self) -> Option<u64> {
match self.data.len() { match self.data.len() {
0 => Some(0), 0 => Some(0),
1 => Some(self.data.as_slice()[0] as u64), 1 => Some(self.data[0] as u64),
2 => Some(BigDigit::to_doublebigdigit(self.data.as_slice()[1], self.data.as_slice()[0]) 2 => Some(BigDigit::to_doublebigdigit(self.data[1], self.data[0])
as u64), as u64),
_ => None _ => None
} }
@ -658,9 +658,9 @@ fn to_str_radix(me: &BigUint, radix: uint) -> String {
assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]"); assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]");
let (base, max_len) = get_radix_base(radix); let (base, max_len) = get_radix_base(radix);
if base == BigDigit::base { if base == BigDigit::base {
return fill_concat(me.data.as_slice(), radix, max_len) return fill_concat(me.data[], radix, max_len)
} }
return fill_concat(convert_base(me, base).as_slice(), radix, max_len); return fill_concat(convert_base(me, base)[], radix, max_len);
fn convert_base(n: &BigUint, base: DoubleBigDigit) -> Vec<BigDigit> { fn convert_base(n: &BigUint, base: DoubleBigDigit) -> Vec<BigDigit> {
let divider = base.to_biguint().unwrap(); let divider = base.to_biguint().unwrap();
@ -684,10 +684,10 @@ fn to_str_radix(me: &BigUint, radix: uint) -> String {
let mut s = String::with_capacity(v.len() * l); let mut s = String::with_capacity(v.len() * l);
for n in v.iter().rev() { for n in v.iter().rev() {
let ss = fmt::radix(*n as uint, radix as u8).to_string(); let ss = fmt::radix(*n as uint, radix as u8).to_string();
s.push_str("0".repeat(l - ss.len()).as_slice()); s.push_str("0".repeat(l - ss.len())[]);
s.push_str(ss.as_slice()); s.push_str(ss[]);
} }
s.as_slice().trim_left_chars('0').to_string() s.trim_left_chars('0').to_string()
} }
} }
@ -703,7 +703,39 @@ impl FromStrRadix for BigUint {
/// Creates and initializes a `BigUint`. /// Creates and initializes a `BigUint`.
#[inline] #[inline]
fn from_str_radix(s: &str, radix: uint) -> Option<BigUint> { fn from_str_radix(s: &str, radix: uint) -> Option<BigUint> {
BigUint::parse_bytes(s.as_bytes(), radix) let (base, unit_len) = get_radix_base(radix);
let base_num = match base.to_biguint() {
Some(base_num) => base_num,
None => { return None; }
};
let mut end = s.len();
let mut n: BigUint = Zero::zero();
let mut power: BigUint = One::one();
loop {
let start = cmp::max(end, unit_len) - unit_len;
match FromStrRadix::from_str_radix(s[start .. end], radix) {
Some(d) => {
let d: Option<BigUint> = FromPrimitive::from_uint(d);
match d {
Some(d) => {
// FIXME(#5992): assignment operator overloads
// n += d * power;
n = n + d * power;
}
None => { return None; }
}
}
None => { return None; }
}
if end <= unit_len {
return Some(n);
}
end -= unit_len;
// FIXME(#5992): assignment operator overloads
// power *= base_num;
power = power * base_num;
}
} }
} }
@ -728,42 +760,9 @@ impl BigUint {
} }
/// Creates and initializes a `BigUint`. /// Creates and initializes a `BigUint`.
#[inline]
pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> { pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
let (base, unit_len) = get_radix_base(radix); str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix))
let base_num = match base.to_biguint() {
Some(base_num) => base_num,
None => { return None; }
};
let mut end = buf.len();
let mut n: BigUint = Zero::zero();
let mut power: BigUint = One::one();
loop {
let start = cmp::max(end, unit_len) - unit_len;
match str::from_utf8(buf.slice(start, end)).and_then(|s| {
FromStrRadix::from_str_radix(s, radix)
}) {
Some(d) => {
let d: Option<BigUint> = FromPrimitive::from_uint(d);
match d {
Some(d) => {
// FIXME(#5992): assignment operator overloads
// n += d * power;
n = n + d * power;
}
None => { return None; }
}
}
None => { return None; }
}
if end <= unit_len {
return Some(n);
}
end -= unit_len;
// FIXME(#5992): assignment operator overloads
// power *= base_num;
power = power * base_num;
}
} }
#[inline] #[inline]
@ -771,7 +770,7 @@ impl BigUint {
if n_unit == 0 || self.is_zero() { return (*self).clone(); } if n_unit == 0 || self.is_zero() { return (*self).clone(); }
let mut v = Vec::from_elem(n_unit, ZERO_BIG_DIGIT); let mut v = Vec::from_elem(n_unit, ZERO_BIG_DIGIT);
v.push_all(self.data.as_slice()); v.push_all(self.data[]);
BigUint::new(v) BigUint::new(v)
} }
@ -795,9 +794,7 @@ impl BigUint {
fn shr_unit(&self, n_unit: uint) -> BigUint { fn shr_unit(&self, n_unit: uint) -> BigUint {
if n_unit == 0 { return (*self).clone(); } if n_unit == 0 { return (*self).clone(); }
if self.data.len() < n_unit { return Zero::zero(); } if self.data.len() < n_unit { return Zero::zero(); }
return BigUint::from_slice( BigUint::from_slice(self.data[n_unit ..])
self.data.slice(n_unit, self.data.len())
);
} }
#[inline] #[inline]
@ -1280,7 +1277,15 @@ impl FromStrRadix for BigInt {
/// Creates and initializes a BigInt. /// Creates and initializes a BigInt.
#[inline] #[inline]
fn from_str_radix(s: &str, radix: uint) -> Option<BigInt> { fn from_str_radix(s: &str, radix: uint) -> Option<BigInt> {
BigInt::parse_bytes(s.as_bytes(), radix) if s.is_empty() { return None; }
let mut sign = Plus;
let mut start = 0;
if s.starts_with("-") {
sign = Minus;
start = 1;
}
FromStrRadix::from_str_radix(s[start ..], radix)
.map(|bu| BigInt::from_biguint(sign, bu))
} }
} }
@ -1396,18 +1401,12 @@ impl BigInt {
} }
/// Creates and initializes a `BigInt`. /// Creates and initializes a `BigInt`.
#[inline]
pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigInt> { pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigInt> {
if buf.is_empty() { return None; } str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix))
let mut sign = Plus;
let mut start = 0;
if buf[0] == b'-' {
sign = Minus;
start = 1;
}
return BigUint::parse_bytes(buf.slice(start, buf.len()), radix)
.map(|bu| BigInt::from_biguint(sign, bu));
} }
/// Converts this `BigInt` into a `BigUint`, if it's not negative. /// Converts this `BigInt` into a `BigUint`, if it's not negative.
#[inline] #[inline]
pub fn to_biguint(&self) -> Option<BigUint> { pub fn to_biguint(&self) -> Option<BigUint> {

View File

@ -174,7 +174,7 @@ impl<T: fmt::Show + Num + PartialOrd> fmt::Show for Complex<T> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#![allow(non_uppercase_statics)] #![allow(non_upper_case_globals)]
use super::{Complex64, Complex}; use super::{Complex64, Complex};
use std::num::{Zero, One, Float}; use std::num::{Zero, One, Float};

View File

@ -44,6 +44,7 @@
#![feature(macro_rules)] #![feature(macro_rules)]
#![feature(default_type_params)] #![feature(default_type_params)]
#![feature(slicing_syntax)]
#![crate_name = "num"] #![crate_name = "num"]
#![experimental] #![experimental]

View File

@ -668,7 +668,7 @@ mod test {
#[test] #[test]
fn test_to_from_str() { fn test_to_from_str() {
fn test(r: Rational, s: String) { fn test(r: Rational, s: String) {
assert_eq!(FromStr::from_str(s.as_slice()), Some(r)); assert_eq!(FromStr::from_str(s[]), Some(r));
assert_eq!(r.to_string(), s); assert_eq!(r.to_string(), s);
} }
test(_1, "1".to_string()); test(_1, "1".to_string());