Rundungsfehler in JavaScript

Rundungsfehler in JavaScript

In JavaScript existieren Zahlen im Datentyp Number, wodurch man bei Rechenoperationen auf Rundungsprobleme stößt. Karsten Rieger, ehemaliger Professional Frontend Developer bei Neofonie, erklärt das Phänomen und stellt Lösungsansätze vor.

Wer Rechenoperationen mit JavaScript ausführen will, wird früher oder später auf ungenaue Ergebnisse stoßen.

Schauen wir uns ein Beispiel genauer an:

var result = 0.1 + 0.2;

result === 0.3

// false !

// result == 0.30000000000000004

Um zu verstehen, warum das so ist, muss man wissen, wie Zahlen in JavaScript verwaltet werden.

Der Datentyp Number

In JavaScript existiert für Zahlen nur ein Datentyp: Number.

Number ist ein 64Bit Floatingpoint  Datentyp. Diese 64 Bit werden dabei entsprechend dem Standard IEEE 754 (bzw. double precision binary floating point format) so aufgeteilt, dass die Bits 0 bis 51 für die Mantisse (den eigentlichen Zahlenwert), die Bits 52 bis 62 für den Exponenten und das letzte Bit (63) für das Vorzeichen verwendet werden.
Jede Zahl wird also in einer binären Exponential-Repräsentation abgebildet. Für Ganzzahlwerte bedeutet dies, dass eine gesicherte Darstellung bis 15 Ziffern möglich ist, bevor Rundungsfehler bedingt durch die exponentielle Abbildung auftreten.

Integer sind bis 15 Stellen sicher

var x = 999999999999999;   // 999999999999999

var y = 9999999999999999;  // 10000000000000000

Bei Fließkommazahlen wirkt sich dies entsprechend auf die Genauigkeit der Nachkommastellen aus (s. erstes Beispiel).

JavaScript steht nicht allein da

Wer sich nun bestätigt darin fühlt, dass JavaScript eine total verkorkste Sprache sei und nicht einmal ordentlich rechnen kann, wird erstaunt sein, dass dieses Problem nicht allein auf JavaScript beschränkt ist. Alle Sprachen, welche Fließkommazahlen nach IEEE 754 implementieren, weisen entsprechende Rundungsfehler auf. Der Unterschied besteht lediglich in den diversen Sprachen sich unterscheidenden zusätzlichen Datentypen.

Wer es nicht glaubt, kann gerne einmal in groovy (bzw. Java) folgendes ausprobieren:

Rundungsproblem in Java/Groovy

println"0.1 + 0.2 = ${0.1 + 0.2}"// "0.1 + 0.2 = 0.3"

println"0.1f + 0.2f = ${0.1f + 0.2f}"// "0.1f + 0.2f = 0.30000000447034836"

println"0.1d + 0.2d = ${0.1d + 0.2d}"// "0.1d + 0.2d = 0.30000000000000004"

Daran lässt sich auch gut erkennen, dass Number dem Datentyp Double in Java entspricht.

Eine Anekdote am Rande

Wem das alles nun viel zu kompliziert erscheint, der ist an dieser Stelle sicher nicht alleine. Wichtig ist es zu wissen, dass Rundungsfehler aufgrund der Abbildung entstehen können.

Selbst ein so genialer Kopf wie Steve Wozniak hat es vermieden einen Floatingpoint Datentyp in Apples erstem Basic zu implementieren. Laut Wikipedia war Wozniak zu sehr mit der Entwicklung des Diskettenlaufwerks beschäftigt, weshalb Microsoft  beauftragt wurde ein Basic mit Fließkommazahlen zu entwickeln (später genannt Applesoft Basic).

Sicher hätte Wozniak die intellektuellen Kapazitäten dazu gehabt, das Problem zügig zu lösen. Witzig ist jedoch, dass es nie eine offizielle Begründung gab, warum Wozniak damals keine Fließkommazahlen in Apple Basic umgesetzt hat. Während eines Interviews bei All Things Digital (2007) sagt Jobs auf die Frage, warum Wozniak keine Fließkommazahlen in Apple Basic umsetzte, lediglich: „This is one of the mysteries of life“.

Wie vermeidet man Rundungsfehler?

Ist man gezwungen mit großen Zahlen innerhalb von JavaScript zu rechen und sucht etwas analoges zu Javas BigDecimal, sollte man sich vielleicht bignumber.js oder BigDecimal.js einmal anschauen.

