Você está na página 1de 15

O

MANIPULAO DE BITS
OBJETIVOS
Entender o conceito da manipulao de bits. Poder usar os operadores bit a bit. Poder usar a classe BitArray para executar a manipulao de bits.

Apndice O Manipulao de Bits

O-171

Resumo
O.1 O.2 O.3 Introduo A manipulao de bits e os operadores bit a bit A classe BitArray

Resumo Terminologia

O.1 Introduo
Neste apndice apresentaremos uma discusso extensa sobre a manipulao de bits e os operadores bit a bit que a permitem. Tambm discutiremos a classe BitArray, por meio da qual possvel criar objetos teis para manipular conjuntos de bits.

O.2 A manipulao de bits e os operadores bit a bit


O C# fornece capacidades extensas de manipulao de bits para os programadores que precisam trabalhar no nvel de bits e bytes. Os sistemas operacionais, o software de equipamentos de teste, o software de rede e muitos outros tipos de aplicativos exigem que os programadores se comuniquem diretamente com o hardware. Nesta e na prxima seo discutiremos as capacidades de manipulao do C#. Aps apresentar os operadores bit a bit de C#, demonstraremos o uso dos operadores em exemplos de cdigo vivo. Os computadores representam os dados internamente como seqncias de bits. As ALUs (Arithmetic Logic Units unidades lgico-aritmticas), as CPUs (Central Processing Units unidades de processamento central) e outros elementos de um computador processam os dados como bits ou grupos de bits. Cada bit pode assumir o valor 0 ou 1. Em todos os sistemas, uma seqncia de oito bits forma um byte a unidade padro de armazenamento de uma varivel do tipo byte. Os outros tipos de dados exigem nmeros maiores de bytes para o armazenamento. Os operadores bit a bit manipulam os bits de operandos inteiros (ou seja, sbyte, byte, char, short, ushort, int, uint, long e ulong). Observe que a discusso sobre os operadores bit a bit desta seo ilustra as representaes binrias dos operandos inteiros. Para obter uma explicao detalhada do sistema de numerao binrio (tambm chamado base 2) consulte o Apndice B. Os operadores E bit a bit (&), OU bit a bit inclusivo (|) e OU bit a bit exclusivo (^) operam de modo semelhante aos seus equivalentes lgicos, exceto que as verses de bit a bit operam no nvel de bits. O operador E bit a bit congura cada bit do resultado como 1, se o bit correspondente de ambos os operandos for 1 (Figura O.2). O operador OU bit a bit inclusivo congura cada bit do resultado como 1, se o bit correspondente de um ou ambos os operadores for 1 (Figura O.3). O operador OU bit a bit exclusivo congura cada bit do resultado como 1, se o bit correspondente exatamente de um operando for 1 (Figura O.4). O OU exclusivo tambm conhecido como XOR. O operador de deslocamento esquerda (<<) desloca os bits de seu operando esquerdo para a esquerda pelo nmero de bits especicado em seu operando direito. O operador de deslocamento direita (>>) desloca os bits de seu operando esquerdo para a direita pelo nmero de bits especicados em seu operando direito. Se o operando esquerdo for negativo, os 1s so deslocados a partir da esquerda, mas se o operando for positivo, os 0s so deslocados a partir da esquerda. O operador bit a bit de complemento (~) congura todos os bits 0 de seu operando como 1 e todos os bits 1 como 0 no resultado; esse processo s vezes chamado de tomar o complemento de um do valor. Uma discusso detalhada sobre cada operador bit a bit vir nos prximos exemplos. Os operadores bit a bit e suas funes esto resumidos na Figura O.1. Ao usar os operadores bit a bit, bom exibir os valores em suas representaes binrias para ilustrar os efeitos desses operadores. Na Figura O.5, os inteiros so exibidos em suas representaes binrias como grupos de oito bits cada um. O mtodo GetBits (linhas 67 a 91) da classe PrintBits usa o operador E bit a bit (linha 79) para combinar a varivel number com a varivel displayMask. Quase sempre, o operador E bit a bit usado com um operando de mscara um valor inteiro com bits especcos congurados como 1. As mscaras ocultam alguns bits em um valor e selecionam outros bits. GetBits atribui varivel de mscara displayMask o valor 1 << 31 (10000000 00000000 00000000 00000000).

O-172

C# Como Programar

O operador de deslocamento esquerda desloca o valor 1 do bit de ordem inferior (mais direita) para o bit de ordem superior (mais esquerda) em displayMask e preenche os bits 0 a partir da direita. Como o segundo operador 31, 31 bits (cada um 0) so preenchidos a partir da direita. A palavra preencher nesse contexto signica que inclumos um bit no lado direito e exclumos um no lado esquerdo. Toda vez que inclumos um 0 no lado direito, removemos o bit no lado esquerdo. A instruo da linha 79 determina se um 1 ou um 0 deve ser anexado StringBuilder output para o bit mais esquerda da varivel number. Nesse exemplo vamos assumir que number contm 11111 (00000000 00000000 00101011

Operador & | ^ << >>

Nome E bit a bit OU bit a bit inclusivo OU bit a bit exclusivo deslocamento esquerda deslocamento direita

Descrio Cada bit do resultado congurado como 1 se os bits correspondentes dos dois operandos forem ambos 1. Caso contrrio, o bit congurado como 0. Cada bit do resultado congurado como 1 se pelo menos um dos bits correspondentes dos dois operandos for 1. Caso contrrio, o bit congurado como 0. Cada bit do resultado congurado como 1 se exatamente um dos bits correspondentes dos dois operandos for 1. Caso contrrio, o bit congurado como 0. Desloca os bits do primeiro operando esquerda pelo nmero de bits especicado pelo segundo operando; preenche a partir da direita com bits 0. Desloca os bits do primeiro operando direita pelo nmero de bits especicado pelo segundo operando. Se o primeiro operando for negativo, 1s so deslocados a partir da esquerda; caso contrrio, 0s so deslocados a partir da esquerda. Todos os bits 0 so congurados como 1, e todos os bits 1 so congurados como 0.

complemento

Figura O.1 Operadores de bit a bit.

Bit 1 0 1 0 1

Bit 2 0 0 1 1

Bit 1 & Bit 2 0 0 0 1

Figura O.2 Resultados da combinao entre dois bits com o operador E bit a bit (&).

Bit 1 0 1 0 1

Bit 2 0 0 1 1

Bit 1 | Bit 2 0 1 1 1

Figura O.3 Resultados da combinao entre dois bits com o operador OU bit a bit inclusivo (|).

Bit 1 0 1 0 1

Bit 2 0 0 1 1

Bit 1 ^ Bit 2 0 1 1 0

Figura O.4 Resultados da combinao entre dois bits com o operador OU bit a bit exclusivo (^).

Apndice O Manipulao de Bits

O-173

01100111). Quando number e displayMask so combinados usando &, todos os bits (exceto o bit de ordem superior da varivel) number tm uma mscara (so ocultos), porque qualquer bit E 0 resulta em 0. Se o bit mais esquerda 0, number & displayMask avaliado como 0 e 0 anexado; caso contrrio, 1 anexado. Em seguida, a linha 83 muda a varivel val um bit com a expresso number << = 1 (isso equivalente a number = number << 1). Essas etapas so repetidas para cada bit da varivel number. No nal do mtodo GetBits, a linha 89 converte StringBuilder em uma string e a retorna do mtodo.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

// Fig. O.5: PrintBits.cs // Imprimindo os bits que constituem um inteiro. using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Text;

// exibe a representao de bits da entrada do usurio public class PrintBits : System.Windows.Forms.Form { private System.Windows.Forms.Label promptLabel; private System.Windows.Forms.Label viewLabel; // para a entrada de usurio private System.Windows.Forms.TextBox inputTextBox; // a representao de bits exibida aqui private System.Windows.Forms.Label displayLabel; private System.ComponentModel.Container components = null; // construtor padro public PrintBits() { InitializeComponent(); } // cdigo gerado pelo Visual Studio .NET [STAThread] static void Main() { Application.Run( new PrintBits() ); } // processa o inteiro quando o usurio pressiona Enter private void inputTextBox_KeyDown( object sender, System.Windows.Forms.KeyEventArgs e ) { // se o usurio pressionou Enter if ( e.KeyCode == Keys.Enter ) { // testa se o usurio inseriu um inteiro try

Figura O.5 Exibindo a representao de bits de um inteiro. (Parte 1 de 2.)

O-174

C# Como Programar

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

{ displayLabel.Text = GetBits( Convert.ToInt32( inputTextBox.Text ) ); } // se o valor no um inteiro, a exceo declarada catch ( FormatException ) { MessageBox.Show( Please Enter an Integer, Error, MessageBoxButtons.OK, MessageBoxIcon.Error ); } } } // m do mtodo inputTextBox_KeyDown // converte o inteiro em sua representao de bits public string GetBits( int number ) { int displayMask = 1 << 31; StringBuilder output = new StringBuilder(); // obtm cada bit, inclui espao a cada 8 bits // para formatao da exibio for ( int c = 1; c <= 32; c++ ) { // anexa 0 ou 1 dependendo do resultado da mscara output.Append( ( number & displayMask ) == 0 ? 0 : 1 ); // mudana esquerda para que a mscara encontre o bit do // prximo dgito durante a prxima interao do lao number <<= 1; if ( c % 8 == 0 ) output.Append( ); } return output.ToString(); } // m do mtodo GetBits } // m da classe PrintBits

Figura O.5 Exibindo a representao de bits de um inteiro. (Parte 2 de 2.)

Erro de programao comum O.1


O uso do operador E lgico (&&) no lugar do operador E bit a bit (&) um erro de programao comum.

Erro de programao comum O.2


O uso do operador OU lgico (||) no lugar do operador OU bit a bit inclusivo (|) um erro comum de programao.

Apndice O Manipulao de Bits

O-175

O programa da Figura O.6 demonstra os operadores E bit a bit, OU bit a bit inclusivo, OU bit a bit exclusivo e complemento bit a bit. O programa usa o mtodo GetBits, o qual retorna uma string contendo a representao em bits de seu argumento inteiro. Os usurios fornecem valores em TextBoxes e pressionam o boto correspondente operao que eles gostariam de testar. O programa exibe o resultado nas representaes inteiras e de bits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

// Fig. O.6: BitOperations.cs // Uma classe que demonstra diversas operaes de bits using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Text;

// permite que o usurio teste os operadores de bits public class BitOperations : System.Windows.Forms.Form { private System.Windows.Forms.Label promptLabel; private System.Windows.Forms.Label representationLabel; private System.Windows.Forms.Label value1Label; private System.Windows.Forms.Label value2Label; private System.Windows.Forms.Label resultLabel; // exibe as representaes de bits private System.Windows.Forms.Label bit1Label; private System.Windows.Forms.Label bit2Label; private System.Windows.Forms.Label resultBitLabel; // permite que o usurio execute as private System.Windows.Forms.Button private System.Windows.Forms.Button private System.Windows.Forms.Button private System.Windows.Forms.Button operaes de bits andButton; inclusiveOrButton; exclusiveOrButton; complementButton;

// o usurio fornece dois inteiros private System.Windows.Forms.TextBox bit1TextBox; private System.Windows.Forms.TextBox bit2TextBox; private System.Windows.Forms.TextBox resultTextBox; private int value1, value2; private System.ComponentModel.Container components = null; // construtor padro public BitOperations() { InitializeComponent(); } // cdigo gerado pelo Visual Studio .NET [STAThread] static void Main() {

Figura O.6 Demonstrando os operadores E bit a bit, OU bit a bit inclusivo, OU bit a bit exclusivo e complemento bit a bit. (Parte 1 de 3.)

O-176

C# Como Programar

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

Application.Run( new BitOperations() ); } // E private void andButton_Click( object sender, System.EventArgs e ) { SetFields(); // atualiza resultTextBox resultTextBox.Text = string.Format( {0}, value1 & value2 ); resultBitLabel.Text = GetBits( value1 & value2 ); } // OU inclusivo private void inclusiveOrButton_Click( object sender, System.EventArgs e ) { SetFields(); // atualiza resultTextBox resultTextBox.Text = string.Format( {0}, value1 | value2 ); resultBitLabel.Text = GetBits( value1 | value2 ); } //OU exclusivo private void exclusiveOrButton_Click( object sender, System.EventArgs e ) { SetFields(); // atualiza resultTextBox resultTextBox.Text = string.Format( {0}, value1 ^ value2 ); resultBitLabel.Text = GetBits( value1 ^ value2 ); } // complemento do primeiro inteiro private void complementButton_Click( object sender, System.EventArgs e ) { value1 = Convert.ToInt32( bit1TextBox.Text ); bit1Label.Text = GetBits( value1 ); // atualiza resultTextBox resultTextBox.Text = string.Format( {0}, ~value1 ); resultBitLabel.Text = GetBits( ~value1 ); } // converte o inteiro em sua representao de bits private string GetBits( int number ) { int displayMask = 1 << 31;

Figura O.6 Demonstrando os operadores E bit a bit, OU bit a bit inclusivo, OU bit a bit exclusivo e complemento bit a bit. (Parte 2 de 3.)

Apndice O Manipulao de Bits

O-177

110 StringBuilder output = new StringBuilder(); 111 // obtm cada bit, inclui espao a cada 8 bits 112 113 // para a formatao da exibio 114 for ( int c = 1; c <= 32; c++ ) 115 { 116 // anexa 0 ou 1 dependendo do resultado da mscara 117 output.Append( 118 ( number & displayMask ) == 0 ? 0 : 1 ); 119 120 // muda esquerda para que a mscara encontre o bit do 121 // prximo dgito da prxima iterao do lao 122 number <<= 1; 123 if ( c % 8 == 0 ) 124 125 output.Append( ); 126 } 127 return output.ToString(); 128 129 } // m do mtodo GetBits 130 131 // dene os campos do formulrio 132 133 private void SetFields() 134 { 135 // recupera os valores de entrada 136 value1 = Convert.ToInt32( bit1TextBox.Text ); 137 value2 = Convert.ToInt32( bit2TextBox.Text ); 138 139 // dene os rtulos para exibir as representaes de bit dos inteiros 140 bit1Label.Text = GetBits( value1 ); 141 bit2Label.Text = GetBits( value2 ); 142 } 143 144 } // m da classe BitOperations

Figura O.6 Demonstrando os operadores E bit a bit, OU bit a bit inclusivo, OU bit a bit exclusivo e complemento bit a bit. (Parte 3 de 3.)

O-178

C# Como Programar

A primeira janela de sada da Figura 0.6 mostra os resultados da combinao entre o valor 17 e 20 usando o operador E bit a bit (&); o resultado 16. A segunda janela de sada mostra os resultados da combinao entre o valor 17 e 20 usando o operador OU bit a bit; o resultado 21. A terceira sada mostra os resultados da combinao entre o valor 17 e 20 usando o operador OU exclusivo; o resultado 5. A quarta janela de sada mostra os resultados de tomar o complemento de um do valor 17; o resultado -18. O programa da Figura O.7 demonstra o uso do operador de deslocamento esquerda (<<) e o operador de deslocamento direita (>>). O mtodo GetBits retorna uma string contendo a representao de bits de um valor inteiro passado para ele como um argumento. Quando os usurios fornecem um inteiro em uma TextBox e pressionam Enter, o programa exibe a representao de bits do inteiro especicado em um Label.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

// Fig. O.7: Deslocamento de bits.cs // Demonstra os operadores de deslocamento de bits. using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Text;

// desloca os bits direita ou esquerda public class Deslocamento de bits : System.Windows.Forms.Form { private System.Windows.Forms.Label inputLabel; // aceita a entrada de usurio private System.Windows.Forms.TextBox inputTextBox; // exibe o inteiro em bits private System.Windows.Forms.Label displayLabel; private System.Windows.Forms.Button rightButton; private System.Windows.Forms.Button leftButton; private System.ComponentModel.Container components = null; // construtor padro public Deslocamento de bits() { InitializeComponent(); } // cdigo gerado pelo Visual Studio .NET [STAThread] static void Main() { Application.Run( new Deslocamento de bits() ); } // processa a entrada de usurio private void inputTextBox_KeyDown( object sender, System.Windows.Forms.KeyEventArgs e ) { if ( e.KeyCode == Keys.Enter ) displayLabel.Text =

Figura O.7 Usando os operadores de deslocamento de bits. (Parte 1 de 3.)

Apndice O Manipulao de Bits

O-179

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

GetBits( Convert.ToInt32( inputTextBox.Text ) ); } // realiza o deslocamento esquerda private void leftButton_Click( object sender, System.EventArgs e ) { // recupera a entrada de usurio int number = Convert.ToInt32( inputTextBox.Text ); // realiza a operao de deslocamento esquerda number <<= 1; // converte para inteiro e exibe na caixa de texto inputTextBox.Text = number.ToString(); // exibe os bits no rtulo displayLabel.Text = GetBits( number ); } // faz o deslocamento direita private void rightButton_Click( object sender, System.EventArgs e ) { // recupera a entrada de usurio int number = Convert.ToInt32( inputTextBox.Text ); // faz a operao de deslocamento direita number >>= 1; // converte para inteiro e exibe na caixa de texto inputTextBox.Text = number.ToString(); // exibe os bits no rtulo displayLabel.Text = GetBits( number ); } // converte o inteiro em sua representao de bit private string GetBits( int number ) { int displayMask = 1 << 31; StringBuilder output = new StringBuilder(); // obtm cada bit, adiciona um espao a cada 8 bits // para exibio formatada for ( int c = 1; c <= 32; c++ ) { // anexa um 0 ou 1 dependendo do resultado da mscara output.Append( ( number & displayMask ) == 0 ? 0 : 1 ); // desloca esquerda para que a mscara encontre o bit do // prximo dgito durante a prxima iterao do lao number <<= 1; if ( c % 8 == 0 ) output.Append( );

Figura O.7 Usando os operadores de deslocamento de bits. (Parte 2 de 3.)

O-180

C# Como Programar

105 } 106 107 return output.ToString(); 108 109 } // m do mtodo GetBits 110 111 } // m da classe BitShift

Figura O.7 Usando os operadores de deslocamento de bits. (Parte 3 de 3.)

Cada operador de deslocamento tem seu prprio boto na GUI do aplicativo. Quando um usurio d um clique em cada boto, os bits do inteiro so deslocados esquerda ou direita em um bit. TextBox e Label exibem o novo valor de inteiro e a nova representao de bits, respectivamente. O operador de deslocamento esquerda (<<) desloca os bits de seu operando esquerdo para a esquerda pelo nmero de bits especicado em seu operando direito. Os bits mais direita so substitudos por 0s; os 1s deslocados para fora da esquerda se perdem. As duas primeiras janelas de sada da Figura O.7 demonstram o operador de deslocamento esquerda. Para produzir a sada, o usurio forneceu o valor 23 e deu um clique no boto de deslocamento esquerda, resultando no valor 46. O operador de deslocamento direita (>>) muda os bits de seu operando esquerdo para a direita pelo nmero de bits especicados em seu operando direito. Os 0s substituem os bits vagos no lado esquerdo se o nmero for positivo, e os 1s substituem os bits vagos se o nmero for negativo. Todos os 1s deslocados para fora da extrema direita se perdem. A terceira e a quarta janela de sada descrevem o resultado da mudana de 184 uma vez para a direita. Cada operador bit a bit (exceto o operador de complemento bit a bit) tem um operador correspondente de atribuio. A Figura O.8 descreve esses operadores de atribuio bit a bit, os quais so usados de modo semelhante aos operadores de designao aritmtica apresentados no Captulo 3.

Operadores de atribuio bit a bit &= |=

Operador de atribuio E bit a bit. Operador de atribuio OU bit a bit inclusivo.

Figura O.8 Operadores de atribuio bit a bit. (Parte 1 de 2.)

Apndice O Manipulao de Bits

O-181

Operadores de atribuio bit a bit ^= <<= >>=

Operador de atribuio OU bit a bit exclusivo. Operador de atribuio de deslocamento esquerda. Operador de atribuio de deslocamento direita.

Figura O.8 Operadores de atribuio bit a bit. (Parte 2 de 2.)

O.3 A Classe BitArray


A classe BitArray facilita a criao e a manipulao de conjuntos de bits, os quais so muito usados pelos programadores para representar um conjunto de ags booleanos. Um ag booleano uma varivel que registra uma determinada deciso booleana. Os BitArrays so redimensionveis dinamicamente mais bits podem ser includos depois que um objeto BitArray criado. Isso faz com que o objeto aumente para acomodar os bits adicionais. A classe BitArray fornece diversos construtores, um dos quais aceita um int como um argumento. O int especica o nmero de bits que BitArray representa. Todos eles so denidos inicialmente como false. O mtodo Set de BitArray pode mudar o valor de um bit individual; ele aceita o ndice do bit a ser alterado e seu novo valor bool. A classe BitArray tambm inclui um indexador que permite obter e congurar os valores individuais de bit. O indexador retorna true se o bit especicado estiver ligado (ou seja, o bit tiver o valor 1) e retorna false, caso contrrio (ou seja, o bit tem o valor 0 ou desligado). O mtodo And da classe BitArray executa um E bit a bit entre dois BitArrays e retorna o resultado de BitArray da operao. Os mtodos Or e Xor executam as operaes OU bit a bit inclusivo e OU bit a bit exclusivo, respectivamente. A classe BitArray tambm fornece uma propriedade Length, a qual retorna o nmero de elementos do BitArray. A Figura O.9 implementa a peneira de Erasttenes, que consiste em uma tcnica para localizar nmeros primos. Um nmero primo um inteiro divisvel apenas por si mesmo e por 1. A peneira de Erasttenes opera desta maneira: a) Cria um array com todos os elementos inicializados como 1 (verdadeiro). Os elementos de array com ndices primos permanecem 1. Todos os outros elementos do array so eventualmente congurados como 0. b) Comeando com o ndice de array 2 (o ndice 1 no deve ser primo), sempre que um elemento do array encontrado com um valor de 1 percorre o restante do array e congura como 0 cada elemento cujo ndice um mltiplo do ndice do elemento com o valor 1. Por exemplo, para o ndice de array 2, todos os elementos aps o 2 no array que so mltiplos de 2 so congurados como 0 (os ndices 4, 6, 8, 10 etc.); para o ndice de array 3, todos os elementos aps 3 do array que so mltiplos de 3 so congurados como 0 (ndices 6, 9, 12, 15 etc.) e assim por diante. No nal desse processo, os ndices dos elementos de array que so 1 so os nmeros primos. Em seguida, a lista de nmeros primos pode ser exibida pela localizao e impresso desses ndices.

1 2 3 4 5 6 7 8 9 10 11 12

// Fig. O.9: BitArrayTest.cs // Demonstra a classe BitArray. using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data;

// implementa a peneira de Erasttenes public class BitArrayTest : System.Windows.Forms.Form

Figura O.9 Peneira de Erasttenes. (Parte 1 de 3.)

O-182

C# Como Programar

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

{ private System.Windows.Forms.Label promptLabel; // o usurio fornece o inteiro private System.Windows.Forms.TextBox inputTextBox; // exibe nmeros primos private System.Windows.Forms.TextBox outputTextBox; // exibe se o inteiro da entrada primo private System.Windows.Forms.Label displayLabel; private BitArray sieve; private System.ComponentModel.Container components = null; // construtor padro public BitArrayTest() { InitializeComponent(); // cria o BitArray e congura todos os bits como verdadeiro sieve = new BitArray( 1024 ); sieve.SetAll( true ); int nalBit = ( int ) Math.Sqrt( sieve.Length ); // executa a operao de peneira for ( int i = 2; i < nalBit; i++ ) if ( sieve.Get( i ) ) for ( int j = 2 * i; j < sieve.Length; j += i ) sieve.Set( j, false ); int counter = 0; // exibe os nmeros primos for ( int i = 2; i < sieve.Length; i++ ) if ( sieve.Get( i ) ) outputTextBox.Text += i + ( ++counter % 7 == 0 ? \r\n : } // cdigo gerado pelo Visual Studio .NET [STAThread] static void Main() { Application.Run( new BitArrayTest() ); } private void inputTextBox_KeyDown( object sender, System.Windows.Forms.KeyEventArgs e ) { // se o usurio pressionou Enter if ( e.KeyCode == Keys.Enter ) { int number = Convert.ToInt32( inputTextBox.Text );

);

Figura O.9 Peneira de Erasttenes. (Parte 2 de 3.)

Apndice O Manipulao de Bits

O-183

71 72 73 74 75 76 77 78 79 80 81

// se a peneira verdadeira no ndice do inteiro // fornecido pelo usurio, ento o nmero primo if ( sieve.Get( number ) ) displayLabel.Text = number + is a prime number; else displayLabel.Text = number + is not a prime number; } } // m do mtodo inputTextBox_KeyDown } // m da classe BitArrayTest

Figura O.9 Peneira de Erasttenes. (Parte 3 de 3.)

Usamos um BitArray para implementar o algoritmo. O programa exibe os nmeros primos do intervalo de 1 a 1023 em uma TextBox. O programa tambm fornece uma TextBox na qual os usurios podem digitar qualquer nmero de 1 a 1023 para determinar se aquele nmero primo (caso em que ele exibe uma mensagem indicando que o nmero primo). A instruo da linha 35 cria um BitArray de 1024 bits. O mtodo BitArray SetAll congura todos os bits como true na linha 36; em seguida, as linhas 41 a 44 determinam todos os nmeros primos ocorridos entre 1 e 1023. O inteiro nalBit determina quando o algoritmo est completo. Quando o usurio insere um nmero e pressiona Enter, a linha 73 testa se o nmero da entrada primo. Essa linha usa o mtodo Get da classe BitArray, a qual toma um nmero e retorna o valor daquele bit no array. As linhas 74 e 76 imprimem uma resposta apropriada.

Resumo
Os computadores representam os dados internamente como seqncias de bits. Cada bit pode assumir o valor 0 ou o valor 1. Em todos os sistemas, uma seqncia de 8 bits forma um byte a unidade de armazenamento padro de uma varivel do tipo byte. Os outros tipos de dados exigem nmeros maiores de bytes para o armazenamento. O operador E bit a bit congura cada bit do resultado como 1 se os bits correspondentes em ambos os operandos for 1. O operador OU bit a bit inclusivo congura cada um dos bits do resultado como 1 se o bit correspondente de um operando (ou ambos) for 1. O operador OU bit a bit exclusivo congura cada bit do resultado como 1 se o bit correspondente em exatamente um operando for 1. O OU exclusivo tambm conhecido como XOR. O operador de deslocamento esquerda (<<) desloca os bits de seu operando esquerdo para a esquerda pelo nmero de bits especicados em seu operando direito.

O-184

C# Como Programar

O operador de deslocamento direita (>>) desloca os bits de seu operando esquerdo para a direita pelo nmero de bits especicados em seu operando direito. Se o operando esquerdo for negativo, os 1s so deslocados a partir da esquerda, enquanto se o operando esquerdo for positivo, os 0s so deslocados a partir da esquerda. O operador de complemento bit a bit (~) congura todos os bits 0 de seu operando como 1 no resultado e congura todos os bits 1 como 0 no resultado; esse processo tambm chamado de tomar o complemento de um do valor. Com freqncia, o operador E bit a bit usado com um operando de mscara um valor de inteiro com bits especcos congurados como 1. As mscaras ocultam alguns bits de um valor e selecionam outros bits. Cada operador bit a bit (exceto o operador de complemento bit a bit) tem um operador de atribuio. A classe BitArray facilita a criao e manipulao dos conjuntos de bits, os quais so muito usados pelos programadores para representar um conjunto de ags booleanos. Um ag booleano uma varivel que registra determinada deciso booleana. Os BitArrays so redimensionados dinamicamente mais bits podem ser adicionados depois que um BitArray criado. Isso faz com que o objeto aumente para acomodar os bits adicionais. O mtodo Set de BitArray pode alterar o valor de um bit individual ele aceita o ndice do bit a ser alterado e o valor bool para o qual o bit deve ser mudado. O mtodo BitArray And executa um E bit a bit entre dois BitArrays. Ele retorna o BitArray que o resultado da execuo dessa operao. Os mtodos Or e Xor executam o OU bit a bit inclusivo e OU bit a bit exclusivo, respectivamente. O mtodo BitArray SetAll congura todos os bits de BitArray como true.

Terminologia
& (E bit a bit) &= (operador bit a bit de atribuio E) ^ (OU bit a bit exclusivo) | (OU bit a bit inclusivo) |= (operador de atribuio OU bit a bit inclusivo) ~ (operador de complemento bit a bit) << (operador de deslocamento esquerda) <<= (operador de atribuio de deslocamento esquerda) >> (operador de deslocamento direita) >>= (operador de atribuio de deslocamento direita) ALU (Arithmetic Logic Unit unidade lgica aritmtica) bit bit de ordem inferior bit de ordem superior BitArrayText.cs BitSht.cs byte classe BitArray complemento de um (~) conjunto de bits CPU (Central Processing Unit unidade de processamento central) deciso booleana E bit a bit (&) ag booleano indexador BitArray manipulao de bits mscara de bits mtodo And da classe BitArray mtodo Get da classe BitArray mtodo Or da classe BitArray mtodo Set da classe BitArray mtodo SetAll da classe BitArray mtodo Xor da classe BitArray nvel de bits e bytes nmero primo operador de atribuio bit a bit E (&=) operador de atribuio de deslocamento direita (>>=) operador de atribuio de deslocamento esquerda (<<=) operador de atribuio OU bit a bit exclusivo (^=) operador de atribuio OU bit a bit inclusivo (|=) operador de complemento bit a bit (~) operador de deslocamento direita (>>) operador OU bit a bit exclusivo (^) operador OU bit a bit inclusivo (|) operadores de atribuio bit a bit operadores bit a bit peneira de Erasttenes propriedade Length da classe BitArray representao binria representao de bits de um inteiro sistema de numerao base 2 sistema de numerao binrio tipo de dados primitivo byte XOR (OU exclusivo)

Você também pode gostar