您应该bc
在字符串中构建命令,然后将此字符串传递给bc
.
如果我理解正确,你有一个数字memory
1和一个变量的数组,mean
并且你想计算 的标准差memory
(我猜,mean
这里是 的平均值memory
)。
您需要建立以下形式的字符串(X-mean)^2
:
sum_terms=0
for i in "${memory[@]}"; do
sum_terms+="+(($i)-($mean))^2"
done
此时,字符串sum_terms
包含扩展为类似以下内容的字符串:
0+((m1)-(mean))^2+((m2)-(mean))^2+ ... +((mn)-(mean))^2
最后,您想将其括在括号中,前置sqrt(
和附加/5)
并将其传递给bc
:
bc <<< "sqrt(($sum_terms)/5)"
一体:
sum_terms=0
for i in "${memory[@]}"; do
sum_terms+="+(($i)-($mean))^2"
done
bc -l <<< "sqrt(($sum_terms)/5)"
请注意,我将$mean
术语括在括号中,以防万一这是一个负数(否则它会与前面的负号发生冲突)——当我在这里时,我也将$i
术语括在括号中。
作为旁注,您还可以使用E((X-E(X))^2)=E(X^2)-E(X)^2
来计算标准偏差,并以更通用的方式进行:
给定一个数组memory
,计算其标准差:
memory=( 782636 781460 782492 781704 781860 )
sum_mem=0 sum_memsq=0
for i in "${memory[@]}"; do
sum_mem+="+($i)"
sum_memsq+="+($i)^2"
done
mean=$(bc -l <<< "($sum_mem)/${#memory[@]}")
bc -l <<< "sqrt(($sum_memsq)/${#memory[@]}-($mean)^2)"
实际上,您在这里并不需要显式for
循环,您可以printf
为您完成这项工作:
memory=( 782636 781460 782492 781704 781860 )
printf -v sum_mem '+(%s)' "${memory[@]}"
printf -v sum_memsq '+(%s)^2' "${memory[@]}"
mean=$(bc -l <<< "(0$sum_mem)/${#memory[@]}")
bc -l <<< "sqrt((0$sum_memsq)/${#memory[@]}-($mean)^2)"
1让我把你所有的变量名都小写,大写的变量名被认为是不好的做法