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