11 Stimmen

Was ist der Unterschied zwischen Bitverschiebung und arithmetischen Operationen?

int aNumber;

aNumber = aValue / 2;
aNumber = aValue >> 1;

aNumber = aValue * 2;
aNumber = aValue << 1;

aNumber = aValue / 4;
aNumber = aValue >> 2;

aNumber = aValue * 8;
aNumber = aValue << 3;

// etc.

Was ist der "beste" Weg, um Operationen durchzuführen? Wann ist es besser, Bit-Shifting zu verwenden?

19voto

fmark Punkte 53936

Die beiden sind in den von Ihnen genannten Beispielen funktional gleichwertig (mit Ausnahme des letzten Beispiels, das folgendermaßen lauten müsste aValue * 8 == aValue << 3 ), wenn Sie Folgendes verwenden positive Ganzzahlen . Dies ist nur beim Multiplizieren oder Dividieren mit 2er-Potenzen.

Die Bitverschiebung ist nie langsamer als die Arithmetik. Je nach Compiler kann die arithmetische Version auf die bitverschiebende Version herunterkompiliert werden, so dass beide gleich effizient sind. Ansonsten sollte Bit-Shifting deutlich schneller sein als Arithmetik.

Die arithmetische Version ist jedoch oft besser lesbar. Daher verwende ich in fast allen Fällen die arithmetische Version und verwende die Bitverschiebung nur, wenn die Profilerstellung ergibt, dass die Anweisung einen Engpass darstellt:

Programme sollten geschrieben werden, damit Menschen sie lesen können, und nur in Ausnahmefällen, damit Maschinen sie ausführen können.

8voto

AnT Punkte 300728

Der Unterschied besteht darin, dass arithmetische Operationen klar definierte Ergebnisse haben (es sei denn, sie führen zu einem vorzeichenbehafteten Überlauf). Verschiebeoperationen haben in vielen Fällen keine definierten Ergebnisse. Sie sind für vorzeichenlose Typen sowohl in C als auch in C++ klar definiert, aber bei vorzeichenbehafteten Typen wird es schnell kompliziert.

In der Sprache C++ ist die arithmetische Bedeutung von left-shift << für vorzeichenbehaftete Typen ist nicht definiert. Es werden lediglich Bits verschoben und mit Nullen auf der rechten Seite aufgefüllt. Was dies im arithmetischen Sinne bedeutet, hängt von der von der Plattform verwendeten vorzeichenbehafteten Darstellung ab. Praktisch das Gleiche gilt für die Rechtsverschiebung >> Betreiber. Die Rechtsverschiebung negativer Werte führt zu implementierungsabhängigen Ergebnissen.

In der Sprache C sind die Dinge etwas anders definiert. Eine Linksverschiebung negativer Werte ist unmöglich: Sie führt zu undefiniertem Verhalten. Die Rechtsverschiebung negativer Werte führt zu implementierungsdefinierten Ergebnissen.

In den meisten praktischen Implementierungen führt jede einzelne Rechtsverschiebung eine Division durch 2 mit Abrundung gegen negativ unendlich aus. Dies unterscheidet sich übrigens deutlich von der arithmetischen Division / durch 2, da in der Regel (und in C99 immer) gegen 0 gerundet wird.

Was die Verwendung von Bit-Shifting angeht... Bit-Shifting ist für Operationen, die mit Bits arbeiten. Bit-Shifting-Operatoren werden nur sehr selten als Ersatz für arithmetische Operatoren verwendet (z. B. sollten Sie niemals Shifts verwenden, um eine Multiplikation/Division mit einer Konstanten durchzuführen).

4voto

xtofl Punkte 39285

Das Verschieben von Bits ist ein Vorgang, der meist keine Informationen darüber enthält, was man eigentlich erreichen will.

Wenn Sie eine Zahl durch zwei dividieren wollen, schreiben Sie einfach x/2 . Dies wird erreicht durch x >> 1 Letzteres verschleiert jedoch die Absicht.

Wenn sich dies als Engpass herausstellt, überarbeiten Sie den Code.

2voto

David Titarenco Punkte 31667

Was ist der "beste" Weg, um Operationen durchzuführen?

Verwenden Sie arithmetische Operationen, wenn Sie mit Zahlen umgehen. Verwenden Sie Bitoperationen, wenn es um Bits geht. Punkt. Das ist gesunder Menschenverstand. Ich bezweifle, dass irgendjemand jemals auf die Idee käme, Bitverschiebungsoperationen für Ints oder Doubles als alltägliche Sache zu verwenden.

Wann ist es besser, Bit-Shifting zu verwenden?

Beim Umgang mit Bits?

Zusätzliche Frage: Verhalten sie sich bei einem arithmetischen Überlauf gleich?

Ja. Geeignete arithmetische Operationen werden von den meisten modernen Compilern (oft, aber nicht immer) auf ihre Bit-Shift-Gegenstücke vereinfacht.

bearbeiten : Die Antwort wurde akzeptiert, aber ich möchte nur hinzufügen, dass in dieser Frage eine Menge schlechter Ratschläge enthalten sind. Sie sollten niemals (lies: fast niemals) Bit-Shift-Operationen verwenden, wenn Sie mit Ints arbeiten. Das ist eine furchtbare Praxis.

2voto

Toad Punkte 15025

Wenn es darum geht, einige Zahlen zu multiplizieren, ist die Verwendung von arithmetischen Operatoren sinnvoll.

Wenn Sie die Bits tatsächlich logisch verschieben wollen, dann verwenden Sie die Verschiebeoperatoren.

Wenn Sie zum Beispiel die RGB-Komponenten eines RGB-Wortes aufteilen, ist dieser Code sinnvoll:

 int r,g,b;
 short rgb = 0x74f5;
 b = rgb & 0x001f;
 g = (rgb & 0x07e0) >> 5;
 r = (rgb & 0xf800) >> 11;

Wenn Sie hingegen einen Wert mit 4 multiplizieren wollen, sollten Sie Ihre Absicht wirklich kodieren und keine Verschiebungen vornehmen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X