4

I have an expression "5+50*3/20 + (19*2)/7" I need to round it up to 3 decimal places. The answer to this is 17.92857142857143. When I use the script below it is giving me 17.928. The answer should be 17.929.

read exp
echo "scale=3; $exp" |bc -l

And one more question is how to use printf to do the same task

4
  • You mean "round up" to three decimals. Depending on the rounding conventions applied, 17.928 may or may not be correct.
    – muru
    Dec 8, 2014 at 14:51
  • Yes round it up. Dec 8, 2014 at 14:52
  • 1
    Don't try to do it in bash, use python or something else. At any rate, see: askubuntu.com/questions/179898/…
    – muru
    Dec 8, 2014 at 14:54
  • 1
    echo $(printf "%.3f\n" $(echo " scale=4; $exp" |bc)) I used this and got the ans. But will see any one comes up with alternate method. I am learning bash so using it. Dec 8, 2014 at 14:59

4 Answers 4

8

Just write this:

read exp
printf %.3f $(echo "$exp" | bc -l)
2
  • 1
    Please elaborate your answer for the benefit of other users. Feb 28, 2017 at 9:38
  • 1
    $(command) is 'command substitution', it runs the command, captures its output and inserts it into the command line that contains the $(…) bc -l is calculating the expression and giving the result upto 20 decimal places printf %.3f is taking floating number where .3 tells it to round the number to 3 decimal places.
    – Amit24x7
    Feb 28, 2017 at 13:33
4

You can simplify the expression from your comment by using "here string" end removing both echos:

 printf "%.3f\n" "$(bc -l <<< "$var")"

or even

 printf "%.3f\n" "$(bc -l <<< "5+50*3/20 + (19*2)/7")"
2
  • Are the quotes around $(...) and $var necessary? It seems to work without the quotes, so I was wondering if they are there for some other cases.
    – Rahul
    Mar 25, 2015 at 16:59
  • 1
    @Rahul Yes, it works here with or without quotes, but I recommend to always quote variables, command substitutions, arithmetic expansion, etc. unless you really know what you are doing. Read about details here: unix.stackexchange.com/questions/171346/…
    – jimmij
    Mar 25, 2015 at 18:48
1

Python seems have your preferred behaviour:

$ echo 'print(round(' "5+50*3/20 + (19*2)/7" ', 3))' | python3
17.929
3
  • Seems contrived to me to call a whole programming language to perform a single-line operation. Especially since there are solutions to this using purely bash. Why add such a dependancy, essentially for formatting? What if the os doesn't have python3? What if the interpreter would be call by python (as is the case on some distribution)? Older distribution? Does that work on Windows?
    – Francky_V
    Nov 13, 2020 at 17:22
  • 1
    Nobody's posted a pure bash answer yet, though. I don't see it is all that different from calling bc. If anything, Python is more likely to be available than bc these days, and likely to be already loading into memory for some other program too, so it's probably faster to launch than bc.
    – muru
    Nov 13, 2020 at 17:45
  • You're correct it is not pure bash. Still, IMO the point stands, I don't think it's a good practice. The path to the python interpreter may very well change from OS to os even on unix-base systems, not to mention windows. If that's going to be solution, then pretty much anything you can do in bash, you can do with nicer syntax in python, so why bother with bash at all, save for #!/bin/bash python [path-to-myscript.py]...
    – Francky_V
    Nov 13, 2020 at 17:53
0

Assuming that the variable $exp gets the value 17.92857142857143 in your shell script, use the following line to round and print it:

python2 -c 'print round('$exp',3)'

1
  • As for the other - answer using python... Calling on such a dependancy for as one-liner that can definitely be done in multiple ways in bash is beyond me....
    – Francky_V
    Nov 13, 2020 at 17:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .