Diese Version hört sich gut an, werds dann morgen mal probieren.Zitat von mare_crisium
Ist mir schon klar, aber mir reichen ja auch 24 bit. eigentlich brauch ich ja nur 18.
Werbung
Naja auf jeden Fall funktioniert es.Weil Unions nicht dafür gemacht sind, "a" reinzustecken und "b" rauszuholen.
Deine Methode ist sicher am edelsten, aber zum Verstehen am schwersten.Wenn du castest brauchst du auch keinen doppelten Speicher - und bei meiner Variante ebenfalls nicht
Ein Nachteil ist aber auch, dass sie nicht mit float, sondern nur mit int, int32_t und so was funktioniert, weil float keine Bitoperationen zulässt.
Ich würde C_Classic diese Methode aber trotzdem empfehlen, solange er kein float hat.
Diese Version hört sich gut an, werds dann morgen mal probieren.Zitat von mare_crisium
Ist mir schon klar, aber mir reichen ja auch 24 bit. eigentlich brauch ich ja nur 18.
@C_Classic:
Könnte so aussehen:Könntest du mir bitte erklären, wie diese union denn aussehen muss... hab noch nie damit gearbeitet.Danach kann man eine Variable var32 so deklarieren:Code:typedef union { uint32_t bits; struct { uint8_t byte_1; uint8_t byte_2; uint8_t byte_3; uint8_t byte_4; }; } fourbytes_t;
fourbytes_t var32;
Auf die einzelnen Bytes kann man so zugreifen (uint8_t var8:
Bytes auslesen: var8 = var32.byte_x;
Bytes schreiben: var32.byte_x = var8;
Gruß Dirk
Weil GCC laut Dokumentation sich wie erwartet verhält. siehe DokumentationZitat von _R2D2
Ist ein Cast auf einen entsprechenden Integertypen so schlimm?Zitat von _R2D2
mfG
Markus
EDIT: "GCC" aus dem Linktext entfernt, das Forum macht den Link sonst kaputt
Ich wusste nicht, dass das funktioniert, weil float das mit den Kommastellen und dem Bit für Vorzeichen (also negativ / positiv) ja etwas anders handhabt, wie ein int32_t (das ja gar keine Nachkommastellen haben kann), oder?Ist ein Cast auf einen entsprechenden Integertypen so schlimm?
Nach weiterer Recherche und einigen Experimenten mit GCC ziehe ich meine Aussage zum Cast zurück und behaupte das Gegenteil, natürlich kannst du float nicht auf Integer casten ohne dass dabei eine Typumwandlung oder abgrundtief verbotenes Type-Punning über Pointer stattfindet.![]()
Ich bin auf einen sehr guten Artikel zu dem Thema gestoßen, der die ganze Problematik sehr gründlich untersucht.
Ebenso wie hier kommt man zu dem Ergebnis, dass Type-Punning über Unions nicht wirklich dem Standard entspricht, aber unter GCC das Mittel der Wahl ist, um Daten ohne Typumwandlung zu reinterpretieren.
Unter letzerem Link ist übrigens auch ein Makro zu finden, dass das ganze vereinfachen soll, eine weitere Möglichkeit besteht darin, den Speicherbereich (via memcpy oder von Hand) zu kopieren, GCC sollte das gewünschte Vorhaben dann auch erkennen.
Ich fasse die gefundenen Ergebnisse noch einmal kurz zusammen:
Type-Punning über Unions ist im C-Standard undefiniert, über Pointertrickserei à la *(uint32_t *) &floatvariable sogar (strikt) verboten.
GCC definiert, um solche Operationen zuzulassen, dass Unions (wie man es eigentlich erwarten würde) "a rein, b raus" ermöglichen.
Aktiviert man den Compilerschalter "-fno-strict-aliasing" hat man den ganzen Stress auch nicht, dadurch werden aber einige Optimierungen unmöglich.
mfG
Markus
PS: Die Ursache des ganzen liegt in der Spezifikation von C(99), die verbietet dass zwei Pointer unterschiedlichen Typs beim dereferenzieren auf das gleiche Objekt verweisen.
Lesezeichen