Für den gewöhnlichen Gebrauch genügt es jedoch meist, sich auf drei bis vier Stellen nach dem Komma zu beschränken und die nativen Methoden numObj .toPrecisionStelligkeit ) oder numObj .toFixedNachkommastellen ) zu verwenden. Der Unterschied zwischen beiden ist, dass man bei toPrecision() die Gesamtanzahl der darzustellenden Ziffern (Vorkomma + Nachkomma) angibt, während man bei toFixed() die Anzahl der darzustellenden Nachkommastellen angibt.

var result = parseFloat((0.1+ 0.2).toPrecision(1));

result === 0.3

// true

Zu beachten sei noch, dass sowohl .toFixed() als auch .toPrecision() als Rückgabewert kein Numberobjekt sondern einen String liefern, weshalb in dem oberen Beispiel auch noch einmal ein parseFloat() nötig ist, um auch einem Typvergleich (===) standzuhalten.

Neben einer Berechnung wie zuvor gesehen, ist auch bei der Übertragung von Zahlen darauf zu achten, ob diese eventuell implizit zu Number konvertiert werden. So interpretiert beispielsweise jQuery.data() den im Data-Attribut des angefragten Elements enthaltenen Wert. Ist dieser ein Zahlen wert, wird dieser entsprechend als Number zurückgegeben. Dies ist solange kein Problem, wie der Wertebereich Double eingehalten wird. Oft werden jedoch IDs auf diese Weise übertragen, welche wiederum gerne Long Werte sind und daher auch eine Stelligkeit jenseits der gesicherten 15 Stellen erreichen können. Um eine implizite Umwandlung zu vermeiden, sollte man daher auf das Data-Attribut, welches einen Long-Wert enthält zur Sicherheit mit der Methode jQuery.attr() zugreifen, welche stets einen String zurückliefert.

Wer das Problem der Rundungsgenauigkeit beim Abbilden von Fließkommazahlen in eine binäre Exponentialdarstellung selber einmal im Code lösen möchte, kann sich ja einmal am folgenden Coding Kata versuchen: Codewars – Float to binary conversion (wenn beim ersten Pageload eine Fehlermeldung erscheint, einfach erneut ein Reload versuchen)

Der vollständige Artikel kann auf entwickler.de gelesen werden.

Veröffentlicht am 10. Dezember 2015, aktualisiert am 10. Oktober 2020

Teilen auf
Karsten Rieger

Karsten Rieger

Karsten Rieger ist ehemaliger Professional Frontend Developer bei Neofonie. Seit 2006 hat er diverse technische Abteilungen wie ASP, Forschung und Entwicklung sowie Projects bzw. Software Factories durchlaufen. Sein Interesse gilt dabei verstärkt der Frontend-Entwicklung. Als Teil des Client Teams entdeckt er bei der Umsetzung diverser Kundenprojekte, dass hinter Frontend-Entwicklung mehr als „nur ein bisschen HTML und CSS“ steckt.

Mittelstandskonferenz

Neofonie auf der BMBF-Mittelstandskonferenz in Berlin

Auf der BMBF-Mittelstandskonferenz stellt Neofonie mit ihrer KI-Agentur ontolux die beiden Forschungsprojekte „Tech2Text“ und „AI4SCM“ vor.

Neofonie auf der GTM-Conference in Berlin

Jan-Tilmann Seipp von Neofonie stellt gemeinsam mit David Harbecke (DFKI) und Felix Köhler (inpro) Ergebnisse vom kollaborativen Forschungsprojekt „Text2Tech“ vor.

Newsbox_contenful_SAP

Content Commerce mit SAP und Contentful

Die Composable Content Platform von Contentful steht jetzt auch als App für die SAP Commerce Cloud zur Verfügung. Als Contentful und SAP Partner unterstützt Neofonie Unternehmen, beide Systeme bestmöglich zu nutzen.

newsbox-Axel-digitale_leute

Search UX auf dem Digitale Leute Summit

Der Digitale Leute Summit ist Deutschlands führende Konferenz rund um die digitale Produktentwicklung. Axel Hillebrand von Neofonie stellt das Thema Search UX vor.

Arzt mit einem Mobiltelefon in den Händen

Herausforderungen für Innovatoren im komplexen E-Health-Markt

