|
@@ -67,7 +67,7 @@ use std::num::{ToPrimitive, FromPrimitive};
|
|
|
use std::num::{Zero, One, FromStrRadix};
|
|
|
use std::str;
|
|
|
use std::string::String;
|
|
|
-use std::{uint, i64, u64};
|
|
|
+use std::{i64, u64};
|
|
|
|
|
|
/// A `BigDigit` is a `BigUint`'s composing element.
|
|
|
pub type BigDigit = u32;
|
|
@@ -703,46 +703,18 @@ impl FromStrRadix for BigUint {
|
|
|
/// Creates and initializes a `BigUint`.
|
|
|
#[inline]
|
|
|
fn from_str_radix(s: &str, radix: uint) -> Option<BigUint> {
|
|
|
- BigUint::parse_bytes(s.as_bytes(), radix)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl BigUint {
|
|
|
- /// Creates and initializes a `BigUint`.
|
|
|
- ///
|
|
|
- /// The digits are be in base 2^32.
|
|
|
- #[inline]
|
|
|
- pub fn new(mut digits: Vec<BigDigit>) -> BigUint {
|
|
|
- // omit trailing zeros
|
|
|
- let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
|
|
|
- digits.truncate(new_len);
|
|
|
- BigUint { data: digits }
|
|
|
- }
|
|
|
-
|
|
|
- /// Creates and initializes a `BigUint`.
|
|
|
- ///
|
|
|
- /// The digits are be in base 2^32.
|
|
|
- #[inline]
|
|
|
- pub fn from_slice(slice: &[BigDigit]) -> BigUint {
|
|
|
- BigUint::new(slice.to_vec())
|
|
|
- }
|
|
|
-
|
|
|
- /// Creates and initializes a `BigUint`.
|
|
|
- pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
|
|
|
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 = buf.len();
|
|
|
- let mut n: BigUint = Zero::zero();
|
|
|
- let mut power: BigUint = One::one();
|
|
|
+ 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 str::from_utf8(buf.slice(start, end)).and_then(|s| {
|
|
|
- FromStrRadix::from_str_radix(s, radix)
|
|
|
- }) {
|
|
|
+ match FromStrRadix::from_str_radix(s.slice(start, end), radix) {
|
|
|
Some(d) => {
|
|
|
let d: Option<BigUint> = FromPrimitive::from_uint(d);
|
|
|
match d {
|
|
@@ -765,6 +737,33 @@ impl BigUint {
|
|
|
power = power * base_num;
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+impl BigUint {
|
|
|
+ /// Creates and initializes a `BigUint`.
|
|
|
+ ///
|
|
|
+ /// The digits are be in base 2^32.
|
|
|
+ #[inline]
|
|
|
+ pub fn new(mut digits: Vec<BigDigit>) -> BigUint {
|
|
|
+ // omit trailing zeros
|
|
|
+ let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
|
|
|
+ digits.truncate(new_len);
|
|
|
+ BigUint { data: digits }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Creates and initializes a `BigUint`.
|
|
|
+ ///
|
|
|
+ /// The digits are be in base 2^32.
|
|
|
+ #[inline]
|
|
|
+ pub fn from_slice(slice: &[BigDigit]) -> BigUint {
|
|
|
+ BigUint::new(slice.to_vec())
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Creates and initializes a `BigUint`.
|
|
|
+ #[inline]
|
|
|
+ pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
|
|
|
+ str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix))
|
|
|
+ }
|
|
|
|
|
|
#[inline]
|
|
|
fn shl_unit(&self, n_unit: uint) -> BigUint {
|
|
@@ -1280,7 +1279,15 @@ impl FromStrRadix for BigInt {
|
|
|
/// Creates and initializes a BigInt.
|
|
|
#[inline]
|
|
|
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.slice_from(start), radix)
|
|
|
+ .map(|bu| BigInt::from_biguint(sign, bu))
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1396,18 +1403,12 @@ impl BigInt {
|
|
|
}
|
|
|
|
|
|
/// Creates and initializes a `BigInt`.
|
|
|
+ #[inline]
|
|
|
pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigInt> {
|
|
|
- if buf.is_empty() { return None; }
|
|
|
- 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));
|
|
|
+ str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix))
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/// Converts this `BigInt` into a `BigUint`, if it's not negative.
|
|
|
#[inline]
|
|
|
pub fn to_biguint(&self) -> Option<BigUint> {
|