Ausgerechnet heute, am Feiertag (03. Oktober), hat doch in einem Projekt der Kunde ein böses Problem entdeckt… Die Applikation funktioniert nicht mehr! (zumindest ein ganz spezieller Fall) normal ;-)
In der entsprechenden Applikation (Webapplikation) werden im Frontend in Javascript einige Berechnungen durchgeführt (eher trivial, dafür allerdings ziemlich viel). Berechnungen in Javascript? Spart den Serverrroundtrip, der per AJAX notwendig wäre… Zur Kontrolle wird aber natürlich nochmal alles im Backend in Java mit BigDecimal nachgerechnet. …und da passen die Ergebnisse jetzt leider nicht zusammen. Die Applikation wirft einen Fehler und funktioniert nicht mehr.
Die Berechnung
function roundNumber(value, maxDecimalPlaces ) {
var e = Math.pow(10, maxDecimalPlaces);
return (Math.round(value * e) / e);
}
var x = 234.7;
var factor = 0.95;
var result = roundNumber( x * factor, 2 );
alert(result);
Das Ergebnis ist 222,96
Eigentlich hätte man aber ein leicht anderes Ergebnis erwartet… sauber gerechnet ist x*factor=222,965. Kaufmännische gerundet sollte das Ergebnis 222,97 sein.
Das Problem liegt natürlich an Fließkommazahlen und deren Rundungsfehler. Vergisst man nur mal schnell wenn man ein "bischen" in JavaScript hackt.
Das Ergebnis in Javascript für x * factor:
234.7 * 0.95 = 222.96499999999997
Und somit wird hier natürlich anschließend auch falsch gerundet.
Abhilfe schafft eine modifizierte round Methode:
function roundNumber(value, maxDecimalPlaces ) {
var e = Math.pow(10, maxDecimalPlaces);
//fliesskommaaritmetic
value = value + 0.0000000000001;
value = (Math.round(value * e) / e);
return value;
}
Keine Kommentare:
Kommentar veröffentlichen