use crate::core::{Expression, MathConstant, Number};
pub fn ln(arg: &Expression) -> Expression {
match arg {
Expression::Constant(MathConstant::E) => Expression::integer(1),
Expression::Number(Number::Integer(1)) => Expression::integer(0),
Expression::Number(Number::Float(f)) if *f > 0.0 => Expression::float(f.ln()),
Expression::Number(Number::Integer(i)) if *i > 0 => Expression::float((*i as f64).ln()),
_ => Expression::function("ln", vec![arg.clone()]),
}
}
pub fn log10(arg: &Expression) -> Expression {
match arg {
Expression::Number(Number::Integer(1)) => Expression::integer(0),
Expression::Number(Number::Integer(10)) => Expression::integer(1),
Expression::Number(Number::Float(f)) if *f > 0.0 => Expression::float(f.log10()),
Expression::Number(Number::Integer(i)) if *i > 0 => Expression::float((*i as f64).log10()),
_ => Expression::function("log10", vec![arg.clone()]),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ln_one() {
assert_eq!(ln(&Expression::integer(1)), Expression::integer(0));
}
#[test]
fn test_log10_one() {
assert_eq!(log10(&Expression::integer(1)), Expression::integer(0));
}
#[test]
fn test_log10_ten() {
assert_eq!(log10(&Expression::integer(10)), Expression::integer(1));
}
}