How to do integer & float calculations, in bash or other languages/frameworks?
Solution 1
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>
Solution 2
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.
Solution 3
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.
Solution 4
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
Solution 5
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
Comments
-
Michael Durrant almost 2 years
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))
prints0
:(.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.
-
zinking about 12 yearsI assume author is asking for bash command line, while answers all tend to diversify to all kinds of scripting languages.
-
aqwert about 12 yearsman bash → /expression
-
minorcaseDev almost 10 yearsTeach bash integer division with floating point results: stackoverflow.com/a/24431665/3776858
-
RussellStewart almost 10 yearsI like to use pythonpy (github.com/russell91/pythonpy) for my calculator: py 3224/3807 => 0.846861045443. py 'math.factorial(4)' => 24.
-
Scott - Слава Україні over 9 years
-
Nikana Reklawyks over 8 yearsI came here because bash can't multiply floats, only integers.
-
ndemou almost 7 yearsI really don't like how this part of the question "...or other languages/frameworks?" opened the gates of hell to answers for all kind of languages/frameworks.
-
-
Michael Durrant about 12 yearsand bc is interesting:
whatis bc
->An arbitrary precision calculator language
Interesting! Thanks! -
Michael Durrant about 12 years+1 for both pipe ("|") and interactive mode options for bs. Does one
ctrl-d
to exit? -
Levon about 12 years@MichaelDurrant Yes, ^D will do the trick as will
quit
-
lgarzo about 12 years@MichaelDurrant could you re-revise your edits, I must have rejected by mistake?
-
Michael Durrant about 12 yearsadded some bolding in. Looks ok
-
Michael Durrant about 12 yearsI added your
expr
option to the accepted answer. Had to pick one to accept and centralize. -
Arcege about 12 yearsThere is also
dc
, which is even more fun since it works by reverse polish notation.echo 20 5 + p | dc
But not as practical unless you work with reverse polish notation a lot. -
Michael Durrant about 12 yearsI also like the use of
<<<
, does this mean pipe it in AND execute the command? -
lgarzo about 12 yearsThat is a Here String. (From the manual:)
<<<word
is expanded and supplied to the command on its standard input. Shorter thanecho ... |
. -
manatwork about 12 yearsAs seems you are collecting the alternatives in this answer, you may add
node
too:node -pe 20+5
. This one benefits the power of JavaScript, for example:node -pe 20+5/Math.PI
. -
lgarzo about 12 years@manatwork Added your solution.
-
manatwork about 12 years
bc
's result is not integer, just rounded toscale
, who's default value is 0. Sobc <<< 'scale=4;9.0/2.0'
if you want the fractional part. -
Marco about 12 yearsThanks for the correction. But still, it's error prone. Will I remeber to add
scale
if I usebc
in a couple of weeks? Probably not. And even if there's a way to change it permanently, it will bite you if you're on a system with the default settings. -
Peter.O about 12 yearsYou don't need to enter interactive mode, unless you particularly want to, eg:
calc -e '2+4; 3+5; 3.4+5; 2^4
prints 4 output lines, or justcalc -e 33+(3^3)
.. +1 I like the idea of using something called 'calc' for a calculator :) -
user unknown about 12 yearsJust count bc as one of the scripting languages. I always know whether I need integer results or not - if integer is alright I stay in bash, else I rarely have reason to use bc. For lua, you have to remember -e, print and parenthesis.
-
Levon about 12 yearsme too! Python is my swiss army knife
-
Peter.O about 12 yearsI've just realized that the
-e
option is not needed when there is only one expression... neat!.. -
manatwork about 12 yearsIs that
ghc
meaning Glasgow Haskell Compiler? -
David Andersson about 12 yearsThe
perl -e "print x+y"
produce ugly output. It should beperl -e 'print x+y,"\n"'
but then the input becomes ugly instead. -
lgarzo about 12 years@DavidAndersson Well, I do not use perl (just looked up the reference), but you can make the input more crowded by using
perl -e "use feature say; say 2+2"
. Or append a; echo
to the command, even anecho $(perl ...)
. Which do you think would suit best? -
manatwork about 12 years@lgarzo,
perl -E 'say 2+2'
. -
Arcege about 12 yearsI always have one window in
screen
just running Python. -
manatwork about 12 years@lgarzo, @MichaelDurrant, I made some changes: 1) Unified the examples: kept old expression for tools unknown by me; kept original
20+5
expression where floating point is not supported; added20+5/2
expression; where20+5/2
produces integer/rounded result, added floating point alternative. 2) As the question was tagged interactive, added information about how to start the tool in interactive mode. 3) If expressions' result are automatically displayed in interactive mode (ex:20+5
vs.print 20+5
), added the note “output function not needed”). Hope you also find it cleaner now. -
lgarzo about 12 years@manatwork Thanks for your thorough editing! Now it really makes sense.
-
manatwork about 12 yearsSome minor details worth to mention: 1)
from dual
is needed by Oracle, MySQL is able toselect
withoutfrom
clause. 2) PostgreSQL not requires the alias. 3) The;
is only required by SQLite. 4) MySQL and PostgreSQL will work only if they are able to connect to a database server. 5) MySQL and PostgreSQL will draw ASCII-art table around the results. To get only the value:mysql -BNe 'select 1+1'
andpsql -tAc 'select 1+1
. -
gokhan acar about 12 yearsAs a variation on the bc approach, I added the following function (that I found on stackexchange somewhere) to my .bashrc file. I can just enter calc 2+3 and get 5.
## Command line calculator calc () { bc -l <<< "$@" }
-
gopi1410 about 12 yearsholy crap! I doubt if there's anything more left!
-
rush about 12 yearsYou're trying to execute
expr 20+5
. You need to type spaces between numbers and plus to make it work:expr 20 + 5
. That's important. -
Dalker about 11 yearsJust always use
bc -l
rather than plainbc
, then never worry aboutscale
. -
Daniel over 10 yearsmy hat is off to you
-
CMCDragonkai about 10 yearsWow this is the best, even supports floats. It works without installing anything!
-
Hastur about 10 years@gopi1410 There is,[there is...(unix.stackexchange.com/a/136507/6638.8). To Michael I cannot resist the temptation to answer even if you just edit... :-) Sorry
-
RussellStewart almost 10 yearspythonpy (github.com/russell91/pythonpy) is a nice way to do this and other things in python syntax without having to fire up an interactive shell: py '3.2 * 5' => 16
-
Gavin S. Yancey over 9 yearswouldn't
print(eval(' '.join(sys.argv[1:])))
do the same thing? -
user2820379 over 9 yearsIf I would have enough reputation I would vote this down because it includes many commands which will not produce what we can say would be the expected output. Some will not even work at all (see answers below).
-
Paul Tobias over 8 yearsVery nice, I wanted to have a floating comparison, here is how I did it with your help:
a=0; b=0.0; if echo "$a" "$b" | awk '{ exit ($1 == $2) ? 0 : 1 }'; then echo 'equals'; else echo 'not equals'; fi
-
Daniel Alder over 7 years
echo "$((20.0/7))"
fails in bash and dash -
Sergio Abreu over 7 yearssugest you removing bc without scale configuration as bc without scaling doesn't perform division correctly (it rounds floor), so bc <<< 20+5/2 = fail
-
ndemou almost 7 yearsI don't like the emphasis on what other answers got wrong. When looking for answers I personally expect the answer first.
-
ndemou almost 7 yearsYou're using a hammer to hit a fly here
-
Random832 almost 7 years@ndemou It's installed by default on some distributions... and a lot of these other answers aren't. And did you really need to comment that on an answer that's five years old?
-
ndemou almost 7 yearsI think it's good to comment when I down-vote and it is a practice that's also encouraged by S.E. I don't see why five years are relevant. The same comment applies to all similar answers -- nothing personal. (BTW even the most obscure program can be be installed by default on some distribution. In this case I've tested recent installations of Debian, Ubuntu, CentOS and RedHat and units is not)
-
Stéphane Chazelas almost 7 years
awk
will use your system'sdouble
floating point type, so is going to be as precise as most other tools that don't do arbitrary precision (note that gawk can do arbitrary precision).awk
uses theOFMT
variable to convert number to their string representation for output (%.6g
by default, you may want to change that to%.17g
is you want higher precision). -
Stéphane Chazelas almost 7 years
-
asmeurer almost 7 years@ndemou I said "interactive" calculator. Although it's also worth noting that at some point if you are doing complex enough things in a script, sanity dictates you use something other than bash (like Python).
-
ipatch over 6 years@Stéphane Chazelas great answer! However I couldn't find a solution / answer for fish shell 🐠 🐚 => fishshell.com
-
Stéphane Chazelas over 6 years@Chris, fish is a moving target. They're working on their new
math
builtin (or whatever it's called now) as we speak. Feel free to edit. It's not my answer and it's community wiki. -
ipatch over 6 years@StéphaneChazelas yeah doing a search on this page for
fish
got me to the right place. ;) -
ndemou over 6 yearsThanks Stéphane Chazelas -- I've updated my answer (
math -s4
seems to be supported in older versions also) -
ijoseph almost 6 years
c () { bc -l <<< "$@" }
will define a functionc
for quick and easy use. e.g.c 3/2
will give you1.50000000000000000000
. The link in the above describing how to do that is dead. -
Levon almost 6 years@ijoseph not quite sure about the 'dead link' comment, the bc man page? Still works for me.
-
ijoseph almost 6 years@Levon the man page link still works. However, the link: paweng.com/2008/08/15/unix-command-line-calculator , which you provide as the target of "This" in the sentence "This page also shows how to set up an alias…" appears dead.
-
Levon almost 6 years@ijoseph Thanks .. I removed the reference to that 6 year old link (wish the links stood out more clearly on my browser - didn't even see it when I looked yesterday)
-
volvox about 5 yearsGreat post, but IMHO none of these are convenient in the 21st century. bc should default to scale=4 as a default.
-
Alberto Salvia Novella about 4 years📦 As command: gitlab.com/es20490446e/calc
-
Alberto Salvia Novella about 4 yearsSince all the solutions have notorious drawbacks, I have created a new command for this: unix.stackexchange.com/a/577257/223253
-
Alberto Salvia Novella about 4 years@Jeff Schaller Don't delete post without any feedback.
-
0andriy about 3 yearsWhy are you using bashism in examples where it's not needed?
-
Admin about 2 years@done The commands are not duplicates. Intentionally, there are two sequential commands of the same type to show the interger and decimal division. For example
bc
without-l
andbc
withscale
(not the whole-l
). Similar for thepython
commands, the first one is integer dividion by purpose. -
Admin about 2 years@thanasisp, though there's
dc <<< "4 k 20 5 + 2 / p"
andecho 4 k 20 5 2 / + p | dc
, which are just two ways of doing the same thing (apart from the (20+5)/2 vs. 20+5/2 distinction). The former doesn't have the integer equivalent, and the other tools don't have the variants withecho
, just the nonstandard here-string ones. The Python thing case might warrant a comment because of the Python 2 vs. 3 difference, and well,dc
'sk
might warrant a note too, though since it's RPN, I guess it can just be left obscure too. (Also thedc <<<
isn't mentioned in the longer descriptions.) -
Admin about 2 years(Saying that kinda makes me think I should go through the whole list, and besides it would be nice to have them all spell out the same expression... but I don't think I can be bothered right now. )
-
Admin about 2 years@ilkkachu I rolled back last change for the reason I explain into my comment. For example, it modified the
bc
example for integer division tobc -l
which is decimal. If you or anyone think of any improvement, please do it. -
Admin about 2 years@thanasisp, yes, and I'm saying not all of your arguments seem to apply, for the reasons I explained.