Der E-Health-Markt bietet viele Möglichkeiten für digitale Medizinprodukte, ist jedoch anspruchsvoll. Welche Herausforderungen gibt es für Unternehmen?

Portrait von Poppe Poppe

Wandern zwischen den Welten – von den USA nach Berlin

Es ist der Traum vieler Deutscher in die USA auszuwandern. Poppe wanderte nach Deutschland aus und ging nach Berlin. Ein Interview über ganz persönliche Erfahrungen.

Neofonie erhält Deep Tech Award 2023

Neofonie erhält Deep Tech Award 2023 in der Kategorie IT-Security von der Berliner Senatsverwaltung für Wirtschaft, Energie und Betriebe. Bei dem eingereichten Projekt kommt TXTWerk zur Anwendung.

EHealth_news

Zertifizierung nach ISO 13485 – Gesundheit braucht Qualität

Neofonie ist zertifiziert nach ISO 13485. Erfahren Sie, was die Zertifizierung nach der Norm beinhaltet und welche Vorteile sie bringt.

ontolux bei der Berlin Buzzwords 2023

Bei der Berlin Buzzwords stellen Qi Wu, Bertram Sändig von ontolux am 19.06.23 in ihrem Vortrag domänenspezifische Ontologien in der IT-Sicherheitsbranche im Bereich ML vor.

Carolin Meyer Senior Projektmanagerin steht vor einer Wand mit Bemalung, modern mit Robotern, Linien usw.

Women in Tech – Projektmanagement in der IT

Frauen im IT-Projektmanagement sind selten. Carolin Meyer, Senior Projektmanagerin bei Neofonie, beschreibt ihren Weg in die IT-Branche und ihren Berufsalltag.

Thomas_Interview

Qualitätssicherung im Healthcare Markt

Was Qualitätssicherung im Healthcare Markt für die Softwareentwicklung bedeutet, erklärt Thomas Kitlitschko, CEO der Digitalagentur Neofonie.

Neofonie_25th_adjustments_Header

Neofonie feiert 25 Jahre

Neofonie hat sich mit der ersten deutschen Internetsuchmaschine hin zur führenden Digitalagentur entwickelt, wie das aktuelle Internetagenturranking des BVDW zeigt.

Cert_ISO13485_neofonie

Neofonie ist ISO 13485 zertifiziert

Zur Erfüllung der neuen europäischen Standards (Medical Device Regulation) hat die Neofonie Gruppe ihr Qualitätsmanagement nach ISO 13485 zertifiziert.

ontolux bei der Minds Mastering Machines 2023

Auf der M3 Konferenz stellt Bertram Sändig von ontolux am 11.05.23 in seinem Vortrag domänenspezifische Ontologien in der IT-Sicherheitsbranche im Bereich ML vor.

typo3-1200_650px-onblack

Neofonie ist TYPO3 Gold Member

Neofonie baut die Zusammenarbeit mit der TYPO3-Association aus und zertifiziert sich als Gold Member.

AI4SCM untersucht Supply Chain Risiken

Das AI4SCM Forschungsprojekt hat zum Ziel, Methoden für die Beobachtung und Erkennung von Supply-Chain Risiken zu entwickeln.

Portrait von Marvin Krüger bei Neofonie GmbH

Arbeiten mit chronischer Erkrankung

Menschen mit chronischen Krankheiten können leistungsfähig im Job sein, es braucht individuelle Lösungen. Wir sprachen zum Thema mit Marvin Krüger.

Schwarzes Mikrofon

Neofonie im Digital Insurance Podcast

Digital Insurance Podcast: Wie Versicherer die interne Informationsflut bewältigen und von einer ausgefeilte Intranetsuche profitieren.

ChatGPT im Realitätscheck

ChatGPT ist ein Meilenstein in der KI-Entwicklung. Doch wie können Unternehmen die Technologie einsetzen? ontolux geht der Frage nach.

Testkonzepte im Software Testing einfach erklärt

Software Testing unterstützt Firmen, qualitativ hochwertige Software auf den Markt zu bringen. Was ein Testkonzept braucht, verrät Khayrat Glende von Neofonie.

Unser Newsletter „Neo Report“ vermittelt konkretes Praxiswissen, Trends und Know-how für Ihr digitales Business – quartalsweise und kompakt. Jetzt anmelden.