簡體   English   中英

在Bash中使用bc舍入數字

[英]Rounding Numbers with bc in Bash

我想用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 ,這應該足夠了。

下一個函數將參數'x'轉換為'd'數字:

define r(x, d) {
    auto r, s

    if(0 > x) {
        return -r(-x, d)
    }
    r = x + 0.5*10^-d
    s = scale
    scale = d
    r = r*10/10
    scale = s  
    return r
} 

這個解決方案不是flexibile(它只是將float轉換為int),但它可以處理負數:

e=$( echo "scale=0; (${e}+0.5)/1" | bc -l )
if [[ "${e}" -lt 0 ]] ; then
    e=$(( e - 1 ))
fi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM