C # Convert.ToDouble () verliert Dezimalpunkte, wenn die Zeichenfolge in Double konvertiert wird

8

Nehmen wir an, wir haben den folgenden einfachen Code

%Vor%

nach dieser Umwandlung numberAsDouble Variable hat den Wert 93389.43. Was kann ich tun, damit diese Variable die volle Zahl behält, ohne sie zu runden? Ich habe festgestellt, dass Convert.ToDecimal sich nicht auf die gleiche Weise verhält, aber ich muss den Wert als double haben.

------------------- kleines Update ---------------------

Das Einfügen eines Haltepunkts in Zeile 2 des obigen Codes zeigt, dass die Variable numberAsDouble den gerundeten Wert 93389.43 hat, bevor sie in der Konsole angezeigt wird.

    
Giorgos Manoltzas 15.01.2013, 17:45
quelle

7 Antworten

10

93389.429999999993 kann nicht genau als 64-Bit Gleitkommazahl dargestellt werden. A double kann nur 15 oder 16 Ziffern enthalten, während Sie 17 Ziffern haben. Wenn Sie diese Genauigkeitsstufe benötigen, verwenden Sie stattdessen decimal .

(Ich weiß, Sie sagen, Sie brauchen es als Doppel, aber wenn Sie erklären könnten, warum, gibt es alternative Lösungen)

    
D Stanley 15.01.2013, 17:51
quelle
6

Dies ist das erwartete Verhalten.

Ein Double kann nicht jede Zahl genau darstellen. Das hat nichts mit der String-Konvertierung zu tun.

Sie können es selbst überprüfen:

%Vor%

Dies wird 93389.43 ausgeben.

Folgendes zeigt dies auch:

%Vor%

Dies druckt True .

    
Daniel Hilgarth 15.01.2013 17:47
quelle
4

Beachten Sie, dass hier zwei Konvertierungen stattfinden. Zuerst konvertierst du die Zeichenkette in eine doppelte und dann konvertierst du diese doppelt zurück in eine Zeichenkette, um sie anzuzeigen.

Sie müssen auch berücksichtigen, dass eine double keine unendliche Genauigkeit hat; Abhängig von der Zeichenkette können einige Daten verloren gehen, da ein Double nicht die Kapazität hat, sie zu speichern.

Bei der Konvertierung in ein Double wird es nicht mehr "round", als es sein muss. Es wird das Doppelte erzeugen, das der gegebenen Zahl am nächsten kommt, wenn man die Fähigkeiten eines Doppels berücksichtigt. Bei der Umwandlung dieses Double in einen String ist es viel wahrscheinlicher, dass einige Informationen nicht gespeichert werden.

    
Servy 15.01.2013 17:48
quelle
3

Siehe Folgendes (insbesondere der erste Teil von Michael Borgwardts Antwort):

dezimal vs. double! - Welchen sollte ich verwenden und wann?

Ein Double wird nicht immer die Genauigkeit beibehalten, abhängig von der Zahl, die Sie konvertieren möchten

Wenn Sie genau sein müssen, müssen Sie decimal

verwenden     
NinjaNye 15.01.2013 17:50
quelle
0

Dies ist eine Grenze für die Genauigkeit, die ein double speichern kann. Sie können dies selbst sehen, indem Sie versuchen, stattdessen 3389.429999999993 zu konvertieren.

    
Bobson 15.01.2013 17:50
quelle
0

Der double -Typ hat eine endliche Genauigkeit von 64 Bits, daher tritt ein Rundungsfehler auf, wenn die reelle Zahl in der numberAsDouble-Variable gespeichert wird.

Eine Lösung, die für Ihr Beispiel funktioniert, ist die Verwendung des Typs decimal mit einer Genauigkeit von 128 Bit. Das gleiche Problem tritt jedoch mit einem kleineren Unterschied auf.

Bei beliebig großen Zahlen unterstützt das Objekt System.Numerics.BigInteger von .NET Framework 4.0 eine beliebige Genauigkeit für Ganzzahlen. Sie benötigen jedoch eine Bibliothek von Drittanbietern, um beliebig große reelle Zahlen zu verwenden.

    
J-Mik 15.01.2013 18:04
quelle
0

Sie können die Dezimalstellen auf die Anzahl der benötigten Ziffern reduzieren, die doppelte Genauigkeit nicht überschreiten.

Dies wird zum Beispiel auf 5 Dezimalstellen gekürzt, wobei 93389.42999 erhalten wird. Ersetzen Sie einfach 100000 für den benötigten Wert

%Vor%     
Esteban Elverdin 15.01.2013 18:07
quelle

Tags und Links