BASH:百分比变化 - 如何计算?如何在没有bc的情况下获得绝对价值?

问题描述 投票:2回答:4

我需要计算两个值之间的百分比变化。

我在这里的代码:

echo $time1
echo $time2
pc=$(( (($time2 - $time1)/$time1 * 100) ))
echo $pc

在控制台中输出这样的输出(使用set -xe选项)

+ echo 1800
1800
+ echo 1000
1000
+ pc=0
+ echo 0

数学表达式中的代码似乎写得正确,但是,我得到-80左右。为什么这发生在我身上?

问题的第二部分。我没有访问权限,我将无法访问bc命令。从我听到它可以给我我的数字的绝对值。

所以..没有bc命令 - 对于IF条件,这是一个好主意吗?

if (( (( "$pc" > 20 || (( "$pc" < -20 )); then...
bash math arithmetic-expressions
4个回答
4
投票

正如你所提到的,没有必要在bash中这样做,我建议使用awk:

awk -v t1="$time1" -v t2="$time2" 'BEGIN{print (t2-t1)/t1 * 100}'

通常,awk旨在处理文件,但您可以使用BEGIN块执行计算,而无需将任何文件传递给它。可以使用-v开关将Shell变量传递给它。

如果您希望对结果进行舍入,则可以始终使用printf

awk -v t1="$time1" -v t2="$time2" 'BEGIN{printf "%.0f", (t2-t1)/t1 * 100}'

%.0f格式说明符导致结果四舍五入为整数(浮点数为0位小数)。


1
投票

正确的舍入,nicer空白,没有多余的$标志:

pc=$(( ((((time2 - time1) * 1000) / time1) + (time2 > time1 ? 5 : -5)) / 10 ))

1
投票

也许你想要更喜欢bc + awk混合线,如下所示:

total=70
item=30
percent=$(echo %$(echo "scale = 2; ($item / $total)" | bc -l | awk -F '.' '{print $2}'))
echo $percent

1
投票

一些说明:

  • 数学是基于整数的,所以你早就得零,因为你分裂了
  • $(( ))语法将扩展变量,因此使用time1而不是$time1
  • 百分比答案是-44而不是-80

这里有些例子:

echo $(( time2-time1 )) # Output: -800
echo $(( (time2-time1)/time1 )) # Output: 0. see it's already zero!
echo $(( (time2-time1)/time1*100 )) # Output: 0. it's still zero and still 'incorrect'
echo $(( (time2-time1)*100 )) # Output: -80000. fix by multiplying before dividing
echo $(( (time2-time1)*100/time1 )) # Output: -44. this is the 'correct' answer
echo $(( (time2-time1)*100/time2 )) # Output: -80. note this is also an 'incorrect' answer
© www.soinside.com 2019 - 2024. All rights reserved.