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,absexp,lnsin,cos,tan,asin,acos,atan,atan2sinh,cosh,tanh,asinh,acosh,atanhfloor,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