13

I have read that bash can do integer arithmetic without using an external command, for example:

echo "$((3 * (2 + 1)))"

Can bash also do floating-point arithmetic without using an external command?

  • 1
    I don't believe so, but zsh does. – jesse_b Dec 23 '17 at 20:14
  • 11
    Technically, since floating point arithmetic can be calculated (or approximated) with integers, the answer is "yes". But writing a software floating point library in shell script isn't really my idea of fun. – Chris Davies Dec 23 '17 at 21:22
  • If you know how many bits you need for the fraction part of your numbers and the whole part, you just can calculate in these fractions as units. https://codegolf.stackexchange.com/a/61719/19214 shows a mandelbrot calculation in BASH with a resolution of 1/4096. Such a strategy can be applied to a wide range of everyday problems. The example was for PCG, so a bit cryptic, but the shift operations give a hint about how multiplication looks in this number representation. –  Dec 24 '17 at 01:26
  • 1
    ksh does floating point arithmetic and also has full support for all libm mathematical functions. – fpmurphy Dec 24 '17 at 03:08
  • 1
    @yeti: That's fixed-point, not floating point. It's certainly worth pointing out as an alternate way to handle fractional values using mostly integer math, but floating point means there's an exponent stored explicitly so the relative precision is the same at any magnitude. (i.e. a constant number of significant figures instead of a constant number of places after the decimal.) – Peter Cordes Dec 24 '17 at 03:26

2 Answers2

27

No.

Bash cannot perform floating point arithmetic natively.


This is not what you're looking for but may help someone else:

Alternatives

  1. bc

bc allows floating point arithmetic, and can even convert whole numbers to floating point by setting the scale value. (Note the scale value only affects division within bc but a workaround for this is ending any formula with division by 1)

$ echo '10.1 / 1.1' | bc -l
9.18181818181818181818
$ echo '55 * 0.111111' | bc -l
6.111105
$ echo 'scale=4; 1 + 1' | bc -l
2
$ echo 'scale=4; 1 + 1 / 1' | bc -l
2.0000

  1. awk

awk is a programming language in itself, but is easily leveraged to perform floating point arithmetic in your bash scripts, but that's not all it can do!

echo | awk '{print 10.1 / 1.1}'
9.18182
$ awk 'BEGIN{print 55 * 0.111111}'
6.11111
$ echo | awk '{print log(100)}'
4.60517
$ awk 'BEGIN{print sqrt(100)}'
10

I used both echo piped to awk and a BEGIN to show two ways of doing this. Anything within an awk BEGIN statement will be executed before input is read, however without input or a BEGIN statement awk wouldn't execute so you need to feed it input.


  1. Perl

Another programming language that can be leveraged within a bash script.

$ perl -l -e 'print 10.1 / 1.1'
9.18181818181818
$ somevar="$(perl -e 'print 55 * 0.111111')"; echo "$somevar"
6.111105

  1. Python

Another programming language that can be leveraged within a bash script.

$ python -c 'print 10.1 / 1.1'
9.18181818182
$ somevar="$(python -c 'print 55 * 0.111111')"; echo "$somevar"
6.111105

  1. Ruby

Another programming language that can be leveraged within a bash script.

$ ruby -l -e 'print 10.1 / 1.1'
9.18181818181818
$ somevar="$(ruby -e 'print 55 * 0.111111')"; echo "$somevar"
6.111105
jesse_b
  • 37,005
  • 1
    and more alternatives by @Stéphane Chazelas https://unix.stackexchange.com/questions/40786/how-to-do-integer-float-calculations-in-bash-or-other-languages-frameworks/40787 – frams Dec 24 '17 at 03:38
  • Thank you for your detailed answer. I accept the reality, but I don't know the reasoning for it. Why after so many years there is still a strong resistance to support floating point arithmetic In bash? Can someone shed some light on it? Why do we develop ksh and zsh instead of just doing the right thing in bash? – mabalenk Apr 15 '21 at 17:29
3

"Can bash also do floating-point arithmetic without using an external command?"

Nope.

robert@pip2:/tmp$ echo $((2.5 * 3))
bash: 2.5 * 3: syntax error: invalid arithmetic operator (error token is ".5 * 3")