Laden...

decimal, float oder double

Erstellt von heimi vor 17 Jahren Letzter Beitrag vor 17 Jahren 6.829 Views
H
heimi Themenstarter:in
22 Beiträge seit 2007
vor 17 Jahren
decimal, float oder double

Ich will ne ganz einfache Rechnung mit Nachkommastellen machen und weiss nicht, ob ich decimal, float, double, etc. nehmen muss, damit das Resultat stimmt.


double a;
double b = 6.5;
a = 1300 / 8 * b;

Eigentlich müsste a (laut jedem Taschenrechner) 1056.25 ergeben.
C# errechnet aber a = 1053.

Warum denn das? Warum 3.25 Abweichung?

HELP!

Heimi

2.082 Beiträge seit 2005
vor 17 Jahren

Hallo heimi,

double ist kein Variablentyp für Nachkommazahlen. Für genaue Berechnungen embfehle ich dir float.

//Edit: VS dürfte dir eigentlich auch nen Hinweis in etwa wie "pobably loss of data" bringen.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

S
8.746 Beiträge seit 2005
vor 17 Jahren

double ist ein Fliesskommatyp für doppelte Genauigkeit. Einfache Genauigkeit ist float.

Das Problem liegt hier aber nicht in der Genauigkeit, sondern in der Art und Weise, wie der Compiler den Ausdruck zerlegt:

1300 / 8 ist eine Integer-Division, der rest wird abgeschnitten, die Multiplikation bringt es dann auf 1053.

So ist es richtig:

a = 1300.0 / 8.0 * b;

F
10.010 Beiträge seit 2004
vor 17 Jahren

@frisch:
Wer hat Dir denn das erzählt?
Float ist abgebildet auf den System.Single, und damit nur halb so genau wie Double.

O
778 Beiträge seit 2007
vor 17 Jahren

Wie oft willst du denn rechnen? Und was willst du erreichen? Das musst dir klar werden. Ich hab dir dann mal eine Entscheidungshilfe zusammengestellt

decimal

  • Innerhalb des Dezimalsystems (d.h., bei Zahlen ohne Perioden, z.B. Geldbeträgen) 100% genau
  • langsamer als die anderen beiden (recht deutlich)

float (entspricht Single)

  • geringer Speicherbedarf
  • evtl. langsamer als Double (wird ja gerade diskutiert)
  • dieselben Rundungsfehler wie double, niedrigere Genauigkeit

double

  • schnellster von den dreien
  • Rundungsfehler z.T. recht deutlich, z.B. (1-1)~10^-324
6.862 Beiträge seit 2003
vor 17 Jahren

Wie kommst du zu der Aussage dass Float langsamer ist als Double?

In der Tat ist Float theoretisch gesehen schneller als Double, da Float nur 32 Bit groß ist und ein Double 64 Bit. Selbst bei gleichwertiger Anzahl von CPU Takten für die Berechnung beider Datentypen, ist Float schneller weil weniger kopiert werden muss.

In der Praxis merkt man das in der Tat kaum, deshalb wird Float auch recht wenig verwendet. Aber langsamer ists auf keinen Fall.

Decimal dagegen ist recht langsam weil die CPU dafür keinen eingebauten Datentyp hat und die Berechnung per "Software" erfolgt.

Baka wa shinanakya naoranai.

Mein XING Profil.

5.658 Beiträge seit 2006
vor 17 Jahren

Original von talla
In der Praxis merkt man das in der Tat kaum, deshalb wird Float auch recht wenig verwendet.

Aber sicher! Fast alle .NET-Internen Datentypen verwenden float, u.a. auch DirectX. Z.B. bestehen die Member der Vector- und Matrix-Datentypen alle float, da scheint sowohl die Geschwindigkeit als auch die Genauigkeit auszureichen.

Die Rundungsfehler sind allerdings bei floats durchaus höher aus bei doubles, das ist ja ganz klar, denn die doubles haben doppelt so viele Bytes zur Verfügung.

Viele Grüße,
Christian

Weeks of programming can save you hours of planning

B
1.529 Beiträge seit 2006
vor 17 Jahren

Der Grund liegt aber eher darin, dass Single mit 23Bit Genauigkeit für die Visualisierung ausreichend genau ist (Positionierung auf ca. ein Achtmillionstel möglich).
Desweiteren kann man per SIMD (SSE, 3Dnow, Altivec) gleich vier Single-Werte auf einmal verarbeiten, d.h. einen ganzen Vektor pro Befehl, was 3D-Grafik erst möglich macht. Die GPU setzt daher auch auf single.

Nur für wissenschaftliche Berechnung (bzw. Berechnungen, die nicht ausschließlich der Visualisierung dienen) nutzt man ein Format mit höherer Genauigkeit (52Bit), also Double.

Und ausschließlich für kaufmännische Berechnungen, die ja immer im Dezimalsystem stattfinden, benutzt man Decimal (Orientierung an COBOL). Dieses wird per Software im BCD-Format berechnet und kennt daher nicht das Problem, dass es (Dezimal-)Zahlen gibt, die nicht ohne Verlust in eine binäre Darstellung umgewandelt werden können. Rundungsfehler gibt es beim Rechnen in diesem Format trotzdem, nur keine Umwandlungsfehler mehr.

O
778 Beiträge seit 2007
vor 17 Jahren

also zum einen hab ich wirklich einem Irrglauben unterlegen und bei Double und float nur die Hälfte der Bits veranschlagt. Aber das Double schneller als Float ist hab ich mir nicht selber ausgedacht, das war Michael Kofler, der in seinem Buch 'Visual Basic 2005' (mit dem ich die Programmierung mit .NET und überhaupt die Programmierung gelernt hab) die Aussage los gelassen hat.

Der Defaultdatentyp für Fließkommazahlen und Fließkommaberechnungen ist Double. Dieser Datentyp kann auch am effizientesten verarbeitet werden. Single (VB-Alias für float) sollte nur dann eingesetzt werden, wenn der Platzbedarf eine wichtige Rolle spielt (etwa bei riesigen Feldern)

Woher der das hat? Keine Ahnung, bei mir hat sich halt nur festgesetzt, dass Double schneller ist, zumal ich mit den Bytes durcheinander gekommen bin (dachte Double hat 32 und float 16bit)

O
778 Beiträge seit 2007
vor 17 Jahren

Bei 64bit-Systemen sollte aber definitiv Double in absolut jedem Fall schneller sein...

2.082 Beiträge seit 2005
vor 17 Jahren

Wer hat Dir denn das erzählt?

8o sry war wohl in Gedanken bei nem anderen Datentyp 😉

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

T
512 Beiträge seit 2006
vor 17 Jahren

Original von onlinegurke
Bei 64bit-Systemen sollte aber definitiv Double in absolut jedem Fall schneller sein...

Mit so einer absoluten Aussage, liegst du auf jeden Fall falsch 😉
Der Kontext ist bei heutigen CPUs sehr entscheidend und auch sehr umfangreich. Eine generelle Aussage ist nicht möglich.

Zwei Bytes zu addieren ist z.B. im Allgemeinen nicht schneller als zwei Integer zu addieren. Im Speziellen lassen sich aber Byte Vektoren schneller addieren als Integervektoren mit gleicher Dimension.

Außerdem ist die FPU eigentlich schon länger mit 64bit Registern ausgestattet.

e.f.q.

Aus Falschem folgt Beliebiges

B
1.529 Beiträge seit 2006
vor 17 Jahren

Innerhalb der x86-FPU werden alle Zahlen in einem Format mit 80 Bit gespeichert (Extended unter Turbo Pascal). Ausschließlich beim Laden oder Speichern von Werten werden diese in das angegebene Format (Single oder Double) gewandelt.
Intern wird in der FPU immer in diesem Format gerechnet. Daher können nur erste langwierige Operationen unterschiedlich lange dauern, da bei Wandlung von Single nach Extended mehr Bits null sind (und evtl. nicht berechnet werden müssten), als bei Wandlung von Double nach Extended. Nach dieser Berechnung enthält das interne FPU-Register die gleiche Bitfolge (abgesehen von Rundungsfehlern) und alle folgenden Berechnungen dauern wieder gleich lang.

Insofern ist es blödsinnig zu behaupten, dass eines der beiden Formate schneller ist als das andere. Der einzige Grund, warum zur Visualisierung Single verwendet wird, liegt wirklich in der ausreichenden Genauigkeit und in den SIMD-Fähigkeiten moderner C-/G-PUs.

Wer sich darüber genauer informieren möchte, soll sich bitte folgende Wikipedia-Artikel durchlesen:
Gleitkommazahl
IEEE 754