floating-point c# - Unterschied zwischen Dezimal, Float und Double in .NET?





decimal vs (16)


Ganze Zahlen sind, wie erwähnt, ganze Zahlen. Sie können den Punkt nicht speichern, z. B. .7, .42 und .007. Wenn Sie Zahlen speichern müssen, die keine ganzen Zahlen sind, benötigen Sie einen anderen Variablentyp. Sie können den Double-Typ oder den Float-Typ verwenden. Sie setzen diese Typen von Variablen auf genau die gleiche Weise: Anstatt das Wort int , geben Sie double oder float . So was:

float myFloat;
double myDouble;

( float ist die Abkürzung für "floating point" und bedeutet einfach eine Zahl mit einem Punkt am Ende.)

Der Unterschied zwischen den beiden liegt in der Größe der Zahlen, die sie halten können. Für float können Sie bis zu 7 Ziffern in Ihrer Nummer haben. Für double s können Sie bis zu 16 Ziffern haben. Um genau zu sein, hier ist die offizielle Größe:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

float ist eine 32-Bit-Nummer und double ist eine 64-Bit-Nummer.

Doppelklicken Sie auf Ihre neue Schaltfläche, um den Code zu erhalten. Fügen Sie Ihrem Schaltflächencode die folgenden drei Zeilen hinzu:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Halten Sie Ihr Programm an und kehren Sie zum Codierungsfenster zurück. Ändern Sie diese Zeile:

myDouble = 0.007;
myDouble = 12345678.1234567;

Führen Sie Ihr Programm aus und klicken Sie auf Ihren Doppelknopf. Das Nachrichtenfeld zeigt die Nummer korrekt an. Fügen Sie am Ende jedoch eine weitere Nummer hinzu, und C # wird erneut aufgerundet. Die Moral ist, wenn Sie Genauigkeit wollen, seien Sie vorsichtig beim Runden!

Was ist der Unterschied zwischen decimal , float und double in .NET?

Wann würde jemand eines davon benutzen?




Das Problem bei all diesen Typen ist, dass eine gewisse Ungenauigkeit besteht UND dass dieses Problem mit kleinen Dezimalzahlen auftreten kann, wie im folgenden Beispiel

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 einer 32 Bit Maschine enthält bLower TRUE !!!

Wenn ich Double durch Decimal ersetze, enthält bLower FALSE, was die gute Antwort ist.

Im doppelten Fall ist das Problem, dass fMean-fDelta = 1.09999999999, das niedriger ist als 1.1.

Vorsicht: Ich denke, dass das gleiche Problem für andere Zahlen sicherlich existieren kann, weil Dezimal nur ein Doppeltes mit höherer Präzision ist und die Genauigkeit immer ein Limit hat.

Tatsächlich entsprechen Double, Float und Decimal BINARY-Dezimalstellen in COBOL!

Es ist bedauerlich, dass andere in COBOL implementierte numerische Typen in .Net nicht existieren. Für diejenigen, die COBOL nicht kennen, gibt es in COBOL 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) 



float 7 Stellen der Genauigkeit

double hat etwa 15 Stellen Genauigkeit

decimal hat etwa 28 Stellen der Genauigkeit

Wenn Sie eine bessere Genauigkeit benötigen, verwenden Sie double statt float. In modernen CPUs haben beide Datentypen fast die gleiche Leistung. Der einzige Vorteil von Float ist, dass sie weniger Platz benötigen. Praktisch zählt nur, wenn Sie viele von ihnen haben.

Ich fand das interessant. Was jeder Informatiker über Gleitkommaarithmetik wissen sollte




In einfachen Worten:

  1. Die Variablentypen Dezimal, Double und Float unterscheiden sich in der Art, in der sie die Werte speichern.
  2. Präzision ist der Hauptunterschied (Beachten Sie, dass dies nicht der einzige Unterschied ist), wobei float ein Gleitkomma-Datentyp mit einfacher Genauigkeit (32 Bit), Double ein Gleitkomma-Datentyp mit doppelter Genauigkeit (64 Bit) und Dezimalzahl ein 128-Bit ist Gleitkommadatentyp.
  3. 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 hier mehr lesen, Float , Double und Decimal .




  1. Double und Float können bei der Kompilierung und Laufzeit durch eine Ganzzahl Null ohne Ausnahme geteilt werden.
  2. Dezimal kann nicht durch Ganzzahl Null geteilt werden. Die Erstellung wird immer fehlschlagen, wenn Sie das tun.



Präzision ist der Hauptunterschied.

Float - 7 Ziffern (32 Bit)

Double -15-16 Ziffern (64 Bit)

Decimal -28-29 signifikante Ziffern (128 Bit)

Dezimalzahlen haben eine viel höhere Genauigkeit und werden normalerweise in Finanzanwendungen verwendet, die ein hohes Maß an Genauigkeit erfordern. Dezimalstellen sind viel langsamer (bis zu 20x in manchen Tests) als ein Double / Float.

Dezimale und Floats / Doubles können nicht ohne eine Besetzung verglichen werden, während Floats und Doubles dies können. Dezimalzahlen ermöglichen auch die Codierung oder abschließende Nullen.

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

Ergebnis:

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333



Die Variablentypen Dezimal, Double und Float unterscheiden sich in der Art, in der sie die Werte speichern. Präzision ist der Hauptunterschied, bei dem Float ein Gleitkomma-Datentyp mit einfacher Genauigkeit (32 Bit), Double ein Gleitkomma-Datentyp mit doppelter Genauigkeit (64 Bit) und Dezimalzahl ein 128-Bit Gleitkomma-Datentyp ist.

Float - 32 Bit (7 Ziffern)

Double - 64 Bit (15-16 Ziffern)

Dezimal - 128 Bit (28-29 signifikante Stellen)

Der Hauptunterschied besteht darin, dass Floats und Doubles binäre Gleitkommatypen sind und ein Dezimalwert den Wert als Gleitkommaart speichert. Dezimale haben daher eine viel höhere Präzision und werden normalerweise in monetären (finanziellen) oder wissenschaftlichen Berechnungsanwendungen verwendet, die ein hohes Maß an Genauigkeit erfordern. In der Leistung sind Dezimalzahlen jedoch langsamer als Double- und Float-Typen.

Dezimal kann 100% genau jede Zahl innerhalb der Genauigkeit des Dezimalformats darstellen, während Float und Double, nicht alle Zahlen genau wiedergeben können, gerade Zahlen, die innerhalb ihrer jeweiligen Formatpräzision sind.

Dezimal

Im Fall von Finanzanwendungen oder wissenschaftlichen Berechnungen ist es besser, Dezimaltypen zu verwenden, da es Ihnen ein hohes Maß an Genauigkeit bietet und Rundungsfehler leicht zu vermeiden ist

Doppelt

Doppeltypen sind wahrscheinlich der am häufigsten verwendete Datentyp für reale Werte, außer Geld zu handhaben.

Schweben

Es wird hauptsächlich in Grafikbibliotheken verwendet, da sehr hohe Anforderungen an die Verarbeitungsleistung gestellt werden, sowie Situationen, in denen Rundungsfehler auftreten können.




float ~ ± 1,5 × 10-45 bis ± 3,4 × 1038 -------- 7 Ziffern
doppelt ~ ± 5,0 x 10-324 bis ± 1,7 x 10308 ------ 15 oder 16 Ziffern
dezimal ~ ± 1,0 x 10-28 bis ± 7,9 x 1028 -------- 28 oder 29 Ziffern




Das war ein interessanter Thread für mich, denn heute haben wir gerade einen kleinen Fehler gehabt, bei dem decimal weniger genau sind als ein float .

In unserem C # -Code lesen wir numerische Werte aus einer Excel-Tabelle, konvertieren sie in eine decimal und senden diese decimal dann an einen Service, um sie in einer SQL Server- Datenbank zu speichern.

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 unsere Excel-Werte funktionierte das wunderbar. Aber für einige, sehr kleine Excel-Werte, mit decimal.TryParse verlor den Wert vollständig. Ein solches Beispiel ist

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), out-Wert); // würde 0 zurückgeben

Bizarrerweise bestand die Lösung darin, die Excel-Werte zuerst in eine double und dann in eine decimal Zahl zu konvertieren:

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;
    …
}

Obwohl double weniger genau ist als eine decimal , würde dies tatsächlich sicherstellen, dass kleine Zahlen immer noch erkannt werden. Aus irgendeinem Grund konnte double.TryParse tatsächlich so kleine Zahlen decimal.TryParse , während decimal.TryParse sie auf Null decimal.TryParse würde.

Ungerade. Sehr komisch.




float und double sind floating binary point types . Mit anderen Worten, sie stellen eine Zahl wie folgt dar:

10001.10010110011

Die Binärzahl und der Ort des Binärpunkts sind beide innerhalb des Wertes codiert.

decimal ist ein Gleitkomma-Typ . Mit anderen Worten, sie stellen eine Zahl wie folgt dar:

12345.65789

Auch hier sind die Zahl und die Position des Dezimalpunkts beide innerhalb des Wertes codiert - das macht decimal immer noch zu einem Fließkommatyp anstelle eines Fixpunkttyps.

Es ist wichtig zu beachten, dass Menschen gewohnt sind, Nicht-Ganzzahlen in einer dezimalen Form darzustellen und exakte Ergebnisse in dezimalen Darstellungen zu erwarten; Nicht alle Dezimalzahlen sind im binären Fließkomma genau darstellbar - zum Beispiel 0.1 - wenn Sie also einen binären Gleitkommawert verwenden, erhalten Sie eine Annäherung an 0.1. Sie erhalten immer noch Näherungen, wenn Sie einen Gleitpunkt verwenden - das Ergebnis der Division von 1 durch 3 kann beispielsweise nicht genau dargestellt werden.

Was zu verwenden, wenn:

  • Für Werte, die "natürlich exakte Dezimalzahlen" sind, ist es gut, decimal zu verwenden. Dies ist normalerweise für alle Konzepte geeignet, die von Menschen erfunden wurden: finanzielle Werte sind das offensichtlichste Beispiel, aber es gibt auch andere. Berücksichtigen Sie beispielsweise die Punktzahl für Taucher oder Eisläufer.

  • Für Werte, die mehr Artefakte der Natur sind, die sowieso nicht wirklich genau gemessen werden können, sind float / double geeigneter. Zum Beispiel würden wissenschaftliche Daten normalerweise in dieser Form dargestellt. Hier sind die ursprünglichen Werte nicht von Anfang an "dezimal genau", daher ist es nicht wichtig, dass die erwarteten Ergebnisse die "Dezimalgenauigkeit" beibehalten. Fließende binäre Punkttypen arbeiten viel schneller als Dezimalstellen.




Für Anwendungen wie Spiele und eingebettete Systeme, bei denen Speicher und Leistung beide kritisch sind, ist Float normalerweise der numerische Typ der Wahl, da es schneller und halb so groß wie ein Double ist. Ganzzahlen waren früher die Waffe der Wahl, aber die Fließkomma-Leistung hat in modernen Prozessoren die Ganzzahl überholt. Dezimal ist richtig!




Die Dezimalstruktur ist strikt auf finanzmathematische Berechnungen ausgerichtet, die eine Rundungsgenauigkeit relativ intolerant sind. Für wissenschaftliche Anwendungen sind Dezimale jedoch aus mehreren Gründen nicht geeignet:

  • Ein gewisser Genauigkeitsverlust ist in vielen wissenschaftlichen Berechnungen aufgrund der praktischen Grenzen des zu messenden physikalischen Problems oder Artefakts akzeptabel. Genauigkeitsverlust ist im Finanzbereich nicht akzeptabel.
  • Dezimal ist für die meisten Operationen viel (viel) langsamer als float und double, hauptsächlich weil Fließkommaoperationen binär ausgeführt werden, während Dezimalkram in der Basis 10 erledigt wird (dh Floats und Doubles werden von der FPU-Hardware wie MMX / SSE gehandhabt) , während Dezimalstellen in Software berechnet werden).
  • Dezimal hat einen unannehmbar kleineren Wertebereich als doppelt, trotz der Tatsache, dass es mehr Stellen der Genauigkeit unterstützt. Daher kann Decimal nicht verwendet werden, um viele wissenschaftliche Werte zu repräsentieren.



Die Variablentypen Dezimal, Double und Float unterscheiden sich in der Art, in der sie die Werte speichern. Präzision ist der Hauptunterschied, bei dem Float ein Gleitkomma-Datentyp mit einfacher Genauigkeit (32 Bit), Double ein Gleitkomma-Datentyp mit doppelter Genauigkeit (64 Bit) und Dezimalzahl ein 128-Bit Gleitkomma-Datentyp ist.

Float - 32 Bit (7 Ziffern)

Double - 64 Bit (15-16 Ziffern)

Dezimal - 128 Bit (28-29 signifikante Stellen)

Mehr über ... den Unterschied zwischen Dezimal, Float und Double




Niemand hat das erwähnt

In den Standardeinstellungen verwenden Floats (System.Single) und Doubles (System.Double) niemals eine Überlaufprüfung, während Decimal (System.Decimal) immer die Überlaufprüfung verwendet.

ich meine

decimal myNumber = decimal.MaxValue;
myNumber += 1;

löst OverflowException aus .

Aber diese nicht:

float myNumber = float.MaxValue;
myNumber += 1;

&

double myNumber = double.MaxValue;
myNumber += 1;






Für Geld: decimal . Es kostet ein wenig mehr Speicher, hat aber keine Rundungsschwierigkeiten, wie es manchmal double Fall ist.





.net floating-point double decimal