Fungsi selanjutnya membulatkan argumen 'x' ke digit '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
}
Trik Anda untuk menambahkan 0.0005 bukanlah ide yang buruk. Padahal, itu tidak bekerja seperti itu. scale digunakan secara internal saat bc melakukan beberapa operasi (seperti pembagian).
Dalam kasus Anda, akan lebih baik untuk melakukan pembagian terlebih dahulu, mungkin menggunakan scale yang besar atau -l beralih ke bc (jika versi Anda mendukungnya), lalu tambahkan 0.0005 lalu atur scale=3 dan melakukan operasi yang melibatkan scale secara internal untuk melakukan pemotongan.
Sesuatu seperti:
`a=$sum/$n+0.0005; scale=3; a/1`
Tentu saja, Anda ingin melanjutkan dengan cara yang berbeda baik sum adalah positif atau negatif. Untungnya, bc memiliki beberapa operator bersyarat.
`a=$sum/$n; if(a>0) a+=0.0005 else if (a<0) a-=0.0005; scale=3; a/1`
Anda kemudian ingin memformat jawaban ini menggunakan printf .
Dibungkus dalam sebuah fungsi round (di mana Anda dapat memilih jumlah angka desimal):
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")"
}
Cobalah:
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
dengan -l beralih, scale disetel ke 20 , yang seharusnya cukup banyak.
Solusi ini tidak fleksibel (hanya mengubah float menjadi int), tetapi dapat menangani angka negatif:
e=$( echo "scale=0; (${e}+0.5)/1" | bc -l )
if [[ "${e}" -lt 0 ]] ; then
e=$(( e - 1 ))
fi