Wie runde ich IEEE 754-Gleitkommazahlen in der Befehlszeile korrekt?
Ich möchte die Genauigkeit der Ausgabenummer angeben - die Anzahl der Bruchstellen.
Eine 6.66
präzise Rundung 1
sollte 6.7
zum Beispiel ergeben. Mehr in der folgenden Tabelle:
Value Precision Rounded
6.66 0 7
6.66 1 6.7
6.66 2 6.66
6.66 3 6.660
6.666 3 6.666
6.6666 3 6.667
Es sollte in einer interaktiven Shell verwendbar sein, aber idealerweise robust genug, um es in Produktions-Shell-Skripten zu verwenden.
bash
command-line
arithmetic
floating-point
Volker Siegel
quelle
quelle
awk
.Antworten:
Rundung von Gleitkommazahlen
Was bedeutet "Runden einer Gleitkommazahl"?
Das ist natürlich einfach ... Wo ist mein Mathematikbuch von der Schule ...
Nein, wir wissen bereits, dass nichts in Bezug auf Gleitkommazahlen einfach ist:
Zunächst gibt es mehrere Rundungsmodi:
Wie gehe ich mit den Eckkoffern um? Wie finde ich heraus, welche Eckfälle es gibt?
OK, es sieht so aus, als würden wir besser eine Implementierung des IEEE 754-Standards verwenden und unser System sich darum kümmern lassen.
Um eine Gleitkommazahl in der Shell auf der Grundlage der Standard-Gleitkomma-Arithmetik zu runden, benötigen wir drei Schritte:
Es stellt sich heraus, dass der Shell-Befehl
printf
all dies kann. Es kann verwendet werden, um Zahlen gemäß einer Formatspezifikation wie in beschrieben zu druckenman 3 printf
. Die Zahlen werden standardmäßig implizit gerundet, wenn dies für das Ausgabeformat erforderlich ist:Der Befehl
Mit Genauigkeit als Befehlszeilenargumente
x
auf diep
Genauigkeit der Ziffern runden :Oder in einer Shell-Pipeline mit Eingabe von
x
auf Standardeingabe undp
als Argument:Beispiele:
Schlechte Fallen
Vorsicht vor dem Gebietsschema! Es gibt das Trennzeichen zwischen dem Integral- und dem Bruchteil an - das
.
, wie Sie vielleicht erwarten.Aber sehen Sie selbst, was in einem deutschen Gebietsschema passiert, zum Beispiel:
Ja, das stimmt
6,667
- sechs Komma sechs sechs sieben. Das würde Ihr Skript sicher durcheinander bringen.(Aber nur für die beiden Kunden in Deutschland. Mit Ausnahme der Entwicklermaschinen, die derzeit für diese Kunden debuggen.)
Robuster
Verwenden Sie:
oder
Dies verwendet
/usr/bin/printf
anstelle der inbash
oderzsh
Implementierung kleinerer Inkonsistenzen bei der Implementierung derprintf
Varianten auch die Shell und umgeht einen sehr schmutzigen Effekt, wenn in einem deutschen GebietsschemaLC_ALL
festgelegt, aber nicht exportiert wird. Dann verwendet das eingebaute,
und/usr/bin/printf
verwendet.
...Siehe auch
%g
zum Runden auf eine bestimmte Anzahl von signifikanten Stellen.quelle
Das Folgende hat bei mir funktioniert.
quelle