Do you wish to register an account?
Browse Source

More work on parsing numbers from strings

master
Timothy Warren 2 months ago
parent
commit
b7f39a5cf7
1 changed files with 71 additions and 9 deletions
  1. +71
    -9
      src/bigint.rs

+ 71
- 9
src/bigint.rs View File

@@ -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() {
let str = "012345";
fn test_from_str_large() {
let str = "ZYXWVUTSRQPONMLKJIHGFEDCBA987654321";
BigInt::from(str);
}

#[test]
fn test_from_str_small() {
let str = "012345";
let num = BigInt::from(str);
assert_eq!(num.inner[0], 12345usize);
}

#[test]
#[should_panic]
fn test_from_string() {
let str = String::from("012345");
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 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…
Cancel
Save