20 个稳定版本
1.9.3 | 2023年9月20日 |
---|---|
1.9.2 | 2023年7月10日 |
1.9.1 | 2023年3月29日 |
1.9.0 | 2022年12月30日 |
1.3.0 | 2020年11月29日 |
#113 in 解析实现
1,107 monthly downloads
在 2 crates 中使用
210KB
4K SLoC
cpc
计算 + 转换
cpc 解析并评估数学字符串,支持单位和单位转换。使用 128 位十进制浮点数进行高精度计算。
它还允许混合单位,例如 1 km - 1m
的结果是 999 米
。
命令行安装
使用 cargo
安装
cargo install cpc
要手动安装,请从 GitHub 发布页面 下载相应的二进制文件,并将其放置在您的操作系统上通常放置二进制文件的位置。
命令行使用
cpc '2h/3 to min'
API 安装
在 Cargo.toml
中将 cpc
添加为依赖项。
API 使用
use cpc::eval;
use cpc::units::Unit;
match eval("3m + 1cm", true, Unit::Celsius, false) {
Ok(answer) => {
// answer: Number { value: 301, unit: Unit::Centimeter }
println!("Evaluated value: {} {:?}", answer.value, answer.unit)
},
Err(e) => {
println!("{e}")
}
}
示例
3 + 4 * 2
8 % 3
(4 + 1)km to light years
10m/2s * 5 trillion s
1 lightyear * 0.001mm in km2
1m/s + 1mi/h in kilometers per h
round(sqrt(2)^4)! liters
10% of abs(sin(pi)) horsepower to watts
支持的单位类型
- 普通数字
- 时间
- 长度
- 面积
- 体积
- 质量
- 数字存储(字节等)
- 能量
- 功率
- 电流
- 电阻
- 电压
- 压力
- 频率
- 速度
- 温度
精度
cpc 使用 128 位十进制浮点数(d128)而不是二进制编码的十进制数以提高精度。cpc 给出的结果仍可能不会总是 100% 准确。建议将结果四舍五入到 20 位或更少。
性能
它运行得相当快,并且具有良好的扩展性。在我的情况下,它通常在0.1毫秒以下运行。性能下降最大的函数是像这样的log()
。 log(12345)
评估需要0.12毫秒,而log(e)
需要0.25毫秒。
要查看它的速度有多快,您可以在CLI中传递--verbose
标志,或者传递给eval()
的verbose
参数。
开发说明
开始
安装Rust。
使用CLI参数作为输入运行cpc
cargo run -- '100ms to s'
以详细模式运行,这将显示一些额外的日志
cargo run -- '100ms to s' --verbose
运行测试
cargo test
构建
cargo build
添加单元
添加单元的好资源
- https://github.com/ryantenney/gnu-units/blob/master/units.dat
- https://support.google.com/websearch/answer/3284611(单位列表)
- https://translatorscafe.com/unit-converter(单位转换)
- https://calculateme.com(单位转换)
- https://wikipedia.org
1. 添加单位
在src/units.rs
中,单位是这样指定的
pub enum UnitType {
Time,
// etc
}
// ...
create_units!(
Nanosecond: (Time, d128!(1)),
Microsecond: (Time, d128!(1000)),
// etc
)
与单位相关的数字是其“权重”。例如,如果一秒的权重是1
,那么一分钟的重量是60
。
2. 为单位添加测试
请确保也为每个单位添加测试。测试看起来像这样
assert_eq!(convert_test(1000.0, Meter, Kilometer), 1.0);
基本上,1000米等于1公里。
3. 将单位添加到词法分析器
文本在lexer.rs
中转换为标记(其中一些是单位)。以下是一个示例
// ...
match string {
"h" | "hr" | "hrs" | "hour" | "hours" => tokens.push(Token::Unit(Hour)),
// etc
}
// ...
潜在改进
- 支持功率、电流、电阻和电压之间的转换。目前支持乘法和除法,但不支持使用sqrt或pow的转换。
- 移至纯Rust十进制实现
rust_decimal
:只支持~1E+29以上的数字bigdecimal
:缺乏数学函数
- E表示法,如2E+10
- 单元类型
- 货币:如何动态更新权重?
- 时区
- 二进制/八进制/十进制/十六进制/base32/base64
- 燃油消耗
- 数据传输速率
- 颜色代码
- 力
- 罗马数字
- 角度
- 流速
发布新版本
- 更新
CHANGELOG.md
- 在
Cargo.toml
中提升版本号 - 运行
cargo test
- 以格式
v#.#.#
创建git标签 - 将发布说明添加到生成的GitHub发布中并发布它
- 运行
cargo publish
依赖关系
~1.6–2.2MB
~34K SLoC