it-swarm.com.de

Unterschied zwischen dezimal, float und double in .NET?

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

Wann würde jemand eines davon benutzen?

1970
Tom

float und double sind Gleitkomma-Typen . Mit anderen Worten, sie repräsentieren eine Zahl wie diese:

10001.10010110011

Die Binärzahl und die Position des Binärpunkts werden beide innerhalb des Werts codiert.

decimal ist ein Gleitkomma . Mit anderen Worten, sie repräsentieren eine Zahl wie diese:

12345.65789

Auch hier werden die Zahl und die Position des Dezimalpunkts innerhalb des Werts codiert - das macht decimal weiterhin zu einem Gleitkommatyp anstelle eines Festkommatyps.

Das Wichtige ist, dass Menschen es gewohnt sind, Nicht-Ganzzahlen in einer Dezimalform darzustellen und genaue Ergebnisse in Dezimaldarstellungen zu erwarten. Nicht alle Dezimalzahlen sind in binären Fließkommazahlen exakt darstellbar (z. B. 0,1). Wenn Sie also einen binären Fließkommazahlenwert verwenden, erhalten Sie eine Annäherung an 0,1. Auch bei Verwendung eines Gleitkommas erhalten Sie weiterhin Annäherungen - das Ergebnis der Division von 1 durch 3 kann beispielsweise nicht genau dargestellt werden.

Was ist zu verwenden, wenn:

  • Für Werte, die "von Natur aus exakte Dezimalstellen" sind, empfiehlt es sich, decimal zu verwenden. Dies ist normalerweise für alle von Menschen erfundenen Konzepte geeignet: Finanzielle Werte sind das offensichtlichste Beispiel, aber es gibt auch andere. Betrachten Sie zum Beispiel die Punktzahl für Taucher oder Eisläufer.

  • Für Werte, bei denen es sich eher um Artefakte der Natur handelt, die sich ohnehin nicht genau messen lassen , ist float/double geeigneter. Beispielsweise würden wissenschaftliche Daten normalerweise in dieser Form dargestellt. In diesem Fall sind die ursprünglichen Werte zunächst nicht "dezimal genau", sodass es für die erwarteten Ergebnisse nicht wichtig ist, die "Dezimalgenauigkeit" beizubehalten. Gleitkomma-Typen lassen sich viel schneller verarbeiten als Dezimalzahlen.

2150
Jon Skeet

Präzision ist der Hauptunterschied.

Float - 7 Stellen (32 Bit)

Double - 15-16 Stellen (64 Bit)

Dezimal -28-29 signifikante Stellen (128 Bit)

Dezimalstellen weisen eine viel höhere Genauigkeit auf und werden normalerweise in Finanzanwendungen verwendet, die ein hohes Maß an Genauigkeit erfordern. Dezimalstellen sind viel langsamer (in einigen Tests bis zu 20-mal) als ein Double/Float.

Dezimalzahlen und Floats/Doubles können nicht ohne Cast verglichen werden, wohingegen Floats und Doubles dies können. Dezimalstellen erlauben auch die Kodierung oder das Nachfolgen von 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
1011
cgreeno

Die Dezimalstruktur ist strikt auf Finanzberechnungen ausgerichtet, die eine Genauigkeit erfordern, die eine Rundung relativ wenig toleriert. Dezimalstellen sind jedoch aus mehreren Gründen für wissenschaftliche Anwendungen nicht geeignet:

  • Ein gewisser Präzisionsverlust ist in vielen wissenschaftlichen Berechnungen aufgrund der praktischen Grenzen des gemessenen physikalischen Problems oder Artefakts akzeptabel. Ein Präzisionsverlust ist im Finanzbereich nicht akzeptabel.
  • Decimal ist für die meisten Operationen viel (viel) langsamer als float und double, vor allem, weil Floating Point-Operationen in Binärform ausgeführt werden, während Decimal-Operationen in Base 10 ausgeführt werden (dh Floats und Doubles werden von der FPU-Hardware wie MMX/SSE verarbeitet) , während Dezimalstellen in Software berechnet werden).
  • Dezimal hat einen unannehmbar kleineren Wertebereich als das Doppelte, obwohl es mehr Stellen mit Genauigkeit unterstützt. Daher kann Decimal nicht zur Darstellung vieler wissenschaftlicher Werte verwendet werden.
78
Mark Jones
+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

Weitere Informationen finden Sie unter:
http://social.msdn.Microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5

70
user2389722

float 7 Stellen Genauigkeit

double hat eine Genauigkeit von ca. 15 Stellen

decimal hat eine Genauigkeit von ca. 28 Stellen

Wenn Sie eine bessere Genauigkeit benötigen, verwenden Sie double anstelle von float. In modernen CPUs haben beide Datentypen fast die gleiche Leistung. Der einzige Vorteil von float ist der geringere Platzbedarf. Praktisch nur wichtig, wenn Sie viele davon haben.

Ich fand das interessant. Was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte

46
CharithJ

Ich werde nicht jede Menge guter (und einige schlechte) Informationen wiederholen, die bereits in anderen Antworten und Kommentaren beantwortet wurden, aber ich werde Ihre Folgefrage mit einem Tipp beantworten:

Wann würde jemand eines davon benutzen?

Verwenden Sie die Dezimalzahl für gezählt Werte

Verwenden Sie float/double für gemessene Werte

Einige Beispiele:

  • geld (zählen wir Geld oder messen wir Geld?)

  • entfernung (Zählen wir die Entfernung oder messen wir die Entfernung? *)

  • punkte (zählen wir Punkte oder messen wir Punkte?)

Wir zählen immer Geld und sollten es niemals messen. Wir messen normalerweise die Entfernung. Wir zählen oft Punkte.

* In einigen Fällen, wie ich nominaler Abstand nenne, möchten wir in der Tat den Abstand "zählen". Zum Beispiel haben wir es vielleicht mit Länderzeichen zu tun, die Entfernungen zu Städten anzeigen, und wir wissen, dass diese Entfernungen nie mehr als eine Dezimalstelle haben (xxx.x km).

42
tomosius

Niemand hat das erwähnt

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

Ich meine

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

wirft OverflowException.

Diese aber nicht:

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

&

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

Ganzzahlen 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 richten diese Variablentypen genauso ein: Anstatt das Wort int zu verwenden, geben Sie double oder float ein. So was:

float myFloat;
double myDouble;

(float steht für "Fließkomma" und bedeutet nur 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 Stellen in Ihrer Nummer haben. Für doubles können Sie bis zu 16 Stellen eingeben. Um genauer 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-Zahl und double ist eine 64-Bit-Zahl.

Doppelklicken Sie auf Ihre neue Schaltfläche, um zum Code zu gelangen. 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 Ihre doppelte Schaltfläche. Das Meldungsfeld zeigt die Nummer korrekt an. Fügen Sie jedoch am Ende eine weitere Zahl hinzu, und C # rundet erneut auf oder ab. Die Moral ist, wenn Sie Genauigkeit wollen, seien Sie vorsichtig beim Runden!

29
daniel
  1. Double und Float können ausnahmslos sowohl zur Kompilierungs- als auch zur Laufzeit durch die Ganzzahl Null geteilt werden.
  2. Die Dezimalzahl kann nicht durch die Ganzzahl Null geteilt werden. Die Kompilierung schlägt immer fehl, wenn Sie dies tun.
27
xport
  • float: ± 1,5 x 10 ^ -45 bis ± 3,4 x 10 ^ 38 (~ 7 signifikante Zahlen)
  • double: ± 5,0 x 10 ^ -324 bis ± 1,7 x 10 ^ 308 (15-16 signifikante Zahlen)
  • dezimal: ± 1,0 x 10 ^ -28 bis ± 7,9 x 10 ^ 28 (28-29 signifikante Ziffern)
13
Mukesh Kumar

Dies war ein interessanter Thread für mich, da wir heute gerade einen bösen kleinen Bug hatten, der sich auf decimal bezieht, der weniger genau ist als ein float.

In unserem C # -Code lesen wir numerische Werte aus einer Excel-Tabelle, konvertieren sie in decimal und senden diese decimal an einen Service zurück, um sie in einem zu speichern. SQL Server-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 dies wunderbar funktioniert. Bei einigen, sehr kleinen Excel-Werten hat die Verwendung von decimal.TryParse den Wert vollständig verloren. Ein solches Beispiel ist

  • cellValue = .00006317592

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

Seltsamerweise bestand die Lösung darin, die Excel-Werte zuerst in double und dann in decimal 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 eine geringere Genauigkeit aufweist als ein decimal, wurde dadurch tatsächlich sichergestellt, dass kleine Zahlen immer noch erkannt werden. Aus irgendeinem Grund konnte double.TryParse tatsächlich so kleine Zahlen abrufen, während decimal.TryParse sie auf Null setzen würde.

Ungerade. Sehr komisch.

13
Mike Gledhill

Für Anwendungen wie Spiele und eingebettete Systeme, bei denen sowohl Speicher als auch Leistung von entscheidender Bedeutung sind, ist Float normalerweise die numerische Wahl, da es schneller und halb so groß wie ein Double ist. Früher waren ganze Zahlen die Waffe der Wahl, aber die Gleitkomma-Leistung hat in modernen Prozessoren ganze Zahlen überholt. Die Dezimalzahl stimmt!

8
yoyo

Die Variablentypen Decimal, Double und Float unterscheiden sich in der Art und Weise, wie sie die Werte speichern. Die Genauigkeit ist der Hauptunterschied, bei dem float ein Gleitkomma-Datentyp mit einfacher Genauigkeit (32 Bit), double ein Gleitkomma-Datentyp mit doppelter Genauigkeit (64 Bit) und decimal ein 128-Bit-Gleitkomma-Datentyp ist.

Float - 32 Bit (7 Stellen)

Double - 64 Bit (15-16 Stellen)

Dezimal - 128 Bit (28-29 signifikante Stellen)

Mehr über ... der Unterschied zwischen Decimal, Float und Double

7
warnerl

Das Problem bei all diesen Typen ist, dass eine gewisse Ungenauigkeit besteht UND dass dieses Problem bei 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 WAHR !!!

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 kleiner als 1.1 ist.

Achtung: Ich denke, dass das gleiche Problem sicherlich auch für andere Zahlen bestehen kann, da Decimal nur ein Double mit höherer Genauigkeit ist und die Genauigkeit immer eine Grenze hat.

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

Es ist bedauerlich, dass andere in COBOL implementierte numerische Typen in .Net nicht vorhanden sind. 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) 
5
schlebe

Der Hauptunterschied zwischen diesen ist die Präzision.

float ist eine 32-bit-Nummer, double ist eine 64-bit-Nummer und decimal ist eine 128-bit-Nummer.

3
user3776645