was ist der bessere Weg, um Gleitkommawerte zu summieren - Unix-Summierung der Werte bis zur Skala 8 bis 9 ergibt falsche Summe

was ist der bessere Weg, um Gleitkommawerte zu summieren - Unix-Summierung der Werte bis zur Skala 8 bis 9 ergibt falsche Summe

ich habe Szenario

wo ich ein Problem habe, weil die UNIX-Summe bis zu den Skalen 8 bis 9 mir eine falsche Summe ergibt, wie kann ich das beheben?

mein Befehl verwendet

awk -F '"?\\|"?' '{T+=$(2)} END {printf "%.2f\n",T}' demofile.txt

Dies ist der Link zur zuvor geposteten Frage Warum gibt es einen Unterschied zwischen diesen beiden Summenbefehlen?

Gibt es eine bessere Möglichkeit, damit umzugehen, sodass ich die genaue Summe erhalte?

durch Verwendung von awk oder bc oder dc

Demodaten

1|"12.8"|demo1
2|"13.5678341234567"|demo1
3|"14.578"|demo1
4|"15.58"|demo1
5|"16.56784"|demo1
6|"17.578"|demo1
7|"18.678"|demo1
8|"19.568890123"|demo1
9|"20.588792"|demo1

Antwort1

Sie sagen nicht, wie groß die Datei ist (also wie viele Zeilen Sie hinzufügen). Der Download war 18,3 MB groß, bevor die Site als „gefährlich“ und „Betrugswarnung“ angezeigt wurde. Wenn die durchschnittliche Zeilenlänge 18 beträgt, werden eine Million Floats hinzugefügt, und wir kennen die Wertespanne nicht. Die Gesamtzahl, die Sie in der Frage angeben, beträgt 13,2 Ziffern, sodass der Durchschnittswert pro Zeile bei etwa 7 Ziffern liegt, mit unbekannter Variabilität.

Wenn Sie Werte wie 27,865326635297 zu einer laufenden Summe hinzufügen, die sich 13 ganzen Ziffern nähert, wird nur der Teil 27,87 (gerundet) in die Summe aufgenommen, da .00532... außerhalb des Ergebnisbereichs von 15 oder 16 Ziffern liegt. Manchmal heben sich diese Fehler auf, manchmal nicht: Monte-Carlo-Arithmetik.

Überprüfen Sie die Ausgabe von awk --version. Wenn MPFR und MP erwähnt werden, ist Ihr awk mit erweiterter Genauigkeit kompiliert. Sie fügen Ihrem awk-Befehl einfach -M 113 hinzu. Das ist die Mantissenlänge, die Ihnen vierfach genaue Realarithmetik ermöglicht – 33 Ziffern Genauigkeit.

www.gnu.org/software/gawk/manual/gawk.html#Arbitrary-Precision-Arithmetic

Antwort2

Dies ist eine Methode, die auf derGleichstromBefehl (vorausgesetzt, dieser ist mit ausreichender Genauigkeit kompiliert). Er füllt die zweite Spalte mit DC-Befehlen auf und arbeitet mit einer Genauigkeit von 60 Ziffern (200 Bit).

Dies läuft auf den 10 zuvor bereitgestellten Datenzeilen plus einigen Extremwerten. Es zeigt Zwischensummen: Um diese zu entfernen, entfernen Sie das „p“ direkt vor dem \n, wo awk $2 ausgibt.

Paul--) cat awkToDc
#! /bin/bash

function Data { cat <<'EOF'
1|"12.8"|demo1
2|"13.5678341234567"|demo1
3|"14.578"|demo1
4|"15.58"|demo1
5|"16.56784"|demo1
6|"17.578"|demo1
7|"18.678"|demo1
8|"19.568890123"|demo1
9|"20.588792"|demo1
10|"55555555555555555555000000000000"|demo1
11|"20.588792"|demo1
12|"0.000000000000000000077777777777"|demo1
EOF
}

function dataDC {

    AWK='
BEGIN { FS = "\042"; printf ("60 k 0\n"); }
{ printf ("%s + p\n", $2); }
END { printf ("p q\n"); }
'
    awk "${AWK}"
}

Erläuterung zu den ausgegebenen DC-Befehlen (die in umgekehrter polnischer Notation vorliegen):

„60 k“ legt die arithmetische Genauigkeit fest und „0“ initialisiert die Summe.
„+“ fügt den Wert von $2 zur Summe hinzu. „p“ druckt zur Veranschaulichung die laufende Summe.
„p q“ druckt die endgültige Summe und beendet das Programm.

    Data | dataDC | dc

Paul--) ./awkToDc
12.8
26.3678341234567
40.9458341234567
56.5258341234567
73.0936741234567
90.6716741234567
109.3496741234567
128.9185642464567
149.5073562464567
55555555555555555555000000000149.5073562464567
55555555555555555555000000000170.0961482464567
55555555555555555555000000000170.096148246456700000077777777777
55555555555555555555000000000170.096148246456700000077777777777
Paul--) 

Jetzt verfügen Sie über vier getestete Techniken (im Vergleich zu Ihrer Testdatei mit 722.277 Zeilen) mit Genauigkeitsbewertungen.

Bei Verwendung von gawk mit einer Genauigkeit von 200 Bit und dc mit einer Genauigkeit von 60 Ziffern stimmen beide auf die gleiche Summe von 33 Ziffern überein, die meiner Meinung nach exakt ist.

25396577843.7560139069641121618832

Die Verwendung von gawk mit der IEEE-Standardgenauigkeit (sollte 15 oder 16 Ziffern sein) stimmt nur mit den ersten 12 dieser Ziffern überein. Ich gehe davon aus, dass eine Million Additionen die Genauigkeit verringern, da die Exponenten disjunkter werden.

25396577843.7769622802734375

Ich habe auch im Standard-AWK einen rekursiven Additionsalgorithmus gefunden. Dieser addiert zunächst Werte entsprechend den letzten 5 Ziffern von NR, um 100.000 Zwischensummen zu erhalten. Dann werden diese addiert, wobei die Anzahl der Ziffern auf 4, 3, 2, 1 und schließlich auf eine einzige Summe reduziert wird. Jede Zahl erhält daher nur 60 Additionen. Dieses Ergebnis stimmt mit den ersten 16 Ziffern der hochpräzisen Ziffern überein, was so gut ist, wie man es erwarten konnte.

25396577843.756011962890625

Antwort3

KasseZusammenfassung von Kahan, es versucht, den Rundungsfehler zu erfassen und gleicht ihn aus. Ein Muss bei solch riesigen Summen.

Antwort4

Mit cvstoolund bc:

$ csvtool -t '|' col 2 A | paste -sd + - | bc
149.5073562464567

verwandte Informationen