2014-12-07 21 views
6

Kullanıcıdan bir aritmetik ifade okuyan ve sonuçta 3 ondalık basamaklı yuvarlama çıktısını çıktı ekranına ekleyen bu bash komut dosyasını çözmeye çalışıyorum.bc aritmetik Hata

örnek giriş

5+50*3/20 + (19*2)/7 

örnek çıktı

17.929 

bir giriş olduğu zaman zaman kodu

read x 
echo "scale = 3; $x" | bc -l 

olduğu

5+50*3/20 + (19*2)/7 

** benim çıkış makine

17.929 

ve buna bağlı i çözüm yanlış olmak istiyor hangi

17.928 

** olduğunu. Herhangi bir fikir ?

+0

Sizin soru oldukça belirsizdir. "Örnek çıktı" olarak ne diyorsunuz? "Çıktım" olarak ne diyorsunuz? Ne diyorsunuz "makine olmasını ister"? Aslında, komut dosyanızın oluşturmasını istediğiniz çıktı nedir: kesik veya yuvarlak mı? –

+0

örnek giriş, komut dosyasının doğru olup olmadığını kontrol etmek için makinenin ürettiği girdidir; bu, çıktının örnek çıktı olan çıktı olmasını bekler. ve çıkışım benim betiğimin ürettiği çıktı, ihtiyacım olan şey benim çıktıya benzeyecek çıkışımdır. @YvesDaoust – krrish

+0

Belki de açıklamanın daha az belirsiz olduğunu söylemenin yanlış olabileceğinden emin değilim. Kesilmiş veya yuvarlak mı? –

cevap

3

Burada anahtar printf kullandığınızdan emin olmaktır "% .3f" nin formatlama özelliğiyle ve printf bc için "scale = 4" olduğu sürece yuvarlamayı istediğiniz gibi yapmaya özen gösterir. Eğer komut bu komutu çalıştırırsanız

echo -e "please enter math to calculate: \c" 
read x 
printf "%.3f\n" $(echo "scale=4;$x" | bc -l) 

Sen, yukarıdaki çözüm ile ne olup bittiğini bir anlayış elde edebilirsiniz:

Burada çalışan bir senaryo echo "scale=4;5+50*3/20 + (19*2)/7" | bc sonuç 17.9285 olacaktır. Bu sonuç bir argüman olarak printf için sağlandığında, fonksiyon dördüncü ondalık hatayı hesaba katar ve değeri biçimlendirir, böylece formatlanmış sonuç tam olarak üç ondalık basamakla ve 17.929 değeriyle görüntülenir. Tamamen size yuvarlama olmadığını jherran katılıyorum

echo -e "please enter math to calculate: \c" 
read x 
printf "%.3f\n" $(bc -l <<< "scale=4;$x") 
+0

Aynı zamanda tutarlı olabilir "printf"% .3f "$ (printf" scale = 4; 5 + 50 * 3/20 + (19 * 2)/7 \ n "| bc)'. ':)' –

+0

One, her iki yerde de printf'in formatlama yeteneklerine ihtiyaç duymaz. Ben kasıtlı olarak eko b/c kullanın, o belirli kısımda biçimlendirecek bir şey yoktur. Diğer taraftan yuvarlama printf "% .3f" anlamlıdır. Kabul edilen cevabı stackoverflow.com/questions/2395284/… - – slevy1

+0

adresinden görmek isteyebilirsiniz. Lütfen karıştırma işlemini her ikisinin de yanlış olduğunu söylüyorsun. Ama düşünürken diğer kişi için kafa karışıklığı hakkında düşünmelisiniz ("Şimdi niçin' printf "ve" her iki yerde de printb "yazıyor ve orada" printf "kullanıyordu?) Yukarıdaki açıklamanız mükemmel. –

3

Numarayı yuvarlamıyorsunuz, onu kırpıyorsunuz.

$ echo "5+50*3/20 + (19*2)/7" | bc -l 
17.92857142857142857142 
$ echo "scale = 3; 5+50*3/20 + (19*2)/7" | bc -l 
17.928 

Ben sayıya yuvarlamak bilmek tek yolu awk kullanıyor:

$ awk 'BEGIN { rounded = sprintf("%.3f", 5+50*3/20 + (19*2)/7); print rounded }' 
17.929 

Yani, size örnek:

read x 
awk 'BEGIN { rounded = sprintf("%.3f", $x; print rounded }' 
1

: bir alt kabuk yaratmış kaçınan şöyle

Alternatif olarak, bu da bc için girdi olarak burada belgeyi yönlendirerek bir boru olmadan çalışır sayıyı, onu kırpıyorsun. Bu ölçeğin muhtemelen istediği gibi davranmayacağını, belki de kimsenin davranmasını istemediği bir şekilde söyleyeceğim.

> x="5+50*3/20 + (19*2)/7" 
> echo "$x" | bc -l 
17.92857142857142857142 
> echo "scale = 3; $x" | bc -l 
17.928 

Ayrıca, because of the behaviour of scale, eklemeleri ayrı her çarpma/bölme yuvarlama.Bana biraz örneklerle benim açımdan kanıtlamak edelim:

> echo "scale=0; 5/2" | bc -l 
2 
> echo "scale=0; 5/2 + 7/2" | bc -l 
5 
> echo "5/2 + 7/2" | bc -l 
6.00000000000000000000 

herhangi bir işlem yapılmazsa ölçek da çalışmıyor Ancak. Çirkin bir çalışma var:

> echo "scale=0; 5.5" | bc -l 
5.5 
> echo "scale=0; 5.5/1" | bc -l 
5 

Çekme işleri bundan kaynaklanıyor.

  • BC ölçeğini kullanmak istiyorsanız

    , sadece nihai sonuç zaten bilgisayarlı ve o zaman bile, dikkat için yap.

  • Yuvarlamanın, istediğiniz hassaslığın bir sayısının + yarısını kırpmakla aynı olduğunu unutmayın.

sen yuvarlanır gereken bir numaraya .5 eklerseniz bize en yakın tam sayıya yuvarlama örneğini ele alalım, onun tamsayı kısmı bir sonraki tamsayı değeri alacak ve kestirme istenilen sonucu verecektir. Bu sayı yuvarlanmalıysa, .5 eklenmesi, tamsayı değerini değiştirmez ve kesme, hiçbir şey eklendiğinde olduğu gibi aynı sonucu verir.

Böylece benim çözüm aşağıdaki gibidir:

Yine
> y=$(echo "$x" | bc -l) 
> echo "scale=3; ($y+0.0005)/1" | bc -l # scale doesn't apply to the +, so we get the expected result 
17.929 

, gerçekten ihtiyaç vardır böylece iki operasyonda da kesiliyor, (yukarıda açıklandığı gibi) aşağıdaki çalışmıyor unutmayın:

> echo "scale=3; ($x+0.0005)/1" | bc -l 
17.928 
+0

aslında bu işe yaramaz, aşağıda bir cevap işaretledim, işe yaradı. neyse, zamanınızı almak ve açıklamak için çok müthiştim, temel kavramı anladım, teşekkürler @Climbali – krrish