diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs index 7facf3e..3c7c815 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -85,7 +85,7 @@ fn main() { | |||
85 | } | 85 | } |
86 | 86 | ||
87 | fn pprint(ans: f64) { | 87 | fn pprint(ans: f64) { |
88 | let ans_string = format!("{:.*}", CONFIGURATION.fix, ans); | 88 | let ans_string = radix_fmt(ans, CONFIGURATION.base).unwrap(); |
89 | let ans_vector: Vec<&str> = ans_string.split(".").collect(); | 89 | let ans_vector: Vec<&str> = ans_string.split(".").collect(); |
90 | match ans_vector.len() { | 90 | match ans_vector.len() { |
91 | 1 => println!("{:>10}", thousand_sep(ans_vector[0])), | 91 | 1 => println!("{:>10}", thousand_sep(ans_vector[0])), |
@@ -94,6 +94,42 @@ fn pprint(ans: f64) { | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | fn radix_fmt(number: f64, obase: usize) -> Result<String, CalcError> { | ||
98 | if obase > 36 { | ||
99 | return Err(CalcError::Syntax("Unknown base".into())); | ||
100 | } | ||
101 | |||
102 | let table: Vec<char> = "0123456789abcdefghijklmnopqrstuvwxyz".chars().collect(); | ||
103 | |||
104 | // format integral part of float | ||
105 | let mut integral = number.trunc() as i64; | ||
106 | let mut obase_int = String::new(); | ||
107 | while integral >= obase as i64 { | ||
108 | obase_int.push(table[(integral % obase as i64) as usize]); | ||
109 | integral /= obase as i64; | ||
110 | } | ||
111 | obase_int.push(table[integral as usize]); | ||
112 | if number.is_sign_negative() { | ||
113 | obase_int.push('-'); | ||
114 | } | ||
115 | let obase_int = obase_int.chars().rev().collect::<String>(); | ||
116 | |||
117 | // format fractional part of float | ||
118 | let mut fract = number.abs().fract(); | ||
119 | let mut obase_fract = String::new(); | ||
120 | let mut i = 0; | ||
121 | loop { | ||
122 | fract *= obase as f64; | ||
123 | obase_fract.push(table[fract.trunc() as usize]); | ||
124 | i += 1; | ||
125 | if fract.fract() == 0. || i > 10 { | ||
126 | break; | ||
127 | } | ||
128 | fract = fract.fract(); | ||
129 | } | ||
130 | Ok(format!("{}.{}", obase_int, obase_fract)) | ||
131 | } | ||
132 | |||
97 | fn thousand_sep(inp: &str) -> String { | 133 | fn thousand_sep(inp: &str) -> String { |
98 | let mut result_string = String::new(); | 134 | let mut result_string = String::new(); |
99 | for (i,c) in inp.to_string().chars().rev().enumerate(){ | 135 | for (i,c) in inp.to_string().chars().rev().enumerate(){ |
@@ -178,11 +214,12 @@ fn eval_math_expression(input: &str) -> Result<f64, CalcError> { | |||
178 | if input.len() == 0 { | 214 | if input.len() == 0 { |
179 | return Ok(0.) | 215 | return Ok(0.) |
180 | } | 216 | } |
181 | let input = autobalance_parens(&input[..])?; | 217 | let input = autobalance_parens(&input[..])?; |
182 | let lexed = lexer(&input[..])?; | 218 | let lexed = lexer(&input[..])?; |
183 | let postfixed = to_postfix(lexed)?; | 219 | let postfixed = to_postfix(lexed)?; |
184 | let evaled = eval_postfix(postfixed)?; | 220 | let evaled = eval_postfix(postfixed)?; |
185 | Ok(evaled) | 221 | let evaled_fixed = format!("{:.*}", CONFIGURATION.fix, evaled).parse::<f64>().unwrap(); |
222 | Ok(evaled_fixed) | ||
186 | } | 223 | } |
187 | 224 | ||
188 | #[cfg(test)] | 225 | #[cfg(test)] |