2010-08-14 21 views
7

me encontré con esta declaración en una pieza de código:¿Qué hace el operador ">>" en C#?

Int32 medianIndex = colorList.Count >> 1; 

colorList es una lista de la clase System.Drawing.Color.

Ahora se supone que la declaración recupera el índice mediano de la lista ... como el punto medio de ella ... pero no puedo entender cómo funciona el símbolo >> y cómo se supone que el "1" da la mediana índice ... Agradecería un poco de ayuda: S

Respuesta

12

El operador >> realiza un bit shift.

La expresión >> 1 * es casi el mismo que / 2 para que el programador estaba calculando el índice colorList.Count/2 que es la median **. Para entender por qué este es el caso, debe observar la representación binaria de los números involucrados. Por ejemplo, si tiene 25 elementos en la lista:

n  : 0 0 0 1 1 0 0 1 = 25 
     \ \ \ \ \ \ \ 
n >> 1: 0 0 0 0 1 1 0 0 = 12 

En general utilizando un operador de bits, cuando en realidad se quiere realizar una división es una mala práctica. Probablemente se trate de una optimización prematura realizada porque el programador pensó que sería más rápido realizar una operación bit a bit en lugar de una división. Sería mucho más claro escribir una división y no me sorprendería si el rendimiento de los dos enfoques es comparable.

* La expresión x >> 1 da el mismo resultado que x/2 para todos los enteros positivos y todos los enteros pares negativos. Sin embargo, da un resultado diferente para los enteros impares negativos. Por ejemplo -101 >> 1 == -51 mientras que -101/2 == -50.

** En realidad, la mediana solo se define de esta manera si la lista tiene un número impar de elementos. Para un número par de elementos, este método estrictamente hablando no dará la mediana.

+0

muchas gracias por la explicación .. estoy familiarizado con el método de desplazamiento y su significado, pero no entendí que es el modo utilizado aquí .. tengo otra pregunta, sin embargo ... es esta forma de dividir en 2 tiene menos complejidad de tiempo que la división "/" normal? – Majd

+0

@Majd: eso depende de la plataforma donde ejecute el código. Recuerde que C# se compila en CIL, que a su vez se traduce ("jitted") en código máquina nativo que difiere de una plataforma a otra. Es muy posible que algunos nervios traduzcan automáticamente 'x/2' en una instrucción de desplazamiento a la derecha. – Timwi

+0

En la primera nota al pie, es un poco confuso que comparen 'x >> 1' con' x/= 2', y creo que el signo '=' es un error tipográfico. Por supuesto, 'x >> 1' es comparable a' x/2', y 'x >> = 1' es comparable a' x/= 2'. –

0

No es un código muy legible, básicamente, sólo se divide por el número 2.

>> es el operador de desplazamiento a la derecha, cambiando todos los bits de una posición a la derecha.

0110 (6) se convierte en 0011 (3)

+0

bits, no bytes. – Timwi

+0

@Timwi: Gracias, por supuesto, tienes razón, lo corrigió. – dbemerlin

1

>> es el operador de desplazamiento a la derecha en modo bit, y el cambio de colorList.Count a la derecha por 1 es más o menos equivalente a colorList.Count/2.

Un desplazamiento a la derecha de a >> b se puede definir como a/2^b.

En cuanto a por qué utilizarías un desplazamiento a la derecha en lugar de dividir por 2, no tengo ni idea.

+0

No lo use en lugar de dividir por 2. El JIT optimiza este tipo de cosas. –

2

Es un bit a bit opperator una definición solo agarre de http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators:

El operador binario >> evalúa sus operandos y devuelve el primer argumento que resulta adecuado en diferido por el número de bits especificado por el segundo argumento. Descarta los bits de bajo orden que se desplazan más allá del tamaño de su primer argumento y establece nuevos bits de alto orden para el bit de signo del primer argumento, o a cero si el primer argumento no está firmado.

Es básicamente dividir por 2 ...

+0

+1 para vincular a la documentación. Me parece divertido si el OP incluso se molestó en publicar aquí en lugar de ir a definiciones de idioma. Hacer una pregunta como esa es algo que me hace hablar con mis empleados sobre su actitud (no: no entiendo qué es el gran cambio "pero" oye, soy demasiado perezoso para buscar especificaciones de idioma para el código que reviso "). – TomTom

1

programadores C (de los cuales he sido uno durante más de 20 años) rutinariamente han usado turnos de bits para multiplicar o dividir por potencias de 2. La razón fue que en arquitecturas antiguas (piense en procesador de 2 MHz, 32K de memoria, y sin disco) fue significativamente más rápido para cambiar y, en general compilado a una sola instrucción de la máquina. A pesar de que actualmente escribo principalmente C#, todavía utilizo este truco como hábito. Otra convención común de C que la mayoría de los programadores de C# nunca han visto es tener una tarea incrustada dentro de un condicional. Por ejemplo:

if ((a = getmeanumber()) == 0) 
    /* do something */ ; 

De todos modos, en cuanto a la pregunta original y las razones para su uso, que en gran medida ya no existen, excepto con el ámbito limitado de programación integrado en cada ciclo de reloj de byte y podría importar.