Escolar Documentos
Profissional Documentos
Cultura Documentos
Recurso
Marco Antnio Queiroz
25 de maio de 2012
TADS Tecnologia em Analise e Desenvolvimento de Sistema
rea de Cincias Exatas e Tecnologia Instituto Federal Goiano Campus Uruta
Rodovia Geraldo Silva Nascimento Km 2,5. CEP 75790-000-Brasil
marco.aq@live.com
Resumo
Seguindo o trabalho proposto, utilizando recurso em algortimos para calculo do fatorial de dez mil, os mil primeiros
valores de fibonacci e a torre de hanoi com quarenta pinos que foi aplicado no desenvolvido, obteve-se alguns
resultados e que sero discutidos a seguir.
Introduo
Recurso uma das tcnicas mais simples e teis que existem para usarmos em nossos algoritmos que consiste em uma
funo chamar a si mesmo, at que o retorno seja trivial.
Fibonacci
A Sequncia de Fibonacci consiste em uma sucesso de nmeros, tais que, definindo os dois
primeiros nmeros da sequncia como 0 e 1, os nmeros seguintes sero obtidos por meio da soma
dos seus dois antecessores. Portanto, os nmeros so: 0,1,1,2,3,5,8,13,21,34,55,89,144,233,...
Dessa sequncia, extrai-se o nmero transcendental conhecido como nmero de ouro.
A sequncia de Fibonacci dada pela frmula:
Hani
A Torre de Hani um "quebra-cabea" que consiste em uma base contendo trs pinos, em um dos
quais so dispostos alguns discos uns sobre os outros, em ordem crescente de dimetro, de cima
para baixo. O problema consiste em passar todos os discos de um pino para outro qualquer, usando
um dos pinos como auxiliar, de maneira que um disco maior nunca fique em cima de outro menor
em nenhuma situao. O nmero de discos pode variar sendo que o mais simples contm apenas
trs.
Para entender a lgica da Torre de Hani necessrio analisar a construo de diferentes nveis da
torre com o nmero mnimo de movimentos, tendo o nvel anterior j formado, sendo que esses
nveis so o nmero de peas desintegradas da torre original que iro formar outra torre com os
menores discos.
Para mover o primeiro disco da torre original, 1 movimento gasto. Para mover o segundo da torre
original, sendo que o primeiro j foi movido e ser construda uma torre com os 2 menores discos,
so gastos 2 movimentos. Para deslocar o terceiro disco formando nova torre com os trs menores
discos, tendo a torre com os dois menores j formada, so gastos 4 movimentos.
Assim se sucede com os prximos discos at que o ensimo disco (o ltimo) seja deslocado
compondo uma torre com os outros discos tendo uma torre com o penltimo disco e os demais
juntos j formada. A sucesso formada pela soma dos movimentos uma sucesso.
temos
Fatorial
O fatorial de um nmero n (n pertence ao conjunto dos nmeros naturais) sempre o produto de
todos os seus antecessores, incluindo si prprio e excluindo o zero. A representao feita pelo
nmero fatorial seguido do sinal de exclamao, n! . Exemplo de nmero fatorial:
6! = 6 . 5 . 4 . 3 . 2 . 1 = 720
T(10)=T(9)+10 >| T(9)=T(8)+9 >| T(8)=T(7)+8 >| T(7)=T(6)+7 >| T(6)=T(5)+6 >| T(5)=T(4)+5 >|
T(4)=T(3)+4 >| T(3)=T(2)+3 >| T(2)=T(1)+2 >| T(1)=T(0)+1=1
At agora cada valor foi colocado numa pilha, com a ordenao inversa do modo que eu ilustrei.
Assim, agora a mquina ir retornar os valores, um a um:
T(2)=3 | T(3)=6 | T(4)=10 | T(5)=15 | T(6)=21 | T(7)=28 | T(8)=36 | T(9)=45 | T(10)=55
Limitado por sua memria
Dado o problema anterior e dando continuidade, temos tambm a limitao do uso de nmeros de
qualquer tamanho, limitado apenas a sua memria. Quando se fala em nmeros, deve-se remeter
para o tamanho da palavra que a ULA suporta (Unidade Lgica e Aritmtica). Assim, em 32 bits, o
maior inteiro que o processador consegue lidar 4.294.967.295 e isto apenas se for considerado
nmeros inteiros positivos, sem sinal. Como os processadores utilizam a representao
complemento de dois para nmeros inteiros, ao permitir que se use sinal a faixa de representao de
um inteiro em 32 bits vai de -2.147.483.648 at +2.147.483.647 (com complemento de dois ganhae uma representao a mais no lado negativo).
O mais interessante que em uma arquitetura de 32 bits, apenas o fatorial de 12 pode ser calculado.
Se for tentar calcular o fatorial de 13, este daria 6.227.020.800, nmero que no pode ser
representado em 32 bits. Agora se voc possui um processador de 64 bits, um sistema operacional
de 64 bits e compilar o cdigo em C o usando um gcc para 64 bits, voc um felizardo pois o
programa conseguir calcular o fatorial de 22, pois fatorial de 23 resulta em
25.852.016.738.884.976.640.000 e este valor no cabe em 64 bits. Isto, ainda, considerando o uso
dos inteiros sem sinal.
Um erro que comete foi pensar que trocando a varivel para double, meus alguns dos meus
problemas seria resolvidos, porem aps o trabalho entendi que double apenas um inteiro
maior(preciso).
No entanto j existem diversas solues em vrias linguagens que permitem manipular nmeros
inteiros de qualquer tamanho.
Dividir para conquistar
A ULA no suportar informaes maiores do que 32 bits (ou 64), no significa que no se pode ir
alm disto. Significa apenas que ela mesmo, a ULA, no consegue lidar com um nmero maior do
que isto de uma nica vez.
Para explicar o conceito, que tal pensarmos em qual o tamanho da nossa ULA?
Voc consegue, com a "sua ULA", executar esta operao 059 + 064?
Se voc respondeu que SIM, desculpe, mas voc errou.
Tipicamente "nossa ULA" de apenas um decimal. S conseguimos lidar com um dgito de cada
vez. Quero dizer que desde a primeira srie aprendemos a usar o conceito de dividir para conquistar.
provvel que voc, para executar a soma anterior, usou a velha tcnica da primeira srie:
059
+ 0 6 4 primeira etapa: 9 + 4 = 13
----3 (e vai um)
1
059
+ 0 6 4 segunda etapa: 5 + 6 + 1(que veio) = 12
----2 3 (e vai 1)
11
059
+ 0 6 4 terceira etapa: 0 + 0 + 1(que veio)
----1 2 3 (FIM)
Sua ULA de apenas um dgito! Voc precisou decompor as operaes complexas em vrias
menores para conseguir resolver.
O mesmo conceito se aplica para qualquer processador. possvel, atravs de programao, fazer
uma operao complexa dividindo ela em operaes menores, cada uma suportada pela ULA.
Assim como o Java, o C no possui suporte a nmeros gigantes em sua sintaxe. Se fosse C++ a
soluo seria semelhante ao Java, ou seja, atravs do uso de alguma classe que manipule estes
inteiros. Mas no C tudo funo e uma biblioteca precisa ser usada para isto.
Uma das mais fantsticas bibliotecas que a OpenSSL. Ela tem tudo o que diz respeito a
criptografia.
Como muitos algoritmos de criptografia necessitam manipular inteiros alm da capacidade da ULA,
a biblioteca OpenSSL implementou suporte a nmeros gigantes internamente. Usar apenas a parte
de nmeros big pode ser feito inserindo-se a biblioteca bn.h do OpenSSL.
Assim como no Java, que tambm no tem suporte a estes nmeros em sua sintaxe, toda a
manipulao destes nmeros deve ser feita usando-se funes apropriadas, como no exemplo
comentado do cdigo que calcula o fatorial.
#include <stdio.h>
#include <openssl/bn.h>
int main(int argc, char *argv[]){
BIGNUM *fat; // declarao de uma varivel Big
BN_ULONG a, f; // apenas um long int normal
char *resp;
int i;
/* Primeiro tem que alocar as variveis BIGNUM */
fat = BN_new();
for (i = 1; i < argc; i++) {
printf("Calculando fatorial de %s\n", argv[i]);
/* convertendo string em long int */
f = atoll(argv[i]);
/* forma de atribuir 1 a uma varivel BIGNUM */
BN_dec2bn(&fat, "1");
for (a = 2; a <= f; a++) {
BN_mul_word(fat, a);
}
/* gerando uma string imprimvel do resultado */
resp = BN_bn2dec(fat);
/* impresso do resultado (agora uma string) */
printf("Fatorial de %s = %s\n", argv[i], resp);
}
}
Para poder compilar o programa em C anterior necessrio ter instalado as bibliotecas OpenSSL
para desenvolvimento. No caso do Ubuntu deve-se instalar o pacote ssl-devel (e, evidentemente, ter
instalado todos os pacotes de desenvolvimento bsico pois o Ubuntu vem at sem gcc!). Na