4Byte little Endian als unsigned long



  • Hi zusammen ich will aus ner Datei 4Byte auslesen welche nach little Endian dann wieder ein long geben sollten.
    Ich versuch es so:

    //Little Endian
    		for (unsigned long i=0; i<laenge-1;i++)
    		{ 
    			pData[i] = pBuffer[laenge-i-1]; 
    		}
    
    		unsigned long Longwert_Block = (unsigned long)(unsigned char)pData;
    

    aber da kommt definitiv nicht das richtige raus. wenn ich das mit dem Hexedit anschau dann sieht es in etwa so aus:

    9E 1F 02 00

    also Little Endian

    00 02 1F 9E

    nimm ich das jetzt dezimal krieg ich 139166 ud das ist genau die Zahl die ich will!
    Wie bekomm ich die?
    Für genanntes Beispiel gibt gezeigte FKT 192 aus.



  • was steht in pData, was steht in pBuffer was ist l und vor allem: was zur ... ist das:

    unsigned long Longwert_Block = (unsigned long)(unsigned char)pData;
    

    ?



  • #include <iostream>
    using namespace std;

    so hab aber mal ein wenig rumgebastelt (ja, mit c++ cast's). muesste zu gebrauchen sein:

    int main()
    	{
    	long x=0x12345678,y=0;
    	char	*ptrX=reinterpret_cast<char*>(&x),
    			*ptrY=reinterpret_cast<char*>(&y);
    	int i=0;
    
    	cout.setf(ios::showbase|ios::uppercase);
    	cout<<hex;
    
    	while (i++<sizeof(long))
    		*(ptrY+sizeof(long)-i)=*ptrX++;
    
    	cout<<x<<'\n'<<y<<endl;
    
    	return 0;
    	};
    


  • die include anweisung gehoert natuerlich mit in den c++-code tag 😃



  • Cpt.Tanga schrieb:

    was steht in pData, was steht in pBuffer was ist l und vor allem: was zur ... ist das:

    unsigned long Longwert_Block = (unsigned long)(unsigned char)pData;
    

    ?

    Also am besten mal die ganze FKT:

    unsigned long laenge = BlockEndbyte - BlockStartbyte+1;
    		if (BlockEndbyte < BlockStartbyte)
    			return FALSE;
    		// Puffer anlegen und Datei einlesen. 
    		char* pBuffer = new char[laenge]; //Göße des Puffers
    		Wavefile.seekg(BlockStartbyte); //geh an die Startposition
    		Wavefile.read(pBuffer, laenge); //einlesen (binär)
    		char* pData = new char[laenge]; //neuen Puffer
    		//Little Endian
    		for (unsigned long i=0; i<laenge-1;i++)
    		{ 
    			pData[i] = pBuffer[laenge-i-1]; 
    		}
    		unsigned long Longwert_Block = (unsigned long)(unsigned char)pData;
    		// Nachher wieder aufräumen. 
    		delete [] pBuffer;
    		delete [] pData;
    
    		return Longwert_Block;
    

    Das hier:

    unsigned long Longwert_Block = (unsigned long)(unsigned char)pData;
    

    war ein versuch! 😃

    Um meinen ersten Post noch mal verständlicher zu machen ich will nur die Dezimalzahl, das hex gedöhns ist nur dass ihr wisst wie ich auf die zahlen komm.

    @ Captain Tanga deine casts versteh ich nicht, vielleicht ist das ja schon das wonach ich suche, doch weiß ich nicht was da passiert und will es drum nicht einfach rein klatschen. Kannst du mir das vielleicht erklären?



  • Polofreak schrieb:

    Um meinen ersten Post noch mal verständlicher zu machen ich will nur die Dezimalzahl, das hex gedöhns ist nur dass ihr wisst wie ich auf die zahlen komm.

    Dezimal und Hex sind nur Darstellungsarten. Du willst den Wert.

    unsigned long Longwert_Block = *(reinterpret_cast<unsigned long*>(pData));
    


  • sehe ich das falsch oder willst du pData (welches eventuell deutlich groesser ist als ein long) auf ein einfaches long casten? -und willst du den gesamten block auf little endian oder jeweils nur den block long-laengen weise auf little endian bringen?



  • Cpt.Tanga schrieb:

    sehe ich das falsch oder willst du pData (welches eventuell deutlich groesser ist als ein long) auf ein einfaches long casten? -und willst du den gesamten block auf little endian oder jeweils nur den block long-laengen weise auf little endian bringen?

    Das siehst du richtig. Aber es ist irrelevant ob pData > sizeof(long). Und um die Endianess muss man sich auch keine Gedanken machen, wenn die Daten in pData eh schon als Little Endian abgelegt sind.



  • Also das ist zwar nicht sonderlich schön und schnell aber hier mal ein Beispiel:

    #include <iomanip>
    #include <algorithm>
    #include <iostream>
    
    struct my_conv
    {
      enum{ulongsize = sizeof(unsigned long) };
      union
      {     
        unsigned long number;
        char          str[ulongsize];
      };
      void reverse()
      {
        std::reverse(str,str+ulongsize);     
      }
      void print()
      {
        std::cout << "0x" 
                  << std::setw(8) 
                  << std::setfill('0') 
                  << std::hex 
                  << number 
                  << std::endl;
      }
    };
    
    int main()
    {
      my_conv conv;
      conv.number = 139166;
      conv.print();
      conv.reverse();
      conv.print();
      conv.reverse();
      conv.print();
    }
    


  • Cpt.Tanga schrieb:

    sehe ich das falsch oder willst du pData (welches eventuell deutlich groesser ist als ein long) auf ein einfaches long casten? -und willst du den gesamten block auf little endian oder jeweils nur den block long-laengen weise auf little endian bringen?

    Ja ich will pData welches evtl. wesentlich größer als ein long ist auf unsigned long casten. das mit dem little Endian ist so, dass ich immer wieder blöcke (4Byte) little Endian hab und dann wieder ein paar bigEndian.
    Aber dank MFK geht es jetzt. Aber es ist irgendwie komisch, weil ich muss meine Daten nicht drehen. so wie oben die Hexdarstellung meiner Daten, ich mach einfach

    unsigned long laenge = BlockEndbyte - BlockStartbyte+1;
    		if (BlockEndbyte < BlockStartbyte)
    			return FALSE;
    		// Puffer anlegen und Datei einlesen. 
    		char* pBuffer = new char[laenge]; //Göße des Puffers
    		Wavefile.seekg(BlockStartbyte); //geh an die Startposition
    		Wavefile.read(pBuffer, laenge); //einlesen (binär)
    		unsigned long Longwert_Block = *(reinterpret_cast<unsigned long*>(pBuffer));
    		// Nachher wieder aufräumen. 
    		delete [] pBuffer;
    		return Longwert_Block;
    

    Das wars schon und ich bekomm meine (in diesem Beispiel Chunksize) zurück.
    VIELEN DANK ERST MAL AN EUCH ALLE!
    Aber kann mir einer erklären warum ich das von Hand im Hexeditor umdrehen muss und so nicht?



  • Polofreak schrieb:

    Aber kann mir einer erklären warum ich das von Hand im Hexeditor umdrehen muss und so nicht?

    weiss zwar nicht wiso ich das noch poste aber wenn man einfach ein char feld (0-terminiert) umkehren will so wie es fuer mich den anschein hat (es sei denn ich habs immer noch nicht verstanden 😃 ) wuerde ich es so machen - mit meiner guten alten reverse funktion:

    void reverse(char *s)
    	{
    	if (!*s) return;
    	char *e=s,*b=s,t;
    	while (*++e);e--;
    	while (b<e)
    		{
    		t=*b;
    		*b++=*e;
    		*e--=t;
    
    //		(*e)^=(*b)^=(*e--)^=(*b++);			//sollte schneller sein -aber die compiler machen da meist nich mit
    		};
    	};
    


  • Keine Ahnung ob ich den nu umdrehen muss oder nicht, weil (siehe letzen Post) es geht ohne wenn ich mir aber die Daten von Hand anschau muss ich schon reversen. Der kann doch gar nicht wissen ob das nu little oder Big Endian ist, oder??

    Zu deinem Code, ich versteh wieder nur Bahnhof!!!



  • Polofreak schrieb:

    Keine Ahnung ob ich den nu umdrehen muss oder nicht, weil (siehe letzen Post) es geht ohne

    Du musst nicht umdrehen, weil die Plattform, auf der du arbeitest, Little Endian ist. Genau so, wie du es im Hexeditor siehst (mit dem höchstwertigen Byte vorn), wird ein unsigned long auf einer Little-Endian-Plattform im Speicher abgelegt.



  • die funktion dreht einfach einen string rum (geht diesen von hinten und vorne durch und vertauscht beide werte, bis zur mitte - grob gesagt).

    Polofreak schrieb:

    Der kann doch gar nicht wissen ob das nu little oder Big Endian ist, oder??

    nein aber das kann er auch nicht. fuer eine funktion sind das alles einfach daten - egal ob big oder little endian. -kommt auch darauf an nach welchen kriterien du auswaehlst ob du daten umkehrst oder nicht.



  • OK ich befriedige mich jetzt mit der Aussage

    MFK schrieb:

    Du musst nicht umdrehen, weil die Plattform, auf der du arbeitest, Little Endian ist.

    Auch wenn ich es im Hexeditor anders seh.

    Vielen lieben Dank!!!



  • Polofreak schrieb:

    OK ich befriedige mich jetzt mit der Aussage

    MFK schrieb:

    Du musst nicht umdrehen, weil die Plattform, auf der du arbeitest, Little Endian ist.

    Auch wenn ich es im Hexeditor anders seh.

    Das täuscht, Du sagtest:

    Polofreak schrieb:

    aber da kommt definitiv nicht das richtige raus. wenn ich das mit dem Hexedit anschau dann sieht es in etwa so aus:

    9E 1F 02 00

    Das ist aber 0x21F9E (dezimal 139166) als Little-Endian-4-Byte-Long. Also liegt hier eher eine Verwirrung vor. Endianess betrifft nur die Reihenfolge der Bytes im Speicher, nicht den Wert der Zahl als Long. Du willst also nicht, das die Bytes im Speicher in der Reihenfolge 00 02 1F 9E liegen, sondern das sie den Wert 0x00021F9E darstellen, und das tun sie auf einer Little-Endian-Maschine in der von Dir im Hex-Editor gesehenen Reihenfolge schon. Also alles grün! 👍



  • Juhu alles in Pologrün! 😃

    Danke für die Aufklärung


Anmelden zum Antworten