Ihr Instinkt ist im Grunde richtig, das Sortieren in aufsteigender Reihenfolge (der Größe) verbessert normalerweise die Dinge etwas. Stellen Sie sich den Fall vor, in dem wir Floats mit einfacher Genauigkeit (32 Bit) hinzufügen und 1 Milliarde Werte gleich 1 / (1 Milliarde) und einen Wert gleich 1 sind. Wenn die 1 an erster Stelle steht, kommt die Summe auf 1, da 1 + (1/1 Milliarde) aufgrund von Genauigkeitsverlust 1 ist. Jede Addition hat keinerlei Einfluss auf die Gesamtsumme.
Wenn die kleinen Werte an erster Stelle stehen, summieren sie sich zumindest zu etwas, obwohl ich selbst dann 2 ^ 30 davon habe, während ich nach ungefähr 2 ^ 25 wieder in der Situation bin, in der jeder einzelne die Summe nicht beeinflusst nicht mehr. Also werde ich noch mehr Tricks brauchen.
Das ist ein Extremfall, aber im Allgemeinen ist das Hinzufügen von zwei Werten ähnlicher Größe genauer als das Hinzufügen von zwei Werten sehr unterschiedlicher Größen, da Sie auf diese Weise weniger Genauigkeitsbits in dem kleineren Wert "verwerfen". Indem Sie die Zahlen sortieren, gruppieren Sie Werte ähnlicher Größe, und indem Sie sie in aufsteigender Reihenfolge hinzufügen, geben Sie den kleinen Werten eine "Chance", kumulativ die Größe der größeren Zahlen zu erreichen.
Wenn es sich jedoch um negative Zahlen handelt, ist es einfach, diesen Ansatz zu "überlisten". Betrachten Sie drei Werte, um zu summieren {1, -1, 1 billionth}
. Die arithmetisch korrekte Summe ist 1 billionth
, aber wenn meine erste Addition den winzigen Wert beinhaltet, ist meine endgültige Summe 0. Von den 6 möglichen Ordnungen sind nur 2 "korrekt" - {1, -1, 1 billionth}
und {-1, 1, 1 billionth}
. Alle 6 Ordnungen liefern Ergebnisse, die auf der Skala des größten Größenwerts in der Eingabe (0,0000001% out) genau sind, aber für 4 von ihnen ist das Ergebnis auf der Skala der wahren Lösung (100% out) ungenau. Das spezielle Problem, das Sie lösen, zeigt Ihnen, ob das erstere gut genug ist oder nicht.
Tatsächlich können Sie viel mehr Streiche spielen, als sie nur in sortierter Reihenfolge hinzuzufügen. Wenn Sie viele sehr kleine Werte, eine mittlere Anzahl mittlerer Werte und eine kleine Anzahl großer Werte haben, ist es möglicherweise am genauesten, zuerst alle kleinen Werte zu addieren, dann die mittleren Werte separat zu addieren und diese beiden Summen zu addieren zusammen dann die großen hinzufügen. Es ist überhaupt nicht trivial, die genaueste Kombination von Gleitkomma-Additionen zu finden, aber um mit wirklich schlimmen Fällen fertig zu werden, können Sie eine ganze Reihe laufender Summen in verschiedenen Größen beibehalten und jeden neuen Wert zu der Summe hinzufügen, die seiner Größe am besten entspricht. und wenn eine laufende Summe für ihre Größe zu groß wird, addieren Sie sie zur nächsten Summe und starten Sie eine neue. Auf den logischen Punkt gebracht, entspricht dieser Prozess der Ausführung der Summe in einem Typ mit beliebiger Genauigkeit (also Sie ' d mach das). Angesichts der vereinfachten Wahl, in aufsteigender oder absteigender Größenordnung zu addieren, ist aufsteigend die bessere Wahl.
Es hat eine gewisse Beziehung zur realen Programmierung, da es einige Fälle gibt, in denen Ihre Berechnung sehr schlecht laufen kann, wenn Sie versehentlich einen "schweren" Schwanz abhacken, der aus einer großen Anzahl von Werten besteht, von denen jeder zu klein ist, um ihn einzeln zu beeinflussen die Summe, oder wenn Sie zu viel Präzision von vielen kleinen Werten wegwerfen, die einzeln nur die letzten Bits der Summe beeinflussen. In Fällen, in denen der Schwanz sowieso vernachlässigbar ist, ist es Ihnen wahrscheinlich egal. Zum Beispiel, wenn Sie zunächst nur eine kleine Anzahl von Werten addieren und nur einige signifikante Zahlen der Summe verwenden.