Integer zu 16Bit-Zahl konvertieren



  • In der zweiten Zeile ist es

    0000 0001 1111 0100
    & 0000 0000 1111 1111
    ---------------------
      0000 0000 1111 0100
    

    In der dritten zeile wird dann geshiftet und dein b ist dann auf

    0000 0000 0000 0001
    

    und in der vierten zeile dann nochmal ein binäres &:

    0000 0000 0000 0001
    & 0000 0000 1111 1111
    ---------------------
      0000 0000 0000 0001
    

    Ergibt 244 für die erste Zahl und 1 für die zweite. Führende nullen vom int hab ich jetzt einfach mal weggelassen.



  • Dort wirds nichts verglichen, es ist eine Zuweisung! Die zweite Zeile macht ein bitweises UND mit dem Wert in Variable b und dem festen Wert 0x00FF. Wenn man sich 0x00FF in der binären Darstellung anguckt wie tkausl schon geschrieben hat sollte klar werden was die Zeile zu bedeuten hat. In der binären Darstellung sind nämlich genau die letzten 8 Bit gesetzt, daher werden in der Zeile nur die letzten 8 Bit von b nach byte1 kopiert. Dann wird b um 8 Bits nach rechts geschoben. Die ursprünglich letzten 8 Bit sind dann weg und es werden die nächsten 8 Bit nach byte2 kopiert. Als Übung empfehle ich dir mal zu überlegen wie man byte1 und byte2 wieder "zusammenbauen" kann, sodass du wieder den gleichen Wert wie in b erhälst (solange b maximal 16 Bit groß war).



  • DICKES DANKE! tkausls Darstellung und sebi707s erklärende Worte haben zusammen den Schalter bei mir umgelegt 🙂



  • Und warum der Umweg über zwei 8-Bit Zahlen?

    b &= 0xffff;
    


  • Warum nicht einfach casten?

    uint16_t b2 = (uint16_t)b;
    

  • Mod

    DarkShadow44 schrieb:

    Warum nicht einfach casten?

    uint16_t b2 = (uint16_t)b;
    

    Was passiert denn, wenn du den Cast weg lässt?



  • SeppJ schrieb:

    Was passiert denn, wenn du den Cast weg lässt?

    Dann muss man sich ne Standpauke vom Compiler von wegen "integer precision" anhören? Oder? 😃


  • Mod

    Finnegan schrieb:

    SeppJ schrieb:

    Was passiert denn, wenn du den Cast weg lässt?

    Dann muss man sich ne Standpauke vom Compiler von wegen "integer precision" anhören? Oder? 😃

    Das wäre an der Stelle eher ungewöhnlich. Kannst du einen Compiler nennen, der da warnt? Expliziter als so kann man kaum schreiben, dass man eine Konvertierung zu uint16_t wünscht.



  • SeppJ schrieb:

    Finnegan schrieb:

    SeppJ schrieb:

    Was passiert denn, wenn du den Cast weg lässt?

    Dann muss man sich ne Standpauke vom Compiler von wegen "integer precision" anhören? Oder? 😃

    Das wäre an der Stelle eher ungewöhnlich. Kannst du einen Compiler nennen, der da warnt? Expliziter als so kann man kaum schreiben, dass man eine Konvertierung zu uint16_t wünscht.

    Wenn man den cast wegläßt?
    Die Frage haste sicher überlesen. 😮



  • SeppJ schrieb:

    Finnegan schrieb:

    SeppJ schrieb:

    Was passiert denn, wenn du den Cast weg lässt?

    Dann muss man sich ne Standpauke vom Compiler von wegen "integer precision" anhören? Oder? 😃

    Das wäre an der Stelle eher ungewöhnlich. Kannst du einen Compiler nennen, der da warnt? Expliziter als so kann man kaum schreiben, dass man eine Konvertierung zu uint16_t wünscht.

    Nein, kann ich nicht. War mir nicht bewusst, dass die Zuweisung als so eindeutig gewollt durchgeht, daher auch das etwas unsichere "Oder?" :D.
    Ist mir bisher noch nicht aufgefallen, weil ich in meinem Code auch solche überflüssigen Casts immer hinschreibe - um im Code zu dokumentieren, dass es mit voller Absicht geschieht (immerhin könnten bei obigem Cast ein paar Bits flöten gehen).

    Finnegan



  • SeppJ schrieb:

    Finnegan schrieb:

    SeppJ schrieb:

    Was passiert denn, wenn du den Cast weg lässt?

    Dann muss man sich ne Standpauke vom Compiler von wegen "integer precision" anhören? Oder? 😃

    Das wäre an der Stelle eher ungewöhnlich. Kannst du einen Compiler nennen, der da warnt? Expliziter als so kann man kaum schreiben, dass man eine Konvertierung zu uint16_t wünscht.

    clang:

    foo.cpp:6:20: warning: implicit conversion loses integer precision: 'std::uint32_t' (aka 'unsigned int') to 'std::uint16_t' (aka 'unsigned short') [-Wconversion]
            std::uint16_t j = i;
                          ~   ^
    


  • VS auch ab Warning Level 4:

    warning C4244: 'initializing' : conversion from 'unsigned int' to 'uint16_t', possible loss of data
    

    Finde ich auch nicht verkehrt. Wenn man es so hinschreibt ist zwar ziemlich klar, dass es eine Konvertierung gibt aber wenn man Funktionen mit uint16_t als Parameter hat und dort einen int übergibt würde ich schon gerne eine Info kriegen.



  • DirkB schrieb:

    Und warum der Umweg über zwei 8-Bit Zahlen?

    b &= 0xffff;
    

    Welchen Datentyp muss b dann haben? unsigned int? Ich muss halt eine Zahl abspeichern, die genau 16 Bit hat. Und wenn ich diese nachher wieder auslese, sollen genau wieder 16 Bit gelesen werden. uint16_t funktioniert nicht, weil der Compiler dann irgendwie stresst.



  • uint16_t funktioniert nicht, weil der Compiler dann irgendwie stresst.

    Sehr genaue Aussage...

    #include <cstdint>
    


  • Hyde++ schrieb:

    uint16_t funktioniert nicht, weil der Compiler dann irgendwie stresst.

    Sehr genaue Aussage...

    #include <cstdint>
    

    Ja, sorry, ich schrieb den Beitrag, als ich nicht an einem der Uni-Rechner saß und deshalb die genaue Meldung nicht nachsehen konnte... cstdint habe ich eingebunden, aber genau da kommt dann eben die Meldung. Die lautet:

    error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options

    Da ich von Linux und Compilern und whatever nicht so viel Ahnung habe, weiß ich nicht, wo ich das hinschreiben müsste. Dies ist mein Makefile:

    CXX = g++
    CXXFLAGS = -O2 -Wall 
    
    ma5b: unit.o mapraview.o greyscale.o 
    	$(CXX) $(CXXFLAGS)  unit.o mapraview.o greyscale.o -o ma5b   
    
    greyscale.o: unit.h greyscale.h greyscale.cpp   
    	$(CXX) $(CXXFLAGS) -c greyscale.cpp 
    
    mapraview.o: unit.h greyscale.h greyscale.cpp mapraview.cpp 
    	$(CXX) $(CXXFLAGS) -c mapraview.cpp 
    
    .PHONY: clean 
    clean: 
    	rm greyscale.o mapraview.o
    

    Wo und wie würde ich jetzt diese Compiler Options hinzufügen müssen? Das Paket habe ich in die greyscale.cpp eingebunden.


  • Mod

    wocknwolla schrieb:

    Wo und wie würde ich jetzt diese Compiler Options hinzufügen müssen? Das Paket habe ich in die greyscale.cpp eingebunden.

    Einfach in der 2. Zeile CXXFLAGS ergänzen.



  • Und zwar:

    -std=c++11
    

Anmelden zum Antworten