Signatur
Beschreibung
Math.sumPrecise() nimmt ein beliebiges Iterable (Array, Set, Generator …) von Zahlen entgegen und gibt deren Summe zurück. Anders als eine naive Schleife oder reduce((a, b) => a + b, 0) rundet die Methode nicht nach jeder einzelnen Addition, sondern berechnet die mathematisch exakte Summe der übergebenen Gleitkommawerte und rundet erst ganz am Ende einmal auf die nächste darstellbare Number.
Dadurch verschwinden typische Probleme der Gleitkomma-Arithmetik: Auslöschung (catastrophic cancellation) bei großen und kleinen Werten gemischt, Abhängigkeit des Ergebnisses von der Reihenfolge der Summanden und scheinbare Überläufe in Zwischenergebnissen. Das Ergebnis ist unabhängig von der Reihenfolge immer identisch.
Sinnvoll ist die Methode überall, wo viele Messwerte, Statistiken, Geldbeträge in Gleitkommadarstellung oder Werte sehr unterschiedlicher Größenordnung aufsummiert werden. Für exakte Dezimalrechnung (z. B. Cent-genaue Buchhaltung) ersetzt sie aber keine Ganzzahl- oder Dezimal-Arithmetik: 0.1 ist bereits als Eingabe nicht exakt darstellbar.
Die Methode ist strikt: Jedes Element muss vom Typ number sein. Es findet keine Typumwandlung statt – Strings, BigInt, null oder Objekte führen zu einem TypeError.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $numbers Pflicht | Iterable<number> | Ein Iterable (z. B. Array, Set, Generator), dessen Elemente alle vom Typ number sind. Kein Iterable oder ein Nicht-Zahl-Element löst einen TypeError aus. |
Rückgabewert
-0; enthält ein Element NaN oder kommen sowohl Infinity als auch -Infinity vor → NaN; übersteigt die exakte Summe den darstellbaren Bereich → ±Infinity.Beispiele
Vergleich mit naivem reduce()
const werte = [1e20, 0.1, -1e20];
const naiv = werte.reduce((a, b) => a + b, 0);
const praezise = Math.sumPrecise(werte);
console.log(naiv); // 0.1 geht durch Auslöschung verloren
console.log(praezise);
console.log([0.1, 0.2, 0.3].reduce((a, b) => a + b, 0));
console.log(Math.sumPrecise([0.1, 0.2, 0.3]));
Beliebige Iterables und Überlauf in Zwischenergebnissen
// Set und Generator funktionieren ebenso wie Arrays
console.log(Math.sumPrecise(new Set([1, 2, 3])));
function* messwerte() {
yield 1e308;
yield 1e308;
yield -1e308;
}
// Naive Summe läuft zwischendurch über
console.log([...messwerte()].reduce((a, b) => a + b, 0));
console.log(Math.sumPrecise(messwerte()));
Sonderfälle und Typprüfung
console.log(Math.sumPrecise([])); // leeres Iterable
console.log(Object.is(Math.sumPrecise([]), -0));
console.log(Math.sumPrecise([1, NaN, 2]));
console.log(Math.sumPrecise([Infinity, -Infinity]));
try {
Math.sumPrecise([1, "2", 3]); // keine Typumwandlung!
} catch (err) {
console.log(err.name);
}
Durchschnitt mit Feature-Erkennung und Fallback
const summe = (werte) =>
typeof Math.sumPrecise === "function"
? Math.sumPrecise(werte)
: [...werte].reduce((a, b) => a + b, 0); // ungenauer Fallback
const mittelwert = (werte) => {
const liste = [...werte];
return liste.length ? summe(liste) / liste.length : NaN;
};
const temperaturen = [21.4, 22.1, 20.9, 23.6];
console.log(mittelwert(temperaturen).toFixed(2));
// Wichtig · Fallstricke
- Browser-Unterstützung: Neu in ES2026; zunächst u. a. in Firefox 137+ verfügbar, in anderen Engines teils noch nicht. Vor der Nutzung per
typeof Math.sumPrecise === "function"prüfen oder ein Polyfill (z. B. auscore-js) einsetzen. - Keine Typumwandlung:
Math.sumPrecise(["1", "2"])wirft einenTypeError. Werte aus Formularen oder JSON-Strings vorher mitNumber()umwandeln. AuchBigIntwird abgelehnt. - Kein Rest-Parameter: Die Methode erwartet ein Iterable, nicht einzelne Argumente wie
Math.max().Math.sumPrecise(1, 2, 3)wirft einenTypeError, weil1nicht iterierbar ist. - Leere Eingabe ergibt
-0: Das ist für die Rechnung meist unerheblich, fällt aber beiObject.is()oder bei der Anzeige von1 / ergebnisauf. - Keine Dezimal-Genauigkeit:
Math.sumPrecise([0.1, 0.2])liefert weiterhin0.30000000000000004, da bereits die Eingabewerte binär gerundet sind. Für Geldbeträge besser in Cent als Ganzzahlen rechnen. - Performance: Der Algorithmus ist aufwändiger als eine einfache Addition. In extrem heißen Schleifen mit gutartigen Daten kann ein naives
reduce()schneller sein.