Ein kurzes Beispiel für die Verwendung von Bash-Skripten:
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
echo "scale=2; $float/1.18" |bc -l
read -p "Press any key to continue..."
bash scriptname.sh
Angenommen, der Preis ist: 48,86 Die Antwort lautet: 41,406779661 (41,40 tatsächlich, weil ich verwende scale=2;
)
Meine Frage lautet: Wie runde ich die zweite Dezimalstelle, um die Antwort auf diese Weise anzuzeigen ?: 41.41
bc
nicht erreicht werden kann, was angefordert wird (oder zumindest die Frage, die ich gestellt habe, als ich diesen Beitrag gefunden habe), wie Dezimalzahlen gerundet werden könnenbc
(das heißt zufällig vonbash
).r()
Funktion, so dass Sie es nutzen könnenbc -le "r($float/1.18, 2)"
.Antworten:
Eine Bash-Round-Funktion:
In Ihrem Codebeispiel verwendet:
Viel Glück: o)
quelle
-0.5
$2 = 3
ich dafür zB verwenden mussteecho $(env printf %.3f $(echo "scale=3;((1000*$1)+0.5)/1000" | bc))
. Beachten Sie die Umgebungsbedingungen vor dem Drucken! Dies wird Ihnen wieder beibringen, dass es immer wichtig ist zu verstehen, was Sie von woanders kopieren.if [
Echo "$ 1/1" | zufrieden gegeben bc` -gt 0] `- gibt es eine elegantere Möglichkeit zu prüfen (außer die Zeichenfolge nach" - "zu analysieren)?Einfachste Lösung:
quelle
+0.5
. Versuchen Sieprintf "%.2f\n" "$(bc -l <<<"48.86/1.18")" "$(bc -l <<<"-48.86/1.18")"
und Sie werden41.41
und bekommen-41.41
.echo "$float/1.18" | bc -l | xargs printf %.2f
bash: printf: 1.69491525423728813559: invalid number
je nach Gebietsschema.Bash / awk-Rundung:
Wenn Sie Python haben, können Sie so etwas verwenden:
quelle
echo "$float" |awk '{printf "%.2f", $1/1.18}'
führt die angeforderte Mathematik der Frage mit der angeforderten Genauigkeit von Hundertsteln durch. Das ist so viel "mit bash" wie derbc
Aufruf in der Frage.python -c "print(round($num))"
where verwendennum=4.678923
. Es gibt keinen Grund, sich mit stdin herumzuschlagen. Sie können auch rund um n Stellen wie folgt:python -c "print(round($num, $n))"
.echo 5 | python -c "print int(round((float(raw_input())/2)-0.5))"
(Wann wird + auf- und abrunden).Hier ist eine rein bc Lösung. Rundungsregeln: Bei +/- 0,5 von Null abrunden.
Geben Sie den gewünschten Maßstab in $ result_scale ein. Ihre Mathematik sollte dort stehen, wo sich $ MATH in der bc-Befehlsliste befindet:
quelle
MATH=-0.34;result_scale=1;bc <<MATH
, #ObjectiveAndClear: 5 wie hier erklärt :)Ich weiß, es ist eine alte Frage, aber ich habe eine reine 'bc'-Lösung ohne' wenn 'oder Zweige:
Verwenden Sie es wie
bcr '2/3' 5
oderbcr '0.666666' 2
-> (Ausdruck gefolgt von Skala)Das ist möglich, weil es in bc (wie C / C ++) erlaubt ist, logische Ausdrücke in Ihre Berechnungen zu mischen. Der Ausdruck
((t>0)-(t<0))/2)
wird abhängig vom Vorzeichen von 't' mit +/- 0,5 bewertet und verwendet daher den richtigen Wert zum Runden.quelle
bcr "5 / 2" 0
kehrt aber2
stattdessen zurück3
. Vermisse ich etwas?Es ist eigentlich ganz einfach: Es ist nicht erforderlich, explizit eine fest codierte "-0,5" -Variante für negative Zahlen hinzuzufügen. Mathematisch gesprochen berechnen wir nur die absoluten Wert des Arguments und addieren trotzdem 0,5, wie wir es normalerweise tun würden. Da wir (leider) keine eingebaute
abs()
Funktion zur Verfügung haben (es sei denn, wir codieren eine), werden wir das Argument einfach negieren , wenn es negativ ist.Außerdem erwies es sich als sehr umständlich, mit dem zu arbeiten Quotienten als Parameter zu arbeiten (da ich für meine Lösung auf Dividende und Divisor getrennt zugreifen müssen). Aus diesem Grund hat mein Skript einen zusätzlichen dritten Parameter.
quelle
echo .. |
Shell-Arithmetik, worum geht esecho $()
? Dies ist leicht zu erklären: Ihre Here-Strings benötigen immer ein beschreibbares/tmp
Verzeichnis! Meine Lösung funktioniert auch in einer schreibgeschützten Umgebung, z. B. einer Notfall-Root-Shell, in der standardmäßig nicht immer schreibgeschützt/
ist . Es gab also einen guten Grund, warum ich es so codiert habe.echo $()
jemals gebraucht? Das und die Einrückung haben meine Änderungen veranlasst, die Herestrings sind einfach passiert.echo $()
überfällig war, um behoben zu werden, war in der Tat die vorletzte Zeile, lol. Danke für die Warnung. Zumindest sieht dieser jetzt viel besser aus, das kann ich nicht leugnen. Jedenfalls habe ich die Logik darin geliebt. Viele boolesche Sachen, weniger überflüssige "wenn" s (die den Code mit Sicherheit um 50 Prozent in die Luft jagen würden).Ich bin noch auf der Suche nach einem reinen
bc
Antwort, um nur einen Wert innerhalb einer Funktion zu runden, aber hier ist eine reinebash
Antwort:Grundsätzlich werden dabei die Dezimalstellen sorgfältig extrahiert und alles mit 100 Milliarden multipliziert (10¹⁰,
10**10
inbash
) , auf Genauigkeit und Rundung korrigiert, die eigentliche Division ausgeführt, auf die entsprechende Größe zurückgeteilt und die Dezimalstelle erneut eingefügt.Schritt für Schritt:
Die
embiggen()
Funktion weist die abgeschnittene Ganzzahlform ihres Arguments zu$int
und speichert die Zahlen nach dem Punkt in$fraction
. Die Anzahl der Nachkommastellen ist in angegeben$precision
. Die Mathematik multipliziert 10¹⁰ mit der Verkettung von$int
und$fraction
passt diese dann an die Genauigkeit an (z. B.embiggen 48.86
wird 10¹⁰ ×488600000000
4886/100 und ergibt 488.600.000.000).Wir wollen eine endgültige Genauigkeit von Hundertsteln, also multiplizieren wir die erste Zahl mit 100, addieren 5 zu Rundungszwecken und dividieren dann die zweite Zahl. Diese Zuordnung
$answer
lässt uns hundertmal die endgültige Antwort.Jetzt müssen wir den Dezimalpunkt hinzufügen. Wir weisen
$int
dem$answer
Ausschluss der letzten beiden Ziffern einen neuen Wert zu , dann denecho
mit einem Punkt und dem$answer
Ausschluss des$int
Werts, für den bereits gesorgt wurde. (Egal, welcher Syntax-Highlighting-Fehler dies wie einen Kommentar erscheinen lässt.)(Bashismus: Potenzierung ist nicht POSIX, also ist dies ein Bashismus. Eine reine POSIX-Lösung würde Schleifen erfordern, um Nullen hinzuzufügen, anstatt Zehnerpotenzen zu verwenden. Außerdem ist "embiggen" ein perfekt kromulantes Wort.)
Einer der Hauptgründe, warum ich
zsh
als Shell verwende, ist die Unterstützung von Gleitkomma-Mathematik. Die Lösung dieser Frage liegt auf der Hand inzsh
:(Ich würde gerne jemanden sehen, der dieser Antwort einen Kommentar mit dem Trick hinzufügt, Gleitkomma-Arithmetik zu aktivieren
bash
, aber ich bin mir ziemlich sicher, dass es eine solche Funktion noch nicht gibt.)quelle
Wenn Sie das Ergebnis haben, ziehen Sie beispielsweise 2.3747888 in Betracht
alles was du tun musst, ist:
Dies rundet die Zahl richtig. Beispiel:
Die Dezimalstellen werden durch entfernt
bc
und so auf 2 abgerundet, wie es sein solltequelle
Ich musste die Gesamtdauer einer Sammlung von Audiodateien berechnen.
Also musste ich:
A. Ermitteln der Dauer für jede Datei ( nicht gezeigt )
B. addiere alle Dauern (sie waren jeweils in
NNN.NNNNNN
(fp) Sekunden)C. getrennte Stunden, Minuten, Sekunden, Sekunden.
D. Ausgabe einer Folge von HR: MIN: SEC: FRAMES, wobei frame = 1/75 sec.
(Frames stammen aus dem in Studios verwendeten SMPTE-Code.)
A: benutze
ffprobe
und parse die Dauerzeile in eine fp Nummer (nicht gezeigt)B:
C:
D:
quelle
Hier ist eine abgekürzte Version Ihres Skripts, die korrigiert wurde, um die gewünschte Ausgabe zu erzielen:
Beachten Sie, dass das Aufrunden auf die nächste Ganzzahl gleichbedeutend ist mit dem Hinzufügen von 0,5 und dem Ermitteln des Floors oder dem Abrunden (für positive Zahlen).
Außerdem wird der Skalierungsfaktor zum Zeitpunkt des Betriebs angewendet. Also (dies sind
bc
Befehle, die Sie in Ihr Terminal einfügen können):quelle
Reine BC-Implementierung wie gewünscht
define ceil(x) { auto os,xx;x=-x;os=scale;scale=0 xx=x/1;if(xx>x).=xx-- scale=os;return(-xx) }
Wenn Sie das in eine Datei namens functions.bc schreiben, können Sie mit abrunden
echo 'ceil(3.1415)' | bc functions.bc
Code für die BC-Implementierung finden Sie unter http://phodd.net/gnu-bc/code/funcs.bc
quelle
quelle
Sie können awk verwenden, keine Rohre erforderlich:
Stellen Sie den Preis vorher mit der Umgebungsvariablen ein
PRICE=<val>
.Dann call the awk -
$PRICE
geht als awk-Variable in awk einprice
.Es wird dann mit +.005 auf die nächste 100 aufgerundet.
Die Formatierungsoption printf
%.2f
begrenzt den Maßstab auf zwei Dezimalstellen.Wenn Sie dies viel tun müssen, ist dieser Weg viel effizienter als die ausgewählte Antwort:
quelle