decimo

Decimo CLI Calculator — User Manual

decimo — A native arbitrary-precision command-line calculator powered by Decimo and ArgMojo.

Overview

decimo is a command-line calculator that supports:

It compiles to a single native binary. The release tarballs carry the Mojo runtime libraries beside it, so neither Mojo nor Pixi is needed to run it.

Installation

Pre-built binaries for macOS arm64 and Linux x86_64 are published through the forfudan/tap Homebrew tap:

brew install forfudan/tap/decimo
decimo --version

To build from a clone instead:

cd /path/to/decimo
pixi run buildcli        # produces ./decimo

Then move the binary to a directory in your $PATH:

mv decimo /usr/local/bin/

Quick Start

# Basic arithmetic
decimo "1 + 2 * 3"
# → 7

# High-precision division
decimo "1/3" -P 100
# → 0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

# Square root of 2 to 50 digits
decimo "sqrt(2)" -P 50
# → 1.4142135623730950488016887242096980785696718753769

# 1000 digits of pi
decimo "pi" -P 1000

# Large integer exponentiation
decimo "2^256" -P 78
# → 115792089237316195423570985008687907853269984665640564039457584007913129639936

Expression Syntax

Numbers

Negative numbers and many expressions starting with - can be passed directly as the positional argument. See Negative Expressions for details.

Operators

Operator Description Example Result
+ Addition 2 + 3 5
- Subtraction 10 - 4 6
* Multiplication 6 * 7 42
/ True division 1 / 3 0.3333...
^ Power 2 ^ 10 1024
** Power (alias) 2 ** 10 1024
(, ) Grouping (2 + 3) * 4 20

Note: Division always produces a decimal result. 7 / 2 gives 3.5, not 3.

Operator Precedence

From lowest to highest:

Precedence Operators Associativity
1 (low) +, - Left
2 *, / Left
3 unary - Right
4 (high) ^ / ** Right

Right-associativity of ^ means 2^3^2 = 2^(3^2) = 2^9 = 512, not (2^3)^2 = 64.

A unary minus binds looser than ^, as in Python: -2^2 is -(2^2) = -4. Write (-2)^2 for 4. A sign inside an exponent is part of the exponent, so 2^-2 is 0.25. A unary plus (+3, 2*+3) is accepted and does nothing.

Functions

All functions use the CLI’s precision setting (default 50, configurable with -P).

Single-argument functions:

Function Description Example
sqrt(x) Square root sqrt(2)
cbrt(x) Cube root cbrt(27)
abs(x) Absolute value abs(-5)5
ln(x) Natural logarithm ln(e)
log10(x) Base-10 logarithm log10(1000)3
exp(x) Exponential (e^x) exp(1)2.718...
sin(x) Sine (radians) sin(pi/2)
cos(x) Cosine (radians) cos(0)1
tan(x) Tangent (radians) tan(pi/4)
cot(x) Cotangent (radians) cot(pi/4)
csc(x) Cosecant (radians) csc(pi/2)

Multi-argument functions:

Function Description Example
root(x, n) Nth root of x root(27, 3)3
log(x, base) Logarithm with any base log(8, 2)

Functions can be nested:

decimo "sqrt(abs(1.1 * -12 - 23/17))"
decimo "ln(exp(1))"

Constants

Constant Description
pi π (3.14159…)
e Euler’s number (2.71828…)

Constants are computed to the requested precision:

decimo "pi" -P 100        # 100 digits of π
decimo "e" -P 500         # 500 digits of e
decimo "2 * pi * 6371"    # Circumference using π

CLI Options

Precision (--precision, -P)

Number of significant digits in the result. Default: 50.

decimo "1/7" -P 10       # 0.1428571429
decimo "1/7" -P 100      # 100 significant digits
decimo "1/7" -P 200      # 200 significant digits

Scientific Notation (--scientific, -S)

Output in scientific notation (e.g., 1.23E+10).

decimo "123456789 * 987654321" -S
# → 1.21932631112635269E+17

Engineering Notation (--engineering, -E)

Output in engineering notation (exponent is always a multiple of 3).

decimo "123456789 * 987654321" -E
# → 121.932631112635269E+15

