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
|
/// Only alphanumeric characters are considered, so exponents and
|
||||||
/// other forms are not parsed
|
/// other forms are not parsed
|
||||||
pub fn from_str_radix<T: ToString>(s: T, radix: usize) -> BigInt {
|
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
|
// Convert each digit to it's decimal representation
|
||||||
let mut raw_digits: Vec<usize> = Vec::with_capacity(input.len());
|
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
|
// Calculate the decimal value by calculating the value
|
||||||
// of each place value
|
// of each place value
|
||||||
|
|
||||||
// In base 1, number of place values = total value
|
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,21 +934,56 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[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";
|
let str = "012345";
|
||||||
BigInt::from(str);
|
let num = BigInt::from(str);
|
||||||
|
assert_eq!(num.inner[0], 12345usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[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");
|
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]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_from_str_radix() {
|
fn test_from_str_radix_large() {
|
||||||
BigInt::from_str_radix("123456", 16);
|
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