Start · Sprachen · JavaScript · Referenz · Math.sumPrecise()

Math.sumPrecise()

Methode

Die statische Methode <code>Math.sumPrecise()</code> summiert ein Iterable von Zahlen ohne Genauigkeitsverlust durch Zwischenrundungen und gibt das korrekt gerundete Ergebnis zurück.

seit JavaScript ES2026 (TC39 Stufe 4) – Firefox 137+, weitere Brow Kategorie: method-property

Signatur

Math.sumPrecise(numbers)

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

Typ
number
Beschreibung
Die korrekt gerundete Summe aller Werte. Sonderfälle: leeres Iterable → -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]));
0 0.1 0.6000000000000001 0.6

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()));
6 Infinity 1e+308

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);
}
-0 true NaN NaN TypeError

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));
22.00

// 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. aus core-js) einsetzen.
  • Keine Typumwandlung: Math.sumPrecise(["1", "2"]) wirft einen TypeError. Werte aus Formularen oder JSON-Strings vorher mit Number() umwandeln. Auch BigInt wird abgelehnt.
  • Kein Rest-Parameter: Die Methode erwartet ein Iterable, nicht einzelne Argumente wie Math.max(). Math.sumPrecise(1, 2, 3) wirft einen TypeError, weil 1 nicht iterierbar ist.
  • Leere Eingabe ergibt -0: Das ist für die Rechnung meist unerheblich, fällt aber bei Object.is() oder bei der Anzeige von 1 / ergebnis auf.
  • Keine Dezimal-Genauigkeit: Math.sumPrecise([0.1, 0.2]) liefert weiterhin 0.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.