summaryrefslogtreecommitdiff
path: root/sem2/src/mpn.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sem2/src/mpn.rs')
-rw-r--r--sem2/src/mpn.rs40
1 files changed, 32 insertions, 8 deletions
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(());
}