diff options
| author | Andrew Guschin <guschin.drew@gmail.com> | 2023-02-16 21:43:45 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin.drew@gmail.com> | 2023-02-16 21:43:45 +0400 |
| commit | ad8ba9184d4c3b6eff9d251a8677853075975fce (patch) | |
| tree | d75028f9033cd9434abd5211c886c2b8d6cf7f65 | |
| parent | b57d081d9bcbe15870ba6d9cf98bb38f188e63ee (diff) | |
Добавлена поддержка недесятичных систем счисления и обработка ошибок
| -rw-r--r-- | sem2/src/main.rs | 44 | ||||
| -rw-r--r-- | sem2/src/mpn.rs | 40 |
2 files changed, 70 insertions, 14 deletions
diff --git a/sem2/src/main.rs b/sem2/src/main.rs index f60350d..ed33b43 100644 --- a/sem2/src/main.rs +++ b/sem2/src/main.rs @@ -2,10 +2,42 @@ use inquire::Text; mod mpn; fn main() { - let a = Text::new("Введите число:").prompt().unwrap(); - let a = mpn::Number::parse(&a).unwrap(); - let b = Text::new("Введите число:").prompt().unwrap(); - let b = mpn::Number::parse(&b).unwrap(); - let c = a + b; - println!("Number: {}", c); + let radix = match Text::new("Введите основание системы счисления:").prompt() + { + Ok(text) => text, + Err(_) => return, + }; + let radix = match radix.parse::<usize>() { + Ok(number) => number, + Err(_) => { + println!("Основание должно быть десятичным числом"); + return; + } + }; + + let a = match Text::new("Введите число:").prompt() { + Ok(text) => text, + Err(_) => return, + }; + let a = match mpn::Number::parse(&a, radix) { + Ok(number) => number, + Err(what) => { + println!("{what}"); + return; + } + }; + + let b = match Text::new("Введите число:").prompt() { + Ok(text) => text, + Err(_) => return, + }; + let b = match mpn::Number::parse(&b, radix) { + Ok(number) => number, + Err(what) => { + println!("{what}"); + return; + } + }; + + println!("Сумма: {}", a + b); } diff --git a/sem2/src/mpn.rs b/sem2/src/mpn.rs index 27f94e0..ecc1d5c 100644 --- a/sem2/src/mpn.rs +++ b/sem2/src/mpn.rs @@ -8,16 +8,21 @@ pub struct Number { } impl Number { - pub fn parse(snum: &str) -> Result<Number, &str> { - let radix = 10_usize; + pub fn parse(snum: &str, radix: usize) -> Result<Number, &str> { let snum = snum.as_bytes(); let mut digits = Vec::new(); for i in (0..snum.len()).rev() { - let digit = snum[i] - '0' as u8; - if digit as usize >= radix { - return Err("Аргумент не является числом"); - } else { - digits.push(digit); + match Number::parse_digit(snum[i]) { + Some(digit) => { + if digit as usize >= radix { + return Err("Аргумент не является числом"); + } else { + digits.push(digit); + } + } + None => { + return Err("Аргумент не является числом"); + } } } return Ok(Number { radix, digits }); @@ -26,12 +31,31 @@ impl Number { pub fn len(&self) -> usize { self.digits.len() } + + fn parse_digit(c: u8) -> Option<u8> { + if c >= 'a' as u8 { + Some(c - 'a' as u8 + 10_u8) + } else if c >= '0' as u8 { + Some(c - '0' as u8) + } else { + None + } + } } impl fmt::Display for Number { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for i in (0..self.digits.len()).rev() { - write!(f, "{}", self.digits[i])?; + let digit = if self.digits[i] > 9 { + ('a' as u8 - 10 + self.digits[i]) as char + } else { + ('0' as u8 + self.digits[i]) as char + }; + write!(f, "{}", digit)?; + } + + if self.radix != 10 { + write!(f, "_{}", self.radix)?; } return Ok(()); } |