Warum gibt es einen Unterschied zwischen diesen beiden Summenbefehlen?

Warum gibt es einen Unterschied zwischen diesen beiden Summenbefehlen?

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: Bildbeschreibung hier eingeben 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 diegawkHandbuchZustände:

Binäre Gleitkommadarstellungen und Arithmetik sind ungenau. Einfache Werte wie 0.1kö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.

gawkist GNU awk. Es unterstützt-M:

-M
--bignum

Wählt Arithmetik mit beliebiger Genauigkeit für Zahlen aus. Diese Option hat keinen Effekt, wenn gawknicht für die Verwendung der GNU MPFR- und MP-Bibliotheken kompiliert wurde.

Ihr Befehl awkkann 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",Tich mit immer noch einen Unterschied sehe. Erhöhen Sie den Wert, PRECum bessere Ergebnisse zu erzielen.

Das zugrunde liegende Problem wird auf dieser Site erklärt:
Was jeder Programmierer über Gleitkommaarithmetik wissen sollte

verwandte Informationen