[ Anterior | Índice | Seguinte ]
Para calcular as representações MOF, NAF, wMOF e wNAF de quaisquer números inteiros positivos no intervalo ]0, 1024[, foi feito um programa, cuja manipulação será explicada nesta seção.
Primeiramente, obtenha o código fonte do programa em C que encontra-se aqui. Descompacte o arquivo no diretório de sua preferência. Entre no diretório mac499/ e siga as instruções que estão no arquivo Readme.txt para compilar e executar o programa. (Observação: as instruções para compilar e executar o programa devem ser realizadas no Linux. Para o Windows, utilize os comandos próprios do compilador utilizado)
Ao executar o programa, será pedido para o usuário entrar com um número inteiro positivo no intervalo ]0, 1024[. Em seguida, será pedido o tamanho da janela w utilizada nos cálculos de wMOF e wNAF. Após isso, serão mostrados na tela as representações MOF, NAF, wMOF e wNAF.
Caso queira continuar calculando as representações para outros números inteiros positivos no intervalo ]0, 1024[, repita o processo descrito no parágrafo anterior. Caso contrário, ou seja, não queira calcular essas representações para outros números, digite 0 (zero) para sair do programa.
Abaixo estão os códigos que geram as formas MOF, NAF, wMOF e wNAF e suas respectivas análises. Como pode ser visto em [ 2 ], há outro modo de se calcular essas formas. Os algoritmos abaixo implementam a explicação dada anteriormente sobre cada representação:
/************************************ MOF *************************************/ /* Função que calcula o MOF de um string binário */ /* Recebe: */ /* - um inteiro n --> o número de iterações */ /* - um vetor de inteiros b --> a representação binária do número */ /* - um vetor de inteiros mof, onde vai ser "devolvida" a forma MOF de d */ 01 void MOF (int n, int b[], int mof[]) { 02 int i, j; 03 mof[n] = b[n - 1]; 04 for (i = n - 1; i > 0; i--) mof[i] = b[i - 1] - b[i]; 05 mof[0] = - b[0]; 06 }/* MOF -------------------------------------------------------------------*/ |
Nas linha 03 é atribuído o valor do bit mais a esquerda (mais significativo) como sendo o do primeiro bit da representação binária usual. Isso garante: O maior bit não nulo é 1.
Na linha 04 é feita a subtração bit a bit das representações binárias do número nas formas d e 2d. Isso garante: Os sinais dos bits adjacentes não nulos (sem considerar os bits nulos) são opostos.
Na linha 05 é atribuído o valor do bit mais a direita (menos significativo) como sendo o do último bit da representação binária usual, com o sinal negativo. Isso garante: O menor bit não nulo é -1.
/************************************ NAF *************************************/ /* Função que calcula o NAF de um string binário */ /* Recebe: */ /* - um inteiro n --> o número de iterações */ /* - um vetor de inteiros b --> a representação binária do número */ /* - um vetor de inteiros naf, onde vai ser "devolvida" a forma NAF de d */ 01 void NAF (int n, int b[], int naf[]) { 02 int i, j; 03 for(i = 0; i < n ; i++) naf[i] = b[i]; 04 naf[n] = 0; 05 i = 0; 06 while ((i + 2) <= n) { 07 if (naf[i] == 1 && naf[i + 1] == 1) { /* transformação NAF */ 08 naf[i] = -1; 09 naf[i + 1] = 0; 10 naf[i + 2] = 1; 11 i += 2; 12 } 13 else i++; 14 } 15 }/* NAF -------------------------------------------------------------------*/ |
Nas linha 03 e 04, o algoritmo faz uma cópia da representação binária do número no vetor naf, acrescentando um zero a esquerda.
Da linha 05 em diante, o algoritmo funciona da seguinte maneira:
- Começando pelo bit mais a direita (menos significativo), são verificados esse bit e o próximo bit a esquerda.
- Se ambos forem iguais a 1, esse 11 é substituído por 01 e o próximo bit a esquerda desse 11 recebe -1.
- Caso contrário, verificam-se os próximos 2 bits a esquerda e o processo se repete.
/*********************************** wMOF *************************************/ /* Função que calcula o wMOF de um string binário */ /* Recebe: */ /* - um inteiro n --> o número de iterações */ /* - um vetor de inteiros b --> a representação binária do número */ /* - um vetor de inteiros wmof, onde vai ser "devolvida" a forma wMOF de d */ 01 void wMOF (int n, int w, int b[], int wmof[]) { 02 int i, j, num, potencia, aux, aux1[NMAX + 1], aux2[NMAX]; 03 if (w == 1) { 04 for (i = 0; i < n; i++) wmof[i] = b[i]; 05 wmof[n] = 0; 06 } 07 else { 08 MOF(n, b, aux1); 09 i = n; 10 while ((i - w) > 0) { 11 num = 0; 12 potencia = pot (2, w - 1); 13 for (j = i; j > (i - w); j--) { 14 wmof[j] = 0; 15 num += aux1[j] * potencia; 16 potencia /= 2; 17 } 18 potencia = pot (2, w); 19 aux = num; 20 if (aux % 2 != 0) { 21 if (aux < pot (2 , (w - 1))) wmof[i - w + 1] = aux; 22 else wmof[i - w + 1] = aux - potencia; 23 } 24 else { 25 for(j = 0; j < w; j++) aux2[j] = 0; 26 if (aux < 0) { 27 num = converte (-aux, aux2); 28 for (j = i, num = w - 1; j > i - w; j--) wmof[j] = - aux2[num--]; 29 } 30 else { 31 num = converte (aux, aux2); 32 for (j = i, num = w - 1; j > i - w; j--) wmof[j] = aux2[num--]; 33 } 34 } 35 } 36 } 37 }/* wMOF-------------------------------------------------------------------*/ |
Das linhas 03 a 06 é tratado o caso em que w = 1.
Na linha 08, o algoritmo transforma a representação binária do número para a forma MOF. Ao fazer a função receber como argumento o número já na forma MOF ao invés de recebê-lo na representação binária usual, estaríamos economizando tempo e retiraríamos a linha 08.
Da linha 09 em diante, o algoritmo funciona da seguinte maneira:
- Começando pelo bit mais a esquerda (mais significativo), são selecionados w bits. Esses w bits representam algum número na representação binária (potência 2) e são transformados na representação decimal (potência 10) (linhas 10 a 17).
- Como na forma wMOF cada dígito não nulo é ímpar e menor que 2w - 1 em valor absoluto, temos 2 casos:
* Caso o número obtido seja ímpar e:
- menor que 2w - 1 em valor absoluto, a linha 21 é executada.
- não seja menor que 2w - 1 em valor absoluto, a linha 22 é executada.
* Caso o número obtido seja par, transformamos esse número para a forma binária e :
- caso o número seja negativo, executamos as linhas 26 a 29.
- caso contrário, executamos as linhas 30 a 33.
- Em seguida, o processo se repete.
/*********************************** wNAF *************************************/ /* Função que calcula o wNAF de um string binário */ /* Recebe: */ /* - um inteiro n --> o número de iterações */ /* - um inteiro w --> a largura da janela usada pelo wNAF */ /* - um vetor de inteiros b --> a representação binária do número */ /* - um vetor de inteiros wnaf, onde vai ser "devolvida" a forma wNAF de d */ 01 void wNAF (int n, int w, int b[], int wnaf[]) { 02 int i, j, num, potencia, aux[NMAX + 1]; 03 if (w == 1) { 04 for (i = 0; i < n; i++) wnaf[i] = b[i]; 05 wnaf[n] = 0; 06 } 07 else { 08 MOF(n, b, aux); 09 i = 0; 10 while ((w + i) < n) { 11 num = 0; 12 potencia = 1; 13 if (aux[i] != 0) { 14 for (j = i; j < (w + i); j++) { 15 num += aux[j] * potencia; 16 potencia *= 2; 17 } 18 potencia = pot (2, w); 19 if (num < pot (2 , (w - 1))) wnaf[i] = num; 20 else wnaf[i] = num - potencia; 21 i += w; 22 } 23 else { 24 wnaf[i] = 0; 25 i++; 26 } 27 } 28 } 29 }/* wNAF ------------------------------------------------------------------*/ |
Das linhas 03 a 06 é tratado o caso em que w = 1.
Na linha 08, o algoritmo transforma a representação binária usual do número para a forma MOF. Ao fazer a função receber como argumento o número já na forma MOF ao invés de recebê-lo na representação binária usual, estaríamos economizando tempo e retiraríamos a linha 08.
Da linha 09 em diante, o algoritmo funciona da seguinte maneira:
- Começando pelo bit mais a direita (menos significativo), é verificado se esse bit é nulo ou não. Caso o bit seja igual a 0, são executadas as linhas 23 a 26. Caso contrário, são selecionados w bits. Esses w bits representam algum número na representação binária (potência 2) e são transformados na representação decimal (potência 10) (linhas 14 a 17). Isso garante: Dentre quaisquer w dígitos consecutivos, ao menos um é não nulo.
- Caso o número obtido não seja menor que 2w - 1 em valor absoluto, a linha 20 é executada. Caso contrário, a linha 19 é executada. Isso garante: Cada dígito não nulo é ímpar e menor que 2w -1 em valor absoluto.
- Em seguida, o processo se repete. Assim que o algoritmo termina, o bit mais significativo não nulo é positivo.
Os gráficos abaixo demonstram a quantidade de vezes em que o vetor com a representação binária inicial é modificado até se obter a forma de representação binária com sinal, de acordo com o tamanho de w :
Os números 687 e 1000 apresentam a mesma seqüência |
Dos gráficos apresentados, podemos notar que a forma wMOF executa menos modificações no vetor do que a forma wNAF, dependendo do número a ser calculado e do tamanho da janela w.
|