Ich habe zwei 16-Bit-Kurzschlüsse (s1 und s2), und ich versuche, sie zu einer einzigen 32-Bit-Ganzzahl (i1) zu kombinieren. Entsprechend der Spezifikation, mit der ich es zu tun habe, ist s1 das signifikanteste Wort, und s2 ist das am wenigsten signifikante Wort, und das kombinierte Wort scheint unterschrieben zu sein. (d. h. das oberste Bit von s1 ist das Vorzeichen.)
Was ist der sauberste Weg, um s1 und s2 zu kombinieren?
Ich dachte mir etwas wie
%Vor%würde es tun, und es scheint zu funktionieren, aber ich mache mir Sorgen, dass ich um 16 eine Linkskurve wechseln könnte.
Ich bin auch an der Idee interessiert, eine Gewerkschaft zu benutzen, um zu arbeiten, irgendwelche Gedanken darüber, ob das eine gute oder eine schlechte Idee ist?
Was Sie tun, ist nur dann sinnvoll, wenn die Shorts und der Int alle nicht signiert sind. Wenn eine der Kurzzeichen signiert ist und einen negativen Wert hat, ist die Idee, sie zu einem einzigen int zu kombinieren, bedeutungslos, es sei denn, Sie haben eine domänenspezifische Spezifikation erhalten, um eine solche Möglichkeit abzudecken.
Was Sie haben, sieht fast korrekt aus, wird aber wahrscheinlich fehlschlagen, wenn der zweite Teil negativ ist; Die implizite Umwandlung in int wird wahrscheinlich die obigen 16 Bits vorzeichenerweitern und mit Einsen füllen. Eine Umwandlung in unsigned short würde das wahrscheinlich verhindern, aber der beste Weg, um sicher zu sein, ist das Maskieren der Bits.
%Vor%Ich weiß, dass dies ein alter Beitrag ist, aber die Qualität der vorliegenden geposteten Antworten ist bedrückend ...
Dies sind die zu beachtenden Punkte:
int
, der signiert ist. Dies geschieht unabhängig von der Signedness des kleinen Integer-Typs. Integer-Promotion findet in den Schichtoperationen und im bitweisen OR statt. Eine richtige Lösung wird daher:
Es wird so aussehen:
%Vor%Jede andere Lösung ist sehr fragwürdig und im besten Fall nicht portabel.
Sie möchten data.first zunächst auf ein int32-Objekt umwandeln, bevor Sie die Verschiebung vornehmen. Andernfalls wird die Verschiebung den Speicher überlaufen lassen, bevor die Chance besteht, dass sie automatisch heraufgestuft wird, wenn sie kombinierten Daten zugewiesen wird.
Versuchen Sie:
%Vor%Dies setzt natürlich voraus, dass data.first und data.second Typen sind, die garantiert genau 16 Bit lang sind, sonst haben Sie größere Probleme.
Ich verstehe Ihre Aussage wirklich nicht "wenn Daten.Sekunde zu groß wird, wird die | Tatsache nicht berücksichtigt, dass sie beides sind."
Edit: Und Neil hat absolut recht, wenn es um Signiertheit geht.
Die Verwendung einer Union zur Ausführung des Jobs scheint eine gute Wahl zu sein, ist aber aufgrund von Endian-Unterschieden der Prozessoren ein Problem der Portabilität. Es ist machbar, aber Sie müssen bereit sein, Ihre Verbindung basierend auf der Zielarchitektur zu ändern. Bit-Shifting ist portabel, aber bitte schreiben Sie eine Funktion / Methode, um es für Sie zu tun. Inline, wenn Sie möchten.
Was die Signiertheit der Kurzformen betrifft, ist für diese Art von Operation die Bedeutung wichtig, nicht der Datentyp. Mit anderen Worten, wenn s1 und s2 als zwei Hälften eines 32-Bit-Worts interpretiert werden sollen, hat das Setzen von Bit 15 nur dann eine Bedeutung, wenn Sie etwas tun, das bewirkt, dass s2 vorzeichenerweitert wird. Siehe Mark Ransoms Antwort, die besser sein könnte als
%Vor%Tags und Links c++