[READ-ONLY] Mirror of https://github.com/probablykasper/cpc. Text calculator with support for units and conversion cpc.kasper.space
calculator cli conversion converter library math package units units-converter wasm website
0

Configure Feed

Select the types of activity you want to include in your feed.

Rust 97.3%
Svelte 1.6%
TypeScript 0.6%
HTML 0.3%
JavaScript 0.1%
CSS 0.1%
303 2 26

Clone this repository

https://tangled.org/kasper.space/cpc https://tangled.org/did:plc:3zz4fru6e6zzv6dz4zbf2l7h
git@tangled.org:kasper.space/cpc git@tangled.org:did:plc:3zz4fru6e6zzv6dz4zbf2l7h

For self-hosted knots, clone URLs may differ based on your setup.



README.md

cpc#

calculation + conversion

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

For example 1tonne * 1sqm / 2second^3 / 5ampere results in 100 volts.

Crates.io Documentation

List of all supported units

Web Interface#

Try it out at cpc.kasper.space

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'

Examples#

3 + 4 * 2

6'3" to cm

1tonne * 1sqm / 2s^3 / 5a

(7 % 4)km to light years

10m/2s * 5 trillion s

1 lightyear * 0.001mm in km2

1m/s + 1mi/5h in kilometers per h

round(sqrt(2)^4)! liters

10% of abs(sin(pi)) horsepower to watts

Supported unit types#

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

API Installation#

Add cpc as a dependency in Cargo.toml.

API Usage#

use cpc::eval;
use cpc::units::Unit;

match eval("3m + 1cm", true, false) {
    Ok(answer) => {
        // answer: Number { value: 301, unit: Unit::Centimeter }
        println!("Evaluated value: {} {:?}", answer.value, answer.unit)
    },
    Err(e) => {
        println!("{e}")
    }
}

Accuracy#

Inexact results are always indicated with . 128-bit Decimal Floating Point (d128) numbers are used for high accuracy, and prevents most floating-point errors.

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, d!(1), "nanosecond", "nanoseconds"),
  Microsecond:        (Time, d!(1000), "microsecond", "microseconds"),
  // 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#

  • Fractional numbers (to make 1/3*2*3 accurate)
  • E notation, like 2E+10
  • Unit types
    • Timezones
    • Binary/octal/decimal/hexadecimal/base32/base64
    • Fuel consumption
    • Color codes
    • Force
    • Roman numerals
    • Angles
    • Flow rate

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