double a -> char array[sizeof(double)] ???
-
Mal auf die gefahr hin das ich gelüncht werde

Mir schwebt irgendwie sowas vor:int x; //Die zu konvertierende Zahl char *x_ptr=reinterpret_cast<char *>(&x); //Ein Pointer dessen adrese byteweise erhöht wird for(unsigned int count=0;count < sizeof(x) count++) *(x_ptr+count)Geht aber noch nicht. Und ich weiß nicht so richtig warum
GrußP.s.
Bitte lünchen ersparen, bin nicht sadomistisch veranlagt *ggg*
-
Was passt dir denn an der oben genannten Methode nicht??
-
@Drakon
-Mir ist zu spät aufgefallen, dass ich in dem Codeabschnitt wo ich mich gerade befinde keinen speicher merh anfordern darf.
Wenn isch std::stringstream auch richtig initialisiere, glaube ich trotzdem, dass
die Methode c_str neuen braucht.
-Des weitern benötige ich eine Binäre umrechnung.
Bei deiner Methode bekomme ich
x=100;
char a[3];
a[0]=1;
a[1]=0;
a[2]=0;
Ich würde benötigen:
100=0x64=0000 0000 0110 0100
a[0]=0000
a[1]=0000
a[2]=0110
a[3]=0100
Wobei die Konvertierung ja einfach dein a c_string -'0' wäre.
-Ich bin der überzeugung, dass wenn der cast nach char* läuft,
das fast nicht effizienter gemacht werden kannGruß
-
Ich habs, lesen mit
(*(x_ptr+count)&0x0FF);geht dann
Gruß
-
AlexXXx schrieb:
Ich habs, lesen mit
(*(x_ptr+count)&0x0FF);geht dann
GrußBesser wäre, von vornherein unsigned char zu verwenden.
*(x_ptr+count)
ist nicht falsch, nur hast du möglicherweise falsche Erwartungen.memcpy gibt es auch noch.
-
Also so gehts ganz gut:
int x=-999999; char *x_ptr=reinterpret_cast<char *>(&x); unsigned char ar[sizeof(x)]; std::cout <<"\nx " <<x; for(unsigned int count=0;count<sizeof(x);count++) ar[count]=(int)(*(x_ptr+count) & 0x0FF); x=0; for(int count=sizeof(x)-1;count>=0;count--) { x=x << 8; x|=ar[count]; } std::cout <<"\nx " <<x;
-
@camper
Ja du hast Recht, memcpy wäre eine lösung.
Würds gern so noch ein bisschen weiter versuchen zum üben.
Was muß ich denn für double machen ??
double nach unsigned long int casten und dann wie vorher ??
Gruß
-
AlexXXx schrieb:
ar[count]=(int)(*(x_ptr+count) & 0x0FF);Das funktioniert, macht aber nicht den Eindruck, als dir wirklich bewusst ist, was hier passiert. Der Cast und das & 0xFF sind völlig überflüssig (naja, nicht ganz im Allgemeinen, im Extremfall ist allerdings auch dein Konstrukt nicht korrekt).
Wieso nicht einfach x_ptr ebenfalls als unsigned char*?Ich vermute mal, dass char bei dir vorzeichenbehaftet ist, und dann mitunter negative Zahlen entstehen, mit denen du nicht gerechnet hast?
-
@camper,
Doch mir ist schon klar was passiert.
Dass es überflüssig ist merk ich jetzt auch. Aber wies so ist, man tastet sich an den code ran.
Dass MSB Vorzeichen ist ist klar.
count mit unsigned char aufrufen ist besser. Stimmt schon.
Ändert aber nichts an den Werten im Speicher.Wenn mir was unklar ist, freu ich miich wenn dus mir erklärst, glaube es abernicht.

P.s.: char ist bei mir nicht mehr vorzeichen behaftet gewesen.
0x0FF hab ich vergessen raus zu machen. Da hst du schon Recht.Aber wie bekomme ich das mit gleitkomazahlen hin. Wei0t du was ??
Fang jetzt bitte nicht an mit ich weiß nicht wie die aufgebaut sond oder sowas.
Wenni ch was nicht weiß, frage ich. (Das ist glaub erstes Semester gewesen )Gruß
-
So ists besser.

int x=-99; char *x_ptr=reinterpret_cast<char *>(&x); unsigned char ar[sizeof(x)]; std::cout <<"\nx " <<x; for(unsigned int count=0;count<sizeof(x);count++) ar[count]=*(x_ptr+count) ; x=0; for(int count=sizeof(x)-1;count>=0;count--) { x=x << 8; x|=ar[count]; }
-
So gehts auch für double. Ist glaub gut so.
double x=0.999; char *x_ptr=reinterpret_cast<char *>(&x); unsigned char ar[sizeof(x)]; std::cout <<"\nx " <<x; for(unsigned int count=0;count<sizeof(x);count++) ar[count]=*(x_ptr+count) ; x=0; for(int count=sizeof(x)-1;count>=0;count--) *(x_ptr+count)|=ar[count]; std::cout <<"\nx " <<x;
-
AlexXXx schrieb:
int x=-99; char *x_ptr=reinterpret_cast<char *>(&x); unsigned char ar[sizeof(x)]; std::cout <<"\nx " <<x; for(unsigned int count=0;count<sizeof(x);count++) ar[count]=*(x_ptr+count) ; x=0; for(int count=sizeof(x)-1;count>=0;count--) { x=x << 8; x|=ar[count]; }Was soll'n das werden, wenn's fertig ist? Die Kodierung passt überhaupt nicht zur Dekorierung. Das ist sowas von un-portabel, dass es nicht mal auf ein und demselben Rechner funktionieren muss.
Das hier wäre wenigstens konsistent:
void ich_scheiss_auf_portabel__nach_mir_die_sintflut() { int foo = 23; char dings[sizeof(foo)]; std::memcpy(dings,&foo,sizeof(dings)); // foo --> dings std::memcpy(&foo,dings,sizeof(foo) ); // dings --> foo }Der Haken: Solltest Du dings in eine Datei schreiben und auf einem anderen Rechner einer anderen Gattung wieder lesen wollen, wird das eventuell wieder nicht funktionieren.
Wenn Du vorhast plattformunabhängige Binärdateien zu schreiben, solltest Du das anders machen. Zum Beispiel unsigned ints manuell durch Shiften und Maskieren in unsigned chars zerlegen und wieder zurück.
Es gibt da übrigends noch so eine "Aliasing"-Regel, die man mit reinterpret_cast leicht verletzen kann. In Deinem Fall geht das noch in Ordnung, da Zeiger auf char bzw unsigned char auf alles zeigen dürfen.
Gruß,
SP
-
-Also wie man das mit memcpy macht ist mir auch klar.
Das hat schon jemand vor dir empfohlen und ich halte es auch mit für die beste Lösung.
-Aber ich will ja auch was lernen.
-Wiso das auf einem Rechner schief gehen soll ist mir nicht klar.
(Würd mich über eine erklärung freuen)(Ich glaub das im Übrigen auch nicht wenn dus nicht begründest)
(Zumal das Programm getestet ist und bei mir sehr gut läuft).
-Unportabel zu anderen rechnern Meinst du wegen Big und Littel Endian ??
-Kannst du mir die Aliasing Regel erklären ?? Die kenne ich nicht.
(Gehts darum, dass ich die Blockgröße verletze,
wenn sizeof(ptr_type a) den datenblock auf den es zeigt nicht ohne Rest teilt ??)Wenn ja ists trivial
(-Aliasing kenne ich nur aus Nachrichtentechnik)
-Die neuste version des codes schaut bereits so aus:AlexXXx schrieb:
double x=0.999; char *x_ptr=reinterpret_cast<char *>(&x); unsigned char ar[sizeof(x)]; std::cout <<"\nx " <<x; for(unsigned int count=0;count<sizeof(x);count++) ar[count]=*(x_ptr+count) ; x=0; for(int count=sizeof(x)-1;count>=0;count--) *(x_ptr+count)|=ar[count]; std::cout <<"\nx " <<x;
-
Werdet ihr echt für eure Antworten bezahlt, oder gute deutsche Hilfsbereitschaft??
*ggg*
Würd mich interessieren.
Gruß
-
AlexXXx schrieb:
-Wiso das auf einem Rechner schief gehen soll ist mir nicht klar.
Du greifst auf einen int über einen char* zu. Hier spielt die Byte-Ordnung eine Rolle und wieviel Bits ein Byte besitzt. Die ist nicht auf jedem Rechner gleich. Dann setzt Du den int wieder aus bytes manuell zusammen über << und + oder |. Dabei nimmst Du an, dass Bytes 8 Bits besitzen und ein int im Little-Endian Format abgelegt ist. Auf einer Big-Endian-Maschine oder auf einer, die zB 16Bit-Bytes benutzt, kommt bei Dir Murks raus.
AlexXXx schrieb:
-Unportabel zu anderen rechnern Meinst du wegen Big und Littel Endian ??
Ja, und auch, was die Größe von ints angeht (16 bit? 24 bit? 32 bit? 64 bit?...)
AlexXXx schrieb:
-Kannst du mir die Aliasing Regel erklären ?? Die kenne ich nicht.
(Gehts darum, dass ich die Blockgröße verletze,
wenn sizeof(ptr_type a) den datenblock auf den es zeigt nicht ohne Rest teilt ??)Wenn ja ists trivial
(-Aliasing kenne ich nur aus Nachrichtentechnik)GIYF, strict aliasing
AlexXXx schrieb:
-Die neuste version des codes schaut bereits so aus:
Pfui bah!
- Du greifst über char* zu und speicherst in unsigned char
- Du gehst davon aus, dass wenn Du x=0 setzt, alle Bits 0 sind
- Du benutzt nicht std::memcpy
AlexXXx schrieb:
Werdet ihr echt für eure Antworten bezahlt, oder gute deutsche Hilfsbereitschaft??
Bezahlt? Nein. Deswegen solltest Du darauf achten, dass Du nicht unnötig Kapazität an Hilfsbereitschaft aufbrauchst. Statt so viele Fragen zu stellen, kannst Du Dir auch einfach 2-3 schlaue Bücher besorgen, und Internetsuchmaschinen benutzen. Das mit den Büchern lohnt sich -- auch für Dich.
Gruß,
SP
-
@SebastianP
-Zunächt mal danke für kompetente Antwort. Hat mir weiter geholfen.
-memcpy benutze ich nicht, weil ich ganz zu anfang gschrieben habe, dass ich
eigentlich eine Funktion aufrufen will. Also:write(char *,int size,......)wenn ich memcpy verwenden möchte, müßte ich ja
int x; //zu schreibende Wert unsigned char *x_ptr[sizeof(x)]; memcpy(....); //x nach x_ptr glaub es war (destination,target,size) bin zu faul nach zu schauen write(x_ptr,sizeof(x),...);schreiben.
Mit der anderen Variante stell ichi mir das so vor:int x; unsigned char x_ptr=einterpret_cast<unsigned char *>(&x); write(x_ptr,sizeof(x),...);Wegen bücher.
"auch". Also wenn ich Bücher lese, lerne ich eigentlich immer was dazu. Mach das eigentlich ganz gern. Mein C und C++ ist weit davon entfernt ausgereift zu sein, und das wird wahrscheinlich auch immer so bleiben.
Bücher würdest du die auf deiner Homepage empfahlen denke ich??
Hatte mit Büchern in C++ bis jetzt nur Pech.
habe mir C++ von A bis Z gekauft
Und mein erstes war Praktische C++ Programmierung von O'Reilly.
Gruß
-
AlexXXx schrieb:
@SebastianP
-Zunächt mal danke für kompetente Antwort. Hat mir weiter geholfen.
-memcpy benutze ich nicht, weil ich ganz zu anfang gschrieben habe, dass ich
eigentlich eine Funktion aufrufen will. Also:write(char *,int size,......)wenn ich memcpy verwenden möchte, müßte ich ja
int x; //zu schreibende Wert unsigned char x_ptr[sizeof(x)]; memcpy(....); //x nach x_ptr glaub es war (destination,target,size) bin zu faul nach zu schauen write(x_ptr,sizeof(x),...);schreiben.
Mit der anderen Variante stell ichi mir das so vor:int x; unsigned char *x_ptr=einterpret_cast<unsigned char *>(&x); write(x_ptr,sizeof(x),...);Wegen bücher.
"auch". Also wenn ich Bücher lese, lerne ich eigentlich immer was dazu. Mach das eigentlich ganz gern. Mein C und C++ ist weit davon entfernt ausgereift zu sein, und das wird wahrscheinlich auch immer so bleiben.
Bücher würdest du die auf deiner Homepage empfahlen denke ich??
Hatte mit Büchern in C++ bis jetzt nur Pech.
habe mir C++ von A bis Z gekauft
Und mein erstes war Praktische C++ Programmierung von O'Reilly.
Gruß
-
Was mich noch interessiern würd wäre:
Sebastian schrieb:
Ja, und auch, was die Größe von ints angeht (16 bit? 24 bit? 32 bit? 64 bit?...)
Ich dachte dass egal auf welcher Maschine char jeden
Typen (Also gleitkomma oder ganzzahl)
Ohne Rest teilen müßte.
Folglich dürfte das bei der letzten Lösung keine Rolle spielen.
(Big und little Endian ist nach wie vor ein Problem. Aber für mich zunächst uninteressant.)
Der << akzeptiere ich als schrott.
-
AlexXXx schrieb:
Mir ist zu spät aufgefallen, dass ich in dem Codeabschnitt in dem ich mich gerade befinde keinen speicher mehr anfordern darf. Wenn ich std::stringstream richtig initialisiere, glaube ich trotzdem, dass die Methode c_str() neuen braucht.
Könntest du mal bitte sagen, wieso?
Welche Werte bekommst du denn und wieso musst du sie wo genau speichern? Wieso bist du dir so sicher, dass du da überhauptc_str()brauchst?
Und wieso darfst du keinen Speicher mehr anfordern?bb
-
Also es funktioniert einwandfrei nach der zuletzt entwickelten Methode.
Schief gehen würde es meiner Meinung nach lediglich, wenn char
einen Typen nicht ohne Rest teilt. (Abgesehen von dem Little und Big endian Problem)
Und da bin ich der Auffassung, daß das nicht sein darf.
Gruß