Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

A quick example of what I want using bash scripting:

echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
echo "scale=2; $float/1.18" |bc -l
read -p "Press any key to continue..."

Assuming that the price is: 48.86 The answer will be:41.406779661 (41.40 actually because I'm using scale=2;)

My Question is: How I round the second decimal to show the answer in this way?: 41.41

share|improve this question
I find it weird because "printf "%0.2f\n" 41.445" does now work but "printf "%0.2f\n" 41.435 and printf "%0.2f\n" 41.455" do. Even your own case works (On 12.04) but not with the .445 – Luis Alvarado Aug 24 '12 at 16:44
IMHO, nobody has answered this question satisfactorily, perhaps because bc cannot achieve what is being requested (or at least the question I was asking when I found this post), which is how to round decimals using bc (that happens to be called by bash). – Adam Katz May 21 '15 at 22:51
up vote 18 down vote accepted

A bash round function:

echo $(printf %.$2f $(echo "scale=$2;(((10^$2)*$1)+0.5)/(10^$2)" | bc))

Used in your code example:

# the function "round()" was taken from 

# the round function:
echo $(printf %.$2f $(echo "scale=$2;(((10^$2)*$1)+0.5)/(10^$2)" | bc))

echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
#echo "scale=2; $float/1.18" |bc -l
echo $(round $float/1.18 2);
read -p "Press any key to continue..."

Good luck :o)

share|improve this answer
Right now, this is the nicest way to do it, thanks for your knowledge. – blackedx Aug 24 '12 at 16:51
btw, if the number is negative, we have to use -0.5 – Aquarius Power Jun 4 '14 at 4:47
Couldn't get the example to work on the testing console! "Debugging" a little revealed that for e. g. $2 = 3 I had to use echo $(env printf %.3f $(echo "scale=3;((1000*$1)+0.5)/1000" | bc)). Mind the env before printf! This'll teach ya again that it's always important to understand what you're copy-pasting from elsewhere. – syntaxerror Oct 23 '14 at 23:04
@Aquarius Power thanks for the inspiration! I've now forked a version of the above script which will work with both negative and positive numbers. – syntaxerror Oct 23 '14 at 23:48
This is unnecessarily complicated and does all kinds of extra arithmetic to arrive at the simpler answers provided by migas and zuberuber. – Adam Katz May 21 '15 at 22:46

Simplest solution:

printf %.2f $(echo "$float/1.18" | bc -l)
share|improve this answer
As noted also in a comment above (, this would behave incorrectly for negative numbers, unfortunately. – RobertG Mar 2 at 16:35

Bash/awk rounding:

echo "23.49" | awk '{printf("%d\n",$1 + 0.5)}'  

If you have python you can use something like this:

echo "4.678923" | python -c "print round(float(raw_input()))"
share|improve this answer
Thanks for the tip but it doesn't solve what I need. I have to do it just by using bash... – blackedx Aug 24 '12 at 14:39
The python command is more readable and good for quick scripts. Also supports arbitrary digit rounding by adding e.g. ", 3" to the round function. Thanks – Jordan Trudgett Nov 13 '13 at 2:07
echo "$float" |awk '{printf "%.2f", $1/1.18}' will perform the question's requested math to the requested percision of hundredths. That's as much "using bash" as the bc call in the question. – Adam Katz May 21 '15 at 22:41
For Python you can just use something like python -c "print(round($num))" where num=4.678923. There's no need to muck about with stdin. You can also round to n digits like so: python -c "print(round($num, $n))". – Six Nov 25 '15 at 20:32
I managed to do something pretty neat with that solution, my problem was 0.5, in this case I didn't always get the round I needed so I came up with the following: echo 5 | python -c "print int(round((float(raw_input())/2)-0.5))" (When + will round up and - round down). – Yaron Jun 13 at 9:39

I'm still looking for a pure bc answer to how to round just one value within a function, but here's a pure bash answer:


echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"

embiggen() {
  local int precision fraction=""
  if [ "$1" != "${1#*.}" ]; then  # there is a decimal point
    fraction="${1#*.}"       # just the digits after the dot
  int="${1%.*}"              # the float as a truncated integer
  precision="${#fraction}"   # the number of fractional digits
  echo $(( 10**10 * $int$fraction / 10**$precision ))

# round down if negative
if [ "$float" != "${float#-}" ]
  then round="-5000000000"
  else round="5000000000"

# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))

int=${answer%??}  # the answer as a truncated integer

echo $int.${answer#$int}  # reassemble with correct precision

read -p "Press any key to continue..."

Basically, this carefully extracts the decimals, multiplies everything by 100 billion (10¹⁰, 10**10 in bash), adjusts for precision and rounding, performs the actual division, divides back to the appropriate magnitude, and then reinserts the decimal.


The embiggen() function assigns the truncated integer form of its argument to $int and saves the numbers after the dot in $fraction. The number of fractional digits is noted in $precision. The math multiplies 10¹⁰ by the concatenation of $int and $fraction and then adjusts that to match the precision (e.g. embiggen 48.86 becomes 10¹⁰ × 4886 / 100 and returns 488600000000 which is 488,600,000,000).

We want a final precision of hundredths, so we multiply the first number by 100, add 5 for rounding purposes, and then divide the second number. This assignment of $answer leaves us at a hundred times the final answer.

Now we need to add the decimal point. We assign a new $int value to $answer excluding its final two digits, then echo it with a dot and the $answer excluding the $int value that's already taken care of. (Never mind the syntax highlighting bug that makes this appear like a comment)

(Bashism: exponentiation is not POSIX, so this is a bashism. A pure POSIX solution would require loops to add zeros rather than using powers of ten. Also, "embiggen" is a perfectly cromulant word.)

One of the main reasons I use zsh as my shell is that it supports floating point math. The solution to this question is quite straightforward in zsh:

printf %.2f $((float/1.18))

(I'd love to see somebody add a comment to this answer with the trick to enabling floating point arithmetic in bash, but I'm pretty sure that such a feature doesn't yet exist.)

share|improve this answer

Here's a purely bc solution. Rounding rules: at +/- 0.5, round away from zero.

Put the scale you're looking for in $result_scale; your math should be where $MATH is located in the bc command list:

bc <<MATH

/* the magnitude of the result scale */
t=(10 ^ $result_scale)

/* work with an extra digit */
scale=$result_scale + 1

/* your math into var: m */

/* rounding and output */
if (m < 0) h=-0.5
if (m > 0) h=0.5

a=(m * t + h)

a / t
share|improve this answer
very interesting! MATH=-0.34;result_scale=1;bc <<MATH, #ObjectiveAndClear:5 as explained here :) – Aquarius Power Mar 2 at 20:42
# - loosely based on the function "round()", taken from 

# - inspired by user85321 @ (original author)
#   and Aquarius Power

# the round function (alternate approach):

    # if negative, negate value ...
    (( $(bc <<<"$v < 0") == 1 )) && v=$(bc <<<"$v * -1")
    r=$(bc <<<"scale=$3;(((10^$3)*$v/$2)+0.5)/(10^$3)")

    # ... however, since value was only negated to get correct rounding, we 
    # have to add the minus sign again for the resulting value ...

    (( $(bc <<< "$vorig < 0") == 1 )) && r=$(bc <<< "$r * -1")
    env printf %.$3f $r

echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
round2 $float 1.18 2
echo && read -p "Press any key to continue..."

It is actually simple: there is no need to explicitly add a hardcoded "-0.5" variant for negative numbers. Mathematically spoken, we'll just compute the absolute value of the argument and still add 0.5 as we normally would. But since we (unfortunately) have no built-in abs() function at our disposal (unless we code one), we will simply negate the argument if it's negative.

Besides, it proved very cumbersome to work with the quotient as a parameter (since for my solution, I must be able to access the dividend and divisor separately). This is why my script has an additional third parameter.

share|improve this answer
@muru about your recent edits: herestrings instead of echo .. |, shell arithmetic, what is the point of echo $()? This is easy to explain: your here strings will always require a writable /tmp directory! And my solution will also work on a read-only environment, e. g. an emergency root shell where / is not always writable by default. So there was a good reason why I coded it that way. – syntaxerror Apr 17 '15 at 14:48
Herestrings, I agree. But when is echo $() ever needed? That and indentation prompted my edits, the herestrings just happened. – muru Apr 17 '15 at 14:54
@muru Well the most pointless case of echo $() that was overdue to get fixed was in fact the penultimate line, lol. Thanks for the heads-up. At least this one does look much better now, I can't deny. Anyways, I loved the logic in this. Lots of boolean stuff, less superfluous "if"s (which surely would blow up the code by 50 percent). – syntaxerror Apr 17 '15 at 14:58

if you have the result, for instance consider 2.3747888

all you have to do is:

d=$(echo "(2.3747888+0.5)/1" | bc); echo $d

this rounds the number correctly example:

(2.49999 + 0.5)/1 = 2.99999 

the decimals are removed by bc and so it rounds down to 2 as it should have

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.