2016-03-30 8 views
0

Die C99 spec Zustände:arithmetische Rechtsverschiebung von Ganzzahl mit Vorzeichen

Das Ergebnis E1 E2 E1 >> rechts verschoben E2 Bitpositionen. Wenn E1 einen Typ ohne Vorzeichen hat oder E1 einen Typ mit Vorzeichen und einen nichtnegativen Wert hat, ist der Wert des Ergebnisses der ganzzahlige Teil des Quotienten von E1/2^E2. Wenn E1 einen Typ mit Vorzeichen und einen negativen Wert hat, ist der resultierende Wert implementierungsdefiniert.

Ich bin neugierig zu wissen, welche Implementierungen/Compiler keine signierten E1 >> 31 als ein Bündel von 11111.... behandeln?

+3

Ein paar wessen -1 ist nicht 1111 ...., und eine Menge, deren Int ist nicht 32 Bits. – user3528438

+1

Hinweis: Verwenden Sie keine veraltete Version des Standards. C-Standard ist C11, nicht C99. Sagte, dass der Text sehr klar ist. Verlassen Sie sich nicht darauf, wenn Sie Ihren Code portabel haben möchten. Beachten Sie, dass die Verschiebung auch undefiniertes Verhalten auslösen kann. Siehe 6.5.7p3 im Standard (d. H. Die einzige gültige Version). – Olaf

+0

Auch viele 32-Bit-Zweierkomplement-Implementierungen, die die Signedness ignorieren und als Ergebnis "1" erzeugen. Der Standard ist in der Tat sorgfältig formuliert, um zu vermeiden, anzugeben, ob ">>" eine arithmetische Verschiebung oder eine logische Verschiebung ausführt. –

Antwort

2

Die meisten eingebetteten Compiler für Mikrocontroller bevorzugen die logische Verschiebung (Verschiebung in Nullen) anstelle der arithmetischen Verschiebung (Verschiebung des Vorzeichen-Bits).

Dies ist wahrscheinlich, weil signierte Zahlen in eingebetteten Systemen etwas selten sind, da diese Programmierung viel näher an der Hardware und weiter weg von Benutzern ist, als zum Beispiel Desktop-Programmierung mit Bildschirmen.

Signierte Zahlen ist nichts anderes als Benutzer Präsentation schließlich. Wenn Sie für einen Benutzer keine Zahlen drucken müssen, benötigen Sie sehr selten signierte Nummern.

Und natürlich macht es eigentlich keinen Sinn, die Verschiebung auf vorzeichenbehaftete Zahlen zu verwenden. Ich habe noch nie in meiner Programmierkarriere ein Szenario erlebt, als ich das tun musste. In den meisten Fällen sind solche Verschiebungen nur zufällige Fehler.

+0

@Lundin Ich arbeite mit einem Krypto-Code, der den Vorteil der arithmetischen Rechtsverschiebung nutzt, um eine if-Anweisung zu entfernen. Danke für deine Antwort. – MarkP

+0

@MarkP Oh, aber dann müssen Sie diesen Algorithmus definitiv überdenken, wenn Portabilität wichtig ist. – Lundin

+0

@Lundin Ja, das ist das Herz des Problems. Es ist unwahrscheinlich, dass dieser Code auf Mikrocontrollern läuft. Die Hauptsorge war, dass es große Computer gibt, die mit dieser Situation nicht umgehen können. – MarkP

0

Sie können eine vorzeichenbehaftete arithmetische Rechtsverschiebung mit 2er-Komplement mit vorzeichenlosen Typen ohne die Verwendung von if-Anweisungen simulieren. Beispiel:

#include <limits.h> 

unsigned int asr(unsigned int x, unsigned int shift) 
{ 
    return (x >> shift) | -((x & ~(UINT_MAX >> 1)) >> shift); 
} 

Möglicherweise müssen Sie einen anderen unsignierten Typ und den zugehörigen Maximalwert in Ihrem Code verwenden.

+1

Was hat das mit der Frage zu tun? – Lundin

+0

@Lundin Es ist mit der Frage verwandt, obwohl die Frage nicht direkt beantwortet. Es ist schwer, Code in einen normalen Kommentar zu schreiben. Es beantwortet es als ein X Y Problem. Wenn Sie sich nicht darauf verlassen können, dass '>>' eine arithmetische Rechtsverschiebung ausführt, wie kann dies portabel gemacht werden? –