# How to do integer & float calculations, in bash or other languages/frameworks?

Using `echo "20+5"`

literally produces the text “`20+5`

“.

What command can I use to get the numeric sum, `25`

in this case?

Also, what’s the easiest way to do it just using bash for floating

point? For example, `echo $((3224/3807.0))`

prints `0`

:(.

I am looking for answers using either the basic command shell (‘command

line’) itself or through using languages that are available from the

command line.

## There are lots of options!!!

## Summary

```
$ printf %.10f\n "$((10**9 * 20/7))e-9" # many shells. Not mksh.
$ echo "$((20.0/7))" # (ksh93/zsh/yash, some bash)
$ awk "BEGIN {print (20+5)/2}"
$ zcalc
$ bc <<< 20+5/2
$ bc <<< "scale=4; (20+5)/2"
$ dc <<< "4 k 20 5 + 2 / p"
$ expr 20 + 5
$ calc 2 + 4
$ node -pe 20+5/2 # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
$ echo 20 5 2 / + p | dc
$ echo 4 k 20 5 2 / + p | dc
$ perl -E "say 20+5/2"
$ python -c "print(20+5/2)"
$ python -c "print(20+5/2.0)"
$ clisp -x "(+ 2 2)"
$ lua -e "print(20+5/2)"
$ php -r 'echo 20+5/2;'
$ ruby -e 'p 20+5/2'
$ ruby -e 'p 20+5/2.0'
$ guile -c '(display (+ 20 (/ 5 2)))'
$ guile -c '(display (+ 20 (/ 5 2.0)))'
$ slsh -e 'printf("%f",20+5/2)'
$ slsh -e 'printf("%f",20+5/2.0)'
$ tclsh <<< 'puts [expr 20+5/2]'
$ tclsh <<< 'puts [expr 20+5/2.0]'
$ sqlite3 <<< 'select 20+5/2;'
$ sqlite3 <<< 'select 20+5/2.0;'
$ echo 'select 1 + 1;' | sqlite3
$ psql -tAc 'select 1+1'
$ R -q -e 'print(sd(rnorm(1000)))'
$ r -e 'cat(pi^2, "n")'
$ r -e 'print(sum(1:100))'
$ smjs
$ jspl
$ gs -q <<< "5 2 div 20 add ="
```

## Details

### Shells

You can use POSIX arithmetic expansion for *integer* arithmetic ** echo "$((...))"**:

```
$ echo "$((20+5))"
25
$ echo "$((20+5/2))"
22
```

Quite portable (** ash dash yash bash ksh93 lksh zsh**):

Using printf ability to print floats we can extend most shells to do floating point math albeit with a limited range (no more than 10 digits):

```
$ printf %.10f\n "$((1000000000 * 20/7 ))e-9"
2.8571428570
```

** ksh93**,

**and**

`yash`

**do support floats here:**

`zsh`

```
$ echo "$((1.2 / 3))"
0.4
```

only ** ksh93** (directly) and

**loading library mathfunc here:**

`zsh`

```
$ echo "$((4*atan(1)))"
3.14159265358979324
```

(`zsh`

need to load `zmodload zsh/mathfunc`

to get functions like `atan`

).

Interactively with zsh:

```
$ autoload zcalc
$ zcalc
1> PI/2
1.5708
2> cos($1)
6.12323e-17
3> :sci 12
6.12323399574e-17
```

With (t)csh (integer only):

```
% @ a=25 / 3; echo $a
8
```

In the `rc`

shell family, `akanga`

is the one with arithmetic expansion:

```
; echo $:25/3
8
```

### POSIX toolchest

** bc** (see below for interactive mode), manual here

Mnemonic: `b`est `c`alculator (though the `b`

is in fact for *basic*).

```
$ echo 20+5/2 | bc
22
$ echo 'scale=4;20+5/2' | bc
22.5000
```

(supports arbitrary precision numbers)

bc interactive mode:

```
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
5+5
10
2.2+3.3
5.5
```

Rush‘s solution, ** expr** (no interactive mode):

```
$ expr 20 + 5
25
$ expr 20 + 5 / 2
22
```

Joshua’s solution: ** awk** (no interactive mode):

```
$ calc() { awk "BEGIN{print $*}"; }
$ calc 1/3
0.333333
```

### Other more or less portable tools

Arcege‘s solution, ** dc** (interactive mode:

`dc`

):Which is even more fun since it works by reverse polish notation.

```
$ echo 20 5 2 / + p | dc
22
$ echo 4 k 20 5 2 / + p | dc
22.5000
```

But not as practical unless you work with reverse polish notation a lot.

^{Note that dc predates bc and bc has been historically implemented as a wrapper around dc but dc was not standardised by POSIX}

DQdims‘s ** calc** (required

`sudo apt-get install apcalc)`

:```
$ calc 2 + 4
6
```

### General purpose language interpreters:

manatwork‘s solution, ** node** (interactive mode:

`node`

; output function not needed):```
$ node -pe 20+5/2 # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
22.5
```

**Perl** (interactive mode: `perl -de 1`

):

```
$ perl -E "say 20+5/2"
22.5
```

**Python** (interactive mode: `python`

; output function not needed):

```
$ python -c "print(20+5/2)"
22 # 22.5 with python3
$ python -c "print(20+5/2.0)"
22.5
```

Also supports arbitrary precision numbers:

```
$ python -c 'print(2**1234)'
295811224608098629060044695716103590786339687135372992239556207050657350796238924261053837248378050186443647759070955993120820899330381760937027212482840944941362110665443775183495726811929203861182015218323892077355983393191208928867652655993602487903113708549402668624521100611794270340232766099317098048887493809023127398253860618772619035009883272941129544640111837184
```

If you have ** clisp** installed, you can also use polish notation:

```
$ clisp -x "(+ 2 2)"
```

Marco‘s solution, ** lua** (interactive mode:

`lua`

):```
$ lua -e "print(20+5/2)"
22.5
```

**PHP** (interactive mode: `php -a`

):

```
$ php -r 'echo 20+5/2;'
22.5
```

**Ruby** (interactive mode: `irb`

; output function not needed):

```
$ ruby -e 'p 20+5/2'
22
$ ruby -e 'p 20+5/2.0'
22.5
```

**Guile** (interactive mode: `guile`

):

```
$ guile -c '(display (+ 20 (/ 5 2)))'
45/2
$ guile -c '(display (+ 20 (/ 5 2.0)))'
22.5
```

**S-Lang** (interactive mode: `slsh`

; output function not needed, just a `;`

terminator):

```
$ slsh -e 'printf("%f",20+5/2)'
22.000000
$ slsh -e 'printf("%f",20+5/2.0)'
22.500000
```

**Tcl** (interactive mode: `tclsh`

; output function not needed, but `expr`

is):

```
$ tclsh <<< 'puts [expr 20+5/2]'
22
$ tclsh <<< 'puts [expr 20+5/2.0]'
22.5
```

**Javascript** shells:

```
$ smjs
js> 25/3
8.333333333333334
js>
$ jspl
JSC: 25/3
RP: 8.33333333333333
RJS: [object Number]
JSC:
Good bye...
$ node
> 25/3
8.333333333333334
>
```

### Various SQL’s:

**SQLite** (interactive mode: `sqlite3`

):

```
$ sqlite3 <<< 'select 20+5/2;'
22
$ sqlite3 <<< 'select 20+5/2.0;'
22.5
```

**MySQL**:

```
mysql -BNe 'select 1+1'
```

**PostgreSQL**:

```
psql -tAc 'select 1+1
```

_The options on mysql and postgres stop the ‘ascii art’ image !

### Specialised math-oriented languages:

**R** in plain mode – lets generate 1000 Normal random numbers and get the standard deviation and print it

```
$ R -q -e 'print(sd(rnorm(1000)))'
> print(sd(rnorm(1000)))
[1] 1.031997
```

**R** using the **littler** script – lets print pi squared

```
$ r -e 'cat(pi^2, "n")'
9.869604
$ r -e 'print(sum(1:100))'
[1] 5050
```

**PARI/GP**, an extensive computer algebra system for number theory, linear algebra, and many other things

```
$ echo "prime(1000)"|gp -q
7919 // the 1000th prime
$ echo "factor(1000)" | gp -q
[2 3]
[5 3] // 2^3*5^3
$ echo "sum(x=1,5,x)" | gp -q
15 // 1+2+3+4+5
```

**GNU Octave** (a high-level interpreted language, primarily intended for numerical computations)

Also supports complex numbers:

```
$ octave
>> 1.2 / 7
ans = 0.17143
>> sqrt(-1)
ans = 0 + 1i
```

**Julia**, high-performance language and interpreter for scientific and numerical computing.

Non-interactive option:

```
$ julia -E '2.5+3.7'
6.2
```

**GhostScript**

GhostScript is a PostScript interpreter, very commonly installed even in very old distributions.

See PostScript docs for a list of supported math commands.

Interactive example:

```
$ GS_DEVICE=display gs
GPL Ghostscript 9.07 (2013-02-14)
Copyright (C) 2012 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>5 2 div 20 add =
22.5
GS>
```

You could use `bc`

. E.g.,

```
$ echo "25 + 5" | bc
30
```

Alternatively `bc <<< 25+5`

will also work.

Or interactively, if you want to do more than just a single simple calculation:

```
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
25 + 5
30
```

The GNU implementation of `bc`

prints that header/copyright info on start-up when both its stdin and stdout go to a terminal. You can suppress it with the (GNU-specific) `-q`

option. For more information see the bc man page

There are many ways to calculate.

For simple expressions you can use `bash`

itself:

```
echo $((20+5))
```

or `expr`

:

```
expr 20 + 5
```

And for complex cases there is great tool `bc`

:

```
echo "20+5" | bc
```

Btw, bc can calculate even very complex expression with roots, logarithms, cos, sin and so on.

The mentioned solutions are fine for very simple calculations, but very error-prone. Examples:

```
# without spaces expr 20+5 produces literally 20+5
expr 20+5
→ 20+5
# bc's result doesn't give the fractional part by default
bc <<< 9.0/2.0
→ 4
# expr does only integer
expr 9 / 2
→ 4
# same for POSIX arithmetic expansion
echo $((9/2))
→ 4
# bash arithmetic expansion chokes on floats
echo $((9.0/2.0))
→ bash: 9/2.0: syntax error: invalid arithmetic operator (error token is ".0")
# Most `expr` implementations also have problems with floats
expr 9.0 / 2.0
→ expr: non-integer argument
```

A syntax error like the last ones is easily noticed, but integer responses with a discarded float part can easily go unnoticed and lead to wrong results.

That’s why I always use a scripting language like Lua for that. But you can choose any scripting language that you’re familiar with. I just use Lua as an example. The advantages are

- a familiar syntax
- familiar functions
- familiar caveats
- flexible input
- spaces usually don’t matter
- floating point output

Examples:

```
lua -e "print(9/2)"
→ 4.5
lua -e "print(9 / 2)"
→ 4.5
lua -e "print(9.0/2)"
→ 4.5
lua -e "print (9 /2.)"
→ 4.5
lua -e "print(math.sqrt(9))"
→ 3
```

You can use `calc`

:

If you just enter `calc`

with no other arguments it enters an interactive mode where you can just keep doing math. You exit this by typing exit:

```
C-style arbitrary precision calculator (version 2.12.3.3)
Calc is open software. For license details type: help copyright
[Type "exit" to exit, or "help" for help.]
; 2+4
6
; 3+5
8
; 3.4+5
8.4
; 2^4
16
; exit
```

Or you use it with the expression as an argument and it will provide the answer and then exit

```
$calc 2 + 4
6
$
```

`calc`

is similar to `bc`

, I just like the way it behave as default better

For console calculations, I use `concalc`

. (`sudo aptitude install concalc`

)

After that, just type `concalc`

and hit enter. It won’t supply a prompt, but just type in the your calculation (no spaces) and hit enter, and on the next line, it’ll give you the numeric value.

I like to fire up Python and use it as an interactive calculator (but then again, I’m a Python programmer).

I can’t believe to read “the power of JavaScript” (but I had to upvote the answer for the other parts, except perl of course.

Practically, for the simple cases where integer arithmetic is sufficient, I use the buildin $((…)) and recommend it. Else, in almost all cases echo “…” | bc is sufficient.

For some arithmetic operations like statistics, matrix operations and more `R`

is the better tool:

```
echo 25 + 5 | R --vanilla
```

and for small datasets and graphical throw away results, `oocalc`

is a nice utility.

```
$> ghc -e '20 + 5'
25
it :: Integer
```

Also `ghci`

, that is the *Glasgow-Haskell Compiler* in interactive mode (`ghc --interactive`

, as opposed to it evaluating an expression with `-e`

), makes for a fascinating “calculator”:

```
$>ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> pi
3.141592653589793
Prelude> ceiling pi
4
Prelude> compare 1 2
LT
```

Since no-one else has mentioned it, and though it’s not strictly a calculator (but neither are all these general-purpose scripting languages), I’d like to mention `units`

:

```
$ units "1 + 1"
Definition: 2
$ units "1 lb" "kg"
* 0.45359237
/ 2.2046226
```

Or, for less output so you can get just the number to use in `$()`

to assign to something:

```
$ units -t "1 + 1"
2
$ units -t "1 lb" "kg"
0.4539237
```

And it even does temperature conversions

```
$ units -t "tempC(20)" "tempF"
68
```

To get the temperature conversion in an expression for further calculation, do this:

```
$ units -t "~tempF(tempC(20))+1"
68.1
```

Nobody has mentioned awk yet?

Using POSIX shell functions, and awk math power, just define this (one line) function:

```
calc(){ awk "BEGIN { print $*}"; }
```

Then just execute things like `calc 1+1`

or `calc 5/2`

Note: To make the function always available, add it to ~/.bashrc (or your corresponding shell’s startup file)

Of course, a little script named “calc” with the following contents:

```
#!/bin/sh -
awk "BEGIN { print $* }"
```

could also work.

**SQLite**:

```
echo 'select 1 + 1;' | sqlite3
```

**MySQL**:

```
mysql -e 'select 1 + 1 from dual;'
```

**PostgreSQL**:

```
psql -c 'select 1 + 1 as sum;'
```

I use a little python script that will evaluate a python expression and print the result, then I can run something like

```
$ pc '[i ** 2 for i in range(10)]'
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

the script is:

```
#!/usr/local/bin/python3
import sys
import traceback
from codeop import CommandCompiler
compile = CommandCompiler()
filename = "<input>"
source = ' '.join(sys.argv[1:]) + 'n'
try:
code = compile(source, filename)
except (OverflowError, SyntaxError, ValueError):
type, value, sys.last_traceback = sys.exc_info()
sys.last_type = type
sys.last_value = value
if filename and type is SyntaxError:
# Work hard to stuff the correct filename in the exception
try:
msg, (dummy_filename, lineno, offset, line) = value.args
except ValueError:
# Not the format we expect; leave it alone
pass
else:
# Stuff in the right filename
value = SyntaxError(msg, (filename, lineno, offset, line))
sys.last_value = value
lines = traceback.format_exception_only(type, value)
print(''.join(lines))
else:
if code:
exec(code)
else:
print('incomplete')
```

Unfortunately I don’t remember where I borrowed most of the code from, so I can’t cite it.

Use the *GNU Multiple Precision Arithmetic Library* through the supplied `run-expr`

program:

- Download and extract(you will need lzip):
`tar -xvf gmp-5.1.3.tar.lz`

- In the top directory,
`./configure`

and`make`

(no need to install) - In demos/expr,
`make run-expr`

- I like to create a symbolic link to it in my
`~/bin`

directory:`ln -s /path/to/gmp/demos/expr/run-expr ~/bin/run-expr`

- Add an alias for easy use; for instance
`alias calcf='run-expr -f'`

for floating point evaluation

Output:

```
# calcf '2/3'
"2/3" base 0: result 0.666666666666666666667e0
```

From the `run-expr.c`

file:

```
Usage: ./run-expr [-z] [-q] [-f] [-p prec] [-b base] expression...
Evaluate each argument as a simple expression. By default this is in mpz
integers, but -q selects mpq or -f selects mpf. For mpf the float
precision can be set with -p. In all cases the input base can be set
with -b, or the default is "0" meaning decimal with "0x" allowed.
```

See the manual for function classes differences and details.

## Gnuplot

*gnuplot – an interactive plotting program*

Follow the above link or type `gnuplot`

form the prompt then `help`

inside the *gnuplot* interpreter.

*Gnuplot* is a program born to plot data, but can be used for calculation too. It offer the advantage that you can define functions and or use the built-in ones.

```
echo "pr 20+5/2" | gnuplot # Lazy-note `pr` instead of print
22 # Integer calculation & result
echo "pr 20.+5/2" | gnuplot # Lazy-note `pr` instead of print
22.0 # Floating point result
echo "pr sin(2*pi/3.)" | gnuplot # Some functions ...
0.866025403784439
```

## Root (or some other *C interpreter*)

The ROOT system provides a set of OO frameworks with all the functionality needed to handle and analyze large amounts of data in a very efficient way…

You can use it as *C interpreter*, *CINT*, or you can use one of the many many other C interpreters . IMHO, it’s huge, complex, powerful, and not always friendly but can give big satisfaction too.

If you really do not want to listen the little voice inside you that cites Confucio and you are ready *to break a (butter)fly on the wheel* you can use *root*. In this case `-l`

is mandatory to avoid to show splash screen…

```
echo "20+5/2" | root -l
(const int)22
echo "20+5/2." | root -l
(const double)2.25000000000000000e+01
echo "cout<< 20+5/2 << endl;" | root -l
22
```

## For Integer arithmetic (where 3/2=1)

`bash`

`echo $(( 1+1 ))`

`fish`

`math 1+1`

`zsh*`

`echo $((1+1))`

*: and ksh93, yash

## For floating point arithmetic (where 3/2=1.5)

`bash`

`awk "BEGIN {print 10/3}"`

*(low precision)*`bash`

`echo "10/3"|bc -l`

*(high precision)*`fish`

`math -s4 10/3`

`zsh*`

`echo $((10./3))`

*: and ksh93, yash

You can of course configure your shell to use awk with minimum typing like `calc 10/3`

(see notes on how to do it for bash^{1} and fish^{2}).

The main reason for suggesting awk for bash is that it’s preinstalled on almost all Unix-like OSes and is reasonably light (there is of course the cost of starting a process) with a less precise but more human-friendly output than `bc -l`

which prints 20 decimal digits (although you can certainly tweak awk to get more decimal digits).

## Notes

### (1) How to use the simplified syntax in bash

Add this bash function to your `~/.bashrc`

:

```
calc(){ awk "BEGIN { print $*}"; }
```

### (2) How to use the simplified syntax in fish

Create a `calc`

fish function (i.e. a text file named `/home/ndemou/.config/fish/functions/calc.fish`

):

```
function calc
awk "BEGIN{ print $argv }" ;
end
```

The rest of solutions here all have notable drawbacks.

So I have created a new command to be able to do this in the simplest and most reliable way.

It’s simply a wrapper around Perl, but by turning behavior predictable. With more flexible input, and actual crashing on unsolvable functions.

Samples:

```
$ solve 1/5
0.2
$ solve 1.5+3.1
4.6
$ solve 1/1000000
1e-06
$ solve 7+2^3
15
$ solve "sqrt(8)"
2.82842712474619
$ solve 1/0
non solvable : 1/0
```