832 Stimmen

Wie geht man mit der Genauigkeit von Fließkommazahlen in JavaScript um?

Ich habe das folgende Dummy-Testskript:

function test() {
  var x = 0.1 * 0.2;
  document.write(x);
}
test();

So wird das Ergebnis gedruckt 0.020000000000000004 während es einfach drucken sollte 0.02 (wenn Sie Ihren Taschenrechner benutzen). Soweit ich verstanden habe, ist dies auf Fehler in der Genauigkeit der Fließkommamultiplikation zurückzuführen.

Hat jemand eine gute Lösung, damit ich in einem solchen Fall das richtige Ergebnis erhalte? 0.02 ? Ich weiß, es gibt Funktionen wie toFixed oder Rundung wäre eine weitere Möglichkeit, aber ich möchte wirklich die ganze Zahl ohne Kürzung und Rundung gedruckt haben. Ich wollte nur wissen, ob jemand von Ihnen eine schöne, elegante Lösung hat.

Natürlich werde ich sonst auf 10 Stellen oder so aufrunden.

157 Stimmen

Eigentlich liegt der Fehler daran, dass es keine Möglichkeit gibt, die 0.1 in eine endliche binäre Gleitkommazahl.

19 Stimmen

Die meisten Brüche lassen sich nicht mit exakter Genauigkeit in eine Dezimalzahl umwandeln. Eine gute Erklärung finden Sie hier: docs.python.org/release/2.5.1/tut/node16.html

8 Stimmen

3voto

Harish.bazee Punkte 620

Verwenden Sie Number(1.234443).toFixed(2); es wird 1.23 gedruckt

function test(){
    var x = 0.1 * 0.2;
    document.write(Number(x).toFixed(2));
}
test();

3voto

Ashish Singhal Punkte 395

enter image description here

    You can use library https://github.com/MikeMcl/decimal.js/. 
    it will   help  lot to give proper solution. 
    javascript console output 95 *722228.630 /100 = 686117.1984999999
    decimal library implementation 
    var firstNumber = new Decimal(95);
    var secondNumber = new Decimal(722228.630);
    var thirdNumber = new Decimal(100);
    var partialOutput = firstNumber.times(secondNumber);
    console.log(partialOutput);
    var output = new Decimal(partialOutput).div(thirdNumber);
    alert(output.valueOf());
    console.log(output.valueOf())== 686117.1985

3voto

DavidTaubmann Punkte 3015

Vermeiden Sie den Umgang mit Fließkommazahlen während der Operation mit Integers

Wie in der bisher meistgewählten Antwort angegeben, können Sie Arbeit mit ganzen Zahlen Das würde bedeuten, dass Sie für jede Dezimalstelle, mit der Sie arbeiten, alle Faktoren mit 10 multiplizieren und das Ergebnis durch dieselbe Zahl dividieren.

Wenn Sie zum Beispiel mit 2 Dezimalzahlen arbeiten, multiplizieren Sie alle Faktoren mit 100, bevor Sie die Operation durchführen, und teilen dann das Ergebnis durch 100.

Hier ein Beispiel: Ergebnis1 ist das übliche Ergebnis, Ergebnis2 ist die Lösung:

var Factor1="1110.7";
var Factor2="2220.2";
var Result1=Number(Factor1)+Number(Factor2);
var Result2=((Number(Factor1)*100)+(Number(Factor2)*100))/100;
var Result3=(Number(parseFloat(Number(Factor1))+parseFloat(Number(Factor2))).toPrecision(2));
document.write("Result1: "+Result1+"<br>Result2: "+Result2+"<br>Result3: "+Result3);

Das dritte Ergebnis soll zeigen, was passiert, wenn stattdessen parseFloat verwendet wird, was in unserem Fall zu einem Konflikt führte.

3voto

Mr_NAIF Punkte 52

Meine Antwort könnte zu spät kommen, aber hier ist meine Lösung:

function float(equation, precision = 9) {
    return Math.floor(equation * (10 ** precision)) / (10 ** precision);
}

console.log(float(0.1 * 0.2)); // => 0.02
console.log(float(0.2 + 0.4)); // => 0.6
console.log(float(1 / 3));     // => 0.333333333
console.log(float(1 / 3, 2));  // => 0.33

3voto

skalee Punkte 11472

Sie haben Recht, der Grund dafür ist die begrenzte Genauigkeit von Gleitkommazahlen. Speichern Sie Ihre rationalen Zahlen als Division zweier ganzer Zahlen, und in den meisten Situationen können Sie die Zahlen ohne Präzisionsverlust speichern. Wenn Sie das Ergebnis ausdrucken wollen, sollten Sie es als Bruch ausgeben. Mit der von mir vorgeschlagenen Darstellung wird dies trivial.

Bei irrationalen Zahlen hilft das natürlich nicht viel. Aber vielleicht möchten Sie Ihre Berechnungen so optimieren, dass sie die wenigsten Probleme verursachen (z. B. das Erkennen von Situationen wie sqrt(3)^2) .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X