Ich habe ein Szenario
wo ich die Summe einer bestimmten Spalte mit den folgenden beiden Befehlen berechne
kann mir jemand im Detail erklären, was der Befehl eigentlich ausführt
Erster Befehl [bei Verwendung zur Berechnung der Summe einer bestimmten Spalte]
awk -F '"?\\|"?' '{T+=$(2)*1000} END {printf "%.2f\n",T/1000}' demofile.txt
Zweiter Befehl [bei Verwendung zur Berechnung der Summe einer bestimmten Spalte]
awk -F '"?\\|"?' '{T+=$(2)} END {printf "%.2f\n",T}' demofile.txt
wenn die mit beiden Befehlen berechnete Summe unterschiedlich ist. Warum ist das so?
Dies ist die Ausgabe: Dies ist die Datei, die zur Berechnung verwendet wurde [bitte herunterladen und testen] (Link vom Moderator entfernt, möglicherweise Sicherheitsbedenken)
Antwort1
Der Unterschied liegt darin, was diegawk
HandbuchZustände:
Binäre Gleitkommadarstellungen und Arithmetik sind ungenau. Einfache Werte wie
0.1
können mit binären Gleitkommazahlen nicht genau dargestellt werden, und die begrenzte Genauigkeit von Gleitkommazahlen bedeutet, dass geringfügige Änderungen in der Reihenfolge der Operationen oder der Genauigkeit der Zwischenspeicherung das Ergebnis verändern können. Um die Sache noch schlimmer zu machen, können Sie bei Gleitkommaarithmetik mit beliebiger Genauigkeit die Genauigkeit vor Beginn einer Berechnung festlegen, können sich dann aber nicht sicher sein, wie viele signifikante Dezimalstellen das Endergebnis haben wird.
gawk
ist GNU awk
. Es unterstützt-M
:
-M --bignum
Wählt Arithmetik mit beliebiger Genauigkeit für Zahlen aus. Diese Option hat keinen Effekt, wenn
gawk
nicht für die Verwendung der GNU MPFR- und MP-Bibliotheken kompiliert wurde.
Ihr Befehl awk
kann gleichbedeutend mit sein oder auch nicht gawk
. In meinem Debian 9 ergibt jeder der folgenden beiden Befehle 25396577843.76
:
LC_NUMERIC=C gawk -M -v PREC=60 -F '"?\\|"?' '{T+=$(2)*1000} END {printf "%.2f\n",T/1000}' demofile.txt
LC_NUMERIC=C gawk -M -v PREC=60 -F '"?\\|"?' '{T+=$(2)} END {printf "%.2f\n",T}' demofile.txt
Obwohl printf "%.4f\n",T
ich mit immer noch einen Unterschied sehe. Erhöhen Sie den Wert, PREC
um bessere Ergebnisse zu erzielen.
Das zugrunde liegende Problem wird auf dieser Site erklärt:
Was jeder Programmierer über Gleitkommaarithmetik wissen sollte