2009-05-06 6 views
4

Ich schreibe Branchenanwendungen. Ich würde gerne ein Front-End-Ende mit Javascript bauen und versuche herauszufinden, wie man mit einem Floating-Point-Fehler umgehen kann (ich verstehe aus der Sicht der Informatik, dass sie nicht als Fehler betrachtet werden). Ich habe viel darüber gelesen und alle Arten von Rundungs-Hacks gesehen, die an gegebenen Beispielen arbeiten, aber dazu neigen, unerwartet zu versagen. Gibt es eine definitive Möglichkeit, dezimale Mathematik in Javascript zu tun?Gibt es eine endgültige Lösung für Fließkommafehler in Javascript?

+0

Ab Juni 2017 gibt es sieben verschiedene endgültige Lösungen – Ryan

Antwort

0

die einzige definitive Lösung scheint zu schreiben Ihre eigene arbitrary Nummer Zahl Typ arbeiten an Strings intern - was kompliziert und schrecklich langsam sein wird.

+0

+1 für kompliziert, aber langsam ist relativ: für einen Frontend auf moderne Hardware ist es wahrscheinlich im akzeptablen Bereich, wenn auch nicht gewährt so schnell wie ein natives Float. –

+0

Ich stimme Joel zu. Ich schrieb eine dezimale große Integer-Klasse, die, obwohl sie viel langsamer als native Zahlen ist (insbesondere Multiplizieren/Dividieren von großen Zahlen), auf jeden Fall schnell genug wäre, um Zahlen von vernünftiger Größe zu erhalten. –

6

Laut Douglas Crockford ist der einzige Weg um dieses Problem zu skalieren Ihre Werte auf Integer. Stellen Sie sicher, dass es sich um eine Ganzzahl handelt, indem Sie Math.round für den skalierten Wert verwenden. (DC spricht nicht über den Rundungsteil, aber ich entdeckte, dass es notwendig war. ZB Math.round(1.1 *100)) Berechnungen durchführen. Wenn Sie mit der mathematischen Skala zurück zur ursprünglichen Präzision fertig sind. Sehen Sie JavaScript: Die guten Teile "Fließender Punkt" Abschnitt

+2

Wenn ich Werte auf ganze Zahlen skaliere (d. H., Speichere alles in Cents), werde ich immer noch Fehler bekommen, wenn ich diese ganzen Zahlen teile? –

+1

Konvertieren Sie alle Werte in Cents. (Siehe oben über Math.round.) Führen Sie so viele Berechnungen durch, wie Sie möchten. Wenn Sie bereit sind, dem Benutzer die Antwort zu geben, konvertieren Sie zurück zu $, indem Sie durch 100 dividieren. Das sollte funktionieren. –

+0

Ich denke nicht, dass das Problem vollständig gelöst wird, Sie können immer noch mit Zwischenproblemen mit mehr als einer Kluft enden. Ich denke nicht, dass es viel besser ist, als alles normal zu machen und am Ende nur eine Runde zu machen. – Nosredna

1

Eine Antwort ist die Mathematik in Dezimal anstelle von Binär zu tun.Dann müssen Sie sich nie um die Dezimal < => binäre Konvertierungsfehler.Sie würden die Zahlen als Binärziffern in einem Array oder einer Zeichenfolge darstellen und schreiben Sie die Mathe-Routinen selbst.

Hier sind einige bignumber Bibliotheken, die Sie untersuchen können, wenn Sie nicht zu diesem Problem gehen möchten:

http://jsfromhell.com/classes/bignumber

http://stz-ida.de/html/oss/js_bigdecimal.html.en