Was ist der Unterschied zwischen decimal
, float
y double
in .NET?
Wann würde jemand so ein Gerät benutzen?
Was ist der Unterschied zwischen decimal
, float
y double
in .NET?
Wann würde jemand so ein Gerät benutzen?
Dies ist ein interessantes Thema für mich, denn heute hatten wir gerade einen bösen kleinen Fehler, der decimal
mit einer geringeren Genauigkeit als ein float
.
In unserem C#-Code lesen wir numerische Werte aus einem Excel-Tabellenblatt und wandeln sie in eine decimal
und sendet dann Folgendes decimal
zurück zu einem Dienst zum Speichern in einer SQLサーバー Datenbank.
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
decimal value = 0;
Decimal.TryParse(cellValue.ToString(), out value);
}
Nun, für fast alle unserer Excel-Werte, hat das wunderbar funktioniert. Aber für einige, sehr kleine Excel-Werte, mit decimal.TryParse
den Wert vollständig verloren. Ein solches Beispiel ist
cellValue = 0.00006317592
Decimal.TryParse(cellValue.ToString(), out value); // würde zurückkehren 0
Die Lösung bestand seltsamerweise darin, die Excel-Werte in eine double
und dann in eine decimal
:
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
double valueDouble = 0;
double.TryParse(cellValue.ToString(), out valueDouble);
decimal value = (decimal) valueDouble;
…
}
Auch wenn double
hat weniger Präzision als eine decimal
Dadurch wurde sichergestellt, dass auch kleine Zahlen noch anerkannt werden. Aus irgendeinem Grund, double.TryParse
tatsächlich in der Lage war, solche kleinen Zahlen abzurufen, während decimal.TryParse
würde sie auf Null setzen.
Seltsam. Sehr seltsam.
Nur aus Neugierde: Was war der Rohwert von cellValue.ToString()? Decimal.TryParse("0.00006317592", out val) scheint zu funktionieren...
-Verstehen Sie mich nicht falsch, wenn es wahr ist, ist es sehr interessant, aber das ist eine andere Frage, es ist sicherlich keine Antwort auf diese Frage.
Vielleicht, weil die Excel-Zelle ein Double zurückgab und der ToString()-Wert "6.31759E-05" war, weshalb decimal.Parse() die Schreibweise nicht mochte. Ich wette, wenn Sie den Rückgabewert von Decimal.TryParse() überprüft hätten, wäre er falsch gewesen.
Die Variablentypen Decimal, Double und Float unterscheiden sich in der Art und Weise, wie sie die Werte speichern. Der Hauptunterschied liegt in der Präzision: Float ist ein Gleitkommadatentyp mit einfacher Präzision (32 Bit), Double ist ein Gleitkommadatentyp mit doppelter Präzision (64 Bit) und Decimal ist ein Gleitkommadatentyp mit 128 Bit.
Fließkomma - 32 Bit (7 Ziffern)
Double - 64 Bit (15-16 Ziffern)
Dezimal - 128 Bit (28-29 signifikante Ziffern)
Mehr über... den Unterschied zwischen Decimal, Float und Double
Für Anwendungen wie Spiele und eingebettete Systeme, bei denen sowohl der Speicher als auch die Leistung entscheidend sind, ist Float in der Regel der numerische Typ der Wahl, da er schneller ist und die Hälfte der Größe eines Double hat. Integer war früher die Waffe der Wahl, aber die Fließkommaleistung hat Integer in modernen Prozessoren überholt. Dezimal ist völlig out!
So gut wie alle modernen Systeme, sogar Mobiltelefone, haben Hardware-Unterstützung für Double; und wenn Ihr Spiel auch nur einfache Physik enthält, werden Sie einen großen Unterschied zwischen Double und Float feststellen. (Zum Beispiel bei der Berechnung der Geschwindigkeit / Reibung in einem einfachen Asteroids-Klon, erlauben Doubles die Beschleunigung viel flüssiger als Float zu fließen. -- Es scheint, als ob es keine Rolle spielen sollte, aber das tut es wirklich).
Das Problem bei all diesen Typen ist, dass eine gewisse Ungenauigkeit vorhanden ist UND dass dieses Problem bei kleinen Dezimalzahlen wie im folgenden Beispiel auftreten kann
Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1
If fMean - fDelta < fLimit Then
bLower = True
Else
bLower = False
End If
Frage: Welchen Wert enthält die Variable bLower?
Antwort: Auf einem 32-Bit-Rechner enthält bLower TRUE !!!
Wenn ich Double durch Decimal ersetze, enthält bLower FALSE, was die richtige Antwort ist.
Bei Double besteht das Problem darin, dass fMean-fDelta = 1,09999999999 und damit niedriger als 1,1 ist.
Vorsicht! Ich denke, dass dasselbe Problem auch bei anderen Zahlen auftreten kann, denn Decimal ist nur ein Double mit höherer Genauigkeit und die Genauigkeit hat immer eine Grenze.
In der Tat entsprechen Double, Float und Decimal in COBOL BINARY decimal!
Es ist bedauerlich, dass andere numerische Typen, die in COBOL implementiert sind, in .Net nicht existieren. Für diejenigen, die COBOL nicht kennen, gibt es in COBOL den folgenden numerischen Typ
BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte)
Mit einfachen Worten:
Die Übersichtstabelle:
/========================================================================================== Type Bits Have up to Approximate Range /========================================================================================== float 32 7 digits -3.4 × 10 ^ (38) to +3.4 × 10 ^ (38) double 64 15-16 digits ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308) decimal 128 28-29 significant digits ±7.9 x 10 ^ (28) or (1 to 10 ^ (28) /==========================================================================================
Sie können mehr lesen aquí , Schwimmer , Doppelter et Dezimal .
Was fügt diese Antwort hinzu, was nicht bereits in den vorhandenen Antworten enthalten ist? Übrigens ist Ihr "oder" in der "Dezimal"-Zeile falsch: Der Schrägstrich in der Webseite, von der Sie kopieren, steht für Division und nicht für eine Alternative.
Und ich würde stark bestreiten, dass die Präzision der Hauptunterschied ist. Der Hauptunterschied ist die Basis: dezimale Fließkommazahlen gegenüber binären Fließkommazahlen. Dieser Unterschied ist es, der Decimal
für Finanzanwendungen geeignet, und es ist das Hauptkriterium bei der Entscheidung zwischen Decimal
y Double
. Es ist selten, dass Double
Präzision ist beispielsweise für wissenschaftliche Anwendungen nicht ausreichend (und Decimal
ist oft Ungeeignet für wissenschaftliche Anwendungen wegen seiner begrenzten Reichweite).
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
3 Stimmen
Interessanter Artikel zetcode.com/lang/csharp/datatypes
0 Stimmen
Verwandt: sandbox.mc.edu/~bennet/cs110/flt/dtof.html
8 Stimmen
Sie können Decimal nicht für die Interoperabilität mit nativem Code verwenden, da es sich um eine .net-spezifische Implementierung handelt, während Float- und Double-Zahlen von CPUs direkt verarbeitet werden können.