Signed to Unsigned int



  • Hallo Leute,

    ich habe eine int zahl, z.B.: 111101101111
    Diese soll als -145 interpretiert werden,
    aber sie wird als 3951 interpretiert, da er nicht erkennt, dass es eine negative Zahl ist.

    Nur leider weiß ich nicht, wie ich das hinbekomme ...

    Könnt ihr mir helfen ?


  • Mod

    C++_Greenhorn schrieb:

    Könnt ihr mir helfen ?

    Nein, denn du redest wirres Zeug.
    Wie man Fragen richtig stellt



  • Ich nehme an, dein Problem sieht so in die Richtung aus:

    int zahl = 0b111101101111;
    

    Ein int ist (zumindest bei mir) ein 32-bit signed Integer. Daher sehen nach dieser Zuweisung die Bits von zahl so aus:
    00000000000000000000111101101111

    Als eine negative Zahl kann das niemals interpretiert werden, weil die vorderen Einsen fehlen. So sollte die Zahl korrekt aussehen:

    11111111111111111111111101101111

    Danns wirds auch korrekt als -145 interpretiert.

    Kannst du uns deinen Code zeigen? Der genaue Lösungsansatz bezieht sich stark darauf, wie dein Problem genau zustande kommt.



  • Hallo Singender Holzkübel ,

    danke für deine Antwort.

    Einen direkten Code hab ich nicht,
    es könnte so aussehen:

    void SignalKommt(tU32 u32Value){
    cout << "Value: " << u32Value << endl;
    
    }
    

    Die funktion wird von alleine aufgerufen, sobald Daten auf dem CAN vorliegen.

    Diese Daten simuliere ich momentan und habe zu Testzwecken die Zahlen 182 und -145 gesendet.

    Bei der 182 kommt auch diese raus, aber bei der -145 kommt 3951 aus.
    Er erkennt nicht, dass eigentliche eine negative Zahl ankommt.

    ich denke ich kann es überprüfen, indem ich den RohWert abfrage.
    0x800 ist ungültig, also sind alle Werte über 0x800 negativ, aber
    wie bekomme ich jetzt den Wert von der Zahl ??? 😕 😕



  • Du hast also 12 Bit Zahlen (inklusive Vorzeichen)? Das ist ja doof.



  • Ich denke, was du suchst, ist das Zweierkomplement ???

    Wie man das aber programmiert, muss ich auch passen ...
    Vielleicht haben die anderen eine Idee



  • Hallo manni66 ,

    jap, genau das habe ich 😕 😕

    @EmbSofti

    Ja, ich denke genau das suche ich.
    Auf dem Papier funktioniert es, aber wie programmieren ?
    Zumal eben die blöden restlichen Stellen aufgefüllt werden 😕 😕



  • Die Zahl befindet sich bereits im Zweierkomplement, nur werden aus irgendeinem Grund die voranstehenden Bits verworfen.
    Es scheint mir, als würde der Integer zu den least significant 12 bit abgeschnitten und dann wieder in einen i32 konvertiert werden.

    Was ist denn dieses CAN von dem du geredet hast, und wie werden die Daten davon gelesen?

    Schau auch mal ob der Rohwert stimmt.



  • Hallo,

    ein CAN ist ein Controller Area Network, ein Bussystem, mit dem Daten übertragen werden können.

    soweit ich weiß, werden die Daten intern in hex gehändelt und zum verschicken, bekommen sie den Datentyp, der in der jeweiligen Spezifikation steht.
    Bei mir sind es 12 Bit signed integer.
    davon ist 0x800 die ungültigkeitsbezeichnung.

    ich hab irgendwie das problem, dass wer auch immer - BS, compiler ... - nicht erkennt, wenn eine negative binär/hexzahl ankommt 😞

    Der Rohwert bei meiner Simulation ist -145 und dieser Rohwert sollte bei mir auch ankommen, aber es kommt als Rohwert leider 3951 raus 😞



  • Naja, das geht ganz genauso wie auf dem Papier. Das MSB hat im Gegensatz zu den restlichen Bits negatives Vorzeichen, das ist alles.

    if (value&(1<<(value_bits-1)))value-=(1<<value_bits);
    


  • Ich fürchte hier geht mal wieder interne Repräsentation der Zahlen und Art der Darstellung durcheinander. Intern werden alle Zahlen binär im Speicher hinterlegt. Bei der Ausgabe kann man dann die Zahl Dezimal oder Hexadezimal oder was auch immer darstellen. Wenn du sagst die Zahlen werden nach Hex geändert glaube ich das fast nicht. Wird die Zahl wirklich in einen String der 3 Hex Zeichen hält konvertiert und diese 3 Zeichen dann übertragen? Oder werden doch eher 2 Byte binär übertragen? Am besten zeigst du uns mal den Code der die Daten über CAN versendet und wieder einlesen soll.



  • Und wieder jemand, der keinen (bzw. kaum) Plan von CAN hat...

    CAN-Daten bestehen einfach aus einer Folge von 1-8 Bytes und die Interpretation der Daten wird entsprechend der PGN (parameter group number) durchgeführt (zumindestens bei J1939 und ISOBUS).

    Wie soll auch jemals eine negative Zahl in der Funktion ankommen, wenn du den Parameter als unsigned deklarierst (ich nehme mal an tU32 steht für 'unsigned int 32'?

    Am besten bietet sich dafür dann ein Bitfeld an (je PGN), welches du dann aus den ankommenden Daten entsprechend umwandelst (castest).



  • Hallo th69,

    ja, ich habe wenig Ahnung vom CAN, da ich gerade erst damit beginne mich damit zu beschäftigen. ⚠

    Ja, das war auch mein Problem.
    Die Daten vom CAN werden über eine firmeninterne API empfangen und ich erhalte die Daten als tU32, was ich ebenfalls doof finde.

    d.h. aber, dass ich es selber umwandeln muss, aber ich weiß noch nicht wie 😞



  • C++_Greenhorn schrieb:

    d.h. aber, dass ich es selber umwandeln muss, aber ich weiß noch nicht wie 😞

    -> in signed speichern -> Stellenwert des MSB verrechnen.
    Wie oft soll man dir das noch erklären bis du aufhörst, die gleiche Frage zu stellen?



  • Wie gesagt, benutze ein Bitfeld, z.B.

    struct MyData
    {
      // evtl. noch mit Paddingdaten (Bits) auffüllen, z.B. int padding:20
      int data:12;
    };
    
    MyData myData = (MyData)u32Value;
    
    int value = myData.data;
    

    Mit welchem CAN-Protokoll arbeitest du denn?



  • Hallo,

    hab gerade meinen Kollegen gefragt, der weiß es auch ned genau:
    entweder CanOpen oder J1939.



  • GiraffeTurboSetzen schrieb:

    C++_Greenhorn schrieb:

    d.h. aber, dass ich es selber umwandeln muss, aber ich weiß noch nicht wie 😞

    -> in signed speichern -> Stellenwert des MSB verrechnen.
    Wie oft soll man dir das noch erklären bis du aufhörst, die gleiche Frage zu stellen?

    Wie oft muss ich das noch erklären, dass ich eine binäre Zahlenfolge als int übergeben bekomme, mit der dieser Befehl nicht funktioniert ???



  • C++_Greenhorn schrieb:

    Wie oft muss ich das noch erklären, dass ich eine binäre Zahlenfolge als int übergeben bekomme, mit der dieser Befehl nicht funktioniert ???

    Was soll daran nicht funktionieren?

    Naja, hat kein Wert mit jemandem zu diskutieren, der nicht lernfähig ist.
    Bitte lass das einfach mit dem Programmieren.



  • C++_Greenhorn schrieb:

    Wie oft muss ich das noch erklären, dass ich eine binäre Zahlenfolge als int übergeben bekomme, mit der dieser Befehl nicht funktioniert ???

    Es funktioniert. Rechne doch einfach nach. Wenn das elfte Bit gesetzt ist (ist in deinem Beispiel) wird von der Zahl 2^12 = 4096 abgezogen. Jetzt setzen wir ein: 3951-4096 = −145. Also genau was du möchtest. Musst du natürlich mit signed ints rechnen.



  • @ sebi707
    Danke für deine kurze Rechnung! Die hat es mir einfacher gemacht,
    GiraffeTurboSetzen's Idee nachzuvollziehen. Jetzt habe ich einen lauffähigen Code,der mit Dezimalzahlen genau diese Idee umsetzt.

    @GiraffeTurboSetzen
    Ggf. habe ich mich umständlich ausgedrückt, daher will ich das Problem nochmal
    genauer beleuchten.
    Ich bekomme von meinem Bus eine Integer-Zahl, die jedoch keine übliche
    Interpretation zulässt. Wenn ich ein int value = 0110 bekomme, versteht in diesem
    Fall mein Interpreter durch die vorangestellt „0“ einen Hexadezimal-Wert und würde
    mir bei einer Ausgabe ohne weiteres Zutun den Wert 272 (also 0x0110 zu 272
    dezimal) ausgeben. Habe ich keine führende Null besteht das Problem
    beispielsweise nicht, aber trotzdem hätte ich z.B. bei einem int value = 1100 eben
    dezimal den Wert 1100, obwohl ich diesen als 0b110 = 12 dezimal verarbeiten muss.
    Hierfür konnte ich mir durch geeignetes maskieren eine Funktion schreiben, die
    diese Problem löst.
    Der Knackpunkt war für mich der Fall, wenn ein int value = 1100 als
    vorzeichenbehaftete Binärzahl im Zweierkomplement interpretiert werden sollte. Wie
    das jetzt umgerechnet wird, war mir auf dem Papier klar, jeoch habe ich es nicht in
    Code umsetzen können, wie ich aus dem Zweierkomplement 0b1100 (aber immer
    noch dezimal 1100 für den Interpreter!) auf den Dezimalwert -4 komme. Wenn ich in
    deine (GiraffeTurboSetzen) genannte if-Abfrage für value = 1100 und für value_bits =
    4 einsetze, dann stünde ausgerechnet folgendes da:

    if ( 8 ) {
    value = 1084;
    }
    

    und das ist mitnichten das Ergebnis, das ich erhofft hatte.
    Wie gesagt, die Idee ist die richtige, jedoch hast du mein Problem nicht richtig
    erkannt…

    Jedoch schlage ich dir bei deinem Tonfall vor, das Schreiben in Foren sein zu lassen, wenn du Leute, die sich momentan nicht sofort richtig artikulieren können und einfach den Wald vor lauter Bäumen nicht sehen, so scharf runtermachst. ⚠ ⚠


Log in to reply