2012-04-03 11 views
7

Ich kam über ein seltsames Problem, möchte ich einige grundlegende mathematische Prüfungen zu tun. Ich habe gelesen, um floating Zahlen zu vermeiden, so entschied ich mich multiplizieren meine mathematischen Werte mit , weil mein Wert zwischen 0,9 und 0,0025 liegen kann.JavaScript Multiplizieren nicht präzise

Alles funktioniert korrekt mit Ausnahme von zwei Werten: 0,56 und 0,57:

var result = 0.57 * 10000 

Das Ergebnis ist: 5699,999999999999 ich für 5700 gehofft !! Und 0,56 geht auch schief, aber alle anderen Werte stimmen, was fehlt mir hier?

+4

[Was jeder Informatiker wissen sollte über Gleitkommaarithmetik] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –

+0

@JamesAllardice Den berühmten Goldberg Variationen! – kojiro

Antwort

3

Ihre Auswahlmöglichkeiten in Javascript (in der Tat in den meisten Sprachen) sind Ganzzahlen oder Fließkommazahlen. Wenn Sie "0.57" schreiben, zwingen Sie es in die Welt des Gleitkommas, wo die Genauigkeit begrenzt ist.

Wenn Sie absolute Genauigkeit wünschen, müssen Sie ausschließlich in Ganzzahlen arbeiten.

3
var result = 0.57 * 10000; 
alert (Math.round(result));​ 
0

Hacky Lösung: value.toFixed(4).substr(-4).replace(/^0+/, "");

11

Die beste Lösung toFixed (x) zu verwenden wäre, und x eine Anzahl von Dezimalstellen festlegen, die immer mehr als die erwarteten Ergebnisse Dezimalstellen sein sollten (ich in der Regel setzte 8 dort).

Aber anstatt zu hacken -als Kirilloid-, sollten Sie das Ergebnis wieder in Zahl konvertieren, so dass nicht benötigte Dezimalstellen entfernt werden. Führen Sie danach eine Formatierung durch, die Ihnen an der Nummer gefällt.

var result = +(0.57 * 10000).toFixed(8) 

Ergebnis wäre jetzt

The + vor, konvertiert die Zeichenfolge Ergebnis von "toFixed" auf eine Zahl wieder:

dies würde das benötigte Ergebnis So zurückzukehren.

Hoffe, dass geholfen hat!

0
var multiply = function(a, b) { 
    var commonMultiplier = 1000000; 

    a *= commonMultiplier; 
    b *= commonMultiplier; 

    return (a * b)/(commonMultiplier * commonMultiplier); 
}; 

Dies funktioniert in einem bekannten Bereich. Daher kann es sinnvoll sein, die Zahl auf einen Dezimalpunkt kleiner als commonMultiplier zu runden.

> multiply(3, .1) 
< 0.3 
> multiply(5, .03) 
< 0.15