aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/format/mod.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/format/mod.rs b/src/format/mod.rs
new file mode 100644
index 0000000..4ac5612
--- /dev/null
+++ b/src/format/mod.rs
@@ -0,0 +1,86 @@
1use crate::CONFIGURATION;
2use crate::error::{
3 CalcError,
4 Math
5};
6
7pub fn autobalance_parens(input: &str) -> Result<String, CalcError> {
8 let mut balanced = String::from(input);
9 let mut left_parens = 0;
10 let mut right_parens = 0;
11 for letter in input.chars() {
12 if letter == '(' {
13 left_parens += 1;
14 } else if letter == ')' {
15 right_parens += 1;
16 }
17 }
18
19 if left_parens > right_parens {
20 let extras = ")".repeat(left_parens - right_parens);
21 balanced.push_str(&extras[..]);
22 Ok(balanced)
23 } else if left_parens < right_parens {
24 return Err(CalcError::Syntax("Mismatched parentheses!".into()))
25 } else {
26 Ok(balanced)
27 }
28}
29
30fn radix_fmt(number: f64, obase: usize) -> Result<String, CalcError> {
31 if obase > 36 {
32 return Err(CalcError::Math(Math::UnknownBase));
33 }
34
35 let table: Vec<char> = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars().collect();
36
37 // format integral part of float
38 let mut integral = number.trunc() as i64;
39 let mut obase_int = String::new();
40 while integral >= obase as i64 {
41 obase_int.push(table[(integral % obase as i64) as usize]);
42 integral /= obase as i64;
43 }
44 obase_int.push(table[integral as usize]);
45 if number.is_sign_negative() {
46 obase_int.push('-');
47 }
48 let obase_int = obase_int.chars().rev().collect::<String>();
49
50 // format fractional part of float
51 let mut fract = number.abs().fract();
52 let mut obase_fract = String::new();
53 let mut i = 0;
54 loop {
55 fract *= obase as f64;
56 obase_fract.push(table[fract.trunc() as usize]);
57 i += 1;
58 if fract.fract() == 0. || i > 10 {
59 break;
60 }
61 fract = fract.fract();
62 }
63 Ok(format!("{}.{}", obase_int, obase_fract))
64}
65
66fn thousand_sep(inp: &str) -> String {
67 let mut result_string = String::new();
68 for (i,c) in inp.to_string().chars().rev().enumerate() {
69 if i % 3 == 0 && i != 0 && c.to_string() != "-" {
70 result_string.push(',');
71 }
72 result_string.push(c)
73 }
74 result_string.chars().rev().collect::<String>()
75}
76
77pub fn pprint(ans: f64) {
78 let ans_string = radix_fmt(ans, CONFIGURATION.base).unwrap();
79 let ans_vector: Vec<&str> = ans_string.split(".").collect();
80 match ans_vector.len() {
81 1 => println!("{:>10}", thousand_sep(ans_vector[0])),
82 2 => println!("{:>10}.{}", thousand_sep(ans_vector[0]),ans_vector[1]),
83 _ => unreachable!("N-nani?!")
84 }
85}
86