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.

Managed Hosting mit mpex für maximale Sicherheit

Die Managed Hosting Lösungen unseres Partner mpex sorgen mit maximaler Sicherheit für beste Ergebnisse im Deployment und Betrieb von Neofonie und unser Kunden.

Core Web Vitals und deren Auswirkung auf die Webentwicklung

Mit der Einführung der Core Web Vitals Mitte Juni 2021 als zusätzliche Rankingfaktoren kommen auf die Webentwicklung neue Herausforderungen zu.

Geburtstagsverlosung bei ION ONE

ION ONE begeistert bereits seit einem Jahr seine Kunden. Feiern Sie das heutige Jubiläum mit und gewinnen Sie einen kostenfreien Workshop Ihrer Wahl.

Fussball_2021

Social Analytics zur UEFA EURO 2020

Wie wird über die spannendsten Ereignisse vor, während und nach den Spielen in den sozialen Netzwerken zur EURO 2020 gesprochen – eine Social Media Analyse von ontolux.

Sinnbild für Online Shopping

Warum eine goldstandard-basierte Evaluation?

Zur diesjährigen MICES trifft sich die E-Commerce-Suchgemeinschaft, um neueste Trends zu diskutieren. Mit dabei sind Cornelia Werk und Bertram Sändig von ontolux, die anhand von Kundenprojekten die Vorteile einer goldstandard-basierten Evaluation vorstellt.

amor_device_700

amor.de auf Shopware 6

Seit über 40 Jahren vertreibt Amor Echtschmuck und ist Europas Marktführer im mittleren Preissegment. Mit der Konzeption und Umsetzung des neuen Onlineshop hat der Schmuckhersteller Neofonie beauftragt.

DigitalHealthcare_Neofonie

Ausbau der Digitalisierung im Gesundheitswesen

Mit dem kürzlich beschlossenen Digitale-Versorgung-und-Pflege-Modernisierungsgesetz (DVPMG) verabschiedet der Bund bereits das dritte Gesetz, um die Digitalisierung im Gesundheitsmarkt voranzutreiben. Für die Vernetzung aller Beteiligten im Markt gestaltet Neofonie die Gesundheitstechnik von morgen aktiv mit und unterstützt Unternehmen, bei der Entwicklung von E-Health Lösungen.

Mit UX-Design die Customer Experience im Onlineshop beeinflussen

In der Videoreihe der media.net berlinbrandenburg zum Thema Customer Experience im E-Commerce, gibt Axel Hillebrand, UX Consultant von ION ONE, wertvolle Tipps, wie eine gute Usability und ein ausgefeiltes UX-Design Nutzer begeistert und so Ihre Conversion positiv beeinflusst.

Digitalen Wandel mit Managed IT-Services gestalten

Die stets an Komplexität gewinnenden Web- und E-Commerce-Projekte erfordern auf allen Ebenen ein Höchstmaß an Leistung, Sicherheit und Zuverlässigkeit. Bei diesen hohen Anforderungen wird Neofonie bereits seit 2004 durch das Berliner Hostingunternehmen mpex in allen Belangen des Betriebs unterstützt.

Digitales Recruiting – mit neuen Strategien gewappnet für die Zukunft

Celina Martin, HR-Managerin bei Neofonie Mobile war bei Digital Bash HR zu Gast und diskutierte mit HR-Experten zum Thema Digitales Recruiting in 2021 und gab Einblicke in HR-Strategien der Neofonie Mobile. Candidate Experience ist besonders wichtig im digitalen Wandel des Recruitings.

Container wird hochgehoben

Docker-Container als ideales Software-Transportmittel

Webprojekte werden immer komplexer und die Halbwertszeit der Technologien, die dabei zum Einsatz kommen, werden immer kürzer. Für die Softwareentwicklung ist die Containertechnologie von Docker ein ideales Transportmittel.

Corona-Reise-Check auf Shortlist für Deutschen Digital Award

In der Kategorie „Digital for Goods“ ist der Corona-Reise-Check des Wort & Bild Verlages für den Deutschen Digital Award 2021 nominiert. Der Bundesverband Digitale Wirtschaft e.V. hat in einer Shortlist die Vorauswahl getroffen.

Corona-Reise-Check-Preview

Neofonie entwickelt Corona Reise-Check App

Die Covid-19 Pandemie verursacht u.a. im Bereich Reisen große Verunsicherung. Die Corona-Reise-Check-App begegnet der Unsicherheit mit Transparenz.

EHealth_news

Neofonie weitet Fokus auf E-Health-Bereich aus

Als neues Verbandsmitglied der VerDiGes setzt die Berliner Digitalagentur Neofonie einen neuen unternehmerisch-strategischen Schwerpunkt im E-Health Umfeld und positioniert sich damit noch klarer als Full-Service Technologiedienstleister im Gesundheitsmarkt.

ION ONE: UX-Workshop für Food-Branche

Die UX-Agentur ION ONE unterstützt Unternehmen aus der Lebensmittelbranche mit einem kostenfreien UX-Workshop dabei, ihre Produkte authentisch und emotionalisierend zu inszenieren, um Nutzer zu begeistern und zum Kauf anzuregen.

Textmining_ontolux_NER

Neue Legal NER Komponente in TXTWerk

Mithilfe von Legal NER können juristische Textbausteine, beispielsweise Paragrafen, erkannt und automatisiert extrahiert werden. So lassen sich Texte in den Bereichen Steuern, Finanzen und Recht strukturieren und für die maschinelle Weiterverarbeitung aufbereiten.

Berliner Wirtschaft: Per Klick zum Onlinehändler

Die „Berliner Wirtschaft“ betrachtet die Berliner Agenturlandschaft unter dem Aspekt der gestiegene Nachfrage an E-Commerce Lösungen in der Corona-Krise. Thomas Kitlitschko, Geschäftsführer von Neofonie, liefert Einblicke.

ontolux Logo

Neofonie gründet KI-Agentur ontolux

Neofonie verkündet den Start einer neuen KI-Agentur, die sich den Themen Text Mining, Suche und Natural Language Processing verschrieben hat. Die langjährige Forschungs- und Projektkompetenz wird ab sofort in der eigenständigen Marke ontolux gebündelt.

wir-liefern-org Screen

wir-liefern.org erhält intelligente Suche

Neofonie unterstützt wir-liefern.org mit der kostenfreien Bereitstellung des Textanalyse Frameworks TXTWerk. Das Tool verbessert die Suche zur Auffindbarkeit lokaler Geschäfte.

WorldUsabilityDay_Newsbox

World Usability Day: Suche als echtes Erlebnis

Der World Usability Day vereint Design, Usability, IT und AI in einem Event und präsentiert am 12. November 2020 neueste Trends einem bundesweiten Publikum. Cornelia Werk von Neofonie stellt eine intelligente Suche als echtes Erlebnis vor.

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