probablykasper / cpc

Licence: MIT license
Text calculator with support for units and conversion

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to cpc

Length.js
📏 JavaScript library for length units conversion.
Stars: ✭ 292 (+228.09%)
Mutual labels:  converter, conversion, units
Unitsnet
Makes life working with units of measurement just a little bit better.
Stars: ✭ 641 (+620.22%)
Mutual labels:  converter, conversion, units
Rink Rs
Unit conversion tool and library written in rust
Stars: ✭ 242 (+171.91%)
Mutual labels:  calculator, conversion, units
desktop
Extendable calculator for the 21st Century ⚡
Stars: ✭ 85 (-4.49%)
Mutual labels:  calculator, math, units
fp-units
An FP-oriented library to easily convert CSS units.
Stars: ✭ 18 (-79.78%)
Mutual labels:  converter, conversion, units
qTsConverter
A simple tool to convert qt translation file (ts) to other format (xlsx / csv) and vice versa
Stars: ✭ 26 (-70.79%)
Mutual labels:  converter, conversion
xsampa
X-SAMPA to IPA converter
Stars: ✭ 20 (-77.53%)
Mutual labels:  converter, conversion
bitsnpicas
Bits'N'Picas - Bitmap & Emoji Font Creation & Conversion Tools
Stars: ✭ 171 (+92.13%)
Mutual labels:  converter, conversion
dftools
Tools for Star Wars: Dark Forces assets.
Stars: ✭ 18 (-79.78%)
Mutual labels:  converter, conversion
quill-markdown-toolbar
A Quill.js module for converting markdown text to rich text format
Stars: ✭ 13 (-85.39%)
Mutual labels:  converter, conversion
sublime-atomizr
Convert Sublime Text completions into Atom (or Visual Studio Code) snippets, and vice versa.
Stars: ✭ 12 (-86.52%)
Mutual labels:  converter, conversion
discoursegraphs
linguistic converter / merging tool for multi-level annotated corpora. graph-based (using Python and NetworkX).
Stars: ✭ 47 (-47.19%)
Mutual labels:  converter, conversion
csv2html
Convert CSV files to HTML tables
Stars: ✭ 64 (-28.09%)
Mutual labels:  converter, conversion
Numbase
Arbitrary number base converter.
Stars: ✭ 22 (-75.28%)
Mutual labels:  converter, math
BlocksConverter
A PocketMine-MP plugin allows you to convert Minecraft PC maps to MCPE/Bedrock maps or vice-versa.
Stars: ✭ 47 (-47.19%)
Mutual labels:  converter, conversion
vectorexpress-api
Vector Express is a free service and API for converting, analyzing and processing vector files.
Stars: ✭ 66 (-25.84%)
Mutual labels:  converter, conversion
Oas Kit
Convert Swagger 2.0 definitions to OpenAPI 3.0 and resolve/validate/lint
Stars: ✭ 516 (+479.78%)
Mutual labels:  converter, conversion
Alfred Calculate Anything
Alfred Workflow to calculate anything with natural language
Stars: ✭ 92 (+3.37%)
Mutual labels:  converter, calculator
Hrconvert2
A self-hosted, drag-and-drop, & nosql file conversion server that supports 62x file formats.
Stars: ✭ 132 (+48.31%)
Mutual labels:  converter, conversion
bank2ynab
Easily convert and import your bank's statements into YNAB. This project consolidates other conversion efforts into one universal tool.
Stars: ✭ 197 (+121.35%)
Mutual labels:  converter, conversion

cpc

calculation + conversion

cpc parses and evaluates strings of math, with support for units and conversion. 128-bit decimal floating points are used for high accuracy.

It also lets you mix units, so for example 1 km - 1m results in 999 Meter.

Crates.io Documentation

List of all supported units

CLI Installation

Install using cargo:

cargo install cpc

To install it manually, grab the appropriate binary from the GitHub Releases page and place it wherever you normally place binaries on your OS.

CLI Usage

cpc '2h/3 to min'

API Installation

Add cpc as a dependency in Cargo.toml.

API Usage

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}")
    }
}

Examples

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

Supported unit types

  • Normal numbers
  • Time
  • Length
  • Area
  • Volume
  • Mass
  • Digital storage (bytes etc)
  • Energy
  • Power
  • Electric current
  • Resistance
  • Voltage
  • Pressure
  • Frequency
  • Speed
  • Temperature

Accuracy

cpc uses 128-bit Decimal Floating Point (d128) numbers instead of Binary Coded Decimals for better accuracy. The result cpc gives will still not always be 100% accurate. I would recommend rounding the result to 20 decimals or less.

Performance

It's pretty fast and scales well. In my case, it usually runs in under 0.1ms. The biggest performance hit is functions like log(). log(12345) evaluates in 0.12ms, and log(e) in 0.25ms.

To see how fast it is, you can pass the --verbose flag in CLI, or the verbose argument to eval().

Dev Instructions

Get started

Install Rust.

Run cpc with a CLI argument as input:

cargo run -- '100ms to s'

Run in verbose mode, which shows some extra logs:

cargo run -- '100ms to s' --verbose

Run tests:

cargo test

Build:

cargo build

Adding a unit

Nice resources for adding units:

1. Add the unit

In src/units.rs, units are specified like this:

pub enum UnitType {
  Time,
  // etc
}

// ...

create_units!(
  Nanosecond:         (Time, d128!(1)),
  Microsecond:        (Time, d128!(1000)),
  // etc
)

The number associated with a unit is it's "weight". For example, if a second's weight is 1, then a minute's weight is 60.

2. Add a test for the unit

Make sure to also add a test for each unit. The tests look like this:

assert_eq!(convert_test(1000.0, Meter, Kilometer), 1.0);

Basically, 1000 Meter == 1 Kilometer.

3. Add the unit to the lexer

Text is turned into tokens (some of which are units) in lexer.rs. Here's one example:

// ...
match string {
  "h" | "hr" | "hrs" | "hour" | "hours" => tokens.push(Token::Unit(Hour)),
  // etc
}
// ...

Potential Improvements

  • Support for conversion between Power, Current, Resistance and Voltage. Multiplication and division is currently supported, but not conversions using sqrt or pow.
  • Move to pure-rust decimal implementation
    • rust_decimal: Only supports numbers up to ~1E+29
    • bigdecimal: Lacking math functions
  • E notation, like 2E+10
  • Unit types

Releasing a new version

  1. Update CHANGELOG.md
  2. Bump the version number in Cargo.toml
  3. Run cargo test
  4. Create a git tag in format v#.#.#
  5. Add release notes to the generated GitHub release and publish it
  6. Run cargo publish
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].