2014-10-02 11 views
5

Ok, das ist ein Hackerrank Problem (https://www.hackerrank.com/challenges/bash-tutorials---arithmetic-operations). Im Grunde ist die Eingabe ein arithmetischer Ausdruck und ich soll eine formatierte Antwort (3 Dezimalstellen) ausdrucken. Ich versuchte dies zuerstUnterschied zwischen printf% .3f und bc Rundungsverhalten

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

Es bestanden mehrere Tests, aber nicht die erste.

5+50*3/20 + (19*2)/7 Die Antwort ist 17.929, aber mein Code druckt 17.928 aus. Ich habe versucht, diesen Code stattdessen

read exp 
printf "%.3f\n" `echo $exp | bc -l` 

Hinweis: das Echo an Backticks sein soll, aber ich habe ‚‘ nicht mit Block Anführungszeichen zu verwirren. Alle Tests bestanden. Was ist der Unterschied?

+0

Backticks sind nur für Code-Formatierung weniger als eine Zeile geeignet - für mehrzeilige Segmente verwenden Sie Einzug für Code-Formatierung (was der Javascript-Editor für Sie tun wird, wenn Sie auf die Schaltfläche Code klicken). –

+0

... alternativ verwenden Sie '$ (...)' anstelle von '\' ... \ '' jedenfalls - es ist die moderne POSIX-Syntax und weniger verwirrend zu verschachteln. –

+0

.... auch - 'echo" $ exp "| bc -l', nicht 'echo $ exp | bc -l'; Wenn Ihr Ausdruck Leerzeichen um das '*' herum enthält, hätten Sie ein sehr überraschendes Verhalten ohne die Anführungszeichen (und sogar ohne die Leerzeichen hätten Sie ein überraschendes Verhalten, wenn Ihre Shell die 'Nullglob'-Option aktiviert hätte). –

Antwort

5

Der Grund, dass die beiden sich unterscheiden, ist, dass bc immer die Zahlen abschneidet, anstatt sie zu runden. I. e. echo "scale = 3 ; 8/9" | bc ergibt 0,888 anstelle der korrekt gerundeten 0,889.

Ihr Testfall ergibt 17,928571429, der mit Ihrem printf Ansatz auf 17,929 gerundet wird, aber mit dem bc Ansatz auf 17,928 abgeschnitten wurde.

2

Ich denke, das Problem ist scale = 3; Teil. Wenn Sie beispielsweise

 printf "%.3f\n" ` echo "scale = 3 ; $exp " | bc -l` 

verwenden, erhalten Sie 17.928 erneut. Die Antwort ist also, dass Sie die Skalierung mindestens auf 4 und dann dreistellig einstellen müssen.

1

Das Problem ist Rundungs ​​ und/oder signifikante Ziffern zurückgegeben durch bc. Wenn Sie echo mit scale=3 verwenden, verlassen Sie sich auf bc, um nur 3 Ziffern zurückzugeben. Wenn Sie printf zur Ausgabe nur 3 Dezimalstellen (mit dem Format %.3f) sagen, verlassen Sie sich auf printf zu bestimmen, welche Ziffern. Im Wesentlichen besteht der Unterschied in der Rundung, die durch bc unter Verwendung von scale=3 und durch printf mit der doppelten %.3f Umwandlung durchgeführt wird.

+0

Ich hoffe, ich bin nicht anmaßend oder schwerfällig mit dem Schnitt. –

+0

Nein - sieht perfekt aus. Nehmen Sie alle redaktionelle Freiheit, die Sie brauchen :) –

0
v=$(sed 's/[[:blank:]]//g') 
(echo "scale=4"; echo $v) | bc | xargs printf '%.3f' 

Die oben liest die ganze Zahl von stdin, entfernt die Leerzeilen, Rohre, es zu bc die Berechnung mit 4 Ziffern Genauigkeit durchzuführen, formatiert sie dann mit korrekter Rundung auf 3 Stellen mit Hilfe von printf. Meine Lösung für das oben erwähnte HackerRank-Problem.

+2

Bitte nicht Code-nur Antworten dump.Erklären Sie, was der Code bedeutet – arco444