Was zwei links spitze Klammern „<<“ in C # bedeuten?
-
21-09-2019 - |
Frage
Grundsätzlich sind die Fragen im Titel. Ich bin an dem MVC 2-Quellcode suchen:
[Flags]
public enum HttpVerbs {
Get = 1 << 0,
Post = 1 << 1,
Put = 1 << 2,
Delete = 1 << 3,
Head = 1 << 4
}
und ich bin einfach neugierig, was der doppelten linken Winkel brackers <<
der Fall ist.
Lösung
Das wäre die bitweise Verschiebung nach links Operator.
Für jede Verschiebung nach links wird der Wert effektiv multipliziert mit 2. So zum Beispiel value << 3
Schreiben wird den Wert von 8 multiplizieren.
Was es wirklich intern tut, ist alles von den tatsächlichen Bits des Werts bewegt einen Platz frei. Also, wenn Sie den Wert 12 (dezimal) haben, in binär, die ist 00001100
; Verschieben es einen Platz frei wird, dass in 00011000
drehen oder 24.
Andere Tipps
Wenn Sie schreiben
1 << n
Sie verschieben die Bitkombination 000000001
für n
mal nach links und so setzen n
in den Exponenten von 2:
2^n
So
1 << 10
Ist wirklich
1024
Für eine Liste von etwa 5 Artikeln Ihres for
Wille Zyklus 32-mal.
Es ist left-shift
Operator genannt. Werfen Sie einen Blick auf die Dokumentation
Der linke Shift-Operator bewirkt, daß das Bitmuster, das in dem ersten Operanden an den durch die Anzahl der Bits, die durch die zweiten Operanden spezifizierten links verschoben werden. Bits, die durch den Schaltvorgang geräumt sind mit Nullen gefüllt. Dies ist eine logische Verschiebung statt einem Schiebe- und Drehvorgang.
Ein einfaches Beispiel, das den left-shift
Operator zeigt:
for (int i = 0; i < 10; i++)
{
var shiftedValue = 1 << i;
Console.WriteLine(" 1 << {0} = {1} \t Binary: {2}",i,shiftedValue,Convert.ToString(shiftedValue,2).PadLeft(10,'0'));
}
//Output:
// 1 << 0 = 1 Binary: 0000000001
// 1 << 1 = 2 Binary: 0000000010
// 1 << 2 = 4 Binary: 0000000100
// 1 << 3 = 8 Binary: 0000001000
// 1 << 4 = 16 Binary: 0000010000
// 1 << 5 = 32 Binary: 0000100000
// 1 << 6 = 64 Binary: 0001000000
// 1 << 7 = 128 Binary: 0010000000
// 1 << 8 = 256 Binary: 0100000000
// 1 << 9 = 512 Binary: 1000000000
Verschieben um ein Bit nach links, um mehrere von two.In Tatsache equivelant ist, sind bewegt Bits schneller als standart multiplication.Let wir einen Blick auf ein Beispiel, das diese Tatsache zeigt:
Lassen Sie uns sagen, wir haben zwei Methoden:
static void ShiftBits(long number,int count)
{
long value = number;
for (int i = 0; i < count; i+=128)
{
for (int j = 1; j < 65; j++)
{
value = value << j;
}
for (int j = 1; j < 65; j++)
{
value = value >> j;
}
}
}
static void MultipleAndDivide(long number, int count)
{
long value = number;
for (int i = 0; i < count; i += 128)
{
for (int j = 1; j < 65; j++)
{
value = value * (2 * j);
}
for (int j = 1; j < 65; j++)
{
value = value / (2 * j);
}
}
}
Und wir wollen, dass sie wie folgt testen:
ShiftBits(1, 10000000);
ShiftBits(1, 100000000);
ShiftBits(1, 1000000000);
...
MultipleAndDivide(1, 10000000);
MultipleAndDivide(1, 100000000);
MultipleAndDivide(1, 1000000000);
...
Hier ist das Ergebnis:
Bit manipulation 10.000.000 times: 58 milliseconds
Bit manipulation 100.000.000 times: 375 milliseconds
Bit manipulation 1.000.000.000 times: 4073 milliseconds
Multiplication and Division 10.000.000 times: 81 milliseconds
Multiplication and Division 100.000.000 times: 824 milliseconds
Multiplication and Division 1.000.000.000 times: 8224 milliseconds
Es ist bitweise Verschiebung nach links es funktioniert durch Ziffern von binären Äquivalent Zahl durch die gegebenen (rechte Seite) Zahlen.
Verschiebungso:
temp = 14 << 2
binäre Äquivalent von 14 ist es 00001110
2mal Verschiebungseinrichtung Null von der rechten Seite drücken und jede Stelle nach links verschiebt, die es equals machen 00111000
bis 56.
In Ihrem Beispiel:
i < (1 << list.Count)
- 0000000001 = 1 , wenn list.Count = 0 Ergebnis 0000000001 = 1
- 0000000001 = 1 , wenn list.Count = 1 Ergebnis 0000000010 = 2
- 0000000001 = 1 , wenn list.Count = 2 Ergebnis 0000000100 = 4
- 0000000001 = 1 , wenn list.Count = 3 Ergebnis 0000001000 = 8
und so weiter. Im Allgemeinen ist es gleich 2 ^ list.Count
(2 auf die Kraft des list.Count angehoben)
Das ist der links bitshift Betreiber . Es verschiebt das Bitmuster des linken Operanden nach links durch die Anzahl der binären Ziffern in den rechten Operanden angegeben.
Get = 1 << 0, // 1
Post = 1 << 1, // 2
Put = 1 << 2, // 4
Delete = 1 << 3, // 8
Head = 1 << 4 // 16
Dies ist semantisch äquivalent zu lOperand * Math.Pow(2, rOperand)
Der Zweck der Schleife ist höchstwahrscheinlich auf allen Teilmengen der Menge der Elemente in der Liste zu erzeugen oder zu bedienen. Und der Schleifenkörper höchstwahrscheinlich hat auch ein gutes Stück (har har) von Bit-Operationen, und zwar sowohl eine weitere Linksverschiebung und bitweise und. (Es also Umschreiben Pow zu verwenden wäre mächtig dumm, ich kaum so viele Leute waren glauben kann, dass die tatsächlich vorgeschlagen.)
Das ist das Bit verschoben wird. Seine im Grunde nur die Bits, die durch Zugabe von 0'en auf die rechte Seite nach links zu bewegen.
public enum HttpVerbs {
Get = 1 << 0, // 00000001 -> 00000001 = 1
Post = 1 << 1, // 00000001 -> 00000010 = 2
Put = 1 << 2, // 00000001 -> 00000100 = 4
Delete = 1 << 3, // 00000001 -> 00001000 = 8
Head = 1 << 4 // 00000001 -> 00010000 = 16
}
Weitere Informationen unter http://www.blackwasp.co.uk/CSharpShiftOperators.aspx
Neben Selman22 Antwort, einige Beispiele:
Ich werde ein paar Werte für list.Count
Liste und was die Schleife wäre:
list.Count == 0: for (int i = 0; i < 1; i++)
list.Count == 1: for (int i = 0; i < 2; i++)
list.Count == 2: for (int i = 0; i < 4; i++)
list.Count == 3: for (int i = 0; i < 8; i++)
Und so weiter.
"Bit Verschiebung nach links." 1 << 0
bedeutet „nimmt den ganzzahligen Wert 1 und Verschiebung seiner Bits von Null-Bits nach links.“ Das heißt, bleibt 00000001
unverändert. 1 << 1
bedeutet „nehmen den ganzzahligen Wert 1 und verschiebt seine Bits eine Stelle nach links.“ 00000001
wird 00000010
.
Sein (<<) eine bitweise Verschiebung nach links Betreiber, bewegt er die Bitwerte eines binären Objekts. Der linke Operand gibt den Wert verschoben werden, und der rechte Operand spezifiziert die Anzahl der Positionen, die die Bits in dem Wert verschoben werden.
In Ihrem Fall, wenn der Wert von list.count 4 dann die Schleife läuft bis i <(1 << 4) das ist 16 (00010000)
00000001 << 4 = 00010000 (16)
Es wird in einer Reihe von Antworten impliziert aber nie direkt gesagt ...
Für jede Position, dass Sie eine binäre Zahl verschieben links, können Sie den ursprünglichen Wert der Zahl verdoppeln.
Beispiel:
Dezimal 5 binäre links verschoben um eine Dezimalstelle 10 ist, oder dezimale 5 verdoppelt.
Dezimal 5 binäre nach links verschoben ist um 3 dezimal 40 oder dezimal 5 verdoppelt 3 mal.
Der Ausdruck (1 << N)
verwendet eine Bit Shift in c #.
In diesem Fall ist es verwendet wird, um eine schnelle ganze Zahl evalution von 2 ^ N durchzuführen, wobei n 0 bis 30 ist.
Ein gutes Werkzeug für jungen whippersnappers Entwickler, die nicht verstehen, wie Bit-Verschiebungen Arbeit ist Windows-Calc in Programmiermodus, die visualisiert die Wirkung von Verschiebungen auf Zahlen mit Vorzeichen in verschiedenen Größen.
Die Lsh
und Rsh
Funktionen zu <<
und >>
sind.
Auswertung Math.Pow innerhalb der Schleife Zustand verwendet, ist (auf meinem System) etwa 7-mal langsamer als die Frage Code für N = 10, ob diese Fragen hängen vom Kontext ab.
Caching die „Schleifenzählung“ in einer separaten Variable wäre es leicht, als der Ausdruck, der die Listenlänge beschleunigen müßte nicht bei jeder Iteration neu bewertet werden.
Vorherige Antworten haben erklärt was es tut, aber niemand scheint, als zu erraten genommen zu haben Warum . Es scheint ziemlich mir wahrscheinlich, dass der Grund für diesen Code ist, dass die Schleife über jede mögliche Kombination von Mitgliedern einer Liste iteriert - das ist der einzige Grund, warum ich sehen kann, warum Sie auf 2 ^ {Liste iterieren würden wollen. Anzahl}. Die Variable i
daher schlecht genannt werden würde: statt eines Index (das ist, was ich ‚i‘ in der Regel interpretieren dahin), dessen Bits eine Kombination von Elementen aus der Liste vertreten, so (zum Beispiel) das erste Element ausgewählt werden kann, wenn Bit Null von i
gesetzt ((i & (1 << 0)) != 0
), das zweite Element, wenn ein Bit gesetzt ist ((i & (1 << 1)) != 0
) und so weiter. 1 << list.Count
ist daher die erste ganze Zahl, die nicht entsprechen eine gültige Kombination von Elementen aus der Liste, da es die Auswahl des nicht-existenten list[list.Count]
anzeigen würde.
Ich weiß, diese Antwort ist ziemlich gelöst, aber ich dachte, die Visualisierung helfen könnte jemand.
[Fact] public void Bit_shift_left()
{
Assert.Equal(Convert.ToInt32("0001", 2), 1 << 0); // 1
Assert.Equal(Convert.ToInt32("0010", 2), 1 << 1); // 2
Assert.Equal(Convert.ToInt32("0100", 2), 1 << 2); // 4
Assert.Equal(Convert.ToInt32("1000", 2), 1 << 3); // 8
}