float: bytes einzeln auslesen und in integer verwandeln ?
-
Hi,
ich habe einen buffer mit 10 float Werten.
Dieser Buffer wird einmal ausgelesen und kann nicht einzeln
übergeben werden. Also alle 10 floats kommen mit einem Schwung.Nun kommt es aber vor, das der ausgelesene buffer als erstes
eine integer Zahl besitzt, die eine Art Index darstellt.
Dieses erkenne ich an einem bestimmten Flag, das in diesem Buffer ist.
Nachdem ich aber beim Auslesen nur floats nehmen kann, muss ich
aus den 4 bytes des floats einen integer mit ebenfalls 4 bytes machen.
Ich möchte also die 4 bytes des floats 1:1 in die 4 possitionen des
Integers kopieren.nur wie ? es handelt sich hier nicht um casten oder "=".
float a; int b; b[0]=a[0]; b[1]=a[1]; b[2]=a[2]; b[3]=a[3];oder kann man das mit Zeigern machen ? wie ?
Gruß
thenoname
-
Kurz und knackig - standardkonform lässt sich das nicht lösen.
Es gibt für jede Plattform, jeden Compiler etc. immer Mmittel und Wege das hinzubekommen, aber der Sprachstandard legt kein speicherinternes Format für Floats/Integers fest.
Außerdem erscheint mir das "Protokoll", das du da entworfen hast nicht besonders gut. Du rätst anhand eines Flags eine bestimmte Bedeutung. Was ist, wenn dieses Flag auch in den Daten vorkommt?
Hast du dieses Protokoll denn selbst entworfen oder ist es Vorgabe? Erklär doch mal bitte ein bisschen genauer, was du vorhast, dann wirst du auch geholfen.

-
man kann doch aber sowas machen, falls es das is, was du meinst
// flag ist im buffer -> index auslesen: float bufer[10]; int index = *((int*)(&buffer[0]));also die addresse des ersten floats wird als zeiger auf einen int interpretiert und dann nach int dereferenziert.
ich glaub mit nem c++-cast wie reinterpret_cast oder so geht das auch
-
Hi,
Maxi, das ist es !!
Ich glaube es ist keine Schande, wenn ich solch einen Aufbau
mit der Referenziererei noch nicht ganz verstehe ?Leider ist die Bufferübergabe in der Tat etwas Bescheiden aufgebaut.
In dem ersten float wird das Flag mitgeliefert, ab dem zweiten beginnt dann
das Datenpacket. Nachdem man sich bei der Übergabe allerdings vorher ent-
scheiden muss, was für eine Struktur man benutzt, wird es kompliziert.
Der Erfinder hat wohl damit gerrechnet, das man aus den einzelnen
bytes dannach seine floats zusammenbastelt.Ich denke das wäre dann so möglich ?
bytes[4]={1,2,3,4}; float wert = *((float*)(&bytes));Wird bei der Referenziererei dann eigentlich eine "virtuelle" float erzeugt,
diese mit dem &bytes gefüllt und dann =wert gesetzt ?
-
Hallo,
vielleicht wird Maxis' Code mit einem C++-Cast leichter zu verstehen sein:
// flag ist im buffer -> index auslesen: float buffer[10]; int index = *(reinterpret_cast<int*>(&buffer[0]));Es wird hier die Speicherstelle &buffer[0] nach *int umgewandelt, sodass int index dann von dem Anfang des Arrays sizeof(int) Bytes ausliest (Zeigerarithmetik).
Gruß Borschtsch
-
Hmm, reicht für diese Methode nicht ein static_cast? reinterpret_cast müsste man doch nur nehmen, wenn man float (nicht float*) casten will:
float buffer[10]; int index = *(static_cast<int*>(&buffer[0])); // 1. index = reinterpret_cast<int> (buffer[0]); // 2. VIEL kürzer
-
.filmor schrieb:
Hmm, reicht für diese Methode nicht ein static_cast? reinterpret_cast müsste man doch nur nehmen, wenn man float (nicht float*) casten will:
float buffer[10]; int index = *(static_cast<int*>(&buffer[0])); // 1. index = reinterpret_cast<int> (buffer[0]); // 2. VIEL kürzerdas dürfte kein compiler akzeptieren. ein static_cast anstelle des reinterpret_cast wäre möglich, hat aber einen ganz anderen als den gewünschten effekt. ein reinterpret_Cast ist in jdem falle nötig (es sei denn man geht den umweg über void*). denkbar ist:
float buffer[10]; int index = reinterpret_cast<int&>(buffer[0]); index = *reinterpret_cast<int*>(&buffer[0]);letzlich handelt es sich immer um implementationsspezifisches verhalten.
-
Hi!
Casts sollten, wann es nur geht, vermieden werden. Daher wäre wohl eine Möglichkeit vorzuziehen die ohne "rumcasten" funktioniert.
union flint { float fValue; int nValue; }; int main( void ) { float f[] = { 10.0f, 20.0f, 30.0f }; flint p; for ( int i = 0; i < 3; ++i ) { p.fValue = f[ i ]; std::cout << p.nValue << std::endl; } return 0; }Etwas das in diese Richtung geht wäre z.B. möglich.
grüße
-
David_pb schrieb:
Casts sollten, wann es nur geht, vermieden werden. Daher wäre wohl eine Möglichkeit vorzuziehen die ohne "rumcasten" funktioniert.
Und was ist an type-punning besser als an Casten? Zumal solche "union-casts" nicht spezifiziertes Verhalten haben.
Du versteckst nicht nur den (Reinterpret-)Cast, der sowieso durchgeführt wird, sondern du nimmst dem Compiler jede Möglichkeit dich über Fehler zu informieren.