sobrecarga significan sharp que programacion parentesis operadores operador los logicos llaves jerarquia ejemplos corchetes como abrir c# .net operators bitwise-operators bit-shift

sharp - ¿Qué significan dos corchetes angulares "<<" en C#?



que significan los corchetes en c++ (14)

"Cambio de bit a la izquierda". 1 << 0 significa "tomar el valor entero 1 y cambiar sus bits a la izquierda por bits cero". Es decir, 00000001 mantiene sin cambios. 1 << 1 significa "tomar el valor entero 1 y cambiar sus bits a un lugar". 00000001 convierte en 00000010 .

Básicamente las preguntas en el título. Estoy mirando el código fuente de MVC 2:

[Flags] public enum HttpVerbs { Get = 1 << 0, Post = 1 << 1, Put = 1 << 2, Delete = 1 << 3, Head = 1 << 4 }

y solo tengo curiosidad sobre lo que hace el doble ángulo izquierdo Brackers << hace.


Ese es el operador de desplazamiento de bits izquierdo . Cambia el patrón de bits del operando izquierdo a la izquierda por la cantidad de dígitos binarios especificados en el operando derecho.

Get = 1 << 0, // 1 Post = 1 << 1, // 2 Put = 1 << 2, // 4 Delete = 1 << 3, // 8 Head = 1 << 4 // 16

Esto es semánticamente equivalente a lOperand * Math.Pow(2, rOperand)


Ese sería el operador de desplazamiento a la izquierda bit a bit .

Para cada desplazamiento hacia la izquierda, el valor se multiplica efectivamente por 2. Entonces, por ejemplo, escribir el value << 3 multiplicará el valor por 8.

Lo que realmente hace internamente es mover todos los bits reales del valor que quedan en un lugar. Entonces, si tiene el valor 12 (decimal), en binario es 00001100 ; desplazarlo a la izquierda un lugar lo convertirá en 00011000 , o 24.


Sé que esta respuesta está bastante resuelta, pero pensé que la visualización podría ayudar a alguien.

[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 }


Además de la respuesta de Selman22, algunos ejemplos:

Voy a enumerar algunos valores para list.Count y lo que sería el bucle:

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++)

Etcétera.


Cuando escribes

1 << n

Cambia la combinación de bits 000000001 por n veces a la izquierda y así pone n en el exponente de 2:

2^n

Asi que

1 << 10

Realmente es

1024

Para obtener una lista de, por ejemplo, 5 elementos, su ciclo 32 veces.


El propósito del ciclo es más probable que genere u opere en todos los subconjuntos del conjunto de elementos en la lista. Y, probablemente, el cuerpo del bucle también tiene un buen bit (har har) de operaciones bit a bit, es decir, tanto otro desplazamiento a la izquierda como a nivel de bit. (Así que reescribirlo para usar Pow sería muy estúpido, no puedo creer que haya tanta gente que realmente sugirió eso).


Es (<<) un operador de desplazamiento a la izquierda bit a bit, mueve los valores de bit de un objeto binario. El operando de la izquierda especifica el valor que se va a desplazar y el operando de la derecha especifica el número de posiciones en las que se deben desplazar los bits del valor.

En su caso, si el valor de list.count es 4, el ciclo se ejecutará hasta i <(1 << 4) que es 16 (00010000)

00000001 << 4 = 00010000 (16)


Es un desplazamiento a nivel de bit izquierdo que funciona al desplazar los dígitos del número binario equivalente de los números dados (lado derecho).

asi que:

temp = 14 << 2

El equivalente binario de 14 es 00001110 2 veces significa presionar cero desde el lado derecho y desplazar cada dígito al lado izquierdo, lo que hace que 00111000 igual a 56.

En tu ejemplo:

i < (1 << list.Count)

  • 0000000001 = 1 si list.Count = 0 resultado es 0000000001 = 1
  • 0000000001 = 1 si list.Count = 1 resultado es 0000000010 = 2
  • 0000000001 = 1 si list.Count = 2 resultado es 0000000100 = 4
  • 0000000001 = 1 si list.Count = 3 result es 0000001000 = 8

y así. En general, es igual a 2 ^ list.Count (2 elevado al poder de list.Count)


Está implícito en una serie de respuestas, pero nunca se menciona directamente ...

Por cada posición que cambie un número binario restante, duplicará el valor original del número.

Por ejemplo,

El decimal 5 binario desplazado a la izquierda es uno decimal 10, o el decimal 5 duplicado.

El decimal 5 binario desplazado a la izquierda por 3 es 40 decimal, o decimal 5 duplicado 3 veces.


Las respuestas anteriores han explicado lo que hace, pero nadie parece haber adivinado por qué . Me parece bastante probable que el motivo de este código sea que el ciclo itera sobre cada posible combinación de miembros de una lista; esta es la única razón por la que puedo ver por qué querría repetir hasta 2 ^ {list. Contar}. Por lo tanto, la variable sería mal nombrada: en lugar de un índice (que es lo que generalmente interpreto como ''significado''), sus bits representan una combinación de elementos de la lista, por lo que (por ejemplo) se puede seleccionar el primer elemento si el bit cero de i está establecido ( (i & (1 << 0)) != 0 ), el segundo elemento si el bit uno está establecido ( (i & (1 << 1)) != 0 ) y así sucesivamente. 1 << list.Count es, por lo tanto, el primer entero que no corresponde a una combinación válida de elementos de la lista, ya que indicaría la selección de la list[list.Count] .


Eso es un poco cambiante. Básicamente, basta con mover los bits hacia la izquierda añadiendo 0''s al lado derecho.

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 }

Más información en http://www.blackwasp.co.uk/CSharpShiftOperators.aspx


Se llama operador de left-shift . Eche un vistazo a la documentación

El operador de desplazamiento a la izquierda hace que el patrón de bits en el primer operando se desplace hacia la izquierda por el número de bits especificado por el segundo operando. Los bits vacíos por la operación de turno no se llenan. Este es un cambio lógico en lugar de una operación de cambio y rotación.

Ejemplo simple que demuestra el operador de left-shift la left-shift :

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

Mover un bit a la izquierda equivale a múltiplo por dos. De hecho, mover los bits es más rápido que la multiplicación estándar. Echemos un vistazo a un ejemplo que demuestra este hecho:

Digamos que tenemos dos métodos:

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); } } }

Y queremos probarlos así:

ShiftBits(1, 10000000); ShiftBits(1, 100000000); ShiftBits(1, 1000000000); ... MultipleAndDivide(1, 10000000); MultipleAndDivide(1, 100000000); MultipleAndDivide(1, 1000000000); ...

Aquí están los resultados:

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


La expresión (1 << N) usa un Cambio de bit en c #.

En este caso, se está utilizando para realizar una evaluación de enteros rápidos de 2 ^ N, donde n es de 0 a 30.

Una buena herramienta para Whippersnappers jóvenes los desarrolladores que no entienden cómo funcionan los cambios de bit son Windows Calc en modo de programador, que visualiza el efecto de los cambios en los números con signo de varios tamaños. Las funciones Lsh y Rsh equivalen a << y >> respectivamente.

Evaluar usando Math.Pow dentro de la condición de bucle es (en mi sistema) aproximadamente 7 veces más lento que el código de pregunta para N = 10, si esto importa depende del contexto.

El almacenamiento en memoria caché del "conteo de bucles" en una variable separada lo aceleraría ligeramente ya que la expresión que involucra la longitud de la lista no necesitaría ser reevaluada en cada iteración.