Forum: PC-Programmierung [C] binäre Darstellung von double -Zahlen


von Herbert Knieling (Gast)


Lesenswert?

Hallo, folgendes Vorhaben habe ich:

Ich habe eine Doublezahl
z.B.

double dWert = 230.43;

Jetzt möchte ich gerne sehen, wie diese im Speicher dargestellt wird.

Leider weiß ich nicht so recht, was die C-Casting Operatoren machen...
Ich schreibe jetzt mal, wie ich es intuitiv machen würde und freue mich 
auf eure Korrekturen:


Folgende Programmzeilen sollen
1. einen Pointer auf den Anfang der Zahl darstellen.
da ich byteweise den Speicher auslesen möchte, halte ich unsigned char 
für sinnvoll.
2. Zählvariable deklarieren, da ich ja nacheinander alle Bytes der 
Doublezahl durchwandern möchte.
3. Jetzt weise ich meinem Pointer die Adresse der Double zu.
Hierzu caste ich zuerst auf ein void*, dass keine komischen Umrechnungen 
und Rundungen durchgeführt werden (wie gesagt: ich weiß leider nicht, 
was die Casting operatoren machen)
Dann caste ich auf unsigned char*, da ich ja eine unsigned char Pointer 
Variable habe.
4. Double Zahl = 64 Bit = 8 Byte-> schleife über i = 0..7
5. Gib Speicher an Adresse hexadezimal aus und erhöhe diese Adresse 
insgesamt 8 mal...


Könnte ich das irgendwie so machen, oder ist das ganz falsch?

unsigned char * pU; // Pointer auf den Anfang der  Zahl
int i;
pU =  (unsigned char *)  ((void*) &dWert);

for (i = 0; i < 8; i++)
{
   printf( "%x ", *(pU ++));

}

Vielen Dank für Korrekturen...

von Florian (Gast)


Lesenswert?

http://de.wikipedia.org/wiki/IEEE_754

Du könntest auch
1
pU = ( unsigned char *) &dWert;

verwenden.

Diese Casting-Operation macht aus einem *double ein *unsigned char, so 
dass *pU ein unsigned char liefert und bei pU++ (in den meisten Fällen) 
die Adresse um 1 erhöht wird.

Würdest Du
1
double *pD = &dWert;
machen, dann würde *pD einen Double liefern und bei pD++ die Adresse (in 
den meisten Fällen) um 8 erhöht werden.

Du könntest auch
1
union {
2
    double d;
3
    unsigned char u[8];
4
} wert;
5
6
wert.d = 1.2345;
machen und dann mit
1
wert.u[0] ... wert.u[8]
die einzelnen Bytes abfragen. Dadurch überlässt Du dem Compiler die 
Pointer-Geschichte.

von Herbert Knieling (Gast)


Lesenswert?

danke, das union war der Befehl, den ich gesucht hatte.
Ist es so, dass Rundungen nur dann durchgeführt werden, wenn ich den Typ 
caste?

z.B.

double dWert = 12.6
int i = (int) dWert;

--> i = 12...

aber int* pI = (int*) &dWert

--> *pI = den Bits entsprechender Wert als int?

von Florian (Gast)


Lesenswert?

Wenn Du den Compiler nötigst, aus dem double einen anderen Zahlentyp zu 
machen (also alle Varianten von int, alle Varianten von char oder auch 
andere Varianten von float), müssen natürlich die Zahlen angepasst 
werden, damit der Wert auch dargestellt werden kann.

Übrigens für Rundungen würde ich mir an Deiner Stelle mal die Funktionen 
ceil() und floor() anschauen.

Wenn ich mal unterstelle, dass die Länge Deines Ints 32 Bit beträgt 
(hängt von der Architektur ab), wird Dir *pI die ersten 32 Bit von dWert 
liefern. Allerdings ist der Wert nicht der, den Du mit dem ersten Cast 
(also 12) erhalten würdest, sondern das, was im Speicher steht.

Beispiel:

Nehmen wir an, die Variable dWert sei im Speicher an Stelle 0x1000 
gespeichert.

Der Speicher würde dann wie folgt aussehen:
0x33 0x33 0x33 0x33 0x33 0x33 0x29 0x40

int * pI = ( int * ) &dWert;
pI hat den Wert 0x1000, zeigt also auf den Speicher von dWert.

*pI würde Dir dann 0x33333333 liefern (falls int 32 Bit lang ist). Auch 
hier hängt die Reihenfolge von der Architektur ab (ausgerechnet bei 12.6 
sind allerdings die ersten 4 Bytes identisch) ---
s. http://de.wikipedia.org/wiki/Byte-Reihenfolge

Wenn Du anstatt int short verwendest (short = 16 Bit) würdest Du mit *pI 
0x3333 bekommen, mit char 0x33 usw. Wenn Du float anstatt int verwenden 
würdest, würde wohl auch irgendein Murks herauskommen.

Aber warum probierst Du das nicht einfach aus?


Wie bereits oben geschrieben:

http://de.wikipedia.org/wiki/IEEE_754

Hier ist der Aufbau der float-Typen beschrieben.


von Herbert Knieling (Gast)


Lesenswert?

Danke für die Tipps...

Ich habe es inzwischen ausprobiert. Ich hatte übers Wochenende 
allerdings keinen Compiler zur Hand...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.