Wenn Sie etwas programmieren, haben Sie möglicherweise gehört, dass "Gleitkommazahlen einen Fehler haben".
Aber ist dir das immer bewusst? Ich war mir dessen nicht bewusst und ging es durch.
Eines Tages musste das Einzahlungsguthaben des Benutzers auf 0,5% Zinsen abgerundet werden. Ich habe diesen Code geschrieben, weil ich dachte, es sei eine einfache Berechnung.
JavaScript
Math.floor(value * 1.005)
…… ** Das ist ein Fehler. ** **.
Lassen Sie uns versuchen, "1000" in "Wert" zu setzen. Ich habe das Gefühl, 0,5% zu 1000 zu addieren, ergibt 1005, aber in Wirklichkeit wird es 1004. Das obige Beispiel ist JavaScript, aber in den meisten wichtigen Sprachen ist das Ergebnis dasselbe. Probieren wir es aus.
Warum passiert das? Wenn Sie versuchen, "1000 * 1.005" so wie es ist auszugeben, wird es "1004.9999999999999" sein. Dieser Wert hat gerade nicht 1005 erreicht. Wenn Sie ihn also abschneiden, ist er 1004. Gleitkommazahlen können 1,005 nicht genau darstellen, daher scheint ein Fehler aufgetreten zu sein.
Dieser Fehler kann sehr leicht auftreten. Alle folgenden Beispiele führen nicht zu den erwarteten Ergebnissen.
JavaScript
Math.floor(0.6 / 0.2) // 2
0.6 / 0.2 // 2.9999999999999996
JavaScript
//Verbrauchssteuer auf die nächste ganze Zahl aufgerundet
Math.ceil(900 * 1.08) // 973
900 * 1.08 // 972.0000000000001
JavaScript
let f = 0;
for (let i = 0; i < 10; i++) {
f += 0.1;
}
Math.floor(f) // 0
f // 0.9999999999999999
Es ist besser zu glauben, dass das Berechnungsergebnis einer Gleitkommazahl keine Ganzzahl ist.
Sie können dieses Problem vermeiden, indem Sie die Ergebnisse vor dem Runden auf eine ausreichend niedrige Ziffer runden.
JavaScript
//Auf die 4. Stelle gerundet
Math.floor((value * 1.005).toFixed(3))
Java
Math.floor(String.format("%.3f", value * 1.005))
PHP
floor(round($value * 1.005, 3))
Es ist möglicherweise nicht für Situationen geeignet, in denen strenge Berechnungen erforderlich sind, aber für die meisten Anwendungen sollte dies ausreichend sein. Möglicherweise möchten Sie die Math-Klasse so erweitern, dass sie von der gesamten Anwendung aus aufgerufen werden kann.
Ich habe einen Kommentar erhalten. Mit dem Dezimaltyp ist es möglich, fehlerfreie Berechnungen ohne seltsame Implementierung durchzuführen. BigDecimal-Klassen können standardmäßig in Java verwendet werden, und JavaScript verfügt auch über eine Bibliothek mit dem Namen decimal.js. Es ist besser, so etwas zu verwenden, als es selbst zu implementieren. (Ergänzung bisher)
Seien Sie vorsichtig bei der Berechnung von Brüchen.
Recommended Posts