decimo— A native arbitrary-precision command-line calculator powered by Decimo and ArgMojo.
--help Referencedecimo is a command-line calculator that supports:
sqrt, ln, exp, sin, cos,
tan, and more.pi and e to any number of digits.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.
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/
# 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
42, -7, 10000003.14, 0.001, .5-3, -3.14, (-5 + 2)-3*pi, -3*pi*(sin(1))2 * -3, sqrt(-1 + 2)+3, 2 * +3 (accepted, does nothing)Negative numbers and many expressions starting with - can be passed directly
as the positional argument. See Negative Expressions
for details.
| 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 / 2gives3.5, not3.
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.
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))"
| 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 π
--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, -S)Output in scientific notation (e.g., 1.23E+10).
decimo "123456789 * 987654321" -S
# → 1.21932631112635269E+17
--engineering, -E)Output in engineering notation (exponent is always a multiple of 3).
decimo "123456789 * 987654321" -E
# → 121.932631112635269E+15
--scientificand--engineeringare mutually exclusive.
--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)
--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, -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
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 |
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.
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.
-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.
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-insensitive — PI, Sqrt, SIN are equivalent to pi,
sqrt, sin.
ans — automatically holds the result of the last successful evaluation.name = expr — assigns the result of expr to a user-defined variable.pi, e, ans, function names) cannot be used as variable
names.:)| 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. |
Append :<settings> to an expression to override settings for that single
evaluation:
decimo> sqrt(2):p 100
| 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. |
Type :q, exit, quit, or press Ctrl-D.
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)
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"
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)
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.
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
decimo "100 * 12 - 23/17"
# → 1198.6470588235294117647058823529411764705882352941
decimo "(1 + 2) * (3 + 4)"
# → 21
decimo "2 ^ 256" -P 78
# → 115792089237316195423570985008687907853269984665640564039457584007913129639936
# 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
# 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
# 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
# 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 −∞)
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
^
--help ReferenceArbitrary-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