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
, yash
and zsh
do support floats here:
$ echo "$((1.2 / 3))"
0.4
only ksh93
(directly) and zsh
loading library mathfunc here:
$ 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: best calculator (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
andmake
(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 bash1 and fish2).
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