--scientific and --engineering are mutually exclusive.

Pad to Precision (--pad)

Pad trailing zeros so the fractional part has exactly precision digits after the decimal point.

When used together with --precision, the precision value is treated as the number of fractional digits for padding purposes, not as a strict limit on total significant digits. As a result, the formatted number can have more than precision significant digits.

decimo "1.5" --pad -P 10
# → 1.5000000000 (10 fractional digits, 11 significant digits)

Digit Separator (--delimiter)

Insert a character every 3 digits for readability.

decimo "2^64" --delimiter _
# → 18_446_744_073_709_551_616

decimo "pi" -P 30 --delimiter _
# → 3.141_592_653_589_793_238_462_643_383_28

Rounding Mode (--rounding-mode, -R)

Choose how the final result is rounded. Default: half-even (banker’s rounding).

Mode Description
half-even Round to nearest even (default)
half-up Round half away from zero
half-down Round half toward zero
up Always round away from zero
down Always round toward zero (truncate)
ceiling Round toward +∞
floor Round toward −∞
decimo "1/6" -P 5 -R half-up       # 0.16667
decimo "1/6" -P 5 -R half-even     # 0.16667
decimo "1/6" -P 5 -R down          # 0.16666
decimo "1/6" -P 5 -R up            # 0.16667

Input Modes

decimo accepts input in four ways: a single expression on the command line, piped stdin, a file, or an interactive REPL session.

Mode Invocation When used
Expression decimo "EXPR" A positional argument is provided as an expression
Pipe echo "EXPR" \| decimo No positional argument and stdin is not a TTY
File decimo -F FILE.dm The -F/--file option is used
REPL decimo No positional argument and stdin is a TTY

Expression Mode (Default)

Pass a single expression as the positional argument:

decimo "1/3" -P 100

This is the most common usage. See Expression Syntax for what you can write.

Pipe Mode (stdin)

When no positional argument is provided and stdin is piped, decimo reads all of stdin and evaluates each non-empty, non-comment line:

# Single expression
echo "sqrt(2)" | decimo -P 30
# → 1.41421356237309504880168872421

# Multiple expressions (one per line)
printf '1/3\nsqrt(2)\npi' | decimo -P 20
# → 0.33333333333333333333
# → 1.4142135623730950488
# → 3.1415926535897932385

# Lines starting with '#' are comments; blank lines are skipped
printf '# constants\npi\n\ne' | decimo -P 10
# → 3.141592654
# → 2.718281828

All CLI options (-P, -S, -E, --delimiter, -R, --pad) apply to every line.

If any expression fails, decimo prints the error for that line, continues evaluating the remaining lines, and exits with code 1.

File Mode (-F)

Use the -F (or --file) flag to evaluate expressions from a file, one per line:

decimo -F expressions.dm -P 50

Example file (expressions.dm):

# Basic arithmetic
1 + 2
100 * 12 - 23/17

# High-precision constants
pi
e

# Functions
sqrt(2)
ln(10)

Comments start with #. Inline comments are also supported (e.g. 1+2 # add). Leading whitespace before # is allowed. Blank lines and whitespace-only lines are skipped.

If the specified file does not exist or cannot be read, decimo reports an error and exits.

Interactive REPL

When invoked with no expression and stdin is a TTY, decimo launches an interactive session:

$ decimo
Decimo — an arbitrary-precision calculator 🔥
Type ? for help, : for settings, :q to quit.
Precision: 50. Rounding: ROUND_HALF_EVEN.
decimo> 100 * 12 - 23/17
1198.6470588235294117647058823529411764705882352941
decimo> ans + 1
1199.6470588235294117647058823529411764705882352941
decimo> x = sqrt(2)
1.4142135623730950488016887242096980785696718753769
decimo> x ^ 2
2
decimo> :q

All input is case-insensitivePI, Sqrt, SIN are equivalent to pi, sqrt, sin.

Variables

Settings commands (prefix with :)

Command Effect
:p N, :precision N Set precision to N digits.
:N Shortcut for :p N (e.g. :100).
:s, :scientific, :sci Toggle scientific notation.
:e, :engineering, :eng Toggle engineering notation.
:pad Toggle zero-padding.
:r MODE, :round, :rm Set rounding mode (he/hu/hd/u/d/c/f/b).
:MODE Set rounding mode (he/hu/hd/u/d/c/f/b).
:delimiter C Set digit-group delimiter.
:p 100 s r d Combine multiple settings in one line.

Inline temp settings

Append :<settings> to an expression to override settings for that single evaluation:

decimo> sqrt(2):p 100

Info commands

Command Effect
: Show all current settings.
?, :help, :h, :? Show REPL help.
$, :vars List all defined variables.
:about, :a, :info Show version, author, license, and links.
:version, :v Show version number.

Quitting

Type :q, exit, quit, or press Ctrl-D.

Shell Integration

Quoting Expressions

The shell interprets *, (, ), and other characters before decimo sees them. Always wrap expressions in quotes:

# Correct: quoted
decimo "2 * (3 + 4)"

# Wrong: the shell may glob or split it
decimo 2 * (3 + 4)

Negative Expressions

Most expressions starting with a hyphen (-) are treated as positional arguments, not as option flags:

# Negative number
decimo "-3.14"
# → -3.14

# Negative expression
decimo "-3*2"
# → -6

# Complex negative expression
decimo "-3*pi*(sin(1))"
# → -7.930677192244368536658197969…

# Options can appear before or after the expression
decimo -P 10 "-3*pi"
decimo "-3*pi" -P 10

Because every short option the calculator defines is uppercase (-P, -S, -E, -R, -F, -A), expressions like -e, -sin(1), and -pi are never mistaken for flags:

# Euler's number, negated
decimo "-e"
# → -2.71828…

# Negative sine
decimo "-sin(1)"
# → -0.84147…

# Negative pi
decimo "-pi"
# → -3.14159…

The -- separator still works if you prefer explicit positional parsing:

decimo -- "-e"

Using noglob

On zsh, you can use noglob to prevent shell interpretation:

noglob decimo 2*(3+4)

Or set up a permanent alias:

# Add to ~/.zshrc:
alias decimo='noglob decimo'

# Then use without quotes:
decimo 2*(3+4)

Shell Completions

decimo can generate completion scripts for Bash, Zsh, and Fish. Tab-completion will suggest option names, rounding mode values, and file paths.

Zsh — add to ~/.zshrc:

eval "$(decimo --completions zsh)"

Bash — add to ~/.bashrc:

eval "$(decimo --completions bash)"

Fish — run once:

decimo --completions fish | source
# Or persist:
decimo --completions fish > ~/.config/fish/completions/decimo.fish

After reloading your shell, pressing Tab after decimo - will show all available options, and pressing Tab after --rounding-mode will list the seven available modes.

Performance

decimo compiles to a single native binary. For most expressions, end-to-end latency is dominated by process startup rather than computation. The benchmark suite verifies both correctness (every significant digit agrees with bc, bar one guard digit for last-digit rounding) and performance (wall-clock timing).

Typical latencies (measured on Apple M1 Max, macOS):

Expression Precision decimo bc -l python3 Match
1 + 1 50 ~6 ms ~4 ms ~18 ms yes
100*12 - 23/17 50 ~6 ms ~4 ms ~21 ms yes
sqrt(2) 50 ~5 ms ~4 ms ~21 ms yes
ln(2) 50 ~5 ms ~4 ms ~41 ms yes
sin(1) 50 ~6 ms ~4 ms ~41 ms yes
pi 50 ~6 ms ~4 ms ~41 ms yes
sqrt(2) 1000 ~6 ms ~5 ms ~22 ms yes
pi 1000 ~49 ms ~13 ms ~40 ms yes
pipe: 5 mixed exprs 50 ~8 ms N/A N/A  

Computation time becomes visible only at high precision, such as π to 1000 digits. At the default precision decimo is about three to four times quicker than python3 to start and answer, and close to bc.

To run the full benchmark (correctness + performance, all 3 tools):

bash benches/cli/bench_cli.sh

Examples

Basic Arithmetic

decimo "100 * 12 - 23/17"
# → 1198.6470588235294117647058823529411764705882352941

decimo "(1 + 2) * (3 + 4)"
# → 21

decimo "2 ^ 256" -P 78
# → 115792089237316195423570985008687907853269984665640564039457584007913129639936

High-Precision Calculations

# 200 digits of 1/7
decimo "1/7" -P 200

# π to 1000 digits
decimo "pi" -P 1000

# e to 500 digits
decimo "e" -P 500

# sqrt(2) to 100 digits
decimo "sqrt(2)" -P 100

Mathematical Functions

# Trigonometry
decimo "sin(pi/6)" -P 50       # → 0.5 followed by trailing zeros
decimo "cos(pi/3)" -P 50       # → 0.5 followed by trailing zeros
decimo "tan(pi/4)" -P 50       # → 1 followed by trailing zeros

# Logarithms
decimo "ln(2)" -P 100
decimo "log10(1000)"            # → 3
decimo "log(256, 2)"            # → 8 followed by trailing zeros

# Nested functions
decimo "sqrt(abs(1.1 * -12 - 23/17))" -P 30
decimo "exp(ln(100))" -P 30     # → 100.0000000000000000000000000000

# Cube root
decimo "cbrt(27)"               # → 3 followed by trailing zeros
decimo "root(1000000, 6)"       # → 10

Output Formatting

# Scientific notation
decimo "123456789.987654321" -S
# → 1.23456789987654321E+8

# Engineering notation
decimo "123456789.987654321" -E
# → 123.456789987654321E+6

# Digit separators
decimo "2^100" --delimiter _
# → 1_267_650_600_228_229_401_496_703_205_376

# Pad trailing zeros
decimo "1/4" -P 20 --pad
# → 0.25000000000000000000

Rounding Modes

# Compare rounding of 2.5 to 0 decimal places:
decimo "2.5 + 0" -P 1 -R half-even   # → 2 (banker's: round to even)
decimo "2.5 + 0" -P 1 -R half-up     # → 3 (traditional)
decimo "2.5 + 0" -P 1 -R down        # → 2 (truncate)
decimo "2.5 + 0" -P 1 -R ceiling     # → 3 (toward +∞)
decimo "2.5 + 0" -P 1 -R floor       # → 2 (toward −∞)

Error Messages

The calculator provides clear error diagnostics with position indicators:

$ decimo "1 + * 2"
Error: missing operand for '+'
  1 + * 2
    ^

$ decimo "sqrt(-1)"
Error: sqrt() is undefined for negative numbers (got -1)
  sqrt(-1)
  ^

$ decimo "1 / 0"
Error: division by zero
  1 / 0
    ^

$ decimo "hello + 1"
Error: unknown identifier 'hello'
  hello + 1
  ^

$ decimo "2 * (3 + 4"
Error: unmatched '('
  2 * (3 + 4
      ^

Full --help Reference

Arbitrary-precision CLI calculator powered by Decimo.

usage: decimo [OPTIONS] [EXPR]

arguments:
  expr  Math expression to evaluate (e.g. 'sqrt(2)', '1/3 + pi')

options:
  -h, --help                Show this help message
  -V, --version             Show version
      --completions <SHELL>
                            Generate shell completion (bash, zsh, fish)

Input:
  -F, --file <PATH>  Evaluate expressions from a file (one per line)

Computation:
  -P, --precision <N>       Number of significant digits
  -R, --rounding-mode <MODE>
                            Rounding mode for the final result

Formatting:
  -S, --scientific        Output in scientific notation (e.g. 1.23E+10)
  -E, --engineering       Output in engineering notation (exponent multiple of
                          3)
      --pad               Pad trailing zeros to the specified precision
      --delimiter <CHAR>  Digit-group separator inserted every 3 digits (e.g.
                          '_' gives 1_234.567_89)

Info:
  -A, --about  Display version, author, license, and links
      --info   Same as --about

tips:
  Use '--' to force option-like tokens into positionals:  decimo -- -p
  If your expression contains *, ( or ), quote it: decimo "2 * (3 + 4)"
  Or use noglob: alias decimo='noglob decimo' (add to ~/.zshrc)
  Pipe expressions: echo '1/3' | decimo -P 100
  Evaluate a file: decimo -F expressions.dm -P 50