Probleme mit reinterpret_cast<double*>
-
Hallo,
ich habe folgendes Problem:
double* k; unsigned int komp; komp = ~komp; k = reinterpret_cast<double*>(&komp);Ich möchte also ein unsigned int in einen double überführen, und vorher jedes einzelne Bit des unsigned int tauschen.
Wenn ich dies in ein float, anstatt einem double mache, läuft es einwandfrei. Hier bekomme ich aber immer nur 0 zurück.
Ich habe nun versucht dies mit Visual Studio 20005 zu debuggen und bekomme als Fehler nach der reinterpret_cast Stelle für k[0]:
2,64...e-308
und komp war allerdings vorher:
3258761612
Dies bekomme ich aber auch, wenn komp vorher
123176233 war,
oder 1538900071.
Also bekomme ich immer dengleichen Wert zurück.
Das kann doch irgendwie nicht stimmen, oder?Kann mir vielleicht jemand helfen?
Florian
-
was ist an
unsigned komp; komp ~= komp; double k = komp;schlecht?
-
Hallo,
diese Fehlermeldung in Visual Studio:
1>c:\dokumente und einstellungen\floriank\eigene dateien\visual studio 2005\projects\komplett\komplett\main_neu.cpp(438) : error C2440: '=': 'unsigned int' kann nicht in 'double *' konvertiert werden
1> Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder FunktionsformatFlorian
-
floriank schrieb:
double* k; unsigned int komp; komp = ~komp; k = reinterpret_cast<double*>(&komp);Ein reinterpret_cast interpretiert deinen Zeiger auf unsigned int als Zeiger auf double. Also das, was im Speicher als unsigned int steht, wird als double interpretiert. Das wird in der Regel nicht der Wert sein, den Du erwartest, zumal die Grössen der Datentypen sich mit ziemlicher Sicherheit unterscheiden. thordk hat Dir ja die richtige Lösung gezeigt. Da wird der Wert gecastet. Mit dem C++-style-cast wäre das ein static_cast:
double k; unsigned int komp = f(); k = static_cast<double>(~komp);Der thordk hat das weggelassen, da das sowieso implizit gemacht wird.
-
tntnet schrieb:
Ein reinterpret_cast interpretiert deinen Zeiger auf unsigned int als Zeiger auf double. Also das, was im Speicher als unsigned int steht, wird als double interpretiert. Das wird in der Regel nicht der Wert sein, den Du erwartest, zumal die Grössen der Datentypen sich mit ziemlicher Sicherheit unterscheiden.
Genau das möchte ich ja eigentlich haben. Ich möchte nicht exakt den Wert haben. Mich stört vorallem, daß bei der anderen Methode immer derselbe Wert nach dem reinterpret_cast heraus kommt, egal was ich eingebe.
Um etwas weiter auszuholen. Ich habe Werte als double gespeichert. Diese möchte ich nun als unsigned int interpretieren (aber nicht den genauen Wert, sondern (sozusagen) die Binärdarstellung davon). Nun führe ich damit verschiedene Dinge aus (z.B. Kompressionen). Beim zurückgewinnen, möchte ich nun also den exakten Wert von vorher zurück (und dieser sollte in der Regel auch ein wirklicher double Wert sein).
Da ich mich vorallem mit den Binärdarstellungen beschäftige, bringt mir ein static_cast gar nichts.
Ich weiß, daß die Werte in komp jeweils mit denen übereinstimmen, die ich auf dem Hinweg gewonnen habe (also nach dem reinterpret_cast<unsigned int*> und nun möchte ich dies einfach rückgängig machen.
Nur mit meiner Methode kommt wie bereits erwähnt immer:
2,64...e-308 heraus.
Da die Werte aber vorher verschieden waren, stimmt hier irgendetwas nicht.Florian
-
Vergleich doch einmal sizeof(int) und sizeof(double) - gut möglich, daß du den hinteren Teil des double's verschluckt (und auf dem Rückweg mit Datenmüll gefüllt) hast.
(aber daß immer der selbe Wert rauskommt, ist auch seltsam)
-
CStoll schrieb:
Vergleich doch einmal sizeof(int) und sizeof(double) - gut möglich, daß du den hinteren Teil des double's verschluckt (und auf dem Rückweg mit Datenmüll gefüllt) hast.
(aber daß immer der selbe Wert rauskommt, ist auch seltsam)
Ja das sind 4 und 8. Daran könnte es natürlich liegen, daß nicht exakt die Werte rauskommen, aber immer derselbe Wert?
-
Wenn ich bei der Konvertierung folgendes mache:
unsigned int *o; double original; o = reinterpret_cast<unsigned int*>(&original);Ist dann das double in o[0] und o[1] gespeichert?
-
Vermutlich ja.
-
Hallo,
für deinen Zeiger auf double steht nicht genug 'korrekten' Speicherplatz
zur Verfügung.
Nach dem Cast zeigt er auf die 4 Byte von unsigned int und auf weitere 4
undefinierte Byte im Arbeitsspeicher.Das bei dir immer der selbe Wert rauskommt, mag daran liegen, das die undefinierten 4 Byte den Exponenten auf einen ebenfalls undefinierten Wert setzen.
Von den 11 Bit für den Exponenten sind nämlich 2 Bit für NaN- und INF-Fälle vorgesehen, wenn diese gesetzt sind, kommt halt Ramsch raus.Wenn du vorher Speicher reservierst, indem du z.B. eine double variable
deklarierst und dann die Bits der unsigned int variable dort
reinkopierst, dann klappt das.
Es kommen Ergebnisse raus, die sich im Wertebereich von double bewegen.In c++ kenne ich keine Funktion, die man statt memcpy nehmen könnte:
int main() { double k = 0.0; unsigned int komp = 3258761612; memcpy( &k, &komp, sizeof(unsigned int) ); cout << k << endl; komp = 123176233; k = 0.0; memcpy( &k, &komp, sizeof(unsigned int) ); cout << k << endl; komp = 1538900071; k = 0.0; memcpy( &k, &komp, sizeof(unsigned int) ); cout << k << endl; return 0; }
-
proggingmania schrieb:
In c++ kenne ich keine funktion, die man statt memcpy nehmen könnte:
std::copy( )
...
-
kenner der dummköpfe schrieb:
proggingmania schrieb:
In c++ kenne ich keine funktion, die man statt memcpy nehmen könnte:
std::copy( )
...
Ja, sehr nett, aber für die Anwendung unbrauchbar

(um auf Byte-Ebene hantieren zu können, sind die passenden C-Funktionen doch ideal)@pm: Die Alternative wäre höchstens noch, einen int und double in einer union zu verstauen

-
kenner der dummköpfe schrieb:
proggingmania schrieb:
In c++ kenne ich keine funktion, die man statt memcpy nehmen könnte:
std::copy( )
...Klasse anonymer Mr. Schlaukopf und wie soll das in Form von Quelltext aussehen ?
Ich bekomme da:error C2782: '_OI __cdecl std::copy(_II,_II,_OI)' : Vorlagenparameter '_II' ist mehrdeutig
-
proggingmania schrieb:
int main() { double k = 0.0; unsigned int komp = 3258761612; memcpy( &k, &komp, sizeof(unsigned int) ); cout << k << endl; komp = 123176233; k = 0.0; memcpy( &k, &komp, sizeof(unsigned int) ); cout << k << endl; komp = 1538900071; k = 0.0; memcpy( &k, &komp, sizeof(unsigned int) ); cout << k << endl; return 0; }
Danke dafür. Nur noch eine Frage. Wenn ich nun den Hinweg anschaue, muss ich anscheinend mein double in 2 unsigned int speichern, richtig?
Wie kann ich diese beiden dann wieder zusammenführen?Also konkret würde ich jetzt so vorgehen:
double k = 1.2345; unsigned int komp*; memcpy( &komp, &k, sizeof(double) );So daß ich den double-Wert in komp[0] und komp[1] gespeichert habe.
oder wenn das nicht klappt:double k = 1.2345; unsigned int komp*; komp = reinterpret_cast<unsigned int*>(&k);Nur wie bekomme ich den Rückweg hin? Ich müßte ja jetzt komp[0] und komp[1] zurückführen nach k.
Florian
-
Wenn du die beiden int-Werte die ganze Zeit am Stück hältst, sollte der Rückweg eigentlich genauso klappen wie der Hinweg:
double dval; unsigned int ival[sizeof(double)/sizeof(int)]; dval=170.0; memcpy(ival,&dval,sizeof(double)); ... memcpy(&dval,ival,sizeof(double)); cout<<dval;
-
CStoll schrieb:
Wenn du die beiden int-Werte die ganze Zeit am Stück hältst, sollte der Rückweg eigentlich genauso klappen wie der Hinweg:
double dval; unsigned int ival[sizeof(double)/sizeof(int)]; dval=170.0; memcpy(ival,&dval,sizeof(double)); ... memcpy(&dval,ival,sizeof(double)); cout<<dval;Danke. Ich werde es mal versuchen einzubauen.
Florian
-
floriank schrieb:
double k = 1.2345; unsigned int komp*; memcpy( &komp, &k, sizeof(double) );pass auf mit sowas. du kopierst den inhalt von k hier in nicht allozierten speicher. vergleich das mit cstolls beispiel von eben.
-
thordk schrieb:
pass auf mit sowas. du kopierst den inhalt von k hier in nicht allozierten speicher. vergleich das mit cstolls beispiel von eben.
Viel schlimmer, er multipliziert eine Variablendefinition mit dem Ende der Zeile

*scnr*
-
naja, und eigentlich versucht er auch den inhalt von k dahin zu schreiben, wo die adresse von komp steht (wenn man mal annimmt, dass die zeile richtig wär). aber das sind spitzfindigkeiten

-
thordk schrieb:
floriank schrieb:
double k = 1.2345; unsigned int komp*; memcpy( &komp, &k, sizeof(double) );pass auf mit sowas. du kopierst den inhalt von k hier in nicht allozierten speicher. vergleich das mit cstolls beispiel von eben.
den Speicher habe ich schon alloziert:
komp = (unsigned int*) calloc(sizeof (unsigned int), 2);
-
yikes, warum schreibst nich einfach unsigned komp[2]; ?