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 解析实现

Download history 207/week @ 2024-04-22 127/week @ 2024-04-29 138/week @ 2024-05-06 169/week @ 2024-05-13 187/week @ 2024-05-20 137/week @ 2024-05-27 174/week @ 2024-06-03 167/week @ 2024-06-10 176/week @ 2024-06-17 160/week @ 2024-06-24 192/week @ 2024-07-01 177/week @ 2024-07-08 183/week @ 2024-07-15 331/week @ 2024-07-22 279/week @ 2024-07-29 269/week @ 2024-08-05

1,107 monthly downloads
2 crates 中使用

MIT 许可证

210KB
4K SLoC

cpc

计算 + 转换

cpc 解析并评估数学字符串,支持单位和单位转换。使用 128 位十进制浮点数进行高精度计算。

它还允许混合单位,例如 1 km - 1m 的结果是 999

Crates.io Documentation

所有支持单位的列表

命令行安装

使用 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

添加单元

添加单元的好资源

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
}
// ...

潜在改进

发布新版本

  1. 更新CHANGELOG.md
  2. Cargo.toml中提升版本号
  3. 运行cargo test
  4. 以格式v#.#.#创建git标签
  5. 将发布说明添加到生成的GitHub发布中并发布它
  6. 运行cargo publish

依赖关系

~1.6–2.2MB
~34K SLoC