Votre instinct a fondamentalement raison, le tri par ordre croissant (de grandeur) améliore généralement quelque peu les choses. Prenons le cas où nous ajoutons des flottants à simple précision (32 bits), et il y a 1 milliard de valeurs égales à 1 / (1 milliard), et une valeur égale à 1. Si le 1 vient en premier, alors la somme viendra à 1, car 1 + (1/1 milliard) est égal à 1 en raison d'une perte de précision. Chaque ajout n'a aucun effet sur le total.
Si les petites valeurs viennent en premier, elles totaliseront au moins quelque chose, même si même dans ce cas j'en ai 2 ^ 30, alors qu'après 2 ^ 25 environ, je suis de retour dans la situation où chacune individuellement n'affecte pas le total plus. Je vais donc encore avoir besoin de plus de trucs.
C'est un cas extrême, mais en général, l'ajout de deux valeurs d'amplitude similaire est plus précis que l'ajout de deux valeurs d'amplitudes très différentes, car vous «rejetez» moins de bits de précision dans la valeur la plus petite de cette façon. En triant les nombres, vous regroupez des valeurs de grandeur similaire et en les additionnant par ordre croissant, vous donnez aux petites valeurs une "chance" d'atteindre cumulativement la grandeur des plus grands nombres.
Pourtant, si des nombres négatifs sont impliqués, il est facile de «déjouer» cette approche. Tenez compte trois valeurs à somme, {1, -1, 1 billionth}
. La somme arithmétiquement correcte est 1 billionth
, mais si mon premier ajout implique la valeur minuscule, ma somme finale sera 0. Sur les 6 ordres possibles, seuls 2 sont "corrects" - {1, -1, 1 billionth}
et{-1, 1, 1 billionth}
. Tous les 6 ordres donnent des résultats qui sont précis à l'échelle de la valeur de plus grande magnitude de l'entrée (0,0000001% en sortie), mais pour 4 d'entre eux, le résultat est inexact à l'échelle de la vraie solution (100% en sortie). Le problème particulier que vous résolvez vous dira si le premier est assez bon ou non.
En fait, vous pouvez jouer beaucoup plus de tours que de simplement les ajouter dans un ordre trié. Si vous avez beaucoup de très petites valeurs, un nombre moyen de valeurs moyennes et un petit nombre de grandes valeurs, alors il peut être plus précis d'additionner d'abord toutes les petites, puis additionner séparément les moyennes, additionner ces deux totaux puis ajoutez les gros. Il n'est pas du tout trivial de trouver la combinaison la plus précise d'ajouts en virgule flottante, mais pour faire face à de très mauvais cas, vous pouvez conserver tout un tableau de totaux cumulés à différentes magnitudes, ajouter chaque nouvelle valeur au total qui correspond le mieux à son ampleur, et lorsqu'un total cumulé commence à devenir trop grand pour son ampleur, ajoutez-le au total suivant et commencez-en un nouveau. Pris à son extrême logique, ce processus équivaut à effectuer la somme dans un type à précision arbitraire (donc vous d faire ça). Mais étant donné le choix simpliste de l'addition par ordre de grandeur croissant ou décroissant, le meilleur pari est de monter.
Il a une certaine relation avec la programmation du monde réel, car il y a des cas où votre calcul peut aller très mal si vous coupez accidentellement une queue "lourde" composée d'un grand nombre de valeurs dont chacune est trop petite pour être affectée individuellement la somme, ou si vous jetez trop de précision à un grand nombre de petites valeurs qui n'affectent individuellement que les derniers bits de la somme. Dans les cas où la queue est négligeable de toute façon, vous ne vous en souciez probablement pas. Par exemple, si vous additionnez seulement un petit nombre de valeurs au départ et que vous n'utilisez que quelques chiffres significatifs de la somme.