我想使用bc
来计算3位小数的平均值,舍入到最接近的值。
例如:
平均3,3和5应该产生3.667
和
平均3,3和4应该产生3.333
我试过了:
echo "scale=3; $sum/$n+0.0005" | bc
但scale
并不像我预期的那样。 我能做些什么来解决我的问题?
你的诀窍添加0.0005
不是一个坏主意。 尽管如此,这并不是那么有效。 当bc
执行某些操作(如分区)时,内部会使用scale
。
在你的情况下,最好先进行分割,也许使用scale
或-l
切换到bc
1 (如果你的版本支持它),然后加0.0005
,然后设置scale=3
并执行涉及scale
的操作在内部进行截断。
就像是:
`a=$sum/$n+0.0005; scale=3; a/1`
当然,不管sum
是正数还是负数,你都要继续不同的处理。 幸运的是, bc
有一些有条件的操作符。
`a=$sum/$n; if(a>0) a+=0.0005 else if (a<0) a-=0.0005; scale=3; a/1`
然后你会想用printf
格式化这个答案。
包装在一个函数round
(你可以选择小数位数):
round() { # $1 is expression to round (should be a valid bc expression) # $2 is number of decimal figures (optional). Defaults to three if none given local df=${2:-3} printf '%.*f\n' "$df" "$(bc -l <<< "a=$1; if(a>0) a+=5/10^($df+1) else if (a<0) a-=5/10^($df+1); scale=$df; a/1")" }
尝试一下:
gniourf$ round "(3+3+4)/3" 3.333 gniourf$ round "(3+3+5)/3" 3.667 gniourf$ round "-(3+3+5)/3" -3.667 gniourf$ round 0 0.000 gniourf$ round 1/3 10 0.3333333333 gniourf$ round 0.0005 0.001 gniourf$ round 0.00049 0.000
1与-l
开关, scale
设置为20
,这应该足够了。