[Erledigt] Zeiger(einzelne bits einer double ausgeben)
-
Hallo Leute wir haben gerade die Zeiger in der Vorlesung behandelt und
haben jetzt Aufgeben dazu bekommen.
Bei der ersten Aufgabe geht es darum, die einzelnen bit's einer double
auszugeben.Aufgabe:
Schreiben Sie eine Funktion displayDoubleBytes(double d), die alle Bytes ausgibt,
die zur Speicherung der in d übergebenen Zahl verwendet werden.
Rufen Sie die Funktion für 0.0, 1.0 und -1.0 auf.Mein bisheriger Quellcode:
#include <stdio.h> #include <stdlib.h> /* * */ void displayDoubleByte(double *d); int main(int argc, char** argv) { double zahl = 0.0; displayDoubleByte(&zahl); return (EXIT_SUCCESS); } void displayDoubleByte(double *d) { int a = *d; int j = 7; while(j>=0) { for(int i = 0; i<=7; i++) { if(a & (1 << i)) printf("1"); else printf("0"); } printf(" "); d--; a = *d; j--; } }
Da ich ein 64bit System habe, ist die double Variable 8 byte groß.
Also wollte ich mir die einzelnen bytes holen und diese ausgeben und immer
ein byte (eine Adresse) weiter springen.Leider gibt mein Programm nicht das richtige aus.
0.0 => 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1.0 => 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 -1.0 => 11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Ich hoffe Hier hat jemand einen Denkansatz bzw. eine kleine Hilfestellung für
mich.mfg rufrider
-
void displayDoubleByte(double *d) { unsigned long long *pBits = (unsigned long long*) d; unsigned long long mask = 1LL << 63; int i; for (i=0;i<64;i++,mask=mask>>1) {printf((mask&pBits[0])?"1":"0");} printf("\n"); }
-
Was denn nun, Bits oder Bytes oder Bits der Bytes?
Auch war in der Aufgabenstellung nicht von einem Zeiger auf double die Rede, den du aber implementierst.
-
Ist die Mantisse nicht immer implizit 1. ... D.h. fuer 1.0 sollte da 00000... stehen.
Ok, genauer hingesehen:
int a = *d;
Hier tritt eine automatische Umwandlung auf von
double
nachint
. Die macht alles kaputt. Naechster Fehler: Auf meinem System, Windows 7 64 Bit, unter VS 11 Beta istint
nur 4 Byte gross.
-
@Wutz Wir sollen Zeiger verwenden, hat der Professor gesagt.
Wegen den bits und bytes:
Wir sollen alle bits einer double variable ausgeben, also
bei einer double größe von 8 byte (mein OS) muss ich 64 bit's
ausgeben.Der Prof. hat den tip gegeben, da ja alle double Adressen( 8 byte = 8 Adressen)
nebeneinander liegen, sollen wir die erste adresse nehmen und dessen 8 bits
ausgeben, danach zur nächsten adresse springen und diese bits ausgeben usw.
(je nach double größe).@knivil
das könnte das problem sein, ich will ja eig nur den teil der double von einer
adresse in das int "stopfen" und danach die nächsten bits der folgenden adressemfg
-
Dann schreibe doch erstmal eine Funktion, die die Bits eines Bytes ausgibt. Normalerweise ist
char
oderunsigned char
8 Bit (1 Byte hier) gross. Dann sehen wir weiter. Darueber hinaus ist double auch auf einem 32 Bit System meist 64 Bit gross.
-
die Funktion gibt mir die bits eines chars aus:
void displayBits(char z) { char i =1; for(i;i<7;i++) { if(z & (1 << i)) printf("1"); else printf("0"); } }
z=12 => 011000 z=27 => 101100
Hoffe hab es richtig verstanden.
Das müsste ich nach byte anzahl einer double wiederholen, um alle bytes einer
double auszugeben. So wie ich es verstehe. Also müsste ich dies doch für jede
Adresse der double machen ?
Nur versteh ich nicht, wie man nur die bits der einen Adresse bekommt und
nicht die ganze double Variable(Ich hoffe ich schreibe nicht zu verwierend)
mfg
-
Die Größe von double hat nichts mit der Adressbreite des Systems zu tun.
C ist so intelligent, das du beim Zeiger weiterzählen nicht wissen musst, wie groß ein double ist.
Das
a = *d;
mag bei der Definition noch das machen was du vorhast.
Als Zuweisung macht es aber etwas anderes.
Zum 1.: ein Zeiger ist kein int.
Zum 2.: durch den Dereferenzierungsoperator bekommst du den Wert auf den der Zeiger zeigt.
Dieser Wert wird dann in ein int gewandelt.Die Größe einer Variablen/Types bekommst du mit
sizeeof()
Also nimm statt <=7 ein `< sizeof(double)`
unsigned char *pc; pc = (char *)d; for(j=0;j<sizeof(double);j++,pc++) printf("%02x ", *pc); putchar("\n");
Ein Byte hat aber so um die 8 Bit (nicht 6). Für den Wert solltest du
CHAR_BIT
aus <limits.h> nehmen.
-
void displayDoubleByte( double d ) { unsigned char *p = (unsigned char*) &d; size_t i = 0; for( ; p < (unsigned char*) &d + sizeof( double ); ++p ) { for( i = CHAR_BIT; i > 0; --i ) { printf( "%c", (*p & 1 << ( i - 1 ) ) ? '1' : '0' ); } printf( " " ); } printf( "\n" ); }
Ihr dürft mich jetzt steinigen.
-
Jaja, zu schnell abgeschickt. Der cast muss bei mir natürlich auch
pc = (unsigned char *)d;
sein.
Obwohl,uint8_t
wäre noch besser.
-
Danke für deine Hilfe
meine Code jetzt:
#include <stdio.h> #include <stdlib.h> #include <limits.h> /* * */ void displayDoubleByte(double *d); int main(int argc, char** argv) { double zahl = 1.0; displayDoubleByte(&zahl); return (EXIT_SUCCESS); } void displayDoubleByte(double *d) { unsigned char *pc; pc = (char *)d; for(int j=0;j<sizeof(double);j++,pc++) { //printf("%02x ", *pc); for(int i = 0; i<=CHAR_BIT; i++) { if(*pc & (1 << i)) printf("1"); else printf("0"); } printf(" "); } }
Die Zeiger werd ich mir noche ein bisschen anschauen müssen.
Edit:
@ Swordfish steinigen wird dich hoffe ich keinerNur bringen fertige Lösungen nicht viel fürs Lernen.
Ich hab noch viel vor mir...mfg
-
DirkB schrieb:
Die Größe von double hat nichts mit der Adressbreite des Systems zu tun.
Na, der Prof. meint das wahrscheinlich anders. Double besteht aus 8 einzeln addressierbaren Einheiten/Bytes.
(Ich hoffe ich schreibe nicht zu verwierend)
Doch tust du.
Nur versteh ich nicht, wie man nur die bits der einen Adresse bekommt
Bytes ... und nicht der Adresse, sondern des Speichers, auf den durch die Adresse verwiesen wird.
011000
Fuer 8 Bit sind das etwas wenig.
Dann ist die kleinste addressierbare Einheit ist ein Byte, meist durch
char
oderunsigned char
repraesentiert. D.h. du musst deinen Zeiger aufdouble
nach Zeiger aufchar
konvertieren, um auf die einzelnen Bytes eines 8 Byte Speicherbereiches zuzugreifen.unsigned char* c = (unsigned char*)(&d);
Und danach fuer jeden Wert deine Funktion displayBits aufrufen.
displayBits(c[7]); displayBits(c[6]); displayBits(c[5]); displayBits(c[4]); displayBits(c[3]); displayBits(c[2]); displayBits(c[1]); displayBits(c[0]);
-
Die 6 bits Ausgabe, war mein Fehler im Eifer des Gefechts, sollte
Eigentlich von o bis <=7 sein.Ich danke euch auf jeden Fall für die schnelle Hilfe!
mfg rufrider und schönen Abend noch.
-
rufrider schrieb:
Eigentlich von o bis <=7 sein.
Hoffentlich hat dann auch o den Wert 0
Gewöhn dir lieber die C-Schreibweise
< 8
an.
Dann siehst du dass es 8 Durchläufe sind (wenn du bei 0 anfängst)
-
rufrider schrieb:
Schreiben Sie eine Funktion displayDoubleBytes(double d), die alle Bytes ausgibt,
rufrider schrieb:
Wir sollen Zeiger verwenden, hat der Professor gesagt.
Entweder dein Professor hat keine Ahnung oder du kannst nicht richtig lesen und schreiben oder beides.
Beide o.g. Aussagen widersprechen sich.
Eine double-Variable ist genau sizeof(double) Bytes und sizeof(double)*CHAR_BIT Bits groß.
-
"Schreiben Sie eine Funktion displayDoubleBytes(double d), die alle Bytes ausgibt," --> so steht es in der PDF des Profs.
Das mit dem keine Ahnung des Profs glaub ich nicht, leider hat er
des öfteren Schreibfehler in seinen Texten und Beispielen.mfg
-
Du kannst jederzeit einen Zeiger auf deine Variable erhalten, indem du den Adressoperator
&
auf beispielsweised
anwendest:double d = 14.3; double* p = &d; // p zeigt auf d