A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Tutoriais e Programação

AoA - Cap.2 - Funções booleanas genéricas

Sex

23

Fev

2007


11:40

(3 votos, média 3.67 de 5) 


Nível intermediário Para uma aplicação específica pode-se criar uma função lógica que dê um determinado resultado. Suponha, entretanto, que você queira escrever um programa para simular qualquer função booleana possível.

Por exemplo, imagine um programa que permita a entrada de uma função booleana arbitrária com quatro variáveis diferentes. Este programa lerá as entradas e produzirá necessariamente os resultados das funções. Uma vez que o número de funções de quatro variáveis únicas é grande (65536, para ser exato), não é prático incluir uma solução específica para cada uma no programa. O que se precisa é de uma função lógica genérica, uma que calcule os resultados para qualquer função arbitrária. Esta seção descreve como escrever tal função.

Uma função booleana genérica de quatro variáveis requer cinco parâmetros - os quatro parâmetros de entrada e um quinto parâmetro que especifica a função que deve ser calculada. Apesar de haver muitas formas de se especificar uma função, optamos por passar o número da função booleana como quinto parâmetro.

À primeira vista você poderia perguntar como é possível calcular uma função utilizando o seu número. Contudo, lembre-se de que os bits que formam o número da função vêm diretamente da tabela verdade da própria função. Então, se extrairmos os bits do número da função, poderemos construir a tabela verdade para a mesma. Além disto, se selecionarmos somente o iésimo bit do número da função, onde i = D*8 + C*4 + B*2 + A, obteremos o resultado da função para os valores especificados para A, B, C e D. O exemplo a seguir, em C e Pascal, mostra como escrever tais funções:

/************************************************************************/ /* */ /* Este programa C demonstra como escrever uma função booleana genérica */ /* que pode calcular qualquer função lógica de quatro variáveis. Com os */ /* operadores de manipulação de bits e com a E/S hexadecimal, esta é */ /* uma tarefa fácil de ser efetuada com a linguagem C. */ /* */ /************************************************************************/ #include #include /* função lógica genérica. O parâmetro "Func" contém o número 16 */ /* da função lógica. Na verdade, isto é a função lógica de uma tabela */ /* verdade codificada. Os parâmetros a, b, c e d são as entradas para */ /* a função lógica. Se tratarmos "func" como um array 2x2x2x2 de bits, */ /* esta função particular seleciona o bit "func[d,c,b,a]" da função. */ int generic(int func, int a, int b, int c, int d) { /* Retorna o bit especificado por a, b, c e d */ return (func >> (a + b*2 + c*4 + d*8)) & 1; } /* Programa principal para comandar a função lógica genérica escrita em C. */ main() { int func, a, b, c, d; /* Repete o seguinte até o usuário entrar zero. */ do { /* Obtém o número da função (tabela verdade) */ printf("Entre o valor da função (hex): "); scanf("%x", &func); /* Se o usuário especificar zero como nro da função */ if (func != 0) { printf("Entre os valores para d, c, b & a: "); scanf("%d%d%d%d", &d, &c, &b, &a); printf("O resultado é %d\n", generic(func,a,b,c,d)); printf("Func = %x, A=%d, B=%d, C=%d, D=%d\n", func, a, b, c, d); } } while (func !=0); }

O programa a seguir, em Pascal, foi escrito para Standard Pascal. O Standard Pascal não fornece quaisquer operações para manipulação de bits, então este programa ficou grande porque ele precisa manipular os bits utilizando um array de inteiros. Muitos Pascals modernos (especialmente o Turbo Pascal) fornecem operações de bits embutidas ou rotinas em bibliotecas que operam bits. Este programa seria muito mais fácil de escrever utilizando tais características não padronizadas.

program GenericFunc(input,output); (* Já que o Pascal Padrão não fornece uma forma fácil para manipular *) (* diretamente bits em um inteiro, simularemos o número da função *) (* utilizando um array de 16 inteiros. "GFTYPE" é o tipo desse array. *) type gftype = array [0..15] of integer; var a, b, c, d:integer; fresult:integer; func: gftype; (* Pascal Padrão não tem a capacidade de deslocar um dado inteiro para *) (* a esquerda ou a direita. Então, simularemos um valor de 16 bits *) (* utilizando um array de 16 inteiros. Podemos simular o deslocamento *) (* movendo o dado através do array. *) (* *) (* Note que o Turbo Pascal *fornece* os operadores shl e shr. *) (* Contudo, este código é escrito para funcionar com o Pascal Padrão, *) (* e não apenas em Turbo Pascal. *) (* *) (* ShiftLeft desloca os valores em func para a esquerda e insere o *) (* valor deslocado no bit de posição zero *) procedure ShiftLeft(shiftin:integer); var i:integer; begin for i := 15 downto 1 do func[i] := func[i-1]; func[0] := shiftin; end; (* ShiftNibble desloca o dado em func para a esquerda quatro posições e *) (* insere os quatro bits a , b, c & d nas posições vagas *) procedure ShiftNibble(d,c,b,a:integer); begin ShiftLeft(d); ShiftLeft(c); ShiftLeft(b); ShiftLeft(a); end; (* ShiftRight desloca o dado em func uma posição à direita. Desloca *) (* um zero para dentro do bit de mais alta ordem do array. *) procedure ShiftRight; var i:integer; begin for i := 0 to 14 do func[i] := func[i+1]; func[15] := 0; end; (* ToUpper converte um caracter minúsculo para maiúsculo. *) procedure toupper(var ch:char); begin if (ch in ['a'..'z']) then ch := chr(ord(ch) - 32); end; (* ReadFunc lê um número de função hexadecimal fornecido pelo usuário *) (* e põe este valor no array func (bit a bit) *) function ReadFunc:integer; var ch:char; i, val:integer; begin write('Entre o número da função (hexadecimal): '); for i := 0 to 15 do func[i] := 0; repeat read(ch); if not eoln then begin toupper(ch); case ch of '0': ShiftNibble(0,0,0,0); '1': ShiftNibble(0,0,0,1); '2': ShiftNibble(0,0,1,0); '3': ShiftNibble(0,0,1,1); '4': ShiftNibble(0,1,0,0); '5': ShiftNibble(0,1,0,1); '6': ShiftNibble(0,1,1,0); '7': ShiftNibble(0,1,1,1); '8': ShiftNibble(1,0,0,0); '9': ShiftNibble(1,0,0,1); 'A': ShiftNibble(1,0,1,0); 'B': ShiftNibble(1,0,1,1); 'C': ShiftNibble(1,1,0,0); 'D': ShiftNibble(1,1,0,1); 'E': ShiftNibble(1,1,1,0); 'F': ShiftNibble(1,1,1,1); else write(chr(7),chr(8)); end; end; until eoln; val := 0; for i := 0 to 15 do val := val + func[i]; ReadFunc := val; end; (* Generic - Calcula a função lógica genérica especificada pelo *) (* número da função "func" nas quatro variáveis *) (* a, b, c & d. Faz isto retornando o bit *) (* d*8 + c*4 + b*2 + a da função. *) function Generic(var func:gftype; a,b,c,d:integer):integer; begin Generic := func[a + b*2 + c*4 + d*8]; end; begin (* main *) repeat fresult := ReadFunc; if (fresult <> 0) then begin write('Entre os valores para D, C, B, & A (0/1):'); readln(d, c, b, a); writeln('O resultado é ',Generic(func,a,b,c,d)); end; until fresult = 0; end.

O código a seguir demonstra o poder das operações de manipulação de bits. Esta nova versão do código acima utiliza características especiais presentes na linguagem de programação do Turbo Pascal que permitem deslocar bits para a direita ou para a esquerda e fazer um AND lógico bit a bit em variáveis inteiras:

program GenericFunc(input,output); const hex = ['a'..'f', 'A'..'F']; decimal = ['0'..'9']; var a, b, c, d:integer; fresult:integer; func: integer; (* Aqui está uma segunda versão da função genérica do Pascal que *) (* utiliza as características do Turbo Pascal para simplificar o *) (* programa. *) function ReadFunc:integer; var ch:char; i, val:integer; begin write('Entre o número da função (hexadecimal): '); repeat read(ch); func := 0; if not eoln then begin if (ch in Hex) then func := (func shl 4) + (ord(ch) and 15) + 9 else if (ch in Decimal) then func := (func shl 4) + (ord(ch) and 15) else write(chr(7)); end; until eoln; ReadFunc := func; end; (* Generic - Calcula a função lógica genérica especificada pelo *) (* número da função "func" nas quatro variáveis *) (* a, b, c e d. Faz isto retornando o bit *) (* d*8 + c*4 + b*2 + a de func. Esta versão deixa o *) (* trabalho para o operador de deslocamento do Turbo *) (* Pascal e sua habilidade para fazer operações em *) (* bits de inteiros. *) function Generic(func,a,b,c,d:integer):integer; begin Generic := (func shr (a + b*2 + c*4 + d*8)) and 1; end; begin (* main *) repeat fresult := ReadFunc; if (fresult <> 0) then begin write('Entre os valores para D, C, B, & A (0/1):'); readln(d, c, b, a); writeln('O resultado é ',Generic(func,a,b,c,d)); end; until fresult = 0; end.

Fonte

  • Art of Assembly de Randall Hyde.
  • Tradução meio que livre da vovó Vicki.
mfx broker инвестициичто сделать чтобы не пригорала чугунная сковородалобановский класс харьковасус планшеталександр лобановскийлобановский александр досьехарьков никас

Informações adicionais