# Why does division in bash arithmetic compute most percentages as 0?

Attempting bash arithemetic for a script, but `\$e` does not update till the end. The output speaks for itself.

``````max=5
for e in \$(seq 1 1 \$max); do
percent=\$(( \$e/\$max*100 ))
echo "echo \$e / \$max : = \$percent"
done
``````

Tl;DR: Display 1..5 as a percentage.

Output :

``````echo 1 / 5 : = 0
echo 2 / 5 : = 0
echo 3 / 5 : = 0
echo 4 / 5 : = 0
echo 5 / 5 : = 100
``````

Why is this?

`bash` cannot handle non-integer arithmetic. It will give you the correct result as long as all the expressions are integers. So you need to avoid getting a non-integer value somewhere in your calculation.

In your case, when you are evaluating `1 / 5`, `2 / 5` etc. it creates the integer zero values in bash correspondings to some non-integer values and the results are coming out to be zero accordingly. Precedence of division and multiplication are the same and same precedent operators are always executed left to right as they are placed in the expression.

One work around will be to do the multiplication first and then the division so bash never has to handle non-integer value. The corrected expression will be,

``````\$ max=5; for e in \$(seq 1 1 \$max); do percent=\$(( \$e*100/\$max )); echo "echo \$e / \$max : = \$percent"; done
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100
``````
• The subexpression `1/5` does not create a non-integer value. It creates the integer value `0`, since the result of integer division of 1 by 5 is 0. Further operations successfully use that value of `0`. This isn't what the OP intended, but no operation creates a non-integer value and no operation fails. Sep 9, 2019 at 18:22
• @EliahKagan thank you for pointing it out the flaw. Edited. Sep 10, 2019 at 5:44

Bash doesn't do very well at this kind of arithmetic... Here's your problem:

``````\$ echo \$((1/5))
0
\$ echo \$((2/5))
0
\$ echo \$((4/5))
0
\$ echo \$((4/5))
0
``````

If you need to handle non-integer values, you can use `bc`

``````\$ max=5; for e in \$(seq 1 1 "\$max"); do percent=\$(bc <<< "scale=1 ; \$e/\$max*100") ; echo "echo \$e / \$max : = \${percent%.*}"; done
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100
``````

(thanks to @Arronical for pointing out how to format the output as integers)

• I shall definitely have a look into this, thanks once again! Sep 16, 2016 at 7:20
• You can trim the `.0` from the output by changing `\$percent` in your echo to `\${percent%.*}` :) Sep 16, 2016 at 11:26

Unlike bash, awk offers full floating point arithmetic. For example:

``````\$ awk -v max=5 'BEGIN{for (e=1;e<=max;e++) print "echo " e " / " max " : = " 100*e/max}'
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100
``````

Try

``````percent=\$(( \$e*100/\$max ))
``````

:)

See section ARITHMETIC EVALUATION of:

``````man bash
``````

It only supports integer.