Tags: , , | Categories: C#, Linguagem de Programação Posted by Rafael on 11/01/2011 19:03 | Comentários (1)

Olá pessoal!

Falaremos hoje sobre operadores C#, em especial sobre os operadores shift, << e >> . A função desses operadores é deslocar bits para a esquerda ( << ) ou para a direita ( >> ), que podem ser utilizados apenas em operações com variáveis do tipo inteiro, pois, não existem números reais na base 2 (binários), apenas números inteiros.

Para entender melhor, vamos falar um pouco sobre números binários e inteiros.

Consideremos a seguinte tabela:

Essa é uma tabela para facilitar a representação de números inteiros em binários. Na linha superior (em azul) temos o expoente da base. Como a base que iremos trabalhar é binária, ou seja, base 2, a linha amarela representa o resultado da potenciação entre a base 2 e seus expoentes. Assim, temos 20 = 1, 21 = 2, 22 = 4, 23 = 8, ..., 210 = 1024, ..., e assim por diante (limitei até o expoente 10 apenas para facilitar a exemplificação).

Muito bem, agora, vamos representar o número inteiro 100 em binário. Na linha amarela, partimos sempre da esquerda para a direita, até encontrar o primeiro número menor ou igual ao número que queremos representar, que nosso caso é o inteiro 100.

Localizamos que o número 64 é o primeiro número menor ou igual a 100, da esquerda para a direita. Assim, “ligamos” o flag, ou seja, inserimos o número 1, da seguinte maneira:

Feito isso, partimos para o segundo bit. Devemos ter em mente o quanto resta para chegarmos a 100 inteiros. A conta é bem simples: se já “ligamos” o 64, a subtração entre 100 e 64 é igual a 36. A partir de agora, localizamos o primeiro número menor ou igual a 36, a partir da primeira célula à direita do flag que representa 64, que é 32.

Como 32 é menor ou igual a 36, ativamos também essa célula, ficando assim:

Legal, agora nos restam 4 inteiros (100 – 64 – 32 = 4). Dando seqüência, como 16 não é menor ou igual a 4, inserimos um 0, ou seja, “desligamos” o flag da célula 16, assim:

Da mesma maneira, fazemos com a célula 8, pois 8 não é menor ou igual a 4, ficando assim:

Como 4 é menor ou igual a 4, “ligamos” o flag, da seguinte maneira:

Como chegamos a 100 inteiros, completamos as células restantes à direita com 0, assim:

Temos agora o número inteiro 100 representado em binário como 1100100.

Muito bom! Agora que já sabemos como representar inteiros em binários de uma forma fácil, vamos entender como os operadores shift trabalham.

Basicamente, como dito anteriormente, o operador shift << desloca um bit à esquerda, inserindo um 0 (zero) na célula vazia, e o operador >> desloca um bit à direita, desconsiderando o bit que “sai” do range. Vamos exemplificar com um Console Application em C#, bem simples, junto com a nossa tabela de conversão.

Consideremos o seguinte Console Application:

namespace Blog.Operadores.Shift

{

    class Program

    {

        static void Main(string[] args)

        {

            try

            {

                Console.WriteLine("Insira um número inteiro:");

 

                int inteiro = 0;

                Int32.TryParse(Console.ReadLine(), out inteiro);

 

                Console.WriteLine("Número inteiro escolhido: " + inteiro.ToString());

 

                Console.WriteLine("");

 

                Console.WriteLine("Quantos bits você deseja deslocar?");

 

                int qtdeBits = 0;

                Int32.TryParse(Console.ReadLine(), out qtdeBits);

 

                Console.WriteLine("Bits a deslocar: " + qtdeBits.ToString());

 

                Console.WriteLine("");

 

                Console.WriteLine("À esquerda ou à direita? Digite << para à esquerda e >> para à direita:");

 

                string comando = Console.ReadLine();

 

                if (comando.Trim() != "<<" && comando.Trim() != ">>")

                {

                    throw new Exception("Comando inválido! Você deve escolher entre << e >>");

                }

 

                switch (comando.Trim())

                {

                    case "<<":

                        Console.WriteLine("Bit deslocado à esquerda");

                        inteiro = inteiro << qtdeBits; // forma simplificada: inteiro <<= qtdeBits;

                        break;

                    case ">>":

                        Console.WriteLine("Bit deslocado à direita");

                        inteiro = inteiro >> qtdeBits; // forma simplificada: inteiro >>= qtdeBits;

                        break;

                    default:

                        break;

                }

 

                Console.WriteLine("");

                Console.WriteLine("Resultado: " + inteiro.ToString());

            }

            catch (Exception ex)

            {

                Console.WriteLine("");

                Console.ForegroundColor = ConsoleColor.Red;

                Console.WriteLine("ERRO: " + ex.Message);

            }

            finally

            {

                Console.ResetColor();

                Console.ReadKey();

            }

        }

    }

}

Se preferir, faça o download do projeto aqui: Blog.Operadores.Shift.zip (19,21 kb)

Note os dois comentários // forma simplificada no código. Podemos escrever tanto assim x = x << y quanto x <<= y ou então x = x >> y quanto x >>= y. A segunda opção é a forma simplificada do comando. Muda apenas a sintaxe, o resultado é o mesmo.

Ao executarmos o aplicativo, temos a seguinte tela:

Para seguir o nosso exemplo, vamos inserir o número 100.

Vamos deslocar apenas 1 bit à esquerda.

Na tabela, podemos ver como pode ser feito manualmente:

Todos os bits são deslocados 1 (uma) casa para a esquerda, e a célula vaga é preenchida com 0 (zero).

Assim, temos o número inteiro 200 como resultado. Agora vamos executar novamente o aplicativo, porém, agora deslocando 1 bit à direita.

Na tabela:

Obtemos como resultado 50 inteiros.

Logo, podemos notar que, se deslocarmos 1 bit à esquerda, multiplicamos o número por 2, e se deslocar à direita, dividimos também por 2. Agora, porque por 2? A resposta é bem simples, como estamos trabalhando com binários, ou seja, base 2, o deslocamento de bits multiplica ou divide o valor pela base, que é 2.

Agora, se deslocarmos 3 bits à direita de 100, temos como resultado 12. Você pode me perguntar: porque não 12,5? A resposta também é simples: porque não existem números reais por representação de bits, ou seja, o resultado 12,5 é truncado, ficando apenas 12.

Vamos ver na tabela:

E na aplicação:

É isso aí.

Até a próxima!

Comentários

Frederico Brazil on 21/01/2011 19:50 Muito boa explicação.

Muito clara!

Parabéns!
Os comentários estão fechados