Compare commits

..
3 changed files with 18 additions and 58 deletions

View file

@ -8,6 +8,24 @@ use rug::Float;
mod nodes; mod nodes;
pub fn parse_and_calc(s: &str) -> Float {
nodes::Nodes::from_str(s).unwrap().evaluate()
}
pub fn get_significant_digits(n: &Float) -> usize {
let raw_string = format!("{n}");
let mut significant_digits = raw_string.len() - 1;
for (i, _) in raw_string.char_indices() {
if !raw_string[i..raw_string.len()].contains(|c| matches!(c, '1'..'9')) {
significant_digits = i;
break;
}
}
significant_digits
}
fn main() { fn main() {
let input = match env::args().skip(1).reduce(|x, a| a + &x) { let input = match env::args().skip(1).reduce(|x, a| a + &x) {
Some(s) => s, Some(s) => s,
@ -20,59 +38,5 @@ fn main() {
let result = parse_and_calc(&input); let result = parse_and_calc(&input);
println!("{result:.0$}", get_significant_digits(&result)); println!("{result:.0$}", get_significant_digits(&result).clamp(0, 6));
}
pub fn parse_and_calc(s: &str) -> Float {
nodes::Nodes::from_str(s).unwrap().evaluate()
}
pub fn get_significant_digits(n: &Float) -> usize {
let raw_string = format!("{n}");
let mut significant_digits = raw_string.len() - 1;
let mut consecutive_zeros = 0;
let mut consecutive_nines = 0;
for (i, c) in raw_string.char_indices() {
if c == '0' {
consecutive_zeros += 1;
} else {
consecutive_zeros = 0;
}
if c == '9' {
consecutive_nines += 1;
} else {
consecutive_nines = 0;
}
if consecutive_zeros >= 10 {
significant_digits = i - consecutive_zeros;
break;
} else if consecutive_nines >= 10 {
significant_digits = i - consecutive_nines;
break;
}
if !raw_string[i..raw_string.len()].contains(|c| matches!(c, '1'..='9')) {
significant_digits = i;
break;
}
}
significant_digits
}
#[test]
fn test_get_significant_digits() {
let many_zeros = parse_and_calc("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4");
assert_eq!(many_zeros.to_f64(), 117.48139);
let many_nines = parse_and_calc("12.0096 + 15.9994 * 2");
assert_eq!(many_nines.to_f64(), 44.0084);
let zero_nine_zero = parse_and_calc("2+12321(5+123)");
assert_eq!(zero_nine_zero.to_f64(), 1577090.0);
assert_eq!(get_significant_digits(&many_zeros), 8);
assert_eq!(get_significant_digits(&many_nines), 6);
assert_eq!(get_significant_digits(&zero_nine_zero), 6);
} }

View file

@ -111,6 +111,10 @@ impl FromStr for Nodes {
} }
ParsingState::ReadingNumber(start_index) => { ParsingState::ReadingNumber(start_index) => {
if !is_number_char(c) { if !is_number_char(c) {
if matches!(nodes.last(), Some(Node::ParenthesisEnd)) {
nodes.push(Node::Operator(Default::default()));
}
nodes.push(Node::Number( nodes.push(Node::Number(
Float::parse(&filtered_string[start_index..i]) Float::parse(&filtered_string[start_index..i])
.map_err(|e| { .map_err(|e| {
@ -134,9 +138,6 @@ impl FromStr for Nodes {
} else if c.is_alphabetic() { } else if c.is_alphabetic() {
state = ParsingState::ReadingFunctionName(i); state = ParsingState::ReadingFunctionName(i);
} else if c == '(' { } else if c == '(' {
if matches!(nodes.last(), Some(Node::Number(_) | Node::ParenthesisEnd)) {
nodes.push(Node::Operator(Default::default()));
}
nodes.push(Node::ParenthesisStart); nodes.push(Node::ParenthesisStart);
} else if c == ')' { } else if c == ')' {
nodes.push(Node::ParenthesisEnd); nodes.push(Node::ParenthesisEnd);

View file

@ -11,11 +11,6 @@ fn implicit_mult() {
Nodes::from_str("10 sin(10)").unwrap().evaluate().to_f64(), Nodes::from_str("10 sin(10)").unwrap().evaluate().to_f64(),
-5.440211108893698 -5.440211108893698
); );
assert_eq!(
Nodes::from_str("(10)(10)").unwrap().evaluate().to_f64(),
100.,
)
} }
#[test] #[test]