在Bash中使用bc舍入数字

Yas*_*aya 9 linux bash bc

我想计算一个带有3位小数的平均值,四舍五入到最近,使用bc.

例如:

平均值为3,3和5应该产生3.667

平均值为3,3和4应该产生3.333

我试过了:

echo "scale=3; $sum/$n+0.0005" | bc
Run Code Online (Sandbox Code Playgroud)

scale不像我期望的那样.我该怎么做才能解决我的问题?

gni*_*urf 5

你添加的技巧0.0005并不是一个坏主意.虽然,它并不是那么有效.scalebc执行某些操作(如分区)时在内部使用.

在您的情况下,最好先执行除法,可能使用大型scale-l切换为bc1(如果您的版本支持它),然后添加0.0005然后设置scale=3并执行scale内部操作以执行截断.

就像是:

`a=$sum/$n+0.0005; scale=3; a/1`
Run Code Online (Sandbox Code Playgroud)

当然,无论sum是积极的还是消极的,你都希望以不同的方式行事.幸运的是,bc有一些条件运算符.

`a=$sum/$n; if(a>0) a+=0.0005 else if (a<0) a-=0.0005; scale=3; a/1`
Run Code Online (Sandbox Code Playgroud)

然后,您将要使用格式化此答案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")"
}
Run Code Online (Sandbox Code Playgroud)

试试吧:

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
Run Code Online (Sandbox Code Playgroud)

1-l开关,scale设置为20,应足够充足.

  • 谢谢!有用.但似乎我必须努力编写这样的代码 (3认同)