More work on parsing numbers from strings
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good
This commit is contained in:
parent
5b445add4b
commit
b7f39a5cf7
@ -135,7 +135,36 @@ impl BigInt {
|
||||
/// Only alphanumeric characters are considered, so exponents and
|
||||
/// other forms are not parsed
|
||||
pub fn from_str_radix<T: ToString>(s: T, radix: usize) -> BigInt {
|
||||
let input = s.to_string();
|
||||
let input = s.to_string().to_ascii_uppercase();
|
||||
let input = input.trim();
|
||||
|
||||
assert!(
|
||||
radix > 0 && radix <= 36,
|
||||
"Radix must be between 1 and 36, inclusive. Given radix: {}",
|
||||
radix
|
||||
);
|
||||
|
||||
// In base 1, number of place values = total value
|
||||
if radix == 1 {
|
||||
let mut raw_digits: Vec<usize> = Vec::with_capacity(input.len());
|
||||
for char in input.chars() {
|
||||
match char {
|
||||
'1' => raw_digits.push(1),
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
return BigInt::from(raw_digits.len());
|
||||
}
|
||||
|
||||
// If the number fits in a usize, try the easy way
|
||||
let easy_res = usize::from_str_radix(input, radix as u32);
|
||||
if easy_res.is_ok() {
|
||||
return BigInt::from(easy_res.unwrap());
|
||||
}
|
||||
|
||||
// TODO: consider parsing out the error, to tell if the
|
||||
// parsed result is valid for the base
|
||||
|
||||
// Convert each digit to it's decimal representation
|
||||
let mut raw_digits: Vec<usize> = Vec::with_capacity(input.len());
|
||||
@ -148,8 +177,6 @@ impl BigInt {
|
||||
|
||||
// Calculate the decimal value by calculating the value
|
||||
// of each place value
|
||||
|
||||
// In base 1, number of place values = total value
|
||||
todo!();
|
||||
}
|
||||
|
||||
@ -907,21 +934,56 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_from_str() {
|
||||
fn test_from_str_large() {
|
||||
let str = "ZYXWVUTSRQPONMLKJIHGFEDCBA987654321";
|
||||
BigInt::from(str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_small() {
|
||||
let str = "012345";
|
||||
BigInt::from(str);
|
||||
let num = BigInt::from(str);
|
||||
assert_eq!(num.inner[0], 12345usize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_from_string() {
|
||||
fn test_from_string_large() {
|
||||
let str = String::from("ZYXWVUTSRQPONMLKJIHGFEDCBA987654321");
|
||||
BigInt::from(str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_string_small() {
|
||||
let str = String::from("012345");
|
||||
BigInt::from(str);
|
||||
let num = BigInt::from(str);
|
||||
assert_eq!(num.inner[0], 12345usize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_radix_1() {
|
||||
let s = "1".repeat(32);
|
||||
let num = BigInt::from_str_radix(s, 1);
|
||||
assert_eq!(num.inner[0], 32usize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_from_str_radix() {
|
||||
BigInt::from_str_radix("123456", 16);
|
||||
fn test_from_str_radix_large() {
|
||||
BigInt::from_str_radix("ZYXWVUTSRQPONMLKJIHGFEDCBA987654321", 36);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_radix_small() {
|
||||
let num = BigInt::from_str_radix("FEDCBA", 16);
|
||||
assert!(num.inner[0] > 0, "Number is not greater than 0");
|
||||
assert!(num.inner[0] < usize::MAX, "Result is larger than usize");
|
||||
assert_eq!(num.inner[0], 0xFEDCBAusize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_radix_lowercase() {
|
||||
let num = BigInt::from_str_radix("fedcba", 16);
|
||||
assert_eq!(num.inner[0], 0xFEDCBAusize);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user