Su instinto es básicamente correcto, ordenar en orden ascendente (de magnitud) generalmente mejora un poco las cosas. Considere el caso en el que estamos agregando flotadores de precisión simple (32 bits), y hay mil millones de valores iguales a 1 / (mil millones) y un valor igual a 1. Si el 1 es primero, entonces la suma vendrá a 1, ya que 1 + (1/1 billón) es 1 debido a la pérdida de precisión. Cada adición no tiene ningún efecto en el total.
Si los valores pequeños vienen primero, al menos sumarán algo, aunque incluso entonces tengo 2 ^ 30 de ellos, mientras que después de 2 ^ 25 más o menos estoy de vuelta en la situación en la que cada uno individualmente no afecta el total nunca más. Así que todavía voy a necesitar más trucos.
Ese es un caso extremo, pero en general, sumar dos valores de magnitud similar es más exacto que sumar dos valores de magnitudes muy diferentes, ya que "descarta" menos bits de precisión en el valor más pequeño de esa manera. Al ordenar los números, agrupa valores de magnitud similar y, al sumarlos en orden ascendente, le da a los valores pequeños una "posibilidad" de alcanzar acumulativamente la magnitud de los números más grandes.
Aún así, si se trata de números negativos, es fácil "burlar" este enfoque. Considere tres valores Resumiendo, {1, -1, 1 billionth}
. La suma aritméticamente correcta es 1 billionth
, pero si mi primera adición involucra el valor minúsculo, entonces mi suma final será 0. De los 6 órdenes posibles, solo 2 son "correctos" - {1, -1, 1 billionth}
y {-1, 1, 1 billionth}
. Los 6 órdenes dan resultados que son precisos en la escala del valor de mayor magnitud en la entrada (0,0000001% fuera), pero para 4 de ellos el resultado es inexacto en la escala de la solución verdadera (100% fuera). El problema particular que está resolviendo le dirá si el primero es lo suficientemente bueno o no.
De hecho, puede jugar muchos más trucos que simplemente agregarlos en orden ordenado. Si tiene muchos valores muy pequeños, un número medio de valores medios y un número pequeño de valores grandes, entonces podría ser más exacto sumar primero todos los pequeños, luego sumar los medianos por separado, sumar esos dos totales juntos luego agregue los grandes. No es en absoluto trivial encontrar la combinación más precisa de adiciones de punto flotante, pero para hacer frente a casos realmente malos, puede mantener un conjunto completo de totales acumulados en diferentes magnitudes, agregar cada nuevo valor al total que mejor coincida con su magnitud, y cuando un total acumulado comience a ser demasiado grande para su magnitud, agréguelo al siguiente total y comience uno nuevo. Llevado a su extremo lógico, este proceso es equivalente a realizar la suma en un tipo de precisión arbitraria (por lo que ' haría eso). Pero dada la opción simplista de sumar en orden de magnitud ascendente o descendente, ascender es la mejor apuesta.
Tiene alguna relación con la programación del mundo real, ya que hay algunos casos en los que su cálculo puede salir muy mal si accidentalmente corta una cola "pesada" que consiste en una gran cantidad de valores, cada uno de los cuales es demasiado pequeño para afectar individualmente la suma, o si descarta demasiada precisión de una gran cantidad de valores pequeños que individualmente solo afectan a los últimos bits de la suma. En los casos en que la cola es insignificante de todos modos, probablemente no le importe. Por ejemplo, si solo está sumando una pequeña cantidad de valores en primer lugar y solo está usando algunas cifras significativas de la suma.