diff --git a/src/bigint.rs b/src/bigint.rs index db59534..3c1c087 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -64,7 +64,7 @@ use std::default::Default; use std::from_str::FromStr; use std::num::CheckedDiv; use std::num::{ToPrimitive, FromPrimitive}; -use std::num::{Zero, One, ToStrRadix, FromStrRadix}; +use std::num::{Zero, One, FromStrRadix}; use std::string::String; use std::{uint, i64, u64}; @@ -169,7 +169,7 @@ impl hash::Hash for BigUint { impl fmt::Show for BigUint { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.to_str_radix(10)) + write!(f, "{}", to_str_radix(self, 10)) } } @@ -487,7 +487,7 @@ impl Integer for BigUint { return (Zero::zero(), Zero::zero(), (*a).clone()); } - let an = a.data.tailn(a.data.len() - n); + let an = a.data.slice_from(a.data.len() - n); let bn = *b.data.last().unwrap(); let mut d = Vec::with_capacity(an.len()); let mut carry = 0; @@ -653,42 +653,48 @@ impl_to_biguint!(u16, FromPrimitive::from_u16) impl_to_biguint!(u32, FromPrimitive::from_u32) impl_to_biguint!(u64, FromPrimitive::from_u64) -impl ToStrRadix for BigUint { - fn to_str_radix(&self, radix: uint) -> String { - assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]"); - let (base, max_len) = get_radix_base(radix); - if base == BigDigit::base { - return fill_concat(self.data.as_slice(), radix, max_len) - } - return fill_concat(convert_base(self, base).as_slice(), radix, max_len); +fn to_str_radix(me: &BigUint, radix: uint) -> String { + assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]"); + let (base, max_len) = get_radix_base(radix); + if base == BigDigit::base { + return fill_concat(me.data.as_slice(), radix, max_len) + } + return fill_concat(convert_base(me, base).as_slice(), radix, max_len); - fn convert_base(n: &BigUint, base: DoubleBigDigit) -> Vec { - let divider = base.to_biguint().unwrap(); - let mut result = Vec::new(); - let mut m = n.clone(); - while m >= divider { - let (d, m0) = m.div_mod_floor(÷r); - result.push(m0.to_uint().unwrap() as BigDigit); - m = d; - } - if !m.is_zero() { - result.push(m.to_uint().unwrap() as BigDigit); - } - return result; + fn convert_base(n: &BigUint, base: DoubleBigDigit) -> Vec { + let divider = base.to_biguint().unwrap(); + let mut result = Vec::new(); + let mut m = n.clone(); + while m >= divider { + let (d, m0) = m.div_mod_floor(÷r); + result.push(m0.to_uint().unwrap() as BigDigit); + m = d; } + if !m.is_zero() { + result.push(m.to_uint().unwrap() as BigDigit); + } + return result; + } - fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> String { - if v.is_empty() { - return "0".to_string() - } - let mut s = String::with_capacity(v.len() * l); - for n in v.iter().rev() { - let ss = (*n as uint).to_str_radix(radix); - s.push_str("0".repeat(l - ss.len()).as_slice()); - s.push_str(ss.as_slice()); - } - s.as_slice().trim_left_chars('0').to_string() + fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> String { + if v.is_empty() { + return "0".to_string() } + let mut s = String::with_capacity(v.len() * l); + for n in v.iter().rev() { + 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(ss.as_slice()); + } + s.as_slice().trim_left_chars('0').to_string() + } +} + +fn to_str_radix_signed(me: &BigInt, radix: uint) -> String { + match me.sign { + Plus => to_str_radix(&me.data, radix), + NoSign => "0".to_string(), + Minus => format!("-{}", to_str_radix(&me.data, radix)), } } @@ -717,7 +723,7 @@ impl BigUint { /// The digits are be in base 2^32. #[inline] pub fn from_slice(slice: &[BigDigit]) -> BigUint { - BigUint::new(Vec::from_slice(slice)) + BigUint::new(slice.to_vec()) } /// Creates and initializes a `BigUint`. @@ -761,7 +767,9 @@ impl BigUint { fn shl_unit(&self, n_unit: uint) -> BigUint { if n_unit == 0 || self.is_zero() { return (*self).clone(); } - BigUint::new(Vec::from_elem(n_unit, ZERO_BIG_DIGIT).append(self.data.as_slice())) + let mut v = Vec::from_elem(n_unit, ZERO_BIG_DIGIT); + v.push_all(self.data.as_slice()); + BigUint::new(v) } #[inline] @@ -894,7 +902,7 @@ impl Default for BigInt { impl fmt::Show for BigInt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.to_str_radix(10)) + write!(f, "{}", to_str_radix_signed(self, 10)) } } @@ -1265,17 +1273,6 @@ impl_to_bigint!(u16, FromPrimitive::from_u16) impl_to_bigint!(u32, FromPrimitive::from_u32) impl_to_bigint!(u64, FromPrimitive::from_u64) -impl ToStrRadix for BigInt { - #[inline] - fn to_str_radix(&self, radix: uint) -> String { - match self.sign { - Plus => self.data.to_str_radix(radix), - NoSign => "0".to_string(), - Minus => format!("-{}", self.data.to_str_radix(radix)), - } - } -} - impl FromStrRadix for BigInt { /// Creates and initializes a BigInt. #[inline] @@ -1422,13 +1419,13 @@ impl BigInt { #[cfg(test)] mod biguint_tests { use Integer; - use super::{BigDigit, BigUint, ToBigUint}; + use super::{BigDigit, BigUint, ToBigUint, to_str_radix, to_str_radix_signed}; use super::{Plus, BigInt, RandBigInt, ToBigInt}; use std::cmp::{Less, Equal, Greater}; use std::from_str::FromStr; use std::i64; - use std::num::{Zero, One, FromStrRadix, ToStrRadix}; + use std::num::{Zero, One, FromStrRadix}; use std::num::{ToPrimitive, FromPrimitive}; use std::num::CheckedDiv; use std::rand::task_rng; @@ -1544,7 +1541,7 @@ mod biguint_tests { fn test_shl() { fn check(s: &str, shift: uint, ans: &str) { let opt_biguint: Option = FromStrRadix::from_str_radix(s, 16); - let bu = (opt_biguint.unwrap() << shift).to_str_radix(16); + let bu = to_str_radix(&(opt_biguint.unwrap() << shift), 16); assert_eq!(bu.as_slice(), ans); } @@ -1666,7 +1663,7 @@ mod biguint_tests { fn check(s: &str, shift: uint, ans: &str) { let opt_biguint: Option = FromStrRadix::from_str_radix(s, 16); - let bu = (opt_biguint.unwrap() >> shift).to_str_radix(16); + let bu = to_str_radix(&(opt_biguint.unwrap() >> shift), 16); assert_eq!(bu.as_slice(), ans); } @@ -2166,7 +2163,7 @@ mod biguint_tests { let &(ref n, ref rs) = num_pair; for str_pair in rs.iter() { let &(ref radix, ref str) = str_pair; - assert_eq!(n.to_str_radix(*radix).as_slice(), + assert_eq!(to_str_radix(n, *radix).as_slice(), str.as_slice()); } } @@ -2291,7 +2288,7 @@ mod bigint_tests { use std::cmp::{Less, Equal, Greater}; use std::i64; use std::num::CheckedDiv; - use std::num::{Zero, One, FromStrRadix, ToStrRadix}; + use std::num::{Zero, One, FromStrRadix}; use std::num::{ToPrimitive, FromPrimitive}; use std::rand::task_rng; use std::u64; @@ -2792,20 +2789,6 @@ mod bigint_tests { assert_eq!(one.abs_sub(&-one), two); } - #[test] - fn test_to_str_radix() { - fn check(n: int, ans: &str) { - let n: BigInt = FromPrimitive::from_int(n).unwrap(); - assert!(ans == n.to_str_radix(10).as_slice()); - } - check(10, "10"); - check(1, "1"); - check(0, "0"); - check(-1, "-1"); - check(-10, "-10"); - } - - #[test] fn test_from_str_radix() { fn check(s: &str, ans: Option) { diff --git a/src/complex.rs b/src/complex.rs index 6690b1d..1ffac74 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -12,7 +12,7 @@ //! Complex numbers. use std::fmt; -use std::num::{Zero, One, ToStrRadix}; +use std::num::{Zero, One}; // FIXME #1284: handle complex NaN & infinity etc. This // probably doesn't map to C's _Complex correctly. @@ -172,20 +172,6 @@ impl fmt::Show for Complex { } } -impl ToStrRadix for Complex { - fn to_str_radix(&self, radix: uint) -> String { - if self.im < Zero::zero() { - format!("{}-{}i", - self.re.to_str_radix(radix), - (-self.im).to_str_radix(radix)) - } else { - format!("{}+{}i", - self.re.to_str_radix(radix), - self.im.to_str_radix(radix)) - } - } -} - #[cfg(test)] mod test { #![allow(non_uppercase_statics)] diff --git a/src/rational.rs b/src/rational.rs index 622f830..89a5bd7 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -16,7 +16,7 @@ use std::cmp; use std::fmt; use std::from_str::FromStr; use std::num; -use std::num::{Zero, One, ToStrRadix, FromStrRadix}; +use std::num::{Zero, One, FromStrRadix}; use bigint::{BigInt, BigUint, Sign, Plus, Minus}; @@ -344,15 +344,6 @@ impl fmt::Show for Ratio { } } -impl ToStrRadix for Ratio { - /// Renders as `numer/denom` where the numbers are in base `radix`. - fn to_str_radix(&self, radix: uint) -> String { - format!("{}/{}", - self.numer.to_str_radix(radix), - self.denom.to_str_radix(radix)) - } -} - impl FromStr for Ratio { /// Parses `numer/denom` or just `numer`. @@ -378,11 +369,11 @@ impl None } else { let a_option: Option = FromStrRadix::from_str_radix( - *split.get(0), + split[0], radix); a_option.and_then(|a| { let b_option: Option = - FromStrRadix::from_str_radix(*split.get(1), radix); + FromStrRadix::from_str_radix(split[1], radix); b_option.and_then(|b| { Some(Ratio::new(a.clone(), b.clone())) }) @@ -395,7 +386,7 @@ impl mod test { use super::{Ratio, Rational, BigRational}; - use std::num::{Zero, One, FromStrRadix, FromPrimitive, ToStrRadix}; + use std::num::{Zero, One, FromStrRadix, FromPrimitive}; use std::from_str::FromStr; use std::hash::hash; use std::num; @@ -700,48 +691,6 @@ mod test { } } - #[test] - fn test_to_from_str_radix() { - fn test(r: Rational, s: String, n: uint) { - assert_eq!(FromStrRadix::from_str_radix(s.as_slice(), n), - Some(r)); - assert_eq!(r.to_str_radix(n).to_string(), s); - } - fn test3(r: Rational, s: String) { test(r, s, 3) } - fn test16(r: Rational, s: String) { test(r, s, 16) } - - test3(_1, "1/1".to_string()); - test3(_0, "0/1".to_string()); - test3(_1_2, "1/2".to_string()); - test3(_3_2, "10/2".to_string()); - test3(_2, "2/1".to_string()); - test3(_NEG1_2, "-1/2".to_string()); - test3(_NEG1_2 / _2, "-1/11".to_string()); - - test16(_1, "1/1".to_string()); - test16(_0, "0/1".to_string()); - test16(_1_2, "1/2".to_string()); - test16(_3_2, "3/2".to_string()); - test16(_2, "2/1".to_string()); - test16(_NEG1_2, "-1/2".to_string()); - test16(_NEG1_2 / _2, "-1/4".to_string()); - test16(Ratio::new(13i,15i), "d/f".to_string()); - test16(_1_2*_1_2*_1_2*_1_2, "1/10".to_string()); - } - - #[test] - fn test_from_str_radix_fail() { - fn test(s: &str) { - let radix: Option = FromStrRadix::from_str_radix(s, 3); - assert_eq!(radix, None); - } - - let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"]; - for &s in xs.iter() { - test(s); - } - } - #[test] fn test_from_float() { fn test(given: T, (numer, denom): (&str, &str)) {