A logica dos operadores logicos

Started by branco, 02 de October , 2006, 10:59:02 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

branco

by zerovalue, vbmania

Introdução

    Pense rápido. Qual a função do operador AND?

    Este é um teste fácil para ver se você precisa ler este artigo. Se precisar, sua resposta provavelmente será algo do tipo: "o operador AND verifica duas expressões booleanas e só retorna True se as duas forem verdadeiras". Que fique claro aqui que jamais disse, e nem direi, que este pensamento está incorreto. Realmente, a função do AND é essa mesmo, porém existem coisas mais profundas envolvidas neste processo de verificação de bits do que uma simples comparação de duas variáveis boolean.

    Tentarei explicar neste artigo como funcionam os operadores lógicos, e você verá que eles servem pra muito mais coisas do que você está acostumado(a) a usá-lo para. Só que para isso terei que explicar outros conceitos que são importantes para a compreensão do principal.

Por que declarar minhas variáveis?

    É um conceito simples, que mesmo que você não aplique, perceberá que no fundo, no fundo mesmo, já sabe.

    A declaração das variáveis, sendo feita por você, ou por uma atribuição Run-Time do VB, serve para um fim a mais do que a simples alocação de memória para armazenar o valor da variável. Declarar uma variável também serve para dizer ao VB como ele vai ler aquele valor. Por exemplo, as variáveis do tipo Long e Single alocam o mesmo número de bytes na memória (4 bytes), porém um byte com o binário 01011000 01111000 00101001 10010000 equivale a decimais diferentes quando o VB for ler.

    Teste simples:

    O comando LSet copia todo o conteúdo de memória dentro de um user defined type para outro (V. VB Help). Inicie um novo projeto, na parte de declarações, insira:

    Type Tipo1
        Valor as Long
    End Type

    Type Tipo2
        Valor as Single
    End Type

    Como pode perceber, todos os dois tipos usam 4 bytes de memória, por isso não haveria problemas em usar LSet nos dois, e talvez quando copiasse o conteúdo de memória de um para outro o número que o VB lê de um seria o mesmo que o do outro. Mas não é bem assim. Insira as declarações e os comandos dentro de algum evento:

      Dim Var1 as Tipo1
      Dim Var2 as Tipo2

      Var1.Valor = 800 'Var1.Valor é do tipo Long

      LSet Var2 = Var1 'Aqui o conteúdo de memória de Var1 é copiado para Var2

      MsgBox Var2.Valor

    Se tudo foi feito corretamente, você pode perceber que apesar das variáveis usarem o mesmo número de bytes na memória, quando o valor binário de um é copiado para o outro, o valor decimal não se mantém. Isso ocorre por que o VB lê cada tipo de variável na memória de uma forma diferente.

    Para explicar os operadores lógicos, colocarei ênfase na forma como o VB lê as variáveis inteiras (Integer e Long), explicadas no tópico seguinte.

O primeiro bit de Long e Integer

    Acho que quase todo mundo que programa sabe o que são os números binários, e creio entendam mais sobre isso do que os redatores daqueles cadernos de informática dos jornais.

    Pela lógica, se uma variável pode ocupar até 4 bits na memória, ela poderia armazenar valores entre 0 (0000) e 15 (1111), pois tendo 4 bits, poderia realizar 2^4 combinações diferentes. Realmente é assim, entretanto, para armazenar as variáveis inteiras, as linguagens de programação em geral utilizam um artifício interessante.

    Exemplo: a variável do tipo Integer ocupa 2 bytes na memória, ou seja 16 bits. Com 16 bits, é possível realizar 2^16 combinações diferentes. Seguindo a lógica dos binários em geral, a variável Integer deveria guardar números entre 0 e 65535. Mas se fosse assim, essa variável não seria inteira, pois o conjunto Z dos números inteiros também compreende os números negativos.

      Para fazer com que a variável seja inteira de verdade foi convencionado que o primeiro bit (da esquerda para a direita) indicaria qual o sinal do número. Voltando ao exemplo da variável de 4 bits, se ela for de um tipo inteiro (tipo Half Byte =P), apenas os 3 últimos bits serão usados para dizer qual o número em si, o primeiro bit será usado para definir o sinal. Sendo assim:
     
      0000 = 0
      0001 = 1
      0010 = 2
      0011 = 3
     
      até ai tudo bem, mas
     
      1000 = -1
      1001 = -2
      1010 = -3
      1011 = -4
     
      Parece estranho, não? Foi dito que os 3 últimos bits definiriam o número em si e os 3 últimos bits de 1000 são 000 e nem por isso definem o número 0. Isso acontece pois haveria perda de um valor se tanto 1000 quanto 0000 valessem 0, por isso foi convencionado que os negativos começariam já do 1, ao invés do 0. Isso explica o porque da variável Integer por exemplo ir de -32768 a 32767. Tem um valor negativo a mais. É por isso, por que a contagem dos negativos conta a partir do -1 realmente, e o 0 é considerado positivo.
     
      Tente entender isso para passar para a próxima parte, que explicará os valores booleanos True e False.

Boolean: 1 bit só. –Ta, sei...

    Possivelmente aquele professor do curso de VB, doido pra falar sobre MsJet, falou que enquanto a variável Integer gasta 16 bits de memória e a Byte gasta 8 bits, a variável Boolean gasta apenas 1 bit de memória. Isso está certo e errado ao mesmo tempo. A variável Boolean, desde os tempos mais primórdios foi feita pra guardar True ou False. Acontece que a memória é divida em células de 8 bits, ficando, portanto, inviável implementar uma variável que só trabalhe com 1 bit. O mínimo que se precisava era uma variável de 8 bits. Porém quando a linguagem Basic foi criada, para fins de compatibilidade, decidiu-se deixar Boolean com o mesmo tamanho de uma Integer. Por isso, até hoje, Boolean armazena seus dados em 16 bits de memória. Entretanto só usa 1, o último, e da mesma forma, o VB só lê 1.

    Explicando isso melhor em outro parágrafo, o VB guarda Boolean em 16 bits, mas na hora de ler, só lê 1, o último da esquerda pra direita. Como Boolean é uma variável inteira como Integer, o valor numérico assumido por True e False é:

False = valor de bit 0 = 0
True = valor de bit 1 = -1

    True (1) vale -1 pelo motivo explicado no tópico passado: como o VB só lê o último bit da variável, ele, estando sozinho, é o que define o sinal. Como não vem nada depois, o número em si é 0. Para sinal 0 e número 0, valor 0. Mas para sinal 1 e número 0, valor -1. Veja o tópico passado para entender melhor.

    Assim como nos tópicos passados, tente entender bem este para passar para o próximo. Adiantando, entrarei no assunto principal: operadores lógicos.

Vamos aos operadores!

    Basicamente, existem três tipos de operadores: aritméticos, de comparação e lógicos. Os dois primeiros trabalham mais especificamente com os valores dos argumentos. Quando você executa a condição IF 2 > 3 THEN, a ênfase é sobre os valores 2 e 3, e não sobre os bits do valor 2 e do valor 3, apesar do processador interpretar esses valores como binários, mas como dito, a ênfase não é essa. O mesmo acontece com os operadores aritméticos, quando se soma 2 + 3.5, não interessa se o primeiro valor é um Integer e o segundo um Single, o que interessa nesse caso é o valor em si, que vai resultar no Single 5.5. Já os operadores lógicos não, eles dão total ênfase ao valor binário dos argumentos que são passados. 5 And 6 (alguns podem se espantar, mas isso é possível) é o mesmo que 101 And 110.

    Para que você possa entender melhor o que foi dito aqui, irei tentar falar algo sobre os seis operadores lógicos disponíveis no VB: OR, XOR, AND, NOT, IMP e EQV.

Operador OR

    O operador OR faz uma disjunção lógica em duas expressões (como diz o help do VB5). Mas o que seria isso? Basicamente, ele vai verificando bit a bit nas duas expressões e retorna uma terceira expressão como resultado.

    A verificação é a seguinte: 1oBitExp1 OR 1oBitExp2 & 2oBitExp1 OR 2oBitExp2 e etc. Se qualquer um dos dois bits na verificação estiver setado (valer 1), o resultado será 1, caso contrário, se os dois forem 0, o resultado é 0.

    Ex.:

    Exp1: 0110
    OR
    Exp2: 1100
    =
    Exp3: 1110

Operador XOR

    O operador XOR realiza uma exclusão lógica em duas expressões (referencia idem ao anterior). Diferentemente do que se pensa, o XOR não é a operação inversa do OR. XOR é a operação inversa do EQV (como vai ser visto a frente).

    No XOR, diferindo do OR, APENAS um dos dois bits deve estar setado para que o resultado seja 1, se os dois ou nenhum estiver setado, o resultado é 0.

    Ex.:
   
    Exp1: 0110
    XOR
    Exp2: 1100
    =
    Exp3: 1010

Operador AND

    O papel do AND é realizar uma conjunção lógica em duas expressões. Sendo necessário que os dois bits estejam setados para que o resultado seja 1, caso contrário o resultado é 0.

    Ex.:

    Exp1: 0110
    AND
    Exp2: 1100
    =
    Exp3: 0100

    O operador AND, ainda tem uma função muito utilizada que acho importante explanar aqui. É sobre a verificação da composição binária. Por exemplo, a função MsgBox utiliza no parâmetro Flags, constantes com números da PG de multiplicador 2 (1,2,4,8,16 e etc). Quando o valor entra na função, ele vem como uma soma. Neste caso, como saber se o usuário adicionou a constante que vale 32, por exemplo?

    Para transformar um binário em decimal, como você deve saber, basta atribuir a cada bit um valor na soma, que é número 2 elevado o sua posição da direita pra esquerda, partindo de 0.

    Ex.:

    Índice do Bit:        3    2    1    0
    Formula do Bit:    2^3    2^2    2^1    2^1
    Valor do Bit:        8    4    2    1
    Bit:            0    1    1    0

    Para descobrir o valor decimal, basta realizar a soma dos valores onde o bit é setado: 4 + 2 = 6, ou seja, 0110 é o mesmo que 6. Num binário de 8 bits, para exemplificar o caso da MsgBox, você saberá que o usuário inseriu a constante de valor 32 se o bit que vale 32 estiver setado.

    Ex.:

    Índice do Bit:        7    6    5    4    3    2    1    0
    Formula do Bit:    2^7    2^6    2^5    2^4    2^3    2^2    2^1    2^1
    Valor do Bit:        128    64    32    16    8    4    2    1
    Bit:            1    0    1    0    0    1    1    0

    Neste caso, o bit que vale 32 está setado, portanto, está confirmado que, nessa soma, o 32 faz parte da composição binária.

    O AND serve para realizar esta verificação facilmente. No caso: Soma AND 32 verificaria se o 32 faz parte da composição binária, pois:

    Soma:    10100110
    32:    00100000

    O operador AND, só retorna o bit 1 se os dois bits na comparação também forem 1. Neste caso, se o bit de valor 32 em Soma estiver setado, o resultado desta comparação será 00100000, caso contrário será 00000000. O Vb interpreta qualquer valor diferente de 0 como True, e o contrário como False. Portanto, se o valor 32 fizer parte de Soma, o VB indicará como True, senão, indicará como False.
   
Operador NOT

    O operador NOT é o mais fácil de todos. A função dele é fazer uma negação lógica em uma só expressão. Onde for 0, é setado 1, onde for 1, torna-se 0.
   
    Ex.:
   
    NOT
    Exp1: 0110 'ignorei a Exp2 de propósito
    =
    Exp3: 1001

Operador IMP

    O operador IMP é pouco conhecido. Ele é utilizado para realizar uma implicação lógica em duas expressões. Nesta operação, o único caso onde o bit resultado será 0 é quando o bit em Exp1 for 1 e o bit em Exp2 for 0, caso contrário, tudo é setado em 1.

    Ex.:
   
    Exp1: 0110
    IMP
    Exp2: 1100
    =
    Exp3: 1101

Operador EQV
   
    O operador EQV também é bem fácil de entender. Utilizado para realizar uma equivalência lógica entre duas expressões, EQV só retorna bit 1 quando os bits nas duas expressões forem iguais, caso contrário, retorna 0.

    Ex.:

    Exp1: 0110
    EQV
    Exp2: 1100
    =
    Exp3: 0101

Enfim, o fim

    Bem, o objetivo deste artigo foi explicar como funcionam os operadores lógicos. Aconselho a todos que se interessaram (e aos que não, também) a darem mais atenção a lógica de programação, que essa anda meio esquecidinha no meio dessas facilidades do VB.

E lembre-se que o mais importante numa linguagem de programação é a linguagem de programação.

Obrigado por ler, espero ter ajudado, e até o próximo artigo.
Olha o trem... Quem vai ficar, quem vai partir? Quem vai chorar, quem vai sorrir?

vuln

#1
Gostei bom conteúdo. Quando comecei a ler pensei que você iria errar a questão do 1 ser verdadeiro e 0 falso. Muitos erram, mas na verdade mesmo, o 1 (True) e 0 (False) são um padrão. Até mais,
Abraços.



Ficou bom mesmo. E melhor ainda porque você pode adaptar o que aprendeu aqui para centenas de coisas, inclusive diversas linguagens de programação.
"O amor por princípio, a Ordem por base, o progresso por objetivo."