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.

War es hilfreich?

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.

Verschiebung

so:

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.

  

visuelle

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
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top