9个版本
使用旧的Rust 2015
0.2.0 | 2018年9月30日 |
---|---|
0.1.0 | 2017年11月11日 |
0.0.9 | 2017年2月21日 |
0.0.7 | 2016年12月7日 |
0.0.5 | 2016年7月25日 |
#502 in 数学
4,363次每月下载
用于 46 个Crates (30个直接使用)
78KB
1.5K SLoC
meval
这个Rust crate提供了一个简单的数学表达式解析和评估。其主要目标是便于使用,同时提供一些灵活性。目前仅支持f64
类型。一个典型的用例是在Rust中配置数值计算,比如通过配置文件或命令行参数来考虑初始数据和边界条件。
文档
安装
只需将相应的条目添加到您的Cargo.toml
依赖项列表中
[dependencies]
meval = "0.2"
并将此添加到您的crate根目录中
extern crate meval;
需要Rust 1.26。
简单示例
extern crate meval;
fn main() {
let r = meval::eval_str("1 + 2").unwrap();
println!("1 + 2 = {}", r);
}
需要从表达式定义Rust函数?没问题,使用Expr
来处理此操作及更多
extern crate meval;
fn main() {
let expr: meval::Expr = "sin(pi * x)".parse().unwrap();
let func = expr.bind("x").unwrap();
let vs: Vec<_> = (0..100+1).map(|i| func(i as f64 / 100.)).collect();
println!("sin(pi * x), 0 <= x <= 1: {:?}", vs);
}
自定义常量和函数?定义一个Context
!
use meval::{Expr, Context};
let y = 1.;
let expr: Expr = "phi(-2 * zeta + x)".parse().unwrap();
// create a context with function definitions and variables
let mut ctx = Context::new(); // built-ins
ctx.func("phi", |x| x + y)
.var("zeta", -1.);
// bind function with a custom context
let func = expr.bind_with_context(ctx, "x").unwrap();
assert_eq!(func(2.), -2. * -1. + 2. + 1.);
对于2、3和N个变量的函数,分别使用Context::func2
、Context::func3
和Context::funcn
。有关更多选项,请参阅Context
。
如果您需要一个依赖于可变参数的自定义函数,您将需要使用Cell
use std::cell::Cell;
use meval::{Expr, Context};
let y = Cell::new(0.);
let expr: Expr = "phi(x)".parse().unwrap();
let mut ctx = Context::empty(); // no built-ins
ctx.func("phi", |x| x + y.get());
let func = expr.bind_with_context(ctx, "x").unwrap();
assert_eq!(func(2.), 2.);
y.set(3.);
assert_eq!(func(2.), 5.);
支持的表达式
meval
支持浮点数的基本数学运算
- 二元运算符:
+
、-
、*
、/
、%
(余数)、^
(幂) - 一元运算符:
+
,-
它支持自定义变量和函数,如 x
,weight
,C_0
,f(1)
等。变量或函数名必须以 [a-zA-Z_]
开头,并且只能包含 [a-zA-Z0-9_]
。还支持具有可变参数数量的自定义函数。
内置函数(由 Context::new()
提供,在没有提供上下文的情况下)目前支持
-
使用与 Rust std 库 中同名函数实现的函数
sqrt
,abs
exp
,ln
sin
,cos
,tan
,asin
,acos
,atan
,atan2
sinh
,cosh
,tanh
,asinh
,acosh
,atanh
floor
,ceil
,round
符号函数
-
其他函数
max(x, ...)
,min(x, ...)
:1 个或多个数字的最大值和最小值
-
常量
π
e
反序列化
Expr
支持使用 serde 库进行反序列化,以简化灵活配置的设置,如果启用了功能 serde
(默认禁用)。
#[macro_use]
extern crate serde_derive;
extern crate toml;
extern crate meval;
use meval::{Expr, Context};
#[derive(Deserialize)]
struct Ode {
#[serde(deserialize_with = "meval::de::as_f64")]
x0: f64,
#[serde(deserialize_with = "meval::de::as_f64")]
t0: f64,
f: Expr,
}
fn main() {
let config = r#"
x0 = "cos(1.)"
t0 = 2
f = "sin(x)"
"#;
let ode: Ode = toml::from_str(config).unwrap();
assert_eq!(ode.x0, 1f64.cos());
assert_eq!(ode.t0, 2f64);
assert_eq!(ode.f.bind("x").unwrap()(2.), 2f64.sin());
}
相关项目
这是我为了学习 Rust 而创建的一个玩具项目,希望在编写命令行脚本时能有所帮助。没有计划将其做成“数学表达式 -> 数字”的“转换器”以外的任何东西。对于更高级的脚本,请参阅
- dyon -- 一个 Rust 动态类型脚本语言
- gluon -- 一个用于应用嵌入的静态、类型推断编程语言
- rodolf0/tox -- 另一个后缀表达式解析器
许可证
本项目由 Unlicense 和 MIT 许可证共同许可。
您可以在任一许可证的条款下使用此代码。
依赖项
~1MB
~17K SLoC