Evaluation result of redundant expression
Closed this issue · 2 comments
Hi there,
I tried evalexpr and found an un-expected result for the expression
"x*0.2*5/4+x*2*4*1*1*1*1*1*1*1+7*math::sin(y)-z/math::sin(3/2/(1-x*4*1*1*1*1))"
I used evalexpr = "6.4.0"
as dependency in my Cargo.toml
. Running
use evalexpr::{build_operator_tree, ContextWithMutableVariables, HashMapContext, Value};
fn main() {
let expr_str = "x*0.2*5/4+x*2*4*1*1*1*1*1*1*1+7*math::sin(y)-z/math::sin(3/2/(1-x*4*1*1*1*1))";
let parsed_exprs = build_operator_tree(expr_str).unwrap();
let compute_result = |x: f64, y: f64, z: f64| {
let mut context = HashMapContext::new();
context.set_value("x".into(), x.into()).unwrap();
context.set_value("y".into(), y.into()).unwrap();
context.set_value("z".into(), z.into()).unwrap();
match parsed_exprs.eval_with_context(&context).unwrap() {
Value::Float(val) => val,
_ => panic!("What?"),
}
};
let compute_reference = |x: f64, y: f64, z: f64| {
x * 0.2 * 5.0 / 4.0 + x * 2.0 * 4.0 + 7.0 * y.sin()
- z / (3.0 / 2.0 / (1.0 - x * 4.0f64)).sin()
};
let res = compute_result(0.0, 3.0, 4.0);
let reference = compute_reference(0.0, 3.0, 4.0);
println!("res {}, ref {}", res, reference);
assert!((res - reference).abs() < 1e-12);
}
resulted in the output
res -3.7657403666934144, ref -3.022205160567829
thread 'main' panicked at 'assertion failed: (res - reference).abs() < 1e-12', src\main.rs:28:5
stack backtrace:
...
I double checked the expression in a Python repl
In [1]: from math import sin
In [2]: x=0
In [3]: y=3
In [4]: z=4
In [5]: x*0.2*5/4+x*2*4*1*1*1*1*1*1*1+7*sin(y)-z/sin(3/2/(1-x*4*1*1*1*1))
Out[5]: -3.022205160567829
Hi, thank you for the report.
I checked your expression, and the issue seems to be caused by a different handling of integer divisions between python and evalexpr. The expression 3 / 2
is evaluated as integer division by evalexpr, while python divides using floats. In the corresponding rust code, you have manually converted the integers to floats, resulting in a floating point division as well.
I added a test for this expression anyways, since I think it is a nice test case. And I also added some examples to the documentation.
Ah. Interesting. Thanks.