Percentage Calculation in Decimal

Hi,

I have two variable and I need to calculate the percentage of them.

Example:

(b-a)*100/b

How can I do it? I need to do it till 2 decimal point.

ksh93:

$ a=10
$ b=13.5
$ printf "%.2f\n" $(((b-a)/b*100))
25.93

or with bc :

$ a=10
$ b=13.5
$ printf "%.2f\n" $(echo "scale=2\n(($b-$a)*100)/$b"|bc)
25.92

not working :frowning:

[[XXXXXXXXXXXXXXXXX]:~ 07:01:55 $]b=47
[[XXXXXXXXXXXXXXXXX]:~ 07:02:09 $]a=7
[[XXXXXXXXXXXXXXXXX]:~ 07:02:16 $]printf "%.2f\n" $(((b-a)/b*100))
0.00
[[XXXXXXXXXXXXXXXXX]:~ 07:02:20 $]printf "%.2f\n" $(((b-a)*100/b))
85.00
[[XXXXXXXXXXXXXXXXX]:~ 07:02:37 $]printf "%.2f\n" $(echo "scale=2\n(($b-$a)*100)/$b"|bc)
(standard_in) 1: illegal character: \
(standard_in) 1: parse error
0.00

Please help.
1st one not giving decimal output and 2nd one not working.

printf "%.2f\n" $(echo -e "scale=2\n(($b-$a)*100)/$b"|bc)
1 Like

now working like a charm :b:

hi,One problem ..
It's not rounding :frowning:
For example if output is 12.359 then it is giving 12.35 not 12.36
Can anybody help me doing it?

Which shell you are using..?

$ printf "%.2f\n" 12.359
12.36

printf sees the output of bc .So, bump up the scale for bc a bit:

printf "%.2f\n" $(echo -e "scale=10\n(($b-$a)*100)/$b"|bc)

sorry my bad. I should have checked the actual problem ..

here is the real problem

printf "%.2f\n" 12.355 --> output 12.35

But I need it as 12.36

Seem to be a bug that may not be so simple to solve.

12.355000 -> 12.35 correct 12.36
12.355001 -> 12.36 correct 12.36
printf "%.2f\n" $(echo -e "scale=10\n(($b-$a)*100)/$b"+0.01|bc)

It will solve your problem. :slight_smile:

will it? What if I have like 12.991 ?
Then it will make it 13 right? Should I add some more small value? :smiley:
Like 0.0001 :wink:

good catch...:slight_smile:

my bad :o

if you think about small value then still it will be same case if you find there also 12.9999 for 0.0001. :smiley:

It better if you check the digit after .
if it is 55 then change it to 56.

I know this is also not good way of doing it..

try

printf "%.2f\n" $(echo -e "scale=10\n(($b-$a)*100)/$b"|bc | sed 's/\.55/\.56/')
1 Like

one more problem ..

what if the value is 12.55? It will make it 12.56 right?
And also we may need to take care many more things :frowning:

Like it's not only that I will get 12.55

I may get 1.155 --> And it should give me 1.16

Yes it will make any number having .55 to .56

for your second and first condition use..:slight_smile:

printf "%.2f\n" $(echo -e "scale=10\n(($b-$a)*100)/$b"|bc | awk -F "." '$2 ~ /^55|[0-9]55/{sub("55","56",$2)}1' OFS=".")

EDIT -

what if we use only awk..

echo "" | awk -v BB="$b" -v AA="$a" '{ s=(( BB - AA)* 100)/BB;
if(s ~ /\.55|\.[0-9]55/){split(s,P,".");sub("55","56",P[2]);s=P[1]"."P[2]};printf "%.2f", s}'

pamu

It seems that bash is using Round half down instead of the more commonly used Round half up .
So if you do not like this rule, you need to make a test for the number, and then round it up as in example of pamu.

What Bash does in terms of rounding depends on the underlying libc sprintf() function. In most cases, sprintf() does unbiased rounding - not round half down or round half up.

In unbiased rounding, �.5' rounds to even. For example:

$ printf "%.0f\n"  1.5
2
$ printf "%.0f\n"  2.5
2