2012-03-26 19 views
1

Ich habe das folgende Codebeispiel:Konvertieren von float auf Dezimal, falsch Präzision zu verlieren

 float val = 16777216.0F; 
     var badResult = Convert.ToDecimal(val); 
     //badResult has value 16777220 

Warum diese Genauigkeit verloren geht? Der angegebene Wert ist 2^24, ein Wert, der float darstellen kann. Gibt es irgendwelche .net-Bibliotheken, die ich verwenden kann, um diese Konvertierung korrekt zu funktionieren, ohne meinen eigenen iCustomFormatter rollen zu müssen?

Danke!

bearbeiten, ist dies der hässliche Code, den ich als Lösung

var goodResult = Convert.ToDecimal(((double)val)); 
+2

Wenn Sie mit Mathematik arbeiten, verwenden Sie Floats/Doubles den ganzen Weg. Wenn Sie mit Währungen arbeiten, verwenden Sie die Dezimalstellen vollständig. Warum müssten Sie zwischen ihnen konvertieren? –

+0

siehe auch http://ideone.com/w1sTm –

+0

@graham. Ich arbeite leider mit Returncodes von Hardware. – greggorob64

Antwort

3

für System.Single Aus der Dokumentation verwendet:

enthält standardmäßig ein einzelner Wert nur 7 Dezimalstellen Präzision, obwohl maximal 9 Ziffern werden intern gepflegt.

Der angegebene Wert ist in der Tat korrekt zu 7 signifikanten Stellen. Während der genaue Wert des Floats in der Tat ist, die Sie angegeben haben, scheint es sinnvoll für die Umwandlung in String, nur die Anzahl der Ziffern, die bekannt sind, korrekt zu sein, mit der Endziffer möglicherweise gerundet.

+0

Nun, die temporäre Lösung, die ich gefunden habe, ist dies: var goodResult = Convert.ToDecimal (((Doppel) val)); Diese Umwandlung funktioniert, aber scheint, na ja, albern. Ich weiß Float ist nur für 7 Sig-Ziffern anwendbar, aber dieser Code gibt korrekte Werte zurück. Kann ich diesen Code rosten? – greggorob64

+0

@ greggorob64: Nun, ich würde nicht mit der Konvertierung zwischen 'float' /' double' und 'dezimal' anfangen, um ehrlich zu sein. Das ist fast * immer * ein Zeichen, dass du früher falsch gelaufen bist. Und obwohl ich verstehen kann, warum das in diesem speziellen Fall funktioniert, müssen Sie * sehr * genau wissen, was Sie in verschiedenen Fällen erreichen wollten, bevor ich Ihnen sagen würde, ob es das macht, was Sie wollen. Ich verstehe nicht, warum Sie * die achte signifikante Ziffer * wollen, wenn Sie wissen, dass sie nicht vertrauenswürdig ist. –

+0

Danke für die Eingabe. Ich habe einen Sensor, der einen Schwimmer (keine Kontrolle darüber) zurückgibt, und wir brauchen Werte bis zu 8 Ziffern, denn wenn die Nummer über 1mil ist, wird ein Fehlercode, vom Design, und 2^24 ausgelesen, es wird bei der Kalibrierung ausgegeben. Es war schlechtes Design, aber ich muss es in eine Dezimalzahl für zukünftige Speicherung bringen. – greggorob64

1

Die Umwandlung in Dezimal funktioniert einwandfrei; Das Problem ist, dass der float Typ (System.Single) diesen Wert nicht genau darstellen kann, also ist es eigentlich 1.677722E+07. Wenn Sie double (System.Double) verwenden, das eine höhere Genauigkeit hat, wird es wie erwartet funktionieren.