bit shifting
-
hi
hätte mal eine frage zum bit shifting. und zwar habe ich vier werte:
0x0 - 0x0 0x10 0x40
Diese sind in einem char-array definiert und sollen jetzt in einen float konvertiert werden. nach meiner überlegung sollte es so aussehen (little endian):float wert = { 0x0 << 4 | 0x0 << 8 | 0x10 << 16 | 0x40 << 24 };das ergebnis muss genau 1 sein... kann mir einer erklären was ich falsch mache und warum? stehe etwas auf dem schlauch
-
Das hier:
{ 0x0 << 4 | 0x0 << 8 | 0x10 << 16 | 0x40 << 24 }ist ein (unsigned) integer. Und mit den Bits, die Du da setzt, kenne ich keine Darstellung, die da eine 1 ergeben würde.
-
fkrauthahn schrieb:
float wert = { 0x0 << 4 | 0x0 << 8 | 0x10 << 16 | 0x40 << 24 };Das
<< 4sieht da nicht ganz richtig aus. Abgesehen davon bekommst Du einen float, der der Ganzzahl (0x40100000) entspricht und nicht 1.Probier mal folgendes:
#include<iostream> #include<string.h> #include<stdint.h> int main() { uint32_t i = 0x3F800000; float f; memcpy(&f,&i,sizeof(f)); std::cout << f << '\n'; }Warnung: Das Verhalten ist "implementation defined". Es funktioniert nicht auf jeder Maschine. Der C++ Standard schreibt nicht vor, dass "float" die IEEE 754 32bit Fließkommazahl-Repräsentierung benutzen muss. Außerdem, könnte es sein, dass die Byteordnung zwischen Ganzzahlen und Fließkommazahlen inkompatibel ist.
Um Dich diesbezüglich abzusichern, kannst Du noch Unit-Tests schreiben und/oder einige der C++-Implementierungseigenschaften über die Header <climits> und <limits> (std::numeric_limits<>) erfragen.
Gruß,
SP
-
hi,
sorry, 0x1040 war der falsche wert, es muss 0x803F0000 sein. ich, frkauthahn bin halt etwas sehr doof.
-
das problem ist halt, dass ich die daten in einem char-array habe. außerdem funzt der code von dir nicht, kommt 1.#QNA oder so raus.
-
fkrauthahn schrieb:
das problem ist halt, dass ich die daten in einem char-array habe.
In welchem Format denn? Im nativen Format Deiner Maschine? Du kannst natürlich per memcpy ein float zu char[sizeof(float)] kopieren und wieder zurück. Das ist garantiert lauffähig und verlustfrei, da eines von beiden ein char array ist und beide Typen Skalare sind. Du darfst Dich aber nicht darauf verlassen, dass wenn Du ein float auf einer Maschine zu char[] konvertierst und auf einer anderen wieder zu float konvertierst, dass da noch das gleiche herauskommt.
fkrauthahn schrieb:
außerdem funzt der code von dir nicht, kommt 1.#QNA oder so raus.
Bei mir geht es (EMT64T-Architektur im 32bit Modus unter Linux, sizeof(uint32_t)==sizeof(float), std::numeric_limits<float>::is_iec559==true).
Gruß,
SP
-
ok, danke danke. ich habe btw 64 bit vista...
In welchem Format denn?
? ich habe die dezimalwerte von den hex-werten. bzw ist der char ein buffer, in den der komplette inhalt einer binären datei kommt.
Im nativen Format Deiner Maschine?
ja.
Du darfst Dich aber nicht darauf verlassen,...
ist da die little- bigendian formatierung mit inbegriffen?
ich versuche das mal mit dem memcpy.
-
fkrauthahn schrieb:
0x0 << 4 | 0x0 << 80 um 4 oder 8 oder irgendwas zu shiften macht nicht wirklich Sinn.
-
Mal abgesehen davon sind die 4 unteren Bits immer 0. Ob das so richtig ist?