double in c#

15/02/2009 - 12:34 von Markus | Report spam
Ich lerne gerade das Programmieren in C# aus einem Buch.
Da ich erst angefangen habe, habe ich eine Anfàngerfrage.

Ich kenne das Rechnen mit nur aus einem Basicdialekt für PalmOS und wundere
mich über die Verwendung des Datentyps double.

In einem der Beispiele im Buch werden mit den Datentypen float, double und
decimal die Konstanten 10.0 und 9.9 deklariert und dann jeweils subtrahiert.
Also 10.0 - 9.9
Ergebnisse sind:

float = 0,1000004
double = 0,0999999999999996
decimal = 0,1

Mir will sich einfach nicht erschließen warum float und double in diesem
Fall falsch rechnen. Es geht um eine Zahl die nur eine Stelle hinterm Komma
hat, was beide Datentypen eigentlich können sollten.

Kann mir einer erklàren wie es kommt, was übersehe ich?

Gruß Markus
 

Lesen sie die antworten

#1 Armin Zingler
15/02/2009 - 15:18 | Warnen spam
Markus wrote:
Ich lerne gerade das Programmieren in C# aus einem Buch.
Da ich erst angefangen habe, habe ich eine Anfàngerfrage.

Ich kenne das Rechnen mit nur aus einem Basicdialekt für PalmOS und
wundere mich über die Verwendung des Datentyps double.

In einem der Beispiele im Buch werden mit den Datentypen float,
double und decimal die Konstanten 10.0 und 9.9 deklariert und dann
jeweils subtrahiert. Also 10.0 - 9.9
Ergebnisse sind:

float = 0,1000004
double = 0,0999999999999996
decimal = 0,1

Mir will sich einfach nicht erschließen warum float und double in
diesem Fall falsch rechnen. Es geht um eine Zahl die nur eine Stelle
hinterm Komma hat, was beide Datentypen eigentlich können sollten.

Kann mir einer erklàren wie es kommt, was übersehe ich?

Gruß Markus




Das liegt an der internen Darstellung der Werte im binàren Format. Eine
Zahl, die in unserem gewohnten Dezimalsystem endlich ist, ist oft nicht
auch im dualen System endlich. Deshalb làsst sich 0,1 nicht exakt binàr
speichern (bei float und double). Ohne jetzt auf das konkrete,
standardisierte Format einzugehen...: Versuche doch mal die Zahl 0,1
dual darzustellen. Gehen wir davon aus, dass die Stellen vor dem Komma
die Wertigkeit 1, 2, 4, 8 usw haben. Nach dem Komma haben sie die
Wertigkeit 1/2, 1/4, 1/8 usw.

0,1 ist also

0/2 + 0/4 + 0/8 + 1/16 + 1/32 + 0/64 + 0/128 + 1/256 + 1/512 + 0/1024 +
0/2048 + 1/4096

also: 0,000110011001

Du merkst, das ginge endlos weiter. Da aber jeder Variablen nur begrenzt
Speicherplatz zur Verfügung steht, muss irgendwo "abgeschnitten" werden.
Dadurch geht Genauigkeit verloren. Somit ist der gespeicherte Wert nur
_ungefàhr_ 0,1. Deswegen kannst du dich bei float nur auf 7 und bei double
auf 14 Dezimalstellen verlassen. Decimal ist eine skalierte Dezimalzahl,
deshalb trifft das da nicht zu.

Wie es auch in der Hilfe steht, die interne Speicherung "entspricht der Norm
IEC 60559:1989 (IEEE 754) für binàre Gleitkomma-Arithmetik"
(http://de.wikipedia.org/wiki/IEEE_754)


Armin

Ähnliche fragen