Compare commits
2 commits
e6c3df373f
...
eba5317419
Author | SHA1 | Date | |
---|---|---|---|
eba5317419 | |||
ed9be1c739 |
4 changed files with 59 additions and 1 deletions
|
@ -1,3 +1,4 @@
|
|||
|
||||
use evalexpr::{
|
||||
Value,
|
||||
|
||||
|
@ -38,6 +39,51 @@ pub fn fix(arg: &Value) -> EvalResult {
|
|||
} else { Err(EvalexprError::wrong_function_argument_amount(1, 2)) }
|
||||
}
|
||||
|
||||
pub fn fraction(arg: &Value) -> EvalResult {
|
||||
if let Value::Float(arg) = arg {
|
||||
let mut intermediate = arg.clone();
|
||||
let mut pow = 0;
|
||||
while intermediate.fract() != 0_f64 {
|
||||
intermediate *= 10_f64;
|
||||
pow += 1;
|
||||
}
|
||||
let value = intermediate as i64;
|
||||
let tens: i64 = 10_i64.pow(pow);
|
||||
let gcd = util::gcd(value, tens);
|
||||
|
||||
let numerator = value / gcd;
|
||||
let denominator = tens / gcd;
|
||||
|
||||
Ok(Value::String(format!("{numerator}/{denominator}")))
|
||||
} else { Err(EvalexprError::expected_float(arg.clone())) }
|
||||
}
|
||||
|
||||
pub fn greatest_common_divisor(arg: &Value) -> EvalResult {
|
||||
if let Value::Tuple(args) = arg {
|
||||
let len = args.len();
|
||||
if len != 2 { return Err(EvalexprError::wrong_function_argument_amount(len, 2)); }
|
||||
|
||||
let a = args[0].clone();
|
||||
let b = args[1].clone();
|
||||
|
||||
if let (Value::Int(a), Value::Int(b)) = (a, b) { Ok( Value::Int( util::gcd(i64::max(a, b), i64::min(a, b)) ) ) }
|
||||
else { Err(EvalexprError::expected_int( if !args[0].is_int() { args[0].clone() } else { args[1].clone() } )) }
|
||||
} else { Err(EvalexprError::expected_tuple(arg.clone())) }
|
||||
}
|
||||
|
||||
pub fn least_common_multiple(arg: &Value) -> EvalResult {
|
||||
if let Value::Tuple(args) = arg {
|
||||
let len = args.len();
|
||||
if len != 2 { return Err(EvalexprError::wrong_function_argument_amount(len, 2)); }
|
||||
|
||||
let a = args[0].clone();
|
||||
let b = args[1].clone();
|
||||
|
||||
if let (Value::Int(a), Value::Int(b)) = (a, b) { Ok( Value::Int( util::lcm(i64::max(a, b), i64::min(a, b)) ) ) }
|
||||
else { Err(EvalexprError::expected_int( if !args[0].is_int() { args[0].clone() } else { args[1].clone() } )) }
|
||||
} else { Err(EvalexprError::expected_tuple(arg.clone())) }
|
||||
}
|
||||
|
||||
pub fn logarithm(arg: &Value) -> EvalResult {
|
||||
let value: f64;
|
||||
let base: Option<f64>;
|
||||
|
|
|
@ -27,7 +27,10 @@ pub fn build(args: &mut Arguments) -> HashMapContext {
|
|||
|
||||
// math functions
|
||||
"cos" => Function::new(|arg| helper::cosine(arg)),
|
||||
"fract" => Function::new(|arg| helper::fraction(arg)),
|
||||
"fix" => Function::new(|arg| helper::fix(arg)),
|
||||
"gcd" => Function::new(|arg| helper::greatest_common_divisor(arg)),
|
||||
"lcm" => Function::new(|arg| helper::least_common_multiple(arg)),
|
||||
"log" => Function::new(|arg| helper::logarithm(arg)),
|
||||
"sin" => Function::new(|arg| helper::sine(arg)),
|
||||
"sqrt" => Function::new(|arg| helper::square_root(arg)),
|
||||
|
|
|
@ -14,7 +14,6 @@ use std::{
|
|||
use evalexpr::{
|
||||
eval_with_context_mut,
|
||||
|
||||
ContextWithMutableVariables,
|
||||
EvalexprError,
|
||||
HashMapContext,
|
||||
Value
|
||||
|
|
10
src/util.rs
10
src/util.rs
|
@ -1,6 +1,16 @@
|
|||
|
||||
use evalexpr::{ EvalexprError, Value };
|
||||
|
||||
pub fn gcd(big: i64, small: i64) -> i64 {
|
||||
if small == 0 { big }
|
||||
else { gcd(small, big % small) }
|
||||
}
|
||||
|
||||
pub fn lcm(big: i64, small: i64) -> i64 {
|
||||
let product = (big * small).abs();
|
||||
product / gcd(big, small)
|
||||
}
|
||||
|
||||
pub fn parse_radix(prefix: &str, base: u32, arg: &str) -> Result<Value, EvalexprError> {
|
||||
let parse = arg.strip_prefix(prefix).unwrap_or(arg);
|
||||
|
||||
|
|
Loading…
Reference in a new issue