Frage

Ich studierte Shift -Operatoren in C#und versuchte herauszufinden, wann sie in meinem Code verwendet werden sollen.

Ich habe eine Antwort gefunden, aber für Java könnten Sie:

a) machen Schneller Ganzzahl -Multiplikation und Abteilungsoperationen:

* 4839534 * 4 * kann wie folgt erfolgen: 4839534 << 2

oder

543894 / 2 kann so gemacht werden: 543894 >> 1

Schichtvorgänge viel schneller als die Multiplikation für die meisten Prozessoren.

b) Byte -Streams zu int -Werten zusammenbauen

c) zum Beschleunigen von Operationen mit Grafiken seit rot, grün und blau -Farben, die durch separate Bytes codiert werden.

d) kleine Zahlen in eine einzige lange verpacken ...


Für B, C und D kann ich mir hier eine echte Probe nicht vorstellen.

Weiß jemand, ob wir all diese Artikel in C#erreichen können? Gibt es mehr praktische Verwendung für Schichtbetreiber in C#?

War es hilfreich?

Lösung

Es ist nicht erforderlich, sie für Optimierungszwecke zu verwenden, da der Compiler dies für Sie darstellt.

Verwenden Sie sie nur, wenn Sie Bits verschieben, die eigentliche Absicht Ihres Codes (wie in den verbleibenden Beispielen in Ihrer Frage). Die restliche Zeit verwenden Sie einfach Multiply und Divide, damit die Leser Ihres Codes ihn auf einen Blick verstehen können.

Andere Tipps

Wenn es nicht einen sehr überzeugenden Grund gibt, ist meine Meinung, dass die Verwendung von cleveren Tricks in der Regel nur für verwirrendere Code mit geringem Mehrwert sorgt. Die Compiler -Autoren sind eine kluge Gruppe von Entwicklern und kennen viel mehr dieser Tricks als der durchschnittliche Programmierer. Zum Beispiel ist die Aufteilung einer Ganzzahl durch eine Leistung von 2 mit dem Schaltoperator schneller als eine Abteilung, aber es ist wahrscheinlich nicht notwendig, da der Compiler dies für Sie tun wird. Sie können dies sehen, indem Sie sich die Baugruppe ansehen, die sowohl der Microsoft C/C ++ - Compiler als auch GCC diese Optimierungen durchführen.

Ich werde eine interessante Verwendung teilen, über die ich in der Vergangenheit gestolpert bin. Dieses Beispiel wird schamlos aus einer ergänzenden Antwort auf die Frage kopiert. "Was bedeutet das [Flags] Enum -Attribut in C#?"

[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3
}

Dies kann einfacher zu erweitern sein als wörtlich zu schreiben 1, 2, 4, 8, ... Werte, besonders wenn Sie über 17 Flags vorbeikommen.

Der Kompromiss ist, wenn Sie mehr als 31 Flags benötigen (1 << 30), Sie müssen auch darauf achten, Ihre Aufzählung als etwas mit einer höheren Obergrenze als eine signierte Ganzzahl anzugeben (indem Sie ihn als deklarieren public enum MyEnum : ulong, Zum Beispiel, was Sie bis zu 64 Flags gibt). Das ist weil...

1 << 29 == 536870912
1 << 30 == 1073741824
1 << 31 == -2147483648
1 << 32 == 1
1 << 33 == 2

Wenn Sie dagegen einen Enumswert direkt auf 2147483648 festlegen, werfen der Compiler einen Fehler.

Wie von ClickRick hervorgehoben, muss Ihr Bitverschiebungsvorgang auch dann, wenn Ihre Aufzählung von Ulong stammt, gegen einen ULONG durchgeführt werden, oder Ihre Enum -Werte werden weiterhin unterbrochen.

[Flags]
public enum MyEnum : ulong
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3,

    // Compiler error:
    // Constant value '-2147483648' cannot be converted to a 'ulong'
    // (Note this wouldn't be thrown if MyEnum derived from long)
    ThirtySecond = 1 << 31,

    // so what you would have to do instead is...
    ThirtySecond = 1UL << 31,
    ThirtyThird  = 1UL << 32,
    ThirtyFourth = 1UL << 33
}

Schauen Sie sich diese Wikipedia -Artikel darüber an das Binärzahlsystem und die arithmetische Verschiebung. Ich denke, sie werden Ihre Fragen beantworten.

Die Schichtbetreiber werden heute in Geschäftsanwendungen selten angetroffen. Sie werden häufig in Code mit niedrigem Niveau erscheinen, der mit Hardware interagiert oder verpackte Daten manipuliert. Sie waren in den Tagen von 64 -km -Speichersegmenten häufiger